fix: add/remove field & update columns

This commit is contained in:
Shariq Ansari 2024-12-29 18:45:01 +05:30
parent 721c5321e3
commit 625b8cc4fe
3 changed files with 53 additions and 23 deletions

View File

@ -19,31 +19,37 @@
{{ __('Fields Order') }} {{ __('Fields Order') }}
</div> </div>
<Draggable <Draggable
v-if="oldFields.length" v-if="oldFields?.length"
:list="fields" :list="fields"
@end="reorder" @end="reorder"
group="fields" group="fields"
item-key="name" item-key="fieldname"
class="flex flex-col gap-1" class="flex flex-col gap-1"
> >
<template #item="{ element: field }"> <template #item="{ element: field }">
<div <div
class="px-1 py-0.5 border border-outline-gray-modals rounded text-base text-ink-gray-8 flex items-center justify-between gap-2" class="px-1 py-0.5 bg-surface-gray-2 border border-outline-gray-modals rounded text-base text-ink-gray-8 flex items-center justify-between gap-2"
> >
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<DragVerticalIcon class="h-3.5 cursor-grab" /> <DragVerticalIcon class="h-3.5 cursor-grab" />
<div>{{ field.label }}</div> <div>{{ field.label }}</div>
</div> </div>
<div> <div class="flex items-center gap-2">
<TextInput
variant="outline"
type="number"
v-model="field.columns"
class="w-20"
/>
<Button variant="ghost" icon="x" @click="removeField(field)" /> <Button variant="ghost" icon="x" @click="removeField(field)" />
</div> </div>
</div> </div>
</template> </template>
</Draggable> </Draggable>
<Autocomplete <Autocomplete
v-if="fields" v-if="dropdownFields?.length"
value="" value=""
:options="fields" :options="dropdownFields"
@change="(e) => addField(e)" @change="(e) => addField(e)"
> >
<template #target="{ togglePopover }"> <template #target="{ togglePopover }">
@ -58,7 +64,7 @@
</Button> </Button>
</template> </template>
<template #item-label="{ option }"> <template #item-label="{ option }">
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1 text-ink-gray-9">
<div>{{ option.label }}</div> <div>{{ option.label }}</div>
<div class="text-ink-gray-4 text-sm"> <div class="text-ink-gray-4 text-sm">
{{ `${option.fieldname} - ${option.fieldtype}` }} {{ `${option.fieldname} - ${option.fieldtype}` }}
@ -66,6 +72,7 @@
</div> </div>
</template> </template>
</Autocomplete> </Autocomplete>
<ErrorMessage class="mt-3" v-if="error" :message="error" />
</div> </div>
</template> </template>
<template #actions> <template #actions>
@ -89,10 +96,11 @@
</Dialog> </Dialog>
</template> </template>
<script setup> <script setup>
import DragVerticalIcon from '@/components/Icons/DragVerticalIcon.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue' import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import { getMeta } from '@/stores/meta' import { getMeta } from '@/stores/meta'
import Draggable from 'vuedraggable' import Draggable from 'vuedraggable'
import { Dialog } from 'frappe-ui' import { Dialog, ErrorMessage } from 'frappe-ui'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
const props = defineProps({ const props = defineProps({
@ -107,6 +115,7 @@ const { userSettings, getFields, getGridSettings, saveUserSettings } = getMeta(
const show = defineModel() const show = defineModel()
const loading = ref(false) const loading = ref(false)
const error = ref(null)
const dirty = computed(() => { const dirty = computed(() => {
return JSON.stringify(fields.value) !== JSON.stringify(oldFields.value) return JSON.stringify(fields.value) !== JSON.stringify(oldFields.value)
@ -118,41 +127,67 @@ const oldFields = computed(() => {
if (gridSettings.length) { if (gridSettings.length) {
return gridSettings.map((field) => { return gridSettings.map((field) => {
return _fields.find((f) => f.fieldname === field.fieldname) let f = _fields.find((f) => f.fieldname === field.fieldname)
if (f) {
f.columns = field.columns
return fieldObj(f)
}
}) })
} }
return _fields?.filter((field) => field.in_list_view) return _fields?.filter((field) => field.in_list_view).map((f) => fieldObj(f))
}) })
const fields = ref(JSON.parse(JSON.stringify(oldFields.value)) || []) const fields = ref(JSON.parse(JSON.stringify(oldFields.value || [])))
const dropdownFields = computed(() => {
return getFields()?.filter(
(field) => !fields.value.find((f) => f.fieldname === field.fieldname),
)
})
function reset() { function reset() {
fields.value = JSON.parse(JSON.stringify(oldFields.value)) fields.value = JSON.parse(JSON.stringify(oldFields.value || []))
} }
function addField(field) { function addField(field) {
fields.value.push(field) fields.value.push(fieldObj(field))
} }
function removeField(field) { function removeField(field) {
const index = fields.value.findIndex((f) => f.name === field.name) const index = fields.value.findIndex((f) => f.fieldname === field.fieldname)
fields.value.splice(index, 1) fields.value.splice(index, 1)
} }
const update = () => { function update() {
loading.value = true loading.value = true
let updateFields = fields.value.map((field, idx) => { let updateFields = fields.value.map((field, idx) => {
return { return {
fieldname: field.fieldname, fieldname: field.fieldname,
columns: 2, columns: field.columns,
} }
}) })
if (updateFields.length === 0) {
error.value = __('At least one field is required')
return
}
saveUserSettings(props.parentDoctype, 'GridView', updateFields, () => { saveUserSettings(props.parentDoctype, 'GridView', updateFields, () => {
loading.value = false loading.value = false
show.value = false show.value = false
userSettings.value['GridView'][props.doctype] = updateFields userSettings.value['GridView'][props.doctype] = updateFields
}) })
} }
function fieldObj(field) {
return {
label: field.label,
fieldname: field.fieldname,
fieldtype: field.fieldtype,
options: field.options,
in_list_view: field.in_list_view,
columns: field.columns || 2,
}
}
</script> </script>

View File

@ -89,7 +89,7 @@
</Button> </Button>
</template> </template>
<template #item-label="{ option }"> <template #item-label="{ option }">
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1 text-ink-gray-9">
<div>{{ option.label }}</div> <div>{{ option.label }}</div>
<div class="text-ink-gray-4 text-sm"> <div class="text-ink-gray-4 text-sm">
{{ `${option.fieldname} - ${option.fieldtype}` }} {{ `${option.fieldname} - ${option.fieldtype}` }}

View File

@ -80,12 +80,7 @@ export function getMeta(doctype) {
let oldUserSettings = userSettings.value let oldUserSettings = userSettings.value
let newUserSettings = JSON.parse(JSON.stringify(oldUserSettings)) let newUserSettings = JSON.parse(JSON.stringify(oldUserSettings))
if (typeof value === 'object') { newUserSettings[key][doctype] = value
newUserSettings[key][doctype] = newUserSettings[key][doctype] || {}
Object.assign(newUserSettings[key][doctype], value)
} else {
newUserSettings[key][doctype] = value
}
if (JSON.stringify(oldUserSettings) !== JSON.stringify(newUserSettings)) { if (JSON.stringify(oldUserSettings) !== JSON.stringify(newUserSettings)) {
return createResource({ return createResource({