@backstage/plugin-scaffolder-react 3.0.0-next.0 → 3.0.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/alpha.d.ts +7 -0
- package/dist/index.d.ts +1 -1
- package/dist/next/components/Form/BuiTheme/templates/ArrayFieldItemTemplate.esm.js +25 -25
- package/dist/next/components/Form/BuiTheme/templates/ArrayFieldItemTemplate.esm.js.map +1 -1
- package/dist/next/components/Form/BuiTheme/widgets/SelectWidget.esm.js +50 -30
- package/dist/next/components/Form/BuiTheme/widgets/SelectWidget.esm.js.map +1 -1
- package/dist/next/components/ReviewState/ReviewState.esm.js +3 -2
- package/dist/next/components/ReviewState/ReviewState.esm.js.map +1 -1
- package/dist/next/components/Stepper/Stepper.esm.js +63 -25
- package/dist/next/components/Stepper/Stepper.esm.js.map +1 -1
- package/dist/next/hooks/useTemplateSchema.esm.js +6 -5
- package/dist/next/hooks/useTemplateSchema.esm.js.map +1 -1
- package/package.json +18 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-react
|
|
2
2
|
|
|
3
|
+
## 3.0.0-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e8c4fb9: Improved screen reader support in the BUI scaffolder form theme: array item controls include the item name in their labels.
|
|
8
|
+
- 818fbd6: The BUI form theme now renders a multi-select dropdown for array fields with unique `enum` items, and focus/blur events now report the selected values correctly.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/core-components@0.18.16-next.1
|
|
11
|
+
- @backstage/ui@0.20.0-next.0
|
|
12
|
+
- @backstage/frontend-plugin-api@0.19.0-next.2
|
|
13
|
+
- @backstage/catalog-client@1.16.4-next.1
|
|
14
|
+
- @backstage/catalog-model@1.10.3-next.0
|
|
15
|
+
- @backstage/core-plugin-api@1.12.12-next.2
|
|
16
|
+
- @backstage/plugin-catalog-react@4.0.0-next.2
|
|
17
|
+
- @backstage/plugin-scaffolder-common@2.4.0-next.1
|
|
18
|
+
- @backstage/plugin-permission-react@0.5.7-next.1
|
|
19
|
+
|
|
20
|
+
## 3.0.0-next.1
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- ff0ef74: The scaffolder wizard now shows or hides parameter steps based on their `when` condition, and values from hidden steps are left out of the submitted parameters.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/catalog-client@1.16.4-next.0
|
|
30
|
+
- @backstage/core-plugin-api@1.12.12-next.1
|
|
31
|
+
- @backstage/frontend-plugin-api@0.19.0-next.1
|
|
32
|
+
- @backstage/plugin-scaffolder-common@2.4.0-next.0
|
|
33
|
+
- @backstage/plugin-catalog-react@4.0.0-next.1
|
|
34
|
+
|
|
3
35
|
## 3.0.0-next.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/dist/alpha.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ interface ParsedTemplateSchema {
|
|
|
35
35
|
schema: JsonObject;
|
|
36
36
|
title: string;
|
|
37
37
|
description?: string;
|
|
38
|
+
when?: string | boolean;
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* This hook will parse the template schema and return the steps with the
|
|
@@ -54,6 +55,12 @@ declare const useTemplateSchema: (manifest: TemplateParameterSchema) => {
|
|
|
54
55
|
type ReviewStateProps = {
|
|
55
56
|
schemas: ParsedTemplateSchema[];
|
|
56
57
|
formState: JsonObject;
|
|
58
|
+
/**
|
|
59
|
+
* The complete form state, used to resolve conditional schemas such as
|
|
60
|
+
* `dependencies` so that review masks still apply when `formState` has had
|
|
61
|
+
* values removed. Defaults to `formState`.
|
|
62
|
+
*/
|
|
63
|
+
schemaFormState?: JsonObject;
|
|
57
64
|
};
|
|
58
65
|
/**
|
|
59
66
|
* The component used by the {@link Stepper} to render the review step.
|
package/dist/index.d.ts
CHANGED
|
@@ -560,7 +560,7 @@ declare const ScaffolderLayouts: ComponentType<PropsWithChildren<{}>>;
|
|
|
560
560
|
* Hook that returns all custom field extensions from the current outlet.
|
|
561
561
|
* @public
|
|
562
562
|
*/
|
|
563
|
-
declare const useCustomLayouts: <TComponentDataType = LayoutOptions
|
|
563
|
+
declare const useCustomLayouts: <TComponentDataType = LayoutOptions>(outlet: React.ReactNode) => TComponentDataType[];
|
|
564
564
|
|
|
565
565
|
/**
|
|
566
566
|
* The status of the step being processed
|
|
@@ -21,33 +21,33 @@ function ArrayFieldItemTemplate({
|
|
|
21
21
|
uiSchema
|
|
22
22
|
}) {
|
|
23
23
|
const [isOpen, setIsOpen] = useState(true);
|
|
24
|
-
const itemTitle = uiSchema?.["ui:title"]
|
|
24
|
+
const itemTitle = uiSchema?.["ui:title"] || (schema.title ? `${schema.title} ${index + 1}` : `Item ${index + 1}`);
|
|
25
25
|
return /* @__PURE__ */ jsx(Box, { mb: "4", children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(Disclosure, { isExpanded: isOpen, onExpandedChange: setIsOpen, children: ({ isExpanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
26
26
|
/* @__PURE__ */ jsx(
|
|
27
27
|
CardHeader,
|
|
28
28
|
{
|
|
29
29
|
style: { backgroundColor: "var(--bui-bg-neutral-2)" },
|
|
30
30
|
children: /* @__PURE__ */ jsx(Box, { py: "3", px: "4", children: /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "between", children: [
|
|
31
|
-
/* @__PURE__ */
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
31
|
+
/* @__PURE__ */ jsx(Flex, { align: "center", gap: "2", children: /* @__PURE__ */ jsxs(
|
|
32
|
+
Button,
|
|
33
|
+
{
|
|
34
|
+
slot: "trigger",
|
|
35
|
+
style: {
|
|
36
|
+
padding: "2px",
|
|
37
|
+
background: "none",
|
|
38
|
+
border: "none",
|
|
39
|
+
cursor: "pointer",
|
|
40
|
+
display: "flex",
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
gap: "8px",
|
|
43
|
+
color: "var(--bui-fg-secondary)"
|
|
44
|
+
},
|
|
45
|
+
children: [
|
|
46
|
+
isExpanded ? /* @__PURE__ */ jsx(RiArrowDownSLine, { size: 18 }) : /* @__PURE__ */ jsx(RiArrowRightSLine, { size: 18 }),
|
|
47
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-medium", weight: "bold", children: itemTitle })
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
) }),
|
|
51
51
|
hasToolbar && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "1", children: [
|
|
52
52
|
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
53
53
|
/* @__PURE__ */ jsx(
|
|
@@ -57,7 +57,7 @@ function ArrayFieldItemTemplate({
|
|
|
57
57
|
size: "small",
|
|
58
58
|
isDisabled: disabled || readonly || !hasMoveUp,
|
|
59
59
|
onClick: onReorderClick(index, index - 1),
|
|
60
|
-
"aria-label":
|
|
60
|
+
"aria-label": `Move up ${itemTitle}`,
|
|
61
61
|
icon: /* @__PURE__ */ jsx(RiArrowUpSLine, { size: 18 })
|
|
62
62
|
}
|
|
63
63
|
),
|
|
@@ -68,7 +68,7 @@ function ArrayFieldItemTemplate({
|
|
|
68
68
|
size: "small",
|
|
69
69
|
isDisabled: disabled || readonly || !hasMoveDown,
|
|
70
70
|
onClick: onReorderClick(index, index + 1),
|
|
71
|
-
"aria-label":
|
|
71
|
+
"aria-label": `Move down ${itemTitle}`,
|
|
72
72
|
icon: /* @__PURE__ */ jsx(RiArrowDownSLine, { size: 18 })
|
|
73
73
|
}
|
|
74
74
|
)
|
|
@@ -80,7 +80,7 @@ function ArrayFieldItemTemplate({
|
|
|
80
80
|
size: "small",
|
|
81
81
|
isDisabled: disabled || readonly,
|
|
82
82
|
onClick: onCopyIndexClick(index),
|
|
83
|
-
"aria-label":
|
|
83
|
+
"aria-label": `Duplicate ${itemTitle}`,
|
|
84
84
|
icon: /* @__PURE__ */ jsx(RiAddLine, { size: 18 })
|
|
85
85
|
}
|
|
86
86
|
),
|
|
@@ -91,7 +91,7 @@ function ArrayFieldItemTemplate({
|
|
|
91
91
|
size: "small",
|
|
92
92
|
isDisabled: disabled || readonly,
|
|
93
93
|
onClick: onDropIndexClick(index),
|
|
94
|
-
"aria-label":
|
|
94
|
+
"aria-label": `Remove ${itemTitle}`,
|
|
95
95
|
icon: /* @__PURE__ */ jsx(RiDeleteBinLine, { size: 18 })
|
|
96
96
|
}
|
|
97
97
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayFieldItemTemplate.esm.js","sources":["../../../../../../src/next/components/Form/BuiTheme/templates/ArrayFieldItemTemplate.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ArrayFieldTemplateItemType,\n FormContextType,\n RJSFSchema,\n StrictRJSFSchema,\n} from '@rjsf/utils';\nimport { useState } from 'react';\nimport {\n Card,\n CardHeader,\n CardBody,\n Flex,\n Text,\n ButtonIcon,\n Box,\n Button,\n} from '@backstage/ui';\nimport { Disclosure, DisclosurePanel } from 'react-aria-components';\nimport {\n RiArrowDownSLine,\n RiArrowUpSLine,\n RiDeleteBinLine,\n RiAddLine,\n RiArrowRightSLine,\n} from '@remixicon/react';\n\nexport default function ArrayFieldItemTemplate<\n T = any,\n S extends StrictRJSFSchema = RJSFSchema,\n F extends FormContextType = any,\n>({\n children,\n disabled,\n hasToolbar,\n hasCopy,\n hasMoveDown,\n hasMoveUp,\n hasRemove,\n index,\n onCopyIndexClick,\n onDropIndexClick,\n onReorderClick,\n readonly,\n schema,\n uiSchema,\n}: ArrayFieldTemplateItemType<T, S, F>) {\n const [isOpen, setIsOpen] = useState(true);\n\n const itemTitle =\n uiSchema?.['ui:title']
|
|
1
|
+
{"version":3,"file":"ArrayFieldItemTemplate.esm.js","sources":["../../../../../../src/next/components/Form/BuiTheme/templates/ArrayFieldItemTemplate.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ArrayFieldTemplateItemType,\n FormContextType,\n RJSFSchema,\n StrictRJSFSchema,\n} from '@rjsf/utils';\nimport { useState } from 'react';\nimport {\n Card,\n CardHeader,\n CardBody,\n Flex,\n Text,\n ButtonIcon,\n Box,\n Button,\n} from '@backstage/ui';\nimport { Disclosure, DisclosurePanel } from 'react-aria-components';\nimport {\n RiArrowDownSLine,\n RiArrowUpSLine,\n RiDeleteBinLine,\n RiAddLine,\n RiArrowRightSLine,\n} from '@remixicon/react';\n\nexport default function ArrayFieldItemTemplate<\n T = any,\n S extends StrictRJSFSchema = RJSFSchema,\n F extends FormContextType = any,\n>({\n children,\n disabled,\n hasToolbar,\n hasCopy,\n hasMoveDown,\n hasMoveUp,\n hasRemove,\n index,\n onCopyIndexClick,\n onDropIndexClick,\n onReorderClick,\n readonly,\n schema,\n uiSchema,\n}: ArrayFieldTemplateItemType<T, S, F>) {\n const [isOpen, setIsOpen] = useState(true);\n\n const itemTitle =\n uiSchema?.['ui:title'] ||\n (schema.title ? `${schema.title} ${index + 1}` : `Item ${index + 1}`);\n\n return (\n <Box mb=\"4\">\n <Card>\n <Disclosure isExpanded={isOpen} onExpandedChange={setIsOpen}>\n {({ isExpanded }) => (\n <>\n <CardHeader\n style={{ backgroundColor: 'var(--bui-bg-neutral-2)' }}\n >\n <Box py=\"3\" px=\"4\">\n <Flex align=\"center\" justify=\"between\">\n <Flex align=\"center\" gap=\"2\">\n <Button\n slot=\"trigger\"\n style={{\n padding: '2px',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n color: 'var(--bui-fg-secondary)',\n }}\n >\n {isExpanded ? (\n <RiArrowDownSLine size={18} />\n ) : (\n <RiArrowRightSLine size={18} />\n )}\n <Text variant=\"body-medium\" weight=\"bold\">\n {itemTitle}\n </Text>\n </Button>\n </Flex>\n {hasToolbar && (\n <Flex align=\"center\" gap=\"1\">\n {(hasMoveUp || hasMoveDown) && (\n <>\n <ButtonIcon\n variant=\"tertiary\"\n size=\"small\"\n isDisabled={disabled || readonly || !hasMoveUp}\n onClick={onReorderClick(index, index - 1)}\n aria-label={`Move up ${itemTitle}`}\n icon={<RiArrowUpSLine size={18} />}\n />\n <ButtonIcon\n variant=\"tertiary\"\n size=\"small\"\n isDisabled={disabled || readonly || !hasMoveDown}\n onClick={onReorderClick(index, index + 1)}\n aria-label={`Move down ${itemTitle}`}\n icon={<RiArrowDownSLine size={18} />}\n />\n </>\n )}\n {hasCopy && (\n <ButtonIcon\n variant=\"tertiary\"\n size=\"small\"\n isDisabled={disabled || readonly}\n onClick={onCopyIndexClick(index)}\n aria-label={`Duplicate ${itemTitle}`}\n icon={<RiAddLine size={18} />}\n />\n )}\n {hasRemove && (\n <ButtonIcon\n variant=\"tertiary\"\n size=\"small\"\n isDisabled={disabled || readonly}\n onClick={onDropIndexClick(index)}\n aria-label={`Remove ${itemTitle}`}\n icon={<RiDeleteBinLine size={18} />}\n />\n )}\n </Flex>\n )}\n </Flex>\n </Box>\n </CardHeader>\n <DisclosurePanel>\n <CardBody>\n <Box p=\"4\">{children}</Box>\n </CardBody>\n </DisclosurePanel>\n </>\n )}\n </Disclosure>\n </Card>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { ariaDescribedByIds, enumOptionsIndexForValue, enumOptionsValueForIndex } from '@rjsf/utils';
|
|
3
3
|
import { Select } from '@backstage/ui';
|
|
4
4
|
import overrides from './selectOverrides.module.css.esm.js';
|
|
5
5
|
|
|
@@ -19,21 +19,22 @@ function SelectWidget({
|
|
|
19
19
|
rawErrors = []
|
|
20
20
|
}) {
|
|
21
21
|
const { enumOptions, emptyValue } = options;
|
|
22
|
-
const
|
|
23
|
-
const actualIndex = newValue === "" ? "" : newValue;
|
|
22
|
+
const handleSingleChange = (newValue) => {
|
|
24
23
|
onFieldChange(
|
|
25
|
-
enumOptionsValueForIndex(
|
|
24
|
+
enumOptionsValueForIndex(newValue ?? "", enumOptions, emptyValue)
|
|
26
25
|
);
|
|
27
26
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
27
|
+
const handleMultiChange = (selected) => {
|
|
28
|
+
onFieldChange(
|
|
29
|
+
enumOptionsValueForIndex(selected, enumOptions, emptyValue)
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
const handleBlur = () => {
|
|
33
|
+
onFieldBlur(id, value);
|
|
34
|
+
};
|
|
35
|
+
const handleFocus = () => {
|
|
36
|
+
onFieldFocus(id, value);
|
|
37
|
+
};
|
|
37
38
|
const hasError = rawErrors.length > 0;
|
|
38
39
|
const selectOptions = enumOptions?.map(({ label: optionLabel }, index) => ({
|
|
39
40
|
value: String(index),
|
|
@@ -45,26 +46,45 @@ function SelectWidget({
|
|
|
45
46
|
label: options.placeholder || "Select an option"
|
|
46
47
|
});
|
|
47
48
|
}
|
|
49
|
+
const commonProps = {
|
|
50
|
+
className: overrides.select,
|
|
51
|
+
id,
|
|
52
|
+
name: id,
|
|
53
|
+
label: label || schema.title,
|
|
54
|
+
secondaryLabel: required ? "Required" : void 0,
|
|
55
|
+
options: selectOptions,
|
|
56
|
+
isRequired: required,
|
|
57
|
+
isDisabled: disabled || readonly,
|
|
58
|
+
isInvalid: hasError,
|
|
59
|
+
onBlur: handleBlur,
|
|
60
|
+
onFocus: handleFocus,
|
|
61
|
+
"aria-describedby": ariaDescribedByIds(id)
|
|
62
|
+
};
|
|
63
|
+
if (multiple) {
|
|
64
|
+
const selectedIndices = enumOptionsIndexForValue(
|
|
65
|
+
value,
|
|
66
|
+
enumOptions,
|
|
67
|
+
true
|
|
68
|
+
);
|
|
69
|
+
const normalizedIndices = Array.isArray(selectedIndices) ? selectedIndices.map(String) : [];
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
Select,
|
|
72
|
+
{
|
|
73
|
+
...commonProps,
|
|
74
|
+
selectionMode: "multiple",
|
|
75
|
+
value: normalizedIndices,
|
|
76
|
+
onChange: handleMultiChange
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const selectedIndex = enumOptionsIndexForValue(value, enumOptions);
|
|
48
81
|
return /* @__PURE__ */ jsx(
|
|
49
82
|
Select,
|
|
50
83
|
{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
secondaryLabel: required ? "Required" : void 0,
|
|
56
|
-
options: selectOptions,
|
|
57
|
-
selectedKey: selectedIndex !== void 0 ? String(selectedIndex) : "",
|
|
58
|
-
onSelectionChange: (key) => {
|
|
59
|
-
const selected = key ? String(key) : "";
|
|
60
|
-
handleChange(selected);
|
|
61
|
-
},
|
|
62
|
-
isRequired: required,
|
|
63
|
-
isDisabled: disabled || readonly,
|
|
64
|
-
isInvalid: hasError,
|
|
65
|
-
onBlur: handleBlur,
|
|
66
|
-
onFocus: handleFocus,
|
|
67
|
-
"aria-describedby": ariaDescribedByIds(id)
|
|
84
|
+
...commonProps,
|
|
85
|
+
selectionMode: "single",
|
|
86
|
+
value: selectedIndex !== void 0 ? String(selectedIndex) : "",
|
|
87
|
+
onChange: handleSingleChange
|
|
68
88
|
}
|
|
69
89
|
);
|
|
70
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectWidget.esm.js","sources":["../../../../../../src/next/components/Form/BuiTheme/widgets/SelectWidget.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ariaDescribedByIds,\n enumOptionsIndexForValue,\n enumOptionsValueForIndex,\n FormContextType,\n RJSFSchema,\n StrictRJSFSchema,\n WidgetProps,\n} from '@rjsf/utils';\nimport { Select } from '@backstage/ui';\nimport overrides from './selectOverrides.module.css';\n\nexport default function SelectWidget<\n T = any,\n S extends StrictRJSFSchema = RJSFSchema,\n F extends FormContextType = any,\n>({\n id,\n options,\n required,\n disabled,\n readonly,\n value,\n multiple,\n label,\n schema,\n onChange: onFieldChange,\n onBlur: onFieldBlur,\n onFocus: onFieldFocus,\n rawErrors = [],\n}: WidgetProps<T, S, F>) {\n const { enumOptions, emptyValue } = options;\n\n const
|
|
1
|
+
{"version":3,"file":"SelectWidget.esm.js","sources":["../../../../../../src/next/components/Form/BuiTheme/widgets/SelectWidget.tsx"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ariaDescribedByIds,\n enumOptionsIndexForValue,\n enumOptionsValueForIndex,\n FormContextType,\n RJSFSchema,\n StrictRJSFSchema,\n WidgetProps,\n} from '@rjsf/utils';\nimport { Select } from '@backstage/ui';\nimport type { Key } from 'react-aria-components';\nimport overrides from './selectOverrides.module.css';\n\nexport default function SelectWidget<\n T = any,\n S extends StrictRJSFSchema = RJSFSchema,\n F extends FormContextType = any,\n>({\n id,\n options,\n required,\n disabled,\n readonly,\n value,\n multiple,\n label,\n schema,\n onChange: onFieldChange,\n onBlur: onFieldBlur,\n onFocus: onFieldFocus,\n rawErrors = [],\n}: WidgetProps<T, S, F>) {\n const { enumOptions, emptyValue } = options;\n\n const handleSingleChange = (newValue: Key | null) => {\n onFieldChange(\n enumOptionsValueForIndex<S>(newValue ?? '', enumOptions, emptyValue),\n );\n };\n\n const handleMultiChange = (selected: Key[]) => {\n onFieldChange(\n enumOptionsValueForIndex<S>(selected, enumOptions, emptyValue),\n );\n };\n\n const handleBlur = () => {\n onFieldBlur(id, value);\n };\n\n const handleFocus = () => {\n onFieldFocus(id, value);\n };\n\n const hasError = rawErrors.length > 0;\n\n const selectOptions =\n enumOptions?.map(({ label: optionLabel }, index) => ({\n value: String(index),\n label: optionLabel,\n })) || [];\n\n if (!multiple && schema.default === undefined) {\n selectOptions.unshift({\n value: '',\n label: (options.placeholder as string) || 'Select an option',\n });\n }\n\n const commonProps = {\n className: overrides.select,\n id,\n name: id,\n label: label || schema.title,\n secondaryLabel: required ? 'Required' : undefined,\n options: selectOptions,\n isRequired: required,\n isDisabled: disabled || readonly,\n isInvalid: hasError,\n onBlur: handleBlur,\n onFocus: handleFocus,\n 'aria-describedby': ariaDescribedByIds<T>(id),\n };\n\n if (multiple) {\n const selectedIndices = enumOptionsIndexForValue<S>(\n value,\n enumOptions,\n true,\n );\n const normalizedIndices = Array.isArray(selectedIndices)\n ? selectedIndices.map(String)\n : [];\n\n return (\n <Select\n {...commonProps}\n selectionMode=\"multiple\"\n value={normalizedIndices}\n onChange={handleMultiChange}\n />\n );\n }\n\n const selectedIndex = enumOptionsIndexForValue<S>(value, enumOptions);\n\n return (\n <Select\n {...commonProps}\n selectionMode=\"single\"\n value={selectedIndex !== undefined ? String(selectedIndex) : ''}\n onChange={handleSingleChange}\n />\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -40,10 +40,11 @@ function processSchema(key, value, schema, formState) {
|
|
|
40
40
|
return [[name, value]];
|
|
41
41
|
}
|
|
42
42
|
const ReviewState = (props) => {
|
|
43
|
+
const schemaFormState = props.schemaFormState ?? props.formState;
|
|
43
44
|
const reviewData = Object.fromEntries(
|
|
44
45
|
Object.entries(props.formState).flatMap(([key, value]) => {
|
|
45
|
-
const schema = findSchemaForKey(key, props.schemas,
|
|
46
|
-
return schema ? processSchema(key, value, schema,
|
|
46
|
+
const schema = findSchemaForKey(key, props.schemas, schemaFormState);
|
|
47
|
+
return schema ? processSchema(key, value, schema, schemaFormState) : [[formatKey(key), value]];
|
|
47
48
|
}).filter((prop) => prop.length > 0)
|
|
48
49
|
);
|
|
49
50
|
return /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewState.esm.js","sources":["../../../../src/next/components/ReviewState/ReviewState.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { StructuredMetadataTable } from '@backstage/core-components';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { Draft07 as JSONSchema } from 'json-schema-library';\nimport { ParsedTemplateSchema } from '../../hooks/useTemplateSchema';\nimport { isJsonObject, formatKey, findSchemaForKey } from './util';\n\n/**\n * The props for the {@link ReviewState} component.\n * @alpha\n */\nexport type ReviewStateProps = {\n schemas: ParsedTemplateSchema[];\n formState: JsonObject;\n};\n\nfunction processSchema(\n key: string,\n value: JsonValue | undefined,\n schema: ParsedTemplateSchema,\n formState: JsonObject,\n): [string, JsonValue | undefined][] {\n const parsedSchema = new JSONSchema(schema.mergedSchema);\n const definitionInSchema = parsedSchema.getSchema({\n pointer: `#/${key}`,\n data: formState,\n });\n\n const name =\n definitionInSchema?.['ui:backstage']?.review?.name ??\n definitionInSchema?.title ??\n formatKey(key);\n\n if (definitionInSchema) {\n const backstageReviewOptions = definitionInSchema['ui:backstage']?.review;\n if (backstageReviewOptions) {\n if (backstageReviewOptions.mask) {\n return [[name, backstageReviewOptions.mask]];\n }\n if (backstageReviewOptions.show === false) {\n return [];\n }\n }\n\n if (\n definitionInSchema['ui:widget'] === 'password' ||\n definitionInSchema['ui:field']?.toLowerCase() === 'secret'\n ) {\n return [[name, '******']];\n }\n\n if (definitionInSchema.enum && definitionInSchema.enumNames) {\n return [\n [\n name,\n definitionInSchema.enumNames[\n definitionInSchema.enum.indexOf(value)\n ] || value,\n ],\n ];\n }\n\n if (backstageReviewOptions?.explode !== false && isJsonObject(value)) {\n // Recurse nested objects\n return Object.entries(value).flatMap(([nestedKey, nestedValue]) =>\n processSchema(`${key}/${nestedKey}`, nestedValue, schema, formState),\n );\n }\n }\n\n return [[name, value]];\n}\n\n/**\n * The component used by the {@link Stepper} to render the review step.\n * @alpha\n */\nexport const ReviewState = (props: ReviewStateProps) => {\n const reviewData = Object.fromEntries(\n Object.entries(props.formState)\n .flatMap(([key, value]) => {\n const schema = findSchemaForKey(key, props.schemas,
|
|
1
|
+
{"version":3,"file":"ReviewState.esm.js","sources":["../../../../src/next/components/ReviewState/ReviewState.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { StructuredMetadataTable } from '@backstage/core-components';\nimport { JsonObject, JsonValue } from '@backstage/types';\nimport { Draft07 as JSONSchema } from 'json-schema-library';\nimport { ParsedTemplateSchema } from '../../hooks/useTemplateSchema';\nimport { isJsonObject, formatKey, findSchemaForKey } from './util';\n\n/**\n * The props for the {@link ReviewState} component.\n * @alpha\n */\nexport type ReviewStateProps = {\n schemas: ParsedTemplateSchema[];\n formState: JsonObject;\n /**\n * The complete form state, used to resolve conditional schemas such as\n * `dependencies` so that review masks still apply when `formState` has had\n * values removed. Defaults to `formState`.\n */\n schemaFormState?: JsonObject;\n};\n\nfunction processSchema(\n key: string,\n value: JsonValue | undefined,\n schema: ParsedTemplateSchema,\n formState: JsonObject,\n): [string, JsonValue | undefined][] {\n const parsedSchema = new JSONSchema(schema.mergedSchema);\n const definitionInSchema = parsedSchema.getSchema({\n pointer: `#/${key}`,\n data: formState,\n });\n\n const name =\n definitionInSchema?.['ui:backstage']?.review?.name ??\n definitionInSchema?.title ??\n formatKey(key);\n\n if (definitionInSchema) {\n const backstageReviewOptions = definitionInSchema['ui:backstage']?.review;\n if (backstageReviewOptions) {\n if (backstageReviewOptions.mask) {\n return [[name, backstageReviewOptions.mask]];\n }\n if (backstageReviewOptions.show === false) {\n return [];\n }\n }\n\n if (\n definitionInSchema['ui:widget'] === 'password' ||\n definitionInSchema['ui:field']?.toLowerCase() === 'secret'\n ) {\n return [[name, '******']];\n }\n\n if (definitionInSchema.enum && definitionInSchema.enumNames) {\n return [\n [\n name,\n definitionInSchema.enumNames[\n definitionInSchema.enum.indexOf(value)\n ] || value,\n ],\n ];\n }\n\n if (backstageReviewOptions?.explode !== false && isJsonObject(value)) {\n // Recurse nested objects\n return Object.entries(value).flatMap(([nestedKey, nestedValue]) =>\n processSchema(`${key}/${nestedKey}`, nestedValue, schema, formState),\n );\n }\n }\n\n return [[name, value]];\n}\n\n/**\n * The component used by the {@link Stepper} to render the review step.\n * @alpha\n */\nexport const ReviewState = (props: ReviewStateProps) => {\n const schemaFormState = props.schemaFormState ?? props.formState;\n const reviewData = Object.fromEntries(\n Object.entries(props.formState)\n .flatMap(([key, value]) => {\n const schema = findSchemaForKey(key, props.schemas, schemaFormState);\n return schema\n ? processSchema(key, value, schema, schemaFormState)\n : [[formatKey(key), value]];\n })\n .filter(prop => prop.length > 0),\n );\n return (\n <StructuredMetadataTable\n metadata={reviewData}\n options={{ titleFormat: key => key }}\n />\n );\n};\n"],"names":["JSONSchema"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useAnalytics, useApiHolder } from '@backstage/core-plugin-api';
|
|
3
3
|
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { resolveParameterSteps } from '@backstage/plugin-scaffolder-common/alpha';
|
|
4
5
|
import { Button } from '@backstage/ui';
|
|
5
6
|
import LinearProgress from '@material-ui/core/LinearProgress';
|
|
6
7
|
import MuiStep from '@material-ui/core/Step';
|
|
@@ -10,7 +11,7 @@ import { makeStyles } from '@material-ui/core/styles';
|
|
|
10
11
|
import { customizeValidator } from '@rjsf/validator-ajv8';
|
|
11
12
|
import ajvErrors from 'ajv-errors';
|
|
12
13
|
import { merge } from 'lodash';
|
|
13
|
-
import { useState,
|
|
14
|
+
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
14
15
|
import { scaffolderReactTranslationRef } from '../../../translation.esm.js';
|
|
15
16
|
import { useFormDataFromQuery } from '../../hooks/useFormDataFromQuery.esm.js';
|
|
16
17
|
import { useTemplateSchema } from '../../hooks/useTemplateSchema.esm.js';
|
|
@@ -59,10 +60,30 @@ const Stepper = (stepperProps) => {
|
|
|
59
60
|
const analytics = useAnalytics();
|
|
60
61
|
const { presentation, steps } = useTemplateSchema(props.manifest);
|
|
61
62
|
const apiHolder = useApiHolder();
|
|
62
|
-
const [
|
|
63
|
+
const [activeStepIndex, setActiveStepIndex] = useState(0);
|
|
63
64
|
const [isValidating, setIsValidating] = useState(false);
|
|
64
65
|
const [initialState] = useFormDataFromQuery(props.initialState);
|
|
65
66
|
const [stepsState, setStepsState] = useState(initialState);
|
|
67
|
+
const { visibleSteps, filteredFormState } = useMemo(() => {
|
|
68
|
+
const resolved = resolveParameterSteps(
|
|
69
|
+
stepsState,
|
|
70
|
+
steps.map((step) => ({ schema: step.mergedSchema, when: step.when }))
|
|
71
|
+
);
|
|
72
|
+
return {
|
|
73
|
+
visibleSteps: steps.filter((_, index) => resolved.visible[index]),
|
|
74
|
+
filteredFormState: resolved.values
|
|
75
|
+
};
|
|
76
|
+
}, [steps, stepsState]);
|
|
77
|
+
const nextVisibleStep = visibleSteps.findIndex(
|
|
78
|
+
(step) => steps.indexOf(step) >= activeStepIndex
|
|
79
|
+
);
|
|
80
|
+
const activeStep = nextVisibleStep === -1 ? visibleSteps.length : nextVisibleStep;
|
|
81
|
+
const setActiveStep = useCallback(
|
|
82
|
+
(step) => setActiveStepIndex(
|
|
83
|
+
step < visibleSteps.length ? steps.indexOf(visibleSteps[step]) : steps.length
|
|
84
|
+
),
|
|
85
|
+
[steps, visibleSteps]
|
|
86
|
+
);
|
|
66
87
|
const [errors, setErrors] = useState();
|
|
67
88
|
const styles = useStyles();
|
|
68
89
|
const formWrapperRef = useRef(null);
|
|
@@ -84,14 +105,18 @@ const Stepper = (stepperProps) => {
|
|
|
84
105
|
);
|
|
85
106
|
}, [props.extensions]);
|
|
86
107
|
const validation = useMemo(() => {
|
|
87
|
-
return createAsyncValidators(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
return createAsyncValidators(
|
|
109
|
+
visibleSteps[activeStep]?.mergedSchema,
|
|
110
|
+
validators,
|
|
111
|
+
{ apiHolder }
|
|
112
|
+
);
|
|
113
|
+
}, [visibleSteps, activeStep, validators, apiHolder]);
|
|
91
114
|
const handleBack = useCallback(() => {
|
|
92
|
-
setActiveStep(
|
|
93
|
-
}, [setActiveStep]);
|
|
94
|
-
const currentStep = useTransformSchemaToProps(
|
|
115
|
+
setActiveStep(activeStep - 1);
|
|
116
|
+
}, [activeStep, setActiveStep]);
|
|
117
|
+
const currentStep = useTransformSchemaToProps(visibleSteps[activeStep], {
|
|
118
|
+
layouts
|
|
119
|
+
});
|
|
95
120
|
const {
|
|
96
121
|
formContext: propFormContext,
|
|
97
122
|
uiSchema: propUiSchema,
|
|
@@ -121,14 +146,20 @@ const Stepper = (stepperProps) => {
|
|
|
121
146
|
setErrors(returnedValidation);
|
|
122
147
|
} else {
|
|
123
148
|
setErrors(void 0);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
149
|
+
const stepNum = activeStep + 1;
|
|
150
|
+
analytics.captureEvent("click", `Next Step (${stepNum})`);
|
|
151
|
+
const current = steps.indexOf(visibleSteps[activeStep]);
|
|
152
|
+
const { visible } = resolveParameterSteps(
|
|
153
|
+
{ ...stepsState, ...formData },
|
|
154
|
+
steps.map((step) => ({ schema: step.mergedSchema, when: step.when }))
|
|
155
|
+
);
|
|
156
|
+
const next = visible.findIndex(
|
|
157
|
+
(isVisible, index) => isVisible && index > current
|
|
158
|
+
);
|
|
159
|
+
setActiveStepIndex(next === -1 ? steps.length : next);
|
|
129
160
|
}
|
|
130
161
|
},
|
|
131
|
-
[validation, analytics]
|
|
162
|
+
[validation, analytics, activeStep, steps, visibleSteps, stepsState]
|
|
132
163
|
);
|
|
133
164
|
useEffect(() => {
|
|
134
165
|
const getScrollableParent = (element) => {
|
|
@@ -153,11 +184,11 @@ const Stepper = (stepperProps) => {
|
|
|
153
184
|
setIsCreating(true);
|
|
154
185
|
analytics.captureEvent("click", `${createLabel}`);
|
|
155
186
|
try {
|
|
156
|
-
await onCreate(
|
|
187
|
+
await onCreate(filteredFormState);
|
|
157
188
|
} finally {
|
|
158
189
|
setIsCreating(false);
|
|
159
190
|
}
|
|
160
|
-
}, [analytics, createLabel,
|
|
191
|
+
}, [analytics, createLabel, filteredFormState, onCreate]);
|
|
161
192
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
162
193
|
isValidating && /* @__PURE__ */ jsx(LinearProgress, { variant: "indeterminate" }),
|
|
163
194
|
/* @__PURE__ */ jsxs(
|
|
@@ -168,7 +199,7 @@ const Stepper = (stepperProps) => {
|
|
|
168
199
|
variant: "elevation",
|
|
169
200
|
style: { overflowX: "auto" },
|
|
170
201
|
children: [
|
|
171
|
-
|
|
202
|
+
visibleSteps.map((step, index) => {
|
|
172
203
|
const isAllowedLabelClick = activeStep > index;
|
|
173
204
|
return /* @__PURE__ */ jsx(MuiStep, { children: /* @__PURE__ */ jsx(
|
|
174
205
|
MuiStepLabel,
|
|
@@ -180,13 +211,13 @@ const Stepper = (stepperProps) => {
|
|
|
180
211
|
},
|
|
181
212
|
children: step.title
|
|
182
213
|
}
|
|
183
|
-
) },
|
|
214
|
+
) }, steps.indexOf(step));
|
|
184
215
|
}),
|
|
185
216
|
/* @__PURE__ */ jsx(MuiStep, { children: /* @__PURE__ */ jsx(MuiStepLabel, { children: reviewLabel }) })
|
|
186
217
|
]
|
|
187
218
|
}
|
|
188
219
|
),
|
|
189
|
-
/* @__PURE__ */ jsx("div", { className: styles.formWrapper, ref: formWrapperRef, children: activeStep <
|
|
220
|
+
/* @__PURE__ */ jsx("div", { className: styles.formWrapper, ref: formWrapperRef, children: activeStep < visibleSteps.length ? /* @__PURE__ */ jsx(
|
|
190
221
|
Form,
|
|
191
222
|
{
|
|
192
223
|
validator,
|
|
@@ -216,25 +247,32 @@ const Stepper = (stepperProps) => {
|
|
|
216
247
|
children: backLabel
|
|
217
248
|
}
|
|
218
249
|
),
|
|
219
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", type: "submit", isDisabled: isValidating, children: activeStep ===
|
|
250
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", type: "submit", isDisabled: isValidating, children: activeStep === visibleSteps.length - 1 ? reviewLabel : t("stepper.nextButtonText") })
|
|
220
251
|
] })
|
|
221
252
|
},
|
|
222
|
-
activeStep
|
|
253
|
+
steps.indexOf(visibleSteps[activeStep])
|
|
223
254
|
) : (
|
|
224
255
|
// TODO: potentially move away from this pattern, deprecate?
|
|
225
256
|
ReviewStepComponent ? /* @__PURE__ */ jsx(
|
|
226
257
|
ReviewStepComponent,
|
|
227
258
|
{
|
|
228
259
|
disableButtons: isValidating,
|
|
229
|
-
formData:
|
|
260
|
+
formData: filteredFormState,
|
|
230
261
|
handleBack,
|
|
231
262
|
handleReset: () => {
|
|
232
263
|
},
|
|
233
|
-
steps,
|
|
264
|
+
steps: visibleSteps,
|
|
234
265
|
handleCreate
|
|
235
266
|
}
|
|
236
267
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
237
|
-
/* @__PURE__ */ jsx(
|
|
268
|
+
/* @__PURE__ */ jsx(
|
|
269
|
+
ReviewStateComponent,
|
|
270
|
+
{
|
|
271
|
+
formState: filteredFormState,
|
|
272
|
+
schemaFormState: stepsState,
|
|
273
|
+
schemas: visibleSteps
|
|
274
|
+
}
|
|
275
|
+
),
|
|
238
276
|
/* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
|
|
239
277
|
/* @__PURE__ */ jsx(
|
|
240
278
|
Button,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper.esm.js","sources":["../../../../src/next/components/Stepper/Stepper.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useAnalytics, useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n FieldExtensionOptions,\n FormProps,\n LayoutOptions,\n ReviewStepProps,\n TemplateParameterSchema,\n} from '@backstage/plugin-scaffolder-react';\nimport { JsonValue } from '@backstage/types';\nimport { Button } from '@backstage/ui';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport MuiStep from '@material-ui/core/Step';\nimport MuiStepLabel from '@material-ui/core/StepLabel';\nimport MuiStepper from '@material-ui/core/Stepper';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { type IChangeEvent } from '@rjsf/core';\nimport { ErrorSchema } from '@rjsf/utils';\nimport { customizeValidator } from '@rjsf/validator-ajv8';\nimport ajvErrors from 'ajv-errors';\nimport { merge } from 'lodash';\nimport {\n ComponentType,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport { scaffolderReactTranslationRef } from '../../../translation';\nimport { useFormDataFromQuery, useTemplateSchema } from '../../hooks';\nimport { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps';\nimport { Form } from '../Form';\nimport { PasswordWidget } from '../PasswordWidget/PasswordWidget';\nimport { ReviewState, type ReviewStateProps } from '../ReviewState';\nimport {\n createAsyncValidators,\n type FormValidation,\n} from './createAsyncValidators';\nimport { ErrorListTemplate } from './ErrorListTemplate';\nimport * as FieldOverrides from './FieldOverrides';\nimport { hasErrors } from './utils';\n\nconst validator = customizeValidator();\najvErrors(validator.ajv);\n\n/** @alpha */\nexport type BackstageTemplateStepperClassKey =\n | 'backButton'\n | 'footer'\n | 'formWrapper';\n\nconst useStyles = makeStyles(\n theme => ({\n backButton: {\n marginRight: theme.spacing(1),\n },\n footer: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'right',\n marginTop: theme.spacing(2),\n },\n formWrapper: {\n padding: theme.spacing(2),\n },\n }),\n { name: 'BackstageTemplateStepper' },\n);\n\n/**\n * The Props for {@link Stepper} component\n * @alpha\n */\nexport type StepperProps = {\n manifest: TemplateParameterSchema;\n extensions: FieldExtensionOptions<any, any>[];\n /**\n * @deprecated This was only ever used for analytics tracking purposes, which\n * is now handled in the `<Workflow />` component. Passing it in will have no\n * effect.\n */\n templateName?: string;\n formProps?: FormProps;\n initialState?: Record<string, JsonValue>;\n onCreate: (values: Record<string, JsonValue>) => Promise<void>;\n components?: {\n ReviewStepComponent?: ComponentType<ReviewStepProps>;\n ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element;\n backButtonText?: ReactNode;\n createButtonText?: ReactNode;\n reviewButtonText?: ReactNode;\n };\n layouts?: LayoutOptions[];\n};\n\n/**\n * The `Stepper` component is the Wizard that is rendered when a user selects a template\n * @alpha\n */\nexport const Stepper = (stepperProps: StepperProps) => {\n const { t } = useTranslationRef(scaffolderReactTranslationRef);\n const { layouts = [], components = {}, onCreate, ...props } = stepperProps;\n const {\n ReviewStateComponent = ReviewState,\n ReviewStepComponent,\n backButtonText = t('stepper.backButtonText'),\n createButtonText = t('stepper.createButtonText'),\n reviewButtonText = t('stepper.reviewButtonText'),\n } = components;\n const analytics = useAnalytics();\n const { presentation, steps } = useTemplateSchema(props.manifest);\n const apiHolder = useApiHolder();\n const [activeStep, setActiveStep] = useState(0);\n const [isValidating, setIsValidating] = useState(false);\n const [initialState] = useFormDataFromQuery(props.initialState);\n const [stepsState, setStepsState] =\n useState<Record<string, JsonValue>>(initialState);\n\n const [errors, setErrors] = useState<undefined | FormValidation>();\n const styles = useStyles();\n const formWrapperRef = useRef<HTMLDivElement>(null);\n\n const backLabel =\n presentation?.buttonLabels?.backButtonText ?? backButtonText;\n const createLabel =\n presentation?.buttonLabels?.createButtonText ?? createButtonText;\n const reviewLabel =\n presentation?.buttonLabels?.reviewButtonText ?? reviewButtonText;\n\n const extensions = useMemo(() => {\n return Object.fromEntries(\n props.extensions.map(({ name, component }) => [name, component]),\n );\n }, [props.extensions]);\n\n const fields = useMemo(\n () => ({ ...FieldOverrides, ...extensions }),\n [extensions],\n );\n\n const validators = useMemo(() => {\n return Object.fromEntries(\n props.extensions.map(({ name, validation }) => [name, validation]),\n );\n }, [props.extensions]);\n\n const validation = useMemo(() => {\n return createAsyncValidators(steps[activeStep]?.mergedSchema, validators, {\n apiHolder,\n });\n }, [steps, activeStep, validators, apiHolder]);\n\n const handleBack = useCallback(() => {\n setActiveStep(prevActiveStep => prevActiveStep - 1);\n }, [setActiveStep]);\n\n const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts });\n\n const {\n formContext: propFormContext,\n uiSchema: propUiSchema,\n liveOmit: _shouldLiveOmit,\n omitExtraData: _shouldOmitExtraData,\n ...restFormProps\n } = props.formProps ?? {};\n\n const handleChange = useCallback(\n (e: IChangeEvent) => {\n setStepsState(current => {\n return { ...current, ...e.formData };\n });\n },\n [setStepsState],\n );\n\n const handleNext = useCallback(\n async ({ formData = {} }: { formData?: Record<string, JsonValue> }) => {\n // The validation should never throw, as the validators are wrapped in a try/catch.\n // This makes it fine to set and unset state without try/catch.\n setErrors(undefined);\n setIsValidating(true);\n\n const returnedValidation = await validation(formData);\n\n setStepsState(current => ({\n ...current,\n ...formData,\n }));\n\n setIsValidating(false);\n\n if (hasErrors(returnedValidation)) {\n setErrors(returnedValidation);\n } else {\n setErrors(undefined);\n setActiveStep(prevActiveStep => {\n const stepNum = prevActiveStep + 1;\n analytics.captureEvent('click', `Next Step (${stepNum})`);\n return stepNum;\n });\n }\n },\n [validation, analytics],\n );\n\n useEffect(() => {\n const getScrollableParent = (\n element: HTMLElement | null,\n ): HTMLElement | null => {\n if (!element) return null;\n const { overflowY } = window.getComputedStyle(element);\n const isScrollable = overflowY === 'auto' || overflowY === 'scroll';\n if (isScrollable && element.scrollHeight > element.clientHeight) {\n return element;\n }\n return getScrollableParent(element.parentElement);\n };\n\n const scrollTarget = getScrollableParent(formWrapperRef.current);\n\n if (scrollTarget && typeof scrollTarget.scrollTo === 'function') {\n scrollTarget.scrollTo({ top: 0, behavior: 'auto' });\n } else {\n window.scrollTo({ top: 0, behavior: 'auto' });\n }\n }, [activeStep]);\n\n const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema);\n\n const [isCreating, setIsCreating] = useState(false);\n\n const handleCreate = useCallback(async () => {\n setIsCreating(true);\n analytics.captureEvent('click', `${createLabel}`);\n try {\n await onCreate(stepsState);\n } finally {\n setIsCreating(false);\n }\n }, [analytics, createLabel, onCreate, stepsState]);\n\n return (\n <>\n {isValidating && <LinearProgress variant=\"indeterminate\" />}\n <MuiStepper\n activeStep={activeStep}\n alternativeLabel\n variant=\"elevation\"\n style={{ overflowX: 'auto' }}\n >\n {steps.map((step, index) => {\n const isAllowedLabelClick = activeStep > index;\n return (\n <MuiStep key={index}>\n <MuiStepLabel\n aria-label={t('stepper.stepIndexLabel', { index: index + 1 })}\n style={{ cursor: isAllowedLabelClick ? 'pointer' : 'default' }}\n onClick={() => {\n if (isAllowedLabelClick) setActiveStep(index);\n }}\n >\n {step.title}\n </MuiStepLabel>\n </MuiStep>\n );\n })}\n <MuiStep>\n <MuiStepLabel>{reviewLabel}</MuiStepLabel>\n </MuiStep>\n </MuiStepper>\n <div className={styles.formWrapper} ref={formWrapperRef}>\n {/* eslint-disable-next-line no-nested-ternary */}\n {activeStep < steps.length ? (\n <Form\n key={activeStep}\n validator={validator}\n extraErrors={errors as unknown as ErrorSchema}\n formData={stepsState}\n formContext={{ ...propFormContext, formData: stepsState }}\n schema={currentStep.schema}\n uiSchema={mergedUiSchema}\n onSubmit={handleNext}\n fields={fields}\n showErrorList=\"top\"\n templates={{ ErrorListTemplate }}\n onChange={handleChange}\n widgets={{ password: PasswordWidget }}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n {...restFormProps}\n >\n <div className={styles.footer}>\n <Button\n variant=\"tertiary\"\n onPress={handleBack}\n className={styles.backButton}\n isDisabled={activeStep < 1 || isValidating}\n >\n {backLabel}\n </Button>\n <Button variant=\"primary\" type=\"submit\" isDisabled={isValidating}>\n {activeStep === steps.length - 1\n ? reviewLabel\n : t('stepper.nextButtonText')}\n </Button>\n </div>\n </Form>\n ) : // TODO: potentially move away from this pattern, deprecate?\n ReviewStepComponent ? (\n <ReviewStepComponent\n disableButtons={isValidating}\n formData={stepsState}\n handleBack={handleBack}\n handleReset={() => {}}\n steps={steps}\n handleCreate={handleCreate}\n />\n ) : (\n <>\n <ReviewStateComponent formState={stepsState} schemas={steps} />\n <div className={styles.footer}>\n <Button\n variant=\"tertiary\"\n onPress={handleBack}\n className={styles.backButton}\n isDisabled={activeStep < 1}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"primary\"\n isDisabled={isCreating}\n onPress={handleCreate}\n >\n {createLabel}\n </Button>\n </div>\n </>\n )}\n </div>\n </>\n );\n};\n"],"names":["FieldOverrides","validation"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAM,YAAY,kBAAA,EAAmB;AACrC,SAAA,CAAU,UAAU,GAAG,CAAA;AAQvB,MAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAA,KAAA,MAAU;AAAA,IACR,UAAA,EAAY;AAAA,MACV,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,KAC9B;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,KAAA;AAAA,MACf,cAAA,EAAgB,OAAA;AAAA,MAChB,SAAA,EAAW,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,KAC5B;AAAA,IACA,WAAA,EAAa;AAAA,MACX,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA;AAC1B,GACF,CAAA;AAAA,EACA,EAAE,MAAM,0BAAA;AACV,CAAA;AAgCO,MAAM,OAAA,GAAU,CAAC,YAAA,KAA+B;AACrD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,6BAA6B,CAAA;AAC7D,EAAA,MAAM,EAAE,OAAA,GAAU,EAAC,EAAG,UAAA,GAAa,EAAC,EAAG,QAAA,EAAU,GAAG,KAAA,EAAM,GAAI,YAAA;AAC9D,EAAA,MAAM;AAAA,IACJ,oBAAA,GAAuB,WAAA;AAAA,IACvB,mBAAA;AAAA,IACA,cAAA,GAAiB,EAAE,wBAAwB,CAAA;AAAA,IAC3C,gBAAA,GAAmB,EAAE,0BAA0B,CAAA;AAAA,IAC/C,gBAAA,GAAmB,EAAE,0BAA0B;AAAA,GACjD,GAAI,UAAA;AACJ,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,EAAE,YAAA,EAAc,KAAA,EAAM,GAAI,iBAAA,CAAkB,MAAM,QAAQ,CAAA;AAChE,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,CAAC,CAAA;AAC9C,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,CAAC,YAAY,CAAA,GAAI,oBAAA,CAAqB,MAAM,YAAY,CAAA;AAC9D,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAC9B,SAAoC,YAAY,CAAA;AAElD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,EAAqC;AACjE,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,cAAA,GAAiB,OAAuB,IAAI,CAAA;AAElD,EAAA,MAAM,SAAA,GACJ,YAAA,EAAc,YAAA,EAAc,cAAA,IAAkB,cAAA;AAChD,EAAA,MAAM,WAAA,GACJ,YAAA,EAAc,YAAA,EAAc,gBAAA,IAAoB,gBAAA;AAClD,EAAA,MAAM,WAAA,GACJ,YAAA,EAAc,YAAA,EAAc,gBAAA,IAAoB,gBAAA;AAElD,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MACZ,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,SAAA,EAAU,KAAM,CAAC,IAAA,EAAM,SAAS,CAAC;AAAA,KACjE;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,CAAM,UAAU,CAAC,CAAA;AAErB,EAAA,MAAM,MAAA,GAAS,OAAA;AAAA,IACb,OAAO,EAAE,GAAGA,KAAA,EAAgB,GAAG,UAAA,EAAW,CAAA;AAAA,IAC1C,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,MACZ,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,UAAA,EAAAC,WAAAA,EAAW,KAAM,CAAC,IAAA,EAAMA,WAAU,CAAC;AAAA,KACnE;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,CAAM,UAAU,CAAC,CAAA;AAErB,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,OAAO,qBAAA,CAAsB,KAAA,CAAM,UAAU,CAAA,EAAG,cAAc,UAAA,EAAY;AAAA,MACxE;AAAA,KACD,CAAA;AAAA,EACH,GAAG,CAAC,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,SAAS,CAAC,CAAA;AAE7C,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,aAAA,CAAc,CAAA,cAAA,KAAkB,iBAAiB,CAAC,CAAA;AAAA,EACpD,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,MAAM,cAAc,yBAAA,CAA0B,KAAA,CAAM,UAAU,CAAA,EAAG,EAAE,SAAS,CAAA;AAE5E,EAAA,MAAM;AAAA,IACJ,WAAA,EAAa,eAAA;AAAA,IACb,QAAA,EAAU,YAAA;AAAA,IACV,QAAA,EAAU,eAAA;AAAA,IACV,aAAA,EAAe,oBAAA;AAAA,IACf,GAAG;AAAA,GACL,GAAI,KAAA,CAAM,SAAA,IAAa,EAAC;AAExB,EAAA,MAAM,YAAA,GAAe,WAAA;AAAA,IACnB,CAAC,CAAA,KAAoB;AACnB,MAAA,aAAA,CAAc,CAAA,OAAA,KAAW;AACvB,QAAA,OAAO,EAAE,GAAG,OAAA,EAAS,GAAG,EAAE,QAAA,EAAS;AAAA,MACrC,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAChB;AAEA,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,OAAO,EAAE,QAAA,GAAW,IAAG,KAAgD;AAGrE,MAAA,SAAA,CAAU,MAAS,CAAA;AACnB,MAAA,eAAA,CAAgB,IAAI,CAAA;AAEpB,MAAA,MAAM,kBAAA,GAAqB,MAAM,UAAA,CAAW,QAAQ,CAAA;AAEpD,MAAA,aAAA,CAAc,CAAA,OAAA,MAAY;AAAA,QACxB,GAAG,OAAA;AAAA,QACH,GAAG;AAAA,OACL,CAAE,CAAA;AAEF,MAAA,eAAA,CAAgB,KAAK,CAAA;AAErB,MAAA,IAAI,SAAA,CAAU,kBAAkB,CAAA,EAAG;AACjC,QAAA,SAAA,CAAU,kBAAkB,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,MAAS,CAAA;AACnB,QAAA,aAAA,CAAc,CAAA,cAAA,KAAkB;AAC9B,UAAA,MAAM,UAAU,cAAA,GAAiB,CAAA;AACjC,UAAA,SAAA,CAAU,YAAA,CAAa,OAAA,EAAS,CAAA,WAAA,EAAc,OAAO,CAAA,CAAA,CAAG,CAAA;AACxD,UAAA,OAAO,OAAA;AAAA,QACT,CAAC,CAAA;AAAA,MACH;AAAA,IACF,CAAA;AAAA,IACA,CAAC,YAAY,SAAS;AAAA,GACxB;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,mBAAA,GAAsB,CAC1B,OAAA,KACuB;AACvB,MAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,MAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAA,CAAO,iBAAiB,OAAO,CAAA;AACrD,MAAA,MAAM,YAAA,GAAe,SAAA,KAAc,MAAA,IAAU,SAAA,KAAc,QAAA;AAC3D,MAAA,IAAI,YAAA,IAAgB,OAAA,CAAQ,YAAA,GAAe,OAAA,CAAQ,YAAA,EAAc;AAC/D,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,OAAO,mBAAA,CAAoB,QAAQ,aAAa,CAAA;AAAA,IAClD,CAAA;AAEA,IAAA,MAAM,YAAA,GAAe,mBAAA,CAAoB,cAAA,CAAe,OAAO,CAAA;AAE/D,IAAA,IAAI,YAAA,IAAgB,OAAO,YAAA,CAAa,QAAA,KAAa,UAAA,EAAY;AAC/D,MAAA,YAAA,CAAa,SAAS,EAAE,GAAA,EAAK,CAAA,EAAG,QAAA,EAAU,QAAQ,CAAA;AAAA,IACpD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,SAAS,EAAE,GAAA,EAAK,CAAA,EAAG,QAAA,EAAU,QAAQ,CAAA;AAAA,IAC9C;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,iBAAiB,KAAA,CAAM,EAAC,EAAG,YAAA,EAAc,aAAa,QAAQ,CAAA;AAEpE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAElD,EAAA,MAAM,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,SAAA,CAAU,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG,WAAW,CAAA,CAAE,CAAA;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,UAAU,CAAA;AAAA,IAC3B,CAAA,SAAE;AACA,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,SAAA,EAAW,WAAA,EAAa,QAAA,EAAU,UAAU,CAAC,CAAA;AAEjD,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,YAAA,oBAAgB,GAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAQ,eAAA,EAAgB,CAAA;AAAA,oBACzD,IAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,UAAA;AAAA,QACA,gBAAA,EAAgB,IAAA;AAAA,QAChB,OAAA,EAAQ,WAAA;AAAA,QACR,KAAA,EAAO,EAAE,SAAA,EAAW,MAAA,EAAO;AAAA,QAE1B,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAC1B,YAAA,MAAM,sBAAsB,UAAA,GAAa,KAAA;AACzC,YAAA,2BACG,OAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,cAAC,YAAA;AAAA,cAAA;AAAA,gBACC,cAAY,CAAA,CAAE,wBAAA,EAA0B,EAAE,KAAA,EAAO,KAAA,GAAQ,GAAG,CAAA;AAAA,gBAC5D,KAAA,EAAO,EAAE,MAAA,EAAQ,mBAAA,GAAsB,YAAY,SAAA,EAAU;AAAA,gBAC7D,SAAS,MAAM;AACb,kBAAA,IAAI,mBAAA,gBAAmC,KAAK,CAAA;AAAA,gBAC9C,CAAA;AAAA,gBAEC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,iBARI,KAUd,CAAA;AAAA,UAEJ,CAAC,CAAA;AAAA,0BACD,GAAA,CAAC,OAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAc,uBAAY,CAAA,EAC7B;AAAA;AAAA;AAAA,KACF;AAAA,oBACA,GAAA,CAAC,SAAI,SAAA,EAAW,MAAA,CAAO,aAAa,GAAA,EAAK,cAAA,EAEtC,QAAA,EAAA,UAAA,GAAa,KAAA,CAAM,MAAA,mBAClB,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QAEC,SAAA;AAAA,QACA,WAAA,EAAa,MAAA;AAAA,QACb,QAAA,EAAU,UAAA;AAAA,QACV,WAAA,EAAa,EAAE,GAAG,eAAA,EAAiB,UAAU,UAAA,EAAW;AAAA,QACxD,QAAQ,WAAA,CAAY,MAAA;AAAA,QACpB,QAAA,EAAU,cAAA;AAAA,QACV,QAAA,EAAU,UAAA;AAAA,QACV,MAAA;AAAA,QACA,aAAA,EAAc,KAAA;AAAA,QACd,SAAA,EAAW,EAAE,iBAAA,EAAkB;AAAA,QAC/B,QAAA,EAAU,YAAA;AAAA,QACV,OAAA,EAAS,EAAE,QAAA,EAAU,cAAA,EAAe;AAAA,QACpC,qCAAA,EAAuC;AAAA,UACrC,KAAA,EAAO;AAAA,SACT;AAAA,QACC,GAAG,aAAA;AAAA,QAEJ,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,MAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,UAAA;AAAA,cACR,OAAA,EAAS,UAAA;AAAA,cACT,WAAW,MAAA,CAAO,UAAA;AAAA,cAClB,UAAA,EAAY,aAAa,CAAA,IAAK,YAAA;AAAA,cAE7B,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,0BACA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,SAAA,EAAU,MAAK,QAAA,EAAS,UAAA,EAAY,YAAA,EACjD,QAAA,EAAA,UAAA,KAAe,MAAM,MAAA,GAAS,CAAA,GAC3B,WAAA,GACA,CAAA,CAAE,wBAAwB,CAAA,EAChC;AAAA,SAAA,EACF;AAAA,OAAA;AAAA,MAhCK;AAAA,KAiCP;AAAA;AAAA,MAEF,mBAAA,mBACE,GAAA;AAAA,QAAC,mBAAA;AAAA,QAAA;AAAA,UACC,cAAA,EAAgB,YAAA;AAAA,UAChB,QAAA,EAAU,UAAA;AAAA,UACV,UAAA;AAAA,UACA,aAAa,MAAM;AAAA,UAAC,CAAA;AAAA,UACpB,KAAA;AAAA,UACA;AAAA;AAAA,0BAGF,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,oBAAA,EAAA,EAAqB,SAAA,EAAW,UAAA,EAAY,OAAA,EAAS,KAAA,EAAO,CAAA;AAAA,wBAC7D,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,MAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,UAAA;AAAA,cACR,OAAA,EAAS,UAAA;AAAA,cACT,WAAW,MAAA,CAAO,UAAA;AAAA,cAClB,YAAY,UAAA,GAAa,CAAA;AAAA,cAExB,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,0BACA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,UAAA,EAAY,UAAA;AAAA,cACZ,OAAA,EAAS,YAAA;AAAA,cAER,QAAA,EAAA;AAAA;AAAA;AACH,SAAA,EACF;AAAA,OAAA,EACF;AAAA,KAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;;"}
|
|
1
|
+
{"version":3,"file":"Stepper.esm.js","sources":["../../../../src/next/components/Stepper/Stepper.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useAnalytics, useApiHolder } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n FieldExtensionOptions,\n FormProps,\n LayoutOptions,\n ReviewStepProps,\n TemplateParameterSchema,\n} from '@backstage/plugin-scaffolder-react';\nimport { resolveParameterSteps } from '@backstage/plugin-scaffolder-common/alpha';\nimport { JsonValue } from '@backstage/types';\nimport { Button } from '@backstage/ui';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport MuiStep from '@material-ui/core/Step';\nimport MuiStepLabel from '@material-ui/core/StepLabel';\nimport MuiStepper from '@material-ui/core/Stepper';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { type IChangeEvent } from '@rjsf/core';\nimport { ErrorSchema } from '@rjsf/utils';\nimport { customizeValidator } from '@rjsf/validator-ajv8';\nimport ajvErrors from 'ajv-errors';\nimport { merge } from 'lodash';\nimport {\n ComponentType,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport { scaffolderReactTranslationRef } from '../../../translation';\nimport { useFormDataFromQuery, useTemplateSchema } from '../../hooks';\nimport { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps';\nimport { Form } from '../Form';\nimport { PasswordWidget } from '../PasswordWidget/PasswordWidget';\nimport { ReviewState, type ReviewStateProps } from '../ReviewState';\nimport {\n createAsyncValidators,\n type FormValidation,\n} from './createAsyncValidators';\nimport { ErrorListTemplate } from './ErrorListTemplate';\nimport * as FieldOverrides from './FieldOverrides';\nimport { hasErrors } from './utils';\n\nconst validator = customizeValidator();\najvErrors(validator.ajv);\n\n/** @alpha */\nexport type BackstageTemplateStepperClassKey =\n | 'backButton'\n | 'footer'\n | 'formWrapper';\n\nconst useStyles = makeStyles(\n theme => ({\n backButton: {\n marginRight: theme.spacing(1),\n },\n footer: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'right',\n marginTop: theme.spacing(2),\n },\n formWrapper: {\n padding: theme.spacing(2),\n },\n }),\n { name: 'BackstageTemplateStepper' },\n);\n\n/**\n * The Props for {@link Stepper} component\n * @alpha\n */\nexport type StepperProps = {\n manifest: TemplateParameterSchema;\n extensions: FieldExtensionOptions<any, any>[];\n /**\n * @deprecated This was only ever used for analytics tracking purposes, which\n * is now handled in the `<Workflow />` component. Passing it in will have no\n * effect.\n */\n templateName?: string;\n formProps?: FormProps;\n initialState?: Record<string, JsonValue>;\n onCreate: (values: Record<string, JsonValue>) => Promise<void>;\n components?: {\n ReviewStepComponent?: ComponentType<ReviewStepProps>;\n ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element;\n backButtonText?: ReactNode;\n createButtonText?: ReactNode;\n reviewButtonText?: ReactNode;\n };\n layouts?: LayoutOptions[];\n};\n\n/**\n * The `Stepper` component is the Wizard that is rendered when a user selects a template\n * @alpha\n */\nexport const Stepper = (stepperProps: StepperProps) => {\n const { t } = useTranslationRef(scaffolderReactTranslationRef);\n const { layouts = [], components = {}, onCreate, ...props } = stepperProps;\n const {\n ReviewStateComponent = ReviewState,\n ReviewStepComponent,\n backButtonText = t('stepper.backButtonText'),\n createButtonText = t('stepper.createButtonText'),\n reviewButtonText = t('stepper.reviewButtonText'),\n } = components;\n const analytics = useAnalytics();\n const { presentation, steps } = useTemplateSchema(props.manifest);\n const apiHolder = useApiHolder();\n // Index into `steps` rather than `visibleSteps`, so that the active step\n // stays the same when other steps are shown or hidden.\n const [activeStepIndex, setActiveStepIndex] = useState(0);\n const [isValidating, setIsValidating] = useState(false);\n const [initialState] = useFormDataFromQuery(props.initialState);\n const [stepsState, setStepsState] =\n useState<Record<string, JsonValue>>(initialState);\n\n const { visibleSteps, filteredFormState } = useMemo(() => {\n const resolved = resolveParameterSteps(\n stepsState,\n steps.map(step => ({ schema: step.mergedSchema, when: step.when })),\n );\n return {\n visibleSteps: steps.filter((_, index) => resolved.visible[index]),\n filteredFormState: resolved.values,\n };\n }, [steps, stepsState]);\n\n // If the active step is hidden, move on to the next visible step.\n const nextVisibleStep = visibleSteps.findIndex(\n step => steps.indexOf(step) >= activeStepIndex,\n );\n const activeStep =\n nextVisibleStep === -1 ? visibleSteps.length : nextVisibleStep;\n\n const setActiveStep = useCallback(\n (step: number) =>\n setActiveStepIndex(\n step < visibleSteps.length\n ? steps.indexOf(visibleSteps[step])\n : steps.length,\n ),\n [steps, visibleSteps],\n );\n\n const [errors, setErrors] = useState<undefined | FormValidation>();\n const styles = useStyles();\n const formWrapperRef = useRef<HTMLDivElement>(null);\n\n const backLabel =\n presentation?.buttonLabels?.backButtonText ?? backButtonText;\n const createLabel =\n presentation?.buttonLabels?.createButtonText ?? createButtonText;\n const reviewLabel =\n presentation?.buttonLabels?.reviewButtonText ?? reviewButtonText;\n\n const extensions = useMemo(() => {\n return Object.fromEntries(\n props.extensions.map(({ name, component }) => [name, component]),\n );\n }, [props.extensions]);\n\n const fields = useMemo(\n () => ({ ...FieldOverrides, ...extensions }),\n [extensions],\n );\n\n const validators = useMemo(() => {\n return Object.fromEntries(\n props.extensions.map(({ name, validation }) => [name, validation]),\n );\n }, [props.extensions]);\n\n const validation = useMemo(() => {\n return createAsyncValidators(\n visibleSteps[activeStep]?.mergedSchema,\n validators,\n { apiHolder },\n );\n }, [visibleSteps, activeStep, validators, apiHolder]);\n\n const handleBack = useCallback(() => {\n setActiveStep(activeStep - 1);\n }, [activeStep, setActiveStep]);\n\n const currentStep = useTransformSchemaToProps(visibleSteps[activeStep], {\n layouts,\n });\n\n const {\n formContext: propFormContext,\n uiSchema: propUiSchema,\n liveOmit: _shouldLiveOmit,\n omitExtraData: _shouldOmitExtraData,\n ...restFormProps\n } = props.formProps ?? {};\n\n const handleChange = useCallback(\n (e: IChangeEvent) => {\n setStepsState(current => {\n return { ...current, ...e.formData };\n });\n },\n [setStepsState],\n );\n\n const handleNext = useCallback(\n async ({ formData = {} }: { formData?: Record<string, JsonValue> }) => {\n // The validation should never throw, as the validators are wrapped in a try/catch.\n // This makes it fine to set and unset state without try/catch.\n setErrors(undefined);\n setIsValidating(true);\n\n const returnedValidation = await validation(formData);\n\n setStepsState(current => ({\n ...current,\n ...formData,\n }));\n\n setIsValidating(false);\n\n if (hasErrors(returnedValidation)) {\n setErrors(returnedValidation);\n } else {\n setErrors(undefined);\n const stepNum = activeStep + 1;\n analytics.captureEvent('click', `Next Step (${stepNum})`);\n // Move to the next step that is visible with the submitted values.\n const current = steps.indexOf(visibleSteps[activeStep]);\n const { visible } = resolveParameterSteps(\n { ...stepsState, ...formData },\n steps.map(step => ({ schema: step.mergedSchema, when: step.when })),\n );\n const next = visible.findIndex(\n (isVisible, index) => isVisible && index > current,\n );\n setActiveStepIndex(next === -1 ? steps.length : next);\n }\n },\n [validation, analytics, activeStep, steps, visibleSteps, stepsState],\n );\n\n useEffect(() => {\n const getScrollableParent = (\n element: HTMLElement | null,\n ): HTMLElement | null => {\n if (!element) return null;\n const { overflowY } = window.getComputedStyle(element);\n const isScrollable = overflowY === 'auto' || overflowY === 'scroll';\n if (isScrollable && element.scrollHeight > element.clientHeight) {\n return element;\n }\n return getScrollableParent(element.parentElement);\n };\n\n const scrollTarget = getScrollableParent(formWrapperRef.current);\n\n if (scrollTarget && typeof scrollTarget.scrollTo === 'function') {\n scrollTarget.scrollTo({ top: 0, behavior: 'auto' });\n } else {\n window.scrollTo({ top: 0, behavior: 'auto' });\n }\n }, [activeStep]);\n\n const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema);\n\n const [isCreating, setIsCreating] = useState(false);\n\n const handleCreate = useCallback(async () => {\n setIsCreating(true);\n analytics.captureEvent('click', `${createLabel}`);\n try {\n await onCreate(filteredFormState);\n } finally {\n setIsCreating(false);\n }\n }, [analytics, createLabel, filteredFormState, onCreate]);\n\n return (\n <>\n {isValidating && <LinearProgress variant=\"indeterminate\" />}\n <MuiStepper\n activeStep={activeStep}\n alternativeLabel\n variant=\"elevation\"\n style={{ overflowX: 'auto' }}\n >\n {visibleSteps.map((step, index) => {\n const isAllowedLabelClick = activeStep > index;\n return (\n <MuiStep key={steps.indexOf(step)}>\n <MuiStepLabel\n aria-label={t('stepper.stepIndexLabel', { index: index + 1 })}\n style={{ cursor: isAllowedLabelClick ? 'pointer' : 'default' }}\n onClick={() => {\n if (isAllowedLabelClick) setActiveStep(index);\n }}\n >\n {step.title}\n </MuiStepLabel>\n </MuiStep>\n );\n })}\n <MuiStep>\n <MuiStepLabel>{reviewLabel}</MuiStepLabel>\n </MuiStep>\n </MuiStepper>\n <div className={styles.formWrapper} ref={formWrapperRef}>\n {/* eslint-disable-next-line no-nested-ternary */}\n {activeStep < visibleSteps.length ? (\n <Form\n key={steps.indexOf(visibleSteps[activeStep])}\n validator={validator}\n extraErrors={errors as unknown as ErrorSchema}\n formData={stepsState}\n formContext={{ ...propFormContext, formData: stepsState }}\n schema={currentStep.schema}\n uiSchema={mergedUiSchema}\n onSubmit={handleNext}\n fields={fields}\n showErrorList=\"top\"\n templates={{ ErrorListTemplate }}\n onChange={handleChange}\n widgets={{ password: PasswordWidget }}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n {...restFormProps}\n >\n <div className={styles.footer}>\n <Button\n variant=\"tertiary\"\n onPress={handleBack}\n className={styles.backButton}\n isDisabled={activeStep < 1 || isValidating}\n >\n {backLabel}\n </Button>\n <Button variant=\"primary\" type=\"submit\" isDisabled={isValidating}>\n {activeStep === visibleSteps.length - 1\n ? reviewLabel\n : t('stepper.nextButtonText')}\n </Button>\n </div>\n </Form>\n ) : // TODO: potentially move away from this pattern, deprecate?\n ReviewStepComponent ? (\n <ReviewStepComponent\n disableButtons={isValidating}\n formData={filteredFormState}\n handleBack={handleBack}\n handleReset={() => {}}\n steps={visibleSteps}\n handleCreate={handleCreate}\n />\n ) : (\n <>\n <ReviewStateComponent\n formState={filteredFormState}\n schemaFormState={stepsState}\n schemas={visibleSteps}\n />\n <div className={styles.footer}>\n <Button\n variant=\"tertiary\"\n onPress={handleBack}\n className={styles.backButton}\n isDisabled={activeStep < 1}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"primary\"\n isDisabled={isCreating}\n onPress={handleCreate}\n >\n {createLabel}\n </Button>\n </div>\n </>\n )}\n </div>\n </>\n );\n};\n"],"names":["FieldOverrides","validation"],"mappings":"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"}
|
|
@@ -3,11 +3,12 @@ import { extractSchemaFromStep } from '../lib/schema.esm.js';
|
|
|
3
3
|
|
|
4
4
|
const useTemplateSchema = (manifest) => {
|
|
5
5
|
const featureFlags = useApi(featureFlagsApiRef);
|
|
6
|
-
const steps = manifest.steps.map((
|
|
7
|
-
title,
|
|
8
|
-
description,
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const steps = manifest.steps.map((step) => ({
|
|
7
|
+
title: step.title,
|
|
8
|
+
description: step.description,
|
|
9
|
+
...step.when !== void 0 ? { when: step.when } : {},
|
|
10
|
+
mergedSchema: step.schema,
|
|
11
|
+
...extractSchemaFromStep(step.schema)
|
|
11
12
|
}));
|
|
12
13
|
const returningSteps = steps.filter((step) => {
|
|
13
14
|
const stepFeatureFlag = step.uiSchema["ui:backstage"]?.featureFlag;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTemplateSchema.esm.js","sources":["../../../src/next/hooks/useTemplateSchema.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api';\nimport { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\nimport { UiSchema } from '@rjsf/utils';\nimport { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react';\nimport { extractSchemaFromStep } from '../lib';\n\n/**\n * This is the parsed template schema that is returned from the {@link useTemplateSchema} hook.\n * @alpha\n */\nexport interface ParsedTemplateSchema {\n uiSchema: UiSchema;\n mergedSchema: JsonObject;\n schema: JsonObject;\n title: string;\n description?: string;\n}\n\n/**\n * This hook will parse the template schema and return the steps with the\n * parsed schema and uiSchema. Filtering out any steps or properties that\n * are not enabled with feature flags.\n * @alpha\n */\nexport const useTemplateSchema = (\n manifest: TemplateParameterSchema,\n): {\n steps: ParsedTemplateSchema[];\n presentation?: TemplatePresentationV1beta3;\n} => {\n const featureFlags = useApi(featureFlagsApiRef);\n const steps = manifest.steps.map(
|
|
1
|
+
{"version":3,"file":"useTemplateSchema.esm.js","sources":["../../../src/next/hooks/useTemplateSchema.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api';\nimport { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\nimport { UiSchema } from '@rjsf/utils';\nimport { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react';\nimport { extractSchemaFromStep } from '../lib';\n\n/**\n * This is the parsed template schema that is returned from the {@link useTemplateSchema} hook.\n * @alpha\n */\nexport interface ParsedTemplateSchema {\n uiSchema: UiSchema;\n mergedSchema: JsonObject;\n schema: JsonObject;\n title: string;\n description?: string;\n when?: string | boolean;\n}\n\n/**\n * This hook will parse the template schema and return the steps with the\n * parsed schema and uiSchema. Filtering out any steps or properties that\n * are not enabled with feature flags.\n * @alpha\n */\nexport const useTemplateSchema = (\n manifest: TemplateParameterSchema,\n): {\n steps: ParsedTemplateSchema[];\n presentation?: TemplatePresentationV1beta3;\n} => {\n const featureFlags = useApi(featureFlagsApiRef);\n const steps = manifest.steps.map(step => ({\n title: step.title,\n description: step.description,\n ...(step.when !== undefined ? { when: step.when } : {}),\n mergedSchema: step.schema,\n ...extractSchemaFromStep(step.schema),\n }));\n\n const returningSteps = steps\n // Filter out steps that are not enabled with the feature flags\n .filter(step => {\n const stepFeatureFlag = step.uiSchema['ui:backstage']?.featureFlag;\n return stepFeatureFlag ? featureFlags.isActive(stepFeatureFlag) : true;\n })\n // Then filter out the properties that are not enabled with feature flag\n .map(step => {\n // Title is rendered at the top of the page, so let's ignore this from jsonschemaform\n const { title, ...stepSchema } = step.schema;\n\n const strippedSchema = {\n ...step,\n schema: {\n ...stepSchema,\n },\n } as ParsedTemplateSchema;\n\n if (step.schema?.properties || !step.schema?.dependencies) {\n strippedSchema.schema.properties = Object.fromEntries(\n Object.entries((step.schema?.properties ?? {}) as JsonObject).filter(\n ([key]) => {\n const stepFeatureFlag =\n step.uiSchema[key]?.['ui:backstage']?.featureFlag;\n return stepFeatureFlag\n ? featureFlags.isActive(stepFeatureFlag)\n : true;\n },\n ),\n );\n }\n\n return strippedSchema;\n });\n\n return {\n presentation: manifest.presentation,\n steps: returningSteps,\n };\n};\n"],"names":[],"mappings":";;;AAyCO,MAAM,iBAAA,GAAoB,CAC/B,QAAA,KAIG;AACH,EAAA,MAAM,YAAA,GAAe,OAAO,kBAAkB,CAAA;AAC9C,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,IACxC,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,GAAI,KAAK,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK,GAAI,EAAC;AAAA,IACrD,cAAc,IAAA,CAAK,MAAA;AAAA,IACnB,GAAG,qBAAA,CAAsB,IAAA,CAAK,MAAM;AAAA,GACtC,CAAE,CAAA;AAEF,EAAA,MAAM,cAAA,GAAiB,KAAA,CAEpB,MAAA,CAAO,CAAA,IAAA,KAAQ;AACd,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,QAAA,CAAS,cAAc,CAAA,EAAG,WAAA;AACvD,IAAA,OAAO,eAAA,GAAkB,YAAA,CAAa,QAAA,CAAS,eAAe,CAAA,GAAI,IAAA;AAAA,EACpE,CAAC,CAAA,CAEA,GAAA,CAAI,CAAA,IAAA,KAAQ;AAEX,IAAA,MAAM,EAAE,KAAA,EAAO,GAAG,UAAA,KAAe,IAAA,CAAK,MAAA;AAEtC,IAAA,MAAM,cAAA,GAAiB;AAAA,MACrB,GAAG,IAAA;AAAA,MACH,MAAA,EAAQ;AAAA,QACN,GAAG;AAAA;AACL,KACF;AAEA,IAAA,IAAI,KAAK,MAAA,EAAQ,UAAA,IAAc,CAAC,IAAA,CAAK,QAAQ,YAAA,EAAc;AACzD,MAAA,cAAA,CAAe,MAAA,CAAO,aAAa,MAAA,CAAO,WAAA;AAAA,QACxC,OAAO,OAAA,CAAS,IAAA,CAAK,QAAQ,UAAA,IAAc,EAAiB,CAAA,CAAE,MAAA;AAAA,UAC5D,CAAC,CAAC,GAAG,CAAA,KAAM;AACT,YAAA,MAAM,kBACJ,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,cAAc,CAAA,EAAG,WAAA;AACxC,YAAA,OAAO,eAAA,GACH,YAAA,CAAa,QAAA,CAAS,eAAe,CAAA,GACrC,IAAA;AAAA,UACN;AAAA;AACF,OACF;AAAA,IACF;AAEA,IAAA,OAAO,cAAA;AAAA,EACT,CAAC,CAAA;AAEH,EAAA,OAAO;AAAA,IACL,cAAc,QAAA,CAAS,YAAA;AAAA,IACvB,KAAA,EAAO;AAAA,GACT;AACF;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-react",
|
|
3
|
-
"version": "3.0.0-next.
|
|
3
|
+
"version": "3.0.0-next.2",
|
|
4
4
|
"description": "A frontend library that helps other Backstage plugins interact with the Scaffolder",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "web-library",
|
|
@@ -74,17 +74,17 @@
|
|
|
74
74
|
"test": "backstage-cli package test"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@backstage/catalog-client": "1.16.
|
|
78
|
-
"@backstage/catalog-model": "1.10.
|
|
79
|
-
"@backstage/core-components": "0.18.16-next.
|
|
80
|
-
"@backstage/core-plugin-api": "1.12.12-next.
|
|
81
|
-
"@backstage/frontend-plugin-api": "0.
|
|
82
|
-
"@backstage/plugin-catalog-react": "4.0.0-next.
|
|
83
|
-
"@backstage/plugin-permission-react": "0.5.7-next.
|
|
84
|
-
"@backstage/plugin-scaffolder-common": "2.
|
|
77
|
+
"@backstage/catalog-client": "1.16.4-next.1",
|
|
78
|
+
"@backstage/catalog-model": "1.10.3-next.0",
|
|
79
|
+
"@backstage/core-components": "0.18.16-next.1",
|
|
80
|
+
"@backstage/core-plugin-api": "1.12.12-next.2",
|
|
81
|
+
"@backstage/frontend-plugin-api": "0.19.0-next.2",
|
|
82
|
+
"@backstage/plugin-catalog-react": "4.0.0-next.2",
|
|
83
|
+
"@backstage/plugin-permission-react": "0.5.7-next.1",
|
|
84
|
+
"@backstage/plugin-scaffolder-common": "2.4.0-next.1",
|
|
85
85
|
"@backstage/theme": "0.7.3",
|
|
86
86
|
"@backstage/types": "1.2.2",
|
|
87
|
-
"@backstage/ui": "0.
|
|
87
|
+
"@backstage/ui": "0.20.0-next.0",
|
|
88
88
|
"@backstage/version-bridge": "1.0.12",
|
|
89
89
|
"@material-ui/core": "^4.12.2",
|
|
90
90
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -114,13 +114,13 @@
|
|
|
114
114
|
"zod-to-json-schema": "^3.25.1"
|
|
115
115
|
},
|
|
116
116
|
"devDependencies": {
|
|
117
|
-
"@backstage/cli": "0.36.8-next.
|
|
118
|
-
"@backstage/core-app-api": "1.20.7-next.
|
|
119
|
-
"@backstage/frontend-test-utils": "0.7.0-next.
|
|
120
|
-
"@backstage/plugin-catalog": "2.0.11-next.
|
|
121
|
-
"@backstage/plugin-catalog-common": "1.2.
|
|
122
|
-
"@backstage/plugin-permission-common": "0.9.
|
|
123
|
-
"@backstage/test-utils": "1.7.24-next.
|
|
117
|
+
"@backstage/cli": "0.36.8-next.2",
|
|
118
|
+
"@backstage/core-app-api": "1.20.7-next.2",
|
|
119
|
+
"@backstage/frontend-test-utils": "0.7.0-next.2",
|
|
120
|
+
"@backstage/plugin-catalog": "2.0.11-next.2",
|
|
121
|
+
"@backstage/plugin-catalog-common": "1.2.2-next.0",
|
|
122
|
+
"@backstage/plugin-permission-common": "0.9.13-next.0",
|
|
123
|
+
"@backstage/test-utils": "1.7.24-next.1",
|
|
124
124
|
"@testing-library/dom": "^10.0.0",
|
|
125
125
|
"@testing-library/jest-dom": "^6.0.0",
|
|
126
126
|
"@testing-library/react": "^16.0.0",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"swr": "^2.0.0"
|
|
134
134
|
},
|
|
135
135
|
"peerDependencies": {
|
|
136
|
-
"@backstage/frontend-test-utils": "0.7.0-next.
|
|
136
|
+
"@backstage/frontend-test-utils": "0.7.0-next.2",
|
|
137
137
|
"@types/react": "^17.0.0 || ^18.0.0",
|
|
138
138
|
"react": "^17.0.0 || ^18.0.0",
|
|
139
139
|
"react-dom": "^17.0.0 || ^18.0.0",
|