@backstage/plugin-scaffolder 1.6.0-next.3 → 1.6.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 CHANGED
@@ -1,5 +1,43 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3424a8075d: Added support for `async` validation for the `next` version of the plugin
8
+ - ad036784e9: Ability to modify the layout of the step form
9
+ - 192d856495: Implementing review step for the scaffolder under `create/next`
10
+
11
+ ### Patch Changes
12
+
13
+ - 817f3196f6: Updated React Router dependencies to be peer dependencies.
14
+ - eadf56bbbf: Bump `git-url-parse` version to `^13.0.0`
15
+ - 9ffb75616d: Fix bug with empty strings in `EntityPicker`
16
+ - 3f739be9d9: Minor API signatures cleanup
17
+ - 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters.
18
+ - a66d44b72b: Fixing bug when the workspace would not be automatically saved when using `allowedOwners`
19
+ - 7d47def9c4: Removed dependency on `@types/jest`.
20
+ - 6522e459aa: Support displaying and ordering by counts in `EntityTagPicker` field. Add the `showCounts` option to enable this. Also support configuring `helperText`.
21
+ - f0510a20b5: Addition of a dismissible Error Banner in Scaffolder page
22
+ - 667d917488: Updated dependency `msw` to `^0.47.0`.
23
+ - 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`.
24
+ - 9097278df2: Updated dependency `json-schema-library` to `^7.0.0`.
25
+ - bf5e9030eb: Updated dependency `msw` to `^0.45.0`.
26
+ - de336de9cd: fix uiSchema generation when using complex dependencies
27
+ - Updated dependencies
28
+ - @backstage/core-components@0.11.1
29
+ - @backstage/core-plugin-api@1.0.6
30
+ - @backstage/plugin-catalog-react@1.1.4
31
+ - @backstage/plugin-permission-react@0.4.5
32
+ - @backstage/integration@1.3.1
33
+ - @backstage/catalog-client@1.1.0
34
+ - @backstage/catalog-model@1.1.1
35
+ - @backstage/config@1.0.2
36
+ - @backstage/errors@1.1.1
37
+ - @backstage/integration-react@1.1.4
38
+ - @backstage/plugin-scaffolder-common@1.2.0
39
+ - @backstage/plugin-catalog-common@1.0.6
40
+
3
41
  ## 1.6.0-next.3
4
42
 
5
43
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder",
3
- "version": "1.6.0-next.3",
3
+ "version": "1.6.0",
4
4
  "main": "../dist/index.esm.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -3,7 +3,7 @@ import { useNavigate, Navigate, useOutlet, Routes, Route } from 'react-router';
3
3
  import { ItemCardHeader, MarkdownContent, Button, ContentHeader, Progress, WarningPanel, Link as Link$1, Content, ItemCardGrid, Page, Header, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, ErrorPage, ErrorPanel, LogViewer, StatusError, StatusOK, StatusPending, Lifecycle, EmptyState, Table as Table$1 } from '@backstage/core-components';
4
4
  import { useRouteRef, useApi, errorApiRef, featureFlagsApiRef, useApiHolder, useRouteRefParams, alertApiRef, useElementFilter } from '@backstage/core-plugin-api';
5
5
  import { getEntityRelations, getEntitySourceLocation, FavoriteEntity, EntityRefLinks, useEntityList, EntityListProvider, CatalogFilterLayout, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, catalogApiRef, humanizeEntityRef, EntityRefLink } from '@backstage/plugin-catalog-react';
6
- import { s as selectedTemplateRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, S as SecretsContext, c as scaffolderApiRef, d as scaffolderTaskRouteRef, f as rootRouteRef, g as TaskStatusStepper, h as TaskPageLinks, F as FIELD_EXTENSION_WRAPPER_KEY, i as FIELD_EXTENSION_KEY, l as legacySelectedTemplateRouteRef, j as SecretsContextProvider, k as TaskPage } from './index-3b8e3839.esm.js';
6
+ import { s as selectedTemplateRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, S as SecretsContext, c as scaffolderApiRef, d as scaffolderTaskRouteRef, f as rootRouteRef, g as TaskStatusStepper, h as TaskPageLinks, F as FIELD_EXTENSION_WRAPPER_KEY, i as FIELD_EXTENSION_KEY, L as LAYOUTS_WRAPPER_KEY, j as LAYOUTS_KEY, l as legacySelectedTemplateRouteRef, k as SecretsContextProvider, m as TaskPage } from './index-59f10b07.esm.js';
7
7
  import { RELATION_OWNED_BY, parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
8
8
  import { makeStyles, useTheme, Card, CardMedia, CardContent, Box, Typography, Chip, CardActions, IconButton, Tooltip, Link, Stepper, Step, StepLabel, StepContent, Button as Button$1, Paper, LinearProgress, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Divider as Divider$1, FormControl, InputLabel, Select, MenuItem as MenuItem$1, List as List$2, ListItemIcon as ListItemIcon$1, ListItemText as ListItemText$1 } from '@material-ui/core';
9
9
  import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
@@ -65,7 +65,7 @@ import SettingsIcon from '@material-ui/icons/Settings';
65
65
  import AllIcon from '@material-ui/icons/FontDownload';
66
66
  import { DateTime, Interval } from 'luxon';
67
67
  import humanizeDuration from 'humanize-duration';
68
- import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-77c6fe10.esm.js';
68
+ import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-e3b0d980.esm.js';
69
69
  import '@backstage/errors';
70
70
  import 'zen-observable';
71
71
  import '@material-ui/core/FormControl';
@@ -439,12 +439,22 @@ function extractUiSchema(schema, uiSchema) {
439
439
  }
440
440
  }
441
441
  }
442
- function transformSchemaToProps(inputSchema) {
442
+ function transformSchemaToProps(inputSchema, layouts = []) {
443
+ var _a;
444
+ const customLayoutName = inputSchema["ui:ObjectFieldTemplate"];
443
445
  inputSchema.type = inputSchema.type || "object";
444
446
  const schema = JSON.parse(JSON.stringify(inputSchema));
445
447
  delete schema.title;
446
448
  const uiSchema = {};
447
449
  extractUiSchema(schema, uiSchema);
450
+ if (customLayoutName) {
451
+ const Layout = (_a = layouts.find(
452
+ (layout) => layout.name === customLayoutName
453
+ )) == null ? void 0 : _a.component;
454
+ if (Layout) {
455
+ uiSchema["ui:ObjectFieldTemplate"] = Layout;
456
+ }
457
+ }
448
458
  return { schema, uiSchema };
449
459
  }
450
460
 
@@ -512,7 +522,8 @@ const MultistepJsonForm = (props) => {
512
522
  onFinish,
513
523
  fields,
514
524
  widgets,
515
- finishButtonLabel
525
+ finishButtonLabel,
526
+ layouts
516
527
  } = props;
517
528
  const [activeStep, setActiveStep] = useState(0);
518
529
  const [disableButtons, setDisableButtons] = useState(false);
@@ -597,7 +608,7 @@ const MultistepJsonForm = (props) => {
597
608
  handleNext();
598
609
  },
599
610
  ...formProps,
600
- ...transformSchemaToProps(schema)
611
+ ...transformSchemaToProps(schema, layouts)
601
612
  }, /* @__PURE__ */ React.createElement(Button$1, {
602
613
  disabled: activeStep === 0,
603
614
  onClick: handleBack
@@ -686,7 +697,8 @@ const useTemplateParameterSchema = (templateRef) => {
686
697
  return { schema: value, loading, error };
687
698
  };
688
699
  const TemplatePage = ({
689
- customFieldExtensions = []
700
+ customFieldExtensions = [],
701
+ layouts = []
690
702
  }) => {
691
703
  const apiHolder = useApiHolder();
692
704
  const secretsContext = useContext(SecretsContext);
@@ -771,6 +783,7 @@ const TemplatePage = ({
771
783
  onChange: handleChange,
772
784
  onReset: handleFormReset,
773
785
  onFinish: handleCreate,
786
+ layouts,
774
787
  steps: schema.steps.map((step) => {
775
788
  return {
776
789
  ...step,
@@ -1763,7 +1776,8 @@ function TemplateEditorForm(props) {
1763
1776
  onUpdate,
1764
1777
  onDryRun,
1765
1778
  setErrorText,
1766
- fieldExtensions = []
1779
+ fieldExtensions = [],
1780
+ layouts = []
1767
1781
  } = props;
1768
1782
  const classes = useStyles$4();
1769
1783
  const apiHolder = useApiHolder();
@@ -1841,7 +1855,8 @@ function TemplateEditorForm(props) {
1841
1855
  onChange: (e) => onUpdate(e.formData),
1842
1856
  onReset: () => onUpdate({}),
1843
1857
  finishButtonLabel: onDryRun && "Try It",
1844
- onFinish: onDryRun && (() => onDryRun(data))
1858
+ onFinish: onDryRun && (() => onDryRun(data)),
1859
+ layouts
1845
1860
  }))));
1846
1861
  }
1847
1862
  function TemplateEditorFormDirectoryEditorDryRun(props) {
@@ -2022,7 +2037,8 @@ const TemplateEditor = (props) => {
2022
2037
  className: classes.preview
2023
2038
  }, /* @__PURE__ */ React.createElement(TemplateEditorForm.DirectoryEditorDryRun, {
2024
2039
  setErrorText,
2025
- fieldExtensions: props.fieldExtensions
2040
+ fieldExtensions: props.fieldExtensions,
2041
+ layouts: props.layouts
2026
2042
  })), /* @__PURE__ */ React.createElement("section", {
2027
2043
  className: classes.results
2028
2044
  }, /* @__PURE__ */ React.createElement(DryRunResults, null)))));
@@ -2094,7 +2110,8 @@ const useStyles$1 = makeStyles((theme) => ({
2094
2110
  const TemplateFormPreviewer = ({
2095
2111
  defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,
2096
2112
  customFieldExtensions = [],
2097
- onClose
2113
+ onClose,
2114
+ layouts = []
2098
2115
  }) => {
2099
2116
  const classes = useStyles$1();
2100
2117
  const alertApi = useApi(alertApiRef);
@@ -2176,7 +2193,8 @@ const TemplateFormPreviewer = ({
2176
2193
  fieldExtensions: customFieldExtensions,
2177
2194
  data: formState,
2178
2195
  onUpdate: setFormState,
2179
- setErrorText
2196
+ setErrorText,
2197
+ layouts
2180
2198
  }))));
2181
2199
  };
2182
2200
 
@@ -2187,13 +2205,15 @@ function TemplateEditorPage(props) {
2187
2205
  content = /* @__PURE__ */ React.createElement(TemplateEditor, {
2188
2206
  directory: selection.directory,
2189
2207
  fieldExtensions: props.customFieldExtensions,
2190
- onClose: () => setSelection(void 0)
2208
+ onClose: () => setSelection(void 0),
2209
+ layouts: props.layouts
2191
2210
  });
2192
2211
  } else if ((selection == null ? void 0 : selection.type) === "form") {
2193
2212
  content = /* @__PURE__ */ React.createElement(TemplateFormPreviewer, {
2194
2213
  defaultPreviewTemplate: props.defaultPreviewTemplate,
2195
2214
  customFieldExtensions: props.customFieldExtensions,
2196
- onClose: () => setSelection(void 0)
2215
+ onClose: () => setSelection(void 0),
2216
+ layouts: props.layouts
2197
2217
  });
2198
2218
  } else {
2199
2219
  content = /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(TemplateEditorIntro, {
@@ -2461,6 +2481,14 @@ const Router = (props) => {
2461
2481
  )
2462
2482
  )
2463
2483
  ];
2484
+ const customLayouts = useElementFilter(
2485
+ outlet,
2486
+ (elements) => elements.selectByComponentData({
2487
+ key: LAYOUTS_WRAPPER_KEY
2488
+ }).findComponentData({
2489
+ key: LAYOUTS_KEY
2490
+ })
2491
+ );
2464
2492
  const RedirectingComponent = () => {
2465
2493
  const { templateName } = useRouteRefParams(legacySelectedTemplateRouteRef);
2466
2494
  const newLink = useRouteRef(selectedTemplateRouteRef);
@@ -2487,7 +2515,8 @@ const Router = (props) => {
2487
2515
  }), /* @__PURE__ */ React.createElement(Route, {
2488
2516
  path: selectedTemplateRouteRef.path,
2489
2517
  element: /* @__PURE__ */ React.createElement(SecretsContextProvider, null, /* @__PURE__ */ React.createElement(TemplatePage, {
2490
- customFieldExtensions: fieldExtensions
2518
+ customFieldExtensions: fieldExtensions,
2519
+ layouts: customLayouts
2491
2520
  }))
2492
2521
  }), /* @__PURE__ */ React.createElement(Route, {
2493
2522
  path: scaffolderListTaskRouteRef.path,
@@ -2502,7 +2531,8 @@ const Router = (props) => {
2502
2531
  path: editRouteRef.path,
2503
2532
  element: /* @__PURE__ */ React.createElement(SecretsContextProvider, null, /* @__PURE__ */ React.createElement(TemplateEditorPage, {
2504
2533
  defaultPreviewTemplate,
2505
- customFieldExtensions: fieldExtensions
2534
+ customFieldExtensions: fieldExtensions,
2535
+ layouts: customLayouts
2506
2536
  }))
2507
2537
  }), /* @__PURE__ */ React.createElement(Route, {
2508
2538
  path: "preview",
@@ -2513,4 +2543,4 @@ const Router = (props) => {
2513
2543
  };
2514
2544
 
2515
2545
  export { Router };
2516
- //# sourceMappingURL=Router-7a18bcf2.esm.js.map
2546
+ //# sourceMappingURL=Router-ad1d6fa2.esm.js.map