-
Notifications
You must be signed in to change notification settings - Fork 510
dbeaver/pro#7023 [CB] Find and replace functionality in the data editor #4076
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: devel
Are you sure you want to change the base?
dbeaver/pro#7023 [CB] Find and replace functionality in the data editor #4076
Conversation
…o UI-kit add chevron Icon to UI-kit (used in Search Panel)
…thods to DataGridRef
…p in DataGridSearchStore
…nd data grid table
…or' of github.com:dbeaver/cloudbeaver into 7023-cb-find-and-replace-functionality-in-the-data-editor
after some tests, added only debounce for user input, even on the big tables sync search doesn't show large degradation of ux/response time
webapp/common-react/@dbeaver/ui-kit/src/SearchPanel/SearchPanel.tsx
Outdated
Show resolved
Hide resolved
| 'rdg-cell-search-match': searchState.isMatch(rowIdx, colIdx), | ||
| 'rdg-cell-search-active': searchState.isActiveMatch(rowIdx, colIdx), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very heavy operation, you should put them in the computed or consider having a fast computed table on every search (so you can directly get information from this table without search operations, like Map<number, Map<number, SearchInfo>>
| const SEARCH_DEBOUNCE_MS = 300; | ||
|
|
||
|
|
||
| export class DataGridSearchStore implements IDataGridSearchStateInternal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be overcomplicated. Maybe it's not a good idea to complete this task right now, but better to decompose it into smaller tasks and plan its implementation again. We can keep transfer of the search panel to the ui-kit but it needs some improvements (localization)
… SearchPanel export
…usage in data grid components
…pressEditorSelection
…GridSearch implementation
| scrollToCell: (position: Partial<ICellPosition>) => { | ||
| innerGridRef.current?.scrollToCell({ idx: position.colIdx && dndHeaderContext.getDataColIdx(position.colIdx), rowIdx: position.rowIdx }); | ||
| }, | ||
| scrollToDataCell: (position: Partial<ICellPosition> & { colIdx?: number }) => { | ||
| const virtualIdx = position.colIdx !== undefined ? dndHeaderContext.getVirtualColIdx(position.colIdx) : undefined; | ||
| innerGridRef.current?.scrollToCell({ idx: virtualIdx, rowIdx: position.rowIdx }); | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scrollToCell should be enough, I think that we need to fix its behaviour because of dndHeaderContext.getVirtualColIdx
| scrollToDataCell: (position: Partial<ICellPosition> & { colIdx?: number }) => void; | ||
| openEditor: (position: ICellPosition) => void; | ||
| getColumnsOrdered: () => readonly CalculatedColumn<IInnerRow, unknown>[]; | ||
| getDataColIdxByKey: (key: string) => number | null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getDataColIdxByKey should not be exposed
| getRowCount: () => tableData.rows.length, | ||
| getColumnCount: () => tableData.columns.length, | ||
| getCellText: (rowIdx: number, colIdx: number) => { | ||
| const row = tableData.rows[rowIdx]; | ||
| const column = tableData.getColumn(colIdx)?.key; | ||
| if (!row || !column) { | ||
| return ''; | ||
| } | ||
| return tableData.format.getText(tableData.format.get({ row, column })); | ||
| }, | ||
| setCellValue: (rowIdx: number, colIdx: number, value: string) => { | ||
| const row = tableData.rows[rowIdx]; | ||
| const column = tableData.getColumn(colIdx)?.key; | ||
| if (!row || !column) { | ||
| return; | ||
| } | ||
| tableData.editor?.set({ row, column }, value); | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all this data is available in the common-react/@dbeaver/react-data-grid/src/DataGrid.tsx
| export class GridSearchService { | ||
| private readonly stores = new Map<string, GridSearchStore>(); | ||
|
|
||
| getOrCreateStore(key: string): GridSearchStore { | ||
| if (this.stores.has(key)) { | ||
| return this.stores.get(key)!; | ||
| } | ||
|
|
||
| const store = new GridSearchStore(createDefaultSearchCache()); | ||
| this.stores.set(key, store); | ||
| return store; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that we need a global service and store for this feature, because for different tables state can be stored differently
| this.reactionDisposers.push( | ||
| reaction( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not use MobX here; it's better to use imperative logic in such cases
… in grid interfaces
Screen.Recording.2026-01-21.at.11.02.45.mov