@backstage/plugin-scaffolder 1.30.1 → 1.31.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +46 -4
  2. package/dist/alpha/components/TemplateEditorPage/{CustomFieldPlaygroud.esm.js → CustomFieldPlayground.esm.js} +3 -3
  3. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlayground.esm.js.map +1 -0
  4. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js +24 -2
  5. package/dist/alpha/components/TemplateEditorPage/TemplateEditorToolbar.esm.js.map +1 -1
  6. package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js +1 -1
  7. package/dist/alpha/components/TemplateEditorPage/TemplateFormPreviewer.esm.js.map +1 -1
  8. package/dist/alpha/components/TemplateListPage/TemplateListPage.esm.js +4 -2
  9. package/dist/alpha/components/TemplateListPage/TemplateListPage.esm.js.map +1 -1
  10. package/dist/alpha/plugin.esm.js +4 -3
  11. package/dist/alpha/plugin.esm.js.map +1 -1
  12. package/dist/alpha.d.ts +23 -0
  13. package/dist/api.esm.js +1 -1
  14. package/dist/api.esm.js.map +1 -1
  15. package/dist/components/ActionsPage/ActionsPage.esm.js +4 -2
  16. package/dist/components/ActionsPage/ActionsPage.esm.js.map +1 -1
  17. package/dist/components/FileBrowser/FileBrowser.esm.js +3 -3
  18. package/dist/components/FileBrowser/FileBrowser.esm.js.map +1 -1
  19. package/dist/components/ListTasksPage/ListTasksPage.esm.js +4 -2
  20. package/dist/components/ListTasksPage/ListTasksPage.esm.js.map +1 -1
  21. package/dist/components/RenderSchema/RenderSchema.esm.js.map +1 -1
  22. package/dist/components/Router/Router.esm.js +9 -1
  23. package/dist/components/Router/Router.esm.js.map +1 -1
  24. package/dist/components/TemplatingExtensionsPage/TemplateFilters.esm.js +132 -0
  25. package/dist/components/TemplatingExtensionsPage/TemplateFilters.esm.js.map +1 -0
  26. package/dist/components/TemplatingExtensionsPage/TemplateGlobals.esm.js +168 -0
  27. package/dist/components/TemplatingExtensionsPage/TemplateGlobals.esm.js.map +1 -0
  28. package/dist/components/TemplatingExtensionsPage/TemplatingExtensionsPage.esm.js +250 -0
  29. package/dist/components/TemplatingExtensionsPage/TemplatingExtensionsPage.esm.js.map +1 -0
  30. package/dist/components/TemplatingExtensionsPage/functionArgs.esm.js +19 -0
  31. package/dist/components/TemplatingExtensionsPage/functionArgs.esm.js.map +1 -0
  32. package/dist/components/TemplatingExtensionsPage/navigation.esm.js +24 -0
  33. package/dist/components/TemplatingExtensionsPage/navigation.esm.js.map +1 -0
  34. package/dist/components/fields/EntityPicker/EntityPicker.esm.js +4 -1
  35. package/dist/components/fields/EntityPicker/EntityPicker.esm.js.map +1 -1
  36. package/dist/index.d.ts +1 -0
  37. package/dist/plugin.esm.js +3 -2
  38. package/dist/plugin.esm.js.map +1 -1
  39. package/dist/routes.esm.js +6 -1
  40. package/dist/routes.esm.js.map +1 -1
  41. package/dist/translation.esm.js +37 -0
  42. package/dist/translation.esm.js.map +1 -1
  43. package/package.json +22 -22
  44. package/dist/alpha/components/TemplateEditorPage/CustomFieldPlaygroud.esm.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,13 +1,55 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
- ## 1.30.1
3
+ ## 1.31.0-next.1
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - 2612de2: Fix EntityPicker field to render description as markdown, matching other form components in the system.
8
- - 40de23c: Fixing a bug where the name for `templatingExtensions` was incorrectly set to `templateExtensions`
7
+ - fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`.
8
+ - 72d019d: Removed various typos
9
9
  - Updated dependencies
10
- - @backstage/plugin-scaffolder-react@1.15.1
10
+ - @backstage/core-components@0.17.2-next.0
11
+ - @backstage/frontend-plugin-api@0.10.2-next.0
12
+ - @backstage/core-compat-api@0.4.2-next.1
13
+ - @backstage/integration@1.16.4-next.1
14
+ - @backstage/plugin-catalog-react@1.18.0-next.1
15
+ - @backstage/plugin-scaffolder-react@1.16.0-next.1
16
+ - @backstage/integration-react@1.2.7-next.1
17
+ - @backstage/catalog-client@1.10.0-next.0
18
+ - @backstage/catalog-model@1.7.3
19
+ - @backstage/core-plugin-api@1.10.6
20
+ - @backstage/errors@1.2.7
21
+ - @backstage/types@1.2.1
22
+ - @backstage/plugin-catalog-common@1.1.4-next.0
23
+ - @backstage/plugin-permission-react@0.4.34-next.0
24
+ - @backstage/plugin-scaffolder-common@1.5.11-next.0
25
+
26
+ ## 1.31.0-next.0
27
+
28
+ ### Minor Changes
29
+
30
+ - 4235e87: add templating extensions page
31
+
32
+ ### Patch Changes
33
+
34
+ - 92c3658: Full support in EntityPicker (and derivatives) for default EntityPresentationApi
35
+ - d7da01d: Fix EntityPicker field to render description as markdown, matching other form components in the system.
36
+ - 36ae651: Fixing a bug where the name for `templatingExtensions` was incorrectly set to `templateExtensions`
37
+ - Updated dependencies
38
+ - @backstage/integration@1.16.4-next.0
39
+ - @backstage/core-compat-api@0.4.2-next.0
40
+ - @backstage/plugin-catalog-react@1.18.0-next.0
41
+ - @backstage/plugin-scaffolder-react@1.16.0-next.0
42
+ - @backstage/catalog-client@1.10.0-next.0
43
+ - @backstage/integration-react@1.2.7-next.0
44
+ - @backstage/catalog-model@1.7.3
45
+ - @backstage/core-components@0.17.1
46
+ - @backstage/core-plugin-api@1.10.6
47
+ - @backstage/errors@1.2.7
48
+ - @backstage/frontend-plugin-api@0.10.1
49
+ - @backstage/types@1.2.1
50
+ - @backstage/plugin-catalog-common@1.1.3
51
+ - @backstage/plugin-permission-react@0.4.33
52
+ - @backstage/plugin-scaffolder-common@1.5.10
11
53
 
12
54
  ## 1.30.0
13
55
 
@@ -37,7 +37,7 @@ const useStyles = makeStyles(
37
37
  }),
38
38
  { name: "ScaffolderCustomFieldExtensionsPlaygroud" }
39
39
  );
40
- const CustomFieldPlaygroud = ({
40
+ const CustomFieldPlayground = ({
41
41
  fieldExtensions = []
42
42
  }) => {
43
43
  const classes = useStyles();
@@ -203,5 +203,5 @@ const CustomFieldPlaygroud = ({
203
203
  ] });
204
204
  };
205
205
 
206
- export { CustomFieldPlaygroud };
207
- //# sourceMappingURL=CustomFieldPlaygroud.esm.js.map
206
+ export { CustomFieldPlayground };
207
+ //# sourceMappingURL=CustomFieldPlayground.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomFieldPlayground.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/CustomFieldPlayground.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 */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport yaml from 'yaml';\nimport validator from '@rjsf/validator-ajv8';\nimport CodeMirror from '@uiw/react-codemirror';\nimport { StreamLanguage } from '@codemirror/language';\nimport { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Accordion from '@material-ui/core/Accordion';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport TextField from '@material-ui/core/TextField';\nimport Button from '@material-ui/core/Button';\nimport InputAdornment from '@material-ui/core/InputAdornment';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport SearchIcon from '@material-ui/icons/Search';\n\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { Form } from '@backstage/plugin-scaffolder-react/alpha';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { TemplateEditorForm } from './TemplateEditorForm';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateRows: 'auto 1fr',\n },\n controls: {\n marginBottom: theme.spacing(3),\n },\n code: {\n width: '100%',\n },\n }),\n { name: 'ScaffolderCustomFieldExtensionsPlaygroud' },\n);\n\nexport const CustomFieldPlayground = ({\n fieldExtensions = [],\n}: {\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) => {\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const fieldOptions = fieldExtensions.filter(field => !!field.schema);\n const [refreshKey, setRefreshKey] = useState(Date.now());\n const [fieldFormState, setFieldFormState] = useState({});\n const [selectedField, setSelectedField] = useState(fieldOptions[0]);\n const sampleFieldTemplate = useMemo(\n () =>\n yaml.stringify({\n parameters: [\n {\n title: `${selectedField.name} Example`,\n properties: {\n [selectedField.name]: {\n type: selectedField.schema?.returnValue?.type,\n 'ui:field': selectedField.name,\n 'ui:options': fieldFormState,\n },\n },\n },\n ],\n }),\n [fieldFormState, selectedField],\n );\n\n const fieldComponents = useMemo(() => {\n return Object.fromEntries(\n fieldExtensions.map(({ name, component }) => [name, component]),\n );\n }, [fieldExtensions]);\n\n const handleSelectionChange = useCallback(\n (selection: FieldExtensionOptions) => {\n setSelectedField(selection);\n setFieldFormState({});\n },\n [setFieldFormState, setSelectedField],\n );\n\n const handleFieldConfigChange = useCallback(\n (state: {}) => {\n setFieldFormState(state);\n // Force TemplateEditorForm to re-render since some fields\n // may not be responsive to ui:option changes\n setRefreshKey(Date.now());\n },\n [setFieldFormState, setRefreshKey],\n );\n\n return (\n <main className={classes.root}>\n <div className={classes.controls}>\n <Autocomplete\n id=\"custom-fields-autocomplete\"\n value={selectedField}\n options={fieldOptions}\n getOptionLabel={option => option.name}\n renderInput={params => (\n <TextField\n {...params}\n aria-label={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n placeholder={t(\n 'templateEditorPage.customFieldExplorer.selectFieldLabel',\n )}\n variant=\"outlined\"\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon />\n </InputAdornment>\n ),\n }}\n />\n )}\n onChange={(_event, option) => {\n if (option) {\n handleSelectionChange(option);\n }\n }}\n disableClearable\n fullWidth\n />\n </div>\n <div>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-code-content\"\n id=\"panel-code-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.preview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <div className={classes.code}>\n <CodeMirror\n readOnly\n theme=\"dark\"\n height=\"100%\"\n width=\"100%\"\n extensions={[StreamLanguage.define(yamlSupport)]}\n value={sampleFieldTemplate}\n />\n </div>\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-preview-content\"\n id=\"panel-preview-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldPreview.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <TemplateEditorForm\n key={refreshKey}\n content={sampleFieldTemplate}\n contentIsSpec\n fieldExtensions={fieldExtensions}\n setErrorText={() => null}\n />\n </AccordionDetails>\n </Accordion>\n <Accordion defaultExpanded>\n <AccordionSummary\n expandIcon={<ExpandMoreIcon />}\n aria-controls=\"panel-options-content\"\n id=\"panel-options-header\"\n >\n <Typography variant=\"h6\">\n {t('templateEditorPage.customFieldExplorer.fieldForm.title')}\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <Form\n showErrorList={false}\n fields={{ ...fieldComponents }}\n noHtml5Validate\n formData={fieldFormState}\n formContext={{ fieldFormState }}\n onSubmit={e => handleFieldConfigChange(e.formData)}\n validator={validator}\n schema={selectedField.schema?.uiOptions || {}}\n experimental_defaultFormStateBehavior={{\n allOf: 'populateDefaults',\n }}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n type=\"submit\"\n disabled={!selectedField.schema?.uiOptions}\n >\n {t(\n 'templateEditorPage.customFieldExplorer.fieldForm.applyButtonTitle',\n )}\n </Button>\n </Form>\n </AccordionDetails>\n </Accordion>\n </div>\n </main>\n );\n};\n"],"names":["yamlSupport"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAM,SAAY,GAAA,UAAA;AAAA,EAChB,CAAU,KAAA,MAAA;AAAA,IACR,IAAM,EAAA;AAAA,MACJ,QAAU,EAAA,aAAA;AAAA,MACV,OAAS,EAAA,MAAA;AAAA,MACT,gBAAkB,EAAA;AAAA,KACpB;AAAA,IACA,QAAU,EAAA;AAAA,MACR,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA,KAC/B;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,KAAO,EAAA;AAAA;AACT,GACF,CAAA;AAAA,EACA,EAAE,MAAM,0CAA2C;AACrD,CAAA;AAEO,MAAM,wBAAwB,CAAC;AAAA,EACpC,kBAAkB;AACpB,CAEM,KAAA;AACJ,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,wBAAwB,CAAA;AACxD,EAAA,MAAM,eAAe,eAAgB,CAAA,MAAA,CAAO,WAAS,CAAC,CAAC,MAAM,MAAM,CAAA;AACnE,EAAA,MAAM,CAAC,UAAY,EAAA,aAAa,IAAI,QAAS,CAAA,IAAA,CAAK,KAAK,CAAA;AACvD,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,QAAA,CAAS,EAAE,CAAA;AACvD,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,IAAI,QAAS,CAAA,YAAA,CAAa,CAAC,CAAC,CAAA;AAClE,EAAA,MAAM,mBAAsB,GAAA,OAAA;AAAA,IAC1B,MACE,KAAK,SAAU,CAAA;AAAA,MACb,UAAY,EAAA;AAAA,QACV;AAAA,UACE,KAAA,EAAO,CAAG,EAAA,aAAA,CAAc,IAAI,CAAA,QAAA,CAAA;AAAA,UAC5B,UAAY,EAAA;AAAA,YACV,CAAC,aAAc,CAAA,IAAI,GAAG;AAAA,cACpB,IAAA,EAAM,aAAc,CAAA,MAAA,EAAQ,WAAa,EAAA,IAAA;AAAA,cACzC,YAAY,aAAc,CAAA,IAAA;AAAA,cAC1B,YAAc,EAAA;AAAA;AAChB;AACF;AACF;AACF,KACD,CAAA;AAAA,IACH,CAAC,gBAAgB,aAAa;AAAA,GAChC;AAEA,EAAM,MAAA,eAAA,GAAkB,QAAQ,MAAM;AACpC,IAAA,OAAO,MAAO,CAAA,WAAA;AAAA,MACZ,eAAA,CAAgB,GAAI,CAAA,CAAC,EAAE,IAAA,EAAM,WAAgB,KAAA,CAAC,IAAM,EAAA,SAAS,CAAC;AAAA,KAChE;AAAA,GACF,EAAG,CAAC,eAAe,CAAC,CAAA;AAEpB,EAAA,MAAM,qBAAwB,GAAA,WAAA;AAAA,IAC5B,CAAC,SAAqC,KAAA;AACpC,MAAA,gBAAA,CAAiB,SAAS,CAAA;AAC1B,MAAA,iBAAA,CAAkB,EAAE,CAAA;AAAA,KACtB;AAAA,IACA,CAAC,mBAAmB,gBAAgB;AAAA,GACtC;AAEA,EAAA,MAAM,uBAA0B,GAAA,WAAA;AAAA,IAC9B,CAAC,KAAc,KAAA;AACb,MAAA,iBAAA,CAAkB,KAAK,CAAA;AAGvB,MAAc,aAAA,CAAA,IAAA,CAAK,KAAK,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,mBAAmB,aAAa;AAAA,GACnC;AAEA,EAAA,uBACG,IAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,OAAA,CAAQ,IACvB,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,QACtB,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,EAAG,EAAA,4BAAA;AAAA,QACH,KAAO,EAAA,aAAA;AAAA,QACP,OAAS,EAAA,YAAA;AAAA,QACT,cAAA,EAAgB,YAAU,MAAO,CAAA,IAAA;AAAA,QACjC,aAAa,CACX,MAAA,qBAAA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACE,GAAG,MAAA;AAAA,YACJ,YAAY,EAAA,CAAA;AAAA,cACV;AAAA,aACF;AAAA,YACA,WAAa,EAAA,CAAA;AAAA,cACX;AAAA,aACF;AAAA,YACA,OAAQ,EAAA,UAAA;AAAA,YACR,UAAY,EAAA;AAAA,cACV,GAAG,MAAO,CAAA,UAAA;AAAA,cACV,gCACG,GAAA,CAAA,cAAA,EAAA,EAAe,UAAS,OACvB,EAAA,QAAA,kBAAA,GAAA,CAAC,cAAW,CACd,EAAA;AAAA;AAEJ;AAAA,SACF;AAAA,QAEF,QAAA,EAAU,CAAC,MAAA,EAAQ,MAAW,KAAA;AAC5B,UAAA,IAAI,MAAQ,EAAA;AACV,YAAA,qBAAA,CAAsB,MAAM,CAAA;AAAA;AAC9B,SACF;AAAA,QACA,gBAAgB,EAAA,IAAA;AAAA,QAChB,SAAS,EAAA;AAAA;AAAA,KAEb,EAAA,CAAA;AAAA,yBACC,KACC,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAC,IAAA,CAAA,SAAA,EAAA,EAAU,iBAAe,IACxB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,UAAA,sBAAa,cAAe,EAAA,EAAA,CAAA;AAAA,YAC5B,eAAc,EAAA,oBAAA;AAAA,YACd,EAAG,EAAA,mBAAA;AAAA,YAEH,8BAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,IACjB,EAAA,QAAA,EAAA,CAAA,CAAE,sDAAsD,CAC3D,EAAA;AAAA;AAAA,SACF;AAAA,4BACC,gBACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,IACtB,EAAA,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,QAAQ,EAAA,IAAA;AAAA,YACR,KAAM,EAAA,MAAA;AAAA,YACN,MAAO,EAAA,MAAA;AAAA,YACP,KAAM,EAAA,MAAA;AAAA,YACN,UAAY,EAAA,CAAC,cAAe,CAAA,MAAA,CAAOA,MAAW,CAAC,CAAA;AAAA,YAC/C,KAAO,EAAA;AAAA;AAAA,WAEX,CACF,EAAA;AAAA,OACF,EAAA,CAAA;AAAA,sBACA,IAAA,CAAC,SAAU,EAAA,EAAA,eAAA,EAAe,IACxB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,UAAA,sBAAa,cAAe,EAAA,EAAA,CAAA;AAAA,YAC5B,eAAc,EAAA,uBAAA;AAAA,YACd,EAAG,EAAA,sBAAA;AAAA,YAEH,8BAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,IACjB,EAAA,QAAA,EAAA,CAAA,CAAE,2DAA2D,CAChE,EAAA;AAAA;AAAA,SACF;AAAA,4BACC,gBACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YAEC,OAAS,EAAA,mBAAA;AAAA,YACT,aAAa,EAAA,IAAA;AAAA,YACb,eAAA;AAAA,YACA,cAAc,MAAM;AAAA,WAAA;AAAA,UAJf;AAAA,SAMT,EAAA;AAAA,OACF,EAAA,CAAA;AAAA,sBACA,IAAA,CAAC,SAAU,EAAA,EAAA,eAAA,EAAe,IACxB,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,gBAAA;AAAA,UAAA;AAAA,YACC,UAAA,sBAAa,cAAe,EAAA,EAAA,CAAA;AAAA,YAC5B,eAAc,EAAA,uBAAA;AAAA,YACd,EAAG,EAAA,sBAAA;AAAA,YAEH,8BAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,IACjB,EAAA,QAAA,EAAA,CAAA,CAAE,wDAAwD,CAC7D,EAAA;AAAA;AAAA,SACF;AAAA,4BACC,gBACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,aAAe,EAAA,KAAA;AAAA,YACf,MAAA,EAAQ,EAAE,GAAG,eAAgB,EAAA;AAAA,YAC7B,eAAe,EAAA,IAAA;AAAA,YACf,QAAU,EAAA,cAAA;AAAA,YACV,WAAA,EAAa,EAAE,cAAe,EAAA;AAAA,YAC9B,QAAU,EAAA,CAAA,CAAA,KAAK,uBAAwB,CAAA,CAAA,CAAE,QAAQ,CAAA;AAAA,YACjD,SAAA;AAAA,YACA,MAAQ,EAAA,aAAA,CAAc,MAAQ,EAAA,SAAA,IAAa,EAAC;AAAA,YAC5C,qCAAuC,EAAA;AAAA,cACrC,KAAO,EAAA;AAAA,aACT;AAAA,YAEA,QAAA,kBAAA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,OAAQ,EAAA,WAAA;AAAA,gBACR,KAAM,EAAA,SAAA;AAAA,gBACN,IAAK,EAAA,QAAA;AAAA,gBACL,QAAA,EAAU,CAAC,aAAA,CAAc,MAAQ,EAAA,SAAA;AAAA,gBAEhC,QAAA,EAAA,CAAA;AAAA,kBACC;AAAA;AACF;AAAA;AACF;AAAA,SAEJ,EAAA;AAAA,OACF,EAAA;AAAA,KACF,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
@@ -14,10 +14,12 @@ import DialogContentText from '@material-ui/core/DialogContentText';
14
14
  import DialogActions from '@material-ui/core/DialogActions';
15
15
  import ExtensionIcon from '@material-ui/icons/Extension';
16
16
  import DescriptionIcon from '@material-ui/icons/Description';
17
+ import FunctionsIcon from '@material-ui/icons/Functions';
17
18
  import { useTranslationRef } from '@backstage/frontend-plugin-api';
18
19
  import { ActionPageContent } from '../../../components/ActionsPage/ActionsPage.esm.js';
19
20
  import { scaffolderTranslationRef } from '../../../translation.esm.js';
20
- import { CustomFieldPlaygroud } from './CustomFieldPlaygroud.esm.js';
21
+ import { CustomFieldPlayground } from './CustomFieldPlayground.esm.js';
22
+ import { TemplatingExtensionsPageContent } from '../../../components/TemplatingExtensionsPage/TemplatingExtensionsPage.esm.js';
21
23
 
22
24
  const useStyles = makeStyles(
23
25
  (theme) => ({
@@ -60,6 +62,7 @@ function TemplateEditorToolbar(props) {
60
62
  const { t } = useTranslationRef(scaffolderTranslationRef);
61
63
  const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);
62
64
  const [showActionsDrawer, setShowActionsDrawer] = useState(false);
65
+ const [showExtensionsDrawer, setShowExtensionsDrawer] = useState(false);
63
66
  const [showPublishModal, setShowPublishModal] = useState(false);
64
67
  return /* @__PURE__ */ jsx(AppBar, { className: classes.appbar, position: "relative", children: /* @__PURE__ */ jsxs(Toolbar, { className: classes.toolbar, children: [
65
68
  /* @__PURE__ */ jsx("div", { className: classes.toolbarCustomActions, children }),
@@ -80,6 +83,15 @@ function TemplateEditorToolbar(props) {
80
83
  children: /* @__PURE__ */ jsx(Button, { onClick: () => setShowActionsDrawer(true), children: /* @__PURE__ */ jsx(DescriptionIcon, {}) })
81
84
  }
82
85
  ),
86
+ /* @__PURE__ */ jsx(
87
+ Tooltip,
88
+ {
89
+ title: t(
90
+ "templateEditorToolbar.templatingExtensionsDocumentationTooltip"
91
+ ),
92
+ children: /* @__PURE__ */ jsx(Button, { onClick: () => setShowExtensionsDrawer(true), children: /* @__PURE__ */ jsx(FunctionsIcon, {}) })
93
+ }
94
+ ),
83
95
  /* @__PURE__ */ jsx(Button, { onClick: () => setShowPublishModal(true), children: t("templateEditorToolbar.addToCatalogButton") })
84
96
  ] }),
85
97
  /* @__PURE__ */ jsx(
@@ -89,7 +101,7 @@ function TemplateEditorToolbar(props) {
89
101
  anchor: "right",
90
102
  open: showFieldsDrawer,
91
103
  onClose: () => setShowFieldsDrawer(false),
92
- children: /* @__PURE__ */ jsx(CustomFieldPlaygroud, { fieldExtensions })
104
+ children: /* @__PURE__ */ jsx(CustomFieldPlayground, { fieldExtensions })
93
105
  }
94
106
  ),
95
107
  /* @__PURE__ */ jsx(
@@ -102,6 +114,16 @@ function TemplateEditorToolbar(props) {
102
114
  children: /* @__PURE__ */ jsx(ActionPageContent, {})
103
115
  }
104
116
  ),
117
+ /* @__PURE__ */ jsx(
118
+ Drawer,
119
+ {
120
+ classes: { paper: classes.paper },
121
+ anchor: "right",
122
+ open: showExtensionsDrawer,
123
+ onClose: () => setShowExtensionsDrawer(false),
124
+ children: /* @__PURE__ */ jsx(TemplatingExtensionsPageContent, {})
125
+ }
126
+ ),
105
127
  /* @__PURE__ */ jsxs(
106
128
  Dialog,
107
129
  {
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditorToolbar.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { ReactNode, useState } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport ExtensionIcon from '@material-ui/icons/Extension';\nimport DescriptionIcon from '@material-ui/icons/Description';\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { ActionPageContent } from '../../../components/ActionsPage/ActionsPage';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { CustomFieldPlaygroud } from './CustomFieldPlaygroud';\n\nconst useStyles = makeStyles(\n theme => ({\n paper: {\n width: '90%',\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n [theme.breakpoints.up('sm')]: {\n width: '70%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n },\n appbar: {\n zIndex: 1,\n },\n toolbar: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gridGap: theme.spacing(1),\n padding: theme.spacing(0, 1),\n backgroundColor: theme.palette.background.paper,\n },\n toolbarCustomActions: {\n display: 'grid',\n alignItems: 'center',\n gridAutoFlow: 'Column',\n gridGap: theme.spacing(1),\n },\n toolbarDefaultActions: {\n justifySelf: 'end',\n },\n }),\n { name: 'ScaffolderTemplateEditorToolbar' },\n);\n\nexport function TemplateEditorToolbar(props: {\n children?: ReactNode;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) {\n const { children, fieldExtensions } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);\n const [showActionsDrawer, setShowActionsDrawer] = useState(false);\n const [showPublishModal, setShowPublishModal] = useState(false);\n\n return (\n <AppBar className={classes.appbar} position=\"relative\">\n <Toolbar className={classes.toolbar}>\n <div className={classes.toolbarCustomActions}>{children}</div>\n <ButtonGroup className={classes.toolbarDefaultActions} variant=\"text\">\n <Tooltip\n title={t('templateEditorToolbar.customFieldExplorerTooltip')}\n >\n <Button onClick={() => setShowFieldsDrawer(true)}>\n <ExtensionIcon />\n </Button>\n </Tooltip>\n <Tooltip\n title={t(\n 'templateEditorToolbar.installedActionsDocumentationTooltip',\n )}\n >\n <Button onClick={() => setShowActionsDrawer(true)}>\n <DescriptionIcon />\n </Button>\n </Tooltip>\n <Button onClick={() => setShowPublishModal(true)}>\n {t('templateEditorToolbar.addToCatalogButton')}\n </Button>\n </ButtonGroup>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showFieldsDrawer}\n onClose={() => setShowFieldsDrawer(false)}\n >\n <CustomFieldPlaygroud fieldExtensions={fieldExtensions} />\n </Drawer>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showActionsDrawer}\n onClose={() => setShowActionsDrawer(false)}\n >\n <ActionPageContent />\n </Drawer>\n <Dialog\n onClose={() => setShowPublishModal(false)}\n open={showPublishModal}\n aria-labelledby=\"publish-dialog-title\"\n aria-describedby=\"publish-dialog-description\"\n >\n <DialogTitle id=\"publish-dialog-title\">\n {t('templateEditorToolbar.addToCatalogDialogTitle')}\n </DialogTitle>\n <DialogContent dividers>\n <DialogContentText id=\"publish-dialog-slide-description\">\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction',\n )}\n <ul>\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsListItems',\n )\n .split('\\n')\n .map((step, index) => (\n <li key={index}>{step}</li>\n ))}\n </ul>\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button\n color=\"primary\"\n href={t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationUrl',\n )}\n target=\"_blank\"\n >\n {t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationButton',\n )}\n </Button>\n </DialogActions>\n </Dialog>\n </Toolbar>\n </AppBar>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateEditorToolbar.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateEditorToolbar.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { ReactNode, useState } from 'react';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\nimport Button from '@material-ui/core/Button';\nimport Drawer from '@material-ui/core/Drawer';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport ExtensionIcon from '@material-ui/icons/Extension';\nimport DescriptionIcon from '@material-ui/icons/Description';\nimport FunctionsIcon from '@material-ui/icons/Functions';\n\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react';\n\nimport { ActionPageContent } from '../../../components/ActionsPage/ActionsPage';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { CustomFieldPlayground } from './CustomFieldPlayground';\nimport { TemplatingExtensionsPageContent } from '../../../components/TemplatingExtensionsPage/TemplatingExtensionsPage';\n\nconst useStyles = makeStyles(\n theme => ({\n paper: {\n width: '90%',\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n [theme.breakpoints.up('sm')]: {\n width: '70%',\n },\n [theme.breakpoints.up('md')]: {\n width: '50%',\n },\n },\n appbar: {\n zIndex: 1,\n },\n toolbar: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gridGap: theme.spacing(1),\n padding: theme.spacing(0, 1),\n backgroundColor: theme.palette.background.paper,\n },\n toolbarCustomActions: {\n display: 'grid',\n alignItems: 'center',\n gridAutoFlow: 'Column',\n gridGap: theme.spacing(1),\n },\n toolbarDefaultActions: {\n justifySelf: 'end',\n },\n }),\n { name: 'ScaffolderTemplateEditorToolbar' },\n);\n\nexport function TemplateEditorToolbar(props: {\n children?: ReactNode;\n fieldExtensions?: FieldExtensionOptions<any, any>[];\n}) {\n const { children, fieldExtensions } = props;\n const classes = useStyles();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const [showFieldsDrawer, setShowFieldsDrawer] = useState(false);\n const [showActionsDrawer, setShowActionsDrawer] = useState(false);\n const [showExtensionsDrawer, setShowExtensionsDrawer] = useState(false);\n const [showPublishModal, setShowPublishModal] = useState(false);\n\n return (\n <AppBar className={classes.appbar} position=\"relative\">\n <Toolbar className={classes.toolbar}>\n <div className={classes.toolbarCustomActions}>{children}</div>\n <ButtonGroup className={classes.toolbarDefaultActions} variant=\"text\">\n <Tooltip\n title={t('templateEditorToolbar.customFieldExplorerTooltip')}\n >\n <Button onClick={() => setShowFieldsDrawer(true)}>\n <ExtensionIcon />\n </Button>\n </Tooltip>\n <Tooltip\n title={t(\n 'templateEditorToolbar.installedActionsDocumentationTooltip',\n )}\n >\n <Button onClick={() => setShowActionsDrawer(true)}>\n <DescriptionIcon />\n </Button>\n </Tooltip>\n <Tooltip\n title={t(\n 'templateEditorToolbar.templatingExtensionsDocumentationTooltip',\n )}\n >\n <Button onClick={() => setShowExtensionsDrawer(true)}>\n <FunctionsIcon />\n </Button>\n </Tooltip>\n <Button onClick={() => setShowPublishModal(true)}>\n {t('templateEditorToolbar.addToCatalogButton')}\n </Button>\n </ButtonGroup>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showFieldsDrawer}\n onClose={() => setShowFieldsDrawer(false)}\n >\n <CustomFieldPlayground fieldExtensions={fieldExtensions} />\n </Drawer>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showActionsDrawer}\n onClose={() => setShowActionsDrawer(false)}\n >\n <ActionPageContent />\n </Drawer>\n <Drawer\n classes={{ paper: classes.paper }}\n anchor=\"right\"\n open={showExtensionsDrawer}\n onClose={() => setShowExtensionsDrawer(false)}\n >\n <TemplatingExtensionsPageContent />\n </Drawer>\n <Dialog\n onClose={() => setShowPublishModal(false)}\n open={showPublishModal}\n aria-labelledby=\"publish-dialog-title\"\n aria-describedby=\"publish-dialog-description\"\n >\n <DialogTitle id=\"publish-dialog-title\">\n {t('templateEditorToolbar.addToCatalogDialogTitle')}\n </DialogTitle>\n <DialogContent dividers>\n <DialogContentText id=\"publish-dialog-slide-description\">\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction',\n )}\n <ul>\n {t(\n 'templateEditorToolbar.addToCatalogDialogContent.stepsListItems',\n )\n .split('\\n')\n .map((step, index) => (\n <li key={index}>{step}</li>\n ))}\n </ul>\n </DialogContentText>\n </DialogContent>\n <DialogActions>\n <Button\n color=\"primary\"\n href={t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationUrl',\n )}\n target=\"_blank\"\n >\n {t(\n 'templateEditorToolbar.addToCatalogDialogActions.documentationButton',\n )}\n </Button>\n </DialogActions>\n </Dialog>\n </Toolbar>\n </AppBar>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -117,7 +117,7 @@ const TemplateFormPreviewer = ({
117
117
  )
118
118
  ).catch(
119
119
  (e) => alertApi.post({
120
- message: `Error loading exisiting templates: ${e.message}`,
120
+ message: `Error loading existing templates: ${e.message}`,
121
121
  severity: "error"
122
122
  })
123
123
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.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 */\n\nimport yaml from 'yaml';\nimport { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\n\nimport {\n TemplateEditorLayout,\n TemplateEditorLayoutToolbar,\n TemplateEditorLayoutFiles,\n TemplateEditorLayoutPreview,\n} from './TemplateEditorLayout';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu';\nimport {\n TemplateOption,\n TemplateEditorToolbarTemplatesMenu,\n} from './TemplateEditorToolbarTemplatesMenu';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'toolbar'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar\"\n \"textArea\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n },\n files: {\n gridArea: 'textArea',\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] = useState<TemplateOption>();\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const handleCloseDirectory = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(({ items }) =>\n setTemplateOptions(\n items.map(template => ({\n label:\n template.metadata.title ??\n humanizeEntityRef(template, { defaultKind: 'template' }),\n value: template,\n })),\n ),\n )\n .catch(e =>\n alertApi.post({\n message: `Error loading exisiting templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: TemplateOption) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.value.spec));\n },\n [setSelectedTemplate, setTemplateYaml],\n );\n\n return (\n <TemplateEditorLayout classes={{ root: classes.root }}>\n <TemplateEditorLayoutToolbar>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <TemplateEditorToolbarFileMenu\n onCloseDirectory={handleCloseDirectory}\n />\n <TemplateEditorToolbarTemplatesMenu\n options={templateOptions}\n selectedOption={selectedTemplate}\n onSelectOption={handleSelectChange}\n />\n </TemplateEditorToolbar>\n </TemplateEditorLayoutToolbar>\n <TemplateEditorLayoutFiles classes={{ root: classes.files }}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </TemplateEditorLayoutFiles>\n <TemplateEditorLayoutPreview>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </TemplateEditorLayoutPreview>\n </TemplateEditorLayout>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAmDA,MAAM,4BAA+B,GAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA+CrC,MAAM,SAAY,GAAA,UAAA;AAAA,EAChB,CAAU,KAAA,MAAA;AAAA,IACR,IAAM,EAAA;AAAA,MACJ,MAAQ,EAAA,MAAA;AAAA,MACR,QAAU,EAAA,aAAA;AAAA,MACV,OAAS,EAAA,MAAA;AAAA,MACT,iBAAmB,EAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,MAKnB,CAAC,KAAM,CAAA,WAAA,CAAY,EAAG,CAAA,IAAI,CAAC,GAAG;AAAA,QAC5B,iBAAmB,EAAA;AAAA;AAAA;AAAA,IAAA,CAAA;AAAA,QAInB,gBAAkB,EAAA,UAAA;AAAA,QAClB,mBAAqB,EAAA;AAAA;AACvB,KACF;AAAA,IACA,KAAO,EAAA;AAAA,MACL,QAAU,EAAA;AAAA;AACZ,GACF,CAAA;AAAA,EACA,EAAE,MAAM,iCAAkC;AAC5C,CAAA;AAEO,MAAM,wBAAwB,CAAC;AAAA,EACpC,sBAAyB,GAAA,4BAAA;AAAA,EACzB,wBAAwB,EAAC;AAAA,EACzB,UAAU,EAAC;AAAA,EACX;AACF,CAMM,KAAA;AACJ,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAM,MAAA,QAAA,GAAW,YAAY,YAAY,CAAA;AAEzC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,QAAiB,EAAA;AACnD,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,QAAyB,EAAA;AACzE,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAA,QAAA,CAA2B,EAAE,CAAA;AAC3E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,sBAAsB,CAAA;AAEvE,EAAM,MAAA,oBAAA,GAAuB,YAAY,MAAM;AAC7C,IAAA,QAAA,CAAS,UAAU,CAAA;AAAA,GAClB,EAAA,CAAC,QAAU,EAAA,QAAQ,CAAC,CAAA;AAEvB,EAAA,QAAA;AAAA,IACE,MACE,WACG,WAAY,CAAA;AAAA,MACX,MAAA,EAAQ,EAAE,IAAA,EAAM,UAAW,EAAA;AAAA,MAC3B,MAAQ,EAAA;AAAA,QACN,MAAA;AAAA,QACA,oBAAA;AAAA,QACA,eAAA;AAAA,QACA,gBAAA;AAAA,QACA,iBAAA;AAAA,QACA,YAAA;AAAA,QACA;AAAA;AACF,KACD,CACA,CAAA,IAAA;AAAA,MAAK,CAAC,EAAE,KAAA,EACP,KAAA,kBAAA;AAAA,QACE,KAAA,CAAM,IAAI,CAAa,QAAA,MAAA;AAAA,UACrB,KAAA,EACE,SAAS,QAAS,CAAA,KAAA,IAClB,kBAAkB,QAAU,EAAA,EAAE,WAAa,EAAA,UAAA,EAAY,CAAA;AAAA,UACzD,KAAO,EAAA;AAAA,SACP,CAAA;AAAA;AACJ,KAED,CAAA,KAAA;AAAA,MAAM,CAAA,CAAA,KACL,SAAS,IAAK,CAAA;AAAA,QACZ,OAAA,EAAS,CAAsC,mCAAA,EAAA,CAAA,CAAE,OAAO,CAAA,CAAA;AAAA,QACxD,QAAU,EAAA;AAAA,OACX;AAAA,KACH;AAAA,IACJ,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA;AAAA,IAEzB,CAAC,QAA6B,KAAA;AAC5B,MAAA,mBAAA,CAAoB,QAAQ,CAAA;AAC5B,MAAA,eAAA,CAAgB,IAAK,CAAA,SAAA,CAAU,QAAS,CAAA,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,KACrD;AAAA,IACA,CAAC,qBAAqB,eAAe;AAAA,GACvC;AAEA,EAAA,4BACG,oBAAqB,EAAA,EAAA,OAAA,EAAS,EAAE,IAAM,EAAA,OAAA,CAAQ,MAC7C,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,2BACC,EAAA,EAAA,QAAA,kBAAA,IAAA,CAAC,qBAAsB,EAAA,EAAA,eAAA,EAAiB,qBACtC,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,6BAAA;AAAA,QAAA;AAAA,UACC,gBAAkB,EAAA;AAAA;AAAA,OACpB;AAAA,sBACA,GAAA;AAAA,QAAC,kCAAA;AAAA,QAAA;AAAA,UACC,OAAS,EAAA,eAAA;AAAA,UACT,cAAgB,EAAA,gBAAA;AAAA,UAChB,cAAgB,EAAA;AAAA;AAAA;AAClB,KAAA,EACF,CACF,EAAA,CAAA;AAAA,wBACC,yBAA0B,EAAA,EAAA,OAAA,EAAS,EAAE,IAAM,EAAA,OAAA,CAAQ,OAClD,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,sBAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,YAAA;AAAA,QACT,QAAU,EAAA,eAAA;AAAA,QACV;AAAA;AAAA,KAEJ,EAAA,CAAA;AAAA,wBACC,2BACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,YAAA;AAAA,QACT,aAAa,EAAA,IAAA;AAAA,QACb,eAAiB,EAAA,qBAAA;AAAA,QACjB,YAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA;AAAA,KAEJ,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TemplateFormPreviewer.esm.js","sources":["../../../../src/alpha/components/TemplateEditorPage/TemplateFormPreviewer.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 */\n\nimport yaml from 'yaml';\nimport { useCallback, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport {\n LayoutOptions,\n FieldExtensionOptions,\n FormProps,\n} from '@backstage/plugin-scaffolder-react';\n\nimport { editRouteRef } from '../../../routes';\n\nimport {\n TemplateEditorLayout,\n TemplateEditorLayoutToolbar,\n TemplateEditorLayoutFiles,\n TemplateEditorLayoutPreview,\n} from './TemplateEditorLayout';\nimport { TemplateEditorToolbar } from './TemplateEditorToolbar';\nimport { TemplateEditorToolbarFileMenu } from './TemplateEditorToolbarFileMenu';\nimport {\n TemplateOption,\n TemplateEditorToolbarTemplatesMenu,\n} from './TemplateEditorToolbarTemplatesMenu';\nimport { TemplateEditorForm } from './TemplateEditorForm';\nimport { TemplateEditorTextArea } from './TemplateEditorTextArea';\n\nconst EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI\nparameters:\n - title: Fill in some steps\n required:\n - name\n properties:\n name:\n title: Name\n type: string\n description: Unique name of the component\n owner:\n title: Owner\n type: string\n description: Owner of the component\n ui:field: OwnerPicker\n ui:options:\n catalogFilter:\n kind: Group\n - title: Choose a location\n required:\n - repoUrl\n properties:\n repoUrl:\n title: Repository Location\n type: string\n ui:field: RepoUrlPicker\n ui:options:\n allowedHosts:\n - github.com\nsteps:\n - id: fetch-base\n name: Fetch Base\n action: fetch:template\n input:\n url: ./template\n values:\n name: \\${{parameters.name}}\n`;\n\n/** @public */\nexport type ScaffolderTemplateFormPreviewerClassKey =\n | 'root'\n | 'toolbar'\n | 'controls'\n | 'textArea'\n | 'preview';\n\nconst useStyles = makeStyles(\n theme => ({\n root: {\n height: '100%',\n gridArea: 'pageContent',\n display: 'grid',\n gridTemplateAreas: `\n \"toolbar\"\n \"textArea\"\n \"preview\"\n `,\n [theme.breakpoints.up('md')]: {\n gridTemplateAreas: `\n \"toolbar toolbar\"\n \"textArea preview\"\n `,\n gridTemplateRows: 'auto 1fr',\n gridTemplateColumns: '1fr 1fr',\n },\n },\n files: {\n gridArea: 'textArea',\n },\n }),\n { name: 'ScaffolderTemplateFormPreviewer' },\n);\n\nexport const TemplateFormPreviewer = ({\n defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML,\n customFieldExtensions = [],\n layouts = [],\n formProps,\n}: {\n defaultPreviewTemplate?: string;\n customFieldExtensions?: FieldExtensionOptions<any, any>[];\n onClose?: () => void;\n layouts?: LayoutOptions[];\n formProps?: FormProps;\n}) => {\n const classes = useStyles();\n const alertApi = useApi(alertApiRef);\n const catalogApi = useApi(catalogApiRef);\n const navigate = useNavigate();\n const editLink = useRouteRef(editRouteRef);\n\n const [errorText, setErrorText] = useState<string>();\n const [selectedTemplate, setSelectedTemplate] = useState<TemplateOption>();\n const [templateOptions, setTemplateOptions] = useState<TemplateOption[]>([]);\n const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate);\n\n const handleCloseDirectory = useCallback(() => {\n navigate(editLink());\n }, [navigate, editLink]);\n\n useAsync(\n () =>\n catalogApi\n .getEntities({\n filter: { kind: 'template' },\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n 'spec.parameters',\n 'spec.steps',\n 'spec.output',\n ],\n })\n .then(({ items }) =>\n setTemplateOptions(\n items.map(template => ({\n label:\n template.metadata.title ??\n humanizeEntityRef(template, { defaultKind: 'template' }),\n value: template,\n })),\n ),\n )\n .catch(e =>\n alertApi.post({\n message: `Error loading existing templates: ${e.message}`,\n severity: 'error',\n }),\n ),\n [catalogApi],\n );\n\n const handleSelectChange = useCallback(\n // TODO(Rugvip): Afaik this should be Entity, but didn't want to make runtime changes while fixing types\n (selected: TemplateOption) => {\n setSelectedTemplate(selected);\n setTemplateYaml(yaml.stringify(selected.value.spec));\n },\n [setSelectedTemplate, setTemplateYaml],\n );\n\n return (\n <TemplateEditorLayout classes={{ root: classes.root }}>\n <TemplateEditorLayoutToolbar>\n <TemplateEditorToolbar fieldExtensions={customFieldExtensions}>\n <TemplateEditorToolbarFileMenu\n onCloseDirectory={handleCloseDirectory}\n />\n <TemplateEditorToolbarTemplatesMenu\n options={templateOptions}\n selectedOption={selectedTemplate}\n onSelectOption={handleSelectChange}\n />\n </TemplateEditorToolbar>\n </TemplateEditorLayoutToolbar>\n <TemplateEditorLayoutFiles classes={{ root: classes.files }}>\n <TemplateEditorTextArea\n content={templateYaml}\n onUpdate={setTemplateYaml}\n errorText={errorText}\n />\n </TemplateEditorLayoutFiles>\n <TemplateEditorLayoutPreview>\n <TemplateEditorForm\n content={templateYaml}\n contentIsSpec\n fieldExtensions={customFieldExtensions}\n setErrorText={setErrorText}\n layouts={layouts}\n formProps={formProps}\n />\n </TemplateEditorLayoutPreview>\n </TemplateEditorLayout>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { DocsIcon, Page, Header, Content, ContentHeader, SupportButton } from '@
6
6
  import { EntityListProvider, CatalogFilterLayout, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, EntityOwnerPicker } from '@backstage/plugin-catalog-react';
7
7
  import { ScaffolderPageContextMenu, TemplateCategoryPicker, TemplateGroups } from '@backstage/plugin-scaffolder-react/alpha';
8
8
  import { RegisterExistingButton } from './RegisterExistingButton.esm.js';
9
- import { registerComponentRouteRef, editRouteRef, actionsRouteRef, scaffolderListTaskRouteRef, viewTechDocRouteRef, selectedTemplateRouteRef } from '../../../routes.esm.js';
9
+ import { registerComponentRouteRef, editRouteRef, actionsRouteRef, scaffolderListTaskRouteRef, viewTechDocRouteRef, selectedTemplateRouteRef, templatingExtensionsRouteRef } from '../../../routes.esm.js';
10
10
  import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
11
11
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
12
12
  import { scaffolderTranslationRef } from '../../../translation.esm.js';
@@ -32,6 +32,7 @@ const TemplateListPage = (props) => {
32
32
  const tasksLink = useRouteRef(scaffolderListTaskRouteRef);
33
33
  const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);
34
34
  const templateRoute = useRouteRef(selectedTemplateRouteRef);
35
+ const templatingExtensionsLink = useRouteRef(templatingExtensionsRouteRef);
35
36
  const app = useApp();
36
37
  const { t } = useTranslationRef(scaffolderTranslationRef);
37
38
  const groups = givenGroups.length ? createGroupsWithOther(givenGroups, t) : [
@@ -43,7 +44,8 @@ const TemplateListPage = (props) => {
43
44
  const scaffolderPageContextMenuProps = {
44
45
  onEditorClicked: props?.contextMenu?.editor !== false ? () => navigate(editorLink()) : void 0,
45
46
  onActionsClicked: props?.contextMenu?.actions !== false ? () => navigate(actionsLink()) : void 0,
46
- onTasksClicked: props?.contextMenu?.tasks !== false ? () => navigate(tasksLink()) : void 0
47
+ onTasksClicked: props?.contextMenu?.tasks !== false ? () => navigate(tasksLink()) : void 0,
48
+ onTemplatingExtensionsClicked: props?.contextMenu?.templatingExtensions !== false ? () => navigate(templatingExtensionsLink()) : void 0
47
49
  };
48
50
  const additionalLinksForEntity = useCallback(
49
51
  (template) => {
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateListPage.esm.js","sources":["../../../../src/alpha/components/TemplateListPage/TemplateListPage.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 */\n\nimport { ComponentType, useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { useApp, useRouteRef } from '@backstage/core-plugin-api';\n\nimport {\n Content,\n ContentHeader,\n DocsIcon,\n Header,\n Page,\n SupportButton,\n} from '@backstage/core-components';\nimport {\n EntityKindPicker,\n EntityListProvider,\n EntitySearchBar,\n EntityTagPicker,\n CatalogFilterLayout,\n UserListPicker,\n EntityOwnerPicker,\n} from '@backstage/plugin-catalog-react';\nimport {\n ScaffolderPageContextMenu,\n TemplateCategoryPicker,\n TemplateGroups,\n} from '@backstage/plugin-scaffolder-react/alpha';\n\nimport { RegisterExistingButton } from './RegisterExistingButton';\nimport {\n actionsRouteRef,\n editRouteRef,\n registerComponentRouteRef,\n scaffolderListTaskRouteRef,\n selectedTemplateRouteRef,\n viewTechDocRouteRef,\n} from '../../../routes';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\n/**\n * @alpha\n */\nexport type TemplateListPageProps = {\n TemplateCardComponent?: ComponentType<{\n template: TemplateEntityV1beta3;\n }>;\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n contextMenu?: {\n editor?: boolean;\n actions?: boolean;\n tasks?: boolean;\n };\n headerOptions?: {\n pageTitleOverride?: string;\n title?: string;\n subtitle?: string;\n };\n};\n\nconst createGroupsWithOther = (\n groups: TemplateGroupFilter[],\n t: TranslationFunction<typeof scaffolderTranslationRef.T>,\n): TemplateGroupFilter[] => [\n ...groups,\n {\n title: t('templateListPage.templateGroups.otherTitle'),\n filter: e => ![...groups].some(({ filter }) => filter(e)),\n },\n];\n\n/**\n * @alpha\n */\nexport const TemplateListPage = (props: TemplateListPageProps) => {\n const registerComponentLink = useRouteRef(registerComponentRouteRef);\n const {\n TemplateCardComponent,\n groups: givenGroups = [],\n templateFilter,\n headerOptions,\n } = props;\n const navigate = useNavigate();\n const editorLink = useRouteRef(editRouteRef);\n const actionsLink = useRouteRef(actionsRouteRef);\n const tasksLink = useRouteRef(scaffolderListTaskRouteRef);\n const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);\n const templateRoute = useRouteRef(selectedTemplateRouteRef);\n const app = useApp();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const groups = givenGroups.length\n ? createGroupsWithOther(givenGroups, t)\n : [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\n ];\n\n const scaffolderPageContextMenuProps = {\n onEditorClicked:\n props?.contextMenu?.editor !== false\n ? () => navigate(editorLink())\n : undefined,\n onActionsClicked:\n props?.contextMenu?.actions !== false\n ? () => navigate(actionsLink())\n : undefined,\n onTasksClicked:\n props?.contextMenu?.tasks !== false\n ? () => navigate(tasksLink())\n : undefined,\n };\n\n const additionalLinksForEntity = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { kind, namespace, name } = parseEntityRef(\n stringifyEntityRef(template),\n );\n return template.metadata.annotations?.['backstage.io/techdocs-ref'] &&\n viewTechDocsLink\n ? [\n {\n icon: app.getSystemIcon('docs') ?? DocsIcon,\n text: t(\n 'templateListPage.additionalLinksForEntity.viewTechDocsTitle',\n ),\n url: viewTechDocsLink({ kind, namespace, name }),\n },\n ]\n : [];\n },\n [app, viewTechDocsLink, t],\n );\n\n const onTemplateSelected = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { namespace, name } = parseEntityRef(stringifyEntityRef(template));\n\n navigate(templateRoute({ namespace, templateName: name }));\n },\n [navigate, templateRoute],\n );\n\n return (\n <EntityListProvider>\n <Page themeId=\"home\">\n <Header\n pageTitleOverride={t('templateListPage.pageTitle')}\n title={t('templateListPage.title')}\n subtitle={t('templateListPage.subtitle')}\n {...headerOptions}\n >\n <ScaffolderPageContextMenu {...scaffolderPageContextMenuProps} />\n </Header>\n <Content>\n <ContentHeader>\n <RegisterExistingButton\n title={t(\n 'templateListPage.contentHeader.registerExistingButtonTitle',\n )}\n to={registerComponentLink && registerComponentLink()}\n />\n <SupportButton>\n {t('templateListPage.contentHeader.supportButtonTitle')}\n </SupportButton>\n </ContentHeader>\n\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>\n <EntitySearchBar />\n <EntityKindPicker initialFilter=\"template\" hidden />\n <UserListPicker\n initialFilter=\"all\"\n availableFilters={['all', 'starred']}\n />\n <TemplateCategoryPicker />\n <EntityTagPicker />\n <EntityOwnerPicker />\n </CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>\n <TemplateGroups\n groups={groups}\n templateFilter={templateFilter}\n TemplateCardComponent={TemplateCardComponent}\n onTemplateSelected={onTemplateSelected}\n additionalLinksForEntity={additionalLinksForEntity}\n />\n </CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </Content>\n </Page>\n </EntityListProvider>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateListPage.esm.js","sources":["../../../../src/alpha/components/TemplateListPage/TemplateListPage.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 */\n\nimport { ComponentType, useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';\nimport { useApp, useRouteRef } from '@backstage/core-plugin-api';\n\nimport {\n Content,\n ContentHeader,\n DocsIcon,\n Header,\n Page,\n SupportButton,\n} from '@backstage/core-components';\nimport {\n EntityKindPicker,\n EntityListProvider,\n EntitySearchBar,\n EntityTagPicker,\n CatalogFilterLayout,\n UserListPicker,\n EntityOwnerPicker,\n} from '@backstage/plugin-catalog-react';\nimport {\n ScaffolderPageContextMenu,\n TemplateCategoryPicker,\n TemplateGroups,\n} from '@backstage/plugin-scaffolder-react/alpha';\n\nimport { RegisterExistingButton } from './RegisterExistingButton';\nimport {\n actionsRouteRef,\n editRouteRef,\n registerComponentRouteRef,\n scaffolderListTaskRouteRef,\n selectedTemplateRouteRef,\n templatingExtensionsRouteRef,\n viewTechDocRouteRef,\n} from '../../../routes';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react';\nimport {\n TranslationFunction,\n useTranslationRef,\n} from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\n\n/**\n * @alpha\n */\nexport type TemplateListPageProps = {\n TemplateCardComponent?: ComponentType<{\n template: TemplateEntityV1beta3;\n }>;\n groups?: TemplateGroupFilter[];\n templateFilter?: (entity: TemplateEntityV1beta3) => boolean;\n contextMenu?: {\n editor?: boolean;\n actions?: boolean;\n tasks?: boolean;\n templatingExtensions?: boolean;\n };\n headerOptions?: {\n pageTitleOverride?: string;\n title?: string;\n subtitle?: string;\n };\n};\n\nconst createGroupsWithOther = (\n groups: TemplateGroupFilter[],\n t: TranslationFunction<typeof scaffolderTranslationRef.T>,\n): TemplateGroupFilter[] => [\n ...groups,\n {\n title: t('templateListPage.templateGroups.otherTitle'),\n filter: e => ![...groups].some(({ filter }) => filter(e)),\n },\n];\n\n/**\n * @alpha\n */\nexport const TemplateListPage = (props: TemplateListPageProps) => {\n const registerComponentLink = useRouteRef(registerComponentRouteRef);\n const {\n TemplateCardComponent,\n groups: givenGroups = [],\n templateFilter,\n headerOptions,\n } = props;\n const navigate = useNavigate();\n const editorLink = useRouteRef(editRouteRef);\n const actionsLink = useRouteRef(actionsRouteRef);\n const tasksLink = useRouteRef(scaffolderListTaskRouteRef);\n const viewTechDocsLink = useRouteRef(viewTechDocRouteRef);\n const templateRoute = useRouteRef(selectedTemplateRouteRef);\n const templatingExtensionsLink = useRouteRef(templatingExtensionsRouteRef);\n const app = useApp();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n\n const groups = givenGroups.length\n ? createGroupsWithOther(givenGroups, t)\n : [\n {\n title: t('templateListPage.templateGroups.defaultTitle'),\n filter: () => true,\n },\n ];\n\n const scaffolderPageContextMenuProps = {\n onEditorClicked:\n props?.contextMenu?.editor !== false\n ? () => navigate(editorLink())\n : undefined,\n onActionsClicked:\n props?.contextMenu?.actions !== false\n ? () => navigate(actionsLink())\n : undefined,\n onTasksClicked:\n props?.contextMenu?.tasks !== false\n ? () => navigate(tasksLink())\n : undefined,\n onTemplatingExtensionsClicked:\n props?.contextMenu?.templatingExtensions !== false\n ? () => navigate(templatingExtensionsLink())\n : undefined,\n };\n\n const additionalLinksForEntity = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { kind, namespace, name } = parseEntityRef(\n stringifyEntityRef(template),\n );\n return template.metadata.annotations?.['backstage.io/techdocs-ref'] &&\n viewTechDocsLink\n ? [\n {\n icon: app.getSystemIcon('docs') ?? DocsIcon,\n text: t(\n 'templateListPage.additionalLinksForEntity.viewTechDocsTitle',\n ),\n url: viewTechDocsLink({ kind, namespace, name }),\n },\n ]\n : [];\n },\n [app, viewTechDocsLink, t],\n );\n\n const onTemplateSelected = useCallback(\n (template: TemplateEntityV1beta3) => {\n const { namespace, name } = parseEntityRef(stringifyEntityRef(template));\n\n navigate(templateRoute({ namespace, templateName: name }));\n },\n [navigate, templateRoute],\n );\n\n return (\n <EntityListProvider>\n <Page themeId=\"home\">\n <Header\n pageTitleOverride={t('templateListPage.pageTitle')}\n title={t('templateListPage.title')}\n subtitle={t('templateListPage.subtitle')}\n {...headerOptions}\n >\n <ScaffolderPageContextMenu {...scaffolderPageContextMenuProps} />\n </Header>\n <Content>\n <ContentHeader>\n <RegisterExistingButton\n title={t(\n 'templateListPage.contentHeader.registerExistingButtonTitle',\n )}\n to={registerComponentLink && registerComponentLink()}\n />\n <SupportButton>\n {t('templateListPage.contentHeader.supportButtonTitle')}\n </SupportButton>\n </ContentHeader>\n\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>\n <EntitySearchBar />\n <EntityKindPicker initialFilter=\"template\" hidden />\n <UserListPicker\n initialFilter=\"all\"\n availableFilters={['all', 'starred']}\n />\n <TemplateCategoryPicker />\n <EntityTagPicker />\n <EntityOwnerPicker />\n </CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>\n <TemplateGroups\n groups={groups}\n templateFilter={templateFilter}\n TemplateCardComponent={TemplateCardComponent}\n onTemplateSelected={onTemplateSelected}\n additionalLinksForEntity={additionalLinksForEntity}\n />\n </CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </Content>\n </Page>\n </EntityListProvider>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,20 +1,21 @@
1
1
  import { convertLegacyRouteRefs } from '@backstage/core-compat-api';
2
2
  import { createFrontendPlugin } from '@backstage/frontend-plugin-api';
3
- import { rootRouteRef, selectedTemplateRouteRef, scaffolderTaskRouteRef, actionsRouteRef, scaffolderListTaskRouteRef, editRouteRef, registerComponentRouteRef, viewTechDocRouteRef } from '../routes.esm.js';
3
+ import { rootRouteRef, selectedTemplateRouteRef, scaffolderTaskRouteRef, actionsRouteRef, scaffolderListTaskRouteRef, editRouteRef, templatingExtensionsRouteRef, registerComponentRouteRef, viewTechDocRouteRef } from '../routes.esm.js';
4
4
  import { scaffolderApi, scaffolderPage, scaffolderNavItem, repoUrlPickerFormField } from './extensions.esm.js';
5
5
  import { formFieldsApi } from '@backstage/plugin-scaffolder-react/alpha';
6
6
  import './api/ref.esm.js';
7
7
  import { formDecoratorsApi } from './api/FormDecoratorsApi.esm.js';
8
8
 
9
9
  var plugin = createFrontendPlugin({
10
- id: "scaffolder",
10
+ pluginId: "scaffolder",
11
11
  routes: convertLegacyRouteRefs({
12
12
  root: rootRouteRef,
13
13
  selectedTemplate: selectedTemplateRouteRef,
14
14
  ongoingTask: scaffolderTaskRouteRef,
15
15
  actions: actionsRouteRef,
16
16
  listTasks: scaffolderListTaskRouteRef,
17
- edit: editRouteRef
17
+ edit: editRouteRef,
18
+ templatingExtensions: templatingExtensionsRouteRef
18
19
  }),
19
20
  externalRoutes: convertLegacyRouteRefs({
20
21
  registerComponent: registerComponentRouteRef,
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../../src/alpha/plugin.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { convertLegacyRouteRefs } from '@backstage/core-compat-api';\nimport { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n rootRouteRef,\n actionsRouteRef,\n editRouteRef,\n registerComponentRouteRef,\n scaffolderListTaskRouteRef,\n scaffolderTaskRouteRef,\n selectedTemplateRouteRef,\n viewTechDocRouteRef,\n} from '../routes';\nimport {\n repoUrlPickerFormField,\n scaffolderNavItem,\n scaffolderPage,\n scaffolderApi,\n} from './extensions';\nimport { formFieldsApi } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApi } from './api';\n\n/** @alpha */\nexport default createFrontendPlugin({\n id: 'scaffolder',\n routes: convertLegacyRouteRefs({\n root: rootRouteRef,\n selectedTemplate: selectedTemplateRouteRef,\n ongoingTask: scaffolderTaskRouteRef,\n actions: actionsRouteRef,\n listTasks: scaffolderListTaskRouteRef,\n edit: editRouteRef,\n }),\n externalRoutes: convertLegacyRouteRefs({\n registerComponent: registerComponentRouteRef,\n viewTechDoc: viewTechDocRouteRef,\n }),\n extensions: [\n scaffolderApi,\n scaffolderPage,\n scaffolderNavItem,\n formDecoratorsApi,\n formFieldsApi,\n repoUrlPickerFormField,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;AAsCA,aAAe,oBAAqB,CAAA;AAAA,EAClC,EAAI,EAAA,YAAA;AAAA,EACJ,QAAQ,sBAAuB,CAAA;AAAA,IAC7B,IAAM,EAAA,YAAA;AAAA,IACN,gBAAkB,EAAA,wBAAA;AAAA,IAClB,WAAa,EAAA,sBAAA;AAAA,IACb,OAAS,EAAA,eAAA;AAAA,IACT,SAAW,EAAA,0BAAA;AAAA,IACX,IAAM,EAAA;AAAA,GACP,CAAA;AAAA,EACD,gBAAgB,sBAAuB,CAAA;AAAA,IACrC,iBAAmB,EAAA,yBAAA;AAAA,IACnB,WAAa,EAAA;AAAA,GACd,CAAA;AAAA,EACD,UAAY,EAAA;AAAA,IACV,aAAA;AAAA,IACA,cAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA;AAEJ,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../../src/alpha/plugin.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 { convertLegacyRouteRefs } from '@backstage/core-compat-api';\nimport { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n rootRouteRef,\n actionsRouteRef,\n editRouteRef,\n registerComponentRouteRef,\n scaffolderListTaskRouteRef,\n scaffolderTaskRouteRef,\n selectedTemplateRouteRef,\n templatingExtensionsRouteRef,\n viewTechDocRouteRef,\n} from '../routes';\nimport {\n repoUrlPickerFormField,\n scaffolderNavItem,\n scaffolderPage,\n scaffolderApi,\n} from './extensions';\nimport { formFieldsApi } from '@backstage/plugin-scaffolder-react/alpha';\nimport { formDecoratorsApi } from './api';\n\n/** @alpha */\nexport default createFrontendPlugin({\n pluginId: 'scaffolder',\n routes: convertLegacyRouteRefs({\n root: rootRouteRef,\n selectedTemplate: selectedTemplateRouteRef,\n ongoingTask: scaffolderTaskRouteRef,\n actions: actionsRouteRef,\n listTasks: scaffolderListTaskRouteRef,\n edit: editRouteRef,\n templatingExtensions: templatingExtensionsRouteRef,\n }),\n externalRoutes: convertLegacyRouteRefs({\n registerComponent: registerComponentRouteRef,\n viewTechDoc: viewTechDocRouteRef,\n }),\n extensions: [\n scaffolderApi,\n scaffolderPage,\n scaffolderNavItem,\n formDecoratorsApi,\n formFieldsApi,\n repoUrlPickerFormField,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;AAuCA,aAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,YAAA;AAAA,EACV,QAAQ,sBAAuB,CAAA;AAAA,IAC7B,IAAM,EAAA,YAAA;AAAA,IACN,gBAAkB,EAAA,wBAAA;AAAA,IAClB,WAAa,EAAA,sBAAA;AAAA,IACb,OAAS,EAAA,eAAA;AAAA,IACT,SAAW,EAAA,0BAAA;AAAA,IACX,IAAM,EAAA,YAAA;AAAA,IACN,oBAAsB,EAAA;AAAA,GACvB,CAAA;AAAA,EACD,gBAAgB,sBAAuB,CAAA;AAAA,IACrC,iBAAmB,EAAA,yBAAA;AAAA,IACnB,WAAa,EAAA;AAAA,GACd,CAAA;AAAA,EACD,UAAY,EAAA;AAAA,IACV,aAAA;AAAA,IACA,cAAA;AAAA,IACA,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA;AAEJ,CAAC,CAAA;;;;"}
package/dist/alpha.d.ts CHANGED
@@ -32,6 +32,7 @@ type TemplateListPageProps = {
32
32
  editor?: boolean;
33
33
  actions?: boolean;
34
34
  tasks?: boolean;
35
+ templatingExtensions?: boolean;
35
36
  };
36
37
  headerOptions?: {
37
38
  pageTitleOverride?: string;
@@ -158,6 +159,26 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
158
159
  readonly "renderSchema.tableCell.type": "Type";
159
160
  readonly "renderSchema.tableCell.title": "Title";
160
161
  readonly "renderSchema.tableCell.description": "Description";
162
+ readonly "templatingExtensions.content.values.title": "Values";
163
+ readonly "templatingExtensions.content.values.notAvailable": "There are no global template values defined.";
164
+ readonly "templatingExtensions.content.emptyState.title": "No information to display";
165
+ readonly "templatingExtensions.content.emptyState.description": "There are no templating extensions available or there was an issue communicating with the backend.";
166
+ readonly "templatingExtensions.content.filters.title": "Filters";
167
+ readonly "templatingExtensions.content.filters.schema.input": "Input";
168
+ readonly "templatingExtensions.content.filters.schema.output": "Output";
169
+ readonly "templatingExtensions.content.filters.schema.arguments": "Arguments";
170
+ readonly "templatingExtensions.content.filters.examples": "Examples";
171
+ readonly "templatingExtensions.content.filters.notAvailable": "There are no template filters defined.";
172
+ readonly "templatingExtensions.content.filters.metadataAbsent": "Filter metadata unavailable";
173
+ readonly "templatingExtensions.content.searchFieldPlaceholder": "Search for an extension";
174
+ readonly "templatingExtensions.content.functions.title": "Functions";
175
+ readonly "templatingExtensions.content.functions.schema.output": "Output";
176
+ readonly "templatingExtensions.content.functions.schema.arguments": "Arguments";
177
+ readonly "templatingExtensions.content.functions.examples": "Examples";
178
+ readonly "templatingExtensions.content.functions.notAvailable": "There are no global template functions defined.";
179
+ readonly "templatingExtensions.title": "Templating Extensions";
180
+ readonly "templatingExtensions.subtitle": "This is the collection of available templating extensions";
181
+ readonly "templatingExtensions.pageTitle": "Templating Extensions";
161
182
  readonly "templateTypePicker.title": "Categories";
162
183
  readonly "templateIntroPage.title": "Manage Templates";
163
184
  readonly "templateIntroPage.subtitle": "Edit, preview, and try out templates, forms, and custom fields";
@@ -213,6 +234,7 @@ declare const scaffolderTranslationRef: _backstage_core_plugin_api_alpha.Transla
213
234
  readonly "templateWizardPage.pageContextMenu.editConfigurationTitle": "Edit Configuration";
214
235
  readonly "templateEditorToolbar.customFieldExplorerTooltip": "Custom Fields Explorer";
215
236
  readonly "templateEditorToolbar.installedActionsDocumentationTooltip": "Installed Actions Documentation";
237
+ readonly "templateEditorToolbar.templatingExtensionsDocumentationTooltip": "Templating Extensions Documentation";
216
238
  readonly "templateEditorToolbar.addToCatalogButton": "Publish";
217
239
  readonly "templateEditorToolbar.addToCatalogDialogTitle": "Publish changes";
218
240
  readonly "templateEditorToolbar.addToCatalogDialogContent.stepsIntroduction": "Follow the instructions below to create or update a template:";
@@ -292,6 +314,7 @@ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
292
314
  actions: _backstage_frontend_plugin_api.SubRouteRef<undefined>;
293
315
  listTasks: _backstage_frontend_plugin_api.SubRouteRef<undefined>;
294
316
  edit: _backstage_frontend_plugin_api.SubRouteRef<undefined>;
317
+ templatingExtensions: _backstage_frontend_plugin_api.SubRouteRef<undefined>;
295
318
  }, {
296
319
  registerComponent: _backstage_frontend_plugin_api.ExternalRouteRef<undefined>;
297
320
  viewTechDoc: _backstage_frontend_plugin_api.ExternalRouteRef<{
package/dist/api.esm.js CHANGED
@@ -214,7 +214,7 @@ class ScaffolderClient {
214
214
  async listTemplatingExtensions() {
215
215
  const baseUrl = await this.discoveryApi.getBaseUrl("scaffolder");
216
216
  const response = await this.fetchApi.fetch(
217
- `${baseUrl}/v2/template-extensions`
217
+ `${baseUrl}/v2/templating-extensions`
218
218
  );
219
219
  if (!response.ok) {
220
220
  throw ResponseError.fromResponse(response);
@@ -1 +1 @@
1
- {"version":3,"file":"api.esm.js","sources":["../src/api.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport {\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n TemplateParameterSchema,\n} from '@backstage/plugin-scaffolder-react';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport { default as qs, default as queryString } from 'qs';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: FetchApi;\n private readonly identityApi?: IdentityApi;\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n identityApi?: IdentityApi;\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n async listTasks(options: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n }): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n const query = queryString.stringify({\n createdBy:\n options.filterByOwnership === 'owned' ? userEntityRef : undefined,\n limit: options.limit,\n offset: options.offset,\n });\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/tasks?${query}`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucket\n .list()\n .filter(\n item =>\n !this.scmIntegrationsApi.bitbucketCloud.byHost(item.config.host) &&\n !this.scmIntegrationsApi.bitbucketServer.byHost(item.config.host),\n ),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n async getTemplateParameterSchema(\n templateRef: string,\n ): Promise<TemplateParameterSchema> {\n const { namespace, kind, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const templatePath = [namespace, kind, name]\n .map(s => encodeURIComponent(s))\n .join('/');\n\n const url = `${baseUrl}/v2/templates/${templatePath}/parameter-schema`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const schema: TemplateParameterSchema = await response.json();\n return schema;\n }\n\n async scaffold(\n options: ScaffolderScaffoldOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const { templateRef, values, secrets = {} } = options;\n const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v2/tasks`;\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n templateRef,\n values: { ...values },\n secrets,\n }),\n });\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = (await response.json()) as { id: string };\n return { taskId: id };\n }\n\n async getTask(taskId: string): Promise<ScaffolderTask> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(options);\n }\n\n return this.streamLogsEventStream(options);\n }\n\n async dryRun(\n options: ScaffolderDryRunOptions,\n ): Promise<ScaffolderDryRunResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/dry-run`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n template: options.template,\n values: options.values,\n secrets: options.secrets,\n directoryContents: options.directoryContents,\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n const ctrl = new AbortController();\n void fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onerror(err) {\n subscriber.error(err);\n },\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n });\n }\n\n private streamLogsPolling({\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n }): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n this.discoveryApi.getBaseUrl('scaffolder').then(async baseUrl => {\n while (!subscriber.closed) {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/events?${qs.stringify({ after })}`;\n const response = await this.fetchApi.fetch(url);\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n });\n });\n }\n\n async listActions(): Promise<ListActionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/actions`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async listTemplatingExtensions(): Promise<ListTemplatingExtensionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/template-extensions`,\n );\n if (!response.ok) {\n throw ResponseError.fromResponse(response);\n }\n return response.json();\n }\n\n async cancelTask(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/cancel`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async retry?(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/retry`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async autocomplete({\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context?: Record<string, string>;\n }): Promise<{ results: { title?: string; id: string }[] }> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n\n const url = `${baseUrl}/v2/autocomplete/${provider}/${resource}`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n token,\n context: context ?? {},\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { results } = await response.json();\n return { results };\n }\n}\n"],"names":["queryString"],"mappings":"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"}
1
+ {"version":3,"file":"api.esm.js","sources":["../src/api.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { parseEntityRef } from '@backstage/catalog-model';\nimport {\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport {\n ListActionsResponse,\n ListTemplatingExtensionsResponse,\n LogEvent,\n ScaffolderApi,\n ScaffolderDryRunOptions,\n ScaffolderDryRunResponse,\n ScaffolderGetIntegrationsListOptions,\n ScaffolderGetIntegrationsListResponse,\n ScaffolderScaffoldOptions,\n ScaffolderScaffoldResponse,\n ScaffolderStreamLogsOptions,\n ScaffolderTask,\n TemplateParameterSchema,\n} from '@backstage/plugin-scaffolder-react';\nimport { Observable } from '@backstage/types';\nimport {\n EventSourceMessage,\n fetchEventSource,\n} from '@microsoft/fetch-event-source';\nimport { default as qs, default as queryString } from 'qs';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * An API to interact with the scaffolder backend.\n *\n * @public\n */\nexport class ScaffolderClient implements ScaffolderApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly scmIntegrationsApi: ScmIntegrationRegistry;\n private readonly fetchApi: FetchApi;\n private readonly identityApi?: IdentityApi;\n private readonly useLongPollingLogs: boolean;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n identityApi?: IdentityApi;\n scmIntegrationsApi: ScmIntegrationRegistry;\n useLongPollingLogs?: boolean;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi ?? { fetch };\n this.scmIntegrationsApi = options.scmIntegrationsApi;\n this.useLongPollingLogs = options.useLongPollingLogs ?? false;\n this.identityApi = options.identityApi;\n }\n\n async listTasks(options: {\n filterByOwnership: 'owned' | 'all';\n limit?: number;\n offset?: number;\n }): Promise<{ tasks: ScaffolderTask[]; totalTasks?: number }> {\n if (!this.identityApi) {\n throw new Error(\n 'IdentityApi is not available in the ScaffolderClient, please pass through the IdentityApi to the ScaffolderClient constructor in order to use the listTasks method',\n );\n }\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n\n const query = queryString.stringify({\n createdBy:\n options.filterByOwnership === 'owned' ? userEntityRef : undefined,\n limit: options.limit,\n offset: options.offset,\n });\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/tasks?${query}`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async getIntegrationsList(\n options: ScaffolderGetIntegrationsListOptions,\n ): Promise<ScaffolderGetIntegrationsListResponse> {\n const integrations = [\n ...this.scmIntegrationsApi.azure.list(),\n ...this.scmIntegrationsApi.bitbucket\n .list()\n .filter(\n item =>\n !this.scmIntegrationsApi.bitbucketCloud.byHost(item.config.host) &&\n !this.scmIntegrationsApi.bitbucketServer.byHost(item.config.host),\n ),\n ...this.scmIntegrationsApi.bitbucketCloud.list(),\n ...this.scmIntegrationsApi.bitbucketServer.list(),\n ...this.scmIntegrationsApi.gerrit.list(),\n ...this.scmIntegrationsApi.gitea.list(),\n ...this.scmIntegrationsApi.github.list(),\n ...this.scmIntegrationsApi.gitlab.list(),\n ]\n .map(c => ({ type: c.type, title: c.title, host: c.config.host }))\n .filter(c => options.allowedHosts.includes(c.host));\n\n return {\n integrations,\n };\n }\n\n async getTemplateParameterSchema(\n templateRef: string,\n ): Promise<TemplateParameterSchema> {\n const { namespace, kind, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const templatePath = [namespace, kind, name]\n .map(s => encodeURIComponent(s))\n .join('/');\n\n const url = `${baseUrl}/v2/templates/${templatePath}/parameter-schema`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const schema: TemplateParameterSchema = await response.json();\n return schema;\n }\n\n async scaffold(\n options: ScaffolderScaffoldOptions,\n ): Promise<ScaffolderScaffoldResponse> {\n const { templateRef, values, secrets = {} } = options;\n const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v2/tasks`;\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n templateRef,\n values: { ...values },\n secrets,\n }),\n });\n\n if (response.status !== 201) {\n const status = `${response.status} ${response.statusText}`;\n const body = await response.text();\n throw new Error(`Backend request failed, ${status} ${body.trim()}`);\n }\n\n const { id } = (await response.json()) as { id: string };\n return { taskId: id };\n }\n\n async getTask(taskId: string): Promise<ScaffolderTask> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;\n\n const response = await this.fetchApi.fetch(url);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n if (this.useLongPollingLogs) {\n return this.streamLogsPolling(options);\n }\n\n return this.streamLogsEventStream(options);\n }\n\n async dryRun(\n options: ScaffolderDryRunOptions,\n ): Promise<ScaffolderDryRunResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/dry-run`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n template: options.template,\n values: options.values,\n secrets: options.secrets,\n directoryContents: options.directoryContents,\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private streamLogsEventStream({\n isTaskRecoverable,\n taskId,\n after,\n }: ScaffolderStreamLogsOptions): Observable<LogEvent> {\n return new ObservableImpl(subscriber => {\n const params = new URLSearchParams();\n if (after !== undefined) {\n params.set('after', String(Number(after)));\n }\n\n this.discoveryApi.getBaseUrl('scaffolder').then(\n baseUrl => {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/eventstream`;\n\n const processEvent = (event: any) => {\n if (event.data) {\n try {\n subscriber.next(JSON.parse(event.data));\n } catch (ex) {\n subscriber.error(ex);\n }\n }\n };\n\n const ctrl = new AbortController();\n void fetchEventSource(url, {\n fetch: this.fetchApi.fetch,\n signal: ctrl.signal,\n onmessage(e: EventSourceMessage) {\n if (e.event === 'log') {\n processEvent(e);\n return;\n } else if (e.event === 'completion' && !isTaskRecoverable) {\n processEvent(e);\n subscriber.complete();\n ctrl.abort();\n return;\n }\n processEvent(e);\n },\n onerror(err) {\n subscriber.error(err);\n },\n });\n },\n error => {\n subscriber.error(error);\n },\n );\n });\n }\n\n private streamLogsPolling({\n taskId,\n after: inputAfter,\n }: {\n taskId: string;\n after?: number;\n }): Observable<LogEvent> {\n let after = inputAfter;\n\n return new ObservableImpl(subscriber => {\n this.discoveryApi.getBaseUrl('scaffolder').then(async baseUrl => {\n while (!subscriber.closed) {\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(\n taskId,\n )}/events?${qs.stringify({ after })}`;\n const response = await this.fetchApi.fetch(url);\n\n if (!response.ok) {\n // wait for one second to not run into an\n await new Promise(resolve => setTimeout(resolve, 1000));\n continue;\n }\n\n const logs = (await response.json()) as LogEvent[];\n\n for (const event of logs) {\n after = Number(event.id);\n\n subscriber.next(event);\n\n if (event.type === 'completion') {\n subscriber.complete();\n return;\n }\n }\n }\n });\n });\n }\n\n async listActions(): Promise<ListActionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(`${baseUrl}/v2/actions`);\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async listTemplatingExtensions(): Promise<ListTemplatingExtensionsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/templating-extensions`,\n );\n if (!response.ok) {\n throw ResponseError.fromResponse(response);\n }\n return response.json();\n }\n\n async cancelTask(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/cancel`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async retry?(taskId: string): Promise<void> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}/retry`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n async autocomplete({\n token,\n resource,\n provider,\n context,\n }: {\n token: string;\n provider: string;\n resource: string;\n context?: Record<string, string>;\n }): Promise<{ results: { title?: string; id: string }[] }> {\n const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');\n\n const url = `${baseUrl}/v2/autocomplete/${provider}/${resource}`;\n\n const response = await this.fetchApi.fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n token,\n context: context ?? {},\n }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { results } = await response.json();\n return { results };\n }\n}\n"],"names":["queryString"],"mappings":"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"}