@backstage/plugin-scaffolder 1.6.0 → 1.7.0-next.1

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,55 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.7.0-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - e4f0a96424: Making the description of the GitLab repoUrl owner field more clearer by focusing it refers to the GitLab namespace.
8
+ - 8220f2fd83: Support custom layouts in dry run editor
9
+ - Updated dependencies
10
+ - @backstage/plugin-catalog-react@1.2.0-next.1
11
+ - @backstage/catalog-client@1.1.1-next.1
12
+ - @backstage/core-components@0.11.2-next.1
13
+ - @backstage/core-plugin-api@1.0.7-next.1
14
+ - @backstage/catalog-model@1.1.2-next.1
15
+ - @backstage/config@1.0.3-next.1
16
+ - @backstage/errors@1.1.2-next.1
17
+ - @backstage/integration@1.3.2-next.1
18
+ - @backstage/integration-react@1.1.5-next.1
19
+ - @backstage/theme@0.2.16
20
+ - @backstage/types@1.0.0
21
+ - @backstage/plugin-catalog-common@1.0.7-next.1
22
+ - @backstage/plugin-permission-react@0.4.6-next.1
23
+ - @backstage/plugin-scaffolder-common@1.2.1-next.1
24
+
25
+ ## 1.7.0-next.0
26
+
27
+ ### Minor Changes
28
+
29
+ - f13d5f3f06: Add support for link to TechDocs and other links defined in template entity specification metadata on TemplateCard
30
+ - 05f22193c5: EntityPickers now support flags to control when to include default namespace
31
+ in result
32
+
33
+ ### Patch Changes
34
+
35
+ - 8960d83013: Add support for `allowedOrganizations` and `allowedOwners` to the `AzureRepoPicker`.
36
+ - b681275e69: Ignore .git directories in Template Editor, increase upload limit for dry-runs to 10MB.
37
+ - Updated dependencies
38
+ - @backstage/catalog-model@1.1.2-next.0
39
+ - @backstage/core-components@0.11.2-next.0
40
+ - @backstage/catalog-client@1.1.1-next.0
41
+ - @backstage/plugin-catalog-react@1.1.5-next.0
42
+ - @backstage/plugin-scaffolder-common@1.2.1-next.0
43
+ - @backstage/integration-react@1.1.5-next.0
44
+ - @backstage/config@1.0.3-next.0
45
+ - @backstage/core-plugin-api@1.0.7-next.0
46
+ - @backstage/errors@1.1.2-next.0
47
+ - @backstage/integration@1.3.2-next.0
48
+ - @backstage/theme@0.2.16
49
+ - @backstage/types@1.0.0
50
+ - @backstage/plugin-catalog-common@1.0.7-next.0
51
+ - @backstage/plugin-permission-react@0.4.6-next.0
52
+
3
53
  ## 1.6.0
4
54
 
5
55
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder",
3
- "version": "1.6.0",
3
+ "version": "1.7.0-next.1",
4
4
  "main": "../dist/index.esm.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -1,12 +1,13 @@
1
1
  import React, { useState, useContext, useCallback, createContext, useEffect, useRef, useMemo, Children, Component, Fragment } from 'react';
2
2
  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
- import { useRouteRef, useApi, errorApiRef, featureFlagsApiRef, useApiHolder, useRouteRefParams, alertApiRef, useElementFilter } from '@backstage/core-plugin-api';
4
+ import { useApp, 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 LAYOUTS_WRAPPER_KEY, j as LAYOUTS_KEY, l as legacySelectedTemplateRouteRef, k as SecretsContextProvider, m as TaskPage } from './index-59f10b07.esm.js';
7
- import { RELATION_OWNED_BY, parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
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';
6
+ import { s as selectedTemplateRouteRef, v as viewTechDocRouteRef, 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-d658652f.esm.js';
7
+ import { RELATION_OWNED_BY, parseEntityRef, stringifyEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
8
+ import { makeStyles, useTheme, Card, CardMedia, CardContent, Box, Typography, Chip, CardActions, Tooltip, IconButton, 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';
10
+ import LanguageIcon from '@material-ui/icons/Language';
10
11
  import WarningIcon from '@material-ui/icons/Warning';
11
12
  import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';
12
13
  import { usePermission } from '@backstage/plugin-permission-react';
@@ -65,7 +66,7 @@ import SettingsIcon from '@material-ui/icons/Settings';
65
66
  import AllIcon from '@material-ui/icons/FontDownload';
66
67
  import { DateTime, Interval } from 'luxon';
67
68
  import humanizeDuration from 'humanize-duration';
68
- import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-e3b0d980.esm.js';
69
+ import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-93ca10ec.esm.js';
69
70
  import '@backstage/errors';
70
71
  import 'zen-observable';
71
72
  import '@material-ui/core/FormControl';
@@ -85,7 +86,6 @@ import '@material-ui/core/Stepper';
85
86
  import '@material-ui/icons/FiberManualRecord';
86
87
  import 'react-use/lib/useInterval';
87
88
  import 'use-immer';
88
- import '@material-ui/icons/Language';
89
89
 
90
90
  const useStyles$e = makeStyles((theme) => ({
91
91
  cardHeader: {
@@ -99,8 +99,7 @@ const useStyles$e = makeStyles((theme) => ({
99
99
  textOverflow: "ellipsis",
100
100
  display: "-webkit-box",
101
101
  "-webkit-line-clamp": 10,
102
- "-webkit-box-orient": "vertical",
103
- paddingBottom: "0.8em"
102
+ "-webkit-box-orient": "vertical"
104
103
  },
105
104
  label: {
106
105
  color: theme.palette.text.secondary,
@@ -111,6 +110,14 @@ const useStyles$e = makeStyles((theme) => ({
111
110
  lineHeight: 1,
112
111
  paddingBottom: "0.2rem"
113
112
  },
113
+ linksLabel: {
114
+ padding: "0 16px"
115
+ },
116
+ description: {
117
+ "& p": {
118
+ margin: "0px"
119
+ }
120
+ },
114
121
  leftButton: {
115
122
  marginRight: "auto"
116
123
  },
@@ -122,6 +129,7 @@ const useStyles$e = makeStyles((theme) => ({
122
129
  color: "#fff"
123
130
  }
124
131
  }));
132
+ const MuiIcon = ({ icon: Icon }) => /* @__PURE__ */ React.createElement(Icon, null);
125
133
  const useDeprecationStyles = makeStyles((theme) => ({
126
134
  deprecationIcon: {
127
135
  position: "absolute",
@@ -134,14 +142,15 @@ const useDeprecationStyles = makeStyles((theme) => ({
134
142
  }
135
143
  }));
136
144
  const getTemplateCardProps = (template) => {
137
- var _a, _b, _c, _d, _e;
145
+ var _a, _b, _c, _d, _e, _f;
138
146
  return {
139
147
  key: template.metadata.uid,
140
148
  name: template.metadata.name,
141
149
  title: `${(_a = template.metadata.title || template.metadata.name) != null ? _a : ""}`,
142
150
  type: (_b = template.spec.type) != null ? _b : "",
143
151
  description: (_c = template.metadata.description) != null ? _c : "-",
144
- tags: (_e = (_d = template.metadata) == null ? void 0 : _d.tags) != null ? _e : []
152
+ tags: (_e = (_d = template.metadata) == null ? void 0 : _d.tags) != null ? _e : [],
153
+ links: (_f = template.metadata.links) != null ? _f : []
145
154
  };
146
155
  };
147
156
  const DeprecationWarning = () => {
@@ -159,7 +168,8 @@ const DeprecationWarning = () => {
159
168
  }, /* @__PURE__ */ React.createElement(WarningIcon, null))));
160
169
  };
161
170
  const TemplateCard = ({ template, deprecated }) => {
162
- var _a;
171
+ var _a, _b, _c;
172
+ const app = useApp();
163
173
  const backstageTheme = useTheme();
164
174
  const templateRoute = useRouteRef(selectedTemplateRouteRef);
165
175
  const templateProps = getTemplateCardProps(template);
@@ -172,6 +182,17 @@ const TemplateCard = ({ template, deprecated }) => {
172
182
  const classes = useStyles$e({ backgroundImage: theme.backgroundImage });
173
183
  const { name, namespace } = parseEntityRef(stringifyEntityRef(template));
174
184
  const href = templateRoute({ templateName: name, namespace });
185
+ const viewTechDoc = useRouteRef(viewTechDocRouteRef);
186
+ const viewTechDocsAnnotation = (_a = template.metadata.annotations) == null ? void 0 : _a["backstage.io/techdocs-ref"];
187
+ const viewTechDocsLink = !!viewTechDocsAnnotation && !!viewTechDoc && viewTechDoc({
188
+ namespace: template.metadata.namespace || DEFAULT_NAMESPACE,
189
+ kind: template.kind,
190
+ name: template.metadata.name
191
+ });
192
+ const iconResolver = (key) => {
193
+ var _a2;
194
+ return key ? (_a2 = app.getSystemIcon(key)) != null ? _a2 : LanguageIcon : LanguageIcon;
195
+ };
175
196
  const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
176
197
  const sourceLocation = getEntitySourceLocation(template, scmIntegrationsApi);
177
198
  return /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(CardMedia, {
@@ -184,13 +205,14 @@ const TemplateCard = ({ template, deprecated }) => {
184
205
  subtitle: templateProps.type,
185
206
  classes: { root: classes.title }
186
207
  })), /* @__PURE__ */ React.createElement(CardContent, {
187
- style: { display: "grid" }
208
+ style: { display: "flex", flexDirection: "column", gap: "16px" }
188
209
  }, /* @__PURE__ */ React.createElement(Box, {
189
210
  className: classes.box
190
211
  }, /* @__PURE__ */ React.createElement(Typography, {
191
212
  variant: "body2",
192
213
  className: classes.label
193
214
  }, "Description"), /* @__PURE__ */ React.createElement(MarkdownContent, {
215
+ className: classes.description,
194
216
  content: templateProps.description
195
217
  })), /* @__PURE__ */ React.createElement(Box, {
196
218
  className: classes.box
@@ -201,18 +223,41 @@ const TemplateCard = ({ template, deprecated }) => {
201
223
  entityRefs: ownedByRelations,
202
224
  defaultKind: "Group"
203
225
  })), /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Typography, {
226
+ style: { marginBottom: "4px" },
204
227
  variant: "body2",
205
228
  className: classes.label
206
- }, "Tags"), (_a = templateProps.tags) == null ? void 0 : _a.map((tag) => /* @__PURE__ */ React.createElement(Chip, {
229
+ }, "Tags"), (_b = templateProps.tags) == null ? void 0 : _b.map((tag) => /* @__PURE__ */ React.createElement(Chip, {
207
230
  size: "small",
208
231
  label: tag,
209
232
  key: tag
210
- })))), /* @__PURE__ */ React.createElement(CardActions, null, sourceLocation && /* @__PURE__ */ React.createElement(IconButton, {
233
+ })))), /* @__PURE__ */ React.createElement(Typography, {
234
+ variant: "body2",
235
+ className: [classes.label, classes.linksLabel].join(" ")
236
+ }, "Links"), /* @__PURE__ */ React.createElement(CardActions, null, /* @__PURE__ */ React.createElement("div", {
237
+ className: classes.leftButton
238
+ }, sourceLocation && /* @__PURE__ */ React.createElement(Tooltip, {
239
+ title: sourceLocation.integrationType || sourceLocation.locationTargetUrl
240
+ }, /* @__PURE__ */ React.createElement(IconButton, {
211
241
  className: classes.leftButton,
212
242
  href: sourceLocation.locationTargetUrl
213
243
  }, /* @__PURE__ */ React.createElement(ScmIntegrationIcon, {
214
244
  type: sourceLocation.integrationType
215
- })), /* @__PURE__ */ React.createElement(Button, {
245
+ }))), viewTechDocsLink && /* @__PURE__ */ React.createElement(Tooltip, {
246
+ title: "View TechDocs"
247
+ }, /* @__PURE__ */ React.createElement(IconButton, {
248
+ className: classes.leftButton,
249
+ href: viewTechDocsLink
250
+ }, /* @__PURE__ */ React.createElement(MuiIcon, {
251
+ icon: iconResolver("docs")
252
+ }))), (_c = templateProps.links) == null ? void 0 : _c.map((link, i) => /* @__PURE__ */ React.createElement(Tooltip, {
253
+ key: `${link.url}_${i}`,
254
+ title: link.title || link.url
255
+ }, /* @__PURE__ */ React.createElement(IconButton, {
256
+ size: "medium",
257
+ href: link.url
258
+ }, /* @__PURE__ */ React.createElement(MuiIcon, {
259
+ icon: iconResolver(link.icon)
260
+ }))))), /* @__PURE__ */ React.createElement(Button, {
216
261
  color: "primary",
217
262
  to: href,
218
263
  "aria-label": `Choose ${templateProps.title}`
@@ -936,6 +981,9 @@ class WebDirectoryAccess {
936
981
  if (handle.kind === "file") {
937
982
  yield new WebFileAccess([...basePath, handle.name].join("/"), handle);
938
983
  } else if (handle.kind === "directory") {
984
+ if (handle.name === ".git") {
985
+ continue;
986
+ }
939
987
  yield* this.listDirectoryContents(handle, [...basePath, handle.name]);
940
988
  }
941
989
  }
@@ -1860,7 +1908,7 @@ function TemplateEditorForm(props) {
1860
1908
  }))));
1861
1909
  }
1862
1910
  function TemplateEditorFormDirectoryEditorDryRun(props) {
1863
- const { setErrorText, fieldExtensions = [] } = props;
1911
+ const { setErrorText, fieldExtensions = [], layouts } = props;
1864
1912
  const dryRun = useDryRun();
1865
1913
  const directoryEditor = useDirectoryEditor();
1866
1914
  const { selectedFile } = directoryEditor;
@@ -1888,7 +1936,8 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
1888
1936
  setErrorText,
1889
1937
  content,
1890
1938
  data,
1891
- onUpdate: setData
1939
+ onUpdate: setData,
1940
+ layouts
1892
1941
  });
1893
1942
  }
1894
1943
  TemplateEditorForm.DirectoryEditorDryRun = TemplateEditorFormDirectoryEditorDryRun;
@@ -2543,4 +2592,4 @@ const Router = (props) => {
2543
2592
  };
2544
2593
 
2545
2594
  export { Router };
2546
- //# sourceMappingURL=Router-ad1d6fa2.esm.js.map
2595
+ //# sourceMappingURL=Router-825957a6.esm.js.map