Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): improvements of no code editor #6804

Merged
merged 8 commits into from
Jan 17, 2025
178 changes: 82 additions & 96 deletions ui/src/components/code/segments/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,17 @@
<div class="p-4">
<template v-if="!route.query.section && !route.query.identifier">
<component
v-for="([k, v], index) in Object.entries(fields.main)"
v-for="([k, v], index) in Object.entries(fields)"
:key="index"
:is="v.component"
v-model="v.value"
v-bind="trimmed(v)"
@update:model-value="emits('updateMetadata', k, v.value)"
/>

<Collapse :items="sections.main">
<template #content>
<component
v-for="([k, v], index) in Object.entries(
fields.general,
)"
:key="index"
:is="v.component"
v-model="v.value"
v-bind="trimmed(v)"
@update:model-value="
emits('updateMetadata', k, v.value)
"
/>
</template>
</Collapse>

<hr class="m-0 mt-3">

<Collapse :items="sections.segments" creation />
<Collapse :items="sections" creation />
</template>

<Task
Expand All @@ -44,13 +27,14 @@
<script setup lang="ts">
import {ref, shallowRef} from "vue";

import {Field, Fields, Sections} from "../utils/types";
import {Field, Fields, CollapseItem} from "../utils/types";

import Collapse from "../components/collapse/Collapse.vue";
import InputText from "../components/inputs/InputText.vue";
import InputSwitch from "../components/inputs/InputSwitch.vue";
import InputLabel from "../components/inputs/InputLabel.vue";

import Editor from "../../inputs/Editor.vue";
import MetadataInputs from "../../flows/MetadataInputs.vue";
import MetadataVariables from "../../flows/MetadataVariables.vue";

Expand Down Expand Up @@ -81,72 +65,80 @@
};

const fields = ref<Fields>({
main: {
id: {
component: shallowRef(InputText),
value: props.metadata.id,
label: t("no_code.fields.main.flow_id"),
required: true,
disabled: !props.creation,
},
namespace: {
component: shallowRef(InputText),
value: props.metadata.namespace,
label: t("no_code.fields.main.namespace"),
required: true,
disabled: !props.creation,
},
description: {
component: shallowRef(InputText),
value: props.metadata.description,
label: t("no_code.fields.main.description"),
},
id: {
component: shallowRef(InputText),
value: props.metadata.id,
label: t("no_code.fields.main.flow_id"),
required: true,
disabled: !props.creation,
},
namespace: {
component: shallowRef(InputText),
value: props.metadata.namespace,
label: t("no_code.fields.main.namespace"),
required: true,
disabled: !props.creation,
},
description: {
component: shallowRef(InputText),
value: props.metadata.description,
label: t("no_code.fields.main.description"),
},
retry: {
component: shallowRef(Editor),
value: props.metadata.retry,
label: t("no_code.fields.general.retry"),
navbar: false,
input: true,
lang: "yaml",
style: {height: "100px"},
},
labels: {
component: shallowRef(InputLabel),
value: props.metadata.labels,
label: t("no_code.fields.general.labels"),
},
general: {
retry: {
component: shallowRef(InputText),
value: props.metadata.retry,
label: t("no_code.fields.general.retry"),
},
labels: {
component: shallowRef(InputLabel),
value: props.metadata.labels,
label: t("no_code.fields.general.labels"),
},
inputs: {
component: shallowRef(MetadataInputs),
value: props.metadata.inputs,
label: t("no_code.fields.general.inputs"),
inputs: props.metadata.inputs,
},
outputs: {
component: shallowRef(InputText),
value: props.metadata.outputs,
label: t("no_code.fields.general.outputs"),
},
variables: {
component: shallowRef(MetadataVariables),
value: props.metadata.variables,
label: t("no_code.fields.general.variables"),
variables: props.metadata.variables,
},
// concurrency: {
// component: shallowRef(InputSwitch), // TODO: To improve slot content
// value: props.metadata.concurrency,
// label: t("no_code.fields.general.concurrency"),
// schema: props.schemas?.definitions?.[CONCURRENCY] ?? {},
// root: "concurrency",
// },
pluginDefaults: {
component: shallowRef(InputText),
value: props.metadata.pluginDefaults,
label: t("no_code.fields.general.plugin_defaults"),
},
disabled: {
component: shallowRef(InputSwitch),
value: props.metadata.disabled,
label: t("no_code.fields.general.disabled"),
},
inputs: {
component: shallowRef(MetadataInputs),
value: props.metadata.inputs,
label: t("no_code.fields.general.inputs"),
inputs: props.metadata.inputs,
},
outputs: {
component: shallowRef(Editor),
value: props.metadata.outputs,
label: t("no_code.fields.general.outputs"),
navbar: false,
input: true,
lang: "yaml",
style: {height: "100px"},
},
variables: {
component: shallowRef(MetadataVariables),
value: props.metadata.variables,
label: t("no_code.fields.general.variables"),
variables: props.metadata.variables,
},
// concurrency: {
// component: shallowRef(InputSwitch), // TODO: To improve slot content
// value: props.metadata.concurrency,
// label: t("no_code.fields.general.concurrency"),
// schema: props.schemas?.definitions?.[CONCURRENCY] ?? {},
// root: "concurrency",
// },
pluginDefaults: {
component: shallowRef(Editor),
value: props.metadata.pluginDefaults,
label: t("no_code.fields.general.plugin_defaults"),
navbar: false,
input: true,
lang: "yaml",
style: {height: "100px"},
},
disabled: {
component: shallowRef(InputSwitch),
value: props.metadata.disabled,
label: t("no_code.fields.general.disabled"),
},
});

Expand All @@ -155,15 +147,9 @@
const title = t(`no_code.sections.${label}`);
return {title, elements};
};
const sections = ref<Sections>({
main: [{title: t("no_code.sections.general")}],
segments: [
getSectionTitle("tasks", YamlUtils.parse(props.flow).tasks ?? []),
getSectionTitle("triggers", YamlUtils.parse(props.flow).triggers ?? []),
getSectionTitle(
"error_handlers",
YamlUtils.parse(props.flow).errors ?? [],
),
],
});
const sections = ref<CollapseItem[]>([
getSectionTitle("tasks", YamlUtils.parse(props.flow).tasks ?? []),
getSectionTitle("triggers", YamlUtils.parse(props.flow).triggers ?? []),
getSectionTitle("error_handlers", YamlUtils.parse(props.flow).errors ?? []),
]);
</script>
16 changes: 9 additions & 7 deletions ui/src/components/code/segments/Task.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<template>
<TaskEditor v-model="yaml" :section @update:model-value="validateTask" />

<hr>
<template v-if="yaml">
<hr>

<div class="d-flex justify-content-between">
<div class="d-flex align-items-center">
<ValidationError :errors link />
</div>
<div class="d-flex justify-content-between">
<div class="d-flex align-items-center">
<ValidationError :errors link />
</div>

<Save @click="saveTask" :what="route.query.section?.toString()" />
</div>
<Save @click="saveTask" :what="route.query.section?.toString()" />
</div>
</template>
</template>

<script setup lang="ts">
Expand Down
38 changes: 17 additions & 21 deletions ui/src/components/code/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,34 @@ type VariableField = Field & {
variables: any[];
};

type Main = {
id: Field;
namespace: Field;
description: Field;
};

type ConcurrencyField = Field & {
root: string;
schema: object;
};

type General = {
retry: Field;
type EditorField = Field & {
navbar: boolean;
input: boolean;
lang: string;
style: {
height: string;
};
};

export type Fields = {
id: Field;
namespace: Field;
description: Field;
retry: EditorField;
labels: LabelField;
inputs: InputField;
outputs: Field;
outputs: EditorField;
variables: VariableField;
concurrency: ConcurrencyField;
pluginDefaults: Field;
concurrency?: ConcurrencyField; // TODO: Make it not optional
pluginDefaults: EditorField;
disabled: Field;
};

export type Fields = {
main: Main;
general: General;
};

export type Breadcrumb = {
label: string;
to: {
Expand All @@ -68,8 +69,3 @@ export type CollapseItem = {
title: string;
elements?: Record<string, any>[];
};

export type Sections = {
main: CollapseItem[];
segments: CollapseItem[];
};
2 changes: 1 addition & 1 deletion ui/src/components/flows/MetadataInputs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
/>
</div>
</drawer>
<div class="w-100">
<div class="w-100 mb-3">
<div>
<div
class="d-flex w-100 mb-2"
Expand Down
3 changes: 1 addition & 2 deletions ui/src/components/flows/MetadataVariables.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
</el-form-item>
</el-form>
</drawer>
<div v-if="variables">
<div v-if="variables" class="mb-3">
<div
class="d-flex w-100 mb-2"
v-for="(value, index) in newVariables"
Expand Down Expand Up @@ -76,7 +76,6 @@
<div v-else class="d-flex justify-content-center">
<el-button
:icon="Plus"
type="success"
class="w-25"
@click="addVariable"
>
Expand Down
8 changes: 7 additions & 1 deletion ui/src/components/inputs/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
</slot>
</nav>
<slot name="absolute" />
<div class="editor-container" ref="container" :class="containerClass">
<span v-if="label" class="label">{{ label }}</span>
<div class="editor-container" ref="container" :class="[containerClass, {'mb-2': label}]">
<div ref="editorContainer" class="editor-wrapper position-relative">
<monaco-editor
ref="monacoEditor"
Expand Down Expand Up @@ -98,6 +99,7 @@
lineNumbers: {type: Boolean, default: undefined},
minimap: {type: Boolean, default: false},
creating: {type: Boolean, default: false},
label: {type: String, default: undefined},
},
components: {
MonacoEditor,
Expand Down Expand Up @@ -474,6 +476,10 @@
};
</script>

<style scoped lang="scss">
@import "../code/styles/code.scss";
</style>

<style lang="scss">
@import "@kestra-io/ui-libs/src/scss/color-palette.scss";
@import "../../styles/layout/root-dark.scss";
Expand Down
Loading
Loading