{showButtonsComponent && (
-
+
)}
@@ -221,26 +222,26 @@ class ButtonBar extends PureComponent> {
{canExport && (
)}
{showChartMenu && }
{canSelectView && (
)}
{ButtonsComponentRight !== undefined && (
-
+
)}
@@ -259,7 +260,7 @@ class ButtonBar
extends PureComponent> {
- {showFiltersButton && }
+ {showFiltersButton && }
{showSearchInput && }
@@ -362,7 +363,7 @@ export const GridTitle: FC
= memo(props => {
)}
{showSave && canSaveCurrent && (
-
@@ -974,7 +975,7 @@ export class GridPanel extends PureComponent, State> {
checked={selected === true}
className="grid-panel__row-checkbox"
disabled={isLoading || isLoadingSelections}
- onChange={this.selectRow.bind(this, row)} // eslint-disable-line
+ onChange={this.selectRow.bind(this, row)}
type="checkbox"
/>
);
@@ -1117,16 +1118,16 @@ export class GridPanel extends PureComponent, State> {
<>
extends PureComponent
, State> {
)}
@@ -1156,7 +1157,7 @@ export class GridPanel extends PureComponent, State> {
)}
- {allowSelections &&
}
+ {allowSelections &&
}
{showFilterStatus && (
extends PureComponent, State> {
{hasData && (
)}
@@ -1200,17 +1201,17 @@ export class GridPanel extends PureComponent, State> {
{showFilterModalFieldKey && (
)}
{showSaveViewModal && (
@@ -1225,10 +1226,10 @@ export class GridPanel extends PureComponent, State> {
)}
{showManageViewsModal && (
)}
>
diff --git a/packages/components/src/public/QueryModel/SelectionStatus.test.tsx b/packages/components/src/public/QueryModel/SelectionStatus.test.tsx
index cd2957d337..61334cc24e 100644
--- a/packages/components/src/public/QueryModel/SelectionStatus.test.tsx
+++ b/packages/components/src/public/QueryModel/SelectionStatus.test.tsx
@@ -26,6 +26,10 @@ describe('SelectionStatus', () => {
});
const ACTIONS = makeTestActions();
+ beforeEach(() => {
+ LABKEY.moduleContext.query = { maxQuerySelection: 100_000 };
+ });
+
test('loading', () => {
render();
expect(document.querySelectorAll('.selection-status')).toHaveLength(0);
@@ -50,7 +54,7 @@ describe('SelectionStatus', () => {
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(0);
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(0);
expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__select-all').textContent).toBe('Select all 21');
+ expect(document.querySelector('.selection-status__select-all')).toHaveTextContent('Select all 21');
});
test('no selections, rowCount greater than maxRows but isLoadingTotalCount', () => {
@@ -63,17 +67,16 @@ describe('SelectionStatus', () => {
expect(document.querySelectorAll('.selection-status')).toHaveLength(1);
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(0);
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(0);
- expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__select-all').textContent).toBe('Select all ');
+ expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(0);
});
test('has selection, rowCount less than maxRows', () => {
render();
expect(document.querySelectorAll('.selection-status')).toHaveLength(1);
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(1);
- expect(document.querySelector('.selection-status__count').textContent).toBe('1 of 1 selected');
+ expect(document.querySelector('.selection-status__count')).toHaveTextContent('1 of 1 selected');
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__clear-all').textContent).toBe('Clear');
+ expect(document.querySelector('.selection-status__clear-all')).toHaveTextContent('Clear');
expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(0);
});
@@ -82,25 +85,27 @@ describe('SelectionStatus', () => {
render();
expect(document.querySelectorAll('.selection-status')).toHaveLength(1);
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(1);
- expect(document.querySelector('.selection-status__count').textContent).toBe('1 of 21 selected');
+ expect(document.querySelector('.selection-status__count')).toHaveTextContent('1 of 21 selected');
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__clear-all').textContent).toBe('Clear');
+ expect(document.querySelector('.selection-status__clear-all')).toHaveTextContent('Clear');
expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__select-all').textContent).toBe('Select all 21');
+ expect(document.querySelector('.selection-status__select-all')).toHaveTextContent('Select all 21');
});
test('has selections, rowCount greater than large maxRows', () => {
const selectionSet = [];
- for (let i = 0; i < 1031; i++) selectionSet.push(i.toString());
+ for (let i = 0; i < 1031; i++) {
+ selectionSet.push(i.toString());
+ }
const model = MODEL_LOADED.mutate({ rowCount: 41321, selections: new Set(selectionSet) });
render();
expect(document.querySelectorAll('.selection-status')).toHaveLength(1);
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(1);
- expect(document.querySelector('.selection-status__count').textContent).toBe('1,031 of 41,321 selected');
+ expect(document.querySelector('.selection-status__count')).toHaveTextContent('1,031 of 41,321 selected');
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__clear-all').textContent).toBe('Clear all');
+ expect(document.querySelector('.selection-status__clear-all')).toHaveTextContent('Clear all');
expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__select-all').textContent).toBe('Select all 41,321');
+ expect(document.querySelector('.selection-status__select-all')).toHaveTextContent('Select all 41,321');
});
test('has selections, rowCount greater than maxRows but isLoadingTotalCount', () => {
@@ -108,10 +113,16 @@ describe('SelectionStatus', () => {
render();
expect(document.querySelectorAll('.selection-status')).toHaveLength(1);
expect(document.querySelectorAll('.selection-status__count')).toHaveLength(1);
- expect(document.querySelector('.selection-status__count').textContent).toBe('1 of selected');
+ expect(document.querySelector('.selection-status__count')).toHaveTextContent('1 of selected');
expect(document.querySelectorAll('.selection-status__clear-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__clear-all').textContent).toBe('Clear');
+ expect(document.querySelector('.selection-status__clear-all')).toHaveTextContent('Clear');
+ expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(0);
+ });
+
+ test('selection loaded, rowCount greater than maxRows and maxSelectionSize', () => {
+ const model = MODEL_LOADED.mutate({ rowCount: 1_115_000 });
+ render();
expect(document.querySelectorAll('.selection-status__select-all')).toHaveLength(1);
- expect(document.querySelector('.selection-status__select-all').textContent).toBe('Select all ');
+ expect(document.querySelector('.selection-status__select-all')).toHaveTextContent('Select first 100,000');
});
});
diff --git a/packages/components/src/public/QueryModel/SelectionStatus.tsx b/packages/components/src/public/QueryModel/SelectionStatus.tsx
index b3e2088c39..9d6baf980b 100644
--- a/packages/components/src/public/QueryModel/SelectionStatus.tsx
+++ b/packages/components/src/public/QueryModel/SelectionStatus.tsx
@@ -1,5 +1,7 @@
import React, { FC, memo, useCallback, useMemo } from 'react';
+import { getServerContext } from '@labkey/api';
+
import { LoadingSpinner } from '../../internal/components/base/LoadingSpinner';
import { RequiresModelAndActions } from './withQueryModels';
@@ -7,6 +9,7 @@ import { RequiresModelAndActions } from './withQueryModels';
export const SelectionStatus: FC = memo(({ actions, model }) => {
const { isLoading, isLoadingSelections, isLoadingTotalCount, maxRows, rowCount, selections } = model;
const selectionSize = selections?.size;
+ const maxSelectionSize = useMemo(() => getServerContext().moduleContext?.query?.maxQuerySelection, []);
const clearSelections = useCallback((): void => {
actions.clearSelections(model.id);
@@ -53,11 +56,19 @@ export const SelectionStatus: FC = memo(({ actions, mod
);
}
- if (rowCount > maxRows && selectionSize !== rowCount && rowCount > 0) {
+ if (
+ rowCount > maxRows &&
+ selectionSize !== rowCount &&
+ rowCount > 0 &&
+ !isLoadingTotalCount &&
+ selectionSize < maxSelectionSize
+ ) {
+ const tooManyRows = rowCount > maxSelectionSize;
selectAllButton = (
);
diff --git a/packages/components/src/public/QueryModel/withQueryModels.tsx b/packages/components/src/public/QueryModel/withQueryModels.tsx
index b80edcb985..5dde0e0a45 100644
--- a/packages/components/src/public/QueryModel/withQueryModels.tsx
+++ b/packages/components/src/public/QueryModel/withQueryModels.tsx
@@ -482,6 +482,7 @@ export function withQueryModels(
console.error(`Error setting selections for model ${id}:`, selectionsError);
model.selectionsError = selectionsError;
+ model.selectionsLoadingState = LoadingState.LOADED;
removeSettingsFromLocalStorage(this.state.queryModels[id]);
})
);
@@ -708,7 +709,9 @@ export function withQueryModels(
this.setState(
produce((draft: WritableDraft) => {
- draft.queryModels[id].rowsLoadingState = LoadingState.LOADING;
+ const model = draft.queryModels[id];
+ model.rowsLoadingState = LoadingState.LOADING;
+ model.selectionsError = undefined;
})
);