From 7629363050eae5f4d2299e8cddd8fb8e25f3fc0a Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Mon, 22 May 2023 17:48:55 +0800 Subject: [PATCH 1/2] fix(nc-gui): incorrect shared form logic --- .../nc-gui/composables/useSharedFormViewStore.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/nc-gui/composables/useSharedFormViewStore.ts b/packages/nc-gui/composables/useSharedFormViewStore.ts index fd8151c437..db93cf4b39 100644 --- a/packages/nc-gui/composables/useSharedFormViewStore.ts +++ b/packages/nc-gui/composables/useSharedFormViewStore.ts @@ -101,18 +101,10 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share {} as Record, ) - let order = 1 - - columns.value = meta?.value?.columns - ?.map((c: Record) => ({ - ...c, - fk_column_id: c.id, - fk_view_id: viewMeta.id, - ...(fieldById[c.id] ? fieldById[c.id] : {}), - order: (fieldById[c.id] && fieldById[c.id].order) || order++, - id: fieldById[c.id] && fieldById[c.id].id, - })) - .sort((a: Record, b: Record) => a.order - b.order) as Record[] + columns.value = viewMeta.model?.columns?.map((c) => ({ + ...c, + description: fieldById[c.id].description, + })) const _sharedViewMeta = (viewMeta as any).meta sharedViewMeta.value = isString(_sharedViewMeta) ? JSON.parse(_sharedViewMeta) : _sharedViewMeta From 37331cd803aae5c3763eead89b03bf45e94090f6 Mon Sep 17 00:00:00 2001 From: Raju Udava <86527202+dstala@users.noreply.github.com> Date: Mon, 22 May 2023 15:51:12 +0530 Subject: [PATCH 2/2] test: LTAR verification in shared form Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com> --- tests/playwright/pages/SharedForm/index.ts | 35 ++++++ tests/playwright/tests/db/viewForm.spec.ts | 126 +++++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/tests/playwright/pages/SharedForm/index.ts b/tests/playwright/pages/SharedForm/index.ts index 2e27d08c94..0d6a32c2c5 100644 --- a/tests/playwright/pages/SharedForm/index.ts +++ b/tests/playwright/pages/SharedForm/index.ts @@ -29,4 +29,39 @@ export class SharedFormPage extends BasePage { }) ).toBeVisible(); } + + async clickLinkToChildList() { + await this.get().locator('button[data-testid="nc-child-list-button-link-to"]').click(); + } + + async verifyChildList(cardTitle?: string[]) { + await this.get().locator('.nc-modal-link-record').waitFor(); + const linkRecord = await this.get(); + + // DOM element validation + // title: Link Record + // button: Add new record + // icon: reload + await expect(this.get().locator(`.ant-modal-title`)).toHaveText(`Link record`); + + // add new record option is not available for shared form + await expect(await linkRecord.locator(`button:has-text("Add new record")`).isVisible()).toBeFalsy(); + + await expect(await linkRecord.locator(`.nc-reload`).isVisible()).toBeTruthy(); + // placeholder: Filter query + await expect(await linkRecord.locator(`[placeholder="Filter query"]`).isVisible()).toBeTruthy(); + + { + const childList = linkRecord.locator(`.ant-card`); + const childCards = await childList.count(); + await expect(childCards).toEqual(cardTitle.length); + for (let i = 0; i < cardTitle.length; i++) { + await expect(await childList.nth(i).textContent()).toContain(cardTitle[i]); + } + } + } + + async selectChildList(cardTitle: string) { + await this.get().locator(`.ant-card:has-text("${cardTitle}"):visible`).click(); + } } diff --git a/tests/playwright/tests/db/viewForm.spec.ts b/tests/playwright/tests/db/viewForm.spec.ts index 558905dde0..d927ee8dc8 100644 --- a/tests/playwright/tests/db/viewForm.spec.ts +++ b/tests/playwright/tests/db/viewForm.spec.ts @@ -5,6 +5,8 @@ import { FormPage } from '../../pages/Dashboard/Form'; import { SharedFormPage } from '../../pages/SharedForm'; import { AccountPage } from '../../pages/Account'; import { AccountAppStorePage } from '../../pages/Account/AppStore'; +import { Api, UITypes } from 'nocodb-sdk'; +let api: Api; // todo: Move most of the ui actions to page object and await on the api response test.describe('Form view', () => { @@ -238,3 +240,127 @@ test.describe('Form view', () => { await sharedForm.verifySuccessMessage(); }); }); + +test.describe('Form view with LTAR', () => { + let dashboard: DashboardPage; + let form: FormPage; + let context: any; + + let cityTable: any, countryTable: any; + + test.beforeEach(async ({ page }) => { + context = await setup({ page, isEmptyProject: true }); + dashboard = new DashboardPage(page, context.project); + form = dashboard.form; + + api = new Api({ + baseURL: `http://localhost:8080/`, + headers: { + 'xc-auth': context.token, + }, + }); + + const cityColumns = [ + { + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, + }, + { + column_name: 'City', + title: 'City', + uidt: UITypes.SingleLineText, + pv: true, + }, + ]; + const countryColumns = [ + { + column_name: 'Id', + title: 'Id', + uidt: UITypes.ID, + }, + { + column_name: 'Country', + title: 'Country', + uidt: UITypes.SingleLineText, + pv: true, + }, + ]; + + try { + const project = await api.project.read(context.project.id); + cityTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { + table_name: 'City', + title: 'City', + columns: cityColumns, + }); + countryTable = await api.base.tableCreate(context.project.id, project.bases?.[0].id, { + table_name: 'Country', + title: 'Country', + columns: countryColumns, + }); + + const cityRowAttributes = [{ City: 'Atlanta' }, { City: 'Pune' }, { City: 'London' }, { City: 'Sydney' }]; + await api.dbTableRow.bulkCreate('noco', context.project.id, cityTable.id, cityRowAttributes); + + const countryRowAttributes = [{ Country: 'India' }, { Country: 'UK' }, { Country: 'Australia' }]; + await api.dbTableRow.bulkCreate('noco', context.project.id, countryTable.id, countryRowAttributes); + + // create LTAR Country has-many City + await api.dbTableColumn.create(countryTable.id, { + column_name: 'CityList', + title: 'CityList', + uidt: UITypes.LinkToAnotherRecord, + parentId: countryTable.id, + childId: cityTable.id, + type: 'hm', + }); + + // await api.dbTableRow.nestedAdd('noco', context.project.id, countryTable.id, '1', 'hm', 'CityList', '1'); + } catch (e) { + console.log(e); + } + + // reload page after api calls + await page.reload(); + }); + + test('Form view with LTAR', async () => { + await dashboard.treeView.openTable({ title: 'Country' }); + + const url = dashboard.rootPage.url(); + + await dashboard.viewSidebar.createFormView({ title: 'NewForm' }); + await dashboard.form.toolbar.clickShareView(); + const formLink = await dashboard.form.toolbar.shareView.getShareLink(); + + await dashboard.rootPage.goto(formLink); + + const sharedForm = new SharedFormPage(dashboard.rootPage); + await sharedForm.cell.fillText({ + columnHeader: 'Country', + text: 'USA', + }); + await sharedForm.clickLinkToChildList(); + await sharedForm.verifyChildList(['Atlanta', 'Pune', 'London', 'Sydney']); + await sharedForm.selectChildList('Atlanta'); + + await sharedForm.submit(); + await sharedForm.verifySuccessMessage(); + + await dashboard.rootPage.goto(url); + await dashboard.viewSidebar.openView({ title: 'Country' }); + + await dashboard.grid.cell.verify({ + index: 3, + columnHeader: 'Country', + value: 'USA', + }); + await dashboard.grid.cell.verifyVirtualCell({ + index: 3, + columnHeader: 'CityList', + count: 1, + value: ['Atlanta'], + }); + }); +});