update the prameter editor to new designs, and add validation. (#52)
This commit is contained in:
Родитель
5d15397bec
Коммит
edf21a37b6
|
@ -150,7 +150,7 @@ const GraphTopology: React.FunctionComponent<IGraphTopologyProps> = (props) => {
|
|||
if (!name) {
|
||||
graphNameValidationError = { description: "sidebarGraphTopologyNameMissing", type: ValidationErrorType.MissingField };
|
||||
setGraphNameError(Localizer.l(graphNameValidationError.description));
|
||||
resolve();
|
||||
resolve("");
|
||||
return;
|
||||
}
|
||||
if (ExtensionInteraction.getVSCode()) {
|
||||
|
@ -173,7 +173,7 @@ const GraphTopology: React.FunctionComponent<IGraphTopologyProps> = (props) => {
|
|||
} else {
|
||||
graphNameValidationError = undefined;
|
||||
setGraphNameError(undefined);
|
||||
resolve();
|
||||
resolve("");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -15,11 +15,12 @@ import { useId } from "@uifabric/react-hooks";
|
|||
import { MediaGraphParameterDeclaration } from "../../../Common/Types/LVASDKTypes";
|
||||
import Localizer from "../../Localization/Localizer";
|
||||
import { ParameterizeValueCallback } from "../../Types/GraphTypes";
|
||||
import { ParamCreateConfig } from "../ParameterSelector/ParameterSelector";
|
||||
import { AdjustedIconButton } from "../ThemeAdjustedComponents/AdjustedIconButton";
|
||||
import { AdjustedPrimaryButton } from "../ThemeAdjustedComponents/AdjustedPrimaryButton";
|
||||
import { createParameter } from "./createParameter";
|
||||
import { ParameterEditorAdvanced } from "./ParameterEditorAdvanced";
|
||||
import { ParameterEditorSimple } from "./ParameterEditorSimple";
|
||||
import { ParameterEditorChoice } from "./ParameterEditorChoice";
|
||||
|
||||
interface IParameterEditorProps {
|
||||
onSelectValue: ParameterizeValueCallback;
|
||||
|
@ -33,7 +34,7 @@ interface IParameterEditorProps {
|
|||
const ParameterEditor: React.FunctionComponent<IParameterEditorProps> = (props) => {
|
||||
const { onSelectValue, parameters, isShown, hideModal, propertyName, prevValue = "" } = props;
|
||||
const [selectedValue, setSelectedValue] = React.useState<string>("");
|
||||
const [parameterCreationConfiguration, setParameterCreationConfiguration] = React.useState<MediaGraphParameterDeclaration | undefined>();
|
||||
const [paramCreateConfig, setParamCreateConfig] = React.useState<ParamCreateConfig | undefined>();
|
||||
|
||||
// use the advanced editor if there are more than two parameters
|
||||
const useAdvancedEditor = prevValue.split("${").length > 2;
|
||||
|
@ -58,9 +59,9 @@ const ParameterEditor: React.FunctionComponent<IParameterEditorProps> = (props)
|
|||
const titleId = useId("title");
|
||||
|
||||
const onClickUse = () => {
|
||||
if (parameterCreationConfiguration) {
|
||||
createParameter(parameterCreationConfiguration, parameters); // TODO. check for duplicates.
|
||||
onSelectValue(`$\{${parameterCreationConfiguration.name}}`);
|
||||
if (paramCreateConfig) {
|
||||
createParameter(paramCreateConfig, parameters); // TODO. check for duplicates.
|
||||
onSelectValue(`$\{${paramCreateConfig.name}}`);
|
||||
} else if (selectedValue) {
|
||||
onSelectValue(selectedValue);
|
||||
}
|
||||
|
@ -69,7 +70,11 @@ const ParameterEditor: React.FunctionComponent<IParameterEditorProps> = (props)
|
|||
|
||||
const resetSelectedValue = () => {
|
||||
setSelectedValue("");
|
||||
setParameterCreationConfiguration(undefined);
|
||||
setParamCreateConfig(undefined);
|
||||
};
|
||||
|
||||
const setButtonDisabled = () => {
|
||||
return (paramCreateConfig == null && selectedValue === "") || paramCreateConfig?.name == "" || !!paramCreateConfig?.nameError;
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -78,41 +83,25 @@ const ParameterEditor: React.FunctionComponent<IParameterEditorProps> = (props)
|
|||
onDismiss={hideModal}
|
||||
maxWidth={800}
|
||||
dialogContentProps={{
|
||||
//className: contentStyles.container,
|
||||
styles: { inner: { minWidth: 600 }, innerContent: { maxHeight: 800 } },
|
||||
titleProps: { id: titleId },
|
||||
type: DialogType.normal,
|
||||
type: DialogType.close,
|
||||
title: Localizer.l("parameterEditorTitle").format(propertyName),
|
||||
subText: Localizer.l("parameterEditorText")
|
||||
}}
|
||||
modalProps={{ isBlocking: true, titleAriaId: titleId, topOffsetFixed: true }}
|
||||
modalProps={{ isBlocking: true, titleAriaId: titleId, topOffsetFixed: false }}
|
||||
>
|
||||
<div className={contentStyles.body}>
|
||||
<Pivot
|
||||
aria-label={Localizer.l("parameterEditorPivotAriaLabel")}
|
||||
styles={{
|
||||
itemContainer: {
|
||||
paddingTop: 10
|
||||
}
|
||||
}}
|
||||
onLinkClick={resetSelectedValue}
|
||||
defaultSelectedIndex={useAdvancedEditor ? 1 : 0}
|
||||
>
|
||||
<PivotItem headerText={Localizer.l("parameterEditorPivotBasicTabLabel")}>
|
||||
<ParameterEditorSimple
|
||||
parameters={parameters}
|
||||
setSelectedValue={setSelectedValue}
|
||||
setParameterCreationConfiguration={setParameterCreationConfiguration}
|
||||
resetSelectedValue={resetSelectedValue}
|
||||
/>
|
||||
</PivotItem>
|
||||
<PivotItem headerText={Localizer.l("parameterEditorPivotAdvancedTabLabel")}>
|
||||
<ParameterEditorAdvanced parameters={parameters} setSelectedValue={setSelectedValue} prevValue={prevValue} />
|
||||
</PivotItem>
|
||||
</Pivot>
|
||||
<ParameterEditorChoice
|
||||
parameters={parameters}
|
||||
setSelectedValue={setSelectedValue}
|
||||
setParamCreateConfig={setParamCreateConfig}
|
||||
resetSelectedValue={resetSelectedValue}
|
||||
prevValue={prevValue}
|
||||
/>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<AdjustedPrimaryButton text={Localizer.l("parameterEditorUseParameterInPropertyButtonText")} onClick={onClickUse} />
|
||||
<AdjustedPrimaryButton text={Localizer.l("parameterEditorUseParameterInPropertyButtonText")} onClick={onClickUse} disabled={setButtonDisabled()} />
|
||||
<DefaultButton text={Localizer.l("cancelButtonText")} onClick={hideModal} />
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
CheckboxVisibility,
|
||||
DefaultButton,
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
|
@ -56,6 +57,7 @@ export const ParameterEditorAdvanced: React.FunctionComponent<IParameterEditorAd
|
|||
key: "insertAction",
|
||||
name: "",
|
||||
minWidth: 0,
|
||||
maxWidth: 60,
|
||||
onRender: (item) => {
|
||||
return (
|
||||
<Link
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
import {
|
||||
CheckboxVisibility,
|
||||
ChoiceGroup,
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
IChoiceGroupOption,
|
||||
IColumn,
|
||||
ScrollablePane,
|
||||
Selection,
|
||||
SelectionMode
|
||||
} from "office-ui-fabric-react";
|
||||
import * as React from "react";
|
||||
import { MediaGraphParameterDeclaration } from "../../../Common/Types/LVASDKTypes";
|
||||
import Localizer from "../../Localization/Localizer";
|
||||
import { ParamCreateConfig } from "../ParameterSelector/ParameterSelector";
|
||||
import { ParameterEditorAdvanced } from "./ParameterEditorAdvanced";
|
||||
import { ParameterEditorCreateForm } from "./ParameterEditorCreateForm";
|
||||
import { ParameterEditorParameterList } from "./ParameterEditorParameterList";
|
||||
|
||||
interface IParameterEditorChoiceProps {
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
setSelectedValue: (newValue: string) => void;
|
||||
setParamCreateConfig: (newParameter: ParamCreateConfig) => void;
|
||||
resetSelectedValue: () => void;
|
||||
prevValue: string;
|
||||
}
|
||||
|
||||
export const ParameterEditorChoice: React.FunctionComponent<IParameterEditorChoiceProps> = (props) => {
|
||||
const { parameters, setSelectedValue, setParamCreateConfig, resetSelectedValue, prevValue } = props;
|
||||
|
||||
const options: IChoiceGroupOption[] = [
|
||||
{
|
||||
key: "new",
|
||||
text: Localizer.l("parameterEditorChoiceCreateNewLabel"),
|
||||
styles: {
|
||||
root: {
|
||||
marginRight: 10,
|
||||
marginTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "existing",
|
||||
text: Localizer.l("parameterEditorChoiceUseExistingLabel"),
|
||||
styles: {
|
||||
root: {
|
||||
marginRight: 10,
|
||||
marginTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "advanced",
|
||||
text: Localizer.l("parameterEditorChoiceAdvancedLabel"),
|
||||
styles: {
|
||||
root: {
|
||||
marginTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
const firstKey = options[0].key;
|
||||
const [selectedFormKey, setSelectedFormKey] = React.useState<string>(firstKey);
|
||||
|
||||
const onParameterSourceChange = (ev?: React.FormEvent, option?: IChoiceGroupOption) => {
|
||||
if (option) {
|
||||
setSelectedFormKey(option.key);
|
||||
}
|
||||
resetSelectedValue();
|
||||
};
|
||||
|
||||
const selectPanel = (selectedKey: string) => {
|
||||
switch (selectedKey) {
|
||||
case "new":
|
||||
return <ParameterEditorCreateForm setParamCreateConfig={setParamCreateConfig} parameters={parameters} />;
|
||||
case "existing":
|
||||
return <ParameterEditorParameterList parameters={parameters} setSelectedValue={setSelectedValue} />;
|
||||
default:
|
||||
return <ParameterEditorAdvanced parameters={parameters} setSelectedValue={setSelectedValue} prevValue={prevValue} />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ChoiceGroup
|
||||
defaultSelectedKey={firstKey}
|
||||
options={options}
|
||||
onChange={onParameterSourceChange}
|
||||
label={Localizer.l("parameterEditorBasicEditorSourceChoiceLabel")}
|
||||
required={true}
|
||||
styles={{
|
||||
flexContainer: {
|
||||
display: "flex"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<React.Suspense fallback={<></>}>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
>
|
||||
{selectPanel(selectedFormKey)}
|
||||
</div>
|
||||
</React.Suspense>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
import some from "lodash/some";
|
||||
import {
|
||||
Dropdown,
|
||||
IDropdownOption,
|
||||
|
@ -10,17 +11,19 @@ import {
|
|||
MediaGraphParameterType
|
||||
} from "../../../Common/Types/LVASDKTypes";
|
||||
import Localizer from "../../Localization/Localizer";
|
||||
import { ParamCreateConfig } from "../ParameterSelector/ParameterSelector";
|
||||
|
||||
interface IParameterEditorCreateFormProps {
|
||||
horizontal?: boolean;
|
||||
setParameterCreationConfiguration: (newParameter: MediaGraphParameterDeclaration) => void;
|
||||
setParamCreateConfig: (newParameter: ParamCreateConfig) => void;
|
||||
name?: string;
|
||||
type?: string;
|
||||
value?: string;
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
}
|
||||
|
||||
export const ParameterEditorCreateForm: React.FunctionComponent<IParameterEditorCreateFormProps> = (props) => {
|
||||
const { setParameterCreationConfiguration, horizontal, name, type, value } = props;
|
||||
const { parameters, setParamCreateConfig, horizontal, name, type, value } = props;
|
||||
|
||||
const options = [
|
||||
{ key: "String", text: "String" },
|
||||
|
@ -31,16 +34,33 @@ export const ParameterEditorCreateForm: React.FunctionComponent<IParameterEditor
|
|||
];
|
||||
|
||||
const [parameterName, setParameterName] = React.useState<string>(name ?? "");
|
||||
const [parameterNameError, setParameterNameError] = React.useState<string>(name ?? "");
|
||||
const [parameterType, setParameterType] = React.useState<MediaGraphParameterType>((type ?? options[0].key) as MediaGraphParameterType);
|
||||
const [parameterDefaultValue, setParameterDefaultValue] = React.useState<string>(value ?? "");
|
||||
|
||||
React.useEffect(() => {
|
||||
setParameterCreationConfiguration({
|
||||
setParamCreateConfig({
|
||||
name: parameterName,
|
||||
type: parameterType,
|
||||
default: parameterDefaultValue
|
||||
default: parameterDefaultValue,
|
||||
nameError: parameterNameError
|
||||
});
|
||||
}, [parameterName, parameterType, parameterDefaultValue]);
|
||||
}, [parameterName, parameterNameError, parameterType, parameterDefaultValue]);
|
||||
|
||||
const parameterNameValidate = (newName: string) => {
|
||||
let error = "";
|
||||
if (!newName) {
|
||||
error = Localizer.l("propertyEditorValidationUndefinedOrEmpty");
|
||||
} else if (
|
||||
some(parameters, (param) => {
|
||||
return param.name !== name && param.name === newName;
|
||||
})
|
||||
) {
|
||||
error = Localizer.l("parameterAlreadyExists");
|
||||
}
|
||||
setParameterNameError(error);
|
||||
return error;
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack style={{ flexGrow: 1 }} horizontal={horizontal} tokens={horizontal ? { childrenGap: "s1" } : {}}>
|
||||
|
@ -49,6 +69,8 @@ export const ParameterEditorCreateForm: React.FunctionComponent<IParameterEditor
|
|||
placeholder={Localizer.l("parameterEditorCreateFormNameFieldPlaceholder")}
|
||||
required
|
||||
value={parameterName}
|
||||
validateOnLoad={false}
|
||||
onGetErrorMessage={parameterNameValidate}
|
||||
onChange={(event, newValue?) => {
|
||||
setParameterName(newValue ?? "");
|
||||
}}
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
import {
|
||||
Announced,
|
||||
CheckboxVisibility,
|
||||
DefaultButton,
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
Dropdown,
|
||||
getTheme,
|
||||
IColumn,
|
||||
Link,
|
||||
ScrollablePane,
|
||||
SearchBox,
|
||||
Selection,
|
||||
SelectionMode,
|
||||
Stack,
|
||||
TextField
|
||||
} from "office-ui-fabric-react";
|
||||
|
@ -20,32 +28,72 @@ import { ParameterEditorCreateForm } from "./ParameterEditorCreateForm";
|
|||
interface IParameterEditorParameterListProps {
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
onAddNew?: (newValue: string) => void;
|
||||
renderItemList: (items: MediaGraphParameterDeclaration[], entryContainerStyles: React.CSSProperties, entryDetailsStyles: React.CSSProperties) => JSX.Element; // TODO: fix
|
||||
renderItemList?: (items: MediaGraphParameterDeclaration[], entryContainerStyles: React.CSSProperties, entryDetailsStyles: React.CSSProperties) => JSX.Element; // TODO: fix
|
||||
setSelectedValue?: (newValue: string) => void;
|
||||
}
|
||||
|
||||
export const ParameterEditorParameterList: React.FunctionComponent<IParameterEditorParameterListProps> = (props) => {
|
||||
const { parameters, onAddNew, renderItemList } = props;
|
||||
const { parameters, onAddNew, renderItemList, setSelectedValue } = props;
|
||||
const [shownFilteredItems, setShownFilteredItems] = React.useState<MediaGraphParameterDeclaration[]>([]);
|
||||
const [isCreateFormShown, { toggle: toggleCreateForm }] = useBoolean(false);
|
||||
const [filterText, setFilterText] = React.useState<string>("");
|
||||
const [parameterCreationConfiguration, setParameterCreationConfiguration] = React.useState<MediaGraphParameterDeclaration | undefined>();
|
||||
|
||||
const items: MediaGraphParameterDeclaration[] = [
|
||||
...parameters,
|
||||
{
|
||||
name: "System.DateTime",
|
||||
type: "String" as MediaGraphParameterType
|
||||
type: MediaGraphParameterType.String
|
||||
},
|
||||
{
|
||||
name: "System.GraphTopologyName",
|
||||
type: "String" as MediaGraphParameterType
|
||||
type: MediaGraphParameterType.String
|
||||
},
|
||||
{
|
||||
name: "System.GraphInstanceName",
|
||||
type: "String" as MediaGraphParameterType
|
||||
type: MediaGraphParameterType.String
|
||||
}
|
||||
];
|
||||
|
||||
const onSearchChange = (event?: React.ChangeEvent, newValue?: string) => {
|
||||
let renderItemsFunction = renderItemList;
|
||||
if (!renderItemsFunction) {
|
||||
const selection = new Selection({
|
||||
onSelectionChanged: () => {
|
||||
const selectedItems = selection.getSelection();
|
||||
if (selectedItems?.length) {
|
||||
console.log(selectedItems);
|
||||
if (setSelectedValue) {
|
||||
setSelectedValue(`$\{${(selectedItems[0] as IColumn).name}}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
selectionMode: SelectionMode.single
|
||||
});
|
||||
|
||||
renderItemsFunction = (items: MediaGraphParameterDeclaration[], entryContainerStyles: React.CSSProperties, entryDetailsStyles: React.CSSProperties) => {
|
||||
return (
|
||||
<div style={{ position: "relative", minHeight: 200 }}>
|
||||
<ScrollablePane>
|
||||
<DetailsList
|
||||
items={items}
|
||||
layoutMode={DetailsListLayoutMode.justified}
|
||||
checkboxVisibility={CheckboxVisibility.always}
|
||||
columns={[
|
||||
{ key: "name", name: "name", fieldName: "name", minWidth: 10, isRowHeader: true },
|
||||
{ key: "type", name: "type", fieldName: "type", minWidth: 80 },
|
||||
{ key: "default", name: "default", fieldName: "default", minWidth: 80 }
|
||||
]}
|
||||
selection={selection}
|
||||
compact={true}
|
||||
/>
|
||||
</ScrollablePane>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
const onSearchChange = (event?: React.FormEvent, newValue?: string) => {
|
||||
setFilterText(newValue!);
|
||||
if (newValue) {
|
||||
const lowerCaseQuery = newValue.toLocaleLowerCase();
|
||||
setShownFilteredItems(items.filter((item) => item.name.toLocaleLowerCase().includes(lowerCaseQuery)));
|
||||
|
@ -82,14 +130,23 @@ export const ParameterEditorParameterList: React.FunctionComponent<IParameterEdi
|
|||
return (
|
||||
<Stack tokens={{ childrenGap: "s1" }} style={parameterListItemContainerStyles}>
|
||||
<Stack horizontal tokens={{ childrenGap: "s1" }}>
|
||||
<SearchBox placeholder={Localizer.l("parameterEditorParameterListSearchPlaceholder")} onChange={onSearchChange} styles={{ root: { flexGrow: 1 } }} />
|
||||
<TextField
|
||||
label={Localizer.l("parameterEditorParameterListSearchLabel")}
|
||||
onChange={onSearchChange}
|
||||
styles={onAddNew ? { root: { flexGrow: 1 } } : { root: { maxWidth: 350 } }}
|
||||
/>
|
||||
{onAddNew && !isCreateFormShown && (
|
||||
<DefaultButton text={Localizer.l("parameterEditorParameterListAddButtonLabel")} iconProps={{ iconName: "Add" }} onClick={toggleCreateForm} />
|
||||
<DefaultButton
|
||||
text={Localizer.l("parameterEditorParameterListAddButtonLabel")}
|
||||
iconProps={{ iconName: "Add" }}
|
||||
onClick={toggleCreateForm}
|
||||
style={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
{isCreateFormShown && (
|
||||
<Stack horizontal tokens={{ childrenGap: "s1" }} verticalAlign={"end"}>
|
||||
<ParameterEditorCreateForm setParameterCreationConfiguration={setParameterCreationConfiguration} horizontal={true} />
|
||||
<ParameterEditorCreateForm setParamCreateConfig={setParameterCreationConfiguration} horizontal={true} parameters={parameters} />
|
||||
<DefaultButton
|
||||
iconProps={{ iconName: "Add" }}
|
||||
onClick={onCreateFormAddClick}
|
||||
|
@ -97,7 +154,8 @@ export const ParameterEditorParameterList: React.FunctionComponent<IParameterEdi
|
|||
/>
|
||||
</Stack>
|
||||
)}
|
||||
{renderItemList(shownFilteredItems.length > 0 ? shownFilteredItems : items, parameterListEntryStyles, parameterListEntryDetailsStyles)}
|
||||
<Announced message={Localizer.l("parameterEditorParameterListFilteredAnnounce").format(shownFilteredItems.length || items.length)} />
|
||||
{renderItemsFunction(filterText ? shownFilteredItems : items, parameterListEntryStyles, parameterListEntryDetailsStyles)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
import {
|
||||
ChoiceGroup,
|
||||
DetailsList,
|
||||
DetailsListLayoutMode,
|
||||
IChoiceGroupOption,
|
||||
IColumn,
|
||||
ScrollablePane,
|
||||
Selection,
|
||||
SelectionMode
|
||||
} from "office-ui-fabric-react";
|
||||
import * as React from "react";
|
||||
import { MediaGraphParameterDeclaration } from "../../../Common/Types/LVASDKTypes";
|
||||
import Localizer from "../../Localization/Localizer";
|
||||
import { ParameterEditorCreateForm } from "./ParameterEditorCreateForm";
|
||||
import { ParameterEditorParameterList } from "./ParameterEditorParameterList";
|
||||
|
||||
interface IParameterEditorSimpleProps {
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
setSelectedValue: (newValue: string) => void;
|
||||
setParameterCreationConfiguration: (newParameter: MediaGraphParameterDeclaration) => void;
|
||||
resetSelectedValue: () => void;
|
||||
}
|
||||
|
||||
export const ParameterEditorSimple: React.FunctionComponent<IParameterEditorSimpleProps> = (props) => {
|
||||
const { parameters, setSelectedValue, setParameterCreationConfiguration, resetSelectedValue } = props;
|
||||
|
||||
const options: IChoiceGroupOption[] = [
|
||||
{
|
||||
key: "new",
|
||||
text: Localizer.l("parameterEditorBasicEditorSourceCreateNewLabel"),
|
||||
styles: {
|
||||
root: {
|
||||
marginRight: 10,
|
||||
marginTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "existing",
|
||||
text: Localizer.l("parameterEditorBasicEditorSourceUseExistingLabel"),
|
||||
styles: {
|
||||
root: {
|
||||
marginTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
const firstKey = options[0].key;
|
||||
const [selectedFormKey, setSelectedFormKey] = React.useState<string>(firstKey);
|
||||
|
||||
const onParameterSourceChange = (ev?: React.FormEvent, option?: IChoiceGroupOption) => {
|
||||
if (option) {
|
||||
setSelectedFormKey(option.key);
|
||||
}
|
||||
resetSelectedValue();
|
||||
};
|
||||
|
||||
const selection = new Selection({
|
||||
onSelectionChanged: () => {
|
||||
const selectedItems = selection.getSelection();
|
||||
if (selectedItems?.length) {
|
||||
console.log(selectedItems);
|
||||
setSelectedValue(`$\{${(selectedItems[0] as IColumn).name}}`);
|
||||
}
|
||||
},
|
||||
selectionMode: SelectionMode.single
|
||||
});
|
||||
|
||||
const renderItemList = (items: MediaGraphParameterDeclaration[], entryContainerStyles: React.CSSProperties, entryDetailsStyles: React.CSSProperties) => {
|
||||
return (
|
||||
<div style={{ position: "relative", minHeight: 200 }}>
|
||||
<ScrollablePane>
|
||||
<DetailsList
|
||||
items={items}
|
||||
columns={[
|
||||
{ key: "name", name: "name", fieldName: "name", minWidth: 10, isRowHeader: true },
|
||||
{ key: "type", name: "type", fieldName: "type", minWidth: 80 },
|
||||
{ key: "default", name: "default", fieldName: "default", minWidth: 80 }
|
||||
]}
|
||||
selectionMode={SelectionMode.single}
|
||||
selection={selection}
|
||||
/>
|
||||
</ScrollablePane>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ChoiceGroup
|
||||
defaultSelectedKey={firstKey}
|
||||
options={options}
|
||||
onChange={onParameterSourceChange}
|
||||
label={Localizer.l("parameterEditorBasicEditorSourceChoiceLabel")}
|
||||
required={true}
|
||||
styles={{
|
||||
flexContainer: {
|
||||
display: "flex"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{selectedFormKey === "new" ? (
|
||||
<div
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
>
|
||||
<ParameterEditorCreateForm setParameterCreationConfiguration={setParameterCreationConfiguration} />
|
||||
</div>
|
||||
) : (
|
||||
<ParameterEditorParameterList renderItemList={renderItemList} parameters={parameters} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -8,6 +8,7 @@ interface EditableParameterProps {
|
|||
id?: number;
|
||||
data: any;
|
||||
showEdit: boolean;
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
onDeleteParameterClick: (index: number) => void;
|
||||
onEditParameterClick: (index: number) => void;
|
||||
onEditSaveParameterClick: (index: number) => void;
|
||||
|
@ -15,7 +16,7 @@ interface EditableParameterProps {
|
|||
}
|
||||
|
||||
export const EditableParameter: React.FunctionComponent<EditableParameterProps> = (props) => {
|
||||
const { id, data, showEdit, onDeleteParameterClick, onEditParameterClick, onEditSaveParameterClick, setParameterCreationConfiguration } = props;
|
||||
const { id, data, showEdit, parameters, onDeleteParameterClick, onEditParameterClick, onEditSaveParameterClick, setParameterCreationConfiguration } = props;
|
||||
const editableParamContainer: React.CSSProperties = {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
|
@ -74,10 +75,11 @@ export const EditableParameter: React.FunctionComponent<EditableParameterProps>
|
|||
<>
|
||||
<Stack style={attributes}>
|
||||
<ParameterEditorCreateForm
|
||||
setParameterCreationConfiguration={setParameterCreationConfiguration}
|
||||
setParamCreateConfig={setParameterCreationConfiguration}
|
||||
name={data.name}
|
||||
value={data.default}
|
||||
type={data.type}
|
||||
parameters={parameters}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack style={editIcons}>
|
||||
|
|
|
@ -2,8 +2,10 @@ import {
|
|||
DefaultButton,
|
||||
IIconProps,
|
||||
Panel,
|
||||
PanelType,
|
||||
PrimaryButton,
|
||||
SearchBox,
|
||||
Separator,
|
||||
Stack,
|
||||
Text
|
||||
} from "office-ui-fabric-react";
|
||||
|
@ -25,9 +27,14 @@ import {
|
|||
import { ParameterEditorCreateForm } from "../ParameterEditor/ParameterEditorCreateForm";
|
||||
import { EditableParameter } from "./EditableParameter";
|
||||
|
||||
export interface ParamCreateConfig extends MediaGraphParameterDeclaration {
|
||||
nameError?: string;
|
||||
defaultValueError?: string;
|
||||
}
|
||||
|
||||
interface ParameterSelectorProps {
|
||||
isOpen: boolean;
|
||||
parameters: any;
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
graph: any;
|
||||
propsApiRef: React.RefObject<IPropsAPI>;
|
||||
onClose: () => void;
|
||||
|
@ -43,10 +50,10 @@ const addIcon: IIconProps = { iconName: "Add" };
|
|||
|
||||
export const ParameterSelector: React.FunctionComponent<ParameterSelectorProps> = (props) => {
|
||||
const { isOpen, onClose, parameters, graph, propsApiRef } = props;
|
||||
const [addNewIsShown, { toggle: setAddNewIsShown }] = useBoolean(false);
|
||||
const [addNewIsShown, { toggle: toggleAddNewIsShown }] = useBoolean(false);
|
||||
const [showDeleteDialog, { toggle: toggleShowDeleteDialog }] = useBoolean(false);
|
||||
const [searchParameter, setSearchParameters] = React.useState<string>("");
|
||||
const [parameterCreationConfiguration, setParameterCreationConfiguration] = React.useState<MediaGraphParameterDeclaration | undefined>();
|
||||
const [paramCreateConfig, setParamCreateConfig] = React.useState<ParamCreateConfig | undefined>();
|
||||
const [editedParameter, setEditedParameter] = React.useState<number>(-1);
|
||||
const [focusedDeleteParameter, setFocusedDeleteParameter] = React.useState<number>(-1);
|
||||
const [paramsThatWillChange, setParamsThatWillChange] = React.useState<ParameterChangeValidation[]>([]);
|
||||
|
@ -69,22 +76,25 @@ export const ParameterSelector: React.FunctionComponent<ParameterSelectorProps>
|
|||
};
|
||||
|
||||
const onCreateFormAddClick = () => {
|
||||
if (parameterCreationConfiguration?.name && parameterCreationConfiguration?.type) {
|
||||
createParameter(parameterCreationConfiguration, parameters); //TODO. check for duplicates
|
||||
setAddNewIsShown();
|
||||
if (paramCreateConfig?.name && paramCreateConfig?.type) {
|
||||
createParameter(paramCreateConfig, parameters); //TODO. check for duplicates
|
||||
toggleAddNewIsShown();
|
||||
}
|
||||
};
|
||||
|
||||
const onEditParameterClick = (index: number) => {
|
||||
if (index >= 0 && addNewIsShown) {
|
||||
toggleAddNewIsShown();
|
||||
}
|
||||
setEditedParameter(index);
|
||||
};
|
||||
|
||||
const onEditSaveParameterClick = (index: number) => {
|
||||
if (parameterCreationConfiguration?.name && parameterCreationConfiguration?.type) {
|
||||
if (parameterCreationConfiguration.name != parameters[index].name) {
|
||||
graph.editParamsFromGraph(parameters[index].name, parameterCreationConfiguration.name);
|
||||
if (paramCreateConfig?.name && paramCreateConfig?.type) {
|
||||
if (paramCreateConfig.name != parameters[index].name) {
|
||||
graph.editParamsFromGraph(parameters[index].name, paramCreateConfig.name);
|
||||
}
|
||||
editParameter(parameterCreationConfiguration, parameters, index);
|
||||
editParameter(paramCreateConfig, parameters, index);
|
||||
}
|
||||
setEditedParameter(-1);
|
||||
};
|
||||
|
@ -125,7 +135,8 @@ export const ParameterSelector: React.FunctionComponent<ParameterSelectorProps>
|
|||
onDeleteParameterClick={onDeleteParameterClick}
|
||||
onEditParameterClick={onEditParameterClick}
|
||||
onEditSaveParameterClick={onEditSaveParameterClick}
|
||||
setParameterCreationConfiguration={setParameterCreationConfiguration}
|
||||
setParameterCreationConfiguration={setParamCreateConfig}
|
||||
parameters={parameters}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -169,47 +180,44 @@ export const ParameterSelector: React.FunctionComponent<ParameterSelectorProps>
|
|||
<DefaultButton onClick={toggleShowDeleteDialog} text={Localizer.l("editParametersCancelButtonText")} />
|
||||
</DialogFooter>
|
||||
</Dialog>
|
||||
<Panel isOpen={isOpen} onDismiss={onClose} closeButtonAriaLabel="Close">
|
||||
<Panel isOpen={isOpen} onDismiss={onClose} closeButtonAriaLabel="Close" type={PanelType.medium} isLightDismiss>
|
||||
{addNewIsShown ? (
|
||||
<Stack style={{ paddingBottom: "20px" }}>
|
||||
<Stack style={{ marginRight: 64 }}>
|
||||
<Stack style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center" }}>
|
||||
<Text style={{ flex: 1 }} variant={"large"}>
|
||||
{Localizer.l("newParameter")}
|
||||
</Text>
|
||||
<Text variant={"medium"} style={{ textDecoration: "underline", cursor: "pointer" }} onClick={setAddNewIsShown}>
|
||||
<Text variant={"medium"} style={{ textDecoration: "underline", cursor: "pointer" }} onClick={toggleAddNewIsShown}>
|
||||
{Localizer.l("hideForm")}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Stack>
|
||||
<ParameterEditorCreateForm setParameterCreationConfiguration={setParameterCreationConfiguration} />
|
||||
<Stack style={{ paddingTop: "15px" }}>
|
||||
<ParameterEditorCreateForm setParamCreateConfig={setParamCreateConfig} parameters={parameters} />
|
||||
<Stack style={{ paddingTop: "15px", paddingBottom: "10px", alignSelf: "flex-end" }}>
|
||||
<DefaultButton
|
||||
text="Add"
|
||||
onClick={onCreateFormAddClick}
|
||||
disabled={
|
||||
parameterCreationConfiguration == null ||
|
||||
parameterCreationConfiguration.name == null ||
|
||||
parameterCreationConfiguration.type == null
|
||||
}
|
||||
disabled={!!(!paramCreateConfig?.name || paramCreateConfig?.nameError || paramCreateConfig?.defaultValueError)}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Separator />
|
||||
</Stack>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Stack style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center", padding: "14px 0px 10px 0px" }}>
|
||||
<Text style={{ flex: 1 }} variant={"large"}>
|
||||
{Localizer.l("parameters")}
|
||||
</Text>
|
||||
{addNewIsShown ? (
|
||||
""
|
||||
) : (
|
||||
<DefaultButton text={Localizer.l("parameterEditorParameterListAddButtonLabel")} iconProps={addIcon} onClick={setAddNewIsShown} />
|
||||
)}
|
||||
</Stack>
|
||||
<Stack style={{ marginRight: 64 }}>
|
||||
<Stack style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center", padding: "14px 0px 10px 0px" }}>
|
||||
<Text style={{ flex: 1 }} variant={"large"}>
|
||||
{Localizer.l("parameters")}
|
||||
</Text>
|
||||
{addNewIsShown ? (
|
||||
""
|
||||
) : (
|
||||
<DefaultButton text={Localizer.l("parameterEditorParameterListAddButtonLabel")} iconProps={addIcon} onClick={toggleAddNewIsShown} />
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<SearchBox placeholder="Search" onSearch={searchFunction} />
|
||||
</Stack>
|
||||
{createParameterFields()}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { ActionButton } from "office-ui-fabric-react/lib/Button";
|
||||
import React, { useState } from "react";
|
||||
import { IPropsAPI } from "@vienna/react-dag-editor";
|
||||
import { MediaGraphParameterDeclaration } from "../../../Common/Types/LVASDKTypes";
|
||||
import Localizer from "../../Localization/Localizer";
|
||||
import { ParameterSelector } from "./ParameterSelector";
|
||||
|
||||
interface IParameterSelectorTriggerProps {
|
||||
parameters: any;
|
||||
parameters: MediaGraphParameterDeclaration[];
|
||||
graph: any;
|
||||
propsApiRef: React.RefObject<IPropsAPI>;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ export const PropertyEditField: React.FunctionComponent<IPropertyEditFieldProps>
|
|||
onRenderLabel={onRenderLabel}
|
||||
aria-labelledby={labelId}
|
||||
onGetErrorMessage={validateInput}
|
||||
validateOnLoad={false}
|
||||
/>
|
||||
);
|
||||
} else if (property.type === "boolean") {
|
||||
|
@ -270,6 +271,7 @@ export const PropertyEditField: React.FunctionComponent<IPropertyEditFieldProps>
|
|||
onRenderLabel={onRenderLabel}
|
||||
aria-labelledby={labelId}
|
||||
onGetErrorMessage={validateInput}
|
||||
validateOnLoad={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
"parameterEditorText": "Create or select a parameter to insert into your value format.",
|
||||
"parameterEditorPivotAriaLabel": "Switch between basic and advanced parameter editor.",
|
||||
"parameterEditorPivotBasicTabLabel": "Basic",
|
||||
"parameterEditorPivotAdvancedTabLabel": "Advanced",
|
||||
"parameterEditorChoiceAdvancedLabel": "Advanced",
|
||||
"parameterEditorUseParameterInPropertyButtonText": "Set",
|
||||
"parameterEditorAdvancedEditorInsertLinkText": "Insert",
|
||||
"parameterEditorAdvancedEditorMainInputLabel": "Value format",
|
||||
|
@ -106,11 +106,12 @@
|
|||
"parameterEditorCreateFormTypeDropdownPlaceholder": "Select a parameter type",
|
||||
"parameterEditorCreateFormDefaultFieldLabel": "Default value",
|
||||
"parameterEditorCreateFormDefaultFieldPlaceholder": "Enter default value",
|
||||
"parameterEditorParameterListSearchPlaceholder": "Search",
|
||||
"parameterEditorParameterListSearchLabel": "Filter by name",
|
||||
"parameterEditorParameterListFilteredAnnounce": "Number of parameters after filter applied: {0}",
|
||||
"parameterEditorParameterListAddButtonLabel": "Add new",
|
||||
"parameterEditorBasicEditorSourceChoiceLabel": "Parameter source",
|
||||
"parameterEditorBasicEditorSourceCreateNewLabel": "Create new",
|
||||
"parameterEditorBasicEditorSourceUseExistingLabel": "Select existing",
|
||||
"parameterEditorChoiceCreateNewLabel": "Create new",
|
||||
"parameterEditorChoiceUseExistingLabel": "Select existing",
|
||||
"propertyEditorCloseButtonAriaLabel": "Click to close the property editor.",
|
||||
"propertyEditorOverflowMenuTitle": "Show more options for this property.",
|
||||
"propertyEditorOverflowMenuAriaLabel": "Click to show more options for this property.",
|
||||
|
@ -122,6 +123,7 @@
|
|||
"propertyEditorValidationUndefined": "This value cannot be undefined.",
|
||||
"propertyEditorValidationEmpty": "This value cannot be empty.",
|
||||
"propertyEditorValidationUndefinedOrEmpty": "This value cannot be undefined or empty.",
|
||||
"parameterAlreadyExists": "This parameter name already exists.",
|
||||
"propertyEditorValidationInvalidJSON": "The entered JSON does not validate.",
|
||||
"nameNotAvailableError": "Name is not available",
|
||||
"hideForm": "Hide form",
|
||||
|
|
|
@ -239,13 +239,13 @@ export default class Graph {
|
|||
|
||||
for (let i = 0; i < propertyKeys.length; i++) {
|
||||
const propertyValue = nestedNode[propertyKeys[i]];
|
||||
if (typeof propertyValue != "number" && typeof propertyValue != "boolean") {
|
||||
if (typeof propertyValue != "string") {
|
||||
if (typeof propertyValue !== "number" && typeof propertyValue !== "boolean") {
|
||||
if (typeof propertyValue !== "string") {
|
||||
nodeDrillDown.push(propertyKeys[i]);
|
||||
const newItem = this.recursiveCheckForParamsInGraphNode(propertyValue, nodeName, nodeId, parameterName, nodeDrillDown);
|
||||
itemsThatWillChange = itemsThatWillChange.concat(newItem);
|
||||
} else {
|
||||
if (propertyValue != null && propertyValue.indexOf(parameterName) != -1) {
|
||||
if (propertyValue != null && propertyValue.indexOf(parameterName) !== -1) {
|
||||
nodeDrillDown.push(propertyKeys[i]);
|
||||
const tempObj: ParameterChangeValidation = {
|
||||
nodeId: nodeId,
|
||||
|
@ -277,7 +277,7 @@ export default class Graph {
|
|||
if (typeof propertyValue != "string") {
|
||||
this.recursiveDeleteParamsFromGraph(propertyValue, parameterName);
|
||||
} else {
|
||||
if (propertyValue != null && propertyValue.indexOf(parameterName) != -1) {
|
||||
if (propertyValue != null && propertyValue.indexOf(parameterName) !== -1) {
|
||||
nestedNode[propertyKeys[i]] = "";
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ export default class Graph {
|
|||
if (typeof propertyValue != "string") {
|
||||
this.recursiveEditParamsFromGraph(propertyValue, oldParameterName, newParameterName);
|
||||
} else {
|
||||
if (propertyValue != null && propertyValue.indexOf(oldParameterName) != -1) {
|
||||
if (propertyValue != null && propertyValue.indexOf(oldParameterName) !== -1) {
|
||||
nestedNode[propertyKeys[i]] = propertyValue.replace(oldParameterName, newParameterName);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче