@backstage/plugin-scaffolder-react 1.10.0-next.2 → 1.11.0-next.0
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 +48 -0
- package/alpha/package.json +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/next/components/ReviewState/ReviewState.esm.js +39 -27
- package/dist/next/components/ReviewState/ReviewState.esm.js.map +1 -1
- package/dist/next/components/ReviewState/util.esm.js +10 -0
- package/dist/next/components/ReviewState/util.esm.js.map +1 -0
- package/dist/next/components/Stepper/Stepper.esm.js +14 -4
- package/dist/next/components/Stepper/Stepper.esm.js.map +1 -1
- package/dist/next/components/TemplateOutputs/DefaultTemplateOutputs.esm.js +18 -7
- package/dist/next/components/TemplateOutputs/DefaultTemplateOutputs.esm.js.map +1 -1
- package/package.json +12 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-react
|
|
2
2
|
|
|
3
|
+
## 1.11.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8839381: Add scaffolder option to display object items in separate rows on review page
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- d0e95a7: Add ability to customise form fields in the UI by exposing `uiSchema` and `formContext` in `FormProps`
|
|
12
|
+
- 4670f06: support `ajv-errors` for scaffolder validation to allow for customizing the error messages
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/plugin-catalog-react@1.12.3-next.0
|
|
15
|
+
- @backstage/core-components@0.14.10-next.0
|
|
16
|
+
- @backstage/catalog-client@1.6.5
|
|
17
|
+
- @backstage/catalog-model@1.5.0
|
|
18
|
+
- @backstage/core-plugin-api@1.9.3
|
|
19
|
+
- @backstage/theme@0.5.6
|
|
20
|
+
- @backstage/types@1.1.1
|
|
21
|
+
- @backstage/version-bridge@1.0.8
|
|
22
|
+
- @backstage/plugin-permission-react@0.4.24
|
|
23
|
+
- @backstage/plugin-scaffolder-common@1.5.4
|
|
24
|
+
|
|
25
|
+
## 1.10.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- 354e68c: Improve validation error display text in scaffolder
|
|
30
|
+
- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker`
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- cc81579: Updated dependency `@rjsf/utils` to `5.18.5`.
|
|
35
|
+
Updated dependency `@rjsf/core` to `5.18.5`.
|
|
36
|
+
Updated dependency `@rjsf/material-ui` to `5.18.5`.
|
|
37
|
+
Updated dependency `@rjsf/validator-ajv8` to `5.18.5`.
|
|
38
|
+
- 4d7e11f: disables rendering of output box if no output is returned
|
|
39
|
+
- Updated dependencies
|
|
40
|
+
- @backstage/core-components@0.14.9
|
|
41
|
+
- @backstage/plugin-catalog-react@1.12.2
|
|
42
|
+
- @backstage/plugin-permission-react@0.4.24
|
|
43
|
+
- @backstage/plugin-scaffolder-common@1.5.4
|
|
44
|
+
- @backstage/catalog-client@1.6.5
|
|
45
|
+
- @backstage/catalog-model@1.5.0
|
|
46
|
+
- @backstage/core-plugin-api@1.9.3
|
|
47
|
+
- @backstage/theme@0.5.6
|
|
48
|
+
- @backstage/types@1.1.1
|
|
49
|
+
- @backstage/version-bridge@1.0.8
|
|
50
|
+
|
|
3
51
|
## 1.10.0-next.2
|
|
4
52
|
|
|
5
53
|
### Patch Changes
|
package/alpha/package.json
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -312,7 +312,7 @@ type TemplateGroupFilter = {
|
|
|
312
312
|
*
|
|
313
313
|
* @public
|
|
314
314
|
*/
|
|
315
|
-
type FormProps = Pick<FormProps$1, 'transformErrors' | 'noHtml5Validate'>;
|
|
315
|
+
type FormProps = Pick<FormProps$1, 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext'>;
|
|
316
316
|
/**
|
|
317
317
|
* The props for the Last Step in scaffolder template form.
|
|
318
318
|
* Which represents the summary of the input provided by the end user.
|
|
@@ -1,38 +1,50 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { StructuredMetadataTable } from '@backstage/core-components';
|
|
3
3
|
import { Draft07 } from 'json-schema-library';
|
|
4
|
+
import { getLastKey, isJsonObject } from './util.esm.js';
|
|
4
5
|
|
|
6
|
+
function processSchema(key, value, schema, formState) {
|
|
7
|
+
const parsedSchema = new Draft07(schema.mergedSchema);
|
|
8
|
+
const definitionInSchema = parsedSchema.getSchema({
|
|
9
|
+
pointer: `#/${key}`,
|
|
10
|
+
data: formState
|
|
11
|
+
});
|
|
12
|
+
if (definitionInSchema) {
|
|
13
|
+
const backstageReviewOptions = definitionInSchema["ui:backstage"]?.review;
|
|
14
|
+
if (backstageReviewOptions) {
|
|
15
|
+
if (backstageReviewOptions.mask) {
|
|
16
|
+
return [[getLastKey(key), backstageReviewOptions.mask]];
|
|
17
|
+
}
|
|
18
|
+
if (backstageReviewOptions.show === false) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (definitionInSchema["ui:widget"] === "password") {
|
|
23
|
+
return [[getLastKey(key), "******"]];
|
|
24
|
+
}
|
|
25
|
+
if (definitionInSchema.enum && definitionInSchema.enumNames) {
|
|
26
|
+
return [
|
|
27
|
+
[
|
|
28
|
+
getLastKey(key),
|
|
29
|
+
definitionInSchema.enumNames[definitionInSchema.enum.indexOf(value)] || value
|
|
30
|
+
]
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
if (backstageReviewOptions?.explode !== false && isJsonObject(value)) {
|
|
34
|
+
return Object.entries(value).flatMap(
|
|
35
|
+
([nestedKey, nestedValue]) => processSchema(`${key}/${nestedKey}`, nestedValue, schema, formState)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return [[getLastKey(key), value]];
|
|
40
|
+
}
|
|
5
41
|
const ReviewState = (props) => {
|
|
6
42
|
const reviewData = Object.fromEntries(
|
|
7
|
-
Object.entries(props.formState).
|
|
43
|
+
Object.entries(props.formState).flatMap(([key, value]) => {
|
|
8
44
|
for (const step of props.schemas) {
|
|
9
|
-
|
|
10
|
-
const definitionInSchema = parsedSchema.getSchema({
|
|
11
|
-
pointer: `#/${key}`,
|
|
12
|
-
data: props.formState
|
|
13
|
-
});
|
|
14
|
-
if (definitionInSchema) {
|
|
15
|
-
const backstageReviewOptions = definitionInSchema["ui:backstage"]?.review;
|
|
16
|
-
if (backstageReviewOptions) {
|
|
17
|
-
if (backstageReviewOptions.mask) {
|
|
18
|
-
return [key, backstageReviewOptions.mask];
|
|
19
|
-
}
|
|
20
|
-
if (backstageReviewOptions.show === false) {
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (definitionInSchema["ui:widget"] === "password") {
|
|
25
|
-
return [key, "******"];
|
|
26
|
-
}
|
|
27
|
-
if (definitionInSchema.enum && definitionInSchema.enumNames) {
|
|
28
|
-
return [
|
|
29
|
-
key,
|
|
30
|
-
definitionInSchema.enumNames[definitionInSchema.enum.indexOf(value)] || value
|
|
31
|
-
];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
45
|
+
return processSchema(key, value, step, props.formState);
|
|
34
46
|
}
|
|
35
|
-
return [key, value];
|
|
47
|
+
return [[key, value]];
|
|
36
48
|
}).filter((prop) => prop.length > 0)
|
|
37
49
|
);
|
|
38
50
|
return /* @__PURE__ */ React.createElement(StructuredMetadataTable, { metadata: reviewData });
|
|
@@ -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 React from 'react';\nimport { StructuredMetadataTable } from '@backstage/core-components';\nimport { JsonObject } from '@backstage/types';\nimport { Draft07 as JSONSchema } from 'json-schema-library';\nimport { ParsedTemplateSchema } from '../../hooks/useTemplateSchema';\n\n/**\n * The props for the {@link ReviewState} component.\n * @alpha\n */\nexport type ReviewStateProps = {\n schemas: ParsedTemplateSchema[];\n formState: JsonObject;\n};\n\
|
|
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 React from 'react';\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, getLastKey } 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 if (definitionInSchema) {\n const backstageReviewOptions = definitionInSchema['ui:backstage']?.review;\n if (backstageReviewOptions) {\n if (backstageReviewOptions.mask) {\n return [[getLastKey(key), backstageReviewOptions.mask]];\n }\n if (backstageReviewOptions.show === false) {\n return [];\n }\n }\n\n if (definitionInSchema['ui:widget'] === 'password') {\n return [[getLastKey(key), '******']];\n }\n\n if (definitionInSchema.enum && definitionInSchema.enumNames) {\n return [\n [\n getLastKey(key),\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 [[getLastKey(key), 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 for (const step of props.schemas) {\n return processSchema(key, value, step, props.formState);\n }\n return [[key, value]];\n })\n .filter(prop => prop.length > 0),\n );\n return <StructuredMetadataTable metadata={reviewData} />;\n};\n"],"names":["JSONSchema"],"mappings":";;;;;AA+BA,SAAS,aACP,CAAA,GAAA,EACA,KACA,EAAA,MAAA,EACA,SACmC,EAAA;AACnC,EAAA,MAAM,YAAe,GAAA,IAAIA,OAAW,CAAA,MAAA,CAAO,YAAY,CAAA,CAAA;AACvD,EAAM,MAAA,kBAAA,GAAqB,aAAa,SAAU,CAAA;AAAA,IAChD,OAAA,EAAS,KAAK,GAAG,CAAA,CAAA;AAAA,IACjB,IAAM,EAAA,SAAA;AAAA,GACP,CAAA,CAAA;AAED,EAAA,IAAI,kBAAoB,EAAA;AACtB,IAAM,MAAA,sBAAA,GAAyB,kBAAmB,CAAA,cAAc,CAAG,EAAA,MAAA,CAAA;AACnE,IAAA,IAAI,sBAAwB,EAAA;AAC1B,MAAA,IAAI,uBAAuB,IAAM,EAAA;AAC/B,QAAA,OAAO,CAAC,CAAC,UAAA,CAAW,GAAG,CAAG,EAAA,sBAAA,CAAuB,IAAI,CAAC,CAAA,CAAA;AAAA,OACxD;AACA,MAAI,IAAA,sBAAA,CAAuB,SAAS,KAAO,EAAA;AACzC,QAAA,OAAO,EAAC,CAAA;AAAA,OACV;AAAA,KACF;AAEA,IAAI,IAAA,kBAAA,CAAmB,WAAW,CAAA,KAAM,UAAY,EAAA;AAClD,MAAA,OAAO,CAAC,CAAC,UAAA,CAAW,GAAG,CAAA,EAAG,QAAQ,CAAC,CAAA,CAAA;AAAA,KACrC;AAEA,IAAI,IAAA,kBAAA,CAAmB,IAAQ,IAAA,kBAAA,CAAmB,SAAW,EAAA;AAC3D,MAAO,OAAA;AAAA,QACL;AAAA,UACE,WAAW,GAAG,CAAA;AAAA,UACd,mBAAmB,SACjB,CAAA,kBAAA,CAAmB,KAAK,OAAQ,CAAA,KAAK,CACvC,CAAK,IAAA,KAAA;AAAA,SACP;AAAA,OACF,CAAA;AAAA,KACF;AAEA,IAAA,IAAI,sBAAwB,EAAA,OAAA,KAAY,KAAS,IAAA,YAAA,CAAa,KAAK,CAAG,EAAA;AAEpE,MAAO,OAAA,MAAA,CAAO,OAAQ,CAAA,KAAK,CAAE,CAAA,OAAA;AAAA,QAAQ,CAAC,CAAC,SAAW,EAAA,WAAW,CAC3D,KAAA,aAAA,CAAc,CAAG,EAAA,GAAG,CAAI,CAAA,EAAA,SAAS,CAAI,CAAA,EAAA,WAAA,EAAa,QAAQ,SAAS,CAAA;AAAA,OACrE,CAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAA,OAAO,CAAC,CAAC,UAAA,CAAW,GAAG,CAAA,EAAG,KAAK,CAAC,CAAA,CAAA;AAClC,CAAA;AAMa,MAAA,WAAA,GAAc,CAAC,KAA4B,KAAA;AACtD,EAAA,MAAM,aAAa,MAAO,CAAA,WAAA;AAAA,IACxB,MAAA,CAAO,OAAQ,CAAA,KAAA,CAAM,SAAS,CAAA,CAC3B,QAAQ,CAAC,CAAC,GAAK,EAAA,KAAK,CAAM,KAAA;AACzB,MAAW,KAAA,MAAA,IAAA,IAAQ,MAAM,OAAS,EAAA;AAChC,QAAA,OAAO,aAAc,CAAA,GAAA,EAAK,KAAO,EAAA,IAAA,EAAM,MAAM,SAAS,CAAA,CAAA;AAAA,OACxD;AACA,MAAA,OAAO,CAAC,CAAC,GAAK,EAAA,KAAK,CAAC,CAAA,CAAA;AAAA,KACrB,CACA,CAAA,MAAA,CAAO,CAAQ,IAAA,KAAA,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,GACnC,CAAA;AACA,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,uBAAwB,EAAA,EAAA,QAAA,EAAU,UAAY,EAAA,CAAA,CAAA;AACxD;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function isJsonObject(value) {
|
|
2
|
+
return typeof value === "object" && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function getLastKey(key) {
|
|
5
|
+
const parts = key.split("/");
|
|
6
|
+
return parts[parts.length - 1];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { getLastKey, isJsonObject };
|
|
10
|
+
//# sourceMappingURL=util.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.esm.js","sources":["../../../../src/next/components/ReviewState/util.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 */\n\nimport { JsonObject, JsonValue } from '@backstage/types';\n\nexport function isJsonObject(value?: JsonValue): value is JsonObject {\n return typeof value === 'object' && !Array.isArray(value);\n}\n\n// Helper function to get the last part of the key\nexport function getLastKey(key: string): string {\n const parts = key.split('/');\n return parts[parts.length - 1];\n}\n"],"names":[],"mappings":"AAkBO,SAAS,aAAa,KAAwC,EAAA;AACnE,EAAA,OAAO,OAAO,KAAU,KAAA,QAAA,IAAY,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA,CAAA;AAC1D,CAAA;AAGO,SAAS,WAAW,GAAqB,EAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,GAAI,CAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AAC3B,EAAO,OAAA,KAAA,CAAM,KAAM,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AAC/B;;;;"}
|
|
@@ -12,7 +12,7 @@ import { useTemplateSchema } from '../../hooks/useTemplateSchema.esm.js';
|
|
|
12
12
|
import 'react-use/esm/useAsync';
|
|
13
13
|
import '../../../api/ref.esm.js';
|
|
14
14
|
import 'lodash/cloneDeep';
|
|
15
|
-
import
|
|
15
|
+
import { customizeValidator } from '@rjsf/validator-ajv8';
|
|
16
16
|
import { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps.esm.js';
|
|
17
17
|
import { hasErrors } from './utils.esm.js';
|
|
18
18
|
import * as index from './FieldOverrides/index.esm.js';
|
|
@@ -20,7 +20,11 @@ import { Form } from '../Form/Form.esm.js';
|
|
|
20
20
|
import { ErrorListTemplate } from './ErrorListTemplate/errorListTemplate.esm.js';
|
|
21
21
|
import { makeStyles } from '@material-ui/core/styles';
|
|
22
22
|
import { PasswordWidget } from '../PasswordWidget/PasswordWidget.esm.js';
|
|
23
|
+
import ajvErrors from 'ajv-errors';
|
|
24
|
+
import { merge } from 'lodash';
|
|
23
25
|
|
|
26
|
+
const validator = customizeValidator();
|
|
27
|
+
ajvErrors(validator.ajv);
|
|
24
28
|
const useStyles = makeStyles((theme) => ({
|
|
25
29
|
backButton: {
|
|
26
30
|
marginRight: theme.spacing(1)
|
|
@@ -105,6 +109,12 @@ const Stepper = (stepperProps) => {
|
|
|
105
109
|
}
|
|
106
110
|
setFormState((current) => ({ ...current, ...formData }));
|
|
107
111
|
};
|
|
112
|
+
const {
|
|
113
|
+
formContext: propFormContext,
|
|
114
|
+
uiSchema: propUiSchema,
|
|
115
|
+
...restFormProps
|
|
116
|
+
} = props.formProps ?? {};
|
|
117
|
+
const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema);
|
|
108
118
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, isValidating && /* @__PURE__ */ React.createElement(LinearProgress, { variant: "indeterminate" }), /* @__PURE__ */ React.createElement(
|
|
109
119
|
MuiStepper,
|
|
110
120
|
{
|
|
@@ -134,9 +144,9 @@ const Stepper = (stepperProps) => {
|
|
|
134
144
|
validator,
|
|
135
145
|
extraErrors: errors,
|
|
136
146
|
formData: formState,
|
|
137
|
-
formContext: { formData: formState },
|
|
147
|
+
formContext: { ...propFormContext, formData: formState },
|
|
138
148
|
schema: currentStep.schema,
|
|
139
|
-
uiSchema:
|
|
149
|
+
uiSchema: mergedUiSchema,
|
|
140
150
|
onSubmit: handleNext,
|
|
141
151
|
fields,
|
|
142
152
|
showErrorList: "top",
|
|
@@ -146,7 +156,7 @@ const Stepper = (stepperProps) => {
|
|
|
146
156
|
experimental_defaultFormStateBehavior: {
|
|
147
157
|
allOf: "populateDefaults"
|
|
148
158
|
},
|
|
149
|
-
...
|
|
159
|
+
...restFormProps
|
|
150
160
|
},
|
|
151
161
|
/* @__PURE__ */ React.createElement("div", { className: styles.footer }, /* @__PURE__ */ React.createElement(
|
|
152
162
|
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 { JsonValue } from '@backstage/types';\nimport MuiStepper from '@material-ui/core/Stepper';\nimport MuiStep from '@material-ui/core/Step';\nimport MuiStepLabel from '@material-ui/core/StepLabel';\nimport Button from '@material-ui/core/Button';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport { type IChangeEvent } from '@rjsf/core';\nimport { ErrorSchema } from '@rjsf/utils';\nimport React, {\n useCallback,\n useMemo,\n useState,\n type ReactNode,\n ComponentType,\n} from 'react';\nimport {\n createAsyncValidators,\n type FormValidation,\n} from './createAsyncValidators';\nimport { ReviewState, type ReviewStateProps } from '../ReviewState';\nimport { useTemplateSchema, useFormDataFromQuery } from '../../hooks';\nimport validator from '@rjsf/validator-ajv8';\nimport { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps';\nimport { hasErrors } from './utils';\nimport * as FieldOverrides from './FieldOverrides';\nimport { Form } from '../Form';\nimport {\n TemplateParameterSchema,\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport { ReviewStepProps } from '@backstage/plugin-scaffolder-react';\nimport { ErrorListTemplate } from './ErrorListTemplate';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { PasswordWidget } from '../PasswordWidget/PasswordWidget';\n\nconst useStyles = makeStyles(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\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 { layouts = [], components = {}, ...props } = stepperProps;\n const {\n ReviewStateComponent = ReviewState,\n ReviewStepComponent,\n backButtonText = 'Back',\n createButtonText = 'Create',\n reviewButtonText = 'Review',\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 [formState, setFormState] = useFormDataFromQuery(props.initialState);\n\n const [errors, setErrors] = useState<undefined | FormValidation>();\n const styles = useStyles();\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 = () => {\n setActiveStep(prevActiveStep => prevActiveStep - 1);\n };\n\n const handleChange = useCallback(\n (e: IChangeEvent) =>\n setFormState(current => ({ ...current, ...e.formData })),\n [setFormState],\n );\n\n const handleCreate = useCallback(() => {\n props.onCreate(formState);\n analytics.captureEvent('click', `${createLabel}`);\n }, [props, formState, analytics, createLabel]);\n\n const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts });\n\n const handleNext = async ({\n formData = {},\n }: {\n formData?: Record<string, JsonValue>;\n }) => {\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 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 setFormState(current => ({ ...current, ...formData }));\n };\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={`Step ${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}>\n {/* eslint-disable-next-line no-nested-ternary */}\n {activeStep < steps.length ? (\n <Form\n validator={validator}\n extraErrors={errors as unknown as ErrorSchema}\n formData={formState}\n formContext={{ formData: formState }}\n schema={currentStep.schema}\n uiSchema={currentStep.uiSchema}\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 {...(props.formProps ?? {})}\n >\n <div className={styles.footer}>\n <Button\n onClick={handleBack}\n className={styles.backButton}\n disabled={activeStep < 1 || isValidating}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={isValidating}\n >\n {activeStep === steps.length - 1 ? reviewLabel : 'Next'}\n </Button>\n </div>\n </Form>\n ) : // TODO: potentially move away from this pattern, deprecate?\n ReviewStepComponent ? (\n <ReviewStepComponent\n disableButtons={isValidating}\n formData={formState}\n handleBack={handleBack}\n handleReset={() => {}}\n steps={steps}\n handleCreate={handleCreate}\n />\n ) : (\n <>\n <ReviewStateComponent formState={formState} schemas={steps} />\n <div className={styles.footer}>\n <Button\n onClick={handleBack}\n className={styles.backButton}\n disabled={activeStep < 1}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleCreate}\n >\n {createLabel}\n </Button>\n </div>\n </>\n )}\n </div>\n </>\n );\n};\n"],"names":["FieldOverrides","validation"],"mappings":"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"}
|
|
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 { JsonValue } from '@backstage/types';\nimport MuiStepper from '@material-ui/core/Stepper';\nimport MuiStep from '@material-ui/core/Step';\nimport MuiStepLabel from '@material-ui/core/StepLabel';\nimport Button from '@material-ui/core/Button';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport { type IChangeEvent } from '@rjsf/core';\nimport { ErrorSchema } from '@rjsf/utils';\nimport React, {\n useCallback,\n useMemo,\n useState,\n type ReactNode,\n ComponentType,\n} from 'react';\nimport {\n createAsyncValidators,\n type FormValidation,\n} from './createAsyncValidators';\nimport { ReviewState, type ReviewStateProps } from '../ReviewState';\nimport { useTemplateSchema, useFormDataFromQuery } from '../../hooks';\nimport { customizeValidator } from '@rjsf/validator-ajv8';\nimport { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps';\nimport { hasErrors } from './utils';\nimport * as FieldOverrides from './FieldOverrides';\nimport { Form } from '../Form';\nimport {\n TemplateParameterSchema,\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\nimport { ReviewStepProps } from '@backstage/plugin-scaffolder-react';\nimport { ErrorListTemplate } from './ErrorListTemplate';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { PasswordWidget } from '../PasswordWidget/PasswordWidget';\nimport ajvErrors from 'ajv-errors';\nimport { merge } from 'lodash';\n\nconst validator = customizeValidator();\najvErrors(validator.ajv);\n\nconst useStyles = makeStyles(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\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 { layouts = [], components = {}, ...props } = stepperProps;\n const {\n ReviewStateComponent = ReviewState,\n ReviewStepComponent,\n backButtonText = 'Back',\n createButtonText = 'Create',\n reviewButtonText = 'Review',\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 [formState, setFormState] = useFormDataFromQuery(props.initialState);\n\n const [errors, setErrors] = useState<undefined | FormValidation>();\n const styles = useStyles();\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 = () => {\n setActiveStep(prevActiveStep => prevActiveStep - 1);\n };\n\n const handleChange = useCallback(\n (e: IChangeEvent) =>\n setFormState(current => ({ ...current, ...e.formData })),\n [setFormState],\n );\n\n const handleCreate = useCallback(() => {\n props.onCreate(formState);\n analytics.captureEvent('click', `${createLabel}`);\n }, [props, formState, analytics, createLabel]);\n\n const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts });\n\n const handleNext = async ({\n formData = {},\n }: {\n formData?: Record<string, JsonValue>;\n }) => {\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 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 setFormState(current => ({ ...current, ...formData }));\n };\n\n const {\n formContext: propFormContext,\n uiSchema: propUiSchema,\n ...restFormProps\n } = props.formProps ?? {};\n\n const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema);\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={`Step ${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}>\n {/* eslint-disable-next-line no-nested-ternary */}\n {activeStep < steps.length ? (\n <Form\n validator={validator}\n extraErrors={errors as unknown as ErrorSchema}\n formData={formState}\n formContext={{ ...propFormContext, formData: formState }}\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 onClick={handleBack}\n className={styles.backButton}\n disabled={activeStep < 1 || isValidating}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={isValidating}\n >\n {activeStep === steps.length - 1 ? reviewLabel : 'Next'}\n </Button>\n </div>\n </Form>\n ) : // TODO: potentially move away from this pattern, deprecate?\n ReviewStepComponent ? (\n <ReviewStepComponent\n disableButtons={isValidating}\n formData={formState}\n handleBack={handleBack}\n handleReset={() => {}}\n steps={steps}\n handleCreate={handleCreate}\n />\n ) : (\n <>\n <ReviewStateComponent formState={formState} schemas={steps} />\n <div className={styles.footer}>\n <Button\n onClick={handleBack}\n className={styles.backButton}\n disabled={activeStep < 1}\n >\n {backLabel}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleCreate}\n >\n {createLabel}\n </Button>\n </div>\n </>\n )}\n </div>\n </>\n );\n};\n"],"names":["FieldOverrides","validation"],"mappings":"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"}
|
|
@@ -25,14 +25,25 @@ const DefaultTemplateOutputs = (props) => {
|
|
|
25
25
|
if (!output) {
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const emptyOutput = Object.keys(output).length === 0;
|
|
29
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, !emptyOutput ? /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2, "data-testid": "output-box" }, /* @__PURE__ */ React.createElement(Paper, null, /* @__PURE__ */ React.createElement(
|
|
30
|
+
Box,
|
|
30
31
|
{
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
padding: 2,
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
display: "flex",
|
|
35
|
+
gridGap: 16
|
|
36
|
+
},
|
|
37
|
+
/* @__PURE__ */ React.createElement(
|
|
38
|
+
TextOutputs,
|
|
39
|
+
{
|
|
40
|
+
output,
|
|
41
|
+
index: textOutputIndex,
|
|
42
|
+
setIndex: setTextOutputIndex
|
|
43
|
+
}
|
|
44
|
+
),
|
|
45
|
+
/* @__PURE__ */ React.createElement(LinkOutputs, { output })
|
|
46
|
+
))) : null, textOutput ? /* @__PURE__ */ React.createElement(Box, { paddingBottom: 2, "data-testid": "text-output-box" }, /* @__PURE__ */ React.createElement(
|
|
36
47
|
InfoCard,
|
|
37
48
|
{
|
|
38
49
|
title: textOutput.title ?? "Text Output",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultTemplateOutputs.esm.js","sources":["../../../../src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 { InfoCard, MarkdownContent } from '@backstage/core-components';\nimport {\n ScaffolderOutputText,\n ScaffolderTaskOutput,\n} from '@backstage/plugin-scaffolder-react';\nimport Box from '@material-ui/core/Box';\nimport Paper from '@material-ui/core/Paper';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { LinkOutputs } from './LinkOutputs';\nimport { TextOutputs } from './TextOutputs';\n\n/**\n * The DefaultOutputs renderer for the scaffolder task output\n *\n * @alpha\n */\nexport const DefaultTemplateOutputs = (props: {\n output?: ScaffolderTaskOutput;\n}) => {\n const { output } = props;\n const [textOutputIndex, setTextOutputIndex] = useState<number | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (textOutputIndex === undefined && output?.text) {\n const defaultIndex = output.text.findIndex(\n (t: ScaffolderOutputText) => t.default,\n );\n setTextOutputIndex(defaultIndex >= 0 ? defaultIndex : 0);\n }\n }, [textOutputIndex, output]);\n\n const textOutput = useMemo(\n () =>\n textOutputIndex !== undefined ? output?.text?.[textOutputIndex] : null,\n [output, textOutputIndex],\n );\n\n if (!output) {\n return null;\n }\n\n return (\n <>\n <Box paddingBottom={2}>\n
|
|
1
|
+
{"version":3,"file":"DefaultTemplateOutputs.esm.js","sources":["../../../../src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 { InfoCard, MarkdownContent } from '@backstage/core-components';\nimport {\n ScaffolderOutputText,\n ScaffolderTaskOutput,\n} from '@backstage/plugin-scaffolder-react';\nimport Box from '@material-ui/core/Box';\nimport Paper from '@material-ui/core/Paper';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { LinkOutputs } from './LinkOutputs';\nimport { TextOutputs } from './TextOutputs';\n\n/**\n * The DefaultOutputs renderer for the scaffolder task output\n *\n * @alpha\n */\nexport const DefaultTemplateOutputs = (props: {\n output?: ScaffolderTaskOutput;\n}) => {\n const { output } = props;\n const [textOutputIndex, setTextOutputIndex] = useState<number | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (textOutputIndex === undefined && output?.text) {\n const defaultIndex = output.text.findIndex(\n (t: ScaffolderOutputText) => t.default,\n );\n setTextOutputIndex(defaultIndex >= 0 ? defaultIndex : 0);\n }\n }, [textOutputIndex, output]);\n\n const textOutput = useMemo(\n () =>\n textOutputIndex !== undefined ? output?.text?.[textOutputIndex] : null,\n [output, textOutputIndex],\n );\n\n if (!output) {\n return null;\n }\n\n const emptyOutput = Object.keys(output).length === 0;\n\n return (\n <>\n {!emptyOutput ? (\n <Box paddingBottom={2} data-testid=\"output-box\">\n <Paper>\n <Box\n padding={2}\n justifyContent=\"center\"\n display=\"flex\"\n gridGap={16}\n >\n <TextOutputs\n output={output}\n index={textOutputIndex}\n setIndex={setTextOutputIndex}\n />\n <LinkOutputs output={output} />\n </Box>\n </Paper>\n </Box>\n ) : null}\n {textOutput ? (\n <Box paddingBottom={2} data-testid=\"text-output-box\">\n <InfoCard\n title={textOutput.title ?? 'Text Output'}\n noPadding\n titleTypographyProps={{ component: 'h2' }}\n >\n <Box padding={2} height=\"100%\">\n <MarkdownContent content={textOutput.content ?? ''} />\n </Box>\n </InfoCard>\n </Box>\n ) : null}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA+Ba,MAAA,sBAAA,GAAyB,CAAC,KAEjC,KAAA;AACJ,EAAM,MAAA,EAAE,QAAW,GAAA,KAAA,CAAA;AACnB,EAAM,MAAA,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAA,QAAA;AAAA,IAC5C,KAAA,CAAA;AAAA,GACF,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,eAAA,KAAoB,KAAa,CAAA,IAAA,MAAA,EAAQ,IAAM,EAAA;AACjD,MAAM,MAAA,YAAA,GAAe,OAAO,IAAK,CAAA,SAAA;AAAA,QAC/B,CAAC,MAA4B,CAAE,CAAA,OAAA;AAAA,OACjC,CAAA;AACA,MAAmB,kBAAA,CAAA,YAAA,IAAgB,CAAI,GAAA,YAAA,GAAe,CAAC,CAAA,CAAA;AAAA,KACzD;AAAA,GACC,EAAA,CAAC,eAAiB,EAAA,MAAM,CAAC,CAAA,CAAA;AAE5B,EAAA,MAAM,UAAa,GAAA,OAAA;AAAA,IACjB,MACE,eAAoB,KAAA,KAAA,CAAA,GAAY,MAAQ,EAAA,IAAA,GAAO,eAAe,CAAI,GAAA,IAAA;AAAA,IACpE,CAAC,QAAQ,eAAe,CAAA;AAAA,GAC1B,CAAA;AAEA,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,MAAM,WAAc,GAAA,MAAA,CAAO,IAAK,CAAA,MAAM,EAAE,MAAW,KAAA,CAAA,CAAA;AAEnD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,CAAC,WAAA,mBACC,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,eAAe,CAAG,EAAA,aAAA,EAAY,YACjC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,KACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,CAAA;AAAA,MACT,cAAe,EAAA,QAAA;AAAA,MACf,OAAQ,EAAA,MAAA;AAAA,MACR,OAAS,EAAA,EAAA;AAAA,KAAA;AAAA,oBAET,KAAA,CAAA,aAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,KAAO,EAAA,eAAA;AAAA,QACP,QAAU,EAAA,kBAAA;AAAA,OAAA;AAAA,KACZ;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,eAAY,MAAgB,EAAA,CAAA;AAAA,GAEjC,CACF,CAAA,GACE,IACH,EAAA,UAAA,uCACE,GAAI,EAAA,EAAA,aAAA,EAAe,CAAG,EAAA,aAAA,EAAY,iBACjC,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,WAAW,KAAS,IAAA,aAAA;AAAA,MAC3B,SAAS,EAAA,IAAA;AAAA,MACT,oBAAA,EAAsB,EAAE,SAAA,EAAW,IAAK,EAAA;AAAA,KAAA;AAAA,oBAEvC,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,OAAS,EAAA,CAAA,EAAG,MAAO,EAAA,MAAA,EAAA,kBACrB,KAAA,CAAA,aAAA,CAAA,eAAA,EAAA,EAAgB,OAAS,EAAA,UAAA,CAAW,OAAW,IAAA,EAAA,EAAI,CACtD,CAAA;AAAA,GAEJ,IACE,IACN,CAAA,CAAA;AAEJ;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0-next.0",
|
|
4
4
|
"description": "A frontend library that helps other Backstage plugins interact with the Scaffolder",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "web-library",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@backstage/catalog-client": "^1.6.5",
|
|
61
61
|
"@backstage/catalog-model": "^1.5.0",
|
|
62
|
-
"@backstage/core-components": "^0.14.
|
|
62
|
+
"@backstage/core-components": "^0.14.10-next.0",
|
|
63
63
|
"@backstage/core-plugin-api": "^1.9.3",
|
|
64
|
-
"@backstage/plugin-catalog-react": "^1.12.
|
|
65
|
-
"@backstage/plugin-permission-react": "^0.4.
|
|
66
|
-
"@backstage/plugin-scaffolder-common": "^1.5.
|
|
64
|
+
"@backstage/plugin-catalog-react": "^1.12.3-next.0",
|
|
65
|
+
"@backstage/plugin-permission-react": "^0.4.24",
|
|
66
|
+
"@backstage/plugin-scaffolder-common": "^1.5.4",
|
|
67
67
|
"@backstage/theme": "^0.5.6",
|
|
68
68
|
"@backstage/types": "^1.1.1",
|
|
69
69
|
"@backstage/version-bridge": "^1.0.8",
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"@rjsf/validator-ajv8": "5.18.5",
|
|
78
78
|
"@types/json-schema": "^7.0.9",
|
|
79
79
|
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
80
|
+
"ajv-errors": "^3.0.0",
|
|
80
81
|
"classnames": "^2.2.6",
|
|
81
82
|
"flatted": "3.3.1",
|
|
82
83
|
"humanize-duration": "^3.25.1",
|
|
@@ -92,12 +93,12 @@
|
|
|
92
93
|
"zod-to-json-schema": "^3.20.4"
|
|
93
94
|
},
|
|
94
95
|
"devDependencies": {
|
|
95
|
-
"@backstage/cli": "^0.
|
|
96
|
-
"@backstage/core-app-api": "^1.
|
|
97
|
-
"@backstage/plugin-catalog": "^1.21.
|
|
98
|
-
"@backstage/plugin-catalog-common": "^1.0.
|
|
99
|
-
"@backstage/plugin-permission-common": "^0.
|
|
100
|
-
"@backstage/test-utils": "^1.5.
|
|
96
|
+
"@backstage/cli": "^0.27.0-next.0",
|
|
97
|
+
"@backstage/core-app-api": "^1.14.1-next.0",
|
|
98
|
+
"@backstage/plugin-catalog": "^1.21.2-next.0",
|
|
99
|
+
"@backstage/plugin-catalog-common": "^1.0.25",
|
|
100
|
+
"@backstage/plugin-permission-common": "^0.8.0",
|
|
101
|
+
"@backstage/test-utils": "^1.5.9-next.0",
|
|
101
102
|
"@testing-library/dom": "^10.0.0",
|
|
102
103
|
"@testing-library/jest-dom": "^6.0.0",
|
|
103
104
|
"@testing-library/react": "^15.0.0",
|