@kestra-io/ui-libs 0.0.2 → 0.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kestra-io/ui-libs",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
@@ -12,26 +12,32 @@
12
12
  "dev": "vite",
13
13
  "debug": "vite --debug",
14
14
  "preview": "vite preview",
15
+ "build": "vite build",
15
16
  "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path ./.gitignore"
16
17
  },
17
18
  "peerDependencies": {
18
- "@popperjs/core": "^2.11.8",
19
- "@vitejs/plugin-vue": "^4.2.3",
20
- "@vue-flow/core": "^1.22.2",
19
+ "@vue-flow/background": "^1.2.0",
20
+ "@vue-flow/controls": "1.0.6",
21
+ "@vue-flow/core": "1.14.3",
21
22
  "bootstrap": "^5.3.0",
22
23
  "buffer": "^6.0.3",
23
24
  "humanize-duration": "^3.29.0",
25
+ "js-yaml": "^4.1.0",
24
26
  "lodash": "^4.17.21",
25
27
  "moment": "^2.29.4",
26
- "sass": "^1.64.0",
27
- "vite": "^4.4.9",
28
28
  "vue": "^3.3.4",
29
- "vue-material-design-icons": "^5.2.0"
29
+ "vue-material-design-icons": "^5.2.0",
30
+ "vuex": "^4.1.0",
31
+ "yaml": "^2.3.1",
32
+ "vue3-popper": "^1.5.0"
30
33
  },
31
34
  "devDependencies": {
35
+ "@vitejs/plugin-vue": "^4.2.3",
32
36
  "eslint": "^8.46.0",
33
37
  "eslint-plugin-vue": "^9.17.0",
34
38
  "npm": "^9.8.1",
39
+ "sass": "^1.64.0",
40
+ "vite": "^4.4.9",
35
41
  "vite-plugin-static-copy": "^0.17.0"
36
42
  }
37
43
  }
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <g clip-path="url(#clip0_796_3996)">
4
+ <path d="M13.367 1.979C13.7368 1.979 14.0366 2.27881 14.0366 2.64863V13.3626C14.0366 13.7324 13.7368 14.0322 13.367 14.0322H2.65302C2.2832 14.0322 1.9834 13.7324 1.9834 13.3626V2.64863C1.9834 2.27881 2.2832 1.979 2.65302 1.979H13.367ZM7.34039 3.31825H3.32265V12.693H7.34039V10.0145H8.67963V12.693H12.6974V3.31825H8.67963V5.99675H7.34039V3.31825ZM10.0189 5.99675L12.0278 8.00562L10.0189 10.0145V8.67524H6.00114V10.0145L3.99227 8.00562L6.00114 5.99675V7.33599H10.0189V5.99675Z" fill="#CAC5DA" />
5
+ </g>
6
+ <defs>
7
+ <clipPath id="clip0_796_3996">
8
+ <rect width="16" height="16" fill="white" />
9
+ </clipPath>
10
+ </defs>
11
+ </svg>
12
+ </template>
13
+
14
+ <script>
15
+ export default {
16
+ name: "SplitCellsHorizontalIcon",
17
+ emits: ["click"]
18
+ }
19
+ </script>
20
+ <style scoped>
21
+ svg {
22
+ transform: scale(1.5);
23
+ }
24
+ </style>
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <g clip-path="url(#clip0_1111_7266)">
4
+ <path d="M1.97852 2.63349C1.97852 2.26366 2.27832 1.96387 2.64814 1.96387L13.3621 1.96387C13.7319 1.96387 14.0317 2.26366 14.0317 2.63349L14.0317 13.3475C14.0317 13.7173 13.7319 14.0171 13.3621 14.0171L2.64814 14.0171C2.27832 14.0171 1.97852 13.7173 1.97852 13.3475L1.97852 2.63349ZM3.31776 8.6601L3.31776 12.6778L12.6925 12.6778L12.6925 8.6601L10.014 8.6601L10.014 7.32085L12.6925 7.32085L12.6925 3.30311L3.31776 3.30311L3.31776 7.32086L5.99626 7.32085L5.99626 8.6601L3.31776 8.6601ZM5.99626 5.98161L8.00513 3.97274L10.014 5.98161L8.67475 5.98161L8.67475 9.99935L10.014 9.99935L8.00513 12.0082L5.99626 9.99935L7.3355 9.99935L7.3355 5.98161L5.99626 5.98161Z" fill="#CAC5DA" />
5
+ </g>
6
+ <defs>
7
+ <clipPath id="clip0_1111_7266">
8
+ <rect width="16" height="16" fill="white" transform="translate(0 16) rotate(-90)" />
9
+ </clipPath>
10
+ </defs>
11
+ </svg>
12
+ </template>
13
+
14
+ <script>
15
+ export default {
16
+ name: "SplitCellsVerticalIcon",
17
+ emits: ["click"]
18
+ }
19
+ </script>
20
+ <style scoped>
21
+ svg {
22
+ transform: scale(1.5);
23
+ }
24
+ </style>
@@ -8,6 +8,9 @@ import BasicNode from "./nodes/BasicNode.vue";
8
8
  import CollapsedClusterNode from "./nodes/CollapsedClusterNode.vue";
9
9
  import DependenciesNode from "./nodes/DependenciesNode.vue"
10
10
 
11
+ // Topology Component
12
+ import Topology from "./topology/Topology.vue";
13
+
11
14
  // misc
12
15
  import ExecutionInformations from "./misc/ExecutionInformations.vue";
13
16
  import State from "./misc/State.vue";
@@ -17,5 +20,6 @@ import TaskIcon from "./misc/TaskIcon.vue";
17
20
  import AddTaskButton from "./buttons/AddTaskButton.vue";
18
21
 
19
22
  export {ClusterNode, DotNode, EdgeNode, TaskNode, TriggerNode, BasicNode, CollapsedClusterNode, DependenciesNode};
23
+ export {Topology}
20
24
  export {ExecutionInformations, State, TaskIcon};
21
25
  export {AddTaskButton};
@@ -5,8 +5,6 @@
5
5
  </div>
6
6
  </template>
7
7
  <script>
8
- import Delete from "vue-material-design-icons/Delete.vue";
9
- import Pencil from "vue-material-design-icons/Pencil.vue";
10
8
  import {EVENTS} from "../../utils/constants"
11
9
  import moment from "moment";
12
10
  import Duration from "./Duration.vue";
@@ -85,6 +83,10 @@
85
83
  execution: {
86
84
  type: Object,
87
85
  default: null
86
+ },
87
+ task: {
88
+ type: Object,
89
+ default: null
88
90
  }
89
91
  }
90
92
 
@@ -100,7 +102,6 @@
100
102
  left: 0;
101
103
  top: 50%;
102
104
  height: 50%;
103
- border-left: 1px solid var(--bs-gray-100);
104
105
  transform: translateY(-50%);
105
106
  z-index: 500;
106
107
  }
@@ -2,18 +2,27 @@
2
2
  <div
3
3
  :class="[color ? `bg-${color}`: '']"
4
4
  class="div-icon rounded d-flex justify-content-center"
5
+ data-bs-toggle="tooltip"
6
+ data-bs-placement="top"
7
+ :title="cls"
5
8
  >
6
9
  <img :src="backgroundImage" alt="task icon">
7
10
  </div>
8
11
  </template>
9
12
  <script>
13
+ import {mapState} from "vuex";
10
14
  import {Buffer} from "buffer";
15
+ import {Tooltip} from "bootstrap";
11
16
 
12
17
  export default {
13
18
  name: "TaskIcon",
14
19
  props: {
15
- icon: {
16
- type: Object,
20
+ customIcon: {
21
+ type: String,
22
+ default: undefined
23
+ },
24
+ cls: {
25
+ type: String,
17
26
  default: undefined
18
27
  },
19
28
  color: {
@@ -21,7 +30,24 @@
21
30
  default: undefined
22
31
  }
23
32
  },
33
+ mounted(){
34
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"));
35
+ this.tooltips = tooltipTriggerList.map(function (tooltipTriggerEl) {
36
+ return new Tooltip(tooltipTriggerEl, {
37
+ trigger : "hover"
38
+ })
39
+ })
40
+ },
41
+ beforeUnmount() {
42
+ document.querySelectorAll("[data-bs-toggle=\"tooltip\"]").forEach((el) => {
43
+ const tooltip = Tooltip.getInstance(el);
44
+ if (tooltip) {
45
+ tooltip.dispose();
46
+ }
47
+ });
48
+ },
24
49
  computed: {
50
+ ...mapState("plugin", ["icons"]),
25
51
  backgroundImage() {
26
52
  return `data:image/svg+xml;base64,${this.imageBase64}`
27
53
  },
@@ -35,6 +61,9 @@
35
61
  "<path d=\"M288 32H0v448h384V128l-96-96zm64 416H32V64h224l96 96v288z\" fill=\"#0D1523FF\"/>" +
36
62
  "</svg>", "utf8").toString("base64");
37
63
  },
64
+ icon() {
65
+ return this.cls ? (this.icons || {})[this.cls] : this.customIcon;
66
+ }
38
67
  }
39
68
  }
40
69
  </script>
@@ -47,4 +76,4 @@
47
76
  background-color: var(--bs-white);
48
77
  border: 0.4px solid var(--bs-border-color);
49
78
  }
50
- </style>
79
+ </style>
@@ -5,42 +5,60 @@
5
5
  @mouseover="mouseover"
6
6
  @mouseleave="mouseleave"
7
7
  >
8
- <div v-if="state" class="status-div" :class="[`bg-${stateColor}`]" />
8
+ <div v-if="state" class="status-div" :class="[`bg-${stateColor}`]"/>
9
9
  <div>
10
- <TaskIcon :icon="data.icon" :class="taskIconBg" />
10
+ <TaskIcon :icon="data.icon" :cls="cls" :class="taskIconBg"/>
11
11
  </div>
12
12
  <div class="node-content">
13
13
  <div class="d-flex justify-content-around">
14
- <div class="text-truncate task-title">
14
+ <div
15
+ class="text-truncate task-title"
16
+ data-bs-toggle="tooltip"
17
+ data-bs-placement="top"
18
+ :title="id"
19
+ >
15
20
  <span> {{ id }} </span>
16
21
  </div>
17
- <InformationOutline
18
- v-if="description"
19
- @click="$emit(EVENTS.SHOW_DESCRIPTION, {id: id, description:description})"
20
- class="description-button mx-2"
21
- />
22
+ <span
23
+ class="d-flex"
24
+ data-bs-toggle="tooltip"
25
+ data-bs-placement="top"
26
+ :title="$t('show description')"
27
+ >
28
+ <InformationOutline
29
+ v-if="description"
30
+ @click="$emit(EVENTS.SHOW_DESCRIPTION, {id: id, description:description})"
31
+ class="description-button mx-2"
32
+ />
33
+ </span>
22
34
  </div>
23
- <slot name="content" />
35
+ <slot name="content"/>
24
36
  </div>
25
37
  <div class="position-absolute top-0 text-white d-flex top-button-div">
26
- <slot name="badge-button-before" />
38
+ <slot name="badge-button-before"/>
27
39
  <span
28
40
  v-if="link"
29
41
  class="rounded-button"
30
42
  :class="[`bg-${data.color}`]"
31
- @click="$emit(EVENTS.OPEN_LINK, data)"
43
+ @click="$emit(EVENTS.OPEN_LINK, linkData)"
44
+ data-bs-toggle="tooltip"
45
+ data-bs-placement="top"
46
+ :title="$t('open')"
32
47
  >
33
- <OpenInNew class="button-icon" alt="Open in new tab" />
48
+ <OpenInNew class="button-icon" alt="Open in new tab"/>
34
49
  </span>
35
50
  <span
36
51
  v-if="expandable"
37
52
  class="rounded-button"
38
53
  :class="[`bg-${data.color}`]"
39
54
  @click="$emit(EVENTS.EXPAND)"
55
+ data-bs-toggle="tooltip"
56
+ data-bs-placement="top"
57
+ :title="$t('expand')"
40
58
  >
41
- <ArrowExpand class="button-icon" alt="Expand task" />
59
+ <ArrowExpand class="button-icon" alt="Expand task"/>
42
60
  </span>
43
- <slot name="badge-button-after" />
61
+ <slot name="badge-button-after"/>
44
62
  </div>
45
63
  </div>
46
64
  </template>
@@ -51,6 +69,9 @@
51
69
  import {EVENTS} from "../../utils/constants.js";
52
70
  import ArrowExpand from "vue-material-design-icons/ArrowExpand.vue";
53
71
  import OpenInNew from "vue-material-design-icons/OpenInNew.vue";
72
+ import {Tooltip} from "bootstrap";
73
+ import {VueFlowUtils} from "../../index.js";
74
+ import {mapState} from "vuex";
54
75
 
55
76
  export default {
56
77
  components: {
@@ -59,6 +80,22 @@
59
80
  InformationOutline,
60
81
  OpenInNew
61
82
  },
83
+ mounted() {
84
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"));
85
+ this.tooltips = tooltipTriggerList.map(function (tooltipTriggerEl) {
86
+ return new Tooltip(tooltipTriggerEl, {
87
+ trigger: "hover"
88
+ })
89
+ })
90
+ },
91
+ beforeUnmount() {
92
+ document.querySelectorAll("[data-bs-toggle=\"tooltip\"]").forEach((el) => {
93
+ const tooltip = Tooltip.getInstance(el);
94
+ if (tooltip) {
95
+ tooltip.dispose();
96
+ }
97
+ });
98
+ },
62
99
  emits: [
63
100
  EVENTS.EXPAND,
64
101
  EVENTS.OPEN_LINK,
@@ -113,6 +150,7 @@
113
150
  };
114
151
  },
115
152
  computed: {
153
+ ...mapState("execution", ["execution"]),
116
154
  EVENTS() {
117
155
  return EVENTS
118
156
  },
@@ -134,25 +172,32 @@
134
172
  },
135
173
  stateColor() {
136
174
  switch (this.state) {
137
- case "RUNNING":
138
- return "primary"
139
- case "SUCCESS":
140
- return "success"
141
- case "WARNING":
142
- return "warning"
143
- case "FAILED":
144
- return "danger"
145
- default:
146
- return null;
175
+ case "RUNNING":
176
+ return "primary"
177
+ case "SUCCESS":
178
+ return "success"
179
+ case "WARNING":
180
+ return "warning"
181
+ case "FAILED":
182
+ return "danger"
183
+ default:
184
+ return null;
185
+ }
186
+ },
187
+ linkData() {
188
+ if(this.data.node.task) {
189
+ return {link: VueFlowUtils.linkDatas(this.data.node.task, this.execution)}
147
190
  }
191
+ return null
192
+ },
193
+ cls() {
194
+ return this.data.node?.task ? this.data.node.task.type : this.data.node?.trigger ? this.data.node.trigger.type : null
148
195
  }
149
196
  },
150
197
  }
151
198
  </script>
152
199
 
153
200
  <style lang="scss" scoped>
154
- @import "../../scss/custom";
155
-
156
201
  .node-wrapper {
157
202
  background-color: var(--bs-white);
158
203
 
@@ -178,7 +223,7 @@
178
223
  }
179
224
 
180
225
  .description-button {
181
- color: $gray-600;
226
+ color: var(--bs-gray-600);
182
227
  cursor: pointer;
183
228
  width: 25px;
184
229
  }
@@ -223,4 +268,4 @@
223
268
  left: -0.04438rem;
224
269
  border-radius: 0.5rem 0 0 0.5rem;
225
270
  }
226
- </style>
271
+ </style>
@@ -6,8 +6,11 @@
6
6
  class="rounded-button"
7
7
  :class="[`bg-${data.color}`]"
8
8
  @click="collapse()"
9
+ data-bs-toggle="tooltip"
10
+ data-bs-trigger="hover"
11
+ :title="$t('collapse')"
9
12
  >
10
- <ArrowCollapse class="button-icon" alt="Collapse task" />
13
+ <ArrowCollapse class="button-icon" alt="Collapse task"/>
11
14
  </span>
12
15
  </div>
13
16
  </template>
@@ -24,8 +27,31 @@
24
27
 
25
28
  </script>
26
29
  <script>
30
+ import {Tooltip} from "bootstrap";
31
+
27
32
  export default {
28
33
  inheritAttrs: false,
34
+ data() {
35
+ return {
36
+ tooltips: [],
37
+ }
38
+ },
39
+ mounted() {
40
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"));
41
+ this.tooltips = tooltipTriggerList.map(function (tooltipTriggerEl) {
42
+ return new Tooltip(tooltipTriggerEl, {
43
+ placement: "top"
44
+ })
45
+ })
46
+ },
47
+ beforeUnmount() {
48
+ document.querySelectorAll("[data-bs-toggle=\"tooltip\"]").forEach((el) => {
49
+ const tooltip = Tooltip.getInstance(el);
50
+ if (tooltip) {
51
+ tooltip.dispose();
52
+ }
53
+ });
54
+ }
29
55
  }
30
56
  </script>
31
57
  <style scoped lang="scss">
@@ -50,4 +76,4 @@
50
76
  padding: 0.25rem 0.5rem;
51
77
  }
52
78
 
53
- </style>
79
+ </style>
@@ -4,12 +4,22 @@
4
4
  :class="[`border-${data.color}`]"
5
5
  class="dependency-node-wrapper rounded-3 border"
6
6
  >
7
- <TaskIcon color="pink" :icon="{icon: icon}" />
7
+ <TaskIcon color="pink" :custom-icon="{icon: icon}" />
8
8
  <div class="dependency-text d-flex flex-column">
9
- <div class="dependency-flow-text">
9
+ <div
10
+ class="dependency-flow-text text-truncate"
11
+ data-bs-toggle="tooltip"
12
+ data-bs-placement="top"
13
+ :title="data.flowId"
14
+ >
10
15
  {{ data.flowId }}
11
16
  </div>
12
- <div class="dependency-namespace-text">
17
+ <div
18
+ class="dependency-namespace-text text-truncate"
19
+ data-bs-toggle="tooltip"
20
+ data-bs-placement="top"
21
+ :title="data.namespace"
22
+ >
13
23
  {{ data.namespace }}
14
24
  </div>
15
25
  </div>
@@ -21,6 +31,9 @@
21
31
  class="rounded-button"
22
32
  :class="[`bg-${data.color}`]"
23
33
  @click="$emit(EVENTS.OPEN_LINK, data)"
34
+ data-bs-toggle="tooltip"
35
+ data-bs-placement="top"
36
+ :title="$t('open')"
24
37
  >
25
38
  <OpenInNew class="button-icon" alt="Open in new tab" />
26
39
  </span>
@@ -28,6 +41,9 @@
28
41
  class="rounded-button"
29
42
  :class="[`bg-${data.color}`]"
30
43
  @click="$emit(EVENTS.EXPAND_DEPENDENCIES, data)"
44
+ data-bs-toggle="tooltip"
45
+ data-bs-placement="top"
46
+ :title="$t('expand')"
31
47
  >
32
48
  <ArrowExpandAll class="button-icon" alt="Expand task" />
33
49
  </span>
@@ -44,6 +60,7 @@
44
60
  import OpenInNew from "vue-material-design-icons/OpenInNew.vue";
45
61
  import ArrowExpandAll from "vue-material-design-icons/ArrowExpandAll.vue";
46
62
  import {EVENTS} from "../../utils/constants.js";
63
+ import {Tooltip} from "bootstrap";
47
64
 
48
65
  export default {
49
66
  name: "Dependencies",
@@ -55,6 +72,22 @@
55
72
  EVENTS.MOUSE_OVER,
56
73
  EVENTS.MOUSE_LEAVE,
57
74
  ],
75
+ mounted() {
76
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"));
77
+ this.tooltips = tooltipTriggerList.map(function (tooltipTriggerEl) {
78
+ return new Tooltip(tooltipTriggerEl, {
79
+ trigger: "hover"
80
+ })
81
+ })
82
+ },
83
+ beforeUnmount() {
84
+ document.querySelectorAll("[data-bs-toggle=\"tooltip\"]").forEach((el) => {
85
+ const tooltip = Tooltip.getInstance(el);
86
+ if (tooltip) {
87
+ tooltip.dispose();
88
+ }
89
+ });
90
+ },
58
91
  computed: {
59
92
  EVENTS() {
60
93
  return EVENTS
@@ -87,7 +120,6 @@
87
120
  </script>
88
121
 
89
122
  <style scoped lang="scss">
90
-
91
123
  .dependency-node-wrapper {
92
124
  background-color: var(--bs-white);
93
125
  color: var(--bs-black);
@@ -113,16 +145,18 @@
113
145
  .dependency-flow-text {
114
146
  font-size: 0.85rem;
115
147
  font-weight: 700;
148
+ max-width: 121px;
116
149
  }
117
150
 
118
151
  .dependency-namespace-text {
119
152
  font-size: 0.625rem;
120
153
  font-weight: 400;
121
154
  color: #564A75;
155
+ max-width: 121px;
122
156
 
123
157
  html.dark & {
124
158
  color: #E3DBFF;
125
159
  }
126
160
  }
127
161
 
128
- </style>
162
+ </style>
@@ -37,10 +37,11 @@
37
37
  .custom-handle {
38
38
  visibility: hidden
39
39
  }
40
+
40
41
  .dot {
41
42
  display: flex;
42
43
  flex-direction: column;
43
44
  align-items: center;
44
45
  font-size: 5px;
45
46
  }
46
- </style>
47
+ </style>
@@ -3,8 +3,14 @@
3
3
  import {EdgeLabelRenderer, getSmoothStepPath} from "@vue-flow/core";
4
4
  import AddTaskButton from "../buttons/AddTaskButton.vue";
5
5
  import {EVENTS} from "../../utils/constants.js";
6
+ import {Tooltip} from "bootstrap";
6
7
 
7
8
  export default {
9
+ data() {
10
+ return {
11
+ tooltips: [],
12
+ }
13
+ },
8
14
  props: {
9
15
  id: String,
10
16
  data: Object,
@@ -32,6 +38,22 @@
32
38
  path,
33
39
  };
34
40
  },
41
+ mounted(){
42
+ const tooltipTriggerList = [].slice.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"));
43
+ this.tooltips = tooltipTriggerList.map(function (tooltipTriggerEl) {
44
+ return new Tooltip(tooltipTriggerEl, {
45
+ trigger : "hover"
46
+ })
47
+ })
48
+ },
49
+ beforeUnmount() {
50
+ document.querySelectorAll("[data-bs-toggle=\"tooltip\"]").forEach((el) => {
51
+ const tooltip = Tooltip.getInstance(el);
52
+ if (tooltip) {
53
+ tooltip.dispose();
54
+ }
55
+ });
56
+ },
35
57
  inheritAttrs: false,
36
58
  };
37
59
  </script>
@@ -61,6 +83,9 @@
61
83
  v-if="!data.disabled && data.haveAdd != undefined"
62
84
  :add-task="true"
63
85
  @click="$emit(EVENTS.ADD_TASK, data.haveAdd)"
86
+ data-bs-toggle="tooltip"
87
+ data-bs-placement="top"
88
+ :title="$t('add task')"
64
89
  />
65
90
  </div>
66
91
  </EdgeLabelRenderer>