1
0
forked from test/crm

fix: removed old sort logic similar to filter and added new way to sort and save

This commit is contained in:
Shariq Ansari 2023-12-31 17:50:46 +05:30
parent fc4c144abe
commit ffe942d80f
2 changed files with 74 additions and 84 deletions

View File

@ -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>

View File

@ -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,
}
}