From 566b91e2983a5239aa14c97d08c53e7f82b22185 Mon Sep 17 00:00:00 2001 From: andreas-unleash Date: Thu, 22 Jun 2023 11:06:25 +0300 Subject: [PATCH] feat: advanced playground multi value context fields (#4053) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes the autocomplete component in the playground context field - when selecting a custom context field that has legal values - able to select/edit multiple values. ## About the changes Closes # [1-1006](https://linear.app/unleash/issue/1-1006/multi-value-context-field) ### Important files ## Discussion points --------- Signed-off-by: andreas-unleash --- .../PlaygroundCodeFieldset.tsx | 51 +++++++++++++++++-- .../playground/Playground/playground.utils.ts | 14 +++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx index 2912dc803b..7596722829 100644 --- a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx @@ -27,6 +27,8 @@ import useToast from 'hooks/useToast'; import { PlaygroundEditor } from './PlaygroundEditor/PlaygroundEditor'; import { GuidanceIndicator } from 'component/common/GuidanceIndicator/GuidanceIndicator'; import { parseDateValue, parseValidDate } from 'component/common/util'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { isStringOrStringArray } from '../../playground.utils'; interface IPlaygroundCodeFieldsetProps { context: string | undefined; setContext: Dispatch>; @@ -37,6 +39,9 @@ export const PlaygroundCodeFieldset: VFC = ({ setContext, }) => { const theme = useTheme(); + const { uiConfig } = useUiConfig(); + const isAdvancedPlayground = Boolean(uiConfig.flags.advancedPlayground); + const { setToastData } = useToast(); const { context: contextData } = useUnleashContext(); const contextOptions = contextData @@ -103,6 +108,44 @@ export const PlaygroundCodeFieldset: VFC = ({ } }; + const onAutoCompleteChange = ( + e: FormEvent, + newValue: string | (string | string[])[] | null + ) => { + if (!isStringOrStringArray(newValue)) return; + + if (Array.isArray(newValue)) { + const temp = + (newValue || []).length > 1 ? newValue.join(',') : newValue[0]; + return setContextValue(temp); + } + + setContextValue(newValue); + }; + + const resolveAutocompleteValue = (): string | string[] | undefined => { + //This is needed for clearing the Autocomplete Chips when changing the context field + //and the new field also has legal values + if (contextValue === '') { + return undefined; + } + + if (isAdvancedPlayground) { + // Split comma separated strings to array for fields with legal values + const foundField = contextData.find( + contextData => contextData.name === contextField + ); + const hasLegalValues = (foundField?.legalValues || []).length > 1; + if (contextValue.includes(',') && hasLegalValues) { + return contextValue.split(','); + } + + return [contextValue as string]; + } + + return contextValue; + }; + const resolveInput = () => { if (contextField === 'currentTime') { const validDate = parseValidDate(contextValue); @@ -146,12 +189,10 @@ export const PlaygroundCodeFieldset: VFC = ({ disablePortal id="context-legal-values" size="small" - onChange={(e: FormEvent, newValue) => { - if (typeof newValue === 'string') { - return setContextValue(newValue); - } - }} + value={resolveAutocompleteValue()} + onChange={onAutoCompleteChange} options={options} + multiple={isAdvancedPlayground} sx={{ width: 200, maxWidth: '100%' }} renderInput={(params: any) => ( diff --git a/frontend/src/component/playground/Playground/playground.utils.ts b/frontend/src/component/playground/Playground/playground.utils.ts index 868e0c4895..f3ae68cb97 100644 --- a/frontend/src/component/playground/Playground/playground.utils.ts +++ b/frontend/src/component/playground/Playground/playground.utils.ts @@ -59,3 +59,17 @@ export const resolveResultsWidth = ( return '50%'; }; + +export const isStringOrStringArray = ( + value: unknown +): value is string | string[] => { + if (typeof value === 'string') { + return true; + } + + if (Array.isArray(value)) { + return value.every(item => typeof item === 'string'); + } + + return false; +};