fix(frontend): guard startup and loading shortcuts
This commit is contained in:
17 files changed
+420
-15
No files matched your search
@@ -187,7 +187,8 @@ import { useToast } from "@/composables/useToast";
|
||||
import { useNavigationTargets } from "@/composables/useNavigationTargets";
|
||||
import { useDataGridExport, type MongoCopyUpdateTarget } from "@/composables/useDataGridExport";
|
||||
import { eventTargetAllowsNativeClipboard, isPlainClipboardShortcut, readTextFromClipboard } from "@/lib/common/clipboard";
|
||||
import { claimDataGridPaste, clearDataGridClipboardCopy, parseDataGridClipboard, planDataGridPaste } from "@/lib/dataGrid/dataGridClipboard";
|
||||
import { claimDataGridPaste, claimDataGridSelectAll, clearDataGridClipboardCopy, parseDataGridClipboard, planDataGridPaste } from "@/lib/dataGrid/dataGridClipboard";
|
||||
import { beginDataGridNativeSelectionBlock, finishDataGridNativeSelectionBlock } from "@/lib/dataGrid/dataGridNativeSelection";
|
||||
import { DATA_GRID_COPY_EXTRACTOR_DESCRIPTORS, DATA_GRID_COPY_EXTRACTOR_IDS, extractorUnavailableForDatabase, type DataGridCopyExtractorId } from "@/lib/dataGrid/dataGridCopyExtractor";
|
||||
import { columnNamesForCopy } from "@/lib/dataGrid/dataGridColumnNameCopy";
|
||||
import { DATA_GRID_ROW_NUM_WIDTH, dataGridRowNumberColumnWidth, resolveDataGridMaxRowNumber, useDataGridColumnResize } from "@/composables/useDataGridColumnResize";
|
||||
@@ -2541,8 +2542,17 @@ const canFetchNextInfiniteScrollSegment = computed(() =>
|
||||
);
|
||||
const canJumpLastPage = computed(() => canGoNextPage.value && (hasKnownPaginationTotalRowCount.value || allRowsLoaded.value || !!props.tableMeta || !!props.countSql || !!props.countTotalRows));
|
||||
const totalRowCountBusy = computed(() => props.totalRowCountLoading === true || manualTotalRowCountLoading.value);
|
||||
/** Full-grid busy state: query loading or on-demand COUNT (e.g. jump to last page). */
|
||||
const gridSurfaceBusy = computed(() => props.loading === true || totalRowCountBusy.value);
|
||||
/** Full-grid busy state: refresh dispatch, query loading, or on-demand COUNT (e.g. jump to last page). */
|
||||
const gridSurfaceBusy = computed(() => isRefreshingData.value || props.loading === true || totalRowCountBusy.value);
|
||||
const dataGridNativeSelectionBlockOwner = {};
|
||||
watch(
|
||||
gridSurfaceBusy,
|
||||
(busy, prevBusy) => {
|
||||
if (busy) beginDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
else if (prevBusy) finishDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
const canCalculateTotalRowCount = computed(() => !!props.countTotalRows || (!!props.connectionId && (!!props.tableMeta || !!props.countSql)));
|
||||
const showExactTotalCountAction = computed(() => canCalculateTotalRowCount.value && (totalRowCountIsExact.value === false || typeof displayedTotalRowCount.value !== "number"));
|
||||
watch(
|
||||
@@ -3288,6 +3298,7 @@ async function onToolbarRefresh() {
|
||||
}
|
||||
preserveTransposeOnNextResult.value = showTranspose.value;
|
||||
isRefreshingData.value = true;
|
||||
beginDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
emit("reload", props.sql, searchText.value, currentWhereInput(), currentOrderBy(), pageSize.value, (currentPage.value - 1) * pageSize.value, "refresh");
|
||||
}
|
||||
|
||||
@@ -5374,6 +5385,8 @@ watch(
|
||||
|
||||
function pauseCanvasGridWork() {
|
||||
dataGridIsActive = false;
|
||||
stopLoadingElapsedTimer();
|
||||
if (gridSurfaceBusy.value) finishDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
canvasRuntime.pause();
|
||||
gridScrollbarsRuntime.pause();
|
||||
disconnectCellEditResizeObserver();
|
||||
@@ -5386,6 +5399,8 @@ function pauseCanvasGridWork() {
|
||||
|
||||
function resumeCanvasGridWork() {
|
||||
dataGridIsActive = true;
|
||||
startLoadingElapsedTimer();
|
||||
if (gridSurfaceBusy.value) beginDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
canvasRuntime.resume();
|
||||
gridScrollbarsRuntime.resume();
|
||||
nextTick(() => {
|
||||
@@ -6537,8 +6552,8 @@ async function onGridKeydown(event: KeyboardEvent) {
|
||||
return;
|
||||
}
|
||||
if (clipboardShortcut(event, "a")) {
|
||||
if (!hasData.value) return;
|
||||
event.preventDefault();
|
||||
const intent = claimDataGridSelectAll(event, gridSurfaceBusy.value, hasData.value);
|
||||
if (intent !== "select") return;
|
||||
selectAllCells();
|
||||
return;
|
||||
}
|
||||
@@ -7903,11 +7918,21 @@ function stopLoadingElapsedTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
function startLoadingElapsedTimer() {
|
||||
function startLoadingElapsedTimer(reset = false) {
|
||||
stopLoadingElapsedTimer();
|
||||
if (!dataGridIsActive || !gridSurfaceBusy.value) return;
|
||||
_loadingStart = Date.now();
|
||||
loadingElapsed.value = 0;
|
||||
if (!dataGridIsActive || !gridSurfaceBusy.value) {
|
||||
if (!gridSurfaceBusy.value) {
|
||||
_loadingStart = 0;
|
||||
loadingElapsed.value = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (reset || !_loadingStart) {
|
||||
_loadingStart = Date.now();
|
||||
loadingElapsed.value = 0;
|
||||
} else {
|
||||
loadingElapsed.value = Date.now() - _loadingStart;
|
||||
}
|
||||
const updateOnNextFrame = () => {
|
||||
if (!dataGridIsActive || !gridSurfaceBusy.value) return;
|
||||
loadingElapsed.value = Date.now() - _loadingStart;
|
||||
@@ -7926,7 +7951,7 @@ watch(gridSurfaceBusy, (isLoading) => {
|
||||
});
|
||||
}
|
||||
if (isLoading) {
|
||||
startLoadingElapsedTimer();
|
||||
startLoadingElapsedTimer(true);
|
||||
} else if (isDebugLoggingEnabled()) {
|
||||
nextTick(() => {
|
||||
requestAnimationFrame(() => {
|
||||
@@ -7941,11 +7966,9 @@ watch(gridSurfaceBusy, (isLoading) => {
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
startLoadingElapsedTimer();
|
||||
autoRefresh.start();
|
||||
});
|
||||
onDeactivated(() => {
|
||||
stopLoadingElapsedTimer();
|
||||
autoRefresh.stop();
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const dataGridSource = readFileSync(new URL("../DataGrid.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("DataGrid loading elapsed timer", () => {
|
||||
it("resets for a new load but resumes from the original start after KeepAlive activation", () => {
|
||||
expect(dataGridSource).toContain("function startLoadingElapsedTimer(reset = false)");
|
||||
expect(dataGridSource).toContain("if (reset || !_loadingStart)");
|
||||
expect(dataGridSource).toContain("startLoadingElapsedTimer(true);");
|
||||
expect(dataGridSource).toMatch(/function resumeCanvasGridWork\(\) \{\s*dataGridIsActive = true;\s*startLoadingElapsedTimer\(\);/);
|
||||
expect(dataGridSource).toMatch(/function pauseCanvasGridWork\(\) \{\s*dataGridIsActive = false;\s*stopLoadingElapsedTimer\(\);/);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user