Browse Source

Merge branch 'develop' into feat/pnpm

pull/5903/head
Wing-Kam Wong 1 year ago
parent
commit
9ad2b13c15
  1. 6
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 6
      packages/nc-gui/components/cell/SingleSelect.vue
  3. 4
      packages/nc-gui/components/smartsheet/Grid.vue
  4. 2
      packages/nc-lib-gui/package.json
  5. 2
      packages/nocodb-sdk/package.json
  6. 4
      packages/nocodb/package.json
  7. 25
      packages/nocodb/src/version-upgrader/ncXcdbLTARUpgrader.ts
  8. 4
      tests/playwright/pages/Account/License.ts
  9. 149
      tests/playwright/tests/db/updateBulk.ts

6
packages/nc-gui/components/cell/MultiSelect.vue

@ -48,11 +48,11 @@ const readOnly = inject(ReadonlyInj)!
const isEditable = inject(EditModeInj, ref(false)) const isEditable = inject(EditModeInj, ref(false))
const _active = inject(ActiveCellInj, ref(false)) const activeCell = inject(ActiveCellInj, ref(false))
// use both ActiveCellInj or EditModeInj to determine the active state // use both ActiveCellInj or EditModeInj to determine the active state
// since active will be false in case of form view // since active will be false in case of form view
const active = computed(() => _active.value || isEditable.value) const active = computed(() => activeCell.value || isEditable.value)
const isPublic = inject(IsPublicInj, ref(false)) const isPublic = inject(IsPublicInj, ref(false))
@ -180,7 +180,7 @@ watch(isOpen, (n, _o) => {
} }
}) })
useSelectedCellKeyupListener(active, (e) => { useSelectedCellKeyupListener(activeCell, (e) => {
switch (e.key) { switch (e.key) {
case 'Escape': case 'Escape':
isOpen.value = false isOpen.value = false

6
packages/nc-gui/components/cell/SingleSelect.vue

@ -42,11 +42,11 @@ const readOnly = inject(ReadonlyInj)!
const isEditable = inject(EditModeInj, ref(false)) const isEditable = inject(EditModeInj, ref(false))
const _active = inject(ActiveCellInj, ref(false)) const activeCell = inject(ActiveCellInj, ref(false))
// use both ActiveCellInj or EditModeInj to determine the active state // use both ActiveCellInj or EditModeInj to determine the active state
// since active will be false in case of form view // since active will be false in case of form view
const active = computed(() => _active.value || isEditable.value) const active = computed(() => activeCell.value || isEditable.value)
const aselect = ref<typeof AntSelect>() const aselect = ref<typeof AntSelect>()
@ -119,7 +119,7 @@ watch(isOpen, (n, _o) => {
} }
}) })
useSelectedCellKeyupListener(active, (e) => { useSelectedCellKeyupListener(activeCell, (e) => {
switch (e.key) { switch (e.key) {
case 'Escape': case 'Escape':
isOpen.value = false isOpen.value = false

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

@ -82,6 +82,8 @@ const isView = false
let editEnabled = $ref(false) let editEnabled = $ref(false)
const { appInfo } = useGlobal()
const { xWhere, isPkAvail, isSqlView, eventBus } = useSmartsheetStoreOrThrow() const { xWhere, isPkAvail, isSqlView, eventBus } = useSmartsheetStoreOrThrow()
const visibleColLength = $computed(() => fields.value?.length) const visibleColLength = $computed(() => fields.value?.length)
@ -1129,7 +1131,7 @@ function addEmptyRow(row?: number) {
</a-menu-item> </a-menu-item>
<a-menu-item <a-menu-item
v-if="!contextMenuClosing && !contextMenuTarget && data.some((r) => r.rowMeta.selected)" v-if="appInfo.ee && !contextMenuClosing && !contextMenuTarget && data.some((r) => r.rowMeta.selected)"
@click="bulkUpdateDlg = true" @click="bulkUpdateDlg = true"
> >
<div v-e="['a:row:update-bulk']" class="nc-project-menu-item"> <div v-e="['a:row:update-bulk']" class="nc-project-menu-item">

2
packages/nc-lib-gui/package.json

@ -1,6 +1,6 @@
{ {
"name": "nc-lib-gui", "name": "nc-lib-gui",
"version": "0.109.2", "version": "0.109.3",
"description": "NocoDB GUI", "description": "NocoDB GUI",
"author": { "author": {
"name": "NocoDB", "name": "NocoDB",

2
packages/nocodb-sdk/package.json

@ -1,6 +1,6 @@
{ {
"name": "nocodb-sdk", "name": "nocodb-sdk",
"version": "0.109.2", "version": "0.109.3",
"description": "NocoDB SDK", "description": "NocoDB SDK",
"main": "build/main/index.js", "main": "build/main/index.js",
"typings": "build/main/index.d.ts", "typings": "build/main/index.d.ts",

4
packages/nocodb/package.json

@ -1,6 +1,6 @@
{ {
"name": "nocodb", "name": "nocodb",
"version": "0.109.2", "version": "0.109.3",
"description": "NocoDB Backend", "description": "NocoDB Backend",
"main": "dist/bundle.js", "main": "dist/bundle.js",
"author": { "author": {
@ -119,7 +119,7 @@
"mysql2": "^3.2.0", "mysql2": "^3.2.0",
"nanoid": "^3.1.20", "nanoid": "^3.1.20",
"nc-help": "^0.2.88", "nc-help": "^0.2.88",
"nc-lib-gui": "0.109.2", "nc-lib-gui": "0.109.3",
"nc-plugin": "^0.1.3", "nc-plugin": "^0.1.3",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk", "nocodb-sdk": "file:../nocodb-sdk",

25
packages/nocodb/src/version-upgrader/ncXcdbLTARUpgrader.ts

@ -44,6 +44,11 @@ async function upgradeModelRelations({
ncMeta, ncMeta,
); );
// if colOptions not found then skip
if (!colOptions) {
continue;
}
switch (colOptions.type) { switch (colOptions.type) {
case RelationTypes.HAS_MANY: case RelationTypes.HAS_MANY:
{ {
@ -77,17 +82,17 @@ async function upgradeModelRelations({
childTable: relation.tn, childTable: relation.tn,
foreignKeyName: relation.cstn, foreignKeyName: relation.cstn,
}); });
}
// skip postgres since we were already creating the index while creating the relation // skip postgres since we were already creating the index while creating the relation
if (ncMeta.knex.clientType() !== 'pg') { if (ncMeta.knex.clientType() !== 'pg') {
// create a new index for the column // create a new index for the column
const indexArgs = { const indexArgs = {
columns: [relation.cn], columns: [relation.cn],
tn: relation.tn, tn: relation.tn,
non_unique: true, non_unique: true,
}; };
await sqlClient.indexCreate(indexArgs); await sqlClient.indexCreate(indexArgs);
}
} }
} }
break; break;

4
tests/playwright/pages/Account/License.ts

@ -32,6 +32,10 @@ export class AccountLicensePage extends BasePage {
} }
async saveLicenseKey(licenseKey: string) { async saveLicenseKey(licenseKey: string) {
// Kludge: fix me!
// await this.get().waitFor({ state: 'visible' });
await this.rootPage.waitForTimeout(1000);
await this.get().fill(licenseKey); await this.get().fill(licenseKey);
await this.getSaveButton().click(); await this.getSaveButton().click();
await this.verifyToast({ message: 'License key updated' }); await this.verifyToast({ message: 'License key updated' });

149
tests/playwright/tests/db/bulkUpdate.spec.ts → tests/playwright/tests/db/updateBulk.ts

@ -4,8 +4,15 @@ import { DashboardPage } from '../../pages/Dashboard';
import { Api } from 'nocodb-sdk'; import { Api } from 'nocodb-sdk';
import { createDemoTable } from '../../setup/demoTable'; import { createDemoTable } from '../../setup/demoTable';
import { BulkUpdatePage } from '../../pages/Dashboard/BulkUpdate'; import { BulkUpdatePage } from '../../pages/Dashboard/BulkUpdate';
import { AccountLicensePage } from '../../pages/Account/License';
import { AccountPage } from '../../pages/Account';
let bulkUpdateForm: BulkUpdatePage; let bulkUpdateForm: BulkUpdatePage;
let dashboard: DashboardPage;
let context: any;
let api: Api<any>;
let table;
async function updateBulkFields(fields) { async function updateBulkFields(fields) {
// move all fields to active // move all fields to active
for (let i = 0; i < fields.length; i++) { for (let i = 0; i < fields.length; i++) {
@ -21,31 +28,35 @@ async function updateBulkFields(fields) {
await bulkUpdateForm.save({ awaitResponse: true }); await bulkUpdateForm.save({ awaitResponse: true });
} }
test.describe('Bulk update', () => { async function beforeEachInit({ page, tableType }: { page: any; tableType: string }) {
let dashboard: DashboardPage; context = await setup({ page, isEmptyProject: true });
let context: any; dashboard = new DashboardPage(page, context.project);
let api: Api<any>; bulkUpdateForm = dashboard.bulkUpdateForm;
let table; const accountPage: AccountPage = new AccountPage(page);
const accountLicensePage: AccountLicensePage = new AccountLicensePage(accountPage);
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
test.beforeEach(async ({ page }) => { table = await createDemoTable({ context, type: tableType, recordCnt: 50 });
context = await setup({ page, isEmptyProject: true });
dashboard = new DashboardPage(page, context.project); await accountLicensePage.goto();
bulkUpdateForm = dashboard.bulkUpdateForm; await accountLicensePage.saveLicenseKey('1234567890');
await dashboard.goto();
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
table = await createDemoTable({ context, type: 'textBased', recordCnt: 50 }); await dashboard.treeView.openTable({ title: tableType });
await page.reload();
await dashboard.treeView.openTable({ title: 'textBased' }); // Open bulk update form
await dashboard.grid.updateAll();
}
// Open bulk update form test.describe('Bulk update', () => {
await dashboard.grid.updateAll(); test.beforeEach(async ({ page }) => {
await beforeEachInit({ page, tableType: 'textBased' });
}); });
test('General- Click to add & remove', async () => { test('General- Click to add & remove', async () => {
@ -118,30 +129,8 @@ test.describe('Bulk update', () => {
}); });
test.describe('Bulk update', () => { test.describe('Bulk update', () => {
let dashboard: DashboardPage;
let context: any;
let api: Api<any>;
let table;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: true }); await beforeEachInit({ page, tableType: 'numberBased' });
dashboard = new DashboardPage(page, context.project);
bulkUpdateForm = dashboard.bulkUpdateForm;
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
table = await createDemoTable({ context, type: 'numberBased', recordCnt: 50 });
await page.reload();
await dashboard.treeView.openTable({ title: 'numberBased' });
// Open bulk update form
await dashboard.grid.updateAll();
}); });
test('Number based', async () => { test('Number based', async () => {
@ -188,30 +177,8 @@ test.describe('Bulk update', () => {
}); });
test.describe('Bulk update', () => { test.describe('Bulk update', () => {
let dashboard: DashboardPage;
let context: any;
let api: Api<any>;
let table;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: true }); await beforeEachInit({ page, tableType: 'selectBased' });
dashboard = new DashboardPage(page, context.project);
bulkUpdateForm = dashboard.bulkUpdateForm;
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
table = await createDemoTable({ context, type: 'selectBased', recordCnt: 50 });
await page.reload();
await dashboard.treeView.openTable({ title: 'selectBased' });
// Open bulk update form
await dashboard.grid.updateAll();
}); });
test('Select based', async () => { test('Select based', async () => {
@ -251,30 +218,8 @@ test.describe('Bulk update', () => {
}); });
test.describe('Bulk update', () => { test.describe('Bulk update', () => {
let dashboard: DashboardPage;
let context: any;
let api: Api<any>;
let table;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: true }); await beforeEachInit({ page, tableType: 'miscellaneous' });
dashboard = new DashboardPage(page, context.project);
bulkUpdateForm = dashboard.bulkUpdateForm;
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
table = await createDemoTable({ context, type: 'miscellaneous', recordCnt: 50 });
await page.reload();
await dashboard.treeView.openTable({ title: 'miscellaneous' });
// Open bulk update form
await dashboard.grid.updateAll();
}); });
test('Miscellaneous (Checkbox, attachment)', async () => { test('Miscellaneous (Checkbox, attachment)', async () => {
@ -314,30 +259,8 @@ test.describe('Bulk update', () => {
}); });
test.describe('Bulk update', () => { test.describe('Bulk update', () => {
let dashboard: DashboardPage;
let context: any;
let api: Api<any>;
let table;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: true }); await beforeEachInit({ page, tableType: 'dateTimeBased' });
dashboard = new DashboardPage(page, context.project);
bulkUpdateForm = dashboard.bulkUpdateForm;
api = new Api({
baseURL: `http://localhost:8080/`,
headers: {
'xc-auth': context.token,
},
});
table = await createDemoTable({ context, type: 'dateTimeBased', recordCnt: 50 });
await page.reload();
await dashboard.treeView.openTable({ title: 'dateTimeBased' });
// Open bulk update form
await dashboard.grid.updateAll();
}); });
test('Date Time Based', async () => { test('Date Time Based', async () => {
Loading…
Cancel
Save