Browse Source

feat: force primary value column as sticky

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/5060/head
mertmit 2 years ago
parent
commit
03db6b26b5
  1. 1
      packages/nc-gui/components.d.ts
  2. 2
      packages/nc-gui/components/smartsheet/header/Menu.vue
  3. 28
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  4. 5
      packages/nc-gui/composables/useViewColumns.ts
  5. 12
      packages/nocodb/src/lib/models/Model.ts
  6. 99
      packages/nocodb/src/lib/models/View.ts

1
packages/nc-gui/components.d.ts vendored

@ -232,6 +232,7 @@ declare module '@vue/runtime-core' {
MdiTable: typeof import('~icons/mdi/table')['default']
MdiTableColumnPlusAfter: typeof import('~icons/mdi/table-column-plus-after')['default']
MdiTableColumnPlusBefore: typeof import('~icons/mdi/table-column-plus-before')['default']
MdiTableKey: typeof import('~icons/mdi/table-key')['default']
MdiTableLarge: typeof import('~icons/mdi/table-large')['default']
MdiText: typeof import('~icons/mdi/text')['default']
MdiThumbUp: typeof import('~icons/mdi/thumb-up')['default']

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

@ -74,6 +74,8 @@ const setAsPrimaryValue = async () => {
await getMeta(meta?.value?.id as string, true)
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
// Successfully updated as primary column
message.success(t('msg.success.primaryColumnUpdated'))

28
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -188,7 +188,7 @@ useMenuCloseOnEsc(open)
<Draggable v-model="fields" item-key="id" @change="onMove($event)">
<template #item="{ element: field, index: index }">
<div
v-show="filteredFieldList.includes(field)"
v-if="filteredFieldList.slice(1).includes(field)"
:key="field.id"
class="px-2 py-1 flex items-center"
:data-testid="`nc-fields-menu-${field.title}`"
@ -212,6 +212,32 @@ useMenuCloseOnEsc(open)
<MdiDrag class="cursor-move" />
</div>
</template>
<template #header>
<div
v-if="filteredFieldList[0]"
v-show="filteredFieldList[0]"
:key="`pv-${filteredFieldList[0].id}`"
class="px-2 py-1 flex items-center"
:data-testid="`nc-fields-menu-${filteredFieldList[0].title}`"
@click.stop
>
<a-tooltip placement="bottom">
<template #title>
<span class="text-sm">Primary Value</span>
</template>
<MdiTableKey class="text-xs" />
</a-tooltip>
<div class="flex items-center px-[8px]">
<component :is="getIcon(metaColumnById[filteredFieldList[0].fk_column_id as string])" />
<span>{{ filteredFieldList[0].title }}</span>
</div>
<div class="flex-1" />
</div>
</template>
</Draggable>
</div>

5
packages/nc-gui/composables/useViewColumns.ts

@ -173,6 +173,8 @@ export function useViewColumns(
const filteredFieldList = computed(() => {
return (
fields.value?.filter((field: Field) => {
if (metaColumnById?.value?.[field.fk_column_id!].pv) return true
// hide system columns if not enabled
if (!showSystemFields.value && isSystemColumn(metaColumnById?.value?.[field.fk_column_id!])) {
return false
@ -195,7 +197,8 @@ export function useViewColumns(
!showSystemFields.value &&
metaColumnById.value &&
metaColumnById?.value?.[field.fk_column_id!] &&
isSystemColumn(metaColumnById.value?.[field.fk_column_id!])
isSystemColumn(metaColumnById.value?.[field.fk_column_id!]) &&
!metaColumnById.value?.[field.fk_column_id!].pv
) {
return false
}

12
packages/nocodb/src/lib/models/Model.ts

@ -606,6 +606,18 @@ export default class Model implements TableType {
newPvCol.id
);
const grid_views_with_column = await ncMeta.metaList2(null, null, MetaTable.GRID_VIEW_COLUMNS, {
condition: {
fk_column_id: newPvCol.id,
}
})
if (grid_views_with_column.length) {
for (const gv of grid_views_with_column) {
await View.fixPVColumnForView(gv.fk_view_id, ncMeta);
}
}
return true;
}

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

@ -630,6 +630,18 @@ export default class View implements ViewType {
break;
}
const updateObj = extractProps(colData, ['order', 'show']);
const primary_value_column = await ncMeta.metaGet2(null, null, MetaTable.COLUMNS, {
fk_model_id: view.fk_model_id,
pv: true,
});
// keep primary_value_column always visible and first
if (primary_value_column && primary_value_column.id === colId) {
updateObj.order = 1;
updateObj.show = true;
}
// get existing cache
const key = `${cacheScope}:${colId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
@ -1078,6 +1090,17 @@ export default class View implements ViewType {
const view = await this.get(viewId);
const table = this.extractViewColumnsTableName(view);
const scope = this.extractViewColumnsTableNameScope(view);
const primary_value_column = await ncMeta.metaGet2(null, null, MetaTable.COLUMNS, {
fk_model_id: view.fk_model_id,
pv: true,
})
// keep primary_value_column always visible
if (primary_value_column) {
ignoreColdIds.push(primary_value_column.id)
}
// get existing cache
const dataList = await NocoCache.getList(scope, [viewId]);
if (dataList?.length) {
@ -1135,4 +1158,80 @@ export default class View implements ViewType {
sharedViews = sharedViews.filter((v) => v.uuid !== null);
return sharedViews?.map((v) => new View(v));
}
static async fixPVColumnForView(viewId, ncMeta = Noco.ncMeta) {
// get a list of view columns sorted by order
const view_columns = await ncMeta.metaList2(null, null, MetaTable.GRID_VIEW_COLUMNS, {
condition: {
fk_view_id: viewId,
},
orderBy: {
order: 'asc',
},
});
const view_columns_meta = []
// get column meta for each view column
for (const col of view_columns) {
const col_meta = await ncMeta.metaGet2(null, null, MetaTable.COLUMNS, col.fk_column_id);
view_columns_meta.push(col_meta);
}
const primary_value_column_meta = view_columns_meta.find((col) => col.pv);
if (primary_value_column_meta) {
const primary_value_column = view_columns.find((col) => col.fk_column_id === primary_value_column_meta.id);
const primary_value_column_index = view_columns.findIndex((col) => col.fk_column_id === primary_value_column_meta.id);
// if primary_value_column is not visible, make it visible
if (!primary_value_column.show) {
await ncMeta.metaUpdate(
null,
null,
MetaTable.GRID_VIEW_COLUMNS,
{ show: true },
primary_value_column.id,
);
await NocoCache.set(
`${CacheScope.GRID_VIEW_COLUMN}:${primary_value_column.id}`,
primary_value_column
);
}
if (primary_value_column.order < 2) {
// if primary_value_column is in first order do nothing
return;
} else {
// if primary_value_column not in first order, move it to the start of array
if (primary_value_column_index !== 0) {
const temp_pv = view_columns.splice(primary_value_column_index, 1);
view_columns.unshift(...temp_pv);
}
// update order of all columns in view to match the order in array
for (let i = 0; i < view_columns.length; i++) {
await ncMeta.metaUpdate(
null,
null,
MetaTable.GRID_VIEW_COLUMNS,
{ order: i + 1 },
view_columns[i].id
);
await NocoCache.set(
`${CacheScope.GRID_VIEW_COLUMN}:${view_columns[i].id}`,
view_columns[i]
);
}
}
}
const views = await ncMeta.metaList2(null, null, MetaTable.GRID_VIEW_COLUMNS, {
condition: {
fk_view_id: viewId,
},
orderBy: {
order: 'asc',
},
});
await NocoCache.setList(CacheScope.GRID_VIEW_COLUMN, [viewId], views);
}
}

Loading…
Cancel
Save