@kestra-io/ui-libs 0.0.1 → 0.0.3
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/README.md +1 -1
- package/package.json +11 -25
- package/src/components/buttons/AddTaskButton.vue +33 -0
- package/src/components/index.js +21 -0
- package/src/components/misc/Duration.vue +110 -0
- package/src/components/misc/ExecutionInformations.vue +119 -0
- package/src/components/misc/State.vue +57 -0
- package/src/components/misc/TaskIcon.vue +50 -0
- package/src/components/nodes/BasicNode.vue +224 -0
- package/src/components/nodes/ClusterNode.vue +53 -0
- package/src/components/nodes/CollapsedClusterNode.vue +94 -0
- package/src/components/nodes/DependenciesNode.vue +127 -0
- package/src/components/nodes/DotNode.vue +47 -0
- package/src/components/nodes/EdgeNode.vue +67 -0
- package/src/components/nodes/TaskNode.vue +166 -0
- package/src/components/nodes/TriggerNode.vue +101 -0
- package/src/index.js +1 -0
- package/src/scss/app.scss +39 -0
- package/src/scss/bootstrap-dark.scss +49 -0
- package/src/scss/bootstrap.scss +72 -0
- package/src/scss/vendor.scss +12 -0
- package/src/utils/GraphUtils.js +390 -0
- package/src/utils/Utils.js +47 -0
- package/src/utils/YamlUtils.js +478 -0
- package/src/utils/constants.js +19 -0
- package/src/utils/global.js +23 -0
- package/src/utils/state.js +165 -0
- package/dist/kestra-ui.js +0 -2594
- package/dist/kestra-ui.umd.cjs +0 -1
- package/dist/style.css +0 -1
- /package/{dist → src/scss}/_theme-dark.scss +0 -0
- /package/{dist → src/scss}/_variables.scss +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="badge rounded-pill text-color" :class="[`bg-${data.color}`]">{{ id }}</span>
|
|
3
|
+
<div class="position-absolute top-0 start-100 translate-middle text-white d-flex">
|
|
4
|
+
<span
|
|
5
|
+
v-if="data.collapsable"
|
|
6
|
+
class="rounded-button"
|
|
7
|
+
:class="[`bg-${data.color}`]"
|
|
8
|
+
@click="collapse()"
|
|
9
|
+
>
|
|
10
|
+
<ArrowCollapse class="button-icon" alt="Collapse task" />
|
|
11
|
+
</span>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
<script setup>
|
|
15
|
+
import ArrowCollapse from "vue-material-design-icons/ArrowCollapse.vue"
|
|
16
|
+
import {EVENTS} from "../../utils/constants.js";
|
|
17
|
+
|
|
18
|
+
const props = defineProps(["data", "sourcePosition", "targetPosition", "label", "id"]);
|
|
19
|
+
const emit = defineEmits([EVENTS.COLLAPSE])
|
|
20
|
+
|
|
21
|
+
const collapse = () => {
|
|
22
|
+
emit(EVENTS.COLLAPSE, props.id)
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
</script>
|
|
26
|
+
<script>
|
|
27
|
+
export default {
|
|
28
|
+
inheritAttrs: false,
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
<style scoped lang="scss">
|
|
32
|
+
.rounded-button {
|
|
33
|
+
border-radius: 1rem;
|
|
34
|
+
width: 1rem;
|
|
35
|
+
height: 1rem;
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
align-items: center;
|
|
39
|
+
pointer-events: auto !important;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.button-icon {
|
|
43
|
+
font-size: 0.75rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.text-color {
|
|
47
|
+
color: var(--bs-white);
|
|
48
|
+
font-size: 0.625rem;
|
|
49
|
+
font-weight: 700;
|
|
50
|
+
padding: 0.25rem 0.5rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Handle type="source" :position="sourcePosition" />
|
|
3
|
+
<div class="collapsed-cluster-node">
|
|
4
|
+
<span>{{ id }}</span>
|
|
5
|
+
<div class="position-absolute top-0 start-100 translate-middle text-white d-flex top-button-div">
|
|
6
|
+
<slot name="badge-button-before" />
|
|
7
|
+
<span
|
|
8
|
+
v-if="expandable"
|
|
9
|
+
class="rounded-button"
|
|
10
|
+
:class="[`bg-${data.color}`]"
|
|
11
|
+
@click="$emit(EVENTS.EXPAND, id)"
|
|
12
|
+
>
|
|
13
|
+
<ArrowExpand class="button-icon" alt="Expand task" />
|
|
14
|
+
</span>
|
|
15
|
+
<slot name="badge-button-after" />
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<Handle type="target" :position="targetPosition" />
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
import {EVENTS} from "../../utils/constants.js";
|
|
23
|
+
import ArrowExpand from "vue-material-design-icons/ArrowExpand.vue";
|
|
24
|
+
import {Handle} from "@vue-flow/core";
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
components: {
|
|
28
|
+
Handle,
|
|
29
|
+
ArrowExpand
|
|
30
|
+
},
|
|
31
|
+
inheritAttrs: false,
|
|
32
|
+
props: {
|
|
33
|
+
id: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: undefined
|
|
36
|
+
},
|
|
37
|
+
sourcePosition: {
|
|
38
|
+
type: String,
|
|
39
|
+
required: true
|
|
40
|
+
},
|
|
41
|
+
targetPosition: {
|
|
42
|
+
type: String,
|
|
43
|
+
required: true
|
|
44
|
+
},
|
|
45
|
+
data: {
|
|
46
|
+
type: Object,
|
|
47
|
+
required: true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
data() {
|
|
51
|
+
return {
|
|
52
|
+
filter: undefined,
|
|
53
|
+
isOpen: false,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
computed: {
|
|
57
|
+
EVENTS() {
|
|
58
|
+
return EVENTS
|
|
59
|
+
},
|
|
60
|
+
expandable() {
|
|
61
|
+
return this.data?.expandable || false
|
|
62
|
+
},
|
|
63
|
+
description() {
|
|
64
|
+
const node = this.data.node.task ?? this.data.node.trigger ?? null
|
|
65
|
+
if (node) {
|
|
66
|
+
return node.description ?? null
|
|
67
|
+
}
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style lang="scss" scoped>
|
|
75
|
+
.collapsed-cluster-node {
|
|
76
|
+
width: 150px;
|
|
77
|
+
height: 44px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.rounded-button {
|
|
81
|
+
border-radius: 1rem;
|
|
82
|
+
width: 1rem;
|
|
83
|
+
height: 1rem;
|
|
84
|
+
display: flex;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
align-items: center;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.button-icon {
|
|
90
|
+
font-size: 0.75rem;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
</style>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Handle type="source" :position="sourcePosition" />
|
|
3
|
+
<div
|
|
4
|
+
:class="[`border-${data.color}`]"
|
|
5
|
+
class="dependency-node-wrapper rounded-3 border"
|
|
6
|
+
>
|
|
7
|
+
<TaskIcon color="pink" :icon="{icon: icon}" />
|
|
8
|
+
<div class="dependency-text d-flex flex-column">
|
|
9
|
+
<div class="dependency-flow-text">
|
|
10
|
+
{{ data.flowId }}
|
|
11
|
+
</div>
|
|
12
|
+
<div class="dependency-namespace-text">
|
|
13
|
+
{{ data.namespace }}
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="position-absolute top-0 text-white d-flex top-button-div">
|
|
18
|
+
<slot name="badge-button-before" />
|
|
19
|
+
<span
|
|
20
|
+
v-if="data.link"
|
|
21
|
+
class="rounded-button"
|
|
22
|
+
:class="[`bg-${data.color}`]"
|
|
23
|
+
@click="$emit(EVENTS.OPEN_LINK, data)"
|
|
24
|
+
>
|
|
25
|
+
<OpenInNew class="button-icon" alt="Open in new tab" />
|
|
26
|
+
</span>
|
|
27
|
+
<span
|
|
28
|
+
class="rounded-button"
|
|
29
|
+
:class="[`bg-${data.color}`]"
|
|
30
|
+
@click="$emit(EVENTS.EXPAND_DEPENDENCIES, data)"
|
|
31
|
+
>
|
|
32
|
+
<ArrowExpandAll class="button-icon" alt="Expand task" />
|
|
33
|
+
</span>
|
|
34
|
+
<slot name="badge-button-after" />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<Handle type="target" :position="targetPosition" />
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script>
|
|
41
|
+
import {Handle} from "@vue-flow/core";
|
|
42
|
+
import TaskIcon from "../misc/TaskIcon.vue";
|
|
43
|
+
import {Buffer} from "buffer";
|
|
44
|
+
import OpenInNew from "vue-material-design-icons/OpenInNew.vue";
|
|
45
|
+
import ArrowExpandAll from "vue-material-design-icons/ArrowExpandAll.vue";
|
|
46
|
+
import {EVENTS} from "../../utils/constants.js";
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
name: "Dependencies",
|
|
50
|
+
components: {ArrowExpandAll, OpenInNew, TaskIcon, Handle},
|
|
51
|
+
inheritAttrs: false,
|
|
52
|
+
emits: [
|
|
53
|
+
EVENTS.EXPAND_DEPENDENCIES,
|
|
54
|
+
EVENTS.OPEN_LINK,
|
|
55
|
+
EVENTS.MOUSE_OVER,
|
|
56
|
+
EVENTS.MOUSE_LEAVE,
|
|
57
|
+
],
|
|
58
|
+
computed: {
|
|
59
|
+
EVENTS() {
|
|
60
|
+
return EVENTS
|
|
61
|
+
},
|
|
62
|
+
icon() {
|
|
63
|
+
return Buffer.from("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"25\" viewBox=\"0 0 24 25\" fill=\"none\">\n" +
|
|
64
|
+
"<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M4.34546 9.63757C4.74074 10.5277 5.31782 11.3221 6.03835 11.9681L7.03434 10.8209C6.4739 10.3185 6.02504 9.70059 5.71758 9.00824C5.41012 8.3159 5.25111 7.56496 5.25111 6.80532C5.25111 6.04568 5.41012 5.29475 5.71758 4.6024C6.02504 3.91006 6.4739 3.29216 7.03434 2.78977L6.03835 1.64258C5.31782 2.28851 4.74074 3.08293 4.34546 3.97307C3.95019 4.86321 3.74575 5.82867 3.74575 6.80532C3.74575 7.78197 3.95019 8.74744 4.34546 9.63757ZM16.955 4.38931C17.4802 3.97411 18.1261 3.74777 18.7913 3.74576C19.5894 3.74576 20.3547 4.06807 20.919 4.64177C21.4833 5.21548 21.8004 5.9936 21.8004 6.80494C21.8004 7.61628 21.4833 8.3944 20.919 8.96811C20.3547 9.54181 19.5894 9.86412 18.7913 9.86412C18.2559 9.86126 17.7312 9.71144 17.2725 9.43048L12.3325 14.4529L11.2688 13.3715L16.2088 8.34906C16.0668 8.10583 15.9592 7.84348 15.8891 7.56973H11.2688V6.04014H15.8891C16.055 5.38511 16.4298 4.80451 16.955 4.38931ZM17.9555 8.07674C18.2029 8.24482 18.4938 8.33453 18.7913 8.33453C19.1902 8.33412 19.5727 8.17284 19.8548 7.88607C20.1368 7.59931 20.2955 7.21049 20.2959 6.80494C20.2959 6.50241 20.2076 6.20668 20.0423 5.95514C19.877 5.70361 19.642 5.50756 19.3671 5.39178C19.0922 5.27601 18.7897 5.24572 18.4978 5.30474C18.206 5.36376 17.9379 5.50944 17.7275 5.72336C17.5171 5.93727 17.3738 6.20982 17.3157 6.50653C17.2577 6.80324 17.2875 7.11079 17.4014 7.39029C17.5152 7.66978 17.7081 7.90867 17.9555 8.07674ZM3.74621 15.2177V16.7473H7.19606L2.2417 21.7842L3.30539 22.8656L8.25975 17.8287V21.336H9.76427V15.2177H3.74621ZM15.7823 18.2769H12.7733V19.8064H15.7823V22.1008H21.8004V15.9825H15.7823V18.2769ZM17.2868 20.5712V17.5121H20.2959V20.5712H17.2868ZM8.02885 9.67292C7.62863 9.31407 7.30809 8.87275 7.08853 8.37827C6.86897 7.88378 6.75542 7.34747 6.75542 6.80494C6.75542 6.26241 6.86897 5.72609 7.08853 5.23161C7.30809 4.73713 7.62863 4.29581 8.02885 3.93696L9.02484 5.08415C8.78458 5.29946 8.59215 5.5643 8.46034 5.86106C8.32853 6.15782 8.26035 6.47971 8.26035 6.80532C8.26035 7.13094 8.32853 7.45282 8.46034 7.74958C8.59215 8.04634 8.78458 8.31118 9.02484 8.52649L8.02885 9.67292Z\" fill=\"white\"/>\n" +
|
|
65
|
+
"</svg>", "utf8").toString("base64");
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
props: {
|
|
69
|
+
data: {
|
|
70
|
+
type: Object,
|
|
71
|
+
required: true,
|
|
72
|
+
},
|
|
73
|
+
sourcePosition: {
|
|
74
|
+
type: String,
|
|
75
|
+
required: true
|
|
76
|
+
},
|
|
77
|
+
targetPosition: {
|
|
78
|
+
type: String,
|
|
79
|
+
required: true
|
|
80
|
+
},
|
|
81
|
+
id: {
|
|
82
|
+
type: String,
|
|
83
|
+
required: true
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<style scoped lang="scss">
|
|
90
|
+
.dependency-node-wrapper {
|
|
91
|
+
background-color: var(--bs-white);
|
|
92
|
+
color: var(--bs-black);
|
|
93
|
+
|
|
94
|
+
html.dark & {
|
|
95
|
+
background-color: var(--card-bg);
|
|
96
|
+
color: var(--bs-white);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
width: 184px;
|
|
100
|
+
height: 44px;
|
|
101
|
+
margin: 0;
|
|
102
|
+
padding: 8px 18px 8px 6px;
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
box-shadow: 0 12px 12px 0 rgba(130, 103, 158, 0.10);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.dependency-text {
|
|
109
|
+
margin-left: 0.5rem;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.dependency-flow-text {
|
|
113
|
+
font-size: 0.85rem;
|
|
114
|
+
font-weight: 700;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.dependency-namespace-text {
|
|
118
|
+
font-size: 0.625rem;
|
|
119
|
+
font-weight: 400;
|
|
120
|
+
color: #564A75;
|
|
121
|
+
|
|
122
|
+
html.dark & {
|
|
123
|
+
color: #E3DBFF;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
</style>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Handle type="source" class="custom-handle" :position="sourcePosition" />
|
|
3
|
+
<div class="dot">
|
|
4
|
+
<Circle class="circle" alt="circle" />
|
|
5
|
+
</div>
|
|
6
|
+
<Handle type="target" class="custom-handle" :position="targetPosition" />
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import {Handle} from "@vue-flow/core";
|
|
11
|
+
import Circle from "vue-material-design-icons/Circle.vue"
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: "Dot",
|
|
15
|
+
components: {Handle, Circle},
|
|
16
|
+
inheritAttrs: false,
|
|
17
|
+
props: {
|
|
18
|
+
data: {
|
|
19
|
+
type: Object,
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
sourcePosition: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true
|
|
25
|
+
},
|
|
26
|
+
targetPosition: {
|
|
27
|
+
type: String,
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
label: {
|
|
31
|
+
type: String
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
<style scoped>
|
|
37
|
+
.custom-handle {
|
|
38
|
+
visibility: hidden
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.dot {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
align-items: center;
|
|
45
|
+
font-size: 5px;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {computed} from "vue";
|
|
3
|
+
import {EdgeLabelRenderer, getSmoothStepPath} from "@vue-flow/core";
|
|
4
|
+
import AddTaskButton from "../buttons/AddTaskButton.vue";
|
|
5
|
+
import {EVENTS} from "../../utils/constants.js";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
props: {
|
|
9
|
+
id: String,
|
|
10
|
+
data: Object,
|
|
11
|
+
sourceX: Number,
|
|
12
|
+
sourceY: Number,
|
|
13
|
+
targetX: Number,
|
|
14
|
+
targetY: Number,
|
|
15
|
+
markerEnd: String,
|
|
16
|
+
sourcePosition: String,
|
|
17
|
+
targetPosition: String,
|
|
18
|
+
},
|
|
19
|
+
components: {
|
|
20
|
+
AddTaskButton,
|
|
21
|
+
EdgeLabelRenderer
|
|
22
|
+
},
|
|
23
|
+
computed: {
|
|
24
|
+
EVENTS() {
|
|
25
|
+
return EVENTS
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
setup(props) {
|
|
29
|
+
const path = computed(() => getSmoothStepPath(props));
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
path,
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
inheritAttrs: false,
|
|
36
|
+
};
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<path
|
|
41
|
+
:id="id"
|
|
42
|
+
:class="'vue-flow__edge-path stroke-'+data.color"
|
|
43
|
+
:style="data.haveDashArray ?
|
|
44
|
+
{
|
|
45
|
+
strokeDasharray: '2',
|
|
46
|
+
}:
|
|
47
|
+
{}"
|
|
48
|
+
:d="path[0]"
|
|
49
|
+
:marker-end="markerEnd"
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<EdgeLabelRenderer style="z-index: 10">
|
|
53
|
+
<div
|
|
54
|
+
:style="{
|
|
55
|
+
pointerEvents: 'all',
|
|
56
|
+
position: 'absolute',
|
|
57
|
+
transform: `translate(-50%, -50%) translate(${path[1]}px,${path[2]}px)`,
|
|
58
|
+
}"
|
|
59
|
+
>
|
|
60
|
+
<AddTaskButton
|
|
61
|
+
v-if="!data.disabled && data.haveAdd != undefined"
|
|
62
|
+
:add-task="true"
|
|
63
|
+
@click="$emit(EVENTS.ADD_TASK, data.haveAdd)"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</EdgeLabelRenderer>
|
|
67
|
+
</template>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Handle type="source" :position="sourcePosition" />
|
|
3
|
+
<basic-node
|
|
4
|
+
:id="id"
|
|
5
|
+
:data="data"
|
|
6
|
+
:state="state"
|
|
7
|
+
@show-description="forwardEvent(EVENTS.SHOW_DESCRIPTION, $event)"
|
|
8
|
+
@expand="forwardEvent(EVENTS.EXPAND, id)"
|
|
9
|
+
@open-link="forwardEvent(EVENTS.OPEN_LINK, $event)"
|
|
10
|
+
@mouseover="forwardEvent(EVENTS.MOUSE_OVER, $event)"
|
|
11
|
+
@mouseleave="forwardEvent(EVENTS.MOUSE_LEAVE)"
|
|
12
|
+
>
|
|
13
|
+
<template #content>
|
|
14
|
+
<execution-informations v-if="data.execution" :color="color" />
|
|
15
|
+
</template>
|
|
16
|
+
<template #badge-button-before>
|
|
17
|
+
<span
|
|
18
|
+
v-if="execution"
|
|
19
|
+
class="rounded-button"
|
|
20
|
+
:class="[`bg-${color}`]"
|
|
21
|
+
@click="$emit(EVENTS.SHOW_LOGS, {id, taskRuns})"
|
|
22
|
+
>
|
|
23
|
+
<TextBoxSearch class="button-icon" alt="Show logs" />
|
|
24
|
+
</span>
|
|
25
|
+
<span
|
|
26
|
+
v-if="!data.execution && !data.isReadOnly && data.isFlowable"
|
|
27
|
+
class="rounded-button"
|
|
28
|
+
:class="[`bg-${color}`]"
|
|
29
|
+
@click="$emit(EVENTS.ADD_ERROR, {task: data.node.task})"
|
|
30
|
+
>
|
|
31
|
+
<InformationOutline class="button-icon" alt="Edit task" />
|
|
32
|
+
</span>
|
|
33
|
+
<span
|
|
34
|
+
v-if="!data.execution && !data.isReadOnly"
|
|
35
|
+
class="rounded-button"
|
|
36
|
+
:class="[`bg-${color}`]"
|
|
37
|
+
@click="$emit(EVENTS.EDIT, {task: data.node.task, section: SECTIONS.TASKS})"
|
|
38
|
+
>
|
|
39
|
+
<Pencil class="button-icon" alt="Edit task" />
|
|
40
|
+
</span>
|
|
41
|
+
<span
|
|
42
|
+
v-if="!data.execution && !data.isReadOnly"
|
|
43
|
+
class="rounded-button"
|
|
44
|
+
:class="[`bg-${color}`]"
|
|
45
|
+
@click="$emit(EVENTS.DELETE, {id, section: SECTIONS.TASKS})"
|
|
46
|
+
>
|
|
47
|
+
<Delete class="button-icon" alt="Delete task" />
|
|
48
|
+
</span>
|
|
49
|
+
</template>
|
|
50
|
+
</basic-node>
|
|
51
|
+
<Handle type="target" :position="targetPosition" />
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
import BasicNode from "./BasicNode.vue";
|
|
56
|
+
import {Handle} from "@vue-flow/core";
|
|
57
|
+
import State from "../../utils/state.js";
|
|
58
|
+
import {EVENTS, SECTIONS} from "../../utils/constants.js";
|
|
59
|
+
import ExecutionInformations from "../misc/ExecutionInformations.vue";
|
|
60
|
+
import Pencil from "vue-material-design-icons/Pencil.vue";
|
|
61
|
+
import Delete from "vue-material-design-icons/Delete.vue";
|
|
62
|
+
import TextBoxSearch from "vue-material-design-icons/TextBoxSearch.vue";
|
|
63
|
+
import InformationOutline from "vue-material-design-icons/InformationOutline.vue"
|
|
64
|
+
|
|
65
|
+
export default {
|
|
66
|
+
name: "Task",
|
|
67
|
+
inheritAttrs: false,
|
|
68
|
+
computed: {
|
|
69
|
+
SECTIONS() {
|
|
70
|
+
return SECTIONS
|
|
71
|
+
},
|
|
72
|
+
EVENTS() {
|
|
73
|
+
return EVENTS
|
|
74
|
+
},
|
|
75
|
+
color() {
|
|
76
|
+
return this.data.color ?? "primary"
|
|
77
|
+
},
|
|
78
|
+
execution() {
|
|
79
|
+
return this.data.execution
|
|
80
|
+
},
|
|
81
|
+
taskRunList() {
|
|
82
|
+
return this.execution && this.execution.taskRunList ? this.execution.taskRunList : []
|
|
83
|
+
},
|
|
84
|
+
taskRuns() {
|
|
85
|
+
return this.taskRunList.filter(t => t.taskId === this.data.node.task.id)
|
|
86
|
+
},
|
|
87
|
+
state() {
|
|
88
|
+
if (!this.taskRuns) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (this.taskRuns.length === 1) {
|
|
93
|
+
return this.taskRuns[0].state.current
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const allStates = this.taskRuns.map(t => t.state.current);
|
|
97
|
+
|
|
98
|
+
const SORT_STATUS = [
|
|
99
|
+
State.FAILED,
|
|
100
|
+
State.KILLED,
|
|
101
|
+
State.WARNING,
|
|
102
|
+
State.KILLING,
|
|
103
|
+
State.RUNNING,
|
|
104
|
+
State.SUCCESS,
|
|
105
|
+
State.RESTARTED,
|
|
106
|
+
State.CREATED,
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// sorting based on SORT_STATUS array
|
|
110
|
+
const result = allStates
|
|
111
|
+
.map((item) => {
|
|
112
|
+
const n = SORT_STATUS.indexOf(item[1]);
|
|
113
|
+
SORT_STATUS[n] = undefined;
|
|
114
|
+
return [n, item]
|
|
115
|
+
})
|
|
116
|
+
.sort()
|
|
117
|
+
.map((j) => j[1])
|
|
118
|
+
return result[0];
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
emits: [
|
|
122
|
+
EVENTS.EXPAND,
|
|
123
|
+
EVENTS.OPEN_LINK,
|
|
124
|
+
EVENTS.SHOW_LOGS,
|
|
125
|
+
EVENTS.MOUSE_OVER,
|
|
126
|
+
EVENTS.MOUSE_LEAVE,
|
|
127
|
+
EVENTS.ADD_ERROR,
|
|
128
|
+
EVENTS.EDIT,
|
|
129
|
+
EVENTS.DELETE,
|
|
130
|
+
EVENTS.ADD_TASK
|
|
131
|
+
],
|
|
132
|
+
components: {
|
|
133
|
+
Pencil,
|
|
134
|
+
Delete,
|
|
135
|
+
ExecutionInformations,
|
|
136
|
+
Handle,
|
|
137
|
+
BasicNode,
|
|
138
|
+
TextBoxSearch,
|
|
139
|
+
InformationOutline
|
|
140
|
+
},
|
|
141
|
+
props: {
|
|
142
|
+
data: {
|
|
143
|
+
type: Object,
|
|
144
|
+
required: true,
|
|
145
|
+
},
|
|
146
|
+
sourcePosition: {
|
|
147
|
+
type: String,
|
|
148
|
+
required: true
|
|
149
|
+
},
|
|
150
|
+
targetPosition: {
|
|
151
|
+
type: String,
|
|
152
|
+
required: true
|
|
153
|
+
},
|
|
154
|
+
id: {
|
|
155
|
+
type: String,
|
|
156
|
+
required: true
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
methods: {
|
|
160
|
+
forwardEvent(event, payload) {
|
|
161
|
+
this.$emit(event, payload)
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
</script>
|
|
166
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Handle type="source" :position="sourcePosition" />
|
|
3
|
+
<basic-node
|
|
4
|
+
:id="id"
|
|
5
|
+
:data="data"
|
|
6
|
+
:color="color"
|
|
7
|
+
@showDescription="forwardEvent(EVENTS.SHOW_DESCRIPTION, id)"
|
|
8
|
+
@expand="forwardEvent(EVENTS.EXPAND, id)"
|
|
9
|
+
>
|
|
10
|
+
<template #badge-button-before>
|
|
11
|
+
<span
|
|
12
|
+
v-if="!data.execution && !data.isReadOnly"
|
|
13
|
+
class="rounded-button"
|
|
14
|
+
:class="[`bg-${color}`]"
|
|
15
|
+
@click="$emit(EVENTS.EDIT, {task: data.node.trigger, section: SECTIONS.TRIGGERS})"
|
|
16
|
+
>
|
|
17
|
+
<Pencil class="button-icon" alt="Edit task" />
|
|
18
|
+
</span>
|
|
19
|
+
<span
|
|
20
|
+
v-if="!data.execution && !data.isReadOnly"
|
|
21
|
+
class="rounded-button"
|
|
22
|
+
:class="[`bg-${color}`]"
|
|
23
|
+
@click="$emit(EVENTS.DELETE, {id, section: SECTIONS.TRIGGERS})"
|
|
24
|
+
>
|
|
25
|
+
<Delete class="button-icon" alt="Delete task" />
|
|
26
|
+
</span>
|
|
27
|
+
</template>
|
|
28
|
+
</basic-node>
|
|
29
|
+
<Handle type="target" :position="targetPosition" />
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
import BasicNode from "./BasicNode.vue";
|
|
34
|
+
import {Handle} from "@vue-flow/core";
|
|
35
|
+
import {EVENTS, SECTIONS} from "../../utils/constants.js";
|
|
36
|
+
import Pencil from "vue-material-design-icons/Pencil.vue";
|
|
37
|
+
import Delete from "vue-material-design-icons/Delete.vue";
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
name: "Task",
|
|
41
|
+
inheritAttrs: false,
|
|
42
|
+
computed: {
|
|
43
|
+
SECTIONS() {
|
|
44
|
+
return SECTIONS
|
|
45
|
+
},
|
|
46
|
+
EVENTS() {
|
|
47
|
+
return EVENTS
|
|
48
|
+
},
|
|
49
|
+
color() {
|
|
50
|
+
return this.data.color ?? "primary"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
emits: [
|
|
54
|
+
EVENTS.DELETE,
|
|
55
|
+
EVENTS.EDIT
|
|
56
|
+
],
|
|
57
|
+
components: {
|
|
58
|
+
Delete, Pencil,
|
|
59
|
+
Handle,
|
|
60
|
+
BasicNode,
|
|
61
|
+
},
|
|
62
|
+
props: {
|
|
63
|
+
data: {
|
|
64
|
+
type: Object,
|
|
65
|
+
required: true,
|
|
66
|
+
},
|
|
67
|
+
sourcePosition: {
|
|
68
|
+
type: String,
|
|
69
|
+
required: true
|
|
70
|
+
},
|
|
71
|
+
targetPosition: {
|
|
72
|
+
type: String,
|
|
73
|
+
required: true
|
|
74
|
+
},
|
|
75
|
+
id: {
|
|
76
|
+
type: String,
|
|
77
|
+
required: true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
methods: {
|
|
81
|
+
forwardEvent(event, payload) {
|
|
82
|
+
this.$emit(event, payload)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
</script>
|
|
87
|
+
<style scoped lang="scss">
|
|
88
|
+
.rounded-button {
|
|
89
|
+
border-radius: 1rem;
|
|
90
|
+
width: 1rem;
|
|
91
|
+
height: 1rem;
|
|
92
|
+
display: flex;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
align-items: center;
|
|
95
|
+
margin-left: 0.25rem;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.button-icon {
|
|
99
|
+
font-size: 0.75rem;
|
|
100
|
+
}
|
|
101
|
+
</style>
|
package/src/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components/index.js";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@import "variables";
|
|
2
|
+
|
|
3
|
+
.material-design-icon > .material-design-icon__svg {
|
|
4
|
+
bottom: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.vue-flow__node-cluster {
|
|
8
|
+
pointer-events: none !important;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
marker[id*='id=marker-custom&type=arrowclosed'] polyline {
|
|
12
|
+
stroke: $gray-700;
|
|
13
|
+
fill: $gray-700;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.vue-flow__handle {
|
|
17
|
+
opacity: 0 !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
.top-button-div {
|
|
22
|
+
width: 100%;
|
|
23
|
+
justify-content: end;
|
|
24
|
+
transform: translate(-5%, -50%) !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.rounded-button {
|
|
28
|
+
border-radius: 1rem;
|
|
29
|
+
width: 1rem;
|
|
30
|
+
height: 1rem;
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
align-items: center;
|
|
34
|
+
margin-left: 0.25rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.button-icon {
|
|
38
|
+
font-size: 0.75rem;
|
|
39
|
+
}
|