Skip to content

Commit

Permalink
fix(designer): Title changes not updating downstream inputs when seri…
Browse files Browse the repository at this point in the history
…alizing (#4407)

* update the whole token instead

* remove unused singleLine plugin

* not complete

* revert trapzone in tokenpicker

* tempcommit

* fix prev issue

* remove unused code
  • Loading branch information
Eric-B-Wu committed Mar 21, 2024
1 parent f815f0b commit 25cf75b
Show file tree
Hide file tree
Showing 19 changed files with 162 additions and 147 deletions.
2 changes: 1 addition & 1 deletion __mocks__/workflows/Panel.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"Filter_array": {
"type": "Query",
"inputs": {
"from": "@triggerBody()?['array']",
"from": "@body('Parse_JSON')",
"where": "@not(contains(length(split(item(), '|')?[0]),length(split(item(), '|')?[0])))"
},
"runAfter": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export const CollapsedAuthentication = ({
editorState.read(() => {
const nodeMap = new Map<string, ValueSegment>();
const editorString = getChildrenNodes($getRoot(), nodeMap).trim();
console.log(editorString);
const newCollapsedValue = serializeEditorState(editorState);
try {
// no collapsed value, update current Props to be empty
Expand Down
8 changes: 0 additions & 8 deletions libs/designer-ui/src/lib/code/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ export function CodeEditor({
setInTokenPicker(!getInTokenPicker());
};

const setIsInTokenpicker = (b: boolean) => {
setInTokenPicker(b);
if (!b) {
codeEditorRef.current?.focus();
}
};

const tokenClicked = (valueSegment: ValueSegment) => {
if (codeEditorRef.current && valueSegment.token) {
const newText = buildInlineCodeTextFromToken(valueSegment.token, language);
Expand Down Expand Up @@ -122,7 +115,6 @@ export function CodeEditor({
callOutLabelId,
undefined /* TokenPickerMode: undefined uses legacy tokenpicker */,
undefined /* Editortype: undefined defaults to parameter type */,
setIsInTokenpicker,
tokenClicked
)
: null}
Expand Down
5 changes: 2 additions & 3 deletions libs/designer-ui/src/lib/editor/base/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export type GetTokenPickerHandler = (
labelId: string,
tokenPickerMode?: TokenPickerMode,
valueType?: string,
setInTokenpicker?: (b: boolean) => void,
tokenClickedCallback?: (token: ValueSegment) => void
) => JSX.Element;

Expand Down Expand Up @@ -216,7 +215,7 @@ export const BaseEditor = ({
{htmlEditor === 'rich-html' ? null : <ArrowNavigation />}
{tokens ? (
<>
<InsertTokenNode closeTokenPicker={() => setIsTokenPickerOpened(false)} />
<InsertTokenNode />
<DeleteTokenNode />
<OpenTokenPicker openTokenPicker={openTokenPicker} />
<CloseTokenPicker closeTokenPicker={() => setIsTokenPickerOpened(false)} />
Expand All @@ -232,7 +231,7 @@ export const BaseEditor = ({
<FloatingLinkEditorPlugin anchorElem={floatingAnchorElem} isMainEditorFocused={isEditorFocused} />
) : null}
{children}
{tokens && isTokenPickerOpened ? getTokenPicker(editorId, labelId ?? '', tokenPickerMode, valueType, setIsTokenPickerOpened) : null}
{tokens && isTokenPickerOpened ? getTokenPicker(editorId, labelId ?? '', tokenPickerMode, valueType) : null}
</div>
{tokens && isEditorFocused && !isTokenPickerOpened
? createPortal(<TokenPickerButton {...tokenPickerButtonProps} openTokenPicker={openTokenPicker} />, document.body)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import type { LexicalCommand } from 'lexical';
import { COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
import { useEffect } from 'react';

export const CLOSE_TOKENPICKER: LexicalCommand<undefined> = createCommand();
interface CloseTokenPickerPaylaod {
focusEditorAfter?: boolean;
}
export const CLOSE_TOKENPICKER: LexicalCommand<CloseTokenPickerPaylaod> = createCommand();

export interface CloseTokenPickerProps {
closeTokenPicker: () => void;
Expand All @@ -15,8 +18,11 @@ export default function CloseTokenPicker({ closeTokenPicker }: CloseTokenPickerP
useEffect(() => {
return editor.registerCommand(
CLOSE_TOKENPICKER,
() => {
(payload) => {
closeTokenPicker();
if (payload.focusEditorAfter) {
editor.focus();
}
return true;
},
COMMAND_PRIORITY_EDITOR
Expand Down
11 changes: 4 additions & 7 deletions libs/designer-ui/src/lib/editor/base/plugins/InsertTokenNode.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import type { TokenNodeProps } from '../nodes/tokenNode';
import { $createTokenNode, TokenNode } from '../nodes/tokenNode';
import { CLOSE_TOKENPICKER } from './CloseTokenPicker';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import type { LexicalCommand } from 'lexical';
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
import { useEffect } from 'react';

export const INSERT_TOKEN_NODE: LexicalCommand<TokenNodeProps> = createCommand();

export interface InsertTokenNodeProps {
closeTokenPicker: () => void;
}

export default function InsertTokenNode({ closeTokenPicker }: InsertTokenNodeProps): null {
export default function InsertTokenNode(): null {
const [editor] = useLexicalComposerContext();

useEffect(() => {
Expand All @@ -28,12 +25,12 @@ export default function InsertTokenNode({ closeTokenPicker }: InsertTokenNodePro
const tokenNode = $createTokenNode({ ...payload, value, readonly: false });
selection.insertNodes([tokenNode]);
}
closeTokenPicker();
editor.dispatchCommand(CLOSE_TOKENPICKER, { focusEditorAfter: true });
return true;
},
COMMAND_PRIORITY_EDITOR
);
}, [editor, closeTokenPicker]);
}, [editor]);

return null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ export interface PanelHeaderTitleProps {

export const PanelHeaderTitle = ({
titleValue,
onChange,
titleId,
readOnlyMode,
renameTitleDisabled,
onChange,
}: PanelHeaderTitleProps): JSX.Element => {
const intl = useIntl();

Expand Down
7 changes: 3 additions & 4 deletions libs/designer-ui/src/lib/token/inputToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const InputToken: React.FC<InputTokenProps> = ({ value, brandColor, icon,
} else {
clearSelection();
setSelected(true);
editor.dispatchCommand(CLOSE_TOKENPICKER, undefined);
editor.dispatchCommand(CLOSE_TOKENPICKER, { focusEditorAfter: true });
}
});
}
Expand Down Expand Up @@ -130,12 +130,11 @@ export const InputToken: React.FC<InputTokenProps> = ({ value, brandColor, icon,
handleTokenClicked(e);
e.stopPropagation();
}}
title={value}
style={tokenStyle}
ref={tokenRef}
>
<div className="msla-token-title" title={value}>
{title}
</div>
<div className="msla-token-title">{title}</div>
{renderTokenDeleteButton()}
</span>
);
Expand Down
170 changes: 80 additions & 90 deletions libs/designer-ui/src/lib/tokenpicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ValueSegment } from '../editor';
import { CLOSE_TOKENPICKER } from '../editor/base/plugins/CloseTokenPicker';
import type { ExpressionEditorEvent } from '../expressioneditor';
import { ExpressionEditor } from '../expressioneditor';
import { PanelSize } from '../panel/panelUtil';
Expand All @@ -11,7 +12,7 @@ import { TokenPickerPivot } from './tokenpickerpivot';
import type { GetValueSegmentHandler } from './tokenpickersection/tokenpickeroption';
import { TokenPickerSection } from './tokenpickersection/tokenpickersection';
import type { ICalloutContentStyles, ISearchBox, PivotItem } from '@fluentui/react';
import { SearchBox, Callout, DirectionalHint, FocusTrapZone } from '@fluentui/react';
import { SearchBox, DirectionalHint, Callout } from '@fluentui/react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import type { LexicalEditor, NodeKey } from 'lexical';
import type { editor } from 'monaco-editor';
Expand Down Expand Up @@ -48,7 +49,6 @@ export interface TokenPickerProps {
expressionGroup?: TokenGroup[];
// if initialMode is undefined, it is Legacy TokenPicker
initialMode?: TokenPickerMode;
setIsTokenPickerOpened?: (b: boolean) => void;
// tokenClickedCallback is used for the code Editor TokenPicker(Legacy Token Picker)
tokenClickedCallback?: (token: ValueSegment) => void;
hideUTFExpressions?: boolean;
Expand All @@ -61,13 +61,11 @@ export function TokenPicker({
expressionGroup,
initialMode,
hideUTFExpressions,
setIsTokenPickerOpened,
getValueSegmentFromToken,
tokenClickedCallback,
}: TokenPickerProps): JSX.Element {
const intl = useIntl();
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
const [isTokenPickerVisible, setIsTokenPickerVisible] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
const [selectedKey, setSelectedKey] = useState<TokenPickerMode>(initialMode ?? TokenPickerMode.TOKEN);
const [expressionToBeUpdated, setExpressionToBeUpdated] = useState<NodeKey | null>(null);
Expand All @@ -77,6 +75,7 @@ export function TokenPicker({
const [expressionEditorDragDistance, setExpressionEditorDragDistance] = useState(0);
const [expressionEditorCurrentHeight, setExpressionEditorCurrentHeight] = useState(windowDimensions.height < 400 ? 50 : 100);
const [expressionEditorError, setExpressionEditorError] = useState<string>('');
const containerRef = useRef<HTMLDivElement | null>(null);
const expressionEditorRef = useRef<editor.IStandaloneCodeEditor | null>(null);
const searchBoxRef = useRef<ISearchBox | null>(null);
const isExpression = initialMode === TokenPickerMode.EXPRESSION;
Expand Down Expand Up @@ -161,10 +160,6 @@ export function TokenPicker({
editor = null;
}

const closeTokenPicker = () => {
setIsTokenPickerOpened?.(false);
};

return (
<>
<Callout
Expand All @@ -181,12 +176,11 @@ export function TokenPicker({
}
}}
onDismiss={(e) => {
setIsTokenPickerVisible(false);
if (e?.type === 'keydown' && (e as React.KeyboardEvent<HTMLElement>).key === 'Escape') {
editor?.focus();
editor?.dispatchCommand(CLOSE_TOKENPICKER, { focusEditorAfter: true });
} else {
editor?.dispatchCommand(CLOSE_TOKENPICKER, { focusEditorAfter: false });
}

closeTokenPicker();
}}
onRestoreFocus={() => {
return;
Expand All @@ -196,91 +190,87 @@ export function TokenPicker({
hostId: 'msla-layer-host',
}}
>
<FocusTrapZone isClickableOutsideFocusTrap disabled={!isTokenPickerVisible}>
<div
className="msla-token-picker-container-v3"
style={
fullScreen
? {
height: Math.max(windowDimensions.height - 100, Math.min(windowDimensions.height, 550)),
width: Math.max(
windowDimensions.width - (parseInt(PanelSize.Medium, 10) + 40),
Math.min(windowDimensions.width - 16, 400)
),
}
: { maxHeight: Math.min(windowDimensions.height, 550), width: Math.min(windowDimensions.width - 16, 400) }
}
>
<div className="msla-token-picker">
{initialMode ? (
<TokenPickerHeader
fullScreen={fullScreen}
isExpression={isExpression}
closeTokenPicker={closeTokenPicker}
setFullScreen={setFullScreen}
pasteLastUsedExpression={pasteLastUsedExpression}
/>
) : null}
<div
className="msla-token-picker-container-v3"
style={
fullScreen
? {
height: Math.max(windowDimensions.height - 100, Math.min(windowDimensions.height, 550)),
width: Math.max(
windowDimensions.width - (parseInt(PanelSize.Medium, 10) + 40),
Math.min(windowDimensions.width - 16, 400)
),
}
: { maxHeight: Math.min(windowDimensions.height, 550), width: Math.min(windowDimensions.width - 16, 400) }
}
ref={containerRef}
>
<div className="msla-token-picker">
{initialMode ? (
<TokenPickerHeader
fullScreen={fullScreen}
isExpression={isExpression}
setFullScreen={setFullScreen}
pasteLastUsedExpression={pasteLastUsedExpression}
/>
) : null}

{isExpression ? (
<div className="msla-token-picker-expression-subheader">
<ExpressionEditor
initialValue={expression.value}
editorRef={expressionEditorRef}
onBlur={onExpressionEditorBlur}
isDragging={isDraggingExpressionEditor}
dragDistance={expressionEditorDragDistance}
setIsDragging={setIsDraggingExpressionEditor}
currentHeight={expressionEditorCurrentHeight}
setCurrentHeight={setExpressionEditorCurrentHeight}
setExpressionEditorError={setExpressionEditorError}
hideUTFExpressions={hideUTFExpressions}
/>
<div className="msla-token-picker-expression-editor-error">{expressionEditorError}</div>
<TokenPickerPivot selectedKey={selectedKey} selectKey={handleSelectKey} hideExpressions={!!tokenClickedCallback} />
</div>
) : null}
<div className="msla-token-picker-search-container">
<SearchBox
className="msla-token-picker-search"
componentRef={(e) => {
searchBoxRef.current = e;
}}
placeholder={tokenPickerPlaceHolderText}
onChange={(_, newValue) => {
setSearchQuery(newValue ?? '');
}}
data-automation-id="msla-token-picker-search"
{isExpression ? (
<div className="msla-token-picker-expression-subheader">
<ExpressionEditor
initialValue={expression.value}
editorRef={expressionEditorRef}
onBlur={onExpressionEditorBlur}
isDragging={isDraggingExpressionEditor}
dragDistance={expressionEditorDragDistance}
setIsDragging={setIsDraggingExpressionEditor}
currentHeight={expressionEditorCurrentHeight}
setCurrentHeight={setExpressionEditorCurrentHeight}
setExpressionEditorError={setExpressionEditorError}
hideUTFExpressions={hideUTFExpressions}
/>
<div className="msla-token-picker-expression-editor-error">{expressionEditorError}</div>
<TokenPickerPivot selectedKey={selectedKey} selectKey={handleSelectKey} hideExpressions={!!tokenClickedCallback} />
</div>
<TokenPickerSection
tokenGroup={(selectedKey === TokenPickerMode.TOKEN ? filteredTokenGroup : tokenGroup) ?? []}
expressionGroup={expressionGroup ?? []}
expressionEditorRef={expressionEditorRef}
selectedKey={selectedKey}
searchQuery={searchQuery}
fullScreen={fullScreen}
) : null}
<div className="msla-token-picker-search-container">
<SearchBox
className="msla-token-picker-search"
componentRef={(e) => {
searchBoxRef.current = e;
}}
placeholder={tokenPickerPlaceHolderText}
onChange={(_, newValue) => {
setSearchQuery(newValue ?? '');
}}
data-automation-id="msla-token-picker-search"
/>
</div>
<TokenPickerSection
tokenGroup={(selectedKey === TokenPickerMode.TOKEN ? filteredTokenGroup : tokenGroup) ?? []}
expressionGroup={expressionGroup ?? []}
expressionEditorRef={expressionEditorRef}
selectedKey={selectedKey}
searchQuery={searchQuery}
fullScreen={fullScreen}
expression={expression}
setExpression={setExpression}
getValueSegmentFromToken={getValueSegmentFromToken}
tokenClickedCallback={tokenClickedCallback}
noDynamicContent={!isDynamicContentAvailable(filteredTokenGroup ?? [])}
expressionEditorCurrentHeight={expressionEditorCurrentHeight}
/>
{isExpression ? (
<TokenPickerFooter
tokenGroup={tokenGroup ?? []}
expression={expression}
setExpression={setExpression}
expressionToBeUpdated={expressionToBeUpdated}
getValueSegmentFromToken={getValueSegmentFromToken}
tokenClickedCallback={tokenClickedCallback}
noDynamicContent={!isDynamicContentAvailable(filteredTokenGroup ?? [])}
closeTokenPicker={closeTokenPicker}
expressionEditorCurrentHeight={expressionEditorCurrentHeight}
setExpressionEditorError={setExpressionEditorError}
/>
{isExpression ? (
<TokenPickerFooter
tokenGroup={tokenGroup ?? []}
expression={expression}
expressionToBeUpdated={expressionToBeUpdated}
getValueSegmentFromToken={getValueSegmentFromToken}
setExpressionEditorError={setExpressionEditorError}
closeTokenPicker={closeTokenPicker}
/>
) : null}
</div>
) : null}
</div>
</FocusTrapZone>
</div>
</Callout>
{tokenClickedCallback ? null : <TokenPickerHandler handleUpdateExpressionToken={handleUpdateExpressionToken} />}
{tokenClickedCallback ? null : <UpdateTokenNode />}
Expand Down

0 comments on commit 25cf75b

Please sign in to comment.