@backstage/plugin-scaffolder 1.19.4-next.2 → 1.20.1-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.
Files changed (84) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +1 -2
  3. package/alpha/package.json +1 -1
  4. package/dist/api.esm.js +9 -17
  5. package/dist/api.esm.js.map +1 -1
  6. package/dist/components/ActionsPage/ActionsPage.esm.js +10 -13
  7. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  8. package/dist/components/FileBrowser/FileBrowser.esm.js +1 -1
  9. package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -1
  10. package/dist/components/ListTasksPage/ListTasksPage.esm.js +9 -17
  11. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
  12. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js +1 -2
  13. package/dist/components/ListTasksPage/columns/OwnerEntityColumn.esm.js.map +1 -1
  14. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js +1 -1
  15. package/dist/components/ListTasksPage/columns/TemplateTitleColumn.esm.js.map +1 -1
  16. package/dist/components/OngoingTask/ContextMenu.esm.js +1 -1
  17. package/dist/components/OngoingTask/ContextMenu.esm.js.map +1 -1
  18. package/dist/components/OngoingTask/OngoingTask.esm.js +10 -18
  19. package/dist/components/OngoingTask/OngoingTask.esm.js.map +1 -1
  20. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js +3 -3
  21. package/dist/components/fields/EntityNamePicker/EntityNamePicker.esm.js.map +1 -1
  22. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +11 -13
  23. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
  24. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js +6 -7
  25. package/dist/components/fields/EntityTagsPicker/EntityTagsPicker.esm.js.map +1 -1
  26. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js +29 -41
  27. package/dist/components/fields/MultiEntityPicker/MultiEntityPicker.esm.js.map +1 -1
  28. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js +7 -11
  29. package/dist/components/fields/MyGroupsPicker/MyGroupsPicker.esm.js.map +1 -1
  30. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js +1 -1
  31. package/dist/components/fields/OwnedEntityPicker/OwnedEntityPicker.esm.js.map +1 -1
  32. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js +4 -5
  33. package/dist/components/fields/OwnerPicker/OwnerPicker.esm.js.map +1 -1
  34. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js +16 -16
  35. package/dist/components/fields/RepoUrlPicker/AzureRepoPicker.esm.js.map +1 -1
  36. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js +6 -6
  37. package/dist/components/fields/RepoUrlPicker/BitbucketRepoPicker.esm.js.map +1 -1
  38. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js +2 -2
  39. package/dist/components/fields/RepoUrlPicker/GerritRepoPicker.esm.js.map +1 -1
  40. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js +2 -2
  41. package/dist/components/fields/RepoUrlPicker/GiteaRepoPicker.esm.js.map +1 -1
  42. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js +2 -2
  43. package/dist/components/fields/RepoUrlPicker/GithubRepoPicker.esm.js.map +1 -1
  44. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js +2 -2
  45. package/dist/components/fields/RepoUrlPicker/GitlabRepoPicker.esm.js.map +1 -1
  46. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js +8 -25
  47. package/dist/components/fields/RepoUrlPicker/RepoUrlPicker.esm.js.map +1 -1
  48. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js +6 -6
  49. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerHost.esm.js.map +1 -1
  50. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js +3 -3
  51. package/dist/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.esm.js.map +1 -1
  52. package/dist/components/fields/RepoUrlPicker/validation.esm.js +2 -3
  53. package/dist/components/fields/RepoUrlPicker/validation.esm.js.map +1 -1
  54. package/dist/components/fields/SecretInput/SecretInput.esm.js +3 -5
  55. package/dist/components/fields/SecretInput/SecretInput.esm.js.map +1 -1
  56. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js +14 -18
  57. package/dist/next/TemplateEditorPage/CustomFieldExplorer.esm.js.map +1 -1
  58. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js +55 -91
  59. package/dist/next/TemplateEditorPage/DirectoryEditorContext.esm.js.map +1 -1
  60. package/dist/next/TemplateEditorPage/DryRunContext.esm.js +5 -9
  61. package/dist/next/TemplateEditorPage/DryRunContext.esm.js.map +1 -1
  62. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js +1 -2
  63. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsList.esm.js.map +1 -1
  64. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js +8 -12
  65. package/dist/next/TemplateEditorPage/DryRunResults/DryRunResultsView.esm.js.map +1 -1
  66. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js +2 -5
  67. package/dist/next/TemplateEditorPage/DryRunResults/TaskPageLinks.esm.js.map +1 -1
  68. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js +1 -2
  69. package/dist/next/TemplateEditorPage/TemplateEditorBrowser.esm.js.map +1 -1
  70. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js +4 -13
  71. package/dist/next/TemplateEditorPage/TemplateEditorForm.esm.js.map +1 -1
  72. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js +3 -12
  73. package/dist/next/TemplateEditorPage/TemplateEditorIntro.esm.js.map +1 -1
  74. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js +3 -3
  75. package/dist/next/TemplateEditorPage/TemplateEditorPage.esm.js.map +1 -1
  76. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js +5 -15
  77. package/dist/next/TemplateEditorPage/TemplateEditorTextArea.esm.js.map +1 -1
  78. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js +4 -7
  79. package/dist/next/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
  80. package/dist/next/TemplateListPage/TemplateListPage.esm.js +5 -7
  81. package/dist/next/TemplateListPage/TemplateListPage.esm.js.map +1 -1
  82. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js +1 -2
  83. package/dist/next/TemplateWizardPage/TemplateWizardPage.esm.js.map +1 -1
  84. package/package.json +17 -17
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateTitleColumn.esm.js","sources":["../../../../src/components/ListTasksPage/columns/TemplateTitleColumn.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 { useApi } from '@backstage/core-plugin-api';\nimport React from 'react';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\n\nexport const TemplateTitleColumn = ({ entityRef }: { entityRef?: string }) => {\n const scaffolder = useApi(scaffolderApiRef);\n const { value, loading, error } = useAsync(\n () => scaffolder.getTemplateParameterSchema(entityRef || ''),\n [scaffolder, entityRef],\n );\n\n if (loading || error || !entityRef) {\n return null;\n }\n\n return (\n <EntityRefLink entityRef={parseEntityRef(entityRef)} title={value?.title} />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAsBO,MAAM,mBAAsB,GAAA,CAAC,EAAE,SAAA,EAAwC,KAAA;AAC5E,EAAM,MAAA,UAAA,GAAa,OAAO,gBAAgB,CAAA,CAAA;AAC1C,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAChC,MAAM,UAAA,CAAW,0BAA2B,CAAA,SAAA,IAAa,EAAE,CAAA;AAAA,IAC3D,CAAC,YAAY,SAAS,CAAA;AAAA,GACxB,CAAA;AAEA,EAAI,IAAA,OAAA,IAAW,KAAS,IAAA,CAAC,SAAW,EAAA;AAClC,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,iBAAc,SAAW,EAAA,cAAA,CAAe,SAAS,CAAG,EAAA,KAAA,EAAO,+BAAO,KAAO,EAAA,CAAA,CAAA;AAE9E;;;;"}
1
+ {"version":3,"file":"TemplateTitleColumn.esm.js","sources":["../../../../src/components/ListTasksPage/columns/TemplateTitleColumn.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 { useApi } from '@backstage/core-plugin-api';\nimport React from 'react';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\n\nexport const TemplateTitleColumn = ({ entityRef }: { entityRef?: string }) => {\n const scaffolder = useApi(scaffolderApiRef);\n const { value, loading, error } = useAsync(\n () => scaffolder.getTemplateParameterSchema(entityRef || ''),\n [scaffolder, entityRef],\n );\n\n if (loading || error || !entityRef) {\n return null;\n }\n\n return (\n <EntityRefLink entityRef={parseEntityRef(entityRef)} title={value?.title} />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAsBO,MAAM,mBAAsB,GAAA,CAAC,EAAE,SAAA,EAAwC,KAAA;AAC5E,EAAM,MAAA,UAAA,GAAa,OAAO,gBAAgB,CAAA,CAAA;AAC1C,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAChC,MAAM,UAAA,CAAW,0BAA2B,CAAA,SAAA,IAAa,EAAE,CAAA;AAAA,IAC3D,CAAC,YAAY,SAAS,CAAA;AAAA,GACxB,CAAA;AAEA,EAAI,IAAA,OAAA,IAAW,KAAS,IAAA,CAAC,SAAW,EAAA;AAClC,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,iBAAc,SAAW,EAAA,cAAA,CAAe,SAAS,CAAG,EAAA,KAAA,EAAO,OAAO,KAAO,EAAA,CAAA,CAAA;AAE9E;;;;"}
@@ -64,7 +64,7 @@ const ContextMenu = (props) => {
64
64
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
65
65
  transformOrigin: { vertical: "top", horizontal: "right" }
66
66
  },
67
- /* @__PURE__ */ React.createElement(MenuList, null, /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleLogs == null ? void 0 : onToggleLogs(!logsVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Toc, { fontSize: "small" })), /* @__PURE__ */ React.createElement(ListItemText, { primary: logsVisible ? "Hide Logs" : "Show Logs" })), /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleButtonBar == null ? void 0 : onToggleButtonBar(!buttonBarVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(ControlPointIcon, { fontSize: "small" })), /* @__PURE__ */ React.createElement(
67
+ /* @__PURE__ */ React.createElement(MenuList, null, /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleLogs?.(!logsVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Toc, { fontSize: "small" })), /* @__PURE__ */ React.createElement(ListItemText, { primary: logsVisible ? "Hide Logs" : "Show Logs" })), /* @__PURE__ */ React.createElement(MenuItem, { onClick: () => onToggleButtonBar?.(!buttonBarVisible) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(ControlPointIcon, { fontSize: "small" })), /* @__PURE__ */ React.createElement(
68
68
  ListItemText,
69
69
  {
70
70
  primary: buttonBarVisible ? "Hide Button Bar" : "Show Button Bar"
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.esm.js","sources":["../../../src/components/OngoingTask/ContextMenu.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 */\n\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MenuList from '@material-ui/core/MenuList';\nimport Popover from '@material-ui/core/Popover';\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\nimport { useAsync } from '@react-hookz/web';\nimport Cancel from '@material-ui/icons/Cancel';\nimport Retry from '@material-ui/icons/Repeat';\nimport Toc from '@material-ui/icons/Toc';\nimport ControlPointIcon from '@material-ui/icons/ControlPoint';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport React, { useState } from 'react';\nimport { useAnalytics, useApi } from '@backstage/core-plugin-api';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\n\ntype ContextMenuProps = {\n cancelEnabled?: boolean;\n logsVisible?: boolean;\n buttonBarVisible?: boolean;\n onStartOver?: () => void;\n onToggleLogs?: (state: boolean) => void;\n onToggleButtonBar?: (state: boolean) => void;\n taskId?: string;\n};\n\nconst useStyles = makeStyles<Theme, { fontColor: string }>(() => ({\n button: {\n color: ({ fontColor }) => fontColor,\n },\n}));\n\nexport const ContextMenu = (props: ContextMenuProps) => {\n const {\n cancelEnabled,\n logsVisible,\n buttonBarVisible,\n onStartOver,\n onToggleLogs,\n onToggleButtonBar,\n taskId,\n } = props;\n const { getPageTheme } = useTheme();\n const pageTheme = getPageTheme({ themeId: 'website' });\n const classes = useStyles({ fontColor: pageTheme.fontColor });\n const scaffolderApi = useApi(scaffolderApiRef);\n const analytics = useAnalytics();\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n\n const [{ status: cancelStatus }, { execute: cancel }] = useAsync(async () => {\n if (taskId) {\n analytics.captureEvent('cancelled', 'Template has been cancelled');\n await scaffolderApi.cancelTask(taskId);\n }\n });\n\n return (\n <>\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={(event: React.SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n }}\n data-testid=\"menu-button\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={() => setAnchorEl(undefined)}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n <MenuItem onClick={() => onToggleLogs?.(!logsVisible)}>\n <ListItemIcon>\n <Toc fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={logsVisible ? 'Hide Logs' : 'Show Logs'} />\n </MenuItem>\n <MenuItem onClick={() => onToggleButtonBar?.(!buttonBarVisible)}>\n <ListItemIcon>\n <ControlPointIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText\n primary={buttonBarVisible ? 'Hide Button Bar' : 'Show Button Bar'}\n />\n </MenuItem>\n <MenuItem onClick={onStartOver}>\n <ListItemIcon>\n <Retry fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Start Over\" />\n </MenuItem>\n <MenuItem\n onClick={cancel}\n disabled={!cancelEnabled || cancelStatus !== 'not-executed'}\n data-testid=\"cancel-task\"\n >\n <ListItemIcon>\n <Cancel fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Cancel\" />\n </MenuItem>\n </MenuList>\n </Popover>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ContextMenu.esm.js","sources":["../../../src/components/OngoingTask/ContextMenu.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 */\n\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MenuList from '@material-ui/core/MenuList';\nimport Popover from '@material-ui/core/Popover';\nimport { makeStyles, Theme, useTheme } from '@material-ui/core/styles';\nimport { useAsync } from '@react-hookz/web';\nimport Cancel from '@material-ui/icons/Cancel';\nimport Retry from '@material-ui/icons/Repeat';\nimport Toc from '@material-ui/icons/Toc';\nimport ControlPointIcon from '@material-ui/icons/ControlPoint';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport React, { useState } from 'react';\nimport { useAnalytics, useApi } from '@backstage/core-plugin-api';\nimport { scaffolderApiRef } from '@backstage/plugin-scaffolder-react';\n\ntype ContextMenuProps = {\n cancelEnabled?: boolean;\n logsVisible?: boolean;\n buttonBarVisible?: boolean;\n onStartOver?: () => void;\n onToggleLogs?: (state: boolean) => void;\n onToggleButtonBar?: (state: boolean) => void;\n taskId?: string;\n};\n\nconst useStyles = makeStyles<Theme, { fontColor: string }>(() => ({\n button: {\n color: ({ fontColor }) => fontColor,\n },\n}));\n\nexport const ContextMenu = (props: ContextMenuProps) => {\n const {\n cancelEnabled,\n logsVisible,\n buttonBarVisible,\n onStartOver,\n onToggleLogs,\n onToggleButtonBar,\n taskId,\n } = props;\n const { getPageTheme } = useTheme();\n const pageTheme = getPageTheme({ themeId: 'website' });\n const classes = useStyles({ fontColor: pageTheme.fontColor });\n const scaffolderApi = useApi(scaffolderApiRef);\n const analytics = useAnalytics();\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n\n const [{ status: cancelStatus }, { execute: cancel }] = useAsync(async () => {\n if (taskId) {\n analytics.captureEvent('cancelled', 'Template has been cancelled');\n await scaffolderApi.cancelTask(taskId);\n }\n });\n\n return (\n <>\n <IconButton\n aria-label=\"more\"\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n onClick={(event: React.SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n }}\n data-testid=\"menu-button\"\n className={classes.button}\n >\n <MoreVert />\n </IconButton>\n <Popover\n open={Boolean(anchorEl)}\n onClose={() => setAnchorEl(undefined)}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <MenuList>\n <MenuItem onClick={() => onToggleLogs?.(!logsVisible)}>\n <ListItemIcon>\n <Toc fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={logsVisible ? 'Hide Logs' : 'Show Logs'} />\n </MenuItem>\n <MenuItem onClick={() => onToggleButtonBar?.(!buttonBarVisible)}>\n <ListItemIcon>\n <ControlPointIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText\n primary={buttonBarVisible ? 'Hide Button Bar' : 'Show Button Bar'}\n />\n </MenuItem>\n <MenuItem onClick={onStartOver}>\n <ListItemIcon>\n <Retry fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Start Over\" />\n </MenuItem>\n <MenuItem\n onClick={cancel}\n disabled={!cancelEnabled || cancelStatus !== 'not-executed'}\n data-testid=\"cancel-task\"\n >\n <ListItemIcon>\n <Cancel fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary=\"Cancel\" />\n </MenuItem>\n </MenuList>\n </Popover>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -31,7 +31,6 @@ const useStyles = makeStyles((theme) => ({
31
31
  }
32
32
  }));
33
33
  const OngoingTask = (props) => {
34
- var _a, _b, _c, _d, _e, _f, _g, _h;
35
34
  const { taskId } = useParams();
36
35
  const templateRouteRef = useRouteRef(selectedTemplateRouteRef);
37
36
  const navigate = useNavigate();
@@ -40,16 +39,10 @@ const OngoingTask = (props) => {
40
39
  const taskStream = useTaskEventStream(taskId);
41
40
  const classes = useStyles();
42
41
  const steps = useMemo(
43
- () => {
44
- var _a2, _b2;
45
- return (_b2 = (_a2 = taskStream.task) == null ? void 0 : _a2.spec.steps.map((step) => {
46
- var _a3;
47
- return {
48
- ...step,
49
- ...(_a3 = taskStream == null ? void 0 : taskStream.steps) == null ? void 0 : _a3[step.id]
50
- };
51
- })) != null ? _b2 : [];
52
- },
42
+ () => taskStream.task?.spec.steps.map((step) => ({
43
+ ...step,
44
+ ...taskStream?.steps?.[step.id]
45
+ })) ?? [],
53
46
  [taskStream]
54
47
  );
55
48
  const [logsVisible, setLogVisibleState] = useState(false);
@@ -73,9 +66,8 @@ const OngoingTask = (props) => {
73
66
  return 0;
74
67
  }, [steps]);
75
68
  const startOver = useCallback(() => {
76
- var _a2, _b2, _c2, _d2, _e2, _f2;
77
- const { namespace, name } = (_d2 = (_c2 = (_b2 = (_a2 = taskStream.task) == null ? void 0 : _a2.spec.templateInfo) == null ? void 0 : _b2.entity) == null ? void 0 : _c2.metadata) != null ? _d2 : {};
78
- const formData = (_f2 = (_e2 = taskStream.task) == null ? void 0 : _e2.spec.parameters) != null ? _f2 : {};
69
+ const { namespace, name } = taskStream.task?.spec.templateInfo?.entity?.metadata ?? {};
70
+ const formData = taskStream.task?.spec.parameters ?? {};
79
71
  if (!namespace || !name) {
80
72
  return;
81
73
  }
@@ -90,8 +82,8 @@ const OngoingTask = (props) => {
90
82
  }, [
91
83
  analytics,
92
84
  navigate,
93
- (_a = taskStream.task) == null ? void 0 : _a.spec.parameters,
94
- (_d = (_c = (_b = taskStream.task) == null ? void 0 : _b.spec.templateInfo) == null ? void 0 : _c.entity) == null ? void 0 : _d.metadata,
85
+ taskStream.task?.spec.parameters,
86
+ taskStream.task?.spec.templateInfo?.entity?.metadata,
95
87
  templateRouteRef
96
88
  ]);
97
89
  const [{ status: cancelStatus }, { execute: triggerCancel }] = useAsync(
@@ -102,8 +94,8 @@ const OngoingTask = (props) => {
102
94
  }
103
95
  }
104
96
  );
105
- const Outputs = (_e = props.TemplateOutputsComponent) != null ? _e : DefaultTemplateOutputs;
106
- const templateName = (_h = (_g = (_f = taskStream.task) == null ? void 0 : _f.spec.templateInfo) == null ? void 0 : _g.entity) == null ? void 0 : _h.metadata.name;
97
+ const Outputs = props.TemplateOutputsComponent ?? DefaultTemplateOutputs;
98
+ const templateName = taskStream.task?.spec.templateInfo?.entity?.metadata.name;
107
99
  const cancelEnabled = !(taskStream.cancelled || taskStream.completed);
108
100
  return /* @__PURE__ */ React.createElement(Page, { themeId: "website" }, /* @__PURE__ */ React.createElement(
109
101
  Header,
@@ -1 +1 @@
1
- {"version":3,"file":"OngoingTask.esm.js","sources":["../../../src/components/OngoingTask/OngoingTask.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 React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Content, ErrorPanel, Header, Page } from '@backstage/core-components';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Paper from '@material-ui/core/Paper';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n ScaffolderTaskOutput,\n scaffolderApiRef,\n useTaskEventStream,\n} from '@backstage/plugin-scaffolder-react';\nimport { selectedTemplateRouteRef } from '../../routes';\nimport { useAnalytics, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport qs from 'qs';\nimport { ContextMenu } from './ContextMenu';\nimport {\n DefaultTemplateOutputs,\n TaskLogStream,\n TaskSteps,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useAsync } from '@react-hookz/web';\n\nconst useStyles = makeStyles(theme => ({\n contentWrapper: {\n display: 'flex',\n flexDirection: 'column',\n },\n buttonBar: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'right',\n },\n cancelButton: {\n marginRight: theme.spacing(1),\n },\n logsVisibilityButton: {\n marginRight: theme.spacing(1),\n },\n}));\n\n/**\n * @public\n */\nexport const OngoingTask = (props: {\n TemplateOutputsComponent?: React.ComponentType<{\n output?: ScaffolderTaskOutput;\n }>;\n}) => {\n // todo(blam): check that task Id actually exists, and that it's valid. otherwise redirect to something more useful.\n const { taskId } = useParams();\n const templateRouteRef = useRouteRef(selectedTemplateRouteRef);\n const navigate = useNavigate();\n const analytics = useAnalytics();\n const scaffolderApi = useApi(scaffolderApiRef);\n const taskStream = useTaskEventStream(taskId!);\n const classes = useStyles();\n const steps = useMemo(\n () =>\n taskStream.task?.spec.steps.map(step => ({\n ...step,\n ...taskStream?.steps?.[step.id],\n })) ?? [],\n [taskStream],\n );\n\n const [logsVisible, setLogVisibleState] = useState(false);\n const [buttonBarVisible, setButtonBarVisibleState] = useState(true);\n\n useEffect(() => {\n if (taskStream.error) {\n setLogVisibleState(true);\n }\n }, [taskStream.error]);\n\n useEffect(() => {\n if (taskStream.completed && !taskStream.error) {\n setButtonBarVisibleState(false);\n }\n }, [taskStream.error, taskStream.completed]);\n\n const activeStep = useMemo(() => {\n for (let i = steps.length - 1; i >= 0; i--) {\n if (steps[i].status !== 'open') {\n return i;\n }\n }\n\n return 0;\n }, [steps]);\n\n const startOver = useCallback(() => {\n const { namespace, name } =\n taskStream.task?.spec.templateInfo?.entity?.metadata ?? {};\n\n const formData = taskStream.task?.spec.parameters ?? {};\n\n if (!namespace || !name) {\n return;\n }\n\n analytics.captureEvent('click', `Task has been started over`);\n\n navigate({\n pathname: templateRouteRef({\n namespace,\n templateName: name,\n }),\n search: `?${qs.stringify({ formData: JSON.stringify(formData) })}`,\n });\n }, [\n analytics,\n navigate,\n taskStream.task?.spec.parameters,\n taskStream.task?.spec.templateInfo?.entity?.metadata,\n templateRouteRef,\n ]);\n\n const [{ status: cancelStatus }, { execute: triggerCancel }] = useAsync(\n async () => {\n if (taskId) {\n analytics.captureEvent('cancelled', 'Template has been cancelled');\n await scaffolderApi.cancelTask(taskId);\n }\n },\n );\n\n const Outputs = props.TemplateOutputsComponent ?? DefaultTemplateOutputs;\n\n const templateName =\n taskStream.task?.spec.templateInfo?.entity?.metadata.name;\n\n const cancelEnabled = !(taskStream.cancelled || taskStream.completed);\n\n return (\n <Page themeId=\"website\">\n <Header\n pageTitleOverride={`Run of ${templateName}`}\n title={\n <div>\n Run of <code>{templateName}</code>\n </div>\n }\n subtitle={`Task ${taskId}`}\n >\n <ContextMenu\n cancelEnabled={cancelEnabled}\n logsVisible={logsVisible}\n buttonBarVisible={buttonBarVisible}\n onStartOver={startOver}\n onToggleLogs={setLogVisibleState}\n onToggleButtonBar={setButtonBarVisibleState}\n taskId={taskId}\n />\n </Header>\n <Content className={classes.contentWrapper}>\n {taskStream.error ? (\n <Box paddingBottom={2}>\n <ErrorPanel\n error={taskStream.error}\n titleFormat=\"markdown\"\n title={taskStream.error.message}\n />\n </Box>\n ) : null}\n\n <Box paddingBottom={2}>\n <TaskSteps\n steps={steps}\n activeStep={activeStep}\n isComplete={taskStream.completed}\n isError={Boolean(taskStream.error)}\n />\n </Box>\n\n <Outputs output={taskStream.output} />\n\n {buttonBarVisible ? (\n <Box paddingBottom={2}>\n <Paper>\n <Box padding={2}>\n <div className={classes.buttonBar}>\n <Button\n className={classes.cancelButton}\n disabled={!cancelEnabled || cancelStatus !== 'not-executed'}\n onClick={triggerCancel}\n data-testid=\"cancel-button\"\n >\n Cancel\n </Button>\n <Button\n className={classes.logsVisibilityButton}\n color=\"primary\"\n variant=\"outlined\"\n onClick={() => setLogVisibleState(!logsVisible)}\n >\n {logsVisible ? 'Hide Logs' : 'Show Logs'}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={cancelEnabled}\n onClick={startOver}\n >\n Start Over\n </Button>\n </div>\n </Box>\n </Paper>\n </Box>\n ) : null}\n\n {logsVisible ? (\n <Box paddingBottom={2} height=\"100%\">\n <Paper style={{ height: '100%' }}>\n <Box padding={2} height=\"100%\">\n <TaskLogStream logs={taskStream.stepLogs} />\n </Box>\n </Paper>\n </Box>\n ) : null}\n </Content>\n </Page>\n );\n};\n"],"names":["_a","_b","_c","_d","_e","_f"],"mappings":"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"}
1
+ {"version":3,"file":"OngoingTask.esm.js","sources":["../../../src/components/OngoingTask/OngoingTask.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 React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Content, ErrorPanel, Header, Page } from '@backstage/core-components';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Paper from '@material-ui/core/Paper';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n ScaffolderTaskOutput,\n scaffolderApiRef,\n useTaskEventStream,\n} from '@backstage/plugin-scaffolder-react';\nimport { selectedTemplateRouteRef } from '../../routes';\nimport { useAnalytics, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport qs from 'qs';\nimport { ContextMenu } from './ContextMenu';\nimport {\n DefaultTemplateOutputs,\n TaskLogStream,\n TaskSteps,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useAsync } from '@react-hookz/web';\n\nconst useStyles = makeStyles(theme => ({\n contentWrapper: {\n display: 'flex',\n flexDirection: 'column',\n },\n buttonBar: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'right',\n },\n cancelButton: {\n marginRight: theme.spacing(1),\n },\n logsVisibilityButton: {\n marginRight: theme.spacing(1),\n },\n}));\n\n/**\n * @public\n */\nexport const OngoingTask = (props: {\n TemplateOutputsComponent?: React.ComponentType<{\n output?: ScaffolderTaskOutput;\n }>;\n}) => {\n // todo(blam): check that task Id actually exists, and that it's valid. otherwise redirect to something more useful.\n const { taskId } = useParams();\n const templateRouteRef = useRouteRef(selectedTemplateRouteRef);\n const navigate = useNavigate();\n const analytics = useAnalytics();\n const scaffolderApi = useApi(scaffolderApiRef);\n const taskStream = useTaskEventStream(taskId!);\n const classes = useStyles();\n const steps = useMemo(\n () =>\n taskStream.task?.spec.steps.map(step => ({\n ...step,\n ...taskStream?.steps?.[step.id],\n })) ?? [],\n [taskStream],\n );\n\n const [logsVisible, setLogVisibleState] = useState(false);\n const [buttonBarVisible, setButtonBarVisibleState] = useState(true);\n\n useEffect(() => {\n if (taskStream.error) {\n setLogVisibleState(true);\n }\n }, [taskStream.error]);\n\n useEffect(() => {\n if (taskStream.completed && !taskStream.error) {\n setButtonBarVisibleState(false);\n }\n }, [taskStream.error, taskStream.completed]);\n\n const activeStep = useMemo(() => {\n for (let i = steps.length - 1; i >= 0; i--) {\n if (steps[i].status !== 'open') {\n return i;\n }\n }\n\n return 0;\n }, [steps]);\n\n const startOver = useCallback(() => {\n const { namespace, name } =\n taskStream.task?.spec.templateInfo?.entity?.metadata ?? {};\n\n const formData = taskStream.task?.spec.parameters ?? {};\n\n if (!namespace || !name) {\n return;\n }\n\n analytics.captureEvent('click', `Task has been started over`);\n\n navigate({\n pathname: templateRouteRef({\n namespace,\n templateName: name,\n }),\n search: `?${qs.stringify({ formData: JSON.stringify(formData) })}`,\n });\n }, [\n analytics,\n navigate,\n taskStream.task?.spec.parameters,\n taskStream.task?.spec.templateInfo?.entity?.metadata,\n templateRouteRef,\n ]);\n\n const [{ status: cancelStatus }, { execute: triggerCancel }] = useAsync(\n async () => {\n if (taskId) {\n analytics.captureEvent('cancelled', 'Template has been cancelled');\n await scaffolderApi.cancelTask(taskId);\n }\n },\n );\n\n const Outputs = props.TemplateOutputsComponent ?? DefaultTemplateOutputs;\n\n const templateName =\n taskStream.task?.spec.templateInfo?.entity?.metadata.name;\n\n const cancelEnabled = !(taskStream.cancelled || taskStream.completed);\n\n return (\n <Page themeId=\"website\">\n <Header\n pageTitleOverride={`Run of ${templateName}`}\n title={\n <div>\n Run of <code>{templateName}</code>\n </div>\n }\n subtitle={`Task ${taskId}`}\n >\n <ContextMenu\n cancelEnabled={cancelEnabled}\n logsVisible={logsVisible}\n buttonBarVisible={buttonBarVisible}\n onStartOver={startOver}\n onToggleLogs={setLogVisibleState}\n onToggleButtonBar={setButtonBarVisibleState}\n taskId={taskId}\n />\n </Header>\n <Content className={classes.contentWrapper}>\n {taskStream.error ? (\n <Box paddingBottom={2}>\n <ErrorPanel\n error={taskStream.error}\n titleFormat=\"markdown\"\n title={taskStream.error.message}\n />\n </Box>\n ) : null}\n\n <Box paddingBottom={2}>\n <TaskSteps\n steps={steps}\n activeStep={activeStep}\n isComplete={taskStream.completed}\n isError={Boolean(taskStream.error)}\n />\n </Box>\n\n <Outputs output={taskStream.output} />\n\n {buttonBarVisible ? (\n <Box paddingBottom={2}>\n <Paper>\n <Box padding={2}>\n <div className={classes.buttonBar}>\n <Button\n className={classes.cancelButton}\n disabled={!cancelEnabled || cancelStatus !== 'not-executed'}\n onClick={triggerCancel}\n data-testid=\"cancel-button\"\n >\n Cancel\n </Button>\n <Button\n className={classes.logsVisibilityButton}\n color=\"primary\"\n variant=\"outlined\"\n onClick={() => setLogVisibleState(!logsVisible)}\n >\n {logsVisible ? 'Hide Logs' : 'Show Logs'}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={cancelEnabled}\n onClick={startOver}\n >\n Start Over\n </Button>\n </div>\n </Box>\n </Paper>\n </Box>\n ) : null}\n\n {logsVisible ? (\n <Box paddingBottom={2} height=\"100%\">\n <Paper style={{ height: '100%' }}>\n <Box padding={2} height=\"100%\">\n <TaskLogStream logs={taskStream.stepLogs} />\n </Box>\n </Paper>\n </Box>\n ) : null}\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -16,15 +16,15 @@ const EntityNamePicker = (props) => {
16
16
  return /* @__PURE__ */ React.createElement(
17
17
  TextField,
18
18
  {
19
- id: idSchema == null ? void 0 : idSchema.$id,
19
+ id: idSchema?.$id,
20
20
  label: title,
21
21
  placeholder,
22
22
  helperText: description,
23
23
  required,
24
- value: formData != null ? formData : "",
24
+ value: formData ?? "",
25
25
  onChange: ({ target: { value } }) => onChange(value),
26
26
  margin: "normal",
27
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData,
27
+ error: rawErrors?.length > 0 && !formData,
28
28
  inputProps: { autoFocus }
29
29
  }
30
30
  );
@@ -1 +1 @@
1
- {"version":3,"file":"EntityNamePicker.esm.js","sources":["../../../../src/components/fields/EntityNamePicker/EntityNamePicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 { EntityNamePickerProps } from './schema';\nimport TextField from '@material-ui/core/TextField';\n\nexport { EntityNamePickerSchema } from './schema';\n\n/**\n * EntityName Picker\n */\nexport const EntityNamePicker = (props: EntityNamePickerProps) => {\n const {\n onChange,\n required,\n schema: { title = 'Name', description = 'Unique name of the component' },\n rawErrors,\n formData,\n uiSchema: { 'ui:autofocus': autoFocus },\n idSchema,\n placeholder,\n } = props;\n\n return (\n <TextField\n id={idSchema?.$id}\n label={title}\n placeholder={placeholder}\n helperText={description}\n required={required}\n value={formData ?? ''}\n onChange={({ target: { value } }) => onChange(value)}\n margin=\"normal\"\n error={rawErrors?.length > 0 && !formData}\n inputProps={{ autoFocus }}\n />\n );\n};\n"],"names":[],"mappings":";;;;AAwBa,MAAA,gBAAA,GAAmB,CAAC,KAAiC,KAAA;AAChE,EAAM,MAAA;AAAA,IACJ,QAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAQ,EAAA,EAAE,KAAQ,GAAA,MAAA,EAAQ,cAAc,8BAA+B,EAAA;AAAA,IACvE,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA,EAAU,EAAE,cAAA,EAAgB,SAAU,EAAA;AAAA,IACtC,QAAA;AAAA,IACA,WAAA;AAAA,GACE,GAAA,KAAA,CAAA;AAEJ,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,IAAI,QAAU,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAA,GAAA;AAAA,MACd,KAAO,EAAA,KAAA;AAAA,MACP,WAAA;AAAA,MACA,UAAY,EAAA,WAAA;AAAA,MACZ,QAAA;AAAA,MACA,OAAO,QAAY,IAAA,IAAA,GAAA,QAAA,GAAA,EAAA;AAAA,MACnB,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,EAAE,KAAM,EAAA,EAAQ,KAAA,QAAA,CAAS,KAAK,CAAA;AAAA,MACnD,MAAO,EAAA,QAAA;AAAA,MACP,KAAO,EAAA,CAAA,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAW,MAAS,IAAA,CAAA,IAAK,CAAC,QAAA;AAAA,MACjC,UAAA,EAAY,EAAE,SAAU,EAAA;AAAA,KAAA;AAAA,GAC1B,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"EntityNamePicker.esm.js","sources":["../../../../src/components/fields/EntityNamePicker/EntityNamePicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 { EntityNamePickerProps } from './schema';\nimport TextField from '@material-ui/core/TextField';\n\nexport { EntityNamePickerSchema } from './schema';\n\n/**\n * EntityName Picker\n */\nexport const EntityNamePicker = (props: EntityNamePickerProps) => {\n const {\n onChange,\n required,\n schema: { title = 'Name', description = 'Unique name of the component' },\n rawErrors,\n formData,\n uiSchema: { 'ui:autofocus': autoFocus },\n idSchema,\n placeholder,\n } = props;\n\n return (\n <TextField\n id={idSchema?.$id}\n label={title}\n placeholder={placeholder}\n helperText={description}\n required={required}\n value={formData ?? ''}\n onChange={({ target: { value } }) => onChange(value)}\n margin=\"normal\"\n error={rawErrors?.length > 0 && !formData}\n inputProps={{ autoFocus }}\n />\n );\n};\n"],"names":[],"mappings":";;;;AAwBa,MAAA,gBAAA,GAAmB,CAAC,KAAiC,KAAA;AAChE,EAAM,MAAA;AAAA,IACJ,QAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAQ,EAAA,EAAE,KAAQ,GAAA,MAAA,EAAQ,cAAc,8BAA+B,EAAA;AAAA,IACvE,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA,EAAU,EAAE,cAAA,EAAgB,SAAU,EAAA;AAAA,IACtC,QAAA;AAAA,IACA,WAAA;AAAA,GACE,GAAA,KAAA,CAAA;AAEJ,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,IAAI,QAAU,EAAA,GAAA;AAAA,MACd,KAAO,EAAA,KAAA;AAAA,MACP,WAAA;AAAA,MACA,UAAY,EAAA,WAAA;AAAA,MACZ,QAAA;AAAA,MACA,OAAO,QAAY,IAAA,EAAA;AAAA,MACnB,QAAA,EAAU,CAAC,EAAE,MAAA,EAAQ,EAAE,KAAM,EAAA,EAAQ,KAAA,QAAA,CAAS,KAAK,CAAA;AAAA,MACnD,MAAO,EAAA,QAAA;AAAA,MACP,KAAO,EAAA,SAAA,EAAW,MAAS,GAAA,CAAA,IAAK,CAAC,QAAA;AAAA,MACjC,UAAA,EAAY,EAAE,SAAU,EAAA;AAAA,KAAA;AAAA,GAC1B,CAAA;AAEJ;;;;"}
@@ -10,7 +10,6 @@ import useAsync from 'react-use/esm/useAsync';
10
10
  export { EntityPickerSchema } from './schema.esm.js';
11
11
 
12
12
  const EntityPicker = (props) => {
13
- var _a, _b, _c, _d, _e;
14
13
  const {
15
14
  onChange,
16
15
  schema: { title = "Entity", description = "An entity from the catalog" },
@@ -21,8 +20,8 @@ const EntityPicker = (props) => {
21
20
  idSchema
22
21
  } = props;
23
22
  const catalogFilter = buildCatalogFilter(uiSchema);
24
- const defaultKind = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.defaultKind;
25
- const defaultNamespace = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.defaultNamespace) || void 0;
23
+ const defaultKind = uiSchema["ui:options"]?.defaultKind;
24
+ const defaultNamespace = uiSchema["ui:options"]?.defaultNamespace || void 0;
26
25
  const catalogApi = useApi(catalogApiRef);
27
26
  const { value: entities, loading } = useAsync(async () => {
28
27
  const fields = ["metadata.name", "metadata.namespace", "kind"];
@@ -31,7 +30,7 @@ const EntityPicker = (props) => {
31
30
  );
32
31
  return items;
33
32
  });
34
- const allowArbitraryValues = (_d = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.allowArbitraryValues) != null ? _d : true;
33
+ const allowArbitraryValues = uiSchema["ui:options"]?.allowArbitraryValues ?? true;
35
34
  const getLabel = useCallback(
36
35
  (ref) => {
37
36
  try {
@@ -72,9 +71,9 @@ const EntityPicker = (props) => {
72
71
  },
73
72
  [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues]
74
73
  );
75
- const selectedEntity = (_e = entities == null ? void 0 : entities.find((e) => stringifyEntityRef(e) === formData)) != null ? _e : allowArbitraryValues && formData ? getLabel(formData) : "";
74
+ const selectedEntity = entities?.find((e) => stringifyEntityRef(e) === formData) ?? (allowArbitraryValues && formData ? getLabel(formData) : "");
76
75
  useEffect(() => {
77
- if ((entities == null ? void 0 : entities.length) === 1 && selectedEntity === "") {
76
+ if (entities?.length === 1 && selectedEntity === "") {
78
77
  onChange(stringifyEntityRef(entities[0]));
79
78
  }
80
79
  }, [entities, onChange, selectedEntity]);
@@ -83,13 +82,13 @@ const EntityPicker = (props) => {
83
82
  {
84
83
  margin: "normal",
85
84
  required,
86
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData
85
+ error: rawErrors?.length > 0 && !formData
87
86
  },
88
87
  /* @__PURE__ */ React.createElement(
89
88
  Autocomplete,
90
89
  {
91
- disabled: (entities == null ? void 0 : entities.length) === 1,
92
- id: idSchema == null ? void 0 : idSchema.$id,
90
+ disabled: entities?.length === 1,
91
+ id: idSchema?.$id,
93
92
  value: selectedEntity,
94
93
  loading,
95
94
  onChange: onSelect,
@@ -121,7 +120,7 @@ function convertOpsValues(value) {
121
120
  if (typeof value === "object" && value.exists) {
122
121
  return CATALOG_FILTER_EXISTS;
123
122
  }
124
- return value == null ? void 0 : value.toString();
123
+ return value?.toString();
125
124
  }
126
125
  function convertSchemaFiltersToQuery(schemaFilters) {
127
126
  const query = {};
@@ -135,9 +134,8 @@ function convertSchemaFiltersToQuery(schemaFilters) {
135
134
  return query;
136
135
  }
137
136
  function buildCatalogFilter(uiSchema) {
138
- var _a, _b;
139
- const allowedKinds = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.allowedKinds;
140
- const catalogFilter = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.catalogFilter) || allowedKinds && { kind: allowedKinds };
137
+ const allowedKinds = uiSchema["ui:options"]?.allowedKinds;
138
+ const catalogFilter = uiSchema["ui:options"]?.catalogFilter || allowedKinds && { kind: allowedKinds };
141
139
  if (!catalogFilter) {
142
140
  return void 0;
143
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport FormControl from '@material-ui/core/FormControl';\nimport Autocomplete, {\n AutocompleteChangeReason,\n} from '@material-ui/lab/Autocomplete';\nimport React, { useCallback, useEffect } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const {\n onChange,\n schema: { title = 'Entity', description = 'An entity from the catalog' },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = ['metadata.name', 'metadata.namespace', 'kind'];\n const { items } = await catalogApi.getEntities(\n catalogFilter\n ? { filter: catalogFilter, fields }\n : { filter: undefined, fields },\n );\n return items;\n });\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (ref: string) => {\n try {\n return humanizeEntityRef(\n parseEntityRef(ref, { defaultKind, defaultNamespace }),\n {\n defaultKind,\n defaultNamespace,\n },\n );\n } catch (err) {\n return ref;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall\n // back to the given value.\n const selectedEntity =\n entities?.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n useEffect(() => {\n if (entities?.length === 1 && selectedEntity === '') {\n onChange(stringifyEntityRef(entities[0]));\n }\n }, [entities, onChange, selectedEntity]);\n\n return (\n <FormControl\n margin=\"normal\"\n required={required}\n error={rawErrors?.length > 0 && !formData}\n >\n <Autocomplete\n disabled={entities?.length === 1}\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : humanizeEntityRef(option, { defaultKind, defaultNamespace })!\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n helperText={description}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n />\n </FormControl>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport FormControl from '@material-ui/core/FormControl';\nimport Autocomplete, {\n AutocompleteChangeReason,\n} from '@material-ui/lab/Autocomplete';\nimport React, { useCallback, useEffect } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const {\n onChange,\n schema: { title = 'Entity', description = 'An entity from the catalog' },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = ['metadata.name', 'metadata.namespace', 'kind'];\n const { items } = await catalogApi.getEntities(\n catalogFilter\n ? { filter: catalogFilter, fields }\n : { filter: undefined, fields },\n );\n return items;\n });\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (ref: string) => {\n try {\n return humanizeEntityRef(\n parseEntityRef(ref, { defaultKind, defaultNamespace }),\n {\n defaultKind,\n defaultNamespace,\n },\n );\n } catch (err) {\n return ref;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall\n // back to the given value.\n const selectedEntity =\n entities?.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n useEffect(() => {\n if (entities?.length === 1 && selectedEntity === '') {\n onChange(stringifyEntityRef(entities[0]));\n }\n }, [entities, onChange, selectedEntity]);\n\n return (\n <FormControl\n margin=\"normal\"\n required={required}\n error={rawErrors?.length > 0 && !formData}\n >\n <Autocomplete\n disabled={entities?.length === 1}\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : humanizeEntityRef(option, { defaultKind, defaultNamespace })!\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n helperText={description}\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n />\n </FormControl>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":[],"mappings":"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"}
@@ -10,16 +10,15 @@ import Autocomplete from '@material-ui/lab/Autocomplete';
10
10
  export { EntityTagsPickerSchema } from './schema.esm.js';
11
11
 
12
12
  const EntityTagsPicker = (props) => {
13
- var _a, _b, _c;
14
13
  const { formData, onChange, uiSchema } = props;
15
14
  const catalogApi = useApi(catalogApiRef);
16
15
  const [tagOptions, setTagOptions] = useState([]);
17
16
  const [inputValue, setInputValue] = useState("");
18
17
  const [inputError, setInputError] = useState(false);
19
18
  const tagValidator = makeValidator().isValidTag;
20
- const kinds = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.kinds;
21
- const showCounts = (_b = uiSchema["ui:options"]) == null ? void 0 : _b.showCounts;
22
- const helperText = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.helperText;
19
+ const kinds = uiSchema["ui:options"]?.kinds;
20
+ const showCounts = uiSchema["ui:options"]?.showCounts;
21
+ const helperText = uiSchema["ui:options"]?.helperText;
23
22
  const { loading, value: existingTags } = useAsync(async () => {
24
23
  const facet = "metadata.tags";
25
24
  const tagsRequest = { facets: [facet] };
@@ -41,7 +40,7 @@ const EntityTagsPicker = (props) => {
41
40
  let hasError = false;
42
41
  let addDuplicate = false;
43
42
  const currentTags = formData || [];
44
- if ((values == null ? void 0 : values.length) && currentTags.length < values.length) {
43
+ if (values?.length && currentTags.length < values.length) {
45
44
  const newTag = values[values.length - 1] = values[values.length - 1].toLocaleLowerCase("en-US").trim();
46
45
  hasError = !tagValidator(newTag);
47
46
  addDuplicate = currentTags.indexOf(newTag) !== -1;
@@ -65,7 +64,7 @@ const EntityTagsPicker = (props) => {
65
64
  loading,
66
65
  options: tagOptions,
67
66
  ChipProps: { size: "small" },
68
- renderOption: (option) => showCounts ? `${option} (${existingTags == null ? void 0 : existingTags[option]})` : option,
67
+ renderOption: (option) => showCounts ? `${option} (${existingTags?.[option]})` : option,
69
68
  renderInput: (params) => /* @__PURE__ */ React.createElement(
70
69
  TextField,
71
70
  {
@@ -73,7 +72,7 @@ const EntityTagsPicker = (props) => {
73
72
  label: "Tags",
74
73
  onChange: (e) => setInputValue(e.target.value),
75
74
  error: inputError,
76
- helperText: helperText != null ? helperText : "Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters"
75
+ helperText: helperText ?? "Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters"
77
76
  }
78
77
  )
79
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EntityTagsPicker.esm.js","sources":["../../../../src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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, { useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport useEffectOnce from 'react-use/esm/useEffectOnce';\nimport { GetEntityFacetsRequest } from '@backstage/catalog-client';\nimport { makeValidator } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport FormControl from '@material-ui/core/FormControl';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { EntityTagsPickerProps } from './schema';\n\nexport { EntityTagsPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityTagsPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityTagsPicker = (props: EntityTagsPickerProps) => {\n const { formData, onChange, uiSchema } = props;\n const catalogApi = useApi(catalogApiRef);\n const [tagOptions, setTagOptions] = useState<string[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [inputError, setInputError] = useState(false);\n const tagValidator = makeValidator().isValidTag;\n const kinds = uiSchema['ui:options']?.kinds;\n const showCounts = uiSchema['ui:options']?.showCounts;\n const helperText = uiSchema['ui:options']?.helperText;\n\n const { loading, value: existingTags } = useAsync(async () => {\n const facet = 'metadata.tags';\n const tagsRequest: GetEntityFacetsRequest = { facets: [facet] };\n if (kinds) {\n tagsRequest.filter = { kind: kinds };\n }\n\n const { facets } = await catalogApi.getEntityFacets(tagsRequest);\n\n const tagFacets = Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n\n setTagOptions(\n Object.keys(tagFacets).sort((a, b) =>\n showCounts ? tagFacets[b] - tagFacets[a] : a.localeCompare(b),\n ),\n );\n\n return tagFacets;\n });\n\n const setTags = (_: React.ChangeEvent<{}>, values: string[] | null) => {\n // Reset error state in case all tags were removed\n let hasError = false;\n let addDuplicate = false;\n const currentTags = formData || [];\n\n // If adding a new tag\n if (values?.length && currentTags.length < values.length) {\n const newTag = (values[values.length - 1] = values[values.length - 1]\n .toLocaleLowerCase('en-US')\n .trim());\n hasError = !tagValidator(newTag);\n addDuplicate = currentTags.indexOf(newTag) !== -1;\n }\n\n setInputError(hasError);\n setInputValue(!hasError ? '' : inputValue);\n if (!hasError && !addDuplicate) {\n onChange(values || []);\n }\n };\n\n // Initialize field to always return an array\n useEffectOnce(() => onChange(formData || []));\n\n return (\n <FormControl margin=\"normal\">\n <Autocomplete\n multiple\n freeSolo\n filterSelectedOptions\n onChange={setTags}\n value={formData || []}\n inputValue={inputValue}\n loading={loading}\n options={tagOptions}\n ChipProps={{ size: 'small' }}\n renderOption={option =>\n showCounts ? `${option} (${existingTags?.[option]})` : option\n }\n renderInput={params => (\n <TextField\n {...params}\n label=\"Tags\"\n onChange={e => setInputValue(e.target.value)}\n error={inputError}\n helperText={\n helperText ??\n \"Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters\"\n }\n />\n )}\n />\n </FormControl>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EntityTagsPicker.esm.js","sources":["../../../../src/components/fields/EntityTagsPicker/EntityTagsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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, { useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport useEffectOnce from 'react-use/esm/useEffectOnce';\nimport { GetEntityFacetsRequest } from '@backstage/catalog-client';\nimport { makeValidator } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport FormControl from '@material-ui/core/FormControl';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { EntityTagsPickerProps } from './schema';\n\nexport { EntityTagsPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityTagsPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityTagsPicker = (props: EntityTagsPickerProps) => {\n const { formData, onChange, uiSchema } = props;\n const catalogApi = useApi(catalogApiRef);\n const [tagOptions, setTagOptions] = useState<string[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [inputError, setInputError] = useState(false);\n const tagValidator = makeValidator().isValidTag;\n const kinds = uiSchema['ui:options']?.kinds;\n const showCounts = uiSchema['ui:options']?.showCounts;\n const helperText = uiSchema['ui:options']?.helperText;\n\n const { loading, value: existingTags } = useAsync(async () => {\n const facet = 'metadata.tags';\n const tagsRequest: GetEntityFacetsRequest = { facets: [facet] };\n if (kinds) {\n tagsRequest.filter = { kind: kinds };\n }\n\n const { facets } = await catalogApi.getEntityFacets(tagsRequest);\n\n const tagFacets = Object.fromEntries(\n facets[facet].map(({ value, count }) => [value, count]),\n );\n\n setTagOptions(\n Object.keys(tagFacets).sort((a, b) =>\n showCounts ? tagFacets[b] - tagFacets[a] : a.localeCompare(b),\n ),\n );\n\n return tagFacets;\n });\n\n const setTags = (_: React.ChangeEvent<{}>, values: string[] | null) => {\n // Reset error state in case all tags were removed\n let hasError = false;\n let addDuplicate = false;\n const currentTags = formData || [];\n\n // If adding a new tag\n if (values?.length && currentTags.length < values.length) {\n const newTag = (values[values.length - 1] = values[values.length - 1]\n .toLocaleLowerCase('en-US')\n .trim());\n hasError = !tagValidator(newTag);\n addDuplicate = currentTags.indexOf(newTag) !== -1;\n }\n\n setInputError(hasError);\n setInputValue(!hasError ? '' : inputValue);\n if (!hasError && !addDuplicate) {\n onChange(values || []);\n }\n };\n\n // Initialize field to always return an array\n useEffectOnce(() => onChange(formData || []));\n\n return (\n <FormControl margin=\"normal\">\n <Autocomplete\n multiple\n freeSolo\n filterSelectedOptions\n onChange={setTags}\n value={formData || []}\n inputValue={inputValue}\n loading={loading}\n options={tagOptions}\n ChipProps={{ size: 'small' }}\n renderOption={option =>\n showCounts ? `${option} (${existingTags?.[option]})` : option\n }\n renderInput={params => (\n <TextField\n {...params}\n label=\"Tags\"\n onChange={e => setInputValue(e.target.value)}\n error={inputError}\n helperText={\n helperText ??\n \"Add any relevant tags, hit 'Enter' to add new tags. Valid format: [a-z0-9+#] separated by [-], at most 63 characters\"\n }\n />\n )}\n />\n </FormControl>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';
2
- import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
2
+ import { stringifyEntityRef, parseEntityRef } from '@backstage/catalog-model';
3
3
  import { useApi } from '@backstage/core-plugin-api';
4
- import { catalogApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
4
+ import { catalogApiRef, entityPresentationApiRef, EntityDisplayName } from '@backstage/plugin-catalog-react';
5
5
  import TextField from '@material-ui/core/TextField';
6
6
  import FormControl from '@material-ui/core/FormControl';
7
7
  import Autocomplete from '@material-ui/lab/Autocomplete';
@@ -10,7 +10,6 @@ import useAsync from 'react-use/esm/useAsync';
10
10
  export { MultiEntityPickerSchema } from './schema.esm.js';
11
11
 
12
12
  const MultiEntityPicker = (props) => {
13
- var _a, _b, _c, _d, _e;
14
13
  const {
15
14
  onChange,
16
15
  schema: { title = "Entity", description = "An entity from the catalog" },
@@ -21,32 +20,25 @@ const MultiEntityPicker = (props) => {
21
20
  idSchema
22
21
  } = props;
23
22
  const catalogFilter = buildCatalogFilter(uiSchema);
24
- const defaultKind = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.defaultKind;
25
- const defaultNamespace = ((_b = uiSchema["ui:options"]) == null ? void 0 : _b.defaultNamespace) || void 0;
23
+ const defaultKind = uiSchema["ui:options"]?.defaultKind;
24
+ const defaultNamespace = uiSchema["ui:options"]?.defaultNamespace || void 0;
26
25
  const catalogApi = useApi(catalogApiRef);
26
+ const entityPresentationApi = useApi(entityPresentationApiRef);
27
27
  const { value: entities, loading } = useAsync(async () => {
28
28
  const { items } = await catalogApi.getEntities(
29
29
  catalogFilter ? { filter: catalogFilter } : void 0
30
30
  );
31
- return items;
31
+ const entityRefToPresentation = new Map(
32
+ await Promise.all(
33
+ items.map(async (item) => {
34
+ const presentation = await entityPresentationApi.forEntity(item).promise;
35
+ return [stringifyEntityRef(item), presentation];
36
+ })
37
+ )
38
+ );
39
+ return { entities: items, entityRefToPresentation };
32
40
  });
33
- const allowArbitraryValues = (_d = (_c = uiSchema["ui:options"]) == null ? void 0 : _c.allowArbitraryValues) != null ? _d : true;
34
- const getLabel = useCallback(
35
- (ref) => {
36
- try {
37
- return humanizeEntityRef(
38
- parseEntityRef(ref, { defaultKind, defaultNamespace }),
39
- {
40
- defaultKind,
41
- defaultNamespace
42
- }
43
- );
44
- } catch (err) {
45
- return ref;
46
- }
47
- },
48
- [defaultKind, defaultNamespace]
49
- );
41
+ const allowArbitraryValues = uiSchema["ui:options"]?.allowArbitraryValues ?? true;
50
42
  const onSelect = useCallback(
51
43
  (_, refs, reason) => {
52
44
  const values = refs.map((ref) => {
@@ -75,8 +67,8 @@ const MultiEntityPicker = (props) => {
75
67
  [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues]
76
68
  );
77
69
  useEffect(() => {
78
- if ((entities == null ? void 0 : entities.length) === 1) {
79
- onChange([stringifyEntityRef(entities[0])]);
70
+ if (entities?.entities?.length === 1) {
71
+ onChange([stringifyEntityRef(entities?.entities[0])]);
80
72
  }
81
73
  }, [entities, onChange]);
82
74
  return /* @__PURE__ */ React.createElement(
@@ -84,28 +76,22 @@ const MultiEntityPicker = (props) => {
84
76
  {
85
77
  margin: "normal",
86
78
  required,
87
- error: (rawErrors == null ? void 0 : rawErrors.length) > 0 && !formData
79
+ error: rawErrors?.length > 0 && !formData
88
80
  },
89
81
  /* @__PURE__ */ React.createElement(
90
82
  Autocomplete,
91
83
  {
92
84
  multiple: true,
93
85
  filterSelectedOptions: true,
94
- disabled: (entities == null ? void 0 : entities.length) === 1,
95
- id: idSchema == null ? void 0 : idSchema.$id,
96
- value: (
97
- // Since free solo can be enabled, attempt to parse as a full entity ref first, then fall
98
- // back to the given value.
99
- (_e = entities == null ? void 0 : entities.filter(
100
- (e) => formData && formData.includes(stringifyEntityRef(e))
101
- )) != null ? _e : allowArbitraryValues && formData ? formData.map(getLabel) : []
102
- ),
86
+ disabled: entities?.entities?.length === 1,
87
+ id: idSchema?.$id,
103
88
  loading,
104
89
  onChange: onSelect,
105
- options: entities || [],
90
+ options: entities?.entities || [],
91
+ renderOption: (option) => /* @__PURE__ */ React.createElement(EntityDisplayName, { entityRef: option }),
106
92
  getOptionLabel: (option) => (
107
93
  // option can be a string due to freeSolo.
108
- typeof option === "string" ? option : humanizeEntityRef(option, { defaultKind, defaultNamespace })
94
+ typeof option === "string" ? option : entities?.entityRefToPresentation.get(stringifyEntityRef(option))?.entityRef
109
95
  ),
110
96
  autoSelect: true,
111
97
  freeSolo: allowArbitraryValues,
@@ -116,7 +102,10 @@ const MultiEntityPicker = (props) => {
116
102
  label: title,
117
103
  margin: "dense",
118
104
  helperText: description,
119
- FormHelperTextProps: { margin: "dense", style: { marginLeft: 0 } },
105
+ FormHelperTextProps: {
106
+ margin: "dense",
107
+ style: { marginLeft: 0 }
108
+ },
120
109
  variant: "outlined",
121
110
  required,
122
111
  InputProps: {
@@ -142,7 +131,7 @@ function convertOpsValues(value) {
142
131
  if (typeof value === "object" && value.exists) {
143
132
  return CATALOG_FILTER_EXISTS;
144
133
  }
145
- return value == null ? void 0 : value.toString();
134
+ return value?.toString();
146
135
  }
147
136
  function convertSchemaFiltersToQuery(schemaFilters) {
148
137
  const query = {};
@@ -156,8 +145,7 @@ function convertSchemaFiltersToQuery(schemaFilters) {
156
145
  return query;
157
146
  }
158
147
  function buildCatalogFilter(uiSchema) {
159
- var _a;
160
- const catalogFilter = (_a = uiSchema["ui:options"]) == null ? void 0 : _a.catalogFilter;
148
+ const catalogFilter = uiSchema["ui:options"]?.catalogFilter;
161
149
  if (!catalogFilter) {
162
150
  return void 0;
163
151
  }