Skip to content
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

feat: fetch frequencyMax #1152

Merged
merged 1 commit into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -328,6 +328,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) {
quanho marked this conversation as resolved.
Show resolved Hide resolved
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;
};