@backstage/plugin-scaffolder 0.11.13 → 0.11.14

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,19 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 0.11.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 6845cce533: Can specify allowedOwners to the RepoUrlPicker picker in a template definition
8
+ - cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
9
+ - 2edcf7738f: Fix bug with setting owner in RepoUrlPicker causing validation failure
10
+ - b291c3176e: Switch to using `LogViewer` component from `@backstage/core-components` to display scaffolder logs.
11
+ - Updated dependencies
12
+ - @backstage/core-components@0.8.0
13
+ - @backstage/core-plugin-api@0.3.0
14
+ - @backstage/integration-react@0.1.15
15
+ - @backstage/plugin-catalog-react@0.6.5
16
+
3
17
  ## 0.11.13
4
18
 
5
19
  ### Patch Changes
@@ -1,10 +1,10 @@
1
- import React, { useState, useCallback, useEffect, memo, Suspense, useMemo } from 'react';
1
+ import React, { useState, useCallback, useEffect, memo, useMemo } from 'react';
2
2
  import { useNavigate, Navigate, generatePath, useParams as useParams$1, useOutlet, Routes, Route } from 'react-router';
3
- import { Page, Header, Lifecycle, Content, ContentHeader, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, Link, Progress, ErrorPage } from '@backstage/core-components';
3
+ import { Page, Header, Lifecycle, Content, ContentHeader, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, Link, ErrorPage, LogViewer, Progress } from '@backstage/core-components';
4
4
  import { useRouteRef, useApi, errorApiRef, useApiHolder, useApp, useElementFilter } from '@backstage/core-plugin-api';
5
5
  import { EntityListProvider, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, entityRouteRef } from '@backstage/plugin-catalog-react';
6
6
  import { makeStyles, Stepper, Step, StepLabel, Typography, StepContent, Button, Paper, Box, LinearProgress, Grid, StepButton, CircularProgress, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from '@material-ui/core';
7
- import { E as EntityPicker, a as EntityNamePicker, e as entityNamePickerValidation, R as RepoUrlPicker, r as repoPickerValidation, O as OwnerPicker, b as registerComponentRouteRef, T as TemplateTypePicker, c as TemplateList, s as scaffolderApiRef, d as rootRouteRef, F as FIELD_EXTENSION_WRAPPER_KEY, f as FIELD_EXTENSION_KEY } from './index-385b3fc1.esm.js';
7
+ import { E as EntityPicker, a as EntityNamePicker, e as entityNamePickerValidation, R as RepoUrlPicker, r as repoPickerValidation, O as OwnerPicker, b as registerComponentRouteRef, T as TemplateTypePicker, c as TemplateList, s as scaffolderApiRef, d as rootRouteRef, F as FIELD_EXTENSION_WRAPPER_KEY, f as FIELD_EXTENSION_KEY } from './index-306a8b5a.esm.js';
8
8
  import { useParams } from 'react-router-dom';
9
9
  import { useAsync, useInterval } from 'react-use';
10
10
  import { withTheme } from '@rjsf/core';
@@ -128,7 +128,7 @@ function extractUiSchema(schema, uiSchema) {
128
128
  if (!isObject$1(schema)) {
129
129
  return;
130
130
  }
131
- const {properties, items, anyOf, oneOf, allOf, dependencies} = schema;
131
+ const { properties, items, anyOf, oneOf, allOf, dependencies } = schema;
132
132
  for (const propName in schema) {
133
133
  if (!schema.hasOwnProperty(propName)) {
134
134
  continue;
@@ -197,7 +197,7 @@ function transformSchemaToProps(inputSchema) {
197
197
  delete schema.title;
198
198
  const uiSchema = {};
199
199
  extractUiSchema(schema, uiSchema);
200
- return {schema, uiSchema};
200
+ return { schema, uiSchema };
201
201
  }
202
202
 
203
203
  const Form = withTheme(Theme);
@@ -278,7 +278,7 @@ const MultistepJsonForm = ({
278
278
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Stepper, {
279
279
  activeStep,
280
280
  orientation: "vertical"
281
- }, steps.map(({title, schema, ...formProps}, index) => {
281
+ }, steps.map(({ title, schema, ...formProps }, index) => {
282
282
  return /* @__PURE__ */ React.createElement(Step, {
283
283
  key: title
284
284
  }, /* @__PURE__ */ React.createElement(StepLabel, {
@@ -337,12 +337,12 @@ const MultistepJsonForm = ({
337
337
 
338
338
  const useTemplateParameterSchema = (templateName) => {
339
339
  const scaffolderApi = useApi(scaffolderApiRef);
340
- const {value, loading, error} = useAsync(() => scaffolderApi.getTemplateParameterSchema({
340
+ const { value, loading, error } = useAsync(() => scaffolderApi.getTemplateParameterSchema({
341
341
  name: templateName,
342
342
  kind: "template",
343
343
  namespace: "default"
344
344
  }), [scaffolderApi, templateName]);
345
- return {schema: value, loading, error};
345
+ return { schema: value, loading, error };
346
346
  };
347
347
  function isObject(obj) {
348
348
  return typeof obj === "object" && obj !== null && !Array.isArray(obj);
@@ -380,16 +380,16 @@ const TemplatePage = ({
380
380
  const apiHolder = useApiHolder();
381
381
  const errorApi = useApi(errorApiRef);
382
382
  const scaffolderApi = useApi(scaffolderApiRef);
383
- const {templateName} = useParams();
383
+ const { templateName } = useParams();
384
384
  const navigate = useNavigate();
385
385
  const rootLink = useRouteRef(rootRouteRef);
386
- const {schema, loading, error} = useTemplateParameterSchema(templateName);
386
+ const { schema, loading, error } = useTemplateParameterSchema(templateName);
387
387
  const [formState, setFormState] = useState({});
388
388
  const handleFormReset = () => setFormState({});
389
389
  const handleChange = useCallback((e) => setFormState(e.formData), [setFormState]);
390
390
  const handleCreate = async () => {
391
391
  const id = await scaffolderApi.scaffold(templateName, formState);
392
- navigate(generatePath(`${rootLink()}/tasks/:taskId`, {taskId: id}));
392
+ navigate(generatePath(`${rootLink()}/tasks/:taskId`, { taskId: id }));
393
393
  };
394
394
  if (error) {
395
395
  errorApi.post(new Error(`Failed to load template, ${error}`));
@@ -403,8 +403,8 @@ const TemplatePage = ({
403
403
  to: rootLink()
404
404
  });
405
405
  }
406
- const customFieldComponents = Object.fromEntries(customFieldExtensions.map(({name, component}) => [name, component]));
407
- const customFieldValidators = Object.fromEntries(customFieldExtensions.map(({name, validation}) => [name, validation]));
406
+ const customFieldComponents = Object.fromEntries(customFieldExtensions.map(({ name, component }) => [name, component]));
407
+ const customFieldValidators = Object.fromEntries(customFieldExtensions.map(({ name, validation }) => [name, validation]));
408
408
  return /* @__PURE__ */ React.createElement(Page, {
409
409
  themeId: "home"
410
410
  }, /* @__PURE__ */ React.createElement(Header, {
@@ -418,7 +418,7 @@ const TemplatePage = ({
418
418
  }), schema && /* @__PURE__ */ React.createElement(InfoCard, {
419
419
  title: schema.title,
420
420
  noPadding: true,
421
- titleTypographyProps: {component: "h2"}
421
+ titleTypographyProps: { component: "h2" }
422
422
  }, /* @__PURE__ */ React.createElement(MultistepJsonForm, {
423
423
  formData: formState,
424
424
  fields: customFieldComponents,
@@ -428,7 +428,7 @@ const TemplatePage = ({
428
428
  steps: schema.steps.map((step) => {
429
429
  return {
430
430
  ...step,
431
- validate: createValidator(step.schema, customFieldValidators, {apiHolder})
431
+ validate: createValidator(step.schema, customFieldValidators, { apiHolder })
432
432
  };
433
433
  })
434
434
  }))));
@@ -439,7 +439,7 @@ function reducer(draft, action) {
439
439
  switch (action.type) {
440
440
  case "INIT": {
441
441
  draft.steps = action.data.spec.steps.reduce((current, next) => {
442
- current[next.id] = {status: "open", id: next.id};
442
+ current[next.id] = { status: "open", id: next.id };
443
443
  return current;
444
444
  }, {});
445
445
  draft.stepLogs = action.data.spec.steps.reduce((current, next) => {
@@ -505,13 +505,13 @@ const useTaskEventStream = (taskId) => {
505
505
  if (didCancel) {
506
506
  return;
507
507
  }
508
- dispatch({type: "INIT", data: task});
509
- const observable = scaffolderApi.streamLogs({taskId});
508
+ dispatch({ type: "INIT", data: task });
509
+ const observable = scaffolderApi.streamLogs({ taskId });
510
510
  const collectedLogEvents = new Array();
511
511
  function emitLogs() {
512
512
  if (collectedLogEvents.length) {
513
513
  const logs = collectedLogEvents.splice(0, collectedLogEvents.length);
514
- dispatch({type: "LOGS", data: logs});
514
+ dispatch({ type: "LOGS", data: logs });
515
515
  }
516
516
  }
517
517
  logPusher = setInterval(emitLogs, 500);
@@ -522,7 +522,7 @@ const useTaskEventStream = (taskId) => {
522
522
  return collectedLogEvents.push(event);
523
523
  case "completion":
524
524
  emitLogs();
525
- dispatch({type: "COMPLETED", data: event});
525
+ dispatch({ type: "COMPLETED", data: event });
526
526
  return void 0;
527
527
  default:
528
528
  throw new Error(`Unhandled event type ${event.type} in observer`);
@@ -530,12 +530,12 @@ const useTaskEventStream = (taskId) => {
530
530
  },
531
531
  error: (error) => {
532
532
  emitLogs();
533
- dispatch({type: "ERROR", data: error});
533
+ dispatch({ type: "ERROR", data: error });
534
534
  }
535
535
  });
536
536
  }, (error) => {
537
537
  if (!didCancel) {
538
- dispatch({type: "ERROR", data: error});
538
+ dispatch({ type: "ERROR", data: error });
539
539
  }
540
540
  });
541
541
  return () => {
@@ -562,7 +562,7 @@ const useStyles$2 = makeStyles({
562
562
  }
563
563
  });
564
564
  const IconLink = (props) => {
565
- const {href, text, Icon, ...linkProps} = props;
565
+ const { href, text, Icon, ...linkProps } = props;
566
566
  const classes = useStyles$2();
567
567
  return /* @__PURE__ */ React.createElement(Grid, {
568
568
  container: true,
@@ -581,9 +581,9 @@ const IconLink = (props) => {
581
581
  }, text || href)));
582
582
  };
583
583
 
584
- const TaskPageLinks = ({output}) => {
585
- const {entityRef: entityRefOutput, remoteUrl} = output;
586
- let {links = []} = output;
584
+ const TaskPageLinks = ({ output }) => {
585
+ const { entityRef: entityRefOutput, remoteUrl } = output;
586
+ let { links = [] } = output;
587
587
  const app = useApp();
588
588
  const entityRoute = useRouteRef(entityRouteRef);
589
589
  const iconResolver = (key) => {
@@ -591,7 +591,7 @@ const TaskPageLinks = ({output}) => {
591
591
  return key ? (_a = app.getSystemIcon(key)) != null ? _a : LanguageIcon : LanguageIcon;
592
592
  };
593
593
  if (remoteUrl) {
594
- links = [{url: remoteUrl, title: "Repo"}, ...links];
594
+ links = [{ url: remoteUrl, title: "Repo" }, ...links];
595
595
  }
596
596
  if (entityRefOutput) {
597
597
  links = [
@@ -606,14 +606,14 @@ const TaskPageLinks = ({output}) => {
606
606
  return /* @__PURE__ */ React.createElement(Box, {
607
607
  px: 3,
608
608
  pb: 3
609
- }, links.filter(({url, entityRef}) => url || entityRef).map(({url, entityRef, title, icon}) => {
609
+ }, links.filter(({ url, entityRef }) => url || entityRef).map(({ url, entityRef, title, icon }) => {
610
610
  if (entityRef) {
611
611
  const entityName = parseEntityName(entityRef);
612
612
  const target = entityRoute(entityName);
613
- return {title, icon, url: target};
613
+ return { title, icon, url: target };
614
614
  }
615
- return {title, icon, url};
616
- }).map(({url, title, icon}, i) => /* @__PURE__ */ React.createElement(IconLink, {
615
+ return { title, icon, url };
616
+ }).map(({ url, title, icon }, i) => /* @__PURE__ */ React.createElement(IconLink, {
617
617
  key: `output-link-${i}`,
618
618
  href: url,
619
619
  text: title != null ? title : url,
@@ -622,7 +622,6 @@ const TaskPageLinks = ({output}) => {
622
622
  })));
623
623
  };
624
624
 
625
- const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog'));
626
625
  const humanizeDuration = require("humanize-duration");
627
626
  const useStyles$1 = makeStyles$1((theme) => createStyles({
628
627
  root: {
@@ -648,7 +647,7 @@ const useStyles$1 = makeStyles$1((theme) => createStyles({
648
647
  width: "100%"
649
648
  }
650
649
  }));
651
- const StepTimeTicker = ({step}) => {
650
+ const StepTimeTicker = ({ step }) => {
652
651
  const [time, setTime] = useState("");
653
652
  useInterval(() => {
654
653
  if (!step.startedAt) {
@@ -658,7 +657,7 @@ const StepTimeTicker = ({step}) => {
658
657
  const end = step.endedAt ? DateTime.fromISO(step.endedAt) : DateTime.local();
659
658
  const startedAt = DateTime.fromISO(step.startedAt);
660
659
  const formatted = Interval.fromDateTimes(startedAt, end).toDuration().valueOf();
661
- setTime(humanizeDuration(formatted, {round: true}));
660
+ setTime(humanizeDuration(formatted, { round: true }));
662
661
  }, 1e3);
663
662
  return /* @__PURE__ */ React.createElement(Typography$1, {
664
663
  variant: "caption"
@@ -680,7 +679,7 @@ const useStepIconStyles = makeStyles$1((theme) => createStyles({
680
679
  }));
681
680
  function TaskStepIconComponent(props) {
682
681
  const classes = useStepIconStyles();
683
- const {active, completed, error} = props;
682
+ const { active, completed, error } = props;
684
683
  const getMiddle = () => {
685
684
  if (active) {
686
685
  return /* @__PURE__ */ React.createElement(CircularProgress, {
@@ -743,24 +742,11 @@ const TaskStatusStepper = memo(({
743
742
  })))));
744
743
  })));
745
744
  });
746
- const TaskLogger = memo(({log}) => {
747
- return /* @__PURE__ */ React.createElement(Suspense, {
748
- fallback: /* @__PURE__ */ React.createElement(Progress, null)
749
- }, /* @__PURE__ */ React.createElement("div", {
750
- style: {height: "80vh"}
751
- }, /* @__PURE__ */ React.createElement(LazyLog, {
752
- text: log,
753
- extraLines: 1,
754
- follow: true,
755
- selectableLines: true,
756
- enableSearch: true
757
- })));
758
- });
759
- const hasLinks = ({entityRef, remoteUrl, links = []}) => !!(entityRef || remoteUrl || links.length > 0);
745
+ const hasLinks = ({ entityRef, remoteUrl, links = [] }) => !!(entityRef || remoteUrl || links.length > 0);
760
746
  const TaskPage = () => {
761
747
  const [userSelectedStepId, setUserSelectedStepId] = useState(void 0);
762
748
  const [lastActiveStepId, setLastActiveStepId] = useState(void 0);
763
- const {taskId} = useParams$1();
749
+ const { taskId } = useParams$1();
764
750
  const taskStream = useTaskEventStream(taskId);
765
751
  const completed = taskStream.completed;
766
752
  const steps = useMemo(() => {
@@ -794,7 +780,7 @@ const TaskPage = () => {
794
780
  return log.join("\n");
795
781
  }, [taskStream.stepLogs, currentStepId]);
796
782
  const taskNotFound = taskStream.completed === true && taskStream.loading === false && !taskStream.task;
797
- const {output} = taskStream;
783
+ const { output } = taskStream;
798
784
  return /* @__PURE__ */ React.createElement(Page, {
799
785
  themeId: "home"
800
786
  }, /* @__PURE__ */ React.createElement(Header, {
@@ -822,9 +808,11 @@ const TaskPage = () => {
822
808
  }))), /* @__PURE__ */ React.createElement(Grid$1, {
823
809
  item: true,
824
810
  xs: 9
825
- }, /* @__PURE__ */ React.createElement(TaskLogger, {
826
- log: logAsString
827
- }))))));
811
+ }, /* @__PURE__ */ React.createElement("div", {
812
+ style: { height: "80vh" }
813
+ }, /* @__PURE__ */ React.createElement(LogViewer, {
814
+ text: logAsString
815
+ })))))));
828
816
  };
829
817
 
830
818
  const useStyles = makeStyles((theme) => ({
@@ -851,7 +839,7 @@ const useStyles = makeStyles((theme) => ({
851
839
  const ActionsPage = () => {
852
840
  const api = useApi(scaffolderApiRef);
853
841
  const classes = useStyles();
854
- const {loading, value, error} = useAsync(async () => {
842
+ const { loading, value, error } = useAsync(async () => {
855
843
  return api.listActions();
856
844
  });
857
845
  if (loading) {
@@ -935,7 +923,7 @@ const ActionsPage = () => {
935
923
  }), /* @__PURE__ */ React.createElement(Content, null, items));
936
924
  };
937
925
 
938
- const Router = ({TemplateCardComponent, groups}) => {
926
+ const Router = ({ TemplateCardComponent, groups }) => {
939
927
  const outlet = useOutlet();
940
928
  const customFieldExtensions = useElementFilter(outlet, (elements) => elements.selectByComponentData({
941
929
  key: FIELD_EXTENSION_WRAPPER_KEY
@@ -944,7 +932,7 @@ const Router = ({TemplateCardComponent, groups}) => {
944
932
  }));
945
933
  const fieldExtensions = [
946
934
  ...customFieldExtensions,
947
- ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(({name}) => !customFieldExtensions.some((customFieldExtension) => customFieldExtension.name === name))
935
+ ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(({ name }) => !customFieldExtensions.some((customFieldExtension) => customFieldExtension.name === name))
948
936
  ];
949
937
  return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
950
938
  path: "/",
@@ -967,4 +955,4 @@ const Router = ({TemplateCardComponent, groups}) => {
967
955
  };
968
956
 
969
957
  export { Router };
970
- //# sourceMappingURL=Router-8b2aa17e.esm.js.map
958
+ //# sourceMappingURL=Router-0282e15a.esm.js.map