Browse Source

feat(nc-gui): collapse stack logic

pull/3818/head
Wing-Kam Wong 2 years ago
parent
commit
5125a5e2b5
  1. 22
      packages/nc-gui/components/smartsheet/Kanban.vue
  2. 39
      packages/nc-gui/composables/useKanbanViewData.ts

22
packages/nc-gui/components/smartsheet/Kanban.vue

@ -50,8 +50,8 @@ const {
updateKanbanMeta, updateKanbanMeta,
addEmptyRow, addEmptyRow,
groupingFieldColOptions, groupingFieldColOptions,
updateKanbanStackMeta,
groupingField, groupingField,
groupingFieldColumn,
countByStack, countByStack,
deleteStack, deleteStack,
} = useKanbanViewData(meta, view as any) } = useKanbanViewData(meta, view as any)
@ -187,8 +187,9 @@ const handleDeleteStackConfirmClick = async () => {
deleteStackVModel.value = false deleteStackVModel.value = false
} }
const collapseStack = () => { const handleCollapseStack = async (stackIdx: number) => {
// TODO: groupingFieldColOptions.value[stackIdx].collapsed = !groupingFieldColOptions.value[stackIdx].collapsed
await updateKanbanStackMeta()
} }
const renameStack = () => { const renameStack = () => {
@ -218,7 +219,7 @@ openNewRecordFormHook?.on(async (stackTitle) => {
:move="onMoveCallback" :move="onMoveCallback"
@change="onMoveStack($event)" @change="onMoveStack($event)"
> >
<template #item="{ element: stack, index }"> <template #item="{ element: stack, index: stackIdx }">
<a-skeleton v-if="!formattedData[stack.title] || !countByStack" class="p-4" /> <a-skeleton v-if="!formattedData[stack.title] || !countByStack" class="p-4" />
<div v-else class="nc-kanban-stack" :class="{ 'w-[50px]': stack.collapsed }"> <div v-else class="nc-kanban-stack" :class="{ 'w-[50px]': stack.collapsed }">
<a-card <a-card
@ -248,7 +249,7 @@ openNewRecordFormHook?.on(async (stackTitle) => {
Add new record Add new record
</div> </div>
</a-menu-item> </a-menu-item>
<a-menu-item @click="collapseStack"> <a-menu-item @click="handleCollapseStack(stackIdx)">
<div class="py-2 flex gap-2 items-center"> <div class="py-2 flex gap-2 items-center">
<mdi-arrow-collapse class="text-gray-500" /> <mdi-arrow-collapse class="text-gray-500" />
<!-- TODO: i18n --> <!-- TODO: i18n -->
@ -376,13 +377,14 @@ openNewRecordFormHook?.on(async (stackTitle) => {
</a-card> </a-card>
<a-card <a-card
v-else v-else
:key="stack.id" :key="`${stack.id}-collapsed`"
class="nc-kanban-stack nc-kanban-collapsed-stack mx-4 flex !bg-[#f0f2f5] items-center w-[300px] h-[50px] rounded-[12px]" class="nc-kanban-stack nc-kanban-collapsed-stack mx-4 flex !bg-[#f0f2f5] items-center w-[300px] h-[50px] rounded-[12px] cursor-pointer"
:class="{ 'not-draggable': stack.id === 'uncategorized' }" :class="{ 'not-draggable': stack.id === 'uncategorized' }"
:body-style="'width: 100%;'" body-style="padding: 0px; height: 100%; width: 100%;"
> >
<div class="items-center justify-between"> <div class="items-center justify-between" @click="handleCollapseStack(stackIdx)">
<div class="nc-kanban-data-count"> <div :style="`background-color: ${stack.color}`" class="nc-kanban-stack-head-color h-[10px]"></div>
<div class="nc-kanban-data-count mt-[7px] mx-[10px]">
<div class="float-right flex gap-2 items-center cursor-pointer"> <div class="float-right flex gap-2 items-center cursor-pointer">
<GeneralTruncateText>{{ stack.title }}</GeneralTruncateText> <GeneralTruncateText>{{ stack.title }}</GeneralTruncateText>
<mdi-menu-down class="text-grey text-lg" /> <mdi-menu-down class="text-grey text-lg" />

39
packages/nc-gui/composables/useKanbanViewData.ts

@ -36,6 +36,7 @@ export function useKanbanViewData(
const countByStack = useState<Record<string, number>>('KanbanCountByStack', () => ({})) const countByStack = useState<Record<string, number>>('KanbanCountByStack', () => ({}))
const groupingField = useState<string>('KanbanGroupingField', () => '') const groupingField = useState<string>('KanbanGroupingField', () => '')
const groupingFieldColumn = useState<Record<string, any>>('KanbanGroupingFieldColumn', () => ({})) const groupingFieldColumn = useState<Record<string, any>>('KanbanGroupingFieldColumn', () => ({}))
const stackMetaObj = ref<Record<string, any>>({})
const formatData = (list: Record<string, any>[]) => const formatData = (list: Record<string, any>[]) =>
list.map((row) => ({ list.map((row) => ({
@ -89,22 +90,27 @@ export function useKanbanViewData(
const { grp_column_id, stack_meta } = kanbanMetaData.value const { grp_column_id, stack_meta } = kanbanMetaData.value
const stackMetaObj = stack_meta ? JSON.parse(stack_meta as string) : {} stackMetaObj.value = stack_meta ? JSON.parse(stack_meta as string) : {}
if (stackMetaObj && grp_column_id && stackMetaObj[grp_column_id] && groupingFieldColumn.value?.colOptions?.options) { if (
stackMetaObj.value &&
grp_column_id &&
stackMetaObj.value[grp_column_id] &&
groupingFieldColumn.value?.colOptions?.options
) {
// keep the existing order (index of the array) but update the values // keep the existing order (index of the array) but update the values
for (const option of groupingFieldColumn.value.colOptions.options) { for (const option of groupingFieldColumn.value.colOptions.options) {
const idx = stackMetaObj[grp_column_id].findIndex((ele: Record<string, any>) => ele.id === option.id) const idx = stackMetaObj.value[grp_column_id].findIndex((ele: Record<string, any>) => ele.id === option.id)
if (idx !== -1) { if (idx !== -1) {
// update the option in stackMetaObj // update the option in stackMetaObj
stackMetaObj[grp_column_id][idx] = { stackMetaObj.value[grp_column_id][idx] = {
...stackMetaObj[grp_column_id][idx], ...stackMetaObj.value[grp_column_id][idx],
...option, ...option,
} }
} else { } else {
// new option found // new option found
const len = stackMetaObj[grp_column_id].length const len = stackMetaObj.value[grp_column_id].length
stackMetaObj[grp_column_id][len] = { stackMetaObj.value[grp_column_id][len] = {
...option, ...option,
collapsed: false, collapsed: false,
} }
@ -112,15 +118,15 @@ export function useKanbanViewData(
} }
// handle deleted options // handle deleted options
const columnOptionIds = groupingFieldColumn.value.colOptions.options.map(({ id }) => id) const columnOptionIds = groupingFieldColumn.value.colOptions.options.map(({ id }) => id)
stackMetaObj[grp_column_id] stackMetaObj.value[grp_column_id]
.filter(({ id }) => id !== 'uncategorized' && !columnOptionIds.includes(id)) .filter(({ id }) => id !== 'uncategorized' && !columnOptionIds.includes(id))
.forEach(({ id }) => { .forEach(({ id }) => {
const idx = stackMetaObj[grp_column_id].map((ele: Record<string, any>) => ele.id).indexOf(id) const idx = stackMetaObj.value[grp_column_id].map((ele: Record<string, any>) => ele.id).indexOf(id)
if (idx !== -1) { if (idx !== -1) {
stackMetaObj[grp_column_id].splice(idx, 1) stackMetaObj.value[grp_column_id].splice(idx, 1)
} }
}) })
groupingFieldColOptions.value = stackMetaObj[grp_column_id] groupingFieldColOptions.value = stackMetaObj.value[grp_column_id]
} else { } else {
// build stack meta // build stack meta
groupingFieldColOptions.value = [ groupingFieldColOptions.value = [
@ -136,11 +142,15 @@ export function useKanbanViewData(
collapsed: false, collapsed: false,
})) }))
} }
// if grouping column id is present, add the grouping field column options to stackMetaObj await updateKanbanStackMeta()
}
async function updateKanbanStackMeta() {
const { grp_column_id } = kanbanMetaData.value
if (grp_column_id) { if (grp_column_id) {
stackMetaObj[grp_column_id] = groupingFieldColOptions.value stackMetaObj.value[grp_column_id] = groupingFieldColOptions.value
await updateKanbanMeta({ await updateKanbanMeta({
stack_meta: stackMetaObj, stack_meta: stackMetaObj.value,
}) })
} }
} }
@ -288,5 +298,6 @@ export function useKanbanViewData(
updateOrSaveRow, updateOrSaveRow,
addEmptyRow, addEmptyRow,
deleteStack, deleteStack,
updateKanbanStackMeta,
} }
} }

Loading…
Cancel
Save