Skip to content

Commit 33b479f

Browse files
ssilvertpedroigor
authored andcommitted
Workflows now use YAML instead of JSON.
Closes #43665 Signed-off-by: Stan Silvert <[email protected]>
1 parent b2317da commit 33b479f

File tree

6 files changed

+52
-37
lines changed

6 files changed

+52
-37
lines changed

js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3593,8 +3593,8 @@ workflows=Workflows
35933593
titleWorkflows=Workflows
35943594
workflowsExplain=Workflows empower administrators to automate the management of realm resources through time-based or event-based policies.
35953595
createWorkflow=Create workflow
3596-
workflowJSON=Workflow JSON
3597-
workflowJsonHelp=The JSON representation of the workflow.
3596+
workflowYAML=Workflow YAML
3597+
workflowYAMLHelp=The YAML representation of the workflow.
35983598
emptyWorkflows=No workflows
35993599
emptyWorkflowsInstructions=There are no workflows in this realm. Please create a workflow to get started.
36003600
workflowCreated=The workflow has been created.

js/apps/admin-ui/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@
109109
"react-i18next": "^16.0.1",
110110
"react-router-dom": "^6.30.1",
111111
"reactflow": "^11.11.4",
112-
"use-react-router-breadcrumbs": "^4.0.1"
112+
"use-react-router-breadcrumbs": "^4.0.1",
113+
"yaml": "^2.8.1"
113114
},
114115
"devDependencies": {
115116
"@axe-core/playwright": "^4.10.2",

js/apps/admin-ui/src/workflows/WorkflowDetailForm.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from "react-hook-form";
1414
import { useTranslation } from "react-i18next";
1515
import { Link, useNavigate } from "react-router-dom";
16+
import yaml from "yaml";
1617
import { useAdminClient } from "../admin-client";
1718
import {
1819
HelpItem,
@@ -33,7 +34,7 @@ import { ViewHeader } from "../components/view-header/ViewHeader";
3334
import WorkflowRepresentation from "libs/keycloak-admin-client/lib/defs/workflowRepresentation";
3435

3536
type AttributeForm = {
36-
workflowJSON: string;
37+
workflowYAML: string;
3738
};
3839

3940
export default function WorkflowDetailForm() {
@@ -47,7 +48,7 @@ export default function WorkflowDetailForm() {
4748
const form = useForm<AttributeForm>({
4849
mode: "onChange",
4950
defaultValues: {
50-
workflowJSON: "",
51+
workflowYAML: "",
5152
},
5253
});
5354
const { control, handleSubmit, setValue } = form;
@@ -72,13 +73,13 @@ export default function WorkflowDetailForm() {
7273
workflowToSet.name = `${workflow.name} -- ${t("copy")}`;
7374
}
7475

75-
setValue("workflowJSON", JSON.stringify(workflowToSet, null, 2));
76+
setValue("workflowYAML", yaml.stringify(workflowToSet));
7677
},
7778
[mode, id, setValue, t],
7879
);
7980

80-
const validateWorkflowJSON = (jsonStr: string): WorkflowRepresentation => {
81-
const json = JSON.parse(jsonStr);
81+
const validateworkflowYAML = (yamlStr: string): WorkflowRepresentation => {
82+
const json: WorkflowRepresentation = yaml.parse(yamlStr);
8283
if (!json.name) {
8384
throw new Error(t("workflowNameRequired"));
8485
}
@@ -87,8 +88,8 @@ export default function WorkflowDetailForm() {
8788

8889
const onUpdate: SubmitHandler<AttributeForm> = async (data) => {
8990
try {
90-
const json = validateWorkflowJSON(data.workflowJSON);
91-
await adminClient.workflows.update({ id: json.id! }, json);
91+
const json = validateworkflowYAML(data.workflowYAML);
92+
await adminClient.workflows.update({ id }, json);
9293
addAlert(t("workflowUpdated"), AlertVariant.success);
9394
} catch (error) {
9495
addError("workflowUpdateError", error);
@@ -97,8 +98,10 @@ export default function WorkflowDetailForm() {
9798

9899
const onCreate: SubmitHandler<AttributeForm> = async (data) => {
99100
try {
100-
const json = validateWorkflowJSON(data.workflowJSON);
101-
await adminClient.workflows.create(json);
101+
await adminClient.workflows.createAsYaml({
102+
realm,
103+
yaml: data.workflowYAML,
104+
});
102105
addAlert(t("workflowCreated"), AlertVariant.success);
103106
navigate(toWorkflows({ realm }));
104107
} catch (error) {
@@ -136,26 +139,26 @@ export default function WorkflowDetailForm() {
136139
fineGrainedAccess={true}
137140
>
138141
<FormGroup
139-
label={t("workflowJSON")}
142+
label={t("workflowYAML")}
140143
labelIcon={
141144
<HelpItem
142-
helpText={t("workflowJsonHelp")}
145+
helpText={t("workflowYAMLHelp")}
143146
fieldLabelId="code"
144147
/>
145148
}
146149
fieldId="code"
147150
isRequired
148151
>
149152
<Controller
150-
name="workflowJSON"
153+
name="workflowYAML"
151154
control={control}
152155
render={({ field }) => (
153156
<CodeEditor
154-
id="workflowJSON"
155-
data-testid="workflowJSON"
157+
id="workflowYAML"
158+
data-testid="workflowYAML"
156159
value={field.value}
157160
onChange={field.onChange}
158-
language="json"
161+
language="yaml"
159162
height={600}
160163
/>
161164
)}

js/apps/admin-ui/src/workflows/WorkflowsSection.tsx

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Button,
44
ButtonVariant,
55
PageSection,
6+
Switch,
67
} from "@patternfly/react-core";
78
import {
89
Action,
@@ -46,17 +47,17 @@ export default function WorkflowsSection() {
4647
);
4748
};
4849

49-
const toggleEnabled = async (workflowJSON: WorkflowRepresentation) => {
50-
workflowJSON.enabled = !(workflowJSON.enabled ?? true);
51-
50+
const toggleEnabled = async (workflow: WorkflowRepresentation) => {
51+
const enabled = !(workflow.enabled ?? true);
52+
const workflowToUpdate = { ...workflow, enabled };
5253
try {
5354
await adminClient.workflows.update(
54-
{ id: workflowJSON.id! },
55-
workflowJSON,
55+
{ id: workflow.id! },
56+
workflowToUpdate,
5657
);
5758

5859
addAlert(
59-
workflowJSON.enabled ? t("workflowEnabled") : t("workflowDisabled"),
60+
workflowToUpdate.enabled ? t("workflowEnabled") : t("workflowDisabled"),
6061
AlertVariant.success,
6162
);
6263
refresh();
@@ -127,9 +128,14 @@ export default function WorkflowsSection() {
127128
{
128129
name: "status",
129130
displayKey: "status",
130-
cellRenderer: (row: WorkflowRepresentation) => {
131-
return (row.enabled ?? true) ? t("enabled") : t("disabled");
132-
},
131+
cellRenderer: (workflow: WorkflowRepresentation) => (
132+
<Switch
133+
label={t("enabled")}
134+
labelOff={t("disabled")}
135+
isChecked={workflow.enabled ?? true}
136+
onChange={() => toggleEnabled(workflow)}
137+
/>
138+
),
133139
},
134140
]}
135141
actions={[
@@ -149,16 +155,6 @@ export default function WorkflowsSection() {
149155
);
150156
},
151157
} as Action<WorkflowRepresentation>,
152-
{
153-
title: t("changeStatus"),
154-
tooltipProps: {
155-
content: t("changeStatusTooltip"),
156-
},
157-
onRowClick: (workflow) => {
158-
setSelectedWorkflow(workflow);
159-
void toggleEnabled(workflow);
160-
},
161-
} as Action<WorkflowRepresentation>,
162158
]}
163159
loader={loader}
164160
ariaLabelKey="workflows"

js/libs/keycloak-admin-client/src/resources/workflows.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,20 @@ export class Workflows extends Resource<{ realm?: string }> {
4040

4141
public create = this.makeRequest<WorkflowRepresentation, { id: string }>({
4242
method: "POST",
43+
headers: { "Content-Type": "application/json" },
4344
returnResourceIdInLocationHeader: { field: "id" },
4445
});
4546

47+
public createAsYaml = this.makeRequest<
48+
{ realm: string; yaml: string },
49+
{ id: string }
50+
>({
51+
method: "POST",
52+
headers: { "Content-Type": "application/yaml", Accept: "application/yaml" },
53+
returnResourceIdInLocationHeader: { field: "id" },
54+
payloadKey: "yaml",
55+
});
56+
4657
public delById = this.makeRequest<{ id: string }, void>({
4758
method: "DELETE",
4859
path: "/{id}",

js/pnpm-lock.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)