Fix click to show document issue. Table doesn't auto-select first document anymore. (#1864)
This commit is contained in:
parent
416743c548
commit
06d4829422
|
@ -86,6 +86,9 @@ export class DocumentsTabV2 extends TabsBase {
|
|||
}
|
||||
}
|
||||
|
||||
// Use this value to initialize the very time the component is rendered
|
||||
const RESET_INDEX = -1;
|
||||
|
||||
const filterButtonStyle: CSSProperties = {
|
||||
marginLeft: 8,
|
||||
};
|
||||
|
@ -465,7 +468,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
const [selectedDocumentContentBaseline, setSelectedDocumentContentBaseline] = useState<string>(undefined);
|
||||
|
||||
// Table user clicked on this row
|
||||
const [clickedRow, setClickedRow] = useState<TableRowId>(undefined);
|
||||
const [clickedRowIndex, setClickedRowIndex] = useState<number>(RESET_INDEX);
|
||||
// Table multiple selection
|
||||
const [selectedRows, setSelectedRows] = React.useState<Set<TableRowId>>(() => new Set<TableRowId>([0]));
|
||||
|
||||
|
@ -490,6 +493,23 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
}
|
||||
}, [isFilterFocused]);
|
||||
|
||||
// Clicked row must be defined
|
||||
useEffect(() => {
|
||||
if (documentIds.length > 0) {
|
||||
let currentClickedRowIndex = clickedRowIndex;
|
||||
if (
|
||||
(currentClickedRowIndex === RESET_INDEX &&
|
||||
editorState === ViewModels.DocumentExplorerState.noDocumentSelected) ||
|
||||
currentClickedRowIndex > documentIds.length - 1
|
||||
) {
|
||||
// reset clicked row or the current clicked row is out of bounds
|
||||
currentClickedRowIndex = 0;
|
||||
setSelectedRows(new Set([0]));
|
||||
onDocumentClicked(currentClickedRowIndex, documentIds);
|
||||
}
|
||||
}
|
||||
}, [documentIds, clickedRowIndex, editorState]);
|
||||
|
||||
let lastFilterContents = ['WHERE c.id = "foo"', "ORDER BY c._ts DESC", 'WHERE c.id = "foo" ORDER BY c._ts DESC'];
|
||||
|
||||
const applyFilterButton = {
|
||||
|
@ -550,7 +570,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
|
||||
if (!documentsIterator) {
|
||||
try {
|
||||
refreshDocumentsGrid();
|
||||
refreshDocumentsGrid(false);
|
||||
} catch (error) {
|
||||
if (onLoadStartKey !== null && onLoadStartKey !== undefined) {
|
||||
TelemetryProcessor.traceFailure(
|
||||
|
@ -657,7 +677,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
setSelectedDocumentContent(defaultDocument);
|
||||
setSelectedDocumentContentBaseline(defaultDocument);
|
||||
setSelectedRows(new Set());
|
||||
setClickedRow(undefined);
|
||||
setClickedRowIndex(undefined);
|
||||
setEditorState(ViewModels.DocumentExplorerState.newDocumentValid);
|
||||
};
|
||||
|
||||
|
@ -673,8 +693,10 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
return createDocument(_collection, document)
|
||||
.then(
|
||||
(savedDocument: DataModels.DocumentId) => {
|
||||
// TODO: Reuse initDocumentEditor() to remove code duplication
|
||||
const value: string = renderObjectForEditor(savedDocument || {}, null, 4);
|
||||
setSelectedDocumentContentBaseline(value);
|
||||
setSelectedDocumentContent(value);
|
||||
setInitialDocumentContent(value);
|
||||
const partitionKeyValueArray: PartitionKey[] = extractPartitionKeyValues(
|
||||
savedDocument,
|
||||
|
@ -738,7 +760,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
partitionKey as PartitionKeyDefinition,
|
||||
);
|
||||
|
||||
const selectedDocumentId = documentIds[clickedRow as number];
|
||||
const selectedDocumentId = documentIds[clickedRowIndex as number];
|
||||
selectedDocumentId.partitionKeyValue = partitionKeyValueArray;
|
||||
|
||||
onExecutionErrorChange(false);
|
||||
|
@ -786,7 +808,15 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
},
|
||||
)
|
||||
.finally(() => setIsExecuting(false));
|
||||
}, [onExecutionErrorChange, tabTitle, selectedDocumentContent, _collection, partitionKey, documentIds, clickedRow]);
|
||||
}, [
|
||||
onExecutionErrorChange,
|
||||
tabTitle,
|
||||
selectedDocumentContent,
|
||||
_collection,
|
||||
partitionKey,
|
||||
documentIds,
|
||||
clickedRowIndex,
|
||||
]);
|
||||
|
||||
const onRevertExistingDocumentClick = useCallback((): void => {
|
||||
setSelectedDocumentContentBaseline(initialDocumentContent);
|
||||
|
@ -850,7 +880,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
setDocumentIds(newDocumentIds);
|
||||
|
||||
setSelectedDocumentContent(undefined);
|
||||
setClickedRow(undefined);
|
||||
setClickedRowIndex(undefined);
|
||||
setSelectedRows(new Set());
|
||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||
useDialog
|
||||
|
@ -974,8 +1004,27 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
return true;
|
||||
};
|
||||
|
||||
const updateDocumentIds = (newDocumentsIds: DocumentId[]): void => {
|
||||
setDocumentIds(newDocumentsIds);
|
||||
|
||||
if (onLoadStartKey !== null && onLoadStartKey !== undefined) {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.Tab,
|
||||
{
|
||||
databaseName: _collection.databaseId,
|
||||
collectionName: _collection.id(),
|
||||
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle,
|
||||
},
|
||||
onLoadStartKey,
|
||||
);
|
||||
setOnLoadStartKey(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
let loadNextPage = useCallback(
|
||||
(iterator: QueryIterator<ItemDefinition & Resource>, applyFilterButtonClicked?: boolean): Promise<unknown> => {
|
||||
(iterator: QueryIterator<ItemDefinition & Resource>, applyFilterButtonClicked: boolean): Promise<unknown> => {
|
||||
setIsExecuting(true);
|
||||
onExecutionErrorChange(false);
|
||||
let automaticallyCancelQueryAfterTimeout: boolean;
|
||||
|
@ -1028,21 +1077,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
});
|
||||
|
||||
const merged = currentDocuments.concat(nextDocumentIds);
|
||||
setDocumentIds(merged);
|
||||
if (onLoadStartKey !== null && onLoadStartKey !== undefined) {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.Tab,
|
||||
{
|
||||
databaseName: _collection.databaseId,
|
||||
collectionName: _collection.id(),
|
||||
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle,
|
||||
},
|
||||
onLoadStartKey,
|
||||
);
|
||||
setOnLoadStartKey(undefined);
|
||||
}
|
||||
updateDocumentIds(merged);
|
||||
},
|
||||
(error) => {
|
||||
onExecutionErrorChange(true);
|
||||
|
@ -1112,7 +1147,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
const onLoadMoreKeyInput: KeyboardEventHandler<HTMLAnchorElement> = (event) => {
|
||||
if (event.key === " " || event.key === "Enter") {
|
||||
const focusElement = event.target as HTMLElement;
|
||||
loadNextPage(documentsIterator.iterator);
|
||||
loadNextPage(documentsIterator.iterator, false);
|
||||
focusElement && focusElement.focus();
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
@ -1158,10 +1193,10 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
* Document has been clicked on in table
|
||||
* @param tabRowId
|
||||
*/
|
||||
const onDocumentClicked = (tabRowId: TableRowId) => {
|
||||
const onDocumentClicked = (tabRowId: TableRowId, currentDocumentIds: DocumentId[]) => {
|
||||
const index = tabRowId as number;
|
||||
setClickedRow(index);
|
||||
loadDocument(documentIds[index]);
|
||||
setClickedRowIndex(index);
|
||||
loadDocument(currentDocumentIds[index]);
|
||||
};
|
||||
|
||||
let loadDocument = (documentId: DocumentId) =>
|
||||
|
@ -1267,13 +1302,13 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
confirmDiscardingChange(() => {
|
||||
if (selectedRows.size === 0) {
|
||||
setSelectedDocumentContent(undefined);
|
||||
setClickedRow(undefined);
|
||||
setClickedRowIndex(undefined);
|
||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||
}
|
||||
|
||||
// Find if clickedRow is in selectedRows.If not, clear clickedRow and content
|
||||
if (clickedRow !== undefined && !selectedRows.has(clickedRow)) {
|
||||
setClickedRow(undefined);
|
||||
if (clickedRowIndex !== undefined && !selectedRows.has(clickedRowIndex)) {
|
||||
setClickedRowIndex(undefined);
|
||||
setSelectedDocumentContent(undefined);
|
||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||
}
|
||||
|
@ -1281,6 +1316,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
// If only one selection, we consider as a click
|
||||
if (selectedRows.size === 1) {
|
||||
setEditorState(ViewModels.DocumentExplorerState.existingDocumentNoEdits);
|
||||
onDocumentClicked(selectedRows.values().next().value, documentIds);
|
||||
}
|
||||
|
||||
setSelectedRows(selectedRows);
|
||||
|
@ -1441,6 +1477,8 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
|
||||
const value: string = renderObjectForEditor(savedDocument || {}, null, 4);
|
||||
setSelectedDocumentContentBaseline(value);
|
||||
setSelectedDocumentContent(value);
|
||||
setInitialDocumentContent(value);
|
||||
|
||||
setDocumentIds(ids);
|
||||
setEditorState(ViewModels.DocumentExplorerState.existingDocumentNoEdits);
|
||||
|
@ -1491,7 +1529,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
tabTitle,
|
||||
});
|
||||
|
||||
const selectedDocumentId = documentIds[clickedRow as number];
|
||||
const selectedDocumentId = documentIds[clickedRowIndex as number];
|
||||
return MongoProxyClient.updateDocument(
|
||||
_collection.databaseId,
|
||||
_collection as ViewModels.Collection,
|
||||
|
@ -1559,8 +1597,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
.then(
|
||||
({ continuationToken: newContinuationToken, documents }) => {
|
||||
setContinuationToken(newContinuationToken);
|
||||
let currentDocuments = documentIds;
|
||||
const currentDocumentsRids = currentDocuments.map((currentDocument) => currentDocument.rid);
|
||||
const currentDocumentsRids = documentIds.map((currentDocument) => currentDocument.rid);
|
||||
const nextDocumentIds = documents
|
||||
.filter((d: { _rid: string }) => {
|
||||
return currentDocumentsRids.indexOf(d._rid) < 0;
|
||||
|
@ -1569,34 +1606,10 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
.map((rawDocument: any) => {
|
||||
const partitionKeyValue = rawDocument._partitionKeyValue;
|
||||
return newDocumentId(rawDocument, partitionKeyProperties, [partitionKeyValue]);
|
||||
// return new DocumentId(this, rawDocument, [partitionKeyValue]);
|
||||
});
|
||||
|
||||
const merged = currentDocuments.concat(nextDocumentIds);
|
||||
|
||||
setDocumentIds(merged);
|
||||
currentDocuments = merged;
|
||||
|
||||
if (filterContent.length > 0 && currentDocuments.length > 0) {
|
||||
currentDocuments[0].click();
|
||||
} else {
|
||||
setSelectedDocumentContent("");
|
||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||
}
|
||||
if (_onLoadStartKey !== null && _onLoadStartKey !== undefined) {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.Tab,
|
||||
{
|
||||
databaseName: _collection.databaseId,
|
||||
collectionName: _collection.id(),
|
||||
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle,
|
||||
},
|
||||
_onLoadStartKey,
|
||||
);
|
||||
setOnLoadStartKey(undefined);
|
||||
}
|
||||
const merged = documentIds.concat(nextDocumentIds);
|
||||
updateDocumentIds(merged);
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(error: any) => {
|
||||
|
@ -1624,7 +1637,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
// ***************** Mongo ***************************
|
||||
|
||||
const refreshDocumentsGrid = useCallback(
|
||||
async (applyFilterButtonPressed?: boolean): Promise<void> => {
|
||||
(applyFilterButtonPressed: boolean): void => {
|
||||
// clear documents grid
|
||||
setDocumentIds([]);
|
||||
setContinuationToken(undefined); // For mongo
|
||||
|
@ -1638,6 +1651,13 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
// collapse filter
|
||||
setAppliedFilter(filterContent);
|
||||
setIsFilterExpanded(false);
|
||||
|
||||
// If apply filter is pressed, reset current selected document
|
||||
if (applyFilterButtonPressed) {
|
||||
setClickedRowIndex(RESET_INDEX);
|
||||
setEditorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||
setSelectedDocumentContent(undefined);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
useDialog.getState().showOkModalDialog("Refresh documents grid failed", getErrorMessage(error));
|
||||
|
@ -1774,7 +1794,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
>
|
||||
<DocumentsTableComponent
|
||||
items={tableItems}
|
||||
onItemClicked={onDocumentClicked}
|
||||
onItemClicked={(index) => onDocumentClicked(index, documentIds)}
|
||||
onSelectedRowsChange={onSelectedRowsChange}
|
||||
selectedRows={selectedRows}
|
||||
size={tableContainerSizePx}
|
||||
|
|
|
@ -25,7 +25,7 @@ import {
|
|||
import { NormalizedEventKey } from "Common/Constants";
|
||||
import { selectionHelper } from "Explorer/Tabs/DocumentsTabV2/SelectionHelper";
|
||||
import { isEnvironmentCtrlPressed, isEnvironmentShiftPressed } from "Utils/KeyboardUtils";
|
||||
import React, { useCallback, useEffect, useMemo } from "react";
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import { FixedSizeList as List, ListChildComponentProps } from "react-window";
|
||||
|
||||
export type DocumentsTableComponentItem = {
|
||||
|
@ -59,7 +59,6 @@ interface ReactWindowRenderFnProps extends ListChildComponentProps {
|
|||
|
||||
export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> = ({
|
||||
items,
|
||||
onItemClicked,
|
||||
onSelectedRowsChange,
|
||||
selectedRows,
|
||||
style,
|
||||
|
@ -67,8 +66,6 @@ export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> =
|
|||
columnHeaders,
|
||||
isSelectionDisabled,
|
||||
}: IDocumentsTableComponentProps) => {
|
||||
const [activeItemIndex, setActiveItemIndex] = React.useState<number>(undefined);
|
||||
|
||||
const initialSizingOptions: TableColumnSizingOptions = {
|
||||
id: {
|
||||
idealWidth: 280,
|
||||
|
@ -250,18 +247,6 @@ export const DocumentsTableComponent: React.FC<IDocumentsTableComponentProps> =
|
|||
[toggleAllRows],
|
||||
);
|
||||
|
||||
// Load document depending on selection
|
||||
useEffect(() => {
|
||||
if (selectedRows.size === 1 && items.length > 0) {
|
||||
const newActiveItemIndex = selectedRows.values().next().value;
|
||||
if (newActiveItemIndex !== activeItemIndex) {
|
||||
onItemClicked(newActiveItemIndex);
|
||||
setActiveItemIndex(newActiveItemIndex);
|
||||
setSelectionStartIndex(newActiveItemIndex);
|
||||
}
|
||||
}
|
||||
}, [selectedRows, items, activeItemIndex, onItemClicked]);
|
||||
|
||||
// Cell keyboard navigation
|
||||
const keyboardNavAttr = useArrowNavigationGroup({ axis: "grid" });
|
||||
|
||||
|
|
Loading…
Reference in New Issue