Browse Source

Merge pull request #7478 from nocodb/nc-fix/ui-bug-fixes

Nc fix/UI bug fixes
pull/7510/head
Raju Udava 9 months ago committed by GitHub
parent
commit
7479d35d37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  2. 2
      packages/nc-gui/components/smartsheet/grid/GroupByLabel.vue
  3. 2
      packages/nc-gui/components/virtual-cell/BelongsTo.vue
  4. 12
      packages/nocodb-sdk/src/lib/helperFunctions.ts
  5. 32
      packages/nocodb/src/models/Column.ts
  6. 16
      packages/nocodb/src/models/View.ts
  7. 1
      tests/playwright/pages/Dashboard/Grid/Column/index.ts
  8. 18
      tests/playwright/pages/Dashboard/common/Toolbar/Fields.ts
  9. 17
      tests/playwright/tests/db/columns/columnLinkToAnotherRecord.spec.ts
  10. 3
      tests/playwright/tests/db/columns/columnMenuOperations.spec.ts
  11. 3
      tests/playwright/tests/db/columns/columnRelationalExtendedTests.spec.ts
  12. 33
      tests/playwright/tests/db/features/metaLTAR.spec.ts
  13. 6
      tests/playwright/tests/db/views/viewGridShare.spec.ts

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

@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { ColumnReqType, ColumnType } from 'nocodb-sdk'
import { UITypes, isLinksOrLTAR, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { UITypes, isLinksOrLTAR, isSelfReferencingTableColumn, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import {
IsFormInj,
IsKanbanInj,
@ -172,7 +172,7 @@ onMounted(() => {
if (formState.value.pk) {
message.info(t('msg.info.editingPKnotSupported'))
emit('cancel')
} else if (isSystemColumn(formState.value)) {
} else if (isSystemColumn(formState.value) && !isSelfReferencingTableColumn(formState.value)) {
message.info(t('msg.info.editingSystemKeyNotSupported'))
emit('cancel')
}

2
packages/nc-gui/components/smartsheet/grid/GroupByLabel.vue

@ -14,7 +14,7 @@ provide(IsGroupByLabelInj, ref(true))
<template>
<div class="pointer-events-none">
<LazySmartsheetRow :row="{ row: { [column.title]: modelValue }, rowMeta: {} }">
<LazySmartsheetRow :row="{ row: { [column.title as string]: modelValue }, rowMeta: {} }">
<LazySmartsheetVirtualCell
v-if="isVirtualCol(column)"
:model-value="modelValue"

2
packages/nc-gui/components/virtual-cell/BelongsTo.vue

@ -99,7 +99,7 @@ watch([listItemsDlg], () => {
<template v-if="value && relatedTableDisplayValueProp">
<VirtualCellComponentsItemChip
:item="value"
:value="value[relatedTableDisplayValueProp]"
:value="!Array.isArray(value) && typeof value === 'object' ? value[relatedTableDisplayValueProp] : value"
:column="belongsToColumn"
:show-unlink-button="true"
@unlink="unlinkRef(value)"

12
packages/nocodb-sdk/src/lib/helperFunctions.ts

@ -22,6 +22,17 @@ const isSystemColumn = (col): boolean =>
(col.pk && col.meta && col.meta.ag) ||
col.system);
const isSelfReferencingTableColumn = (col): boolean => {
return (
col &&
(col.uidt === UITypes.Links || col.uidt === UITypes.LinkToAnotherRecord) &&
(col?.fk_model_id || col?.colOptions?.fk_model_id) &&
col?.colOptions?.fk_related_model_id &&
(col?.fk_model_id || col?.colOptions?.fk_model_id) ===
col.colOptions.fk_related_model_id
);
};
const extractRolesObj = (roles: RolesType): RolesObj => {
if (!roles) return null;
@ -89,6 +100,7 @@ export {
getSystemColumnsIds,
getSystemColumns,
isSystemColumn,
isSelfReferencingTableColumn,
extractRolesObj,
stringifyRolesObj,
getAvailableRollupForUiType,

32
packages/nocodb/src/models/Column.ts

@ -197,7 +197,16 @@ export default class Column<T = any> implements ColumnType {
{
fk_column_id: row.id,
fk_model_id: column.fk_model_id,
show: !column.view_id,
column_show: {
show:
column.uidt === UITypes.LinkToAnotherRecord ||
(column.uidt === UITypes.Links &&
column.type === 'mm' &&
!column.view_id)
? false
: !column.view_id,
view_id: column.view_id,
},
column_order: column.column_order,
},
ncMeta,
@ -205,27 +214,6 @@ export default class Column<T = any> implements ColumnType {
await View.clearSingleQueryCache(column.fk_model_id);
if (column.view_id) {
const viewColId = await View.getViewColumnId(
{
viewId: column.view_id,
colId: row.id,
},
ncMeta,
);
if (viewColId) {
await View.updateColumn(
column.view_id,
viewColId,
{
show: true,
},
ncMeta,
);
}
}
return col;
}

16
packages/nocodb/src/models/View.ts

@ -533,7 +533,10 @@ export default class View implements ViewType {
fk_column_id: any;
fk_model_id: any;
order?: number;
show;
column_show: {
show: boolean;
view_id?: any;
};
} & Pick<ColumnReqType, 'column_order'>,
ncMeta = Noco.ncMeta,
) {
@ -541,12 +544,19 @@ export default class View implements ViewType {
fk_column_id: param.fk_column_id,
fk_model_id: param.fk_model_id,
order: param.order,
show: param.show,
show: param.column_show.show,
};
const views = await this.list(param.fk_model_id, ncMeta);
for (const view of views) {
const modifiedInsertObj = { ...insertObj, fk_view_id: view.id };
const modifiedInsertObj = {
...insertObj,
fk_view_id: view.id,
};
if (param.column_show?.view_id === view.id) {
modifiedInsertObj.show = true;
}
if (param.column_order?.view_id === view.id) {
modifiedInsertObj.order = param.column_order?.order;

1
tests/playwright/pages/Dashboard/Grid/Column/index.ts

@ -455,6 +455,7 @@ export class ColumnPageObject extends BasePage {
// close sort menu
await this.grid.toolbar.clickSort();
await this.rootPage.waitForTimeout(100);
}
async resize(param: { src: string; dst: string }) {

18
tests/playwright/pages/Dashboard/common/Toolbar/Fields.ts

@ -19,16 +19,34 @@ export class ToolbarFieldsPage extends BasePage {
title,
isLocallySaved,
validateResponse = true,
checked,
}: {
title: string;
isLocallySaved?: boolean;
validateResponse?: boolean;
checked?: boolean;
}) {
await this.toolbar.clickFields();
// hack
await this.rootPage.waitForTimeout(100);
if (checked !== undefined) {
// toggle only if input checked value is not equal to given checked value
await this.get()
.locator(`[data-testid="nc-fields-menu-${title}"]`)
.locator('.nc-switch')
.scrollIntoViewIfNeeded();
const isChecked = await this.get()
.locator(`[data-testid="nc-fields-menu-${title}"]`)
.locator('.nc-switch')
.isChecked();
if ((checked && isChecked) || (!checked && !isChecked)) {
await this.toolbar.clickFields();
return;
}
}
const toggleColumn = () =>
this.get().locator(`[data-testid="nc-fields-menu-${title}"]`).locator('.nc-switch').click();

17
tests/playwright/tests/db/columns/columnLinkToAnotherRecord.spec.ts

@ -56,10 +56,16 @@ test.describe('LTAR create & update', () => {
});
// Sheet2 now has all 3 column categories : HM, BT, MM
//
// Expanded form insert
// Verify fields and toggle the visibility
await dashboard.grid.toolbar.clickFields();
for (const title of ['Sheet1', 'Sheet1s']) {
await dashboard.grid.toolbar.fields.verify({ title, checked: false });
await dashboard.grid.toolbar.fields.click({ title, isLocallySaved: false });
}
await dashboard.grid.toolbar.clickFields();
// Expanded form insert
await dashboard.grid.footbar.clickAddRecordFromForm();
await dashboard.expandedForm.fillField({
columnTitle: 'Title',
@ -100,6 +106,7 @@ test.describe('LTAR create & update', () => {
// Expand record insert
await dashboard.grid.addNewRow({ index: 2, value: '2c-temp' });
await dashboard.grid.openExpandedRow({ index: 2 });
await dashboard.expandedForm.fillField({
columnTitle: 'Sheet1',
value: '1c',
@ -149,6 +156,12 @@ test.describe('LTAR create & update', () => {
await dashboard.closeTab({ title: 'Sheet2' });
await dashboard.treeView.openTable({ title: 'Sheet1' });
// Verify fields and toggle the visibility
await dashboard.grid.toolbar.clickFields();
await dashboard.grid.toolbar.fields.verify({ title: 'Sheet2', checked: false });
await dashboard.grid.toolbar.fields.click({ title: 'Sheet2', isLocallySaved: false });
await dashboard.grid.toolbar.clickFields();
const expected2 = [
[['1 Sheet2'], ['1 Sheet2'], ['1 Sheet2']],
[['1 Sheet2'], ['1 Sheet2'], ['1 Sheet2']],

3
tests/playwright/tests/db/columns/columnMenuOperations.spec.ts

@ -85,6 +85,7 @@ test.describe('Column menu operations', () => {
insertAfterColumnTitle: 'Title',
});
await dashboard.grid.toolbar.fields.toggle({ title: 'Actors', isLocallySaved: false, checked: true });
await dashboard.grid.column.create({
title: 'InsertAfterColumn1',
type: 'SingleLineText',
@ -104,6 +105,7 @@ test.describe('Column menu operations', () => {
isDisplayValue: true,
});
await dashboard.grid.toolbar.fields.toggle({ title: 'Actors', isLocallySaved: false, checked: true });
await dashboard.grid.column.create({
title: 'InsertBeforeColumn1',
type: 'SingleLineText',
@ -121,6 +123,7 @@ test.describe('Column menu operations', () => {
isDisplayValue: true,
});
await dashboard.grid.toolbar.fields.toggle({ title: 'Actors', isLocallySaved: false, checked: true });
await dashboard.grid.column.hideColumn({
title: 'Actors',
});

3
tests/playwright/tests/db/columns/columnRelationalExtendedTests.spec.ts

@ -63,8 +63,8 @@ test.describe('Relational Columns', () => {
///////////// Belongs to
//
await dashboard.treeView.openTable({ title: 'City' });
await dashboard.grid.toolbar.fields.toggle({ title: 'Country', isLocallySaved: false, checked: true });
const countryList = [['Spain'], ['Saudi Arabia']];
for (let i = 0; i < countryList.length; i++) {
await dashboard.grid.cell.verifyVirtualCell({
@ -79,6 +79,7 @@ test.describe('Relational Columns', () => {
///////////// Many to many
//
await dashboard.treeView.openTable({ title: 'Actor' });
await dashboard.grid.toolbar.fields.toggle({ title: 'Films', isLocallySaved: false, checked: true });
const filmList = [
[
'ACADEMY DINOSAUR',

33
tests/playwright/tests/db/features/metaLTAR.spec.ts

@ -111,6 +111,7 @@ test.describe.serial('Test table', () => {
parentId: tables[0].id,
childId: tables[1].id,
type: 'hm',
view_id: tables[0].views[0].id,
});
await api.dbTableColumn.create(tables[1].id, {
uidt: UITypes.Links,
@ -119,6 +120,7 @@ test.describe.serial('Test table', () => {
parentId: tables[1].id,
childId: tables[2].id,
type: 'hm',
view_id: tables[1].views[0].id,
});
// TableA <mm> TableD <mm> TableE
@ -129,6 +131,7 @@ test.describe.serial('Test table', () => {
parentId: tables[0].id,
childId: tables[3].id,
type: 'mm',
view_id: tables[0].views[0].id,
});
await api.dbTableColumn.create(tables[3].id, {
uidt: UITypes.Links,
@ -137,6 +140,7 @@ test.describe.serial('Test table', () => {
parentId: tables[3].id,
childId: tables[4].id,
type: 'mm',
view_id: tables[3].views[0].id,
});
// TableA <hm> TableA : self relation
@ -147,6 +151,7 @@ test.describe.serial('Test table', () => {
parentId: tables[0].id,
childId: tables[0].id,
type: 'hm',
view_id: tables[0].views[0].id,
});
// TableA <mm> TableA : self relation
@ -157,6 +162,7 @@ test.describe.serial('Test table', () => {
parentId: tables[0].id,
childId: tables[0].id,
type: 'mm',
view_id: tables[0].views[0].id,
});
// Add links
@ -212,6 +218,33 @@ test.describe.serial('Test table', () => {
// refresh page
await page.reload();
const hiddenLinksTableColumns = [
{
tableName: 'Table1',
columns: ['Table0'],
},
{
tableName: 'Table2',
columns: ['Table1'],
},
{
tableName: 'Table3',
columns: ['Table0s'],
},
{
tableName: 'Table4',
columns: ['Table3s'],
},
];
// Unhide links columns
for (const table of hiddenLinksTableColumns) {
await dashboard.treeView.openTable({ title: table.tableName });
for (const column of table.columns) {
await dashboard.grid.toolbar.fields.toggle({ title: column, isLocallySaved: false, checked: true });
}
}
});
test.afterEach(async () => {

6
tests/playwright/tests/db/views/viewGridShare.spec.ts

@ -128,6 +128,9 @@ test.describe('Shared view', () => {
await dashboard.closeTab({ title: 'Team & Auth' });
await dashboard.treeView.openTable({ title: 'Address' });
// Unhide City column
await dashboard.grid.toolbar.fields.toggle({ title: 'City', isLocallySaved: false, checked: true });
// hide column
await dashboard.grid.toolbar.fields.toggle({ title: 'Address2' });
await dashboard.grid.toolbar.fields.toggle({ title: 'Stores' });
@ -168,7 +171,6 @@ test.describe('Shared view', () => {
{ title: 'Address', isVisible: true },
{ title: 'Address2', isVisible: false },
{ title: 'District', isVisible: true },
{ title: 'City', isVisible: true },
{ title: 'PostalCode', isVisible: true },
{ title: 'Phone', isVisible: true },
{ title: 'LastUpdate', isVisible: true },
@ -225,7 +227,7 @@ test.describe('Shared view', () => {
await sharedPage.grid.toolbar.clickFilter();
}
await sharedPage.grid.toolbar.fields.toggle({ title: 'LastUpdate', isLocallySaved: true });
expectedColumns[6].isVisible = false;
expectedColumns[5].isVisible = false;
// verify new sort & filter criteria
for (const column of expectedColumns) {

Loading…
Cancel
Save