Browse Source

feat: insert column after/before a column

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/4504/head
Pranav C 2 years ago
parent
commit
44217b0ce4
  1. 25
      packages/nc-gui/components/smartsheet/Grid.vue
  2. 11
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  3. 5
      packages/nc-gui/components/smartsheet/column/EditOrAddProvider.vue
  4. 34
      packages/nc-gui/components/smartsheet/header/Menu.vue
  5. 6
      packages/nc-gui/composables/useColumnCreateStore.ts
  6. 1
      packages/nc-gui/lib/enums.ts

25
packages/nc-gui/components/smartsheet/Grid.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ColumnType, TableType, ViewType } from 'nocodb-sdk' import type { ColumnReqType, ColumnType, TableType, ViewType } from 'nocodb-sdk'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import { UITypes, isVirtualCol } from 'nocodb-sdk'
import { import {
ActiveViewInj, ActiveViewInj,
@ -42,7 +42,7 @@ import {
watch, watch,
} from '#imports' } from '#imports'
import type { Row } from '~/lib' import type { Row } from '~/lib'
import { NavigateDir } from '~/lib' import { NavigateDir, SmartsheetStoreEvents } from '~/lib'
const { t } = useI18n() const { t } = useI18n()
@ -71,7 +71,7 @@ const isView = false
let editEnabled = $ref(false) let editEnabled = $ref(false)
const { xWhere, isPkAvail, isSqlView } = useSmartsheetStoreOrThrow() const { xWhere, isPkAvail, isSqlView, eventBus } = useSmartsheetStoreOrThrow()
const visibleColLength = $computed(() => fields.value?.length) const visibleColLength = $computed(() => fields.value?.length)
@ -544,6 +544,20 @@ watch(
}, },
{ immediate: true }, { immediate: true },
) )
const columnPosition = ref<Pick<ColumnReqType, 'columnOrder'> | null>(null)
eventBus.on(async (event, payload) => {
if (event === SmartsheetStoreEvents.FIELD_ADD) {
columnPosition.value = payload
addColumnDropdown.value = true
}
})
const closeAddColumnMenu = () => {
columnPosition.value = null
addColumnDropdown.value = false
}
</script> </script>
<template> <template>
@ -619,8 +633,9 @@ watch(
<template #overlay> <template #overlay>
<SmartsheetColumnEditOrAddProvider <SmartsheetColumnEditOrAddProvider
v-if="addColumnDropdown" v-if="addColumnDropdown"
@submit="addColumnDropdown = false" :column-position="columnPosition"
@cancel="addColumnDropdown = false" @submit="closeAddColumnMenu"
@cancel="closeAddColumnMenu"
@click.stop @click.stop
@keydown.stop @keydown.stop
/> />

11
packages/nc-gui/components/smartsheet/column/EditOrAdd.vue

@ -1,12 +1,15 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useEventListener } from '@vueuse/core' import { useEventListener } from '@vueuse/core'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import type { ColumnReqType } from 'nocodb-sdk'
import { ColumnType, UITypes, isVirtualCol } from 'nocodb-sdk'
import { import {
IsFormInj, IsFormInj,
IsKanbanInj, IsKanbanInj,
MetaInj, MetaInj,
ReloadViewDataHookInj, ReloadViewDataHookInj,
computed, computed,
defineEmits,
defineProps,
inject, inject,
message, message,
onMounted, onMounted,
@ -22,6 +25,10 @@ import MdiPlusIcon from '~icons/mdi/plus-circle-outline'
import MdiMinusIcon from '~icons/mdi/minus-circle-outline' import MdiMinusIcon from '~icons/mdi/minus-circle-outline'
import MdiIdentifierIcon from '~icons/mdi/identifier' import MdiIdentifierIcon from '~icons/mdi/identifier'
const props = defineProps<{
columnPosition?: Pick<ColumnReqType, 'columnOrder'>
}>()
const emit = defineEmits(['submit', 'cancel']) const emit = defineEmits(['submit', 'cancel'])
const { formState, generateNewColumnMeta, addOrUpdate, onAlter, onUidtOrIdTypeChange, validateInfos, isEdit } = const { formState, generateNewColumnMeta, addOrUpdate, onAlter, onUidtOrIdTypeChange, validateInfos, isEdit } =
@ -71,7 +78,7 @@ const reloadMetaAndData = async () => {
} }
async function onSubmit() { async function onSubmit() {
const saved = await addOrUpdate(reloadMetaAndData) const saved = await addOrUpdate(reloadMetaAndData, props.columnPosition)
if (!saved) return if (!saved) return

5
packages/nc-gui/components/smartsheet/column/EditOrAddProvider.vue

@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
// todo: Remove this "Provider" component and use the "EditOrAdd" component directly // todo: Remove this "Provider" component and use the "EditOrAdd" component directly
import type { ColumnType } from 'nocodb-sdk' import type { ColumnReqType, ColumnType } from 'nocodb-sdk'
import { MetaInj, inject, ref, toRef, useProvideColumnCreateStore } from '#imports' import { MetaInj, inject, ref, toRef, useProvideColumnCreateStore } from '#imports'
interface Props { interface Props {
column?: ColumnType & { meta: any } column?: ColumnType & { meta: any }
columnPosition?: Pick<ColumnReqType, 'columnOrder'>
} }
const props = defineProps<Props>() const props = defineProps<Props>()
@ -19,5 +20,5 @@ useProvideColumnCreateStore(meta, column)
</script> </script>
<template> <template>
<SmartsheetColumnEditOrAdd @submit="emit('submit')" @cancel="emit('cancel')" /> <SmartsheetColumnEditOrAdd :column-position="props.columnPosition" @submit="emit('submit')" @cancel="emit('cancel')" />
</template> </template>

34
packages/nc-gui/components/smartsheet/header/Menu.vue

@ -132,7 +132,6 @@ const duplicateColumn = async () => {
} }
try { try {
const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string) const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string)
const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id) const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id)
@ -141,7 +140,7 @@ const duplicateColumn = async () => {
return return
} }
let newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1]?.order) / 2 const newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1]?.order) / 2
await $api.dbTableColumn.create(meta!.value!.id!, { await $api.dbTableColumn.create(meta!.value!.id!, {
...columnCreatePayload, ...columnCreatePayload,
@ -152,17 +151,38 @@ const duplicateColumn = async () => {
}) })
await getMeta(meta!.value!.id!, true) await getMeta(meta!.value!.id!, true)
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD) eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
} }
const addColumn = async (before = false) => {
const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string)
const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id)
// if (currentColumnIndex === gridViewColumnList.length - 2) {
// return
// }
let newColumnOrder
if (before) {
newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex - 1]?.order) / 2
} else {
newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1]?.order) / 2
}
eventBus.emit(SmartsheetStoreEvents.FIELD_ADD, {
columnOrder: {
order: newColumnOrder,
viewId: view.value?.id as string,
},
})
}
</script> </script>
<template> <template>
<a-dropdown v-if="!isLocked" placement="bottomRight" :trigger="['click']" <a-dropdown v-if="!isLocked" placement="bottomRight" :trigger="['click']" overlay-class-name="nc-dropdown-column-operations">
overlay-class-name="nc-dropdown-column-operations">
<MdiMenuDown class="h-full text-grey nc-ui-dt-dropdown cursor-pointer outline-0" /> <MdiMenuDown class="h-full text-grey nc-ui-dt-dropdown cursor-pointer outline-0" />
<template #overlay> <template #overlay>
@ -183,13 +203,13 @@ const duplicateColumn = async () => {
Duplicate Duplicate
</div> </div>
</a-menu-item> </a-menu-item>
<a-menu-item @click="emit('edit')"> <a-menu-item @click="addColumn()">
<div class="nc-column-insert-after nc-header-menu-item"> <div class="nc-column-insert-after nc-header-menu-item">
<MdiTableColumnPlusAfter class="text-primary" /> <MdiTableColumnPlusAfter class="text-primary" />
Insert After Insert After
</div> </div>
</a-menu-item> </a-menu-item>
<a-menu-item @click="emit('edit')"> <a-menu-item @click="addColumn(true)">
<div class="nc-column-insert-before nc-header-menu-item"> <div class="nc-column-insert-before nc-header-menu-item">
<MdiTableColumnPlusBefore class="text-primary" /> <MdiTableColumnPlusBefore class="text-primary" />
Insert before Insert before

6
packages/nc-gui/composables/useColumnCreateStore.ts

@ -1,5 +1,5 @@
import clone from 'just-clone' import clone from 'just-clone'
import type { ColumnType, TableType } from 'nocodb-sdk' import type { ColumnReqType, ColumnType, TableType } from 'nocodb-sdk'
import { UITypes } from 'nocodb-sdk' import { UITypes } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { import {
@ -191,7 +191,7 @@ const [useProvideColumnCreateStore, useColumnCreateStore] = createInjectionState
if (cdf) formState.value.cdf = formState.value.cdf || null if (cdf) formState.value.cdf = formState.value.cdf || null
} }
const addOrUpdate = async (onSuccess: () => void) => { const addOrUpdate = async (onSuccess: () => void, columnPosition?: Pick<ColumnReqType, 'columnOrder'>) => {
try { try {
if (!(await validate())) return if (!(await validate())) return
} catch (e) { } catch (e) {
@ -228,7 +228,7 @@ const [useProvideColumnCreateStore, useColumnCreateStore] = createInjectionState
// }; // };
// } // }
} }
await $api.dbTableColumn.create(meta.value?.id as string, formState.value) await $api.dbTableColumn.create(meta.value?.id as string, { ...formState.value, ...columnPosition })
/** if LTAR column then force reload related table meta */ /** if LTAR column then force reload related table meta */
if (formState.value.uidt === UITypes.LinkToAnotherRecord && meta.value?.id !== formState.value.childId) { if (formState.value.uidt === UITypes.LinkToAnotherRecord && meta.value?.id !== formState.value.childId) {

1
packages/nc-gui/lib/enums.ts

@ -83,4 +83,5 @@ export enum SmartsheetStoreEvents {
FILTER_RELOAD = 'filter-reload', FILTER_RELOAD = 'filter-reload',
DATA_RELOAD = 'data-reload', DATA_RELOAD = 'data-reload',
FIELD_RELOAD = 'field-reload', FIELD_RELOAD = 'field-reload',
FIELD_ADD = 'field-add',
} }

Loading…
Cancel
Save