Skip to content
Snippets Groups Projects
Commit 0ab11f53 authored by simon.mellerin's avatar simon.mellerin
Browse files

OcMultipleField OcMultilingualField - refacto

parent 306ea4f4
Branches develop
No related tags found
1 merge request!57#52 - Dataset form + OcMultipleField + OcMultinlingualField
Pipeline #10635 passed
......@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3';
import OcMultilingualField from './OcMultilingualField.vue';
import InputText from 'primevue/inputtext';
import Textarea from 'primevue/textarea';
import { ref } from 'vue';
const meta: Meta<typeof OcMultilingualField> = {
component: OcMultilingualField,
......@@ -15,25 +16,51 @@ export const Default: Story = {
render: (args) => ({
components: { OcMultilingualField, InputText },
setup() {
const value = ref({
fr: 'test 1',
en: 'test 2',
})
return {
args,
value
};
},
template: `
<OcMultilingualField v-bind="args"/>
<OcMultilingualField v-bind="args" :initialValue="value" @updateValue="value = $event"/>
<ul class="mt-4">
<li v-for="(content, locale) of value" :key="locale">
{{ locale }} : {{ content }}
</li>
</ul>
`,
}),
args: {
'modelValue': {
fr: 'test 1',
en: 'test 2',
},
id: 'test-default',
inputComponent: InputText,
inputProps: { fluid: true },
},
};
export const withoutInitialValue: Story = {
render: (args) => ({
components: { OcMultilingualField, InputText },
setup() {
return {
args,
};
},
template: `
<OcMultilingualField v-bind="args"/>
`,
}),
args: {
id: 'test-without-initial-value',
inputComponent: InputText,
inputProps: { fluid: true },
},
};
export const TextArea: Story = {
render: (args) => ({
components: { OcMultilingualField, InputText },
......@@ -47,7 +74,7 @@ export const TextArea: Story = {
`,
}),
args: {
'modelValue': {
initialValue: {
fr: 'test 1',
en: 'test 2',
},
......
......@@ -17,20 +17,20 @@
<i class="fa-solid fa-globe"></i>
</InputGroupAddon>
<Select
:modelValue="values[key].code"
:modelValue="values[key].locale"
:options="languageList"
:optionLabel="(locale: any) => locale.label"
:optionValue="(locale: any) => locale.code"
:optionDisabled="
(item: any) =>
item.code !== values[key].code &&
values.map((item) => item.code).includes(item.code)
item.code !== values[key].locale &&
values.map((item) => item.locale).includes(item.code)
"
@update:model-value="handleLocaleChange($event, key)"
filter
:virtualScrollerOptions="{ itemSize: 20 }"
:loading="loadingLanguage"
:invalid="!values[key].code || values[key].code === '@none'"
:invalid="!values[key].locale || values[key].locale === '@none'"
/>
</InputGroup>
<component
......@@ -49,7 +49,7 @@
:label="t('add')"
outlined
size="Small"
@click="values.push({ code: null, value: null })"
@click="values.push({ locale: null, value: null })"
/>
</div>
</template>
......@@ -70,16 +70,19 @@ import InputGroup from 'primevue/inputgroup'
const { t, locale } = useI18n()
const { translateValue } = useTranslateValue()
const model = defineModel<LocalizedProperty<any> | undefined>({ required: true })
const values = ref<{ code: string | null; value: any | any[] }[]>([
{ code: locale.value, value: null }
const values = ref<{ locale: string | null; value: any | any[] }[]>([
{ locale: locale.value, value: null }
])
defineProps({
const props = defineProps({
id: {
type: String,
required: true
},
initialValue: {
type: Object as PropType<LocalizedProperty<any>>,
require: false
},
inputComponent: {
type: Object as PropType<Component>,
required: true
......@@ -92,23 +95,22 @@ defineProps({
}
})
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits<{
updateValue: [value: LocalizedProperty<any>]
}>()
const rawLanguageList = ref<OcLocale[]>([])
const loadingLanguage = ref(false)
const valuesFromModel = () => {
if (model.value && Object.keys(model.value).length) {
values.value = Object.entries<LocalizedProperty<any>>(model.value).map(([locale, value]) => {
return { code: locale, value: value }
onMounted(async () => {
// Initialize value
if (props.initialValue && Object.keys(props.initialValue).length) {
values.value = Object.entries(props.initialValue).map(([locale, value]) => {
return { locale: locale, value: value }
})
} else {
values.value = [{ code: locale.value, value: null }]
values.value = [{ locale: locale.value, value: null }]
}
}
onMounted(async () => {
valuesFromModel()
loadingLanguage.value = true
rawLanguageList.value = await getLocaleList()
......@@ -123,32 +125,29 @@ const languageList = computed(() =>
.sort((a, b) => (a.label > b.label ? 1 : -1))
)
const updateModel = () => {
if (model.value) {
for (const prop of Object.keys(model.value)) {
delete model.value[prop]
}
} else {
model.value = {}
}
const updateValue = () => {
const updated: LocalizedProperty<any> = {}
for (const item of values.value) {
model.value[item.code ?? '@none'] = item.value
if (item.value) {
updated[item.locale ?? '@none'] = item.value
}
}
emit('update:modelValue', model.value)
emit('updateValue', updated)
}
function handleLocaleChange(newCode: string, key: number) {
values.value[key].code = newCode
updateModel()
function handleLocaleChange(newLocale: string, key: number) {
values.value[key].locale = newLocale
updateValue()
}
function handleValueChange(newValue: any, key: number) {
values.value[key].value = newValue
updateModel()
updateValue()
}
function removeValue(key: number) {
values.value.splice(key, 1)
updateModel()
updateValue()
}
</script>
......@@ -4,6 +4,7 @@ import OcMultipleField from './OcMultipleField.vue';
import InputText from 'primevue/inputtext';
import DatePicker from 'primevue/datepicker';
import Textarea from 'primevue/textarea';
import { ref } from 'vue';
const meta: Meta<typeof OcMultipleField> = {
component: OcMultipleField,
......@@ -16,19 +17,25 @@ export const Default: Story = {
render: (args) => ({
components: { OcMultipleField, InputText },
setup() {
const value = ref([
'test 1',
'test 2',
])
return {
args,
value
};
},
template: `
<OcMultipleField v-bind="args"/>
<OcMultipleField v-bind="args" :initialValue="value" @updateValue="value = $event"/>
<ul class="mt-4">
<li v-for="(content, key) of value" :key="key">
{{ key }} : {{ content }}
</li>
</ul>
`,
}),
args: {
modelValue: [
'test 1',
'test 2',
],
id: 'test-default',
inputComponent: InputText,
inputProps: { fluid: true },
......@@ -48,7 +55,7 @@ export const DateRange: Story = {
`,
}),
args: {
modelValue: [
initialValue: [
[new Date("2024-10-02T00:00:00.000"), new Date("2024-10-11T00:00:00.000")]
],
id: 'test-daterange',
......@@ -74,7 +81,7 @@ export const TextArea: Story = {
`,
}),
args: {
modelValue: [
initialValue: [
'some text about something 1',
'some text about something 2',
'some text about something 3',
......
......@@ -39,16 +39,17 @@ import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const model = defineModel<any[] | undefined>({ required: true })
const values = ref<any[]>([])
const emit = defineEmits(['update:modelValue'])
defineProps({
const props = defineProps({
id: {
type: String,
required: true
},
initialValue: {
type: Object as PropType<any[]>,
require: false
},
inputComponent: {
type: Object as PropType<Component>,
required: true
......@@ -61,36 +62,34 @@ defineProps({
}
})
const emit = defineEmits<{
updateValue: [value: any[]]
}>()
onMounted(() => {
if (model.value) {
values.value = [...model.value]
if (props.initialValue) {
values.value = [...props.initialValue]
} else {
values.value = [null]
}
})
const updateModel = () => {
if (model.value !== undefined) {
model.value.splice(0, model.value.length)
} else {
model.value = []
}
for (const item of values.value) {
if (item) {
model.value.push(item)
}
}
emit('update:modelValue', model.value)
const updateValue = () => {
emit(
'updateValue',
values.value.filter((item) => !!item)
)
}
function handleChange(newValue: any, key: number) {
values.value[key] = newValue
updateModel()
updateValue()
}
function removeValue(key: number) {
values.value.splice(key, 1)
updateModel()
updateValue()
}
</script>
......@@ -19,8 +19,8 @@
<OcField for="title" :metadata="datasetMetadata.title">
<OcMultilingualField
id="title"
:modelValue="value"
@update:modelValue="handleChange"
:initial-value="value"
@updateValue="handleChange"
:inputComponent="InputText"
:inputProps="{ invalid: !!errorMessage, required: true, fluid: true }"
/>
......@@ -31,8 +31,8 @@
<OcField for="description" :metadata="datasetMetadata.description">
<OcMultilingualField
id="description"
:model-value="value"
@update:model-value="handleChange"
:initial-value="value"
@updateValue="handleChange"
:inputComponent="Textarea"
:inputProps="{ invalid: !!errorMessage, required: true, fluid: true }"
/>
......@@ -112,8 +112,8 @@
<OcField for="keyword" :metadata="datasetMetadata.keyword">
<OcMultilingualField
id="keyword"
:model-value="value"
@update:model-value="handleChange"
:initial-value="value"
@updateValue="handleChange"
:inputComponent="OcKeywordAutocomplete"
:inputProps="{ invalid: !!errorMessage, required: true, fluid: true }"
/>
......@@ -171,8 +171,8 @@
<OcField for="temporal" :metadata="datasetMetadata.temporal">
<OcMultipleField
id="temporal"
:model-value="value"
@update:model-value="handleChange"
:initial-value="value"
@updateValue="handleChange"
:inputComponent="DatePicker"
:inputProps="{
selectionMode: 'range',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment