Standardize on continent list component
This commit is contained in:
parent
837ab35da5
commit
227713fa26
|
@ -2,14 +2,8 @@
|
||||||
<form class="container">
|
<form class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||||
<div class="form-floating">
|
<continent-list v-model="criteria.continentId" topLabel="Any"
|
||||||
<select id="continentId" class="form-select" :value="criteria.continentId"
|
@update:modelValue="(c) => updateValue('continentId', c)" />
|
||||||
@change="updateValue('continentId', $event.target.value)">
|
|
||||||
<option value="">– Any –</option>
|
|
||||||
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
|
|
||||||
</select>
|
|
||||||
<label for="continentId">Continent</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||||
<div class="form-floating">
|
<div class="form-floating">
|
||||||
|
@ -56,12 +50,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, onMounted, ref, Ref } from 'vue'
|
import { defineComponent, ref, Ref } from 'vue'
|
||||||
import { PublicSearch } from '@/api'
|
import { PublicSearch } from '@/api'
|
||||||
import { useStore } from '@/store'
|
import ContinentList from '../ContinentList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ProfilePublicSearchForm',
|
name: 'ProfilePublicSearchForm',
|
||||||
|
components: { ContinentList },
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -70,17 +65,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
emits: ['search', 'update:modelValue'],
|
emits: ['search', 'update:modelValue'],
|
||||||
setup (props, { emit }) {
|
setup (props, { emit }) {
|
||||||
const store = useStore()
|
|
||||||
|
|
||||||
/** The initial search criteria passed; this is what we'll update and emit when data changes */
|
/** The initial search criteria passed; this is what we'll update and emit when data changes */
|
||||||
const criteria : Ref<PublicSearch> = ref({ ...props.modelValue as PublicSearch })
|
const criteria : Ref<PublicSearch> = ref({ ...props.modelValue as PublicSearch })
|
||||||
|
|
||||||
/** Make sure we have continents */
|
|
||||||
onMounted(async () => await store.dispatch('ensureContinents'))
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
criteria,
|
criteria,
|
||||||
continents: computed(() => store.state.continents),
|
|
||||||
updateValue: (key : string, value : string) => {
|
updateValue: (key : string, value : string) => {
|
||||||
criteria.value = { ...criteria.value, [key]: value }
|
criteria.value = { ...criteria.value, [key]: value }
|
||||||
emit('update:modelValue', criteria.value)
|
emit('update:modelValue', criteria.value)
|
||||||
|
|
|
@ -2,14 +2,8 @@
|
||||||
<form class="container">
|
<form class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
<div class="col col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||||
<div class="form-floating">
|
<continent-list v-model="criteria.continentId" topLabel="Any"
|
||||||
<select id="continentId" class="form-select"
|
@update:modelValue="(c) => updateValue('continentId', c)" />
|
||||||
:value="criteria.continentId" @change="updateValue('continentId', $event.target.value)">
|
|
||||||
<option value="">– Any –</option>
|
|
||||||
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
|
|
||||||
</select>
|
|
||||||
<label for="continentId">Continent</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-xs-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0">
|
<div class="col col-xs-12 col-sm-6 col-offset-md-2 col-lg-3 col-offset-lg-0">
|
||||||
<label class="jjj-label">Seeking Remote Work?</label><br>
|
<label class="jjj-label">Seeking Remote Work?</label><br>
|
||||||
|
@ -56,12 +50,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, onMounted, Ref, ref } from 'vue'
|
import { defineComponent, Ref, ref } from 'vue'
|
||||||
import { ProfileSearch } from '@/api'
|
import { ProfileSearch } from '@/api'
|
||||||
import { useStore } from '@/store'
|
import ContinentList from '../ContinentList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ProfileSearchForm',
|
name: 'ProfileSearchForm',
|
||||||
|
components: { ContinentList },
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -70,17 +65,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
emits: ['search', 'update:modelValue'],
|
emits: ['search', 'update:modelValue'],
|
||||||
setup (props, { emit }) {
|
setup (props, { emit }) {
|
||||||
const store = useStore()
|
|
||||||
|
|
||||||
/** The initial search criteria passed; this is what we'll update and emit when data changes */
|
/** The initial search criteria passed; this is what we'll update and emit when data changes */
|
||||||
const criteria : Ref<ProfileSearch> = ref({ ...props.modelValue as ProfileSearch })
|
const criteria : Ref<ProfileSearch> = ref({ ...props.modelValue as ProfileSearch })
|
||||||
|
|
||||||
/** Make sure we have continents */
|
|
||||||
onMounted(async () => await store.dispatch('ensureContinents'))
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
criteria,
|
criteria,
|
||||||
continents: computed(() => store.state.continents),
|
|
||||||
updateValue: (key : string, value : string) => {
|
updateValue: (key : string, value : string) => {
|
||||||
criteria.value = { ...criteria.value, [key]: value }
|
criteria.value = { ...criteria.value, [key]: value }
|
||||||
emit('update:modelValue', criteria.value)
|
emit('update:modelValue', criteria.value)
|
||||||
|
|
|
@ -23,14 +23,8 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-6 col-md-4">
|
<div class="col-12 col-sm-6 col-md-4">
|
||||||
<div class="form-floating">
|
<continent-list v-model="v$.continentId.$model" :isInvalid="v$.continentId.$error"
|
||||||
<select id="continentId" :class="{ 'form-select': true, 'is-invalid': v$.continentId.$error }"
|
@touch="v$.continentId.$touch() || true" />
|
||||||
:value="v$.continentId.$model" @change="continentChanged">
|
|
||||||
<option v-for="c in continents" :key="c.id" :value="c.id">{{c.name}}</option>
|
|
||||||
</select>
|
|
||||||
<label for="continentId" class="jjj-required">Continent</label>
|
|
||||||
</div>
|
|
||||||
<div class="invalid-feedback">Please select a continent</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-6 col-md-8">
|
<div class="col-12 col-sm-6 col-md-8">
|
||||||
<div class="form-floating">
|
<div class="form-floating">
|
||||||
|
@ -116,6 +110,7 @@ import api, { Citizen, LogOnSuccess, Profile, ProfileForm } from '@/api'
|
||||||
import { toastError, toastSuccess } from '@/components/layout/AppToaster.vue'
|
import { toastError, toastSuccess } from '@/components/layout/AppToaster.vue'
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
|
|
||||||
|
import ContinentList from '@/components/ContinentList.vue'
|
||||||
import LoadData from '@/components/LoadData.vue'
|
import LoadData from '@/components/LoadData.vue'
|
||||||
import MarkdownEditor from '@/components/MarkdownEditor.vue'
|
import MarkdownEditor from '@/components/MarkdownEditor.vue'
|
||||||
import MaybeSave from '@/components/MaybeSave.vue'
|
import MaybeSave from '@/components/MaybeSave.vue'
|
||||||
|
@ -124,6 +119,7 @@ import ProfileSkillEdit from '@/components/profile/SkillEdit.vue'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'EditProfile',
|
name: 'EditProfile',
|
||||||
components: {
|
components: {
|
||||||
|
ContinentList,
|
||||||
LoadData,
|
LoadData,
|
||||||
MarkdownEditor,
|
MarkdownEditor,
|
||||||
MaybeSave,
|
MaybeSave,
|
||||||
|
@ -175,7 +171,6 @@ export default defineComponent({
|
||||||
|
|
||||||
/** Retrieve the user's profile and their real name */
|
/** Retrieve the user's profile and their real name */
|
||||||
const retrieveData = async (errors : string[]) => {
|
const retrieveData = async (errors : string[]) => {
|
||||||
await store.dispatch('ensureContinents')
|
|
||||||
const profileResult = await api.profile.retreive(undefined, user)
|
const profileResult = await api.profile.retreive(undefined, user)
|
||||||
if (typeof profileResult === 'string') {
|
if (typeof profileResult === 'string') {
|
||||||
errors.push(profileResult)
|
errors.push(profileResult)
|
||||||
|
@ -201,21 +196,6 @@ export default defineComponent({
|
||||||
profile.realName = typeof nameResult !== 'undefined' ? (nameResult as Citizen).realName || '' : ''
|
profile.realName = typeof nameResult !== 'undefined' ? (nameResult as Citizen).realName || '' : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark the continent field as changed
|
|
||||||
*
|
|
||||||
* (This works around a really strange sequence where, if the "touch" call is directly wired up to the onChange
|
|
||||||
* event, the first time a value is selected, it doesn't stick (although the field is marked as touched). On second
|
|
||||||
* and subsequent times, it worked. The solution here is to grab the value and update the reactive source for the
|
|
||||||
* form, then manually set the field to touched; this restores the expected behavior. This is probably why the
|
|
||||||
* library doesn't hook into the onChange event to begin with...)
|
|
||||||
*/
|
|
||||||
const continentChanged = (e : Event) : boolean => {
|
|
||||||
profile.continentId = (e.target as HTMLSelectElement).value
|
|
||||||
v$.value.continentId.$touch()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The ID for new skills */
|
/** The ID for new skills */
|
||||||
let newSkillId = 0
|
let newSkillId = 0
|
||||||
|
|
||||||
|
@ -266,8 +246,6 @@ export default defineComponent({
|
||||||
user,
|
user,
|
||||||
isNew,
|
isNew,
|
||||||
profile,
|
profile,
|
||||||
continents: computed(() => store.state.continents),
|
|
||||||
continentChanged,
|
|
||||||
addSkill,
|
addSkill,
|
||||||
removeSkill,
|
removeSkill,
|
||||||
saveProfile,
|
saveProfile,
|
||||||
|
|
|
@ -77,7 +77,7 @@ export default defineComponent({
|
||||||
|
|
||||||
/** An empty set of search criteria */
|
/** An empty set of search criteria */
|
||||||
const emptyCriteria = {
|
const emptyCriteria = {
|
||||||
continentId: undefined,
|
continentId: '',
|
||||||
skill: undefined,
|
skill: undefined,
|
||||||
bioExperience: undefined,
|
bioExperience: undefined,
|
||||||
remoteWork: ''
|
remoteWork: ''
|
||||||
|
@ -98,8 +98,10 @@ export default defineComponent({
|
||||||
searched.value = true
|
searched.value = true
|
||||||
try {
|
try {
|
||||||
searching.value = true
|
searching.value = true
|
||||||
|
// Hold variable for ensuring continent ID is not undefined here, but excluded from search payload
|
||||||
|
const contId = queryValue(route, 'continentId')
|
||||||
const searchParams : ProfileSearch = {
|
const searchParams : ProfileSearch = {
|
||||||
continentId: queryValue(route, 'continentId'),
|
continentId: contId === '' ? undefined : contId,
|
||||||
skill: queryValue(route, 'skill'),
|
skill: queryValue(route, 'skill'),
|
||||||
bioExperience: queryValue(route, 'bioExperience'),
|
bioExperience: queryValue(route, 'bioExperience'),
|
||||||
remoteWork: queryValue(route, 'remoteWork') || ''
|
remoteWork: queryValue(route, 'remoteWork') || ''
|
||||||
|
@ -111,6 +113,7 @@ export default defineComponent({
|
||||||
errors.value.push('The server returned a "Not Found" response (this should not happen)')
|
errors.value.push('The server returned a "Not Found" response (this should not happen)')
|
||||||
} else {
|
} else {
|
||||||
results.value = searchResult
|
results.value = searchResult
|
||||||
|
searchParams.continentId = searchParams.continentId || ''
|
||||||
criteria.value = searchParams
|
criteria.value = searchParams
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default defineComponent({
|
||||||
|
|
||||||
/** An empty set of search criteria */
|
/** An empty set of search criteria */
|
||||||
const emptyCriteria = {
|
const emptyCriteria = {
|
||||||
continentId: undefined,
|
continentId: '',
|
||||||
region: undefined,
|
region: undefined,
|
||||||
skill: undefined,
|
skill: undefined,
|
||||||
remoteWork: ''
|
remoteWork: ''
|
||||||
|
@ -97,8 +97,9 @@ export default defineComponent({
|
||||||
searched.value = true
|
searched.value = true
|
||||||
try {
|
try {
|
||||||
searching.value = true
|
searching.value = true
|
||||||
|
const contId = queryValue(route, 'continentId')
|
||||||
const searchParams : PublicSearch = {
|
const searchParams : PublicSearch = {
|
||||||
continentId: queryValue(route, 'continentId'),
|
continentId: contId === '' ? undefined : contId,
|
||||||
region: queryValue(route, 'region'),
|
region: queryValue(route, 'region'),
|
||||||
skill: queryValue(route, 'skill'),
|
skill: queryValue(route, 'skill'),
|
||||||
remoteWork: queryValue(route, 'remoteWork') || ''
|
remoteWork: queryValue(route, 'remoteWork') || ''
|
||||||
|
@ -110,6 +111,7 @@ export default defineComponent({
|
||||||
errors.value.push('The server returned a "Not Found" response (this should not happen)')
|
errors.value.push('The server returned a "Not Found" response (this should not happen)')
|
||||||
} else {
|
} else {
|
||||||
results.value = searchResult
|
results.value = searchResult
|
||||||
|
searchParams.continentId = searchParams.continentId || ''
|
||||||
criteria.value = searchParams
|
criteria.value = searchParams
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user