Skip to content

Commit 89ddb0b

Browse files
authored
fix(designer-ui): Ensure isAdvanced: false tokens are shown if far down in a list (#4064)
* Move token picker section options filter to a helper fn * Fix bug where later options would not be visible * Add tests for `hasAdvanced`
1 parent b0d825d commit 89ddb0b

File tree

3 files changed

+140
-25
lines changed

3 files changed

+140
-25
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import type { OutputToken } from '../..';
2+
import { getReducedTokenList, hasAdvanced } from '../tokenpickerhelpers';
3+
4+
describe('ui/tokenPicker/tokenPickerSection helpers', () => {
5+
describe('getReducedTokenList', () => {
6+
it('should return a list of tokens with the advanced tokens filtered out', () => {
7+
const tokens: OutputToken[] = [
8+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
9+
{ isAdvanced: true, value: 'Value 2' } as OutputToken,
10+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
11+
{ isAdvanced: true, value: 'Value 4' } as OutputToken,
12+
];
13+
const options = { hasSearchQuery: false, maxRowsShown: 2, showAllOptions: false };
14+
15+
const result = getReducedTokenList(tokens, options);
16+
17+
expect(result).toEqual([
18+
{ isAdvanced: false, value: 'Value 1' },
19+
{ isAdvanced: false, value: 'Value 3' },
20+
]);
21+
});
22+
23+
it('should return a list of tokens with the advanced tokens filtered out and the max rows shown respected', () => {
24+
const tokens: OutputToken[] = [
25+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
26+
{ isAdvanced: true, value: 'Value 2' } as OutputToken,
27+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
28+
{ isAdvanced: true, value: 'Value 4' } as OutputToken,
29+
];
30+
const options = { hasSearchQuery: false, maxRowsShown: 1, showAllOptions: false };
31+
32+
const result = getReducedTokenList(tokens, options);
33+
34+
expect(result).toEqual([{ isAdvanced: false, value: 'Value 1' }]);
35+
});
36+
37+
it('should return a list of tokens with the search query presence respected', () => {
38+
const tokens: OutputToken[] = [
39+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
40+
{ isAdvanced: true, value: 'Value 2' } as OutputToken,
41+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
42+
{ isAdvanced: true, value: 'Value 4' } as OutputToken,
43+
];
44+
const options = { hasSearchQuery: true, maxRowsShown: 2, showAllOptions: false };
45+
46+
const result = getReducedTokenList(tokens, options);
47+
48+
expect(result).toEqual([
49+
{ isAdvanced: false, value: 'Value 1' },
50+
{ isAdvanced: true, value: 'Value 2' },
51+
]);
52+
});
53+
54+
it('should return a list of tokens with the "no more options" field respected', () => {
55+
const tokens: OutputToken[] = [
56+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
57+
{ isAdvanced: true, value: 'Value 2' } as OutputToken,
58+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
59+
{ isAdvanced: true, value: 'Value 4' } as OutputToken,
60+
];
61+
const options = { hasSearchQuery: false, maxRowsShown: 1, showAllOptions: true };
62+
63+
const result = getReducedTokenList(tokens, options);
64+
65+
expect(result).toEqual([
66+
{ isAdvanced: false, value: 'Value 1' },
67+
{ isAdvanced: true, value: 'Value 2' },
68+
{ isAdvanced: false, value: 'Value 3' },
69+
{ isAdvanced: true, value: 'Value 4' },
70+
]);
71+
});
72+
});
73+
74+
describe('hasAdvanced', () => {
75+
it('should return true if any of the tokens are advanced', () => {
76+
const tokens: OutputToken[] = [
77+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
78+
{ isAdvanced: true, value: 'Value 2' } as OutputToken,
79+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
80+
{ isAdvanced: true, value: 'Value 4' } as OutputToken,
81+
];
82+
83+
const result = hasAdvanced(tokens);
84+
85+
expect(result).toEqual(true);
86+
});
87+
88+
it('should return false if none of the tokens are advanced', () => {
89+
const tokens: OutputToken[] = [
90+
{ isAdvanced: false, value: 'Value 1' } as OutputToken,
91+
{ isAdvanced: false, value: 'Value 2' } as OutputToken,
92+
{ isAdvanced: false, value: 'Value 3' } as OutputToken,
93+
{ isAdvanced: false, value: 'Value 4' } as OutputToken,
94+
];
95+
96+
const result = hasAdvanced(tokens);
97+
98+
expect(result).toEqual(false);
99+
});
100+
});
101+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { OutputToken } from '..';
2+
3+
export const getReducedTokenList = (
4+
tokens: OutputToken[],
5+
options: { hasSearchQuery: boolean; maxRowsShown: number; showAllOptions: boolean }
6+
): OutputToken[] => {
7+
const { hasSearchQuery, maxRowsShown, showAllOptions } = options;
8+
9+
let filteredTokens = tokens.filter((token) => !token.isAdvanced || showAllOptions || hasSearchQuery);
10+
if (!showAllOptions) {
11+
filteredTokens = filteredTokens.slice(0, maxRowsShown);
12+
}
13+
14+
return filteredTokens;
15+
};
16+
17+
export const hasAdvanced = (tokens: OutputToken[]): boolean => {
18+
return tokens.some((token) => token.isAdvanced);
19+
};

libs/designer-ui/src/lib/tokenpicker/tokenpickersection/tokenpickeroption.tsx

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { INSERT_TOKEN_NODE } from '../../editor/base/plugins/InsertTokenNode';
55
import { SINGLE_VALUE_SEGMENT } from '../../editor/base/plugins/SingleValueSegment';
66
import { convertUIElementNameToAutomationId } from '../../utils';
77
import type { Token, TokenGroup } from '../models/token';
8+
import { getReducedTokenList, hasAdvanced } from './tokenpickerhelpers';
89
import type { TokenPickerBaseProps } from './tokenpickersection';
910
import { Icon } from '@fluentui/react';
1011
import { useBoolean } from '@fluentui/react-hooks';
@@ -194,36 +195,30 @@ export const TokenPickerOptions = ({
194195
)}
195196
</div>
196197
<div className="msla-token-picker-section-options">
197-
{(!searchQuery ? section.tokens : filteredTokens).map((token, j) => {
198-
if ((token.isAdvanced || j >= maxRowsShown) && moreOptions && !searchQuery) {
199-
return null;
200-
}
201-
202-
return (
203-
<button
204-
className="msla-token-picker-section-option"
205-
data-automation-id={`msla-token-picker-section-option-${j}`}
206-
key={`token-picker-option-${j}`}
207-
onClick={() => handleTokenClicked(token)}
208-
>
209-
<div className="msla-token-picker-section-option-text">
210-
<div className="msla-token-picker-option-inner">
211-
<div className="msla-token-picker-option-title">{token.title}</div>
212-
<div className="msla-token-picker-option-description" title={token.description}>
213-
{token.description}
214-
</div>
198+
{getReducedTokenList(!searchQuery ? section.tokens : filteredTokens, {
199+
hasSearchQuery: !!searchQuery,
200+
maxRowsShown,
201+
showAllOptions: !moreOptions,
202+
}).map((token, j) => (
203+
<button
204+
className="msla-token-picker-section-option"
205+
data-automation-id={`msla-token-picker-section-option-${j}`}
206+
key={`token-picker-option-${j}`}
207+
onClick={() => handleTokenClicked(token)}
208+
>
209+
<div className="msla-token-picker-section-option-text">
210+
<div className="msla-token-picker-option-inner">
211+
<div className="msla-token-picker-option-title">{token.title}</div>
212+
<div className="msla-token-picker-option-description" title={token.description}>
213+
{token.description}
215214
</div>
216215
</div>
217-
</button>
218-
);
219-
})}
216+
</div>
217+
</button>
218+
))}
220219
</div>
221220
</>
222221
) : null}
223222
</>
224223
);
225224
};
226-
227-
function hasAdvanced(tokens: OutputToken[]): boolean {
228-
return tokens.some((token) => token.isAdvanced);
229-
}

0 commit comments

Comments
 (0)