@tduniec/plugin-template-designer 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ import * as react from 'react';
2
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
3
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
+
5
+ /**
6
+ * Backstage frontend plugin.
7
+ *
8
+ * @alpha
9
+ */
10
+ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
11
+ root: _backstage_core_plugin_api.RouteRef<undefined>;
12
+ }, {}, {
13
+ "nav-item:template-designer": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
14
+ kind: "nav-item";
15
+ name: undefined;
16
+ config: {};
17
+ configInput: {};
18
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<{
19
+ title: string;
20
+ icon: _backstage_core_plugin_api.IconComponent;
21
+ routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
22
+ }, "core.nav-item.target", {}>;
23
+ inputs: {};
24
+ params: {
25
+ title: string;
26
+ icon: _backstage_core_plugin_api.IconComponent;
27
+ routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
28
+ };
29
+ }>;
30
+ "page:template-designer": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
31
+ kind: "page";
32
+ name: undefined;
33
+ config: {
34
+ path: string | undefined;
35
+ };
36
+ configInput: {
37
+ path?: string | undefined;
38
+ };
39
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
40
+ optional: true;
41
+ }>;
42
+ inputs: {};
43
+ params: {
44
+ defaultPath?: [Error: `Use the 'path' param instead`];
45
+ path: string;
46
+ loader: () => Promise<JSX.Element>;
47
+ routeRef?: _backstage_frontend_plugin_api.RouteRef;
48
+ };
49
+ }>;
50
+ }>;
51
+
52
+ export { _default as default };
@@ -0,0 +1,30 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { NavItemBlueprint, PageBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
3
+ import { rootRouteRef } from './routes.esm.js';
4
+ import BorderColorIcon from '@material-ui/icons/BorderColor';
5
+
6
+ const templateDesignerNavItem = NavItemBlueprint.make({
7
+ params: {
8
+ title: "Template designer",
9
+ routeRef: rootRouteRef,
10
+ icon: BorderColorIcon
11
+ }
12
+ });
13
+ const templateDesignerPage = PageBlueprint.make({
14
+ params: {
15
+ path: "/template-designer",
16
+ routeRef: rootRouteRef,
17
+ loader: () => import('./components/TemplateDesigner/index.esm.js').then((m) => /* @__PURE__ */ jsx(m.TemplateDesigner, {}))
18
+ }
19
+ });
20
+ var alpha = createFrontendPlugin({
21
+ pluginId: "template-designer",
22
+ info: { packageJson: () => import('./package.json.esm.js') },
23
+ routes: {
24
+ root: rootRouteRef
25
+ },
26
+ extensions: [templateDesignerPage, templateDesignerNavItem]
27
+ });
28
+
29
+ export { alpha as default };
30
+ //# sourceMappingURL=alpha.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["import {\n createFrontendPlugin,\n NavItemBlueprint,\n PageBlueprint,\n} from \"@backstage/frontend-plugin-api\";\nimport { rootRouteRef } from \"./routes\";\nimport BorderColorIcon from \"@material-ui/icons/BorderColor\";\n\nconst templateDesignerNavItem = NavItemBlueprint.make({\n params: {\n title: \"Template designer\",\n routeRef: rootRouteRef,\n icon: BorderColorIcon,\n },\n});\n\nconst templateDesignerPage = PageBlueprint.make({\n params: {\n path: \"/template-designer\",\n routeRef: rootRouteRef,\n loader: () =>\n import(\"./components/TemplateDesigner\").then((m) => (\n <m.TemplateDesigner />\n )),\n },\n});\n\n/**\n * Backstage frontend plugin.\n *\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: \"template-designer\",\n info: { packageJson: () => import(\"../package.json\") },\n routes: {\n root: rootRouteRef,\n },\n extensions: [templateDesignerPage, templateDesignerNavItem],\n});\n"],"names":[],"mappings":";;;;;AAQA,MAAM,uBAAA,GAA0B,iBAAiB,IAAA,CAAK;AAAA,EACpD,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,mBAAA;AAAA,IACP,QAAA,EAAU,YAAA;AAAA,IACV,IAAA,EAAM;AAAA;AAEV,CAAC,CAAA;AAED,MAAM,oBAAA,GAAuB,cAAc,IAAA,CAAK;AAAA,EAC9C,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,oBAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,MAAA,EAAQ,MACN,OAAO,4CAA+B,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,qBAC5C,GAAA,CAAC,CAAA,CAAE,gBAAA,EAAF,EAAmB,CACrB;AAAA;AAEP,CAAC,CAAA;AAOD,YAAe,oBAAA,CAAqB;AAAA,EAClC,QAAA,EAAU,mBAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,uBAAiB,CAAA,EAAE;AAAA,EACrD,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA,GACR;AAAA,EACA,UAAA,EAAY,CAAC,oBAAA,EAAsB,uBAAuB;AAC5D,CAAC,CAAA;;;;"}
@@ -29,7 +29,9 @@ const TemplateDesigner = () => {
29
29
  handleParametersChange,
30
30
  handleOutputChange,
31
31
  handleReloadFromFile,
32
- handleSaveTemplate
32
+ handleSaveTemplate,
33
+ availableTemplates,
34
+ selectCatalogTemplate
33
35
  } = useTemplateState();
34
36
  const {
35
37
  editorState,
@@ -46,6 +48,8 @@ const TemplateDesigner = () => {
46
48
  let reloadButtonLabel = "Reset sample";
47
49
  if (templateSource?.type === "file") {
48
50
  reloadButtonLabel = isReloading ? "Reloading..." : "Reload file";
51
+ } else if (templateSource?.type === "catalog") {
52
+ reloadButtonLabel = "Reload template";
49
53
  }
50
54
  let saveButtonLabel = templateSource?.type === "file" ? "Save" : "Save as file";
51
55
  if (isSaving) {
@@ -69,7 +73,9 @@ const TemplateDesigner = () => {
69
73
  {
70
74
  loadError,
71
75
  onStartSampleTemplate: handleStartSampleTemplate,
72
- onOpenTemplatePicker: handleOpenTemplatePicker
76
+ onOpenTemplatePicker: handleOpenTemplatePicker,
77
+ availableTemplates,
78
+ selectCatalogTemplate
73
79
  }
74
80
  ) : /* @__PURE__ */ jsx(
75
81
  TemplateWorkspace,
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateDesigner.esm.js","sources":["../../../src/components/TemplateDesigner/TemplateDesigner.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport {\n Page,\n Content,\n ContentHeader,\n SupportButton,\n} from \"@backstage/core-components\";\nimport { FieldEditorDialog } from \"./components/FieldEditorDialog\";\nimport { TemplateLanding } from \"./components/TemplateLanding\";\nimport { TemplateWorkspace } from \"./components/TemplateWorkspace\";\nimport { useFieldEditor } from \"./useFieldEditor\";\nimport { useTemplateState } from \"./useTemplateState\";\n\nexport const TemplateDesigner = () => {\n const [showYaml, setShowYaml] = useState(true);\n const {\n templateObject,\n templateYaml,\n yamlError,\n loadError,\n templateSteps,\n templateParameters,\n templateOutput,\n templateSource,\n isReloading,\n isSaving,\n fileInputRef,\n handleStartSampleTemplate,\n handleTemplateFileSelected,\n handleOpenTemplatePicker,\n handleYamlChange,\n handleStepsChange,\n handleParametersChange,\n handleOutputChange,\n handleReloadFromFile,\n handleSaveTemplate,\n } = useTemplateState();\n const {\n editorState,\n editorValue,\n setEditorValue,\n interactionRootRef,\n closeEditor,\n applyEditorValue,\n } = useFieldEditor();\n\n const handleToggleYaml = useCallback(() => {\n setShowYaml((prev) => !prev);\n }, []);\n\n const activeTemplateLabel = templateSource?.label;\n\n let reloadButtonLabel = \"Reset sample\";\n if (templateSource?.type === \"file\") {\n reloadButtonLabel = isReloading ? \"Reloading...\" : \"Reload file\";\n }\n\n let saveButtonLabel =\n templateSource?.type === \"file\" ? \"Save\" : \"Save as file\";\n if (isSaving) {\n saveButtonLabel = \"Saving...\";\n }\n\n return (\n <div ref={interactionRootRef} style={{ height: \"100%\" }}>\n <Page themeId=\"tool\">\n <Content>\n <ContentHeader title=\"Template Designer\">\n <SupportButton>\n Template Designer turns blank Backstage YAML into a\n storyboard-like canvas, guiding anyone through drag-and-drop\n scaffolder authoring before ever touching code. Rally non-experts,\n broadcast best practices, and accelerate template launches\n directly inside Backstage.\n </SupportButton>\n </ContentHeader>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".yaml,.yml,.json\"\n style={{ display: \"none\" }}\n onChange={handleTemplateFileSelected}\n />\n\n {!templateObject ? (\n <TemplateLanding\n loadError={loadError}\n onStartSampleTemplate={handleStartSampleTemplate}\n onOpenTemplatePicker={handleOpenTemplatePicker}\n />\n ) : (\n <TemplateWorkspace\n templateSteps={templateSteps}\n templateParameters={templateParameters}\n templateOutput={templateOutput}\n templateYaml={templateYaml}\n yamlError={yamlError}\n loadError={loadError}\n showYaml={showYaml}\n onToggleYaml={handleToggleYaml}\n onYamlChange={handleYamlChange}\n onStepsChange={handleStepsChange}\n onParametersChange={handleParametersChange}\n onOutputChange={handleOutputChange}\n onReload={handleReloadFromFile}\n onSave={handleSaveTemplate}\n onOpenTemplatePicker={handleOpenTemplatePicker}\n activeTemplateLabel={activeTemplateLabel}\n reloadButtonLabel={reloadButtonLabel}\n saveButtonLabel={saveButtonLabel}\n isReloading={isReloading}\n isSaving={isSaving}\n />\n )}\n </Content>\n </Page>\n <FieldEditorDialog\n open={Boolean(editorState)}\n label={editorState?.label}\n value={editorValue}\n onChange={setEditorValue}\n onClose={closeEditor}\n onApply={applyEditorValue}\n />\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateDesigner.esm.js","sources":["../../../src/components/TemplateDesigner/TemplateDesigner.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport {\n Content,\n ContentHeader,\n Page,\n SupportButton,\n} from \"@backstage/core-components\";\nimport { FieldEditorDialog } from \"./components/FieldEditorDialog\";\nimport { TemplateLanding } from \"./components/TemplateLanding\";\nimport { TemplateWorkspace } from \"./components/TemplateWorkspace\";\nimport { useFieldEditor } from \"./useFieldEditor\";\nimport { useTemplateState } from \"./useTemplateState\";\n\nexport const TemplateDesigner = () => {\n const [showYaml, setShowYaml] = useState(true);\n const {\n templateObject,\n templateYaml,\n yamlError,\n loadError,\n templateSteps,\n templateParameters,\n templateOutput,\n templateSource,\n isReloading,\n isSaving,\n fileInputRef,\n handleStartSampleTemplate,\n handleTemplateFileSelected,\n handleOpenTemplatePicker,\n handleYamlChange,\n handleStepsChange,\n handleParametersChange,\n handleOutputChange,\n handleReloadFromFile,\n handleSaveTemplate,\n availableTemplates,\n selectCatalogTemplate,\n } = useTemplateState();\n const {\n editorState,\n editorValue,\n setEditorValue,\n interactionRootRef,\n closeEditor,\n applyEditorValue,\n } = useFieldEditor();\n\n const handleToggleYaml = useCallback(() => {\n setShowYaml((prev) => !prev);\n }, []);\n\n const activeTemplateLabel = templateSource?.label;\n\n let reloadButtonLabel = \"Reset sample\";\n if (templateSource?.type === \"file\") {\n reloadButtonLabel = isReloading ? \"Reloading...\" : \"Reload file\";\n } else if (templateSource?.type === \"catalog\") {\n reloadButtonLabel = \"Reload template\";\n }\n\n let saveButtonLabel =\n templateSource?.type === \"file\" ? \"Save\" : \"Save as file\";\n if (isSaving) {\n saveButtonLabel = \"Saving...\";\n }\n\n return (\n <div ref={interactionRootRef} style={{ height: \"100%\" }}>\n <Page themeId=\"tool\">\n <Content>\n <ContentHeader title=\"Template Designer\">\n <SupportButton>\n Template Designer turns blank Backstage YAML into a\n storyboard-like canvas, guiding anyone through drag-and-drop\n scaffolder authoring before ever touching code. Rally non-experts,\n broadcast best practices, and accelerate template launches\n directly inside Backstage.\n </SupportButton>\n </ContentHeader>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".yaml,.yml,.json\"\n style={{ display: \"none\" }}\n onChange={handleTemplateFileSelected}\n />\n\n {!templateObject ? (\n <TemplateLanding\n loadError={loadError}\n onStartSampleTemplate={handleStartSampleTemplate}\n onOpenTemplatePicker={handleOpenTemplatePicker}\n availableTemplates={availableTemplates}\n selectCatalogTemplate={selectCatalogTemplate}\n />\n ) : (\n <TemplateWorkspace\n templateSteps={templateSteps}\n templateParameters={templateParameters}\n templateOutput={templateOutput}\n templateYaml={templateYaml}\n yamlError={yamlError}\n loadError={loadError}\n showYaml={showYaml}\n onToggleYaml={handleToggleYaml}\n onYamlChange={handleYamlChange}\n onStepsChange={handleStepsChange}\n onParametersChange={handleParametersChange}\n onOutputChange={handleOutputChange}\n onReload={handleReloadFromFile}\n onSave={handleSaveTemplate}\n onOpenTemplatePicker={handleOpenTemplatePicker}\n activeTemplateLabel={activeTemplateLabel}\n reloadButtonLabel={reloadButtonLabel}\n saveButtonLabel={saveButtonLabel}\n isReloading={isReloading}\n isSaving={isSaving}\n />\n )}\n </Content>\n </Page>\n <FieldEditorDialog\n open={Boolean(editorState)}\n label={editorState?.label}\n value={editorValue}\n onChange={setEditorValue}\n onClose={closeEditor}\n onApply={applyEditorValue}\n />\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,11 +1,14 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { Grid, Paper, Box, Typography, Button } from '@material-ui/core';
2
+ import { Grid, Paper, Box, Typography, Button, TextField } from '@material-ui/core';
3
3
  import { useTheme } from '@material-ui/core/styles';
4
+ import Autocomplete from '@material-ui/lab/Autocomplete';
4
5
 
5
6
  const TemplateLanding = ({
6
7
  loadError,
7
8
  onStartSampleTemplate,
8
- onOpenTemplatePicker
9
+ onOpenTemplatePicker,
10
+ availableTemplates,
11
+ selectCatalogTemplate
9
12
  }) => {
10
13
  const theme = useTheme();
11
14
  return /* @__PURE__ */ jsx(
@@ -16,7 +19,7 @@ const TemplateLanding = ({
16
19
  alignItems: "center",
17
20
  style: { minHeight: "60vh" },
18
21
  children: /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 10, lg: 8, children: /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 4, alignItems: "stretch", children: [
19
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsxs(
22
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 4, children: /* @__PURE__ */ jsxs(
20
23
  Paper,
21
24
  {
22
25
  elevation: 3,
@@ -45,7 +48,7 @@ const TemplateLanding = ({
45
48
  ]
46
49
  }
47
50
  ) }),
48
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsxs(
51
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 4, children: /* @__PURE__ */ jsxs(
49
52
  Paper,
50
53
  {
51
54
  elevation: 3,
@@ -92,6 +95,57 @@ const TemplateLanding = ({
92
95
  )
93
96
  ]
94
97
  }
98
+ ) }),
99
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 4, children: /* @__PURE__ */ jsxs(
100
+ Paper,
101
+ {
102
+ elevation: 3,
103
+ style: {
104
+ padding: 32,
105
+ height: "100%",
106
+ minHeight: 320,
107
+ display: "flex",
108
+ flexDirection: "column",
109
+ gap: 16
110
+ },
111
+ children: [
112
+ /* @__PURE__ */ jsxs(Box, { children: [
113
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Select from catalog" }),
114
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Select existing template from catalog." })
115
+ ] }),
116
+ /* @__PURE__ */ jsx(
117
+ Box,
118
+ {
119
+ mt: "auto",
120
+ display: "flex",
121
+ flexDirection: "column",
122
+ style: { gap: 8 },
123
+ children: /* @__PURE__ */ jsx(
124
+ Autocomplete,
125
+ {
126
+ style: { width: "100%" },
127
+ options: availableTemplates ?? [],
128
+ getOptionLabel: (option) => option.metadata.title ?? option.metadata.name,
129
+ onChange: (_e, value) => {
130
+ if (value) {
131
+ selectCatalogTemplate(value);
132
+ }
133
+ },
134
+ renderInput: (params) => /* @__PURE__ */ jsx(
135
+ TextField,
136
+ {
137
+ ...params,
138
+ autoComplete: "off",
139
+ label: "Select template",
140
+ variant: "outlined"
141
+ }
142
+ )
143
+ }
144
+ )
145
+ }
146
+ )
147
+ ]
148
+ }
95
149
  ) })
96
150
  ] }) })
97
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateLanding.esm.js","sources":["../../../../src/components/TemplateDesigner/components/TemplateLanding.tsx"],"sourcesContent":["import { Box, Button, Grid, Paper, Typography } from \"@material-ui/core\";\nimport { useTheme } from \"@material-ui/core/styles\";\n\ntype TemplateLandingProps = {\n loadError?: string;\n onStartSampleTemplate: () => void;\n onOpenTemplatePicker: () => void;\n};\n\nexport const TemplateLanding = ({\n loadError,\n onStartSampleTemplate,\n onOpenTemplatePicker,\n}: TemplateLandingProps) => {\n const theme = useTheme();\n\n return (\n <Grid\n container\n justifyContent=\"center\"\n alignItems=\"center\"\n style={{ minHeight: \"60vh\" }}\n >\n <Grid item xs={12} md={10} lg={8}>\n <Grid container spacing={4} alignItems=\"stretch\">\n <Grid item xs={12} md={6}>\n <Paper\n elevation={3}\n style={{\n padding: 32,\n height: \"100%\",\n minHeight: 320,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <Box>\n <Typography variant=\"h6\">Create new template</Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Start with a tidy sample blueprint that includes a single\n action step and helpful starter metadata.\n </Typography>\n </Box>\n <Box mt=\"auto\" display=\"flex\" justifyContent=\"flex-start\">\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={onStartSampleTemplate}\n >\n Start new template\n </Button>\n </Box>\n </Paper>\n </Grid>\n <Grid item xs={12} md={6}>\n <Paper\n elevation={3}\n style={{\n padding: 32,\n height: \"100%\",\n minHeight: 320,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <Box>\n <Typography variant=\"h6\">Load from file</Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Import an existing template in YAML or JSON format and iterate\n in the visual designer.\n </Typography>\n </Box>\n <Box\n mt=\"auto\"\n display=\"flex\"\n flexDirection=\"column\"\n style={{ gap: 8 }}\n >\n <Button\n color=\"primary\"\n variant=\"outlined\"\n onClick={onOpenTemplatePicker}\n >\n Choose file\n </Button>\n {loadError && (\n <Typography\n variant=\"body2\"\n style={{ color: theme.palette.error.main }}\n >\n {loadError}\n </Typography>\n )}\n </Box>\n </Paper>\n </Grid>\n </Grid>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateLanding.esm.js","sources":["../../../../src/components/TemplateDesigner/components/TemplateLanding.tsx"],"sourcesContent":["import {\n Box,\n Button,\n Grid,\n Paper,\n TextField,\n Typography,\n} from \"@material-ui/core\";\nimport { useTheme } from \"@material-ui/core/styles\";\nimport { TemplateEntityV1beta3 } from \"@backstage/plugin-scaffolder-common\";\nimport Autocomplete from \"@material-ui/lab/Autocomplete\";\n\ntype TemplateLandingProps = {\n loadError?: string;\n onStartSampleTemplate: () => void;\n onOpenTemplatePicker: () => void;\n availableTemplates: TemplateEntityV1beta3[];\n selectCatalogTemplate: (selected: TemplateEntityV1beta3) => void;\n};\n\nexport const TemplateLanding = ({\n loadError,\n onStartSampleTemplate,\n onOpenTemplatePicker,\n availableTemplates,\n selectCatalogTemplate,\n}: TemplateLandingProps) => {\n const theme = useTheme();\n\n return (\n <Grid\n container\n justifyContent=\"center\"\n alignItems=\"center\"\n style={{ minHeight: \"60vh\" }}\n >\n <Grid item xs={12} md={10} lg={8}>\n <Grid container spacing={4} alignItems=\"stretch\">\n <Grid item xs={12} md={4}>\n <Paper\n elevation={3}\n style={{\n padding: 32,\n height: \"100%\",\n minHeight: 320,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <Box>\n <Typography variant=\"h6\">Create new template</Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Start with a tidy sample blueprint that includes a single\n action step and helpful starter metadata.\n </Typography>\n </Box>\n <Box mt=\"auto\" display=\"flex\" justifyContent=\"flex-start\">\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={onStartSampleTemplate}\n >\n Start new template\n </Button>\n </Box>\n </Paper>\n </Grid>\n <Grid item xs={12} md={4}>\n <Paper\n elevation={3}\n style={{\n padding: 32,\n height: \"100%\",\n minHeight: 320,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <Box>\n <Typography variant=\"h6\">Load from file</Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Import an existing template in YAML or JSON format and iterate\n in the visual designer.\n </Typography>\n </Box>\n <Box\n mt=\"auto\"\n display=\"flex\"\n flexDirection=\"column\"\n style={{ gap: 8 }}\n >\n <Button\n color=\"primary\"\n variant=\"outlined\"\n onClick={onOpenTemplatePicker}\n >\n Choose file\n </Button>\n {loadError && (\n <Typography\n variant=\"body2\"\n style={{ color: theme.palette.error.main }}\n >\n {loadError}\n </Typography>\n )}\n </Box>\n </Paper>\n </Grid>\n <Grid item xs={12} md={4}>\n <Paper\n elevation={3}\n style={{\n padding: 32,\n height: \"100%\",\n minHeight: 320,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <Box>\n <Typography variant=\"h6\">Select from catalog</Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Select existing template from catalog.\n </Typography>\n </Box>\n <Box\n mt=\"auto\"\n display=\"flex\"\n flexDirection=\"column\"\n style={{ gap: 8 }}\n >\n <Autocomplete\n style={{ width: \"100%\" }}\n options={availableTemplates ?? []}\n getOptionLabel={(option) =>\n option.metadata.title ?? option.metadata.name\n }\n onChange={(_e, value) => {\n if (value) {\n selectCatalogTemplate(value);\n }\n }}\n renderInput={(params) => (\n <TextField\n {...params}\n autoComplete=\"off\"\n label=\"Select template\"\n variant=\"outlined\"\n />\n )}\n />\n </Box>\n </Paper>\n </Grid>\n </Grid>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -77,166 +77,175 @@ const TemplateWorkspace = ({
77
77
  },
78
78
  []
79
79
  );
80
- return /* @__PURE__ */ jsx(Grid, { container: true, spacing: 3, direction: "column", children: /* @__PURE__ */ jsx(Grid, { item: true, style: { height: 800 }, children: /* @__PURE__ */ jsxs(
81
- "div",
80
+ return /* @__PURE__ */ jsx(
81
+ Grid,
82
82
  {
83
- style: {
84
- height: "100%",
85
- display: "flex",
86
- flexDirection: "column",
87
- gap: 16
88
- },
89
- children: [
90
- /* @__PURE__ */ jsxs(
91
- "div",
92
- {
93
- style: {
94
- display: "flex",
95
- justifyContent: "space-between",
96
- alignItems: "center",
97
- flexWrap: "wrap",
98
- gap: 12
99
- },
100
- children: [
101
- /* @__PURE__ */ jsxs(
102
- "div",
103
- {
104
- style: {
105
- display: "flex",
106
- alignItems: "center",
107
- gap: 12,
108
- flexWrap: "wrap"
109
- },
110
- children: [
111
- activeTemplateLabel && /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
112
- "Active template: ",
113
- activeTemplateLabel
114
- ] }),
115
- /* @__PURE__ */ jsx(
116
- Button,
117
- {
118
- color: "primary",
119
- variant: "contained",
120
- size: "small",
121
- onClick: onReload,
122
- disabled: isReloading,
123
- children: reloadButtonLabel
124
- }
125
- ),
126
- /* @__PURE__ */ jsx(
127
- Button,
128
- {
129
- color: "primary",
130
- variant: "outlined",
131
- size: "small",
132
- onClick: onSave,
133
- disabled: isSaving,
134
- children: saveButtonLabel
135
- }
136
- ),
137
- /* @__PURE__ */ jsx(
138
- Button,
139
- {
140
- color: "primary",
141
- variant: "outlined",
142
- size: "small",
143
- onClick: onOpenTemplatePicker,
144
- children: "Load different file"
145
- }
146
- )
147
- ]
148
- }
149
- ),
150
- /* @__PURE__ */ jsx(Button, { variant: "outlined", size: "small", onClick: onToggleYaml, children: showYaml ? "Hide YAML" : "Show YAML" })
151
- ]
152
- }
153
- ),
154
- loadError && /* @__PURE__ */ jsx(
155
- Typography,
156
- {
157
- variant: "body2",
158
- style: { color: theme.palette.error.main },
159
- children: loadError
160
- }
161
- ),
162
- /* @__PURE__ */ jsxs(
163
- "div",
164
- {
165
- style: {
166
- flex: 1,
167
- display: "flex",
168
- gap: 16,
169
- minHeight: 0
170
- },
171
- children: [
172
- /* @__PURE__ */ jsx("div", { style: { flex: showYaml ? 1.6 : 1, minWidth: 0 }, children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: /* @__PURE__ */ jsx(
173
- App,
174
- {
175
- steps: templateSteps,
176
- parameters: templateParameters,
177
- output: templateOutput,
178
- onStepsChange,
179
- onParametersChange,
180
- onOutputChange
181
- }
182
- ) }) }),
183
- showYaml && /* @__PURE__ */ jsxs(
184
- Paper,
185
- {
186
- elevation: 2,
187
- style: {
188
- flex: 1,
189
- display: "flex",
190
- flexDirection: "column",
191
- minWidth: 0,
192
- overflow: "hidden"
193
- },
194
- children: [
195
- /* @__PURE__ */ jsx(
196
- "div",
197
- {
198
- style: {
199
- padding: "12px 16px",
200
- borderBottom: "1px solid rgba(0,0,0,0.12)",
201
- fontWeight: 600,
202
- fontSize: "0.875rem"
203
- },
204
- children: "YAML Preview"
205
- }
206
- ),
207
- yamlError && /* @__PURE__ */ jsx(
208
- "div",
209
- {
210
- style: {
211
- padding: "8px 16px",
212
- borderBottom: "1px solid rgba(0,0,0,0.08)",
213
- color: theme.palette.error.main,
214
- fontSize: "0.75rem",
215
- background: paletteMode === "dark" ? "rgba(255, 82, 82, 0.1)" : "rgba(244, 67, 54, 0.08)"
216
- },
217
- children: yamlError
218
- }
219
- ),
220
- /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0, overflow: "auto" }, children: /* @__PURE__ */ jsx(
221
- CodeMirror,
222
- {
223
- value: templateYaml,
224
- extensions: yamlExtensions,
225
- theme: codeMirrorTheme,
226
- height: "100%",
227
- onChange: handleYamlChange,
228
- onBlur: handleYamlBlur
229
- }
230
- ) })
231
- ]
232
- }
233
- )
234
- ]
235
- }
236
- )
237
- ]
83
+ container: true,
84
+ spacing: 3,
85
+ direction: "column",
86
+ style: { height: "calc(100% - 15px)" },
87
+ children: /* @__PURE__ */ jsx(Grid, { item: true, style: { height: "100%" }, children: /* @__PURE__ */ jsxs(
88
+ "div",
89
+ {
90
+ style: {
91
+ height: "100%",
92
+ display: "flex",
93
+ flexDirection: "column",
94
+ gap: 16
95
+ },
96
+ children: [
97
+ /* @__PURE__ */ jsxs(
98
+ "div",
99
+ {
100
+ style: {
101
+ display: "flex",
102
+ justifyContent: "space-between",
103
+ alignItems: "center",
104
+ flexWrap: "wrap",
105
+ gap: 12
106
+ },
107
+ children: [
108
+ /* @__PURE__ */ jsxs(
109
+ "div",
110
+ {
111
+ style: {
112
+ display: "flex",
113
+ alignItems: "center",
114
+ gap: 12,
115
+ flexWrap: "wrap"
116
+ },
117
+ children: [
118
+ activeTemplateLabel && /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
119
+ "Active template: ",
120
+ activeTemplateLabel
121
+ ] }),
122
+ /* @__PURE__ */ jsx(
123
+ Button,
124
+ {
125
+ color: "primary",
126
+ variant: "contained",
127
+ size: "small",
128
+ onClick: onReload,
129
+ disabled: isReloading,
130
+ children: reloadButtonLabel
131
+ }
132
+ ),
133
+ /* @__PURE__ */ jsx(
134
+ Button,
135
+ {
136
+ color: "primary",
137
+ variant: "outlined",
138
+ size: "small",
139
+ onClick: onSave,
140
+ disabled: isSaving,
141
+ children: saveButtonLabel
142
+ }
143
+ ),
144
+ /* @__PURE__ */ jsx(
145
+ Button,
146
+ {
147
+ color: "primary",
148
+ variant: "outlined",
149
+ size: "small",
150
+ onClick: onOpenTemplatePicker,
151
+ children: "Load different file"
152
+ }
153
+ )
154
+ ]
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsx(Button, { variant: "outlined", size: "small", onClick: onToggleYaml, children: showYaml ? "Hide YAML" : "Show YAML" })
158
+ ]
159
+ }
160
+ ),
161
+ loadError && /* @__PURE__ */ jsx(
162
+ Typography,
163
+ {
164
+ variant: "body2",
165
+ style: { color: theme.palette.error.main },
166
+ children: loadError
167
+ }
168
+ ),
169
+ /* @__PURE__ */ jsxs(
170
+ "div",
171
+ {
172
+ style: {
173
+ flex: 1,
174
+ display: "flex",
175
+ gap: 16,
176
+ minHeight: 0
177
+ },
178
+ children: [
179
+ /* @__PURE__ */ jsx("div", { style: { flex: showYaml ? 1.6 : 1, minWidth: 0 }, children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: /* @__PURE__ */ jsx(
180
+ App,
181
+ {
182
+ steps: templateSteps,
183
+ parameters: templateParameters,
184
+ output: templateOutput,
185
+ onStepsChange,
186
+ onParametersChange,
187
+ onOutputChange
188
+ }
189
+ ) }) }),
190
+ showYaml && /* @__PURE__ */ jsxs(
191
+ Paper,
192
+ {
193
+ elevation: 2,
194
+ style: {
195
+ flex: 1,
196
+ display: "flex",
197
+ flexDirection: "column",
198
+ minWidth: 0,
199
+ overflow: "hidden"
200
+ },
201
+ children: [
202
+ /* @__PURE__ */ jsx(
203
+ "div",
204
+ {
205
+ style: {
206
+ padding: "12px 16px",
207
+ borderBottom: "1px solid rgba(0,0,0,0.12)",
208
+ fontWeight: 600,
209
+ fontSize: "0.875rem"
210
+ },
211
+ children: "YAML Preview"
212
+ }
213
+ ),
214
+ yamlError && /* @__PURE__ */ jsx(
215
+ "div",
216
+ {
217
+ style: {
218
+ padding: "8px 16px",
219
+ borderBottom: "1px solid rgba(0,0,0,0.08)",
220
+ color: theme.palette.error.main,
221
+ fontSize: "0.75rem",
222
+ background: paletteMode === "dark" ? "rgba(255, 82, 82, 0.1)" : "rgba(244, 67, 54, 0.08)"
223
+ },
224
+ children: yamlError
225
+ }
226
+ ),
227
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0, overflow: "auto" }, children: /* @__PURE__ */ jsx(
228
+ CodeMirror,
229
+ {
230
+ value: templateYaml,
231
+ extensions: yamlExtensions,
232
+ theme: codeMirrorTheme,
233
+ height: "100%",
234
+ onChange: handleYamlChange,
235
+ onBlur: handleYamlBlur
236
+ }
237
+ ) })
238
+ ]
239
+ }
240
+ )
241
+ ]
242
+ }
243
+ )
244
+ ]
245
+ }
246
+ ) })
238
247
  }
239
- ) }) });
248
+ );
240
249
  };
241
250
 
242
251
  export { TemplateWorkspace };
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateWorkspace.esm.js","sources":["../../../../src/components/TemplateDesigner/components/TemplateWorkspace.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Button, Grid, Paper, Typography } from \"@material-ui/core\";\nimport { useTheme } from \"@material-ui/core/styles\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { yaml } from \"@codemirror/lang-yaml\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../../Nodes/types\";\nimport App from \"../../DesignerFlow/DesignerFlow\";\n\ntype TemplateWorkspaceProps = {\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n showYaml: boolean;\n onToggleYaml: () => void;\n onYamlChange: (value: string) => void;\n onStepsChange: (steps: TaskStep[]) => void;\n onParametersChange: (parameters: TemplateParametersValue) => void;\n onOutputChange: (output?: ScaffolderTaskOutput) => void;\n onReload: () => void;\n onSave: () => void;\n onOpenTemplatePicker: () => void;\n activeTemplateLabel?: string;\n reloadButtonLabel: string;\n saveButtonLabel: string;\n isReloading: boolean;\n isSaving: boolean;\n};\n\nexport const TemplateWorkspace = ({\n templateSteps,\n templateParameters,\n templateOutput,\n templateYaml,\n yamlError,\n loadError,\n showYaml,\n onToggleYaml,\n onYamlChange,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n onReload,\n onSave,\n onOpenTemplatePicker,\n activeTemplateLabel,\n reloadButtonLabel,\n saveButtonLabel,\n isReloading,\n isSaving,\n}: TemplateWorkspaceProps) => {\n const theme = useTheme();\n const paletteMode =\n (theme.palette as { mode?: \"light\" | \"dark\" }).mode ??\n theme.palette.type ??\n \"light\";\n const yamlDraftRef = useRef(templateYaml);\n const templateYamlRef = useRef(templateYaml);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const yamlExtensions = useMemo(() => [yaml()], []);\n const codeMirrorTheme = useMemo(\n () => (paletteMode === \"dark\" ? \"dark\" : \"light\"),\n [paletteMode]\n );\n\n // implementation releated to yaml rendering -> onBlue and onDebounce\n const flushYamlDraft = useCallback(() => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n if (yamlDraftRef.current !== templateYamlRef.current) {\n onYamlChange(yamlDraftRef.current);\n }\n }, [onYamlChange]);\n const handleYamlChange = useCallback(\n (value: string) => {\n yamlDraftRef.current = value;\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n debounceRef.current = setTimeout(() => {\n if (yamlDraftRef.current !== templateYamlRef.current) {\n onYamlChange(yamlDraftRef.current);\n }\n debounceRef.current = null;\n }, 600);\n },\n [onYamlChange]\n );\n const handleYamlBlur = useCallback(() => {\n flushYamlDraft();\n }, [flushYamlDraft]);\n\n useEffect(() => {\n yamlDraftRef.current = templateYaml;\n templateYamlRef.current = templateYaml;\n }, [templateYaml]);\n useEffect(\n () => () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n },\n []\n );\n\n return (\n <Grid container spacing={3} direction=\"column\">\n <Grid item style={{ height: 800 }}>\n <div\n style={{\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n flexWrap: \"wrap\",\n gap: 12,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n flexWrap: \"wrap\",\n }}\n >\n {activeTemplateLabel && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Active template: {activeTemplateLabel}\n </Typography>\n )}\n <Button\n color=\"primary\"\n variant=\"contained\"\n size=\"small\"\n onClick={onReload}\n disabled={isReloading}\n >\n {reloadButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onSave}\n disabled={isSaving}\n >\n {saveButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onOpenTemplatePicker}\n >\n Load different file\n </Button>\n </div>\n <Button variant=\"outlined\" size=\"small\" onClick={onToggleYaml}>\n {showYaml ? \"Hide YAML\" : \"Show YAML\"}\n </Button>\n </div>\n {loadError && (\n <Typography\n variant=\"body2\"\n style={{ color: theme.palette.error.main }}\n >\n {loadError}\n </Typography>\n )}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n gap: 16,\n minHeight: 0,\n }}\n >\n <div style={{ flex: showYaml ? 1.6 : 1, minWidth: 0 }}>\n <div style={{ height: \"100%\" }}>\n <App\n steps={templateSteps}\n parameters={templateParameters}\n output={templateOutput}\n onStepsChange={onStepsChange}\n onParametersChange={onParametersChange}\n onOutputChange={onOutputChange}\n />\n </div>\n </div>\n {showYaml && (\n <Paper\n elevation={2}\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"12px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.12)\",\n fontWeight: 600,\n fontSize: \"0.875rem\",\n }}\n >\n YAML Preview\n </div>\n {yamlError && (\n <div\n style={{\n padding: \"8px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.08)\",\n color: theme.palette.error.main,\n fontSize: \"0.75rem\",\n background:\n paletteMode === \"dark\"\n ? \"rgba(255, 82, 82, 0.1)\"\n : \"rgba(244, 67, 54, 0.08)\",\n }}\n >\n {yamlError}\n </div>\n )}\n <div style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n <CodeMirror\n value={templateYaml}\n extensions={yamlExtensions}\n theme={codeMirrorTheme}\n height=\"100%\"\n onChange={handleYamlChange}\n onBlur={handleYamlBlur}\n />\n </div>\n </Paper>\n )}\n </div>\n </div>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TemplateWorkspace.esm.js","sources":["../../../../src/components/TemplateDesigner/components/TemplateWorkspace.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Button, Grid, Paper, Typography } from \"@material-ui/core\";\nimport { useTheme } from \"@material-ui/core/styles\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { yaml } from \"@codemirror/lang-yaml\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../../Nodes/types\";\nimport App from \"../../DesignerFlow/DesignerFlow\";\n\ntype TemplateWorkspaceProps = {\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n showYaml: boolean;\n onToggleYaml: () => void;\n onYamlChange: (value: string) => void;\n onStepsChange: (steps: TaskStep[]) => void;\n onParametersChange: (parameters: TemplateParametersValue) => void;\n onOutputChange: (output?: ScaffolderTaskOutput) => void;\n onReload: () => void;\n onSave: () => void;\n onOpenTemplatePicker: () => void;\n activeTemplateLabel?: string;\n reloadButtonLabel: string;\n saveButtonLabel: string;\n isReloading: boolean;\n isSaving: boolean;\n};\n\nexport const TemplateWorkspace = ({\n templateSteps,\n templateParameters,\n templateOutput,\n templateYaml,\n yamlError,\n loadError,\n showYaml,\n onToggleYaml,\n onYamlChange,\n onStepsChange,\n onParametersChange,\n onOutputChange,\n onReload,\n onSave,\n onOpenTemplatePicker,\n activeTemplateLabel,\n reloadButtonLabel,\n saveButtonLabel,\n isReloading,\n isSaving,\n}: TemplateWorkspaceProps) => {\n const theme = useTheme();\n const paletteMode =\n (theme.palette as { mode?: \"light\" | \"dark\" }).mode ??\n theme.palette.type ??\n \"light\";\n const yamlDraftRef = useRef(templateYaml);\n const templateYamlRef = useRef(templateYaml);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const yamlExtensions = useMemo(() => [yaml()], []);\n const codeMirrorTheme = useMemo(\n () => (paletteMode === \"dark\" ? \"dark\" : \"light\"),\n [paletteMode]\n );\n\n // implementation releated to yaml rendering -> onBlue and onDebounce\n const flushYamlDraft = useCallback(() => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n if (yamlDraftRef.current !== templateYamlRef.current) {\n onYamlChange(yamlDraftRef.current);\n }\n }, [onYamlChange]);\n const handleYamlChange = useCallback(\n (value: string) => {\n yamlDraftRef.current = value;\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n debounceRef.current = setTimeout(() => {\n if (yamlDraftRef.current !== templateYamlRef.current) {\n onYamlChange(yamlDraftRef.current);\n }\n debounceRef.current = null;\n }, 600);\n },\n [onYamlChange]\n );\n const handleYamlBlur = useCallback(() => {\n flushYamlDraft();\n }, [flushYamlDraft]);\n\n useEffect(() => {\n yamlDraftRef.current = templateYaml;\n templateYamlRef.current = templateYaml;\n }, [templateYaml]);\n useEffect(\n () => () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n },\n []\n );\n\n return (\n <Grid\n container\n spacing={3}\n direction=\"column\"\n style={{ height: \"calc(100% - 15px)\" }}\n >\n <Grid item style={{ height: \"100%\" }}>\n <div\n style={{\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n flexWrap: \"wrap\",\n gap: 12,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n flexWrap: \"wrap\",\n }}\n >\n {activeTemplateLabel && (\n <Typography variant=\"body2\" color=\"textSecondary\">\n Active template: {activeTemplateLabel}\n </Typography>\n )}\n <Button\n color=\"primary\"\n variant=\"contained\"\n size=\"small\"\n onClick={onReload}\n disabled={isReloading}\n >\n {reloadButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onSave}\n disabled={isSaving}\n >\n {saveButtonLabel}\n </Button>\n <Button\n color=\"primary\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onOpenTemplatePicker}\n >\n Load different file\n </Button>\n </div>\n <Button variant=\"outlined\" size=\"small\" onClick={onToggleYaml}>\n {showYaml ? \"Hide YAML\" : \"Show YAML\"}\n </Button>\n </div>\n {loadError && (\n <Typography\n variant=\"body2\"\n style={{ color: theme.palette.error.main }}\n >\n {loadError}\n </Typography>\n )}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n gap: 16,\n minHeight: 0,\n }}\n >\n <div style={{ flex: showYaml ? 1.6 : 1, minWidth: 0 }}>\n <div style={{ height: \"100%\" }}>\n <App\n steps={templateSteps}\n parameters={templateParameters}\n output={templateOutput}\n onStepsChange={onStepsChange}\n onParametersChange={onParametersChange}\n onOutputChange={onOutputChange}\n />\n </div>\n </div>\n {showYaml && (\n <Paper\n elevation={2}\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"12px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.12)\",\n fontWeight: 600,\n fontSize: \"0.875rem\",\n }}\n >\n YAML Preview\n </div>\n {yamlError && (\n <div\n style={{\n padding: \"8px 16px\",\n borderBottom: \"1px solid rgba(0,0,0,0.08)\",\n color: theme.palette.error.main,\n fontSize: \"0.75rem\",\n background:\n paletteMode === \"dark\"\n ? \"rgba(255, 82, 82, 0.1)\"\n : \"rgba(244, 67, 54, 0.08)\",\n }}\n >\n {yamlError}\n </div>\n )}\n <div style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n <CodeMirror\n value={templateYaml}\n extensions={yamlExtensions}\n theme={codeMirrorTheme}\n height=\"100%\"\n onChange={handleYamlChange}\n onBlur={handleYamlBlur}\n />\n </div>\n </Paper>\n )}\n </div>\n </div>\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
- import { useState, useRef, useCallback, useMemo } from 'react';
1
+ import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
2
2
  import { convertJsonToYaml, convertYamlToJson } from '../../utils/yamlJsonConversion.esm.js';
3
3
  import { SAMPLE_TEMPLATE_BLUEPRINT } from '../../utils/sampleTemplate.esm.js';
4
4
  import { cloneDeep, FILE_PICKER_TYPES, asRecord, isTaskStep, cloneSteps, downloadString, DEFAULT_FILE_NAME } from './utils.esm.js';
5
+ import { useApi } from '@backstage/core-plugin-api';
6
+ import { catalogApiRef } from '@backstage/plugin-catalog-react';
5
7
 
6
8
  const parseTemplateYaml = (value) => {
7
9
  const parsed = JSON.parse(convertYamlToJson(value));
@@ -19,6 +21,9 @@ const useTemplateState = () => {
19
21
  const [templateSource, setTemplateSource] = useState();
20
22
  const [isReloading, setIsReloading] = useState(false);
21
23
  const [isSaving, setIsSaving] = useState(false);
24
+ const catalogApi = useApi(catalogApiRef);
25
+ const [selectedTemplate, setSelectedTemplate] = useState(void 0);
26
+ const [availableTemplates, setAvailableTemplates] = useState([]);
22
27
  const fileInputRef = useRef(null);
23
28
  const ensureHandlePermission = useCallback(
24
29
  async (handle, mode) => {
@@ -260,6 +265,15 @@ const useTemplateState = () => {
260
265
  if (!templateSource) {
261
266
  return;
262
267
  }
268
+ if (templateSource.type === "catalog") {
269
+ if (selectedTemplate) {
270
+ applyTemplate(selectedTemplate, {
271
+ type: "catalog",
272
+ label: selectedTemplate.metadata.title ?? selectedTemplate.metadata.name
273
+ });
274
+ }
275
+ return;
276
+ }
263
277
  if (templateSource.type !== "file") {
264
278
  handleStartSampleTemplate();
265
279
  return;
@@ -301,6 +315,7 @@ const useTemplateState = () => {
301
315
  ensureHandlePermission,
302
316
  handleOpenTemplatePicker,
303
317
  handleStartSampleTemplate,
318
+ selectedTemplate,
304
319
  templateSource
305
320
  ]);
306
321
  const handleSaveTemplate = useCallback(async () => {
@@ -362,6 +377,25 @@ const useTemplateState = () => {
362
377
  setIsSaving(false);
363
378
  }
364
379
  }, [ensureHandlePermission, templateObject, templateSource, templateYaml]);
380
+ useEffect(() => {
381
+ catalogApi.getEntities({
382
+ filter: {
383
+ kind: "Template"
384
+ }
385
+ }).then((data) => {
386
+ setAvailableTemplates(data.items);
387
+ }).catch(() => setAvailableTemplates([]));
388
+ }, [catalogApi]);
389
+ const selectCatalogTemplate = useCallback(
390
+ (selected) => {
391
+ setSelectedTemplate(selected);
392
+ applyTemplate(selected, {
393
+ type: "catalog",
394
+ label: selected.metadata.title ?? selected.metadata.name
395
+ });
396
+ },
397
+ [applyTemplate]
398
+ );
365
399
  return {
366
400
  templateObject,
367
401
  templateYaml,
@@ -383,7 +417,9 @@ const useTemplateState = () => {
383
417
  handleParametersChange,
384
418
  handleOutputChange,
385
419
  handleReloadFromFile,
386
- handleSaveTemplate
420
+ handleSaveTemplate,
421
+ availableTemplates,
422
+ selectCatalogTemplate
387
423
  };
388
424
  };
389
425
 
@@ -1 +1 @@
1
- {"version":3,"file":"useTemplateState.esm.js","sources":["../../../src/components/TemplateDesigner/useTemplateState.ts"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { ChangeEvent, RefObject } from \"react\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../Nodes/types\";\nimport {\n convertJsonToYaml,\n convertYamlToJson,\n} from \"../../utils/yamlJsonConversion\";\nimport { SAMPLE_TEMPLATE_BLUEPRINT } from \"../../utils/sampleTemplate\";\nimport {\n DEFAULT_FILE_NAME,\n FILE_PICKER_TYPES,\n FileSystemFileHandleLike,\n FileSystemWindow,\n TemplateSource,\n asRecord,\n cloneDeep,\n cloneSteps,\n downloadString,\n isTaskStep,\n} from \"./utils\";\n\ntype TemplateState = {\n templateObject: Record<string, unknown> | null;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n isDirty: boolean;\n templateSource?: TemplateSource;\n isReloading: boolean;\n isSaving: boolean;\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n fileInputRef: RefObject<HTMLInputElement>;\n handleStartSampleTemplate: () => void;\n handleTemplateFileSelected: (event: ChangeEvent<HTMLInputElement>) => void;\n handleOpenTemplatePicker: () => void;\n handleYamlChange: (value: string) => void;\n handleStepsChange: (steps: TaskStep[]) => void;\n handleParametersChange: (parameters: TemplateParametersValue) => void;\n handleOutputChange: (output?: ScaffolderTaskOutput) => void;\n handleReloadFromFile: () => void;\n handleSaveTemplate: () => void;\n};\n\nconst parseTemplateYaml = (value: string) => {\n const parsed = JSON.parse(convertYamlToJson(value));\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Template YAML must describe an object\");\n }\n return parsed as Record<string, unknown>;\n};\n\n/**\n * Encapsulates the template designer data model including YAML parsing,\n * scaffolder spec updates, and file-system interactions.\n */\nexport const useTemplateState = (): TemplateState => {\n const [templateObject, setTemplateObject] = useState<Record<\n string,\n unknown\n > | null>(null);\n const [templateYaml, setTemplateYaml] = useState(\"\");\n const [yamlError, setYamlError] = useState<string | undefined>();\n const [loadError, setLoadError] = useState<string | undefined>();\n const [isDirty, setIsDirty] = useState(false);\n const [templateSource, setTemplateSource] = useState<\n TemplateSource | undefined\n >();\n const [isReloading, setIsReloading] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n\n const ensureHandlePermission = useCallback(\n async (\n handle: FileSystemFileHandleLike | undefined,\n mode: \"read\" | \"readwrite\"\n ) => {\n if (!handle || !handle.queryPermission || !handle.requestPermission) {\n return true;\n }\n const options = { mode };\n const current = await handle.queryPermission(options);\n if (current === \"granted\") {\n return true;\n }\n const request = await handle.requestPermission(options);\n return request === \"granted\";\n },\n []\n );\n\n const applyTemplate = useCallback(\n (template: Record<string, unknown>, source: TemplateSource) => {\n const nextTemplate = cloneDeep(template);\n const nextYaml = convertJsonToYaml(nextTemplate);\n setTemplateObject(nextTemplate);\n setTemplateYaml(nextYaml);\n setYamlError(undefined);\n setLoadError(undefined);\n setTemplateSource(source);\n setIsDirty(false);\n },\n []\n );\n\n const confirmDiscardChanges = useCallback(() => {\n if (!templateObject || !isDirty) {\n return true;\n }\n\n if (typeof window === \"undefined\") {\n return true;\n }\n\n // eslint-disable-next-line no-alert\n return window.confirm(\n \"This will discard the changes you have made. Continue?\"\n );\n }, [isDirty, templateObject]);\n\n const handleStartSampleTemplate = useCallback(() => {\n if (!confirmDiscardChanges()) {\n return;\n }\n applyTemplate(SAMPLE_TEMPLATE_BLUEPRINT, {\n type: \"sample\",\n label: \"Sample template\",\n });\n }, [applyTemplate, confirmDiscardChanges]);\n\n const handleTemplateFileSelected = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n event.target.value = \"\";\n\n if (!file) {\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n const fileContents = await file.text();\n const parsed = parseTemplateYaml(fileContents);\n applyTemplate(parsed, {\n type: \"file\",\n label: file.name,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n },\n [applyTemplate, confirmDiscardChanges]\n );\n\n const handleOpenTemplatePicker = useCallback(async () => {\n if (!confirmDiscardChanges()) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const fsWindow = window as FileSystemWindow;\n\n if (fsWindow.showOpenFilePicker) {\n try {\n const handles = await fsWindow.showOpenFilePicker({\n multiple: false,\n types: FILE_PICKER_TYPES,\n });\n const [handle] = handles ?? [];\n if (!handle) {\n return;\n }\n\n const granted = await ensureHandlePermission(handle, \"read\");\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: handle.name ?? file.name,\n handle,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return;\n }\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n return;\n }\n\n fileInputRef.current?.click();\n }, [applyTemplate, confirmDiscardChanges, ensureHandlePermission]);\n\n const templateSteps = useMemo(() => {\n if (!templateObject) {\n return [];\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return [];\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return [];\n }\n\n const maybeSteps = spec.steps;\n if (!Array.isArray(maybeSteps)) {\n return [];\n }\n\n const validSteps = maybeSteps.filter(isTaskStep) as TaskStep[];\n return cloneSteps(validSteps);\n }, [templateObject]);\n\n const templateParameters = useMemo((): TemplateParametersValue => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n if (!Object.prototype.hasOwnProperty.call(spec, \"parameters\")) {\n return undefined;\n }\n\n const rawParameters = (spec as Record<string, unknown>).parameters;\n if (rawParameters === undefined) {\n return undefined;\n }\n\n return cloneDeep(rawParameters as TemplateParametersValue);\n }, [templateObject]);\n\n const templateOutput = useMemo(() => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n const rawOutput = spec.output;\n if (!rawOutput || typeof rawOutput !== \"object\") {\n return undefined;\n }\n\n return cloneDeep(rawOutput as ScaffolderTaskOutput);\n }, [templateObject]);\n\n const handleYamlChange = useCallback((value: string) => {\n setTemplateYaml(value);\n setIsDirty(true);\n try {\n const parsed = parseTemplateYaml(value);\n setTemplateObject(parsed);\n setYamlError(undefined);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error parsing YAML\";\n setYamlError(message);\n }\n }, []);\n\n const handleStepsChange = useCallback((steps: TaskStep[]) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextSteps = cloneSteps(steps);\n\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n steps: nextSteps,\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleParametersChange = useCallback(\n (parameters: TemplateParametersValue) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n parameters: cloneDeep(parameters),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n },\n []\n );\n\n const handleOutputChange = useCallback((output?: ScaffolderTaskOutput) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n output: cloneDeep(output),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleReloadFromFile = useCallback(async () => {\n if (!templateSource) {\n return;\n }\n\n if (templateSource.type !== \"file\") {\n handleStartSampleTemplate();\n return;\n }\n\n if (!templateSource.handle) {\n handleOpenTemplatePicker();\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n setIsReloading(true);\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"read\"\n );\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await templateSource.handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: templateSource.handle.name ?? file.name ?? templateSource.label,\n handle: templateSource.handle,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error reloading template\";\n setLoadError(`Could not reload template: ${message}`);\n } finally {\n setIsReloading(false);\n }\n }, [\n applyTemplate,\n confirmDiscardChanges,\n ensureHandlePermission,\n handleOpenTemplatePicker,\n handleStartSampleTemplate,\n templateSource,\n ]);\n\n const handleSaveTemplate = useCallback(async () => {\n if (!templateObject) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n downloadString(templateYaml, DEFAULT_FILE_NAME);\n setIsDirty(false);\n return;\n }\n\n try {\n setIsSaving(true);\n setLoadError(undefined);\n const fsWindow = window as FileSystemWindow;\n\n if (templateSource?.type === \"file\" && templateSource.handle) {\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"readwrite\"\n );\n if (!granted) {\n setLoadError(\"Permission to save to the selected file was denied.\");\n return;\n }\n const writable = await templateSource.handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setIsDirty(false);\n return;\n }\n\n if (fsWindow.showSaveFilePicker) {\n const handle = await fsWindow.showSaveFilePicker({\n suggestedName: templateSource?.label ?? DEFAULT_FILE_NAME,\n types: FILE_PICKER_TYPES,\n });\n const writable = await handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setTemplateSource({\n type: \"file\",\n label: handle.name ?? templateSource?.label ?? DEFAULT_FILE_NAME,\n handle,\n });\n setIsDirty(false);\n return;\n }\n\n downloadString(templateYaml, templateSource?.label ?? DEFAULT_FILE_NAME);\n setIsDirty(false);\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error saving template\";\n setLoadError(`Failed to save template: ${message}`);\n } finally {\n setIsSaving(false);\n }\n }, [ensureHandlePermission, templateObject, templateSource, templateYaml]);\n\n return {\n templateObject,\n templateYaml,\n yamlError,\n loadError,\n isDirty,\n templateSource,\n isReloading,\n isSaving,\n templateSteps,\n templateParameters,\n templateOutput,\n fileInputRef,\n handleStartSampleTemplate,\n handleTemplateFileSelected,\n handleOpenTemplatePicker,\n handleYamlChange,\n handleStepsChange,\n handleParametersChange,\n handleOutputChange,\n handleReloadFromFile,\n handleSaveTemplate,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useTemplateState.esm.js","sources":["../../../src/components/TemplateDesigner/useTemplateState.ts"],"sourcesContent":["import {\n ChangeEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ScaffolderTaskOutput,\n TaskStep,\n} from \"@backstage/plugin-scaffolder-common\";\nimport { TemplateEntityV1beta3 } from \"@backstage/plugin-scaffolder-common\";\nimport type { TemplateParametersValue } from \"../Nodes/types\";\nimport {\n convertJsonToYaml,\n convertYamlToJson,\n} from \"../../utils/yamlJsonConversion\";\nimport { SAMPLE_TEMPLATE_BLUEPRINT } from \"../../utils/sampleTemplate\";\nimport {\n asRecord,\n cloneDeep,\n cloneSteps,\n DEFAULT_FILE_NAME,\n downloadString,\n FILE_PICKER_TYPES,\n FileSystemFileHandleLike,\n FileSystemWindow,\n isTaskStep,\n TemplateSource,\n} from \"./utils\";\nimport { useApi } from \"@backstage/core-plugin-api\";\nimport { catalogApiRef } from \"@backstage/plugin-catalog-react\";\n\ntype TemplateState = {\n templateObject: Record<string, unknown> | null;\n templateYaml: string;\n yamlError?: string;\n loadError?: string;\n isDirty: boolean;\n templateSource?: TemplateSource;\n isReloading: boolean;\n isSaving: boolean;\n templateSteps: TaskStep[];\n templateParameters: TemplateParametersValue;\n templateOutput?: ScaffolderTaskOutput;\n fileInputRef: RefObject<HTMLInputElement>;\n handleStartSampleTemplate: () => void;\n handleTemplateFileSelected: (event: ChangeEvent<HTMLInputElement>) => void;\n handleOpenTemplatePicker: () => void;\n handleYamlChange: (value: string) => void;\n handleStepsChange: (steps: TaskStep[]) => void;\n handleParametersChange: (parameters: TemplateParametersValue) => void;\n handleOutputChange: (output?: ScaffolderTaskOutput) => void;\n handleReloadFromFile: () => void;\n handleSaveTemplate: () => void;\n availableTemplates: TemplateEntityV1beta3[];\n selectCatalogTemplate: (selected: TemplateEntityV1beta3) => void;\n};\n\nconst parseTemplateYaml = (value: string) => {\n const parsed = JSON.parse(convertYamlToJson(value));\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Template YAML must describe an object\");\n }\n return parsed as Record<string, unknown>;\n};\n\n/**\n * Encapsulates the template designer data model including YAML parsing,\n * scaffolder spec updates, and file-system interactions.\n */\nexport const useTemplateState = (): TemplateState => {\n const [templateObject, setTemplateObject] = useState<Record<\n string,\n unknown\n > | null>(null);\n const [templateYaml, setTemplateYaml] = useState(\"\");\n const [yamlError, setYamlError] = useState<string | undefined>();\n const [loadError, setLoadError] = useState<string | undefined>();\n const [isDirty, setIsDirty] = useState(false);\n const [templateSource, setTemplateSource] = useState<\n TemplateSource | undefined\n >();\n const [isReloading, setIsReloading] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const catalogApi = useApi(catalogApiRef);\n const [selectedTemplate, setSelectedTemplate] = useState<\n TemplateEntityV1beta3 | undefined\n >(undefined);\n const [availableTemplates, setAvailableTemplates] = useState<\n TemplateEntityV1beta3[]\n >([]);\n\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n\n const ensureHandlePermission = useCallback(\n async (\n handle: FileSystemFileHandleLike | undefined,\n mode: \"read\" | \"readwrite\"\n ) => {\n if (!handle || !handle.queryPermission || !handle.requestPermission) {\n return true;\n }\n const options = { mode };\n const current = await handle.queryPermission(options);\n if (current === \"granted\") {\n return true;\n }\n const request = await handle.requestPermission(options);\n return request === \"granted\";\n },\n []\n );\n\n const applyTemplate = useCallback(\n (template: Record<string, unknown>, source: TemplateSource) => {\n const nextTemplate = cloneDeep(template);\n const nextYaml = convertJsonToYaml(nextTemplate);\n setTemplateObject(nextTemplate);\n setTemplateYaml(nextYaml);\n setYamlError(undefined);\n setLoadError(undefined);\n setTemplateSource(source);\n setIsDirty(false);\n },\n []\n );\n\n const confirmDiscardChanges = useCallback(() => {\n if (!templateObject || !isDirty) {\n return true;\n }\n\n if (typeof window === \"undefined\") {\n return true;\n }\n\n // eslint-disable-next-line no-alert\n return window.confirm(\n \"This will discard the changes you have made. Continue?\"\n );\n }, [isDirty, templateObject]);\n\n const handleStartSampleTemplate = useCallback(() => {\n if (!confirmDiscardChanges()) {\n return;\n }\n applyTemplate(SAMPLE_TEMPLATE_BLUEPRINT, {\n type: \"sample\",\n label: \"Sample template\",\n });\n }, [applyTemplate, confirmDiscardChanges]);\n\n const handleTemplateFileSelected = useCallback(\n async (event: ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n event.target.value = \"\";\n\n if (!file) {\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n const fileContents = await file.text();\n const parsed = parseTemplateYaml(fileContents);\n applyTemplate(parsed, {\n type: \"file\",\n label: file.name,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n },\n [applyTemplate, confirmDiscardChanges]\n );\n\n const handleOpenTemplatePicker = useCallback(async () => {\n if (!confirmDiscardChanges()) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const fsWindow = window as FileSystemWindow;\n\n if (fsWindow.showOpenFilePicker) {\n try {\n const handles = await fsWindow.showOpenFilePicker({\n multiple: false,\n types: FILE_PICKER_TYPES,\n });\n const [handle] = handles ?? [];\n if (!handle) {\n return;\n }\n\n const granted = await ensureHandlePermission(handle, \"read\");\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: handle.name ?? file.name,\n handle,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return;\n }\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error loading template\";\n setLoadError(`Could not load template: ${message}`);\n }\n return;\n }\n\n fileInputRef.current?.click();\n }, [applyTemplate, confirmDiscardChanges, ensureHandlePermission]);\n\n const templateSteps = useMemo(() => {\n if (!templateObject) {\n return [];\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return [];\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return [];\n }\n\n const maybeSteps = spec.steps;\n if (!Array.isArray(maybeSteps)) {\n return [];\n }\n\n const validSteps = maybeSteps.filter(isTaskStep) as TaskStep[];\n return cloneSteps(validSteps);\n }, [templateObject]);\n\n const templateParameters = useMemo((): TemplateParametersValue => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n if (!Object.prototype.hasOwnProperty.call(spec, \"parameters\")) {\n return undefined;\n }\n\n const rawParameters = (spec as Record<string, unknown>).parameters;\n if (rawParameters === undefined) {\n return undefined;\n }\n\n return cloneDeep(rawParameters as TemplateParametersValue);\n }, [templateObject]);\n\n const templateOutput = useMemo(() => {\n if (!templateObject) {\n return undefined;\n }\n\n const template = asRecord(templateObject);\n if (!template) {\n return undefined;\n }\n\n const spec = asRecord(template.spec);\n if (!spec) {\n return undefined;\n }\n\n const rawOutput = spec.output;\n if (!rawOutput || typeof rawOutput !== \"object\") {\n return undefined;\n }\n\n return cloneDeep(rawOutput as ScaffolderTaskOutput);\n }, [templateObject]);\n\n const handleYamlChange = useCallback((value: string) => {\n setTemplateYaml(value);\n setIsDirty(true);\n try {\n const parsed = parseTemplateYaml(value);\n setTemplateObject(parsed);\n setYamlError(undefined);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Unknown error parsing YAML\";\n setYamlError(message);\n }\n }, []);\n\n const handleStepsChange = useCallback((steps: TaskStep[]) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextSteps = cloneSteps(steps);\n\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n steps: nextSteps,\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleParametersChange = useCallback(\n (parameters: TemplateParametersValue) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n parameters: cloneDeep(parameters),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n },\n []\n );\n\n const handleOutputChange = useCallback((output?: ScaffolderTaskOutput) => {\n setIsDirty(true);\n setTemplateObject((prevTemplate) => {\n const base =\n prevTemplate && typeof prevTemplate === \"object\"\n ? (cloneDeep(prevTemplate) as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n\n const spec = asRecord(base.spec) ?? {};\n const nextTemplate: Record<string, unknown> = {\n ...base,\n spec: {\n ...spec,\n output: cloneDeep(output),\n },\n };\n\n setTemplateYaml(convertJsonToYaml(nextTemplate));\n return nextTemplate;\n });\n }, []);\n\n const handleReloadFromFile = useCallback(async () => {\n if (!templateSource) {\n return;\n }\n\n if (templateSource.type === \"catalog\") {\n if (selectedTemplate) {\n applyTemplate(selectedTemplate as unknown as Record<string, unknown>, {\n type: \"catalog\",\n label:\n selectedTemplate.metadata.title ?? selectedTemplate.metadata.name,\n });\n }\n return;\n }\n if (templateSource.type !== \"file\") {\n handleStartSampleTemplate();\n return;\n }\n\n if (!templateSource.handle) {\n handleOpenTemplatePicker();\n return;\n }\n\n if (!confirmDiscardChanges()) {\n return;\n }\n\n try {\n setIsReloading(true);\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"read\"\n );\n if (!granted) {\n setLoadError(\"Permission to read the selected file was denied.\");\n return;\n }\n\n const file = await templateSource.handle.getFile();\n const text = await file.text();\n const parsed = parseTemplateYaml(text);\n applyTemplate(parsed, {\n type: \"file\",\n label: templateSource.handle.name ?? file.name ?? templateSource.label,\n handle: templateSource.handle,\n });\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error reloading template\";\n setLoadError(`Could not reload template: ${message}`);\n } finally {\n setIsReloading(false);\n }\n }, [\n applyTemplate,\n confirmDiscardChanges,\n ensureHandlePermission,\n handleOpenTemplatePicker,\n handleStartSampleTemplate,\n selectedTemplate,\n templateSource,\n ]);\n\n const handleSaveTemplate = useCallback(async () => {\n if (!templateObject) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n downloadString(templateYaml, DEFAULT_FILE_NAME);\n setIsDirty(false);\n return;\n }\n\n try {\n setIsSaving(true);\n setLoadError(undefined);\n const fsWindow = window as FileSystemWindow;\n\n if (templateSource?.type === \"file\" && templateSource.handle) {\n const granted = await ensureHandlePermission(\n templateSource.handle,\n \"readwrite\"\n );\n if (!granted) {\n setLoadError(\"Permission to save to the selected file was denied.\");\n return;\n }\n const writable = await templateSource.handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setIsDirty(false);\n return;\n }\n\n if (fsWindow.showSaveFilePicker) {\n const handle = await fsWindow.showSaveFilePicker({\n suggestedName: templateSource?.label ?? DEFAULT_FILE_NAME,\n types: FILE_PICKER_TYPES,\n });\n const writable = await handle.createWritable?.();\n if (!writable) {\n throw new Error(\"Unable to open file for writing.\");\n }\n await writable.write(templateYaml);\n await writable.close();\n setTemplateSource({\n type: \"file\",\n label: handle.name ?? templateSource?.label ?? DEFAULT_FILE_NAME,\n handle,\n });\n setIsDirty(false);\n return;\n }\n\n downloadString(templateYaml, templateSource?.label ?? DEFAULT_FILE_NAME);\n setIsDirty(false);\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error saving template\";\n setLoadError(`Failed to save template: ${message}`);\n } finally {\n setIsSaving(false);\n }\n }, [ensureHandlePermission, templateObject, templateSource, templateYaml]);\n\n useEffect(() => {\n catalogApi\n .getEntities({\n filter: {\n kind: \"Template\",\n },\n })\n .then((data) => {\n setAvailableTemplates(data.items as TemplateEntityV1beta3[]);\n })\n .catch(() => setAvailableTemplates([]));\n }, [catalogApi]);\n\n const selectCatalogTemplate = useCallback(\n (selected: TemplateEntityV1beta3) => {\n setSelectedTemplate(selected);\n applyTemplate(selected as unknown as Record<string, unknown>, {\n type: \"catalog\",\n label: selected.metadata.title ?? selected.metadata.name,\n });\n },\n [applyTemplate]\n );\n\n return {\n templateObject,\n templateYaml,\n yamlError,\n loadError,\n isDirty,\n templateSource,\n isReloading,\n isSaving,\n templateSteps,\n templateParameters,\n templateOutput,\n fileInputRef,\n handleStartSampleTemplate,\n handleTemplateFileSelected,\n handleOpenTemplatePicker,\n handleYamlChange,\n handleStepsChange,\n handleParametersChange,\n handleOutputChange,\n handleReloadFromFile,\n handleSaveTemplate,\n availableTemplates,\n selectCatalogTemplate,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.esm.js","sources":["../../../src/components/TemplateDesigner/utils.ts"],"sourcesContent":["import type { TaskStep } from \"@backstage/plugin-scaffolder-common\";\n\nexport const FILE_PICKER_ACCEPT = {\n \"application/yaml\": [\".yaml\", \".yml\"],\n \"application/json\": [\".json\"],\n};\n\nexport const FILE_PICKER_TYPES = [\n {\n description: \"Scaffolder template\",\n accept: FILE_PICKER_ACCEPT,\n },\n];\n\nexport const DEFAULT_FILE_NAME = \"template.yaml\";\n\nexport const isTaskStep = (candidate: unknown): candidate is TaskStep => {\n if (!candidate || typeof candidate !== \"object\") {\n return false;\n }\n const step = candidate as Record<string, unknown>;\n return (\n typeof step.id === \"string\" &&\n typeof step.name === \"string\" &&\n typeof step.action === \"string\"\n );\n};\n\nexport const cloneDeep = <T>(value: T): T => {\n if (value === undefined || value === null) {\n return value;\n }\n return JSON.parse(JSON.stringify(value)) as T;\n};\n\nexport const cloneSteps = (steps: TaskStep[]): TaskStep[] =>\n steps.map((step) => cloneDeep(step));\n\nexport const asRecord = (\n candidate: unknown\n): Record<string, unknown> | undefined => {\n if (!candidate || typeof candidate !== \"object\") {\n return undefined;\n }\n return candidate as Record<string, unknown>;\n};\n\nexport const downloadString = (value: string, fileName: string) => {\n const blob = new Blob([value], { type: \"text/yaml\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = \"none\";\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n};\n\nexport type FileSystemFileHandleLike = {\n name?: string;\n getFile: () => Promise<File>;\n createWritable?: () => Promise<{\n write: (data: Blob | string) => Promise<void>;\n close: () => Promise<void>;\n }>;\n queryPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n requestPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n};\n\nexport type TemplateSource =\n | { type: \"sample\"; label: string }\n | { type: \"file\"; label: string; handle?: FileSystemFileHandleLike };\n\nexport type FileSystemWindow = Window &\n Partial<{\n showOpenFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike[]>;\n showSaveFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike>;\n }>;\n"],"names":[],"mappings":"AAEO,MAAM,kBAAA,GAAqB;AAAA,EAChC,kBAAA,EAAoB,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpC,kBAAA,EAAoB,CAAC,OAAO;AAC9B;AAEO,MAAM,iBAAA,GAAoB;AAAA,EAC/B;AAAA,IACE,WAAA,EAAa,qBAAA;AAAA,IACb,MAAA,EAAQ;AAAA;AAEZ;AAEO,MAAM,iBAAA,GAAoB;AAE1B,MAAM,UAAA,GAAa,CAAC,SAAA,KAA8C;AACvE,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,SAAA;AACb,EAAA,OACE,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,IACnB,OAAO,KAAK,IAAA,KAAS,QAAA,IACrB,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA;AAE3B;AAEO,MAAM,SAAA,GAAY,CAAI,KAAA,KAAgB;AAC3C,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACzC;AAEO,MAAM,UAAA,GAAa,CAAC,KAAA,KACzB,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,SAAA,CAAU,IAAI,CAAC;AAE9B,MAAM,QAAA,GAAW,CACtB,SAAA,KACwC;AACxC,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AAEO,MAAM,cAAA,GAAiB,CAAC,KAAA,EAAe,QAAA,KAAqB;AACjE,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,KAAK,CAAA,EAAG,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AACpD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACzC,EAAA,MAAA,CAAO,IAAA,GAAO,GAAA;AACd,EAAA,MAAA,CAAO,QAAA,GAAW,QAAA;AAClB,EAAA,MAAA,CAAO,MAAM,OAAA,GAAU,MAAA;AACvB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;;;;"}
1
+ {"version":3,"file":"utils.esm.js","sources":["../../../src/components/TemplateDesigner/utils.ts"],"sourcesContent":["import type { TaskStep } from \"@backstage/plugin-scaffolder-common\";\n\nexport const FILE_PICKER_ACCEPT = {\n \"application/yaml\": [\".yaml\", \".yml\"],\n \"application/json\": [\".json\"],\n};\n\nexport const FILE_PICKER_TYPES = [\n {\n description: \"Scaffolder template\",\n accept: FILE_PICKER_ACCEPT,\n },\n];\n\nexport const DEFAULT_FILE_NAME = \"template.yaml\";\n\nexport const isTaskStep = (candidate: unknown): candidate is TaskStep => {\n if (!candidate || typeof candidate !== \"object\") {\n return false;\n }\n const step = candidate as Record<string, unknown>;\n return (\n typeof step.id === \"string\" &&\n typeof step.name === \"string\" &&\n typeof step.action === \"string\"\n );\n};\n\nexport const cloneDeep = <T>(value: T): T => {\n if (value === undefined || value === null) {\n return value;\n }\n return JSON.parse(JSON.stringify(value)) as T;\n};\n\nexport const cloneSteps = (steps: TaskStep[]): TaskStep[] =>\n steps.map((step) => cloneDeep(step));\n\nexport const asRecord = (\n candidate: unknown\n): Record<string, unknown> | undefined => {\n if (!candidate || typeof candidate !== \"object\") {\n return undefined;\n }\n return candidate as Record<string, unknown>;\n};\n\nexport const downloadString = (value: string, fileName: string) => {\n const blob = new Blob([value], { type: \"text/yaml\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = \"none\";\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n};\n\nexport type FileSystemFileHandleLike = {\n name?: string;\n getFile: () => Promise<File>;\n createWritable?: () => Promise<{\n write: (data: Blob | string) => Promise<void>;\n close: () => Promise<void>;\n }>;\n queryPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n requestPermission?: (options?: {\n mode?: \"read\" | \"readwrite\";\n }) => Promise<PermissionState>;\n};\n\nexport type TemplateSource =\n | { type: \"sample\"; label: string }\n | { type: \"file\"; label: string; handle?: FileSystemFileHandleLike }\n | { type: \"catalog\"; label: string };\n\nexport type FileSystemWindow = Window &\n Partial<{\n showOpenFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike[]>;\n showSaveFilePicker: (\n options?: unknown\n ) => Promise<FileSystemFileHandleLike>;\n }>;\n"],"names":[],"mappings":"AAEO,MAAM,kBAAA,GAAqB;AAAA,EAChC,kBAAA,EAAoB,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpC,kBAAA,EAAoB,CAAC,OAAO;AAC9B;AAEO,MAAM,iBAAA,GAAoB;AAAA,EAC/B;AAAA,IACE,WAAA,EAAa,qBAAA;AAAA,IACb,MAAA,EAAQ;AAAA;AAEZ;AAEO,MAAM,iBAAA,GAAoB;AAE1B,MAAM,UAAA,GAAa,CAAC,SAAA,KAA8C;AACvE,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,SAAA;AACb,EAAA,OACE,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,IACnB,OAAO,KAAK,IAAA,KAAS,QAAA,IACrB,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA;AAE3B;AAEO,MAAM,SAAA,GAAY,CAAI,KAAA,KAAgB;AAC3C,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACzC;AAEO,MAAM,UAAA,GAAa,CAAC,KAAA,KACzB,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,SAAA,CAAU,IAAI,CAAC;AAE9B,MAAM,QAAA,GAAW,CACtB,SAAA,KACwC;AACxC,EAAA,IAAI,CAAC,SAAA,IAAa,OAAO,SAAA,KAAc,QAAA,EAAU;AAC/C,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AAEO,MAAM,cAAA,GAAiB,CAAC,KAAA,EAAe,QAAA,KAAqB;AACjE,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,KAAK,CAAA,EAAG,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AACpD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACzC,EAAA,MAAA,CAAO,IAAA,GAAO,GAAA;AACd,EAAA,MAAA,CAAO,QAAA,GAAW,QAAA;AAClB,EAAA,MAAA,CAAO,MAAM,OAAA,GAAU,MAAA;AACvB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;;;;"}
@@ -0,0 +1,164 @@
1
+ var name = "@tduniec/plugin-template-designer";
2
+ var description = "Template Designer turns blank Backstage YAML into a storyboard-like canvas, guiding anyone through drag-and-drop scaffolder authoring before ever touching code. Rally non-experts, broadcast best practices, and accelerate template launches directly inside Backstage.";
3
+ var version = "0.2.4";
4
+ var license = "Apache-2.0";
5
+ var keywords = [
6
+ "backstage",
7
+ "scaffolder",
8
+ "template-designer",
9
+ "no-code",
10
+ "yaml",
11
+ "canvas"
12
+ ];
13
+ var repository = {
14
+ type: "git",
15
+ url: "git+https://github.com/tduniec/template-designer-plugin.git",
16
+ directory: "."
17
+ };
18
+ var exports = {
19
+ ".": "./src/index.ts",
20
+ "./alpha": "./src/alpha.tsx",
21
+ "./package.json": "./package.json"
22
+ };
23
+ var main = "dist/index.esm.js";
24
+ var types = "dist/index.d.ts";
25
+ var publishConfig = {
26
+ access: "public",
27
+ main: "dist/index.esm.js",
28
+ types: "dist/index.d.ts"
29
+ };
30
+ var backstage = {
31
+ role: "frontend-plugin",
32
+ pluginId: "template-designer",
33
+ pluginPackages: [
34
+ "@tduniec/plugin-template-designer"
35
+ ],
36
+ features: {
37
+ "./alpha": "@backstage/FrontendPlugin"
38
+ }
39
+ };
40
+ var sideEffects = false;
41
+ var scripts = {
42
+ start: "backstage-cli package start",
43
+ build: "backstage-cli package build",
44
+ lint: "backstage-cli package lint",
45
+ test: "backstage-cli package test",
46
+ clean: "backstage-cli package clean",
47
+ tsc: "tsc",
48
+ "tsc:full": "tsc --skipLibCheck false --incremental false",
49
+ "lint:all": "backstage-cli repo lint",
50
+ "prettier:check": "prettier --check .",
51
+ prepack: "backstage-cli package prepack",
52
+ postpack: "backstage-cli package postpack",
53
+ validate: "tsc && backstage-cli package lint && prettier --check .",
54
+ "validate:fix": "tsc && backstage-cli package lint --fix && prettier -w .",
55
+ "validate:full": "tsc --skipLibCheck false --incremental false && backstage-cli repo lint && prettier --check .",
56
+ prepare: "husky"
57
+ };
58
+ var dependencies = {
59
+ "@backstage/core-compat-api": "backstage:^",
60
+ "@backstage/core-components": "backstage:^",
61
+ "@backstage/core-plugin-api": "backstage:^",
62
+ "@backstage/frontend-plugin-api": "backstage:^",
63
+ "@backstage/plugin-catalog-react": "backstage:^",
64
+ "@backstage/plugin-scaffolder-common": "backstage:^",
65
+ "@backstage/plugin-scaffolder-react": "backstage:^",
66
+ "@backstage/theme": "backstage:^",
67
+ "@codemirror/lang-yaml": "^6.1.2",
68
+ "@material-ui/core": "^4.12.4",
69
+ "@material-ui/icons": "^4.11.3",
70
+ "@material-ui/lab": "^4.0.0-alpha.61",
71
+ "@xyflow/react": "^12.8.6",
72
+ yaml: "^2.8.1"
73
+ };
74
+ var peerDependencies = {
75
+ "@codemirror/lang-yaml": "^6.0.0",
76
+ "@codemirror/state": "^6.0.0",
77
+ "@codemirror/view": "^6.0.0",
78
+ "@uiw/react-codemirror": "^4.25.2",
79
+ react: "^18.0.0",
80
+ "react-router-dom": "^6.23.0",
81
+ "react-use": "^17.2.4"
82
+ };
83
+ var devDependencies = {
84
+ "@backstage/catalog-client": "backstage:^",
85
+ "@backstage/catalog-model": "backstage:^",
86
+ "@backstage/cli": "backstage:^",
87
+ "@backstage/core-app-api": "backstage:^",
88
+ "@backstage/dev-utils": "backstage:^",
89
+ "@backstage/plugin-catalog-common": "backstage:^",
90
+ "@backstage/test-utils": "backstage:^",
91
+ "@codemirror/lang-yaml": "6.1.2",
92
+ "@codemirror/state": "6.5.2",
93
+ "@codemirror/view": "6.26.3",
94
+ "@commitlint/cli": "^20.1.0",
95
+ "@commitlint/config-conventional": "^20.0.0",
96
+ "@semantic-release/changelog": "^6.0.3",
97
+ "@semantic-release/commit-analyzer": "^13.0.1",
98
+ "@semantic-release/git": "^10.0.1",
99
+ "@semantic-release/github": "^12.0.1",
100
+ "@semantic-release/npm": "^13.1.1",
101
+ "@semantic-release/release-notes-generator": "^14.1.0",
102
+ "@testing-library/dom": "^10.0.0",
103
+ "@testing-library/jest-dom": "^6.0.0",
104
+ "@testing-library/react": "^16.0.0",
105
+ "@testing-library/user-event": "^14.0.0",
106
+ "@types/react": "^18",
107
+ "@types/react-dom": "^18",
108
+ "@uiw/react-codemirror": "4.25.2",
109
+ husky: "^9.1.7",
110
+ "lint-staged": "^16.2.6",
111
+ msw: "^1.0.0",
112
+ prettier: "^2.3.2",
113
+ react: "^18.3.1",
114
+ "react-dom": "^18.3.1",
115
+ "react-router-dom": "^6.23.0",
116
+ "react-use": "^17.2.4",
117
+ "semantic-release": "^25.0.1",
118
+ typescript: "~5.8.0",
119
+ webpack: "~5.96.0"
120
+ };
121
+ var files = [
122
+ "dist"
123
+ ];
124
+ var packageManager = "yarn@4.10.3";
125
+ var typesVersions = {
126
+ "*": {
127
+ alpha: [
128
+ "dist/alpha.d.ts"
129
+ ],
130
+ "package.json": [
131
+ "package.json"
132
+ ]
133
+ }
134
+ };
135
+ var module = "./dist/index.esm.js";
136
+ var _package = {
137
+ name: name,
138
+ description: description,
139
+ version: version,
140
+ license: license,
141
+ keywords: keywords,
142
+ repository: repository,
143
+ exports: exports,
144
+ main: main,
145
+ types: types,
146
+ publishConfig: publishConfig,
147
+ backstage: backstage,
148
+ sideEffects: sideEffects,
149
+ scripts: scripts,
150
+ "lint-staged": {
151
+ "*.{js,ts,jsx,tsx}": "backstage-cli package lint",
152
+ "*.{json,md}": "prettier --write"
153
+ },
154
+ dependencies: dependencies,
155
+ peerDependencies: peerDependencies,
156
+ devDependencies: devDependencies,
157
+ files: files,
158
+ packageManager: packageManager,
159
+ typesVersions: typesVersions,
160
+ module: module
161
+ };
162
+
163
+ export { backstage, _package as default, dependencies, description, devDependencies, exports, files, keywords, license, main, module, name, packageManager, peerDependencies, publishConfig, repository, scripts, sideEffects, types, typesVersions, version };
164
+ //# sourceMappingURL=package.json.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tduniec/plugin-template-designer",
3
3
  "description": "Template Designer turns blank Backstage YAML into a storyboard-like canvas, guiding anyone through drag-and-drop scaffolder authoring before ever touching code. Rally non-experts, broadcast best practices, and accelerate template launches directly inside Backstage.",
4
- "version": "0.2.3",
4
+ "version": "0.3.0",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
7
7
  "backstage",
@@ -16,6 +16,20 @@
16
16
  "url": "git+https://github.com/tduniec/template-designer-plugin.git",
17
17
  "directory": "."
18
18
  },
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/index.esm.js",
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.esm.js"
24
+ },
25
+ "./alpha": {
26
+ "backstage": "@backstage/FrontendPlugin",
27
+ "import": "./dist/alpha.esm.js",
28
+ "types": "./dist/alpha.d.ts",
29
+ "default": "./dist/alpha.esm.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
19
33
  "main": "dist/index.esm.js",
20
34
  "types": "dist/index.d.ts",
21
35
  "publishConfig": {
@@ -28,7 +42,10 @@
28
42
  "pluginId": "template-designer",
29
43
  "pluginPackages": [
30
44
  "@tduniec/plugin-template-designer"
31
- ]
45
+ ],
46
+ "features": {
47
+ "./alpha": "@backstage/FrontendPlugin"
48
+ }
32
49
  },
33
50
  "sideEffects": false,
34
51
  "scripts": {
@@ -53,11 +70,14 @@
53
70
  "*.{json,md}": "prettier --write"
54
71
  },
55
72
  "dependencies": {
56
- "@backstage/core-components": "^0.18.2",
57
- "@backstage/core-plugin-api": "^1.11.1",
58
- "@backstage/plugin-scaffolder-common": "^1.7.2",
59
- "@backstage/plugin-scaffolder-react": "^1.19.2",
60
- "@backstage/theme": "^0.7.0",
73
+ "@backstage/core-compat-api": "backstage:^",
74
+ "@backstage/core-components": "backstage:^",
75
+ "@backstage/core-plugin-api": "backstage:^",
76
+ "@backstage/frontend-plugin-api": "backstage:^",
77
+ "@backstage/plugin-catalog-react": "backstage:^",
78
+ "@backstage/plugin-scaffolder-common": "backstage:^",
79
+ "@backstage/plugin-scaffolder-react": "backstage:^",
80
+ "@backstage/theme": "backstage:^",
61
81
  "@codemirror/lang-yaml": "^6.1.2",
62
82
  "@material-ui/core": "^4.12.4",
63
83
  "@material-ui/icons": "^4.11.3",
@@ -75,10 +95,13 @@
75
95
  "react-use": "^17.2.4"
76
96
  },
77
97
  "devDependencies": {
78
- "@backstage/cli": "^0.34.4",
79
- "@backstage/core-app-api": "^1.19.1",
80
- "@backstage/dev-utils": "^1.1.15",
81
- "@backstage/test-utils": "^1.7.12",
98
+ "@backstage/catalog-client": "backstage:^",
99
+ "@backstage/catalog-model": "backstage:^",
100
+ "@backstage/cli": "backstage:^",
101
+ "@backstage/core-app-api": "backstage:^",
102
+ "@backstage/dev-utils": "backstage:^",
103
+ "@backstage/plugin-catalog-common": "backstage:^",
104
+ "@backstage/test-utils": "backstage:^",
82
105
  "@codemirror/lang-yaml": "6.1.2",
83
106
  "@codemirror/state": "6.5.2",
84
107
  "@codemirror/view": "6.26.3",
@@ -115,6 +138,9 @@
115
138
  "packageManager": "yarn@4.10.3",
116
139
  "typesVersions": {
117
140
  "*": {
141
+ "alpha": [
142
+ "dist/alpha.d.ts"
143
+ ],
118
144
  "package.json": [
119
145
  "package.json"
120
146
  ]