fix: removed old sort logic similar to filter and added new way to sort and save
This commit is contained in:
parent
fc4c144abe
commit
ffe942d80f
@ -3,29 +3,29 @@
|
||||
<template #target>
|
||||
<Button label="Sort" ref="sortButtonRef">
|
||||
<template #prefix><SortIcon class="h-4" /></template>
|
||||
<template v-if="sortValues.length" #suffix>
|
||||
<template v-if="sortValues?.size" #suffix>
|
||||
<div
|
||||
class="flex justify-center items-center w-5 h-5 text-2xs font-medium pt-[1px] bg-gray-900 text-white rounded"
|
||||
class="flex h-5 w-5 items-center justify-center rounded bg-gray-900 pt-[1px] text-2xs font-medium text-white"
|
||||
>
|
||||
{{ sortValues.length }}
|
||||
{{ sortValues.size }}
|
||||
</div>
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
<template #body="{ close }">
|
||||
<div class="rounded-lg border border-gray-100 bg-white shadow-xl my-2">
|
||||
<div class="p-2 min-w-[352px]">
|
||||
<div class="my-2 rounded-lg border border-gray-100 bg-white shadow-xl">
|
||||
<div class="min-w-[352px] p-2">
|
||||
<div
|
||||
v-if="sortValues.length"
|
||||
v-if="sortValues?.size"
|
||||
id="sort-list"
|
||||
class="flex flex-col gap-2 mb-3"
|
||||
class="mb-3 flex flex-col gap-2"
|
||||
>
|
||||
<div
|
||||
v-for="(sort, i) in sortValues"
|
||||
:key="sort.fieldname"
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<div class="flex items-center justify-center h-7 w-7 handle">
|
||||
<div class="handle flex h-7 w-7 items-center justify-center">
|
||||
<DragIcon class="h-4 w-4 cursor-grab text-gray-600" />
|
||||
</div>
|
||||
<Autocomplete
|
||||
@ -38,11 +38,17 @@
|
||||
<FormControl
|
||||
class="!w-32"
|
||||
type="select"
|
||||
v-model="sort.direction"
|
||||
:value="sort.direction"
|
||||
:options="[
|
||||
{ label: 'Ascending', value: 'asc' },
|
||||
{ label: 'Descending', value: 'desc' },
|
||||
]"
|
||||
@change="
|
||||
(e) => {
|
||||
sort.direction = e.target.value
|
||||
apply()
|
||||
}
|
||||
"
|
||||
placeholder="Sort by"
|
||||
/>
|
||||
<Button variant="ghost" icon="x" @click="removeSort(i)" />
|
||||
@ -50,7 +56,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="text-gray-600 flex items-center text-sm px-3 h-7 mb-3"
|
||||
class="mb-3 flex h-7 items-center px-3 text-sm text-gray-600"
|
||||
>
|
||||
Empty - Choose a field to sort by
|
||||
</div>
|
||||
@ -75,7 +81,7 @@
|
||||
</template>
|
||||
</Autocomplete>
|
||||
<Button
|
||||
v-if="sortValues.length"
|
||||
v-if="sortValues?.size"
|
||||
class="!text-gray-600"
|
||||
variant="ghost"
|
||||
label="Clear Sort"
|
||||
@ -93,7 +99,6 @@ import NestedPopover from '@/components/NestedPopover.vue'
|
||||
import SortIcon from '@/components/Icons/SortIcon.vue'
|
||||
import DragIcon from '@/components/Icons/DragIcon.vue'
|
||||
import { useSortable } from '@vueuse/integrations/useSortable'
|
||||
import { useOrderBy } from '@/composables/orderby'
|
||||
import {
|
||||
FeatherIcon,
|
||||
Button,
|
||||
@ -101,7 +106,7 @@ import {
|
||||
FormControl,
|
||||
createResource,
|
||||
} from 'frappe-ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
doctype: {
|
||||
@ -110,10 +115,10 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const { get: getOrderBy, set: setOrderBy } = useOrderBy()
|
||||
const emit = defineEmits(['update'])
|
||||
const list = defineModel()
|
||||
|
||||
const sortButtonRef = ref(null)
|
||||
const sortValues = ref(initialOrderBy())
|
||||
|
||||
const sortOptions = createResource({
|
||||
url: 'crm.api.doc.sort_options',
|
||||
@ -123,75 +128,83 @@ const sortOptions = createResource({
|
||||
},
|
||||
})
|
||||
|
||||
const sortValues = computed({
|
||||
get: () => {
|
||||
if (!list.value?.data) return new Set()
|
||||
let allSortValues = list.value?.params?.order_by
|
||||
if (!allSortValues || !sortOptions.data) return new Set()
|
||||
if (allSortValues.trim() === 'modified desc') return new Set()
|
||||
allSortValues = allSortValues.split(', ').map((sortValue) => {
|
||||
const [fieldname, direction] = sortValue.split(' ')
|
||||
return { fieldname, direction }
|
||||
})
|
||||
return new Set(allSortValues)
|
||||
},
|
||||
set: (value) => {
|
||||
list.value.params.order_by = convertToString(value)
|
||||
},
|
||||
})
|
||||
|
||||
const options = computed(() => {
|
||||
if (!sortOptions.data) return []
|
||||
const selectedOptions = sortValues.value.map((sort) => sort.fieldname)
|
||||
if (!sortValues.value.size) return sortOptions.data
|
||||
const selectedOptions = [...sortValues.value].map((sort) => sort.fieldname)
|
||||
restartSort()
|
||||
return sortOptions.data.filter((option) => {
|
||||
return !selectedOptions.includes(option.value)
|
||||
})
|
||||
})
|
||||
|
||||
function initialOrderBy() {
|
||||
const orderBy = getOrderBy()
|
||||
if (!orderBy) return []
|
||||
const sortOptions = orderBy.split(', ')
|
||||
return sortOptions.map((sortOption) => {
|
||||
const [fieldname, direction] = sortOption.split(' ')
|
||||
return { fieldname, direction }
|
||||
})
|
||||
}
|
||||
|
||||
const sortSortable = useSortable('#sort-list', sortValues, {
|
||||
handle: '.handle',
|
||||
animation: 200,
|
||||
onEnd: () => apply(),
|
||||
})
|
||||
|
||||
watch(
|
||||
() => sortValues.value,
|
||||
(value) => {
|
||||
const updatedSort = value
|
||||
.map((sort) => {
|
||||
const option = sortOptions.data.find((o) => o.value === sort.fieldname)
|
||||
return `${option.value} ${sort.direction}`
|
||||
})
|
||||
.join(', ')
|
||||
setOrderBy(updatedSort)
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => getOrderBy(),
|
||||
(value) => {
|
||||
if (!value) {
|
||||
sortValues.value = []
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function setSort(data) {
|
||||
sortValues.value = [
|
||||
...sortValues.value,
|
||||
{ fieldname: data.value, direction: 'asc' },
|
||||
]
|
||||
sortSortable.start()
|
||||
sortValues.value.add({ fieldname: data.value, direction: 'asc' })
|
||||
restartSort()
|
||||
apply()
|
||||
}
|
||||
|
||||
function updateSort(data, index) {
|
||||
sortValues.value[index] = {
|
||||
let oldSort = Array.from(sortValues.value)[index]
|
||||
sortValues.value.delete(oldSort)
|
||||
sortValues.value.add({
|
||||
fieldname: data.value,
|
||||
direction: sortValues.value[index].direction,
|
||||
}
|
||||
direction: oldSort.direction,
|
||||
})
|
||||
apply()
|
||||
}
|
||||
|
||||
function removeSort(index) {
|
||||
sortValues.value.splice(index, 1)
|
||||
sortValues.value.delete(Array.from(sortValues.value)[index])
|
||||
apply()
|
||||
}
|
||||
|
||||
function clearSort(close) {
|
||||
sortValues.value = []
|
||||
sortValues.value.clear()
|
||||
apply()
|
||||
close()
|
||||
}
|
||||
|
||||
function apply() {
|
||||
nextTick(() => {
|
||||
emit('update', convertToString(sortValues.value))
|
||||
})
|
||||
}
|
||||
|
||||
function convertToString(values) {
|
||||
let _sortValues = ''
|
||||
values.forEach((f) => {
|
||||
_sortValues += `${f.fieldname} ${f.direction}, `
|
||||
})
|
||||
_sortValues = _sortValues.slice(0, -2)
|
||||
return _sortValues
|
||||
}
|
||||
|
||||
function restartSort() {
|
||||
sortSortable.stop()
|
||||
sortSortable.start()
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
export function useOrderBy() {
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
function get() {
|
||||
const q = route.query.sort ?? ''
|
||||
const d = decodeURIComponent(q)
|
||||
return d
|
||||
}
|
||||
|
||||
function set(sort, r) {
|
||||
r = r || route
|
||||
const q = encodeURIComponent(sort)
|
||||
router.push({ ...r, query: { ...r.query, sort: q } })
|
||||
}
|
||||
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user