diff --git a/packages/nc-gui/components/smartsheet/toolbar/SearchData.vue b/packages/nc-gui/components/smartsheet/toolbar/SearchData.vue
index 6e56d64f81..24c6468aec 100644
--- a/packages/nc-gui/components/smartsheet/toolbar/SearchData.vue
+++ b/packages/nc-gui/components/smartsheet/toolbar/SearchData.vue
@@ -17,7 +17,7 @@ const { meta } = useSmartsheetStoreOrThrow()
const activeView = inject(ActiveViewInj, ref())
-const { search, loadFieldQuery } = useFieldQuery(activeView)
+const { search, loadFieldQuery } = useFieldQuery()
const isDropdownOpen = ref(false)
@@ -36,7 +36,7 @@ watch(
() => activeView.value?.id,
(n, o) => {
if (n !== o) {
- loadFieldQuery(activeView)
+ loadFieldQuery(activeView.value?.id)
}
},
{ immediate: true },
@@ -76,6 +76,7 @@ function onPressEnter() {
class="max-w-[200px]"
:placeholder="$t('placeholder.filterQuery')"
:bordered="false"
+ data-testid="search-data-input"
@press-enter="onPressEnter"
>
diff --git a/packages/nc-gui/composables/useFieldQuery.ts b/packages/nc-gui/composables/useFieldQuery.ts
index b18f488ce5..564742dcf2 100644
--- a/packages/nc-gui/composables/useFieldQuery.ts
+++ b/packages/nc-gui/composables/useFieldQuery.ts
@@ -1,8 +1,6 @@
-import type { Ref } from 'vue'
-import type { ViewType } from 'nocodb-sdk'
import { useState } from '#imports'
-export function useFieldQuery(view: Ref) {
+export function useFieldQuery() {
// initial search object
const emptyFieldQueryObj = {
field: '',
@@ -13,21 +11,16 @@ export function useFieldQuery(view: Ref) {
const searchMap = useState>('field-query-search-map', () => ({}))
// the fieldQueryObj under the current view
- const search = useState<{ field: string; query: string }>('field-query-search', () => emptyFieldQueryObj)
-
- // map current view id to emptyFieldQueryObj
- if (view?.value?.id) {
- searchMap.value[view!.value!.id] = search.value
- }
+ const search = useState<{ field: string; query: string }>('field-query-search', () => ({ ...emptyFieldQueryObj }))
// retrieve the fieldQueryObj of the given view id
// if it is not found in `searchMap`, init with emptyFieldQueryObj
- const loadFieldQuery = (view: Ref) => {
- if (!view.value?.id) return
- if (!(view!.value!.id in searchMap.value)) {
- searchMap.value[view!.value!.id!] = emptyFieldQueryObj
+ const loadFieldQuery = (id?: string) => {
+ if (!id) return
+ if (!(id in searchMap.value)) {
+ searchMap.value[id] = { ...emptyFieldQueryObj }
}
- search.value = searchMap.value[view!.value!.id!]
+ search.value = searchMap.value[id]
}
return { search, loadFieldQuery }
diff --git a/packages/nc-gui/composables/useSmartsheetStore.ts b/packages/nc-gui/composables/useSmartsheetStore.ts
index a0982e4b66..d76791a360 100644
--- a/packages/nc-gui/composables/useSmartsheetStore.ts
+++ b/packages/nc-gui/composables/useSmartsheetStore.ts
@@ -19,7 +19,7 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
const cellRefs = ref([])
- const { search } = useFieldQuery(view)
+ const { search } = useFieldQuery()
const eventBus = useEventBus(Symbol('SmartsheetStore'))
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/SearchData.ts b/tests/playwright/pages/Dashboard/common/Toolbar/SearchData.ts
new file mode 100644
index 0000000000..f592407728
--- /dev/null
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/SearchData.ts
@@ -0,0 +1,20 @@
+import BasePage from '../../../Base';
+import { ToolbarPage } from './index';
+import { expect } from '@playwright/test';
+
+export class ToolbarSearchDataPage extends BasePage {
+ readonly toolbar: ToolbarPage;
+
+ constructor(toolbar: ToolbarPage) {
+ super(toolbar.rootPage);
+ this.toolbar = toolbar;
+ }
+
+ get() {
+ return this.rootPage.getByTestId('search-data-input');
+ }
+
+ async verify(query: string) {
+ await expect(await this.get().inputValue()).toBe(query);
+ }
+}
diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/index.ts b/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
index c97c263051..e5e2ccafbf 100644
--- a/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
+++ b/tests/playwright/pages/Dashboard/common/Toolbar/index.ts
@@ -13,6 +13,7 @@ import { KanbanPage } from '../../Kanban';
import { FormPage } from '../../Form';
import { ToolbarStackbyPage } from './StackBy';
import { ToolbarAddEditStackPage } from './AddEditKanbanStack';
+import { ToolbarSearchDataPage } from './SearchData';
export class ToolbarPage extends BasePage {
readonly parent: GridPage | GalleryPage | FormPage | KanbanPage;
@@ -24,6 +25,7 @@ export class ToolbarPage extends BasePage {
readonly actions: ToolbarActionsPage;
readonly stackBy: ToolbarStackbyPage;
readonly addEditStack: ToolbarAddEditStackPage;
+ readonly searchData: ToolbarSearchDataPage;
constructor(parent: GridPage | GalleryPage | FormPage | KanbanPage) {
super(parent.rootPage);
@@ -36,6 +38,7 @@ export class ToolbarPage extends BasePage {
this.actions = new ToolbarActionsPage(this);
this.stackBy = new ToolbarStackbyPage(this);
this.addEditStack = new ToolbarAddEditStackPage(this);
+ this.searchData = new ToolbarSearchDataPage(this);
}
get() {
diff --git a/tests/playwright/tests/views.spec.ts b/tests/playwright/tests/views.spec.ts
index 6db52ecc57..c823384eed 100644
--- a/tests/playwright/tests/views.spec.ts
+++ b/tests/playwright/tests/views.spec.ts
@@ -1,14 +1,17 @@
-import { test } from '@playwright/test';
+import { expect, test } from '@playwright/test';
import { DashboardPage } from '../pages/Dashboard';
+import { ToolbarPage } from '../pages/Dashboard/common/Toolbar';
import setup from '../setup';
test.describe('Views CRUD Operations', () => {
let dashboard: DashboardPage;
let context: any;
+ let toolbar: ToolbarPage;
test.beforeEach(async ({ page }) => {
context = await setup({ page });
dashboard = new DashboardPage(page, context.project);
+ toolbar = dashboard.grid.toolbar;
});
test('Create views, reorder and delete', async () => {
@@ -73,4 +76,48 @@ test.describe('Views CRUD Operations', () => {
index: 1,
});
});
+
+ test('Save search query for each table and view', async () => {
+ await dashboard.treeView.openTable({ title: 'City' });
+
+ await toolbar.searchData.verify('');
+ await toolbar.searchData.get().fill('City-City');
+ await toolbar.searchData.verify('City-City');
+
+ await dashboard.viewSidebar.createGridView({ title: 'CityGrid' });
+ await toolbar.searchData.verify('');
+ await toolbar.searchData.get().fill('City-CityGrid');
+ await toolbar.searchData.verify('City-CityGrid');
+
+ await dashboard.viewSidebar.createGridView({ title: 'CityGrid2' });
+ await toolbar.searchData.verify('');
+ await toolbar.searchData.get().fill('City-CityGrid2');
+ await toolbar.searchData.verify('City-CityGrid2');
+
+ await dashboard.viewSidebar.openView({ title: 'CityGrid' });
+ await expect(dashboard.get().locator('[data-testid="grid-load-spinner"]')).toBeVisible();
+ await dashboard.grid.waitLoading();
+ await toolbar.searchData.verify('City-CityGrid');
+
+ await dashboard.viewSidebar.openView({ title: 'City' });
+ await expect(dashboard.get().locator('[data-testid="grid-load-spinner"]')).toBeVisible();
+ await dashboard.grid.waitLoading();
+ await toolbar.searchData.verify('City-City');
+
+ await dashboard.treeView.openTable({ title: 'Actor' });
+ await toolbar.searchData.verify('');
+
+ await dashboard.viewSidebar.createGridView({ title: 'ActorGrid' });
+ await toolbar.searchData.verify('');
+ await toolbar.searchData.get().fill('Actor-ActorGrid');
+ await toolbar.searchData.verify('Actor-ActorGrid');
+
+ await dashboard.viewSidebar.openView({ title: 'Actor' });
+ await expect(dashboard.get().locator('[data-testid="grid-load-spinner"]')).toBeVisible();
+ await dashboard.grid.waitLoading();
+ await toolbar.searchData.verify('');
+
+ await dashboard.treeView.openTable({ title: 'City', mode: '' });
+ await toolbar.searchData.verify('City-City');
+ });
});