Browse Source

Merge pull request #4001 from nocodb/refactor/kanban-grp-col-id

refactor: kanban grouping column id
pull/4006/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
9efb0f813a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      packages/nc-gui/components/dlg/ViewCreate.vue
  2. 4
      packages/nc-gui/components/smartsheet/Kanban.vue
  3. 2
      packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue
  4. 6
      packages/nc-gui/components/smartsheet/toolbar/StackedBy.vue
  5. 32
      packages/nc-gui/composables/useKanbanViewStore.ts
  6. 281
      packages/nocodb-sdk/package-lock.json
  7. 2
      packages/nocodb-sdk/src/lib/Api.ts
  8. 4
      packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts
  9. 41
      packages/nocodb/src/lib/migrations/v2/nc_021_rename_kanban_grp_col_id.ts
  10. 6
      packages/nocodb/src/lib/models/KanbanView.ts
  11. 6
      packages/nocodb/src/lib/models/View.ts
  12. 2
      scripts/sdk/swagger.json

12
packages/nc-gui/components/dlg/ViewCreate.vue

@ -38,7 +38,7 @@ interface Form {
type: ViewTypes
copy_from_id: string | null
// for kanban view only
grp_column_id: string | null
fk_grp_col_id: string | null
}
const props = defineProps<Props>()
@ -63,7 +63,7 @@ const form = reactive<Form>({
title: props.title || '',
type: props.type,
copy_from_id: null,
grp_column_id: null,
fk_grp_col_id: null,
})
const singleSelectFieldOptions = ref<SelectProps['options']>([])
@ -126,10 +126,10 @@ function init() {
})
if (props.groupingFieldColumnId) {
// take from the one from copy view
form.grp_column_id = props.groupingFieldColumnId
form.fk_grp_col_id = props.groupingFieldColumnId
} else {
// take the first option
form.grp_column_id = singleSelectFieldOptions.value?.[0]?.value as string
form.fk_grp_col_id = singleSelectFieldOptions.value?.[0]?.value as string
}
}
@ -196,11 +196,11 @@ async function onSubmit() {
<a-form-item
v-if="form.type === ViewTypes.KANBAN"
:label="$t('general.groupingField')"
name="grp_column_id"
name="fk_grp_col_id"
:rules="groupingFieldColumnRules"
>
<a-select
v-model:value="form.grp_column_id"
v-model:value="form.fk_grp_col_id"
class="w-full nc-kanban-grouping-field-select"
:options="singleSelectFieldOptions"
:disabled="props.groupingFieldColumnId"

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

@ -175,11 +175,11 @@ function onMoveCallback(event: { draggedContext: { futureIndex: number } }) {
async function onMoveStack(event: any) {
if (event.moved) {
const { oldIndex, newIndex } = event.moved
const { grp_column_id, meta: stack_meta } = kanbanMetaData.value
const { fk_grp_col_id, meta: stack_meta } = kanbanMetaData.value
groupingFieldColOptions.value[oldIndex].order = newIndex
groupingFieldColOptions.value[newIndex].order = oldIndex
const stackMetaObj = JSON.parse(stack_meta as string) || {}
stackMetaObj[grp_column_id as string] = groupingFieldColOptions.value
stackMetaObj[fk_grp_col_id as string] = groupingFieldColOptions.value
await updateKanbanMeta({
meta: stackMetaObj,
})

2
packages/nc-gui/components/smartsheet/sidebar/RenameableMenuItem.vue

@ -105,7 +105,7 @@ function onDuplicate() {
type: vModel.value.type!,
title: vModel.value.title,
copyViewId: vModel.value.id,
groupingFieldColumnId: (vModel.value.view as KanbanType).grp_column_id!,
groupingFieldColumnId: (vModel.value.view as KanbanType).fk_grp_col_id!,
})
$e('c:view:copy', { view: vModel.value.type })

6
packages/nc-gui/components/smartsheet/toolbar/StackedBy.vue

@ -43,15 +43,15 @@ watch(
)
const groupingFieldColumnId = computed({
get: () => kanbanMetaData.value.grp_column_id,
get: () => kanbanMetaData.value.fk_grp_col_id,
set: async (val) => {
if (val) {
await updateKanbanMeta({
grp_column_id: val,
fk_grp_col_id: val,
})
await loadKanbanMeta()
await loadKanbanData()
;(activeView.value?.view as KanbanType).grp_column_id = val
;(activeView.value?.view as KanbanType).fk_grp_col_id = val
}
},
})

32
packages/nc-gui/composables/useKanbanViewStore.ts

@ -139,27 +139,27 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
: await $api.dbView.kanbanRead(viewMeta.value.id)
// set groupingField
groupingFieldColumn.value =
(meta.value.columns as ColumnType[]).filter((f) => f.id === kanbanMetaData.value.grp_column_id)[0] || {}
(meta.value.columns as ColumnType[]).filter((f) => f.id === kanbanMetaData.value.fk_grp_col_id)[0] || {}
groupingField.value = groupingFieldColumn.value.title!
const { grp_column_id, meta: stack_meta } = kanbanMetaData.value
const { fk_grp_col_id, meta: stack_meta } = kanbanMetaData.value
stackMetaObj.value = stack_meta ? JSON.parse(stack_meta as string) : {}
if (stackMetaObj.value && grp_column_id && stackMetaObj.value[grp_column_id]) {
if (stackMetaObj.value && fk_grp_col_id && stackMetaObj.value[fk_grp_col_id]) {
// keep the existing order (index of the array) but update the values done outside kanban
let isChanged = false
let hasNewOptionsAdded = false
for (const option of (groupingFieldColumn.value.colOptions as SelectOptionsType)?.options ?? []) {
const idx = stackMetaObj.value[grp_column_id].findIndex((ele) => ele.id === option.id)
const idx = stackMetaObj.value[fk_grp_col_id].findIndex((ele) => ele.id === option.id)
if (idx !== -1) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { collapsed, ...rest } = stackMetaObj.value[grp_column_id][idx]
const { collapsed, ...rest } = stackMetaObj.value[fk_grp_col_id][idx]
if (!deepCompare(rest, option)) {
// update the option in stackMetaObj
stackMetaObj.value[grp_column_id][idx] = {
...stackMetaObj.value[grp_column_id][idx],
stackMetaObj.value[fk_grp_col_id][idx] = {
...stackMetaObj.value[fk_grp_col_id][idx],
...option,
}
// rename the key in formattedData & countByStack
@ -175,7 +175,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
}
} else {
// new option found - add to stackMetaObj
stackMetaObj.value[grp_column_id].push({
stackMetaObj.value[fk_grp_col_id].push({
...option,
collapsed: false,
})
@ -188,11 +188,11 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
// handle deleted options
const columnOptionIds = (groupingFieldColumn.value?.colOptions as SelectOptionsType)?.options.map(({ id }) => id)
const cols = stackMetaObj.value[grp_column_id].filter(({ id }) => id !== 'uncategorized' && !columnOptionIds.includes(id))
const cols = stackMetaObj.value[fk_grp_col_id].filter(({ id }) => id !== 'uncategorized' && !columnOptionIds.includes(id))
for (const col of cols) {
const idx = stackMetaObj.value[grp_column_id].map((ele: Record<string, any>) => ele.id).indexOf(col.id)
const idx = stackMetaObj.value[fk_grp_col_id].map((ele: Record<string, any>) => ele.id).indexOf(col.id)
if (idx !== -1) {
stackMetaObj.value[grp_column_id].splice(idx, 1)
stackMetaObj.value[fk_grp_col_id].splice(idx, 1)
// there are two cases
// 1. delete option from Add / Edit Stack in kanban view
// 2. delete option from grid view, then switch to kanban view
@ -210,7 +210,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
isChanged = true
}
}
groupingFieldColOptions.value = stackMetaObj.value[grp_column_id]
groupingFieldColOptions.value = stackMetaObj.value[fk_grp_col_id]
if (isChanged) {
await updateKanbanStackMeta()
@ -237,9 +237,9 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
}
async function updateKanbanStackMeta() {
const { grp_column_id } = kanbanMetaData.value
if (grp_column_id) {
stackMetaObj.value[grp_column_id] = groupingFieldColOptions.value
const { fk_grp_col_id } = kanbanMetaData.value
if (fk_grp_col_id) {
stackMetaObj.value[fk_grp_col_id] = groupingFieldColOptions.value
await updateKanbanMeta({
meta: stackMetaObj.value,
})
@ -391,7 +391,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
// update kanban stack meta
groupingFieldColOptions.value.splice(stackIdx, 1)
stackMetaObj.value[kanbanMetaData.value.grp_column_id!] = groupingFieldColOptions.value
stackMetaObj.value[kanbanMetaData.value.fk_grp_col_id!] = groupingFieldColOptions.value
await updateKanbanStackMeta()
$e('a:kanban:delete-stack')
} catch (e: any) {

281
packages/nocodb-sdk/package-lock.json generated

@ -538,19 +538,6 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/table/node_modules/ansi-styles": {
"version": "4.3.0",
"dev": true,
@ -1578,18 +1565,6 @@
"node": ">=10"
}
},
"node_modules/gh-pages/node_modules/array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
"dev": true,
"dependencies": {
"array-uniq": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/escape-goat": {
"version": "2.1.1",
"dev": true,
@ -1811,15 +1786,6 @@
"node": ">=0.10.0"
}
},
"node_modules/nyc/node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/npm-run-all/node_modules/path-key": {
"version": "2.0.1",
"dev": true,
@ -2140,15 +2106,6 @@
"node": ">= 8"
}
},
"node_modules/gh-pages/node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/signal-exit": {
"version": "3.0.7",
"dev": true,
@ -2582,15 +2539,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typedoc/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/trim-repeated": {
"version": "1.0.0",
"dev": true,
@ -3022,18 +2970,6 @@
"node": ">=8"
}
},
"node_modules/git-semver-tags/node_modules/type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-indent": {
"version": "3.0.0",
"dev": true,
@ -4158,15 +4094,6 @@
"node": ">=0.8.0"
}
},
"node_modules/inquirer/node_modules/is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/dotgitignore/node_modules/path-exists": {
"version": "3.0.0",
"dev": true,
@ -5217,15 +5144,6 @@
"once": "^1.4.0"
}
},
"node_modules/array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/escalade": {
"version": "3.1.1",
"dev": true,
@ -5242,21 +5160,6 @@
"node": ">=4.0.0"
}
},
"node_modules/standard-version/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"dependencies": {
"yocto-queue": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-module-utils/node_modules/p-limit": {
"version": "1.3.0",
"dev": true,
@ -5693,15 +5596,6 @@
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/standard-version/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"dev": true,
@ -7207,18 +7101,6 @@
"node": ">=4.8"
}
},
"node_modules/standard-version/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/spawn-wrap": {
"version": "2.0.0",
"dev": true,
@ -7251,18 +7133,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-json-comments": {
"version": "2.0.1",
"dev": true,
@ -7340,21 +7210,6 @@
"license": "MIT",
"optional": true
},
"node_modules/standard-version/node_modules/p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"dependencies": {
"p-limit": "^3.0.2"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@nodelib/fs.walk": {
"version": "1.2.8",
"dev": true,
@ -7608,21 +7463,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/standard-version/node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"dependencies": {
"p-locate": "^5.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/detect-newline": {
"version": "3.1.0",
"dev": true,
@ -8611,15 +8451,6 @@
"ini": "^1.3.2"
}
},
"node_modules/standard-version/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/semver-diff": {
"version": "3.1.1",
"dev": true,
@ -10637,12 +10468,6 @@
"version": "2.1.0",
"dev": true
},
"array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
"dev": true
},
"array.prototype.flat": {
"version": "1.2.5",
"dev": true,
@ -12789,15 +12614,6 @@
"globby": "^6.1.0"
},
"dependencies": {
"array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
"dev": true,
"requires": {
"array-uniq": "^1.0.1"
}
},
"commander": {
"version": "2.20.3",
"dev": true
@ -12825,12 +12641,6 @@
"pify": {
"version": "2.3.0",
"dev": true
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
}
}
},
@ -12927,12 +12737,6 @@
"semver": {
"version": "6.3.0",
"dev": true
},
"type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"dev": true
}
}
},
@ -13300,12 +13104,6 @@
"version": "3.0.0",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true
},
"restore-cursor": {
"version": "2.0.0",
"dev": true,
@ -14266,12 +14064,6 @@
"color-convert": "^2.0.1"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"cliui": {
"version": "6.0.0",
"dev": true,
@ -14313,16 +14105,6 @@
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
@ -15260,12 +15042,6 @@
"supports-color": "^5.3.0"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true
},
"find-up": {
"version": "5.0.0",
"dev": true,
@ -15273,48 +15049,6 @@
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
"p-locate": "^5.0.0"
}
},
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"requires": {
"yocto-queue": "^0.1.0"
}
},
"p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
"p-limit": "^3.0.2"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@ -15794,15 +15528,6 @@
"shiki": "^0.10.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@ -16079,12 +15804,6 @@
"yn": {
"version": "3.1.1",
"dev": true
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
}
}
}

2
packages/nocodb-sdk/src/lib/Api.ts

@ -382,7 +382,7 @@ export interface KanbanType {
alias?: string;
columns?: KanbanColumnType[];
fk_model_id?: string;
grp_column_id?: string | null;
fk_grp_col_id?: string | null;
meta?: string | object;
}

4
packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts

@ -8,6 +8,7 @@ import * as nc_017_add_user_token_version_column from './v2/nc_017_add_user_toke
import * as nc_018_add_meta_in_view from './v2/nc_018_add_meta_in_view';
import * as nc_019_add_meta_in_meta_tables from './v2/nc_019_add_meta_in_meta_tables';
import * as nc_020_add_kanban_meta_col from './v2/nc_020_add_kanban_meta_col';
import * as nc_021_rename_kanban_grp_col_id from './v2/nc_021_rename_kanban_grp_col_id';
// Create a custom migration source class
export default class XcMigrationSourcev2 {
@ -27,6 +28,7 @@ export default class XcMigrationSourcev2 {
'nc_018_add_meta_in_view',
'nc_019_add_meta_in_meta_tables',
'nc_020_add_kanban_meta_col',
'nc_021_rename_kanban_grp_col_id',
]);
}
@ -56,6 +58,8 @@ export default class XcMigrationSourcev2 {
return nc_019_add_meta_in_meta_tables;
case 'nc_020_add_kanban_meta_col':
return nc_020_add_kanban_meta_col;
case 'nc_021_rename_kanban_grp_col_id':
return nc_021_rename_kanban_grp_col_id;
}
}
}

41
packages/nocodb/src/lib/migrations/v2/nc_021_rename_kanban_grp_col_id.ts

@ -0,0 +1,41 @@
import Knex from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {
await knex.schema.alterTable(MetaTable.KANBAN_VIEW, (table) => {
table.renameColumn('grp_column_id', 'fk_grp_col_id')
table
.foreign('fk_grp_col_id')
.references(`${MetaTable.COLUMNS}.id`);
});
};
const down = async (knex) => {
await knex.schema.alterTable(MetaTable.KANBAN_VIEW, (table) => {
table.dropColumns('fk_grp_col_id');
});
};
export { up, down };
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

6
packages/nocodb/src/lib/models/KanbanView.ts

@ -9,7 +9,7 @@ export default class KanbanView implements KanbanType {
title: string;
project_id?: string;
base_id?: string;
grp_column_id?: string;
fk_grp_col_id?: string;
meta?: string | object;
// below fields are not in use at this moment
@ -50,7 +50,7 @@ export default class KanbanView implements KanbanType {
(
await ncMeta.metaList2(null, null, MetaTable.KANBAN_VIEW, {
condition: {
grp_column_id: columnId,
fk_grp_col_id: columnId,
},
})
).length > 0
@ -62,7 +62,7 @@ export default class KanbanView implements KanbanType {
project_id: view.project_id,
base_id: view.base_id,
fk_view_id: view.fk_view_id,
grp_column_id: view.grp_column_id,
fk_grp_col_id: view.fk_grp_col_id,
meta: view.meta,
};

6
packages/nocodb/src/lib/models/View.ts

@ -225,7 +225,7 @@ export default class View implements ViewType {
view: Partial<View> &
Partial<FormView | GridView | GalleryView | KanbanView> & {
copy_from_id?: string;
grp_column_id?: string;
fk_grp_col_id?: string;
created_at?;
updated_at?;
},
@ -312,7 +312,7 @@ export default class View implements ViewType {
break;
case ViewTypes.KANBAN:
// set grouping field
(view as KanbanView).grp_column_id = view.grp_column_id;
(view as KanbanView).fk_grp_col_id = view.fk_grp_col_id;
await KanbanView.insert(
{
@ -398,7 +398,7 @@ export default class View implements ViewType {
}
} else if (view.type === ViewTypes.KANBAN && !copyFromView) {
const kanbanView = await KanbanView.get(view_id, ncMeta);
if (vCol.id === kanbanView?.grp_column_id) {
if (vCol.id === kanbanView?.fk_grp_col_id) {
// include grouping field if it exists
show = true;
} else if (vCol.pv) {

2
scripts/sdk/swagger.json

@ -7913,7 +7913,7 @@
"fk_model_id": {
"type": "string"
},
"grp_column_id": {
"fk_grp_col_id": {
"type": [
"string",
"null"

Loading…
Cancel
Save