Skip to content

Commit

Permalink
feat: fetch frequencyMax (#1152)
Browse files Browse the repository at this point in the history
  • Loading branch information
T-Wizard committed Mar 16, 2023
1 parent 17cf57b commit 2589a93
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 10 deletions.
5 changes: 5 additions & 0 deletions apis/nucleus/src/components/listbox/ListBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import ListBoxDisclaimer from './components/ListBoxDisclaimer';
import ListBoxFooter from './components/ListBoxFooter';
import getScrollIndex from './interactions/listbox-get-scroll-index';
import getFrequencyAllowed from './components/grid-list-components/frequency-allowed';
import useFrequencyMax from './hooks/useFrequencyMax';

const DEFAULT_MIN_BATCH_SIZE = 100;

export default function ListBox({
model,
app,
constraints,
layout,
selections,
Expand Down Expand Up @@ -222,6 +224,8 @@ export default function ListBox({
setLast: (last) => setFocusListItem((prevState) => ({ ...prevState, last })),
});

const frequencyMax = useFrequencyMax(app, layout);

const { List, Grid } = getListBoxComponents({
direction,
layout,
Expand Down Expand Up @@ -249,6 +253,7 @@ export default function ListBox({
focusListItems: getFocusState(),
setCurrentScrollIndex: currentScrollIndex.set,
constraints,
frequencyMax,
freqIsAllowed,
});

Expand Down
1 change: 1 addition & 0 deletions apis/nucleus/src/components/listbox/ListBoxInline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ function ListBoxInline({ options, layout }) {
{({ height, width }) => (
<ListBox
model={model}
app={app}
constraints={constraints}
layout={layout}
selections={selections}
Expand Down
1 change: 1 addition & 0 deletions apis/nucleus/src/components/listbox/ListBoxPopover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export default function ListBoxPopover({
/>
<ListBox
model={model}
app={app}
layout={layout}
selections={selections}
selectionState={selectionState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ export default function getListBoxComponents({
focusListItems,
setCurrentScrollIndex,
constraints,
frequencyMax,
freqIsAllowed,
}) {
const { layoutOptions = {}, frequencyMax } = layout || {};
const { layoutOptions = {} } = layout || {};
const { columnWidth, itemPadding, listHeight, itemHeight, rowCount, columnCount, frequencyWidth } = sizes || {};

const itemWidth = layoutOptions.dataLayout === 'grid' ? columnWidth : width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe('useExistingModel', () => {
histogram: true,
};
const fieldIdentifier = { qLibraryId: '123' };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'] } };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'], qGrouping: 'N' } };
app.getDimension = jest.fn().mockReturnValue({ getLayout: async () => fakeDimLayout });

await render(useOnTheFlyModel, { app, fieldIdentifier, stateName: '$', options });
Expand All @@ -138,7 +138,7 @@ describe('useExistingModel', () => {
});
test('should use title from qDim', async () => {
const fieldIdentifier = { qLibraryId: '123' };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'], title: 'Volume title' } };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'], title: 'Volume title', qGrouping: 'N' } };
app.getDimension = jest.fn().mockReturnValue({ getLayout: async () => fakeDimLayout });

await render(useOnTheFlyModel, { app, fieldIdentifier, stateName: '$' });
Expand All @@ -147,7 +147,7 @@ describe('useExistingModel', () => {
test('should use title from options if provided', async () => {
const options = { title: 'Options title' };
const fieldIdentifier = { qLibraryId: '123' };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'], title: 'Volume title' } };
const fakeDimLayout = { qDim: { qFieldDefs: ['Volume'], title: 'Volume title', qGrouping: 'N' } };
app.getDimension = jest.fn().mockReturnValue({ getLayout: async () => fakeDimLayout });

await render(useOnTheFlyModel, { app, fieldIdentifier, stateName: '$', options });
Expand Down
23 changes: 23 additions & 0 deletions apis/nucleus/src/components/listbox/hooks/useFrequencyMax.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useState, useEffect } from 'react';
import { getFrequencyMax, needToFetchFrequencyMax } from '../utils/frequencyMaxUtil';

const useFrequencyMax = (app, layout) => {
const [frequencyMax, setFrequencyMax] = useState();

const needFetch = needToFetchFrequencyMax(layout);

useEffect(() => {
if (!needFetch) {
return;
}
const fetch = async () => {
const newValue = await getFrequencyMax(layout, app);
setFrequencyMax(newValue);
};
fetch();
}, [needFetch && layout]);

return needFetch ? frequencyMax : layout?.frequencyMax;
};

export default useFrequencyMax;
22 changes: 16 additions & 6 deletions apis/nucleus/src/components/listbox/hooks/useOnTheFlyModel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from 'react';
import extend from 'extend';
import useSessionModel from '../../../hooks/useSessionModel';
import uid from '../../../object/uid';
import { getFrequencyMaxExpression } from '../utils/frequencyMaxUtil';

export default function useOnTheFlyModel({ app, fieldIdentifier, stateName, options = {} }) {
const [fieldDef, setFieldDef] = useState('');
Expand All @@ -16,7 +17,11 @@ export default function useOnTheFlyModel({ app, fieldIdentifier, stateName, opti
const dim = await app.getDimension(fieldIdentifier.qLibraryId);
const dimLayout = await dim.getLayout();
setFallbackTitle(dimLayout.qDim.title);
setFieldDef(dimLayout.qDim.qFieldDefs ? dimLayout.qDim.qFieldDefs[0] : '');
if (dimLayout.qDim.qGrouping === 'N') {
setFieldDef(dimLayout.qDim.qFieldDefs ? dimLayout.qDim.qFieldDefs[0] : '');
} else {
setFieldDef({ multiFieldDim: true });
}
setIsFetching(false);
} catch (e) {
setIsFetching(false);
Expand Down Expand Up @@ -122,11 +127,16 @@ export default function useOnTheFlyModel({ app, fieldIdentifier, stateName, opti
fieldName = fieldIdentifier;
}

if (frequencyMode !== 'N' || histogram) {
const field = fieldIdentifier.qLibraryId ? fieldDef : fieldName;
listdef.frequencyMax = {
qValueExpression: `Max(AGGR(Count([${field}]), [${field}]))`,
};
if (frequencyMode !== 'P' && histogram) {
if (fieldDef?.multiFieldDim) {
listdef.frequencyMax = 'fetch';
// maybe for all lib dimension to handle if it properties change
} else {
const field = fieldIdentifier.qLibraryId ? fieldDef : fieldName;
listdef.frequencyMax = {
qValueExpression: getFrequencyMaxExpression(field),
};
}
}

const [sessionModel] = useSessionModel(listdef, isFetching ? null : app, fieldName, stateName);
Expand Down
21 changes: 21 additions & 0 deletions apis/nucleus/src/components/listbox/utils/frequencyMaxUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const escapeField = (field) => {
if (!field) {
return field;
}
return `${field.replace(/\]/g, ']]')}`;
};

export const needToFetchFrequencyMax = (layout) => layout?.frequencyMax === 'fetch';

export const getFrequencyMaxExpression = (field) => {
const escapedField = escapeField(field);
return `Max(AGGR(Count(${escapedField}), ${escapedField}))`;
};

export const getFrequencyMax = async (layout, app) => {
const dimInfo = layout.qListObject.qDimensionInfo;
const field = dimInfo.qGroupFieldDefs[dimInfo.qGroupPos];
const expression = getFrequencyMaxExpression(field);
const evaluadedExpression = await app.evaluateEx(expression);
return evaluadedExpression.qNumber;
};

0 comments on commit 2589a93

Please sign in to comment.