@openchoreo/backstage-plugin-openchoreo-workflows 1.1.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.
- package/CHANGELOG.md +5 -0
- package/dist/api/GenericWorkflowsClient.esm.js +105 -0
- package/dist/api/GenericWorkflowsClient.esm.js.map +1 -0
- package/dist/api/GenericWorkflowsClientApi.esm.js +8 -0
- package/dist/api/GenericWorkflowsClientApi.esm.js.map +1 -0
- package/dist/components/EntityNamespaceProvider/EntityNamespaceProvider.esm.js +20 -0
- package/dist/components/EntityNamespaceProvider/EntityNamespaceProvider.esm.js.map +1 -0
- package/dist/components/GenericWorkflowsPage/GenericWorkflowsPage.esm.js +170 -0
- package/dist/components/GenericWorkflowsPage/GenericWorkflowsPage.esm.js.map +1 -0
- package/dist/components/GenericWorkflowsPage/index.esm.js +2 -0
- package/dist/components/GenericWorkflowsPage/index.esm.js.map +1 -0
- package/dist/components/TriggerWorkflowPage/TriggerWorkflowPage.esm.js +138 -0
- package/dist/components/TriggerWorkflowPage/TriggerWorkflowPage.esm.js.map +1 -0
- package/dist/components/WorkflowDetailsPage/WorkflowDetailsPage.esm.js +158 -0
- package/dist/components/WorkflowDetailsPage/WorkflowDetailsPage.esm.js.map +1 -0
- package/dist/components/WorkflowRunDetailsPage/WorkflowRunDetailsPage.esm.js +171 -0
- package/dist/components/WorkflowRunDetailsPage/WorkflowRunDetailsPage.esm.js.map +1 -0
- package/dist/components/WorkflowRunEvents/WorkflowRunEvents.esm.js +268 -0
- package/dist/components/WorkflowRunEvents/WorkflowRunEvents.esm.js.map +1 -0
- package/dist/components/WorkflowRunStatusChip/WorkflowRunStatusChip.esm.js +105 -0
- package/dist/components/WorkflowRunStatusChip/WorkflowRunStatusChip.esm.js.map +1 -0
- package/dist/components/WorkflowRunStepLogs/WorkflowRunStepLogs.esm.js +237 -0
- package/dist/components/WorkflowRunStepLogs/WorkflowRunStepLogs.esm.js.map +1 -0
- package/dist/components/WorkflowRunsContent/WorkflowRunsContent.esm.js +723 -0
- package/dist/components/WorkflowRunsContent/WorkflowRunsContent.esm.js.map +1 -0
- package/dist/components/WorkflowTriggerContent/WorkflowTriggerContent.esm.js +113 -0
- package/dist/components/WorkflowTriggerContent/WorkflowTriggerContent.esm.js.map +1 -0
- package/dist/context/NamespaceContext.esm.js +36 -0
- package/dist/context/NamespaceContext.esm.js.map +1 -0
- package/dist/hooks/useNamespaces.esm.js +38 -0
- package/dist/hooks/useNamespaces.esm.js.map +1 -0
- package/dist/hooks/useWorkflowRunDetails.esm.js +90 -0
- package/dist/hooks/useWorkflowRunDetails.esm.js.map +1 -0
- package/dist/hooks/useWorkflowRuns.esm.js +63 -0
- package/dist/hooks/useWorkflowRuns.esm.js.map +1 -0
- package/dist/hooks/useWorkflowSchema.esm.js +49 -0
- package/dist/hooks/useWorkflowSchema.esm.js.map +1 -0
- package/dist/hooks/useWorkflows.esm.js +40 -0
- package/dist/hooks/useWorkflows.esm.js.map +1 -0
- package/dist/index.d.ts +200 -0
- package/dist/index.esm.js +7 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +33 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +23 -0
- package/dist/routes.esm.js.map +1 -0
- package/package.json +77 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
class GenericWorkflowsClient {
|
|
2
|
+
constructor(discovery, fetchApi) {
|
|
3
|
+
this.discovery = discovery;
|
|
4
|
+
this.fetchApi = fetchApi;
|
|
5
|
+
}
|
|
6
|
+
async apiFetch(endpoint, options) {
|
|
7
|
+
const baseUrl = await this.discovery.getBaseUrl(
|
|
8
|
+
"openchoreo-workflows-backend"
|
|
9
|
+
);
|
|
10
|
+
const url = new URL(`${baseUrl}${endpoint}`);
|
|
11
|
+
if (options?.params) {
|
|
12
|
+
url.search = new URLSearchParams(options.params).toString();
|
|
13
|
+
}
|
|
14
|
+
const headers = {};
|
|
15
|
+
if (options?.body !== void 0) {
|
|
16
|
+
headers["Content-Type"] = "application/json";
|
|
17
|
+
}
|
|
18
|
+
const response = await this.fetchApi.fetch(url.toString(), {
|
|
19
|
+
method: options?.method || "GET",
|
|
20
|
+
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
21
|
+
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
const errorText = await response.text();
|
|
25
|
+
throw new Error(`API request failed (${response.status}): ${errorText}`);
|
|
26
|
+
}
|
|
27
|
+
return response.json();
|
|
28
|
+
}
|
|
29
|
+
async listNamespaces() {
|
|
30
|
+
return this.apiFetch("/namespaces");
|
|
31
|
+
}
|
|
32
|
+
async listWorkflows(namespaceName) {
|
|
33
|
+
return this.apiFetch("/workflows", {
|
|
34
|
+
params: { namespaceName }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async getWorkflowSchema(namespaceName, workflowName) {
|
|
38
|
+
return this.apiFetch(
|
|
39
|
+
`/workflows/${encodeURIComponent(workflowName)}/schema`,
|
|
40
|
+
{
|
|
41
|
+
params: { namespaceName }
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
async getClusterWorkflowSchema(clusterWorkflowName) {
|
|
46
|
+
return this.apiFetch(
|
|
47
|
+
`/cluster-workflows/${encodeURIComponent(clusterWorkflowName)}/schema`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
async listWorkflowRuns(namespaceName, workflowName) {
|
|
51
|
+
const params = { namespaceName };
|
|
52
|
+
if (workflowName) {
|
|
53
|
+
params.workflowName = workflowName;
|
|
54
|
+
}
|
|
55
|
+
return this.apiFetch("/workflow-runs", {
|
|
56
|
+
params
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async getWorkflowRun(namespaceName, runName) {
|
|
60
|
+
return this.apiFetch(
|
|
61
|
+
`/workflow-runs/${encodeURIComponent(runName)}`,
|
|
62
|
+
{
|
|
63
|
+
params: { namespaceName }
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
async createWorkflowRun(namespaceName, workflowName, parameters, workflowKind) {
|
|
68
|
+
return this.apiFetch("/workflow-runs", {
|
|
69
|
+
method: "POST",
|
|
70
|
+
params: { namespaceName },
|
|
71
|
+
body: { workflowName, parameters, workflowKind }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async getWorkflowRunLogs(namespaceName, runName, task) {
|
|
75
|
+
const params = { namespaceName };
|
|
76
|
+
if (task) {
|
|
77
|
+
params.task = task;
|
|
78
|
+
}
|
|
79
|
+
return this.apiFetch(
|
|
80
|
+
`/workflow-runs/${encodeURIComponent(runName)}/logs`,
|
|
81
|
+
{ params }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
async getWorkflowRunStatus(namespaceName, runName) {
|
|
85
|
+
return this.apiFetch(
|
|
86
|
+
`/workflow-runs/${encodeURIComponent(runName)}/status`,
|
|
87
|
+
{
|
|
88
|
+
params: { namespaceName }
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
async getWorkflowRunEvents(namespaceName, runName, task) {
|
|
93
|
+
const params = { namespaceName };
|
|
94
|
+
if (task) {
|
|
95
|
+
params.task = task;
|
|
96
|
+
}
|
|
97
|
+
return this.apiFetch(
|
|
98
|
+
`/workflow-runs/${encodeURIComponent(runName)}/events`,
|
|
99
|
+
{ params }
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export { GenericWorkflowsClient };
|
|
105
|
+
//# sourceMappingURL=GenericWorkflowsClient.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericWorkflowsClient.esm.js","sources":["../../src/api/GenericWorkflowsClient.ts"],"sourcesContent":["import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport type { GenericWorkflowsClientApi } from './GenericWorkflowsClientApi';\nimport type {\n Workflow,\n WorkflowRun,\n PaginatedResponse,\n LogsResponse,\n WorkflowRunStatusResponse,\n WorkflowRunEventEntry,\n} from '../types';\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport class GenericWorkflowsClient implements GenericWorkflowsClientApi {\n constructor(\n private readonly discovery: DiscoveryApi,\n private readonly fetchApi: FetchApi,\n ) {}\n\n private async apiFetch<T = unknown>(\n endpoint: string,\n options?: {\n method?: HttpMethod;\n body?: unknown;\n params?: Record<string, string>;\n },\n ): Promise<T> {\n const baseUrl = await this.discovery.getBaseUrl(\n 'openchoreo-workflows-backend',\n );\n const url = new URL(`${baseUrl}${endpoint}`);\n\n if (options?.params) {\n url.search = new URLSearchParams(options.params).toString();\n }\n\n const headers: HeadersInit = {};\n\n if (options?.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n const response = await this.fetchApi.fetch(url.toString(), {\n method: options?.method || 'GET',\n headers: Object.keys(headers).length > 0 ? headers : undefined,\n body:\n options?.body !== undefined ? JSON.stringify(options.body) : undefined,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API request failed (${response.status}): ${errorText}`);\n }\n\n return response.json();\n }\n\n async listNamespaces(): Promise<string[]> {\n return this.apiFetch<string[]>('/namespaces');\n }\n\n async listWorkflows(\n namespaceName: string,\n ): Promise<PaginatedResponse<Workflow>> {\n return this.apiFetch<PaginatedResponse<Workflow>>('/workflows', {\n params: { namespaceName },\n });\n }\n\n async getWorkflowSchema(\n namespaceName: string,\n workflowName: string,\n ): Promise<unknown> {\n return this.apiFetch<unknown>(\n `/workflows/${encodeURIComponent(workflowName)}/schema`,\n {\n params: { namespaceName },\n },\n );\n }\n\n async getClusterWorkflowSchema(\n clusterWorkflowName: string,\n ): Promise<unknown> {\n return this.apiFetch<unknown>(\n `/cluster-workflows/${encodeURIComponent(clusterWorkflowName)}/schema`,\n );\n }\n\n async listWorkflowRuns(\n namespaceName: string,\n workflowName?: string,\n ): Promise<PaginatedResponse<WorkflowRun>> {\n const params: Record<string, string> = { namespaceName };\n if (workflowName) {\n params.workflowName = workflowName;\n }\n return this.apiFetch<PaginatedResponse<WorkflowRun>>('/workflow-runs', {\n params,\n });\n }\n\n async getWorkflowRun(\n namespaceName: string,\n runName: string,\n ): Promise<WorkflowRun> {\n return this.apiFetch<WorkflowRun>(\n `/workflow-runs/${encodeURIComponent(runName)}`,\n {\n params: { namespaceName },\n },\n );\n }\n\n async createWorkflowRun(\n namespaceName: string,\n workflowName: string,\n parameters?: Record<string, unknown>,\n workflowKind?: 'Workflow' | 'ClusterWorkflow',\n ): Promise<WorkflowRun> {\n return this.apiFetch<WorkflowRun>('/workflow-runs', {\n method: 'POST',\n params: { namespaceName },\n body: { workflowName, parameters, workflowKind },\n });\n }\n\n async getWorkflowRunLogs(\n namespaceName: string,\n runName: string,\n task?: string,\n ): Promise<LogsResponse> {\n const params: Record<string, string> = { namespaceName };\n if (task) {\n params.task = task;\n }\n return this.apiFetch<LogsResponse>(\n `/workflow-runs/${encodeURIComponent(runName)}/logs`,\n { params },\n );\n }\n\n async getWorkflowRunStatus(\n namespaceName: string,\n runName: string,\n ): Promise<WorkflowRunStatusResponse> {\n return this.apiFetch<WorkflowRunStatusResponse>(\n `/workflow-runs/${encodeURIComponent(runName)}/status`,\n {\n params: { namespaceName },\n },\n );\n }\n\n async getWorkflowRunEvents(\n namespaceName: string,\n runName: string,\n task?: string,\n ): Promise<WorkflowRunEventEntry[]> {\n const params: Record<string, string> = { namespaceName };\n if (task) {\n params.task = task;\n }\n return this.apiFetch<WorkflowRunEventEntry[]>(\n `/workflow-runs/${encodeURIComponent(runName)}/events`,\n { params },\n );\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createApiRef } from '@backstage/core-plugin-api';
|
|
2
|
+
|
|
3
|
+
const genericWorkflowsClientApiRef = createApiRef({
|
|
4
|
+
id: "plugin.openchoreo-workflows.client"
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export { genericWorkflowsClientApiRef };
|
|
8
|
+
//# sourceMappingURL=GenericWorkflowsClientApi.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericWorkflowsClientApi.esm.js","sources":["../../src/api/GenericWorkflowsClientApi.ts"],"sourcesContent":["import { createApiRef } from '@backstage/core-plugin-api';\nimport type {\n Workflow,\n WorkflowRun,\n PaginatedResponse,\n LogsResponse,\n WorkflowRunStatusResponse,\n WorkflowRunEventEntry,\n} from '../types';\n\n/**\n * API client for generic workflow operations.\n *\n * This client provides methods for:\n * - Listing workflow templates\n * - Getting workflow schemas\n * - Listing and managing workflow runs\n *\n * After the Organization CRD removal, the hierarchy is now:\n * Namespace → Project → Component\n */\nexport interface GenericWorkflowsClientApi {\n /** List OpenChoreo namespaces (labeled openchoreo.dev/control-plane=true) */\n listNamespaces(): Promise<string[]>;\n\n /** List all workflow templates for a namespace */\n listWorkflows(namespaceName: string): Promise<PaginatedResponse<Workflow>>;\n\n /** Get the JSONSchema for a namespace-scoped workflow's parameters */\n getWorkflowSchema(\n namespaceName: string,\n workflowName: string,\n ): Promise<unknown>;\n\n /** Get the JSONSchema for a cluster-scoped workflow's parameters */\n getClusterWorkflowSchema(clusterWorkflowName: string): Promise<unknown>;\n\n /** List workflow runs for a namespace, optionally filtered by workflow name */\n listWorkflowRuns(\n namespaceName: string,\n workflowName?: string,\n ): Promise<PaginatedResponse<WorkflowRun>>;\n\n /** Get details of a specific workflow run */\n getWorkflowRun(namespaceName: string, runName: string): Promise<WorkflowRun>;\n\n /** Create (trigger) a new workflow run */\n createWorkflowRun(\n namespaceName: string,\n workflowName: string,\n parameters?: Record<string, unknown>,\n workflowKind?: 'Workflow' | 'ClusterWorkflow',\n ): Promise<WorkflowRun>;\n\n /** Get logs for a specific workflow run, optionally filtered by task */\n getWorkflowRunLogs(\n namespaceName: string,\n runName: string,\n task?: string,\n ): Promise<LogsResponse>;\n\n /** Get status (including steps) for a specific workflow run */\n getWorkflowRunStatus(\n namespaceName: string,\n runName: string,\n ): Promise<WorkflowRunStatusResponse>;\n\n /** Get Kubernetes events for a specific workflow run, optionally filtered by task */\n getWorkflowRunEvents(\n namespaceName: string,\n runName: string,\n task?: string,\n ): Promise<WorkflowRunEventEntry[]>;\n}\n\n/**\n * ApiRef for the generic workflows client.\n *\n * Usage:\n * ```typescript\n * import { genericWorkflowsClientApiRef } from '@openchoreo/backstage-plugin-openchoreo-workflows';\n *\n * const client = useApi(genericWorkflowsClientApiRef);\n * ```\n */\nexport const genericWorkflowsClientApiRef =\n createApiRef<GenericWorkflowsClientApi>({\n id: 'plugin.openchoreo-workflows.client',\n });\n"],"names":[],"mappings":";;AAqFO,MAAM,+BACX,YAAA,CAAwC;AAAA,EACtC,EAAA,EAAI;AACN,CAAC;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
3
|
+
import { NamespaceProvider } from '../../context/NamespaceContext.esm.js';
|
|
4
|
+
|
|
5
|
+
const NAMESPACE_ANNOTATION = "openchoreo.io/namespace";
|
|
6
|
+
const CLUSTER_SCOPED_KINDS = /* @__PURE__ */ new Set([
|
|
7
|
+
"clusterworkflow",
|
|
8
|
+
"clusterworkflowplane"
|
|
9
|
+
]);
|
|
10
|
+
const EntityNamespaceProvider = ({
|
|
11
|
+
children
|
|
12
|
+
}) => {
|
|
13
|
+
const { entity } = useEntity();
|
|
14
|
+
const annotationNamespace = entity.metadata.annotations?.[NAMESPACE_ANNOTATION];
|
|
15
|
+
const namespace = annotationNamespace || (CLUSTER_SCOPED_KINDS.has(entity.kind?.toLowerCase() ?? "") ? "default" : entity.metadata.namespace) || "";
|
|
16
|
+
return /* @__PURE__ */ jsx(NamespaceProvider, { initialNamespace: namespace, children });
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { EntityNamespaceProvider };
|
|
20
|
+
//# sourceMappingURL=EntityNamespaceProvider.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityNamespaceProvider.esm.js","sources":["../../../src/components/EntityNamespaceProvider/EntityNamespaceProvider.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { NamespaceProvider } from '../../context';\n\nconst NAMESPACE_ANNOTATION = 'openchoreo.io/namespace';\n\ninterface EntityNamespaceProviderProps {\n children: ReactNode;\n}\n\n/**\n * Wraps children in a NamespaceProvider initialized from the entity's\n * `openchoreo.io/namespace` annotation. This allows all workflow hooks\n * (which read from NamespaceContext) to work within catalog entity pages.\n *\n * For cluster-scoped entity kinds (e.g. ClusterWorkflow), `entity.metadata.namespace`\n * is the Backstage catalog namespace (e.g. \"openchoreo-cluster\"), NOT the Kubernetes\n * workload namespace where WorkflowRun CRs are created. For those entities we fall\n * back to \"default\" unless the `openchoreo.io/namespace` annotation explicitly\n * specifies the target namespace.\n */\n\n/** Entity kinds that are cluster-scoped; their Backstage namespace is not a K8s namespace. */\nconst CLUSTER_SCOPED_KINDS = new Set([\n 'clusterworkflow',\n 'clusterworkflowplane',\n]);\n\nexport const EntityNamespaceProvider = ({\n children,\n}: EntityNamespaceProviderProps) => {\n const { entity } = useEntity();\n\n const annotationNamespace =\n entity.metadata.annotations?.[NAMESPACE_ANNOTATION];\n\n // Priority:\n // 1. Explicit openchoreo.io/namespace annotation (always wins)\n // 2. For namespace-scoped kinds: entity.metadata.namespace\n // 3. For cluster-scoped kinds: \"default\" (K8s default namespace for WorkflowRuns)\n // 4. Empty string fallback\n const namespace =\n annotationNamespace ||\n (CLUSTER_SCOPED_KINDS.has(entity.kind?.toLowerCase() ?? '')\n ? 'default'\n : entity.metadata.namespace) ||\n '';\n\n return (\n <NamespaceProvider initialNamespace={namespace}>\n {children}\n </NamespaceProvider>\n );\n};\n"],"names":[],"mappings":";;;;AAIA,MAAM,oBAAA,GAAuB,yBAAA;AAmB7B,MAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EACnC,iBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEM,MAAM,0BAA0B,CAAC;AAAA,EACtC;AACF,CAAA,KAAoC;AAClC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAE7B,EAAA,MAAM,mBAAA,GACJ,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,oBAAoB,CAAA;AAOpD,EAAA,MAAM,SAAA,GACJ,mBAAA,KACC,oBAAA,CAAqB,GAAA,CAAI,MAAA,CAAO,IAAA,EAAM,WAAA,EAAY,IAAK,EAAE,CAAA,GACtD,SAAA,GACA,MAAA,CAAO,SAAS,SAAA,CAAA,IACpB,EAAA;AAEF,EAAA,uBACE,GAAA,CAAC,iBAAA,EAAA,EAAkB,gBAAA,EAAkB,SAAA,EAClC,QAAA,EACH,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { Routes, Route, useNavigate } from 'react-router-dom';
|
|
4
|
+
import { Page, Header, Content, WarningPanel, Progress, Table } from '@backstage/core-components';
|
|
5
|
+
import { FormControl, InputLabel, Select, MenuItem, CircularProgress, Typography, Box, IconButton } from '@material-ui/core';
|
|
6
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
7
|
+
import RefreshIcon from '@material-ui/icons/Refresh';
|
|
8
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
9
|
+
import { openChoreoClientApiRef } from '@openchoreo/backstage-plugin';
|
|
10
|
+
import { useAsync } from 'react-use';
|
|
11
|
+
import { useWorkflows } from '../../hooks/useWorkflows.esm.js';
|
|
12
|
+
import { NamespaceProvider, useNamespaceContext } from '../../context/NamespaceContext.esm.js';
|
|
13
|
+
import { TriggerWorkflowPage } from '../TriggerWorkflowPage/TriggerWorkflowPage.esm.js';
|
|
14
|
+
import { WorkflowRunDetailsPage } from '../WorkflowRunDetailsPage/WorkflowRunDetailsPage.esm.js';
|
|
15
|
+
import { WorkflowDetailsPage } from '../WorkflowDetailsPage/WorkflowDetailsPage.esm.js';
|
|
16
|
+
|
|
17
|
+
const useStyles = makeStyles((theme) => ({
|
|
18
|
+
namespaceSelector: {
|
|
19
|
+
minWidth: 300,
|
|
20
|
+
marginBottom: theme.spacing(3)
|
|
21
|
+
},
|
|
22
|
+
refreshButton: {
|
|
23
|
+
marginLeft: theme.spacing(1)
|
|
24
|
+
},
|
|
25
|
+
headerRow: {
|
|
26
|
+
display: "flex",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
marginBottom: theme.spacing(2)
|
|
29
|
+
},
|
|
30
|
+
emptyState: {
|
|
31
|
+
padding: theme.spacing(4),
|
|
32
|
+
textAlign: "center",
|
|
33
|
+
color: theme.palette.text.secondary
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
const WorkflowsTable = ({ workflows }) => {
|
|
37
|
+
const navigate = useNavigate();
|
|
38
|
+
const columns = [
|
|
39
|
+
{
|
|
40
|
+
title: "Name",
|
|
41
|
+
field: "name",
|
|
42
|
+
highlight: true,
|
|
43
|
+
sorting: false,
|
|
44
|
+
render: (workflow) => /* @__PURE__ */ jsx(Typography, { variant: "body2", children: workflow.displayName || workflow.name })
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: "Type",
|
|
48
|
+
field: "type",
|
|
49
|
+
width: "15%",
|
|
50
|
+
render: (workflow) => /* @__PURE__ */ jsx(Typography, { variant: "body2", children: workflow.type || "-" })
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
title: "Description",
|
|
54
|
+
field: "description",
|
|
55
|
+
render: (workflow) => /* @__PURE__ */ jsx(Typography, { variant: "body2", noWrap: true, title: workflow.description || "", children: workflow.description || "-" })
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
return /* @__PURE__ */ jsx(
|
|
59
|
+
Table,
|
|
60
|
+
{
|
|
61
|
+
columns,
|
|
62
|
+
data: workflows,
|
|
63
|
+
options: {
|
|
64
|
+
paging: true,
|
|
65
|
+
pageSize: 10,
|
|
66
|
+
pageSizeOptions: [10, 20, 50],
|
|
67
|
+
search: true,
|
|
68
|
+
padding: "dense",
|
|
69
|
+
draggable: false
|
|
70
|
+
},
|
|
71
|
+
onRowClick: (_e, workflow) => {
|
|
72
|
+
if (workflow) navigate(encodeURIComponent(workflow.name));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
const WorkflowsListContent = () => {
|
|
78
|
+
const classes = useStyles();
|
|
79
|
+
const client = useApi(openChoreoClientApiRef);
|
|
80
|
+
const { selectedNamespace, setSelectedNamespace } = useNamespaceContext();
|
|
81
|
+
const {
|
|
82
|
+
value: namespaces,
|
|
83
|
+
loading: namespacesLoading,
|
|
84
|
+
error: namespacesError
|
|
85
|
+
} = useAsync(async () => {
|
|
86
|
+
return client.listNamespaces();
|
|
87
|
+
}, [client]);
|
|
88
|
+
const {
|
|
89
|
+
workflows,
|
|
90
|
+
loading: workflowsLoading,
|
|
91
|
+
error: workflowsError,
|
|
92
|
+
refetch
|
|
93
|
+
} = useWorkflows();
|
|
94
|
+
const handleNamespaceChange = (event) => {
|
|
95
|
+
setSelectedNamespace(event.target.value);
|
|
96
|
+
};
|
|
97
|
+
const sortedNamespaces = useMemo(() => {
|
|
98
|
+
if (!namespaces) return [];
|
|
99
|
+
return [...namespaces].sort((a, b) => a.name.localeCompare(b.name));
|
|
100
|
+
}, [namespaces]);
|
|
101
|
+
return /* @__PURE__ */ jsxs(Content, { children: [
|
|
102
|
+
/* @__PURE__ */ jsxs(FormControl, { variant: "outlined", className: classes.namespaceSelector, children: [
|
|
103
|
+
/* @__PURE__ */ jsx(InputLabel, { id: "namespace-select-label", children: "Namespace" }),
|
|
104
|
+
/* @__PURE__ */ jsxs(
|
|
105
|
+
Select,
|
|
106
|
+
{
|
|
107
|
+
labelId: "namespace-select-label",
|
|
108
|
+
label: "Namespace",
|
|
109
|
+
value: selectedNamespace,
|
|
110
|
+
onChange: handleNamespaceChange,
|
|
111
|
+
disabled: namespacesLoading,
|
|
112
|
+
children: [
|
|
113
|
+
namespacesLoading && /* @__PURE__ */ jsxs(MenuItem, { disabled: true, children: [
|
|
114
|
+
/* @__PURE__ */ jsx(CircularProgress, { size: 20, style: { marginRight: 8 } }),
|
|
115
|
+
"Loading namespaces..."
|
|
116
|
+
] }),
|
|
117
|
+
!namespacesLoading && sortedNamespaces.length === 0 && /* @__PURE__ */ jsx(MenuItem, { disabled: true, children: "No namespaces available" }),
|
|
118
|
+
!namespacesLoading && sortedNamespaces.map((ns) => /* @__PURE__ */ jsx(MenuItem, { value: ns.name, children: ns.displayName || ns.name }, ns.name))
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
] }),
|
|
123
|
+
namespacesError && /* @__PURE__ */ jsx(WarningPanel, { severity: "error", title: "Failed to load namespaces", children: /* @__PURE__ */ jsx(Typography, { children: namespacesError.message || "An error occurred while loading namespaces." }) }),
|
|
124
|
+
workflowsError && /* @__PURE__ */ jsx(WarningPanel, { severity: "error", title: "Failed to load workflows", children: /* @__PURE__ */ jsx(Typography, { children: workflowsError.message || "An error occurred while loading workflows." }) }),
|
|
125
|
+
!selectedNamespace && /* @__PURE__ */ jsx(Box, { className: classes.emptyState, children: /* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Select a namespace to view workflow templates" }) }),
|
|
126
|
+
selectedNamespace && workflowsLoading && /* @__PURE__ */ jsx(Progress, {}),
|
|
127
|
+
selectedNamespace && !workflowsLoading && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
128
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.headerRow, children: [
|
|
129
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", children: "Workflow Templates" }),
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
IconButton,
|
|
132
|
+
{
|
|
133
|
+
className: classes.refreshButton,
|
|
134
|
+
onClick: () => refetch(),
|
|
135
|
+
size: "small",
|
|
136
|
+
title: "Refresh",
|
|
137
|
+
children: /* @__PURE__ */ jsx(RefreshIcon, {})
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
] }),
|
|
141
|
+
/* @__PURE__ */ jsx(WorkflowsTable, { workflows })
|
|
142
|
+
] })
|
|
143
|
+
] });
|
|
144
|
+
};
|
|
145
|
+
const GenericWorkflowsPage = () => {
|
|
146
|
+
return /* @__PURE__ */ jsx(NamespaceProvider, { children: /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
Header,
|
|
149
|
+
{
|
|
150
|
+
title: "Generic Workflows",
|
|
151
|
+
subtitle: "Manage namespace-level workflow templates"
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
/* @__PURE__ */ jsxs(Routes, { children: [
|
|
155
|
+
/* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(WorkflowsListContent, {}) }),
|
|
156
|
+
/* @__PURE__ */ jsx(Route, { path: "/:workflowName", element: /* @__PURE__ */ jsx(WorkflowDetailsPage, {}) }),
|
|
157
|
+
/* @__PURE__ */ jsx(
|
|
158
|
+
Route,
|
|
159
|
+
{
|
|
160
|
+
path: "/:workflowName/trigger",
|
|
161
|
+
element: /* @__PURE__ */ jsx(TriggerWorkflowPage, {})
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
/* @__PURE__ */ jsx(Route, { path: "/runs/:runName", element: /* @__PURE__ */ jsx(WorkflowRunDetailsPage, {}) })
|
|
165
|
+
] })
|
|
166
|
+
] }) });
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export { GenericWorkflowsPage };
|
|
170
|
+
//# sourceMappingURL=GenericWorkflowsPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenericWorkflowsPage.esm.js","sources":["../../../src/components/GenericWorkflowsPage/GenericWorkflowsPage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { Routes, Route, useNavigate } from 'react-router-dom';\nimport {\n Content,\n Header,\n Page,\n Progress,\n Table,\n TableColumn,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n Box,\n CircularProgress,\n FormControl,\n IconButton,\n InputLabel,\n MenuItem,\n Select,\n Typography,\n} from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { openChoreoClientApiRef } from '@openchoreo/backstage-plugin';\nimport { useAsync } from 'react-use';\nimport { useWorkflows } from '../../hooks/useWorkflows';\nimport { NamespaceProvider, useNamespaceContext } from '../../context';\nimport { TriggerWorkflowPage } from '../TriggerWorkflowPage';\nimport { WorkflowRunDetailsPage } from '../WorkflowRunDetailsPage';\nimport { WorkflowDetailsPage } from '../WorkflowDetailsPage';\nimport type { Workflow } from '../../types';\n\nconst useStyles = makeStyles(theme => ({\n namespaceSelector: {\n minWidth: 300,\n marginBottom: theme.spacing(3),\n },\n refreshButton: {\n marginLeft: theme.spacing(1),\n },\n headerRow: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: theme.spacing(2),\n },\n emptyState: {\n padding: theme.spacing(4),\n textAlign: 'center',\n color: theme.palette.text.secondary,\n },\n}));\n\n// Workflows Table\nconst WorkflowsTable = ({ workflows }: { workflows: Workflow[] }) => {\n const navigate = useNavigate();\n\n const columns: TableColumn<Workflow>[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n sorting: false,\n render: (workflow: Workflow) => (\n <Typography variant=\"body2\">\n {workflow.displayName || workflow.name}\n </Typography>\n ),\n },\n {\n title: 'Type',\n field: 'type',\n width: '15%',\n render: (workflow: Workflow) => (\n <Typography variant=\"body2\">{workflow.type || '-'}</Typography>\n ),\n },\n {\n title: 'Description',\n field: 'description',\n render: (workflow: Workflow) => (\n <Typography variant=\"body2\" noWrap title={workflow.description || ''}>\n {workflow.description || '-'}\n </Typography>\n ),\n },\n ];\n\n return (\n <Table\n columns={columns}\n data={workflows}\n options={{\n paging: true,\n pageSize: 10,\n pageSizeOptions: [10, 20, 50],\n search: true,\n padding: 'dense',\n draggable: false,\n }}\n onRowClick={(_e, workflow) => {\n if (workflow) navigate(encodeURIComponent(workflow.name));\n }}\n />\n );\n};\n\n// Workflows List Content\nconst WorkflowsListContent = () => {\n const classes = useStyles();\n const client = useApi(openChoreoClientApiRef);\n const { selectedNamespace, setSelectedNamespace } = useNamespaceContext();\n\n // Fetch available namespaces\n const {\n value: namespaces,\n loading: namespacesLoading,\n error: namespacesError,\n } = useAsync(async () => {\n return client.listNamespaces();\n }, [client]);\n\n // Fetch workflows for the selected namespace (reads from context)\n const {\n workflows,\n loading: workflowsLoading,\n error: workflowsError,\n refetch,\n } = useWorkflows();\n\n const handleNamespaceChange = (\n event: React.ChangeEvent<{ value: unknown }>,\n ) => {\n setSelectedNamespace(event.target.value as string);\n };\n\n // Sort namespaces alphabetically\n const sortedNamespaces = useMemo(() => {\n if (!namespaces) return [];\n return [...namespaces].sort((a, b) => a.name.localeCompare(b.name));\n }, [namespaces]);\n\n return (\n <Content>\n {/* Namespace Selector */}\n <FormControl variant=\"outlined\" className={classes.namespaceSelector}>\n <InputLabel id=\"namespace-select-label\">Namespace</InputLabel>\n <Select\n labelId=\"namespace-select-label\"\n label=\"Namespace\"\n value={selectedNamespace}\n onChange={handleNamespaceChange}\n disabled={namespacesLoading}\n >\n {namespacesLoading && (\n <MenuItem disabled>\n <CircularProgress size={20} style={{ marginRight: 8 }} />\n Loading namespaces...\n </MenuItem>\n )}\n {!namespacesLoading && sortedNamespaces.length === 0 && (\n <MenuItem disabled>No namespaces available</MenuItem>\n )}\n {!namespacesLoading &&\n sortedNamespaces.map(ns => (\n <MenuItem key={ns.name} value={ns.name}>\n {ns.displayName || ns.name}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n {/* Error Display */}\n {namespacesError && (\n <WarningPanel severity=\"error\" title=\"Failed to load namespaces\">\n <Typography>\n {namespacesError.message ||\n 'An error occurred while loading namespaces.'}\n </Typography>\n </WarningPanel>\n )}\n\n {workflowsError && (\n <WarningPanel severity=\"error\" title=\"Failed to load workflows\">\n <Typography>\n {workflowsError.message ||\n 'An error occurred while loading workflows.'}\n </Typography>\n </WarningPanel>\n )}\n\n {/* Content */}\n {!selectedNamespace && (\n <Box className={classes.emptyState}>\n <Typography variant=\"h6\">\n Select a namespace to view workflow templates\n </Typography>\n </Box>\n )}\n\n {selectedNamespace && workflowsLoading && <Progress />}\n\n {selectedNamespace && !workflowsLoading && (\n <>\n <Box className={classes.headerRow}>\n <Typography variant=\"h6\">Workflow Templates</Typography>\n <IconButton\n className={classes.refreshButton}\n onClick={() => refetch()}\n size=\"small\"\n title=\"Refresh\"\n >\n <RefreshIcon />\n </IconButton>\n </Box>\n <WorkflowsTable workflows={workflows} />\n </>\n )}\n </Content>\n );\n};\n\nexport const GenericWorkflowsPage = () => {\n return (\n <NamespaceProvider>\n <Page themeId=\"tool\">\n <Header\n title=\"Generic Workflows\"\n subtitle=\"Manage namespace-level workflow templates\"\n />\n <Routes>\n <Route path=\"/\" element={<WorkflowsListContent />} />\n <Route path=\"/:workflowName\" element={<WorkflowDetailsPage />} />\n <Route\n path=\"/:workflowName/trigger\"\n element={<TriggerWorkflowPage />}\n />\n <Route path=\"/runs/:runName\" element={<WorkflowRunDetailsPage />} />\n </Routes>\n </Page>\n </NamespaceProvider>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useNavigate, useParams } from 'react-router-dom';
|
|
4
|
+
import { Content, Progress, InfoCard } from '@backstage/core-components';
|
|
5
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
6
|
+
import { Alert, AlertTitle } from '@material-ui/lab';
|
|
7
|
+
import { Box, IconButton, Typography, Button } from '@material-ui/core';
|
|
8
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
9
|
+
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
|
|
10
|
+
import { RjsfForm } from '@openchoreo/backstage-design-system';
|
|
11
|
+
import { useWorkflowSchema } from '../../hooks/useWorkflowSchema.esm.js';
|
|
12
|
+
import { useSelectedNamespace } from '../../context/NamespaceContext.esm.js';
|
|
13
|
+
import { genericWorkflowsClientApiRef } from '../../api/GenericWorkflowsClientApi.esm.js';
|
|
14
|
+
|
|
15
|
+
const useStyles = makeStyles((theme) => ({
|
|
16
|
+
backButton: {
|
|
17
|
+
marginBottom: theme.spacing(2),
|
|
18
|
+
display: "flex",
|
|
19
|
+
alignItems: "center",
|
|
20
|
+
gap: theme.spacing(1)
|
|
21
|
+
},
|
|
22
|
+
header: {
|
|
23
|
+
marginBottom: theme.spacing(3)
|
|
24
|
+
},
|
|
25
|
+
formContainer: {
|
|
26
|
+
marginTop: theme.spacing(2)
|
|
27
|
+
},
|
|
28
|
+
submitButton: {
|
|
29
|
+
marginTop: theme.spacing(3)
|
|
30
|
+
},
|
|
31
|
+
noSchemaMessage: {
|
|
32
|
+
padding: theme.spacing(3),
|
|
33
|
+
textAlign: "center",
|
|
34
|
+
color: theme.palette.text.secondary
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
const TriggerWorkflowPage = () => {
|
|
38
|
+
const classes = useStyles();
|
|
39
|
+
const navigate = useNavigate();
|
|
40
|
+
const { workflowName } = useParams();
|
|
41
|
+
const decodedWorkflowName = workflowName ? decodeURIComponent(workflowName) : "";
|
|
42
|
+
const namespaceName = useSelectedNamespace();
|
|
43
|
+
const client = useApi(genericWorkflowsClientApiRef);
|
|
44
|
+
const { schema, loading, error } = useWorkflowSchema(decodedWorkflowName);
|
|
45
|
+
const [formData, setFormData] = useState({});
|
|
46
|
+
const [submitting, setSubmitting] = useState(false);
|
|
47
|
+
const [submitError, setSubmitError] = useState(null);
|
|
48
|
+
const handleSubmit = async () => {
|
|
49
|
+
try {
|
|
50
|
+
setSubmitting(true);
|
|
51
|
+
setSubmitError(null);
|
|
52
|
+
const run = await client.createWorkflowRun(
|
|
53
|
+
namespaceName,
|
|
54
|
+
decodedWorkflowName,
|
|
55
|
+
formData
|
|
56
|
+
);
|
|
57
|
+
navigate(`../runs/${encodeURIComponent(run.name)}`);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
setSubmitError(err instanceof Error ? err : new Error(String(err)));
|
|
60
|
+
} finally {
|
|
61
|
+
setSubmitting(false);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const handleBack = () => {
|
|
65
|
+
navigate("..");
|
|
66
|
+
};
|
|
67
|
+
if (loading) {
|
|
68
|
+
return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(Progress, {}) });
|
|
69
|
+
}
|
|
70
|
+
if (error) {
|
|
71
|
+
return /* @__PURE__ */ jsxs(Content, { children: [
|
|
72
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.backButton, children: [
|
|
73
|
+
/* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleBack, children: /* @__PURE__ */ jsx(ArrowBackIcon, {}) }),
|
|
74
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Back to Workflows" })
|
|
75
|
+
] }),
|
|
76
|
+
/* @__PURE__ */ jsxs(Alert, { severity: "error", children: [
|
|
77
|
+
/* @__PURE__ */ jsx(AlertTitle, { children: "Error loading workflow schema" }),
|
|
78
|
+
error.message
|
|
79
|
+
] })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
const hasSchema = schema && typeof schema === "object" && "properties" in schema && Object.keys(schema.properties || {}).length > 0;
|
|
83
|
+
const uiSchema = {
|
|
84
|
+
"ui:submitButtonOptions": {
|
|
85
|
+
norender: true
|
|
86
|
+
// We'll render our own submit button
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsxs(Content, { children: [
|
|
90
|
+
/* @__PURE__ */ jsxs(Box, { className: classes.backButton, children: [
|
|
91
|
+
/* @__PURE__ */ jsx(IconButton, { size: "small", onClick: handleBack, children: /* @__PURE__ */ jsx(ArrowBackIcon, {}) }),
|
|
92
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: "Back to Workflows" })
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsxs(InfoCard, { title: `Trigger: ${decodedWorkflowName}`, children: [
|
|
95
|
+
submitError && /* @__PURE__ */ jsxs(Alert, { severity: "error", style: { marginBottom: 16 }, children: [
|
|
96
|
+
/* @__PURE__ */ jsx(AlertTitle, { children: "Error triggering workflow" }),
|
|
97
|
+
submitError.message
|
|
98
|
+
] }),
|
|
99
|
+
hasSchema ? /* @__PURE__ */ jsx(Box, { className: classes.formContainer, children: /* @__PURE__ */ jsx(
|
|
100
|
+
RjsfForm,
|
|
101
|
+
{
|
|
102
|
+
schema,
|
|
103
|
+
uiSchema,
|
|
104
|
+
formData,
|
|
105
|
+
onChange: (e) => setFormData(e.formData || {}),
|
|
106
|
+
onSubmit: handleSubmit,
|
|
107
|
+
children: /* @__PURE__ */ jsx(
|
|
108
|
+
Button,
|
|
109
|
+
{
|
|
110
|
+
variant: "contained",
|
|
111
|
+
color: "primary",
|
|
112
|
+
onClick: handleSubmit,
|
|
113
|
+
disabled: submitting,
|
|
114
|
+
className: classes.submitButton,
|
|
115
|
+
children: submitting ? "Triggering..." : "Trigger Workflow"
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
) }) : /* @__PURE__ */ jsxs(Box, { children: [
|
|
120
|
+
/* @__PURE__ */ jsx(Typography, { className: classes.noSchemaMessage, children: "This workflow has no configurable parameters." }),
|
|
121
|
+
/* @__PURE__ */ jsx(
|
|
122
|
+
Button,
|
|
123
|
+
{
|
|
124
|
+
variant: "contained",
|
|
125
|
+
color: "primary",
|
|
126
|
+
onClick: handleSubmit,
|
|
127
|
+
disabled: submitting,
|
|
128
|
+
className: classes.submitButton,
|
|
129
|
+
children: submitting ? "Triggering..." : "Trigger Workflow"
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
] })
|
|
133
|
+
] })
|
|
134
|
+
] });
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export { TriggerWorkflowPage };
|
|
138
|
+
//# sourceMappingURL=TriggerWorkflowPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TriggerWorkflowPage.esm.js","sources":["../../../src/components/TriggerWorkflowPage/TriggerWorkflowPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { Content, Progress, InfoCard } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Alert, AlertTitle } from '@material-ui/lab';\nimport { Box, Button, IconButton, Typography } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ArrowBackIcon from '@material-ui/icons/ArrowBack';\nimport { RjsfForm } from '@openchoreo/backstage-design-system';\nimport type { RJSFSchema, UiSchema } from '@rjsf/utils';\nimport { useWorkflowSchema } from '../../hooks/useWorkflowSchema';\nimport { useSelectedNamespace } from '../../context';\nimport { genericWorkflowsClientApiRef } from '../../api';\n\nconst useStyles = makeStyles(theme => ({\n backButton: {\n marginBottom: theme.spacing(2),\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n },\n header: {\n marginBottom: theme.spacing(3),\n },\n formContainer: {\n marginTop: theme.spacing(2),\n },\n submitButton: {\n marginTop: theme.spacing(3),\n },\n noSchemaMessage: {\n padding: theme.spacing(3),\n textAlign: 'center',\n color: theme.palette.text.secondary,\n },\n}));\n\nexport const TriggerWorkflowPage = () => {\n const classes = useStyles();\n const navigate = useNavigate();\n const { workflowName } = useParams<{ workflowName: string }>();\n const decodedWorkflowName = workflowName\n ? decodeURIComponent(workflowName)\n : '';\n\n const namespaceName = useSelectedNamespace();\n const client = useApi(genericWorkflowsClientApiRef);\n const { schema, loading, error } = useWorkflowSchema(decodedWorkflowName);\n\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n const [submitting, setSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<Error | null>(null);\n\n const handleSubmit = async () => {\n try {\n setSubmitting(true);\n setSubmitError(null);\n\n const run = await client.createWorkflowRun(\n namespaceName,\n decodedWorkflowName,\n formData,\n );\n\n // Navigate to the run details page\n navigate(`../runs/${encodeURIComponent(run.name)}`);\n } catch (err) {\n setSubmitError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleBack = () => {\n navigate('..');\n };\n\n if (loading) {\n return (\n <Content>\n <Progress />\n </Content>\n );\n }\n\n if (error) {\n return (\n <Content>\n <Box className={classes.backButton}>\n <IconButton size=\"small\" onClick={handleBack}>\n <ArrowBackIcon />\n </IconButton>\n <Typography variant=\"body2\">Back to Workflows</Typography>\n </Box>\n <Alert severity=\"error\">\n <AlertTitle>Error loading workflow schema</AlertTitle>\n {error.message}\n </Alert>\n </Content>\n );\n }\n\n // Check if schema has properties\n const hasSchema =\n schema &&\n typeof schema === 'object' &&\n 'properties' in schema &&\n Object.keys((schema as any).properties || {}).length > 0;\n\n const uiSchema: UiSchema = {\n 'ui:submitButtonOptions': {\n norender: true, // We'll render our own submit button\n },\n };\n\n return (\n <Content>\n <Box className={classes.backButton}>\n <IconButton size=\"small\" onClick={handleBack}>\n <ArrowBackIcon />\n </IconButton>\n <Typography variant=\"body2\">Back to Workflows</Typography>\n </Box>\n\n <InfoCard title={`Trigger: ${decodedWorkflowName}`}>\n {submitError && (\n <Alert severity=\"error\" style={{ marginBottom: 16 }}>\n <AlertTitle>Error triggering workflow</AlertTitle>\n {submitError.message}\n </Alert>\n )}\n\n {hasSchema ? (\n <Box className={classes.formContainer}>\n <RjsfForm\n schema={schema as RJSFSchema}\n uiSchema={uiSchema}\n formData={formData}\n onChange={e => setFormData(e.formData || {})}\n onSubmit={handleSubmit}\n >\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleSubmit}\n disabled={submitting}\n className={classes.submitButton}\n >\n {submitting ? 'Triggering...' : 'Trigger Workflow'}\n </Button>\n </RjsfForm>\n </Box>\n ) : (\n <Box>\n <Typography className={classes.noSchemaMessage}>\n This workflow has no configurable parameters.\n </Typography>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleSubmit}\n disabled={submitting}\n className={classes.submitButton}\n >\n {submitting ? 'Triggering...' : 'Trigger Workflow'}\n </Button>\n </Box>\n )}\n </InfoCard>\n </Content>\n );\n};\n"],"names":[],"mappings":"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"}
|