Skip to content

Commit

Permalink
feat(ui): improvements of no code editor (#6876)
Browse files Browse the repository at this point in the history
  • Loading branch information
MilosPaunovic authored Jan 22, 2025
1 parent 40c4325 commit b823d9c
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 135 deletions.
8 changes: 6 additions & 2 deletions ui/src/components/code/components/Add.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<template>
<div @click="emits('add', props.what)" class="py-2 adding">
{{ t("no_code.adding", {what: props.what}) }}
{{
props.what
? t("no_code.adding", {what: props.what})
: t("no_code.adding_default")
}}
</div>
</template>

Expand All @@ -9,7 +13,7 @@
const {t} = useI18n({useScope: "global"});
const emits = defineEmits(["add"]);
const props = defineProps({what: {type: String, required: true}});
const props = defineProps({what: {type: String, default: undefined}});
</script>

<style scoped lang="scss">
Expand Down
57 changes: 37 additions & 20 deletions ui/src/components/code/components/Breadcrumbs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
v-for="(breadcrumb, index) in breadcrumbs"
:key="index"
class="item"
@click="store.commit('code/removeBreadcrumb', {position: index})"
>
<router-link :to="breadcrumb.to">
{{ breadcrumb.label }}
Expand All @@ -13,43 +14,59 @@
</template>

<script setup lang="ts">
import {computed} from "vue";
import {Breadcrumb} from "../utils/types";
import {computed, onMounted, watch} from "vue";
import {useRoute} from "vue-router";
const route = useRoute();
import {useStore} from "vuex";
const store = useStore();
import {useI18n} from "vue-i18n";
const {t} = useI18n({useScope: "global"});
const props = defineProps({flow: {type: Object, required: true}});
store.commit("code/clearBreadcrumbs");
const breadcrumbs = computed(() => store.state.code.breadcrumbs);
const params = {
namespace: route.params.namespace,
id: props.flow.id ?? "new",
tab: "edit",
};
const breadcrumbs = computed<Breadcrumb[]>(() => {
return [
{
label: props.flow.id ?? t("create_flow"),
to: {name: route.name, params},
onMounted(() => {
store.commit("code/addBreadcrumbs", {
breadcrumb: {
label:
route.name === "flows/create"
? t("create_flow")
: props.flow.id,
to: {name: route.name, params, query: {}},
},
...(route.query.section
? [
{
label:
route.query.identifier === "new"
? t(`no_code.creation.${route.query.section}`)
: route.query.identifier,
to: {name: route.name, params},
},
]
: []),
];
position: 0,
});
});
watch(
() => route.query.identifier,
(value) => {
if (!value) return;
store.commit("code/addBreadcrumbs", {
breadcrumb: {
label:
route.query.identifier === "new"
? t(`no_code.creation.${route.query.section}`)
: route.query.identifier,
to: {name: route.name, params, query: route.query},
},
position: 1,
});
},
);
</script>

<style scoped lang="scss">
Expand Down
4 changes: 2 additions & 2 deletions ui/src/components/code/components/inputs/InputPair.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<span v-if="required" class="me-1 text-danger">*</span>
<span class="label">{{ label }}</span>
<div class="mt-1 mb-2 wrapper">
<div class="mt-1 mb-2 w-100 wrapper">
<el-row
v-for="(value, key, index) in props.modelValue"
:key="index"
Expand Down Expand Up @@ -50,7 +50,7 @@
default: undefined,
},
label: {type: String, required: true},
property: {type: String, required: true},
property: {type: String, default: undefined},
required: {type: Boolean, default: false},
});
Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/code/components/inputs/InputText.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<span v-if="required" class="me-1 text-danger">*</span>
<span v-if="label" class="label">{{ label }}</span>
<div class="mt-1 mb-2 wrapper">
<div class="mt-1 mb-2 wrapper" :class="props.class">
<el-input v-model="input" @input="handleInput" :placeholder :disabled />
</div>
</template>
Expand All @@ -16,6 +16,7 @@
placeholder: {type: String, default: ""},
required: {type: Boolean, default: false},
disabled: {type: Boolean, default: false},
class: {type: String, default: undefined},
});
const input = ref(props.modelValue);
Expand Down
28 changes: 21 additions & 7 deletions ui/src/components/code/segments/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</template>

<script setup lang="ts">
import {ref, shallowRef} from "vue";
import {ref, shallowRef, computed} from "vue";
import {Field, Fields, CollapseItem} from "../utils/types";
Expand All @@ -47,7 +47,16 @@
import {useI18n} from "vue-i18n";
const {t} = useI18n({useScope: "global"});
const emits = defineEmits(["updateTask", "updateMetadata"]);
const emits = defineEmits(["save", "updateTask", "updateMetadata"]);
const saveEvent = (e: KeyboardEvent) => {
if (e.type === "keydown" && e.key === "s" && e.ctrlKey) {
e.preventDefault();
emits("save");
}
};
document.addEventListener("keydown", saveEvent);
const props = defineProps({
creation: {type: Boolean, default: false},
Expand Down Expand Up @@ -147,9 +156,14 @@
const title = t(`no_code.sections.${label}`);
return {title, elements};
};
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 ?? []),
]);
const sections = computed((): CollapseItem[] => {
return [
getSectionTitle("tasks", YamlUtils.parse(props.flow).tasks ?? []),
getSectionTitle("triggers", YamlUtils.parse(props.flow).triggers ?? []),
getSectionTitle(
"error_handlers",
YamlUtils.parse(props.flow).errors ?? [],
),
];
});
</script>
67 changes: 58 additions & 9 deletions ui/src/components/code/segments/Task.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
<template>
<TaskEditor v-model="yaml" :section @update:model-value="validateTask" />
<TaskEditor
v-if="!lastBreadcumb.shown"
v-model="yaml"
:section
@update:model-value="validateTask"
/>
<component
v-else
:is="lastBreadcumb.component.type"
v-bind="lastBreadcumb.component.props"
v-on="lastBreadcumb.component.listeners"
@update:model-value="validateTask"
/>

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

<div class="d-flex justify-content-between">
<div class="d-flex align-items-center">
<ValidationError :errors link />
<ValidationError v-if="!lastBreadcumb.shown" :errors link />
</div>

<Save @click="saveTask" :what="route.query.section?.toString()" />
Expand All @@ -23,7 +35,8 @@
creation: {type: Boolean, default: false},
});
import {useRoute} from "vue-router";
import {useRouter, useRoute} from "vue-router";
const router = useRouter();
const route = useRoute();
import {SECTIONS} from ".././../../utils/constants";
Expand All @@ -32,6 +45,20 @@
import TaskEditor from "../../../components/flows/TaskEditor.vue";
import YamlUtils from "../../../utils/yamlUtils";
import {useStore} from "vuex";
const store = useStore();
const breadcrumbs = computed(() => store.state.code.breadcrumbs);
const lastBreadcumb = computed(() => {
const index =
breadcrumbs.value.length === 3 ? 2 : breadcrumbs.value.length - 1;
return {
shown: index >= 2,
component: breadcrumbs.value?.[index]?.component,
};
});
const yaml = ref(
YamlUtils.extractTask(props.flow, route.query.identifier)?.toString() || "",
);
Expand Down Expand Up @@ -61,20 +88,36 @@
const CURRENT = ref(null);
const validateTask = (task) => {
let temp = YamlUtils.parse(yaml.value);
if (lastBreadcumb.value.shown) {
temp = {
...temp,
[breadcrumbs.value.at(-1).label]: {
...temp[breadcrumbs.value.at(-1).label],
...task,
},
};
}
temp = YamlUtils.stringify(temp);
store
.dispatch("flow/validateTask", {task, section: section.value})
.then(() => (yaml.value = task));
.dispatch("flow/validateTask", {task: temp, section: section.value})
.then(() => (yaml.value = temp));
CURRENT.value = task;
CURRENT.value = temp;
};
import {useStore} from "vuex";
const store = useStore();
const errors = computed(() => store.getters["flow/taskError"]);
import Save from "../components/Save.vue";
const saveTask = () => {
if (lastBreadcumb.value.shown) {
store.commit("code/removeBreadcrumb", {last: true});
return;
}
const source = props.flow;
const task = YamlUtils.extractTask(
Expand Down Expand Up @@ -114,5 +157,11 @@
emits("updateTask", action);
}
store.commit("code/removeBreadcrumb", {last: true});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {section, identifier, type, ...rest} = route.query;
router.replace({query: {...rest}});
};
</script>
1 change: 1 addition & 0 deletions ui/src/components/code/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type Breadcrumb = {
name: RouteRecordName;
params: RouteParams;
};
component?: ReturnType<typeof defineComponent>;
};

export type CollapseItem = {
Expand Down
5 changes: 1 addition & 4 deletions ui/src/components/flows/tasks/TaskBoolean.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<template>
<el-checkbox
:model-value="modelValue"
@update:model-value="onInput"
/>
<el-checkbox :model-value="modelValue" @update:model-value="onInput" />
</template>

<script>
Expand Down
Loading

0 comments on commit b823d9c

Please sign in to comment.