@kestra-io/ui-libs 0.0.263 → 0.0.264

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.
Files changed (82) hide show
  1. package/dist/{VueFlowUtils-D6fVYEkI.js → VueFlowUtils-DifPO0kH.js} +1229 -1261
  2. package/dist/VueFlowUtils-DifPO0kH.js.map +1 -0
  3. package/dist/VueFlowUtils-DjetWQIy.cjs +2 -0
  4. package/dist/VueFlowUtils-DjetWQIy.cjs.map +1 -0
  5. package/dist/components/index.d.ts +4 -0
  6. package/dist/components/index.d.ts.map +1 -1
  7. package/dist/components/misc/Collapsible.vue.d.ts.map +1 -1
  8. package/dist/components/misc/ElementCard.vue.d.ts +25 -0
  9. package/dist/components/misc/ElementCard.vue.d.ts.map +1 -0
  10. package/dist/components/misc/Status.vue.d.ts.map +1 -1
  11. package/dist/components/misc/SubgroupCard.vue.d.ts +20 -0
  12. package/dist/components/misc/SubgroupCard.vue.d.ts.map +1 -0
  13. package/dist/components/nodes/EdgeNode.vue.d.ts.map +1 -1
  14. package/dist/components/plugins/CollapsibleProperties.vue.d.ts.map +1 -1
  15. package/dist/components/plugins/PluginIndex.vue.d.ts +13 -3
  16. package/dist/components/plugins/PluginIndex.vue.d.ts.map +1 -1
  17. package/dist/components/plugins/PropertyDetail.vue.d.ts.map +1 -1
  18. package/dist/components/plugins/SchemaToHtml.vue.d.ts.map +1 -1
  19. package/dist/components/plugins_v2/CollapsiblePropertiesV2.vue.d.ts +39 -0
  20. package/dist/components/plugins_v2/CollapsiblePropertiesV2.vue.d.ts.map +1 -0
  21. package/dist/components/plugins_v2/CollapsibleV2.vue.d.ts +34 -0
  22. package/dist/components/plugins_v2/CollapsibleV2.vue.d.ts.map +1 -0
  23. package/dist/components/plugins_v2/DefinitionCollapsible.vue.d.ts +34 -0
  24. package/dist/components/plugins_v2/DefinitionCollapsible.vue.d.ts.map +1 -0
  25. package/dist/components/plugins_v2/PropertyBadges.vue.d.ts +13 -0
  26. package/dist/components/plugins_v2/PropertyBadges.vue.d.ts.map +1 -0
  27. package/dist/components/plugins_v2/PropertyDetailV2.vue.d.ts +43 -0
  28. package/dist/components/plugins_v2/PropertyDetailV2.vue.d.ts.map +1 -0
  29. package/dist/components/plugins_v2/PropertyMeta.vue.d.ts +10 -0
  30. package/dist/components/plugins_v2/PropertyMeta.vue.d.ts.map +1 -0
  31. package/dist/components/plugins_v2/SchemaToHtmlV2.vue.d.ts +50 -0
  32. package/dist/components/plugins_v2/SchemaToHtmlV2.vue.d.ts.map +1 -0
  33. package/dist/components/topology/Topology.vue.d.ts +1 -1
  34. package/dist/composables/usePluginElementCounts.d.ts +13 -0
  35. package/dist/composables/usePluginElementCounts.d.ts.map +1 -0
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/kestra-index.cjs.js +15 -13
  39. package/dist/kestra-index.cjs.js.map +1 -1
  40. package/dist/kestra-index.es.js +4862 -4017
  41. package/dist/kestra-index.es.js.map +1 -1
  42. package/dist/kestra-vueflowutils.cjs.js +1 -1
  43. package/dist/kestra-vueflowutils.es.js +10 -10
  44. package/dist/ui-libs.css +1 -1
  45. package/dist/utils/Utils.d.ts +2 -0
  46. package/dist/utils/Utils.d.ts.map +1 -1
  47. package/dist/utils/VueFlowUtils.d.ts.map +1 -1
  48. package/dist/utils/constants.d.ts +0 -39
  49. package/dist/utils/constants.d.ts.map +1 -1
  50. package/dist/utils/plugins.d.ts +30 -0
  51. package/dist/utils/plugins.d.ts.map +1 -1
  52. package/dist/utils/schemaUtils.d.ts +6 -0
  53. package/dist/utils/schemaUtils.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/src/components/index.ts +4 -0
  56. package/src/components/misc/Collapsible.vue +7 -1
  57. package/src/components/misc/ElementCard.vue +132 -0
  58. package/src/components/misc/Status.vue +0 -1
  59. package/src/components/misc/SubgroupCard.vue +178 -0
  60. package/src/components/nodes/EdgeNode.vue +17 -1
  61. package/src/components/plugins/CollapsibleProperties.vue +2 -13
  62. package/src/components/plugins/PluginIndex.vue +166 -37
  63. package/src/components/plugins/PropertyDetail.vue +5 -5
  64. package/src/components/plugins/SchemaToHtml.vue +7 -3
  65. package/src/components/plugins_v2/CollapsiblePropertiesV2.vue +183 -0
  66. package/src/components/plugins_v2/CollapsibleV2.vue +121 -0
  67. package/src/components/plugins_v2/DefinitionCollapsible.vue +208 -0
  68. package/src/components/plugins_v2/PropertyBadges.vue +93 -0
  69. package/src/components/plugins_v2/PropertyDetailV2.vue +127 -0
  70. package/src/components/plugins_v2/PropertyMeta.vue +169 -0
  71. package/src/components/plugins_v2/SchemaToHtmlV2.vue +213 -0
  72. package/src/composables/usePluginElementCounts.ts +16 -0
  73. package/src/index.ts +2 -1
  74. package/src/scss/_variables.scss +69 -0
  75. package/src/utils/Utils.ts +5 -0
  76. package/src/utils/VueFlowUtils.ts +10 -2
  77. package/src/utils/constants.ts +0 -45
  78. package/src/utils/plugins.ts +76 -1
  79. package/src/utils/schemaUtils.ts +45 -1
  80. package/dist/VueFlowUtils-CF-L3pYu.cjs +0 -2
  81. package/dist/VueFlowUtils-CF-L3pYu.cjs.map +0 -1
  82. package/dist/VueFlowUtils-D6fVYEkI.js.map +0 -1
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <div class="property-detail">
3
+ <PropertyMeta :property="property" :subtype="subtype" :enum-values="enumValues" />
4
+
5
+ <div v-if="property.title !== undefined || property.description !== undefined || (depth < maxDepth && referencedDefinitions.length > 0)">
6
+ <div class="property-description markdown">
7
+ <slot v-if="property.title !== undefined" :content="codeSanitizer(property.title)" name="markdown" />
8
+ <slot v-if="property.description !== undefined" :content="codeSanitizer(property.description)" name="markdown" />
9
+ <div v-if="property['$internalStorageURI']">
10
+ <Alert type="info">
11
+ <slot content="Pebble expression referencing an Internal Storage URI e.g. `{{ outputs.mytask.uri }}`." name="markdown" />
12
+ </Alert>
13
+ </div>
14
+
15
+ <div v-if="depth < maxDepth && referencedDefinitions.length > 0" class="mt-3">
16
+ <div class="definitions-header">
17
+ Definitions
18
+ </div>
19
+ <DefinitionCollapsible
20
+ v-for="def in referencedDefinitions"
21
+ :key="`${def.key}-${depth}`"
22
+ :definition="def"
23
+ :definitions="definitions"
24
+ :visited-keys="visitedKeysWithCurrent"
25
+ :depth="depth + 1"
26
+ :max-depth="maxDepth"
27
+ :section="section"
28
+ >
29
+ <template #markdown="{content}">
30
+ <slot :content="content" name="markdown" />
31
+ </template>
32
+ </DefinitionCollapsible>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </template>
38
+
39
+ <script setup lang="ts">
40
+ import {extractEnumValues, extractTypeInfo, extractReferencedDefinitions, type JSONProperty, type JSONSchema} from "../../utils/schemaUtils.ts";
41
+ import {sanitizeForMarkdown} from "../../utils/Utils";
42
+ import {computed} from "vue";
43
+ import Alert from "../content/Alert.vue";
44
+ import PropertyMeta from "./PropertyMeta.vue";
45
+ import DefinitionCollapsible from "./DefinitionCollapsible.vue";
46
+
47
+ const props = withDefaults(defineProps<{
48
+ property: JSONProperty,
49
+ definitions?: Record<string, JSONSchema>,
50
+ visitedKeys?: Set<string>,
51
+ depth?: number,
52
+ maxDepth?: number,
53
+ section?: string
54
+ }>(), {
55
+ definitions: undefined,
56
+ visitedKeys: () => new Set<string>(),
57
+ depth: 0,
58
+ maxDepth: 3,
59
+ section: "properties"
60
+ });
61
+
62
+ const subtype = computed(() => extractTypeInfo(props.property).subType);
63
+ const enumValues = computed(() => extractEnumValues(props.property));
64
+
65
+ const referencedDefinitions = computed(() => {
66
+ const defs = props.definitions;
67
+ const d = props.depth;
68
+ const max = props.maxDepth;
69
+ const prop = props.property;
70
+ const visited = props.visitedKeys;
71
+
72
+ if (!defs || d >= max) return [];
73
+ return extractReferencedDefinitions(prop, defs, visited);
74
+ });
75
+
76
+ const visitedKeysWithCurrent = computed(() => {
77
+ const newSet = new Set(props.visitedKeys);
78
+ referencedDefinitions.value.forEach(def => newSet.add(def.key));
79
+ return newSet;
80
+ });
81
+
82
+ const codeSanitizer = sanitizeForMarkdown;
83
+ </script>
84
+
85
+ <style lang="scss" scoped>
86
+ @use "../../scss/color-palette" as color-palette;
87
+
88
+ .property-detail > * {
89
+ display: flex;
90
+ justify-content: space-between;
91
+ border-top: 1px solid var(--ks-border-primary);
92
+ align-items: center;
93
+ padding: 1rem 0;
94
+ margin: 0;
95
+ gap: var(--spacer);
96
+
97
+ span, .property-description:deep(p) {
98
+ line-height: 1.5rem;
99
+ font-size: .875rem !important;
100
+ }
101
+
102
+ code {
103
+ color: var(--ks-content-primary);
104
+ background: var(--ks-background-body);
105
+ }
106
+
107
+ .border-red {
108
+ border-color: color-palette.$base-red-400 !important;
109
+ }
110
+
111
+ &:first-child {
112
+ border-top: none !important;
113
+ }
114
+
115
+ > * {
116
+ width: fit-content;
117
+ }
118
+ }
119
+
120
+ .definitions-header {
121
+ font-weight: 600;
122
+ font-size: 0.875rem;
123
+ margin-bottom: 0.75rem;
124
+ color: var(--ks-content-primary);
125
+ }
126
+
127
+ </style>
@@ -0,0 +1,169 @@
1
+ <template>
2
+ <div v-if="subtype && !subtype.startsWith('#')">
3
+ <span>SubType</span>
4
+ <span class="type-box rounded fs-7 px-2 py-1">{{ subtype }}</span>
5
+ </div>
6
+
7
+ <div v-if="property.default !== undefined">
8
+ <span>Default</span>
9
+ <code class="border rounded px-2 py-1">{{ property.default }}</code>
10
+ </div>
11
+
12
+ <div v-if="property.pattern !== undefined">
13
+ <span>Validation RegExp</span>
14
+ <code class="border rounded px-2 py-1">{{ property.pattern }}</code>
15
+ </div>
16
+
17
+ <div v-if="property.unit !== undefined && property.unit.trim().length > 0">
18
+ <span>Unit</span>
19
+ <code class="border rounded px-2 py-1">{{ property.unit }}</code>
20
+ </div>
21
+
22
+ <div v-if="property.minLength !== undefined">
23
+ <span>Min length</span>
24
+ <code class="border rounded px-2 py-1">{{ property.minLength }}</code>
25
+ </div>
26
+
27
+ <div v-if="property.maxLength !== undefined">
28
+ <span>Max length</span>
29
+ <code class="border rounded px-2 py-1">{{ property.maxLength }}</code>
30
+ </div>
31
+
32
+ <div v-if="property.minItems !== undefined">
33
+ <span>Min items</span>
34
+ <code class="border rounded px-2 py-1">{{ property.minItems }}</code>
35
+ </div>
36
+
37
+ <div v-if="property.maxItems !== undefined">
38
+ <span>Max items</span>
39
+ <code class="border rounded px-2 py-1">{{ property.maxItems }}</code>
40
+ </div>
41
+
42
+ <div v-if="property.minimum !== undefined">
43
+ <span>Minimum</span>
44
+ <code class="border rounded px-2 py-1">&gt;= {{ property.minimum }}</code>
45
+ </div>
46
+
47
+ <div v-if="property.exclusiveMinimum !== undefined">
48
+ <span>Minimum</span>
49
+ <code class="border rounded px-2 py-1">&gt; {{ property.minimum }}</code>
50
+ </div>
51
+
52
+ <div v-if="property.maximum !== undefined">
53
+ <span>Maximum</span>
54
+ <code class="border rounded px-2 py-1">&lt;= {{ property.maximum }}</code>
55
+ </div>
56
+
57
+ <div v-if="property.exclusiveMaximum !== undefined">
58
+ <span>Maximum</span>
59
+ <code class="border rounded px-2 py-1">&lt; {{ property.maximum }}</code>
60
+ </div>
61
+
62
+ <div v-if="property.format !== undefined">
63
+ <span>Format</span>
64
+ <code class="border rounded px-2 py-1">{{ property.format }}</code>
65
+ </div>
66
+
67
+ <div v-if="enumValues !== undefined">
68
+ <span>Possible Values</span>
69
+ <div class="values-wrapper d-flex flex-wrap justify-content-end gap-7 p-0">
70
+ <code v-for="(possibleValue, index) in enumValues" class="border rounded px-2 py-1" :key="index">
71
+ {{ possibleValue }}
72
+ </code>
73
+ </div>
74
+ </div>
75
+ </template>
76
+
77
+ <script setup lang="ts">
78
+ import type {JSONProperty} from "../../utils/schemaUtils";
79
+
80
+ defineProps<{
81
+ property: JSONProperty,
82
+ subtype?: string,
83
+ enumValues?: string[]
84
+ }>();
85
+ </script>
86
+
87
+ <style lang="scss" scoped>
88
+ @use "../../scss/color-palette" as color-palette;
89
+
90
+ div {
91
+ display: flex;
92
+ justify-content: space-between;
93
+ align-items: center;
94
+ gap: var(--spacer);
95
+ padding: 9px 0;
96
+ padding-bottom: 0;
97
+
98
+ span {
99
+ line-height: 1.5rem;
100
+ font-size: .875rem !important;
101
+ color: var(--ks-content-secondary) !important;
102
+ }
103
+
104
+ code {
105
+ color: var(--ks-content-primary);
106
+ background: var(--ks-background-body);
107
+ }
108
+
109
+ .border-red {
110
+ border-color: color-palette.$base-red-400 !important;
111
+ }
112
+
113
+ &:first-child {
114
+ border-top: none !important;
115
+ }
116
+
117
+ > * {
118
+ width: fit-content;
119
+ }
120
+ }
121
+
122
+ $section-styles: (
123
+ properties: (
124
+ color: var(--ks-content-running),
125
+ background: var(--ks-background-running),
126
+ border-color: var(--ks-border-running)
127
+ ),
128
+ outputs: (
129
+ color: var(--ks-content-success),
130
+ background: rgba(color-palette.$base-green-900, .2),
131
+ border-color: var(--ks-border-success)
132
+ ),
133
+ metrics: (
134
+ color: var(--ks-content-warning),
135
+ background: var(--ks-background-warning),
136
+ border-color: var(--ks-border-warning)
137
+ )
138
+ );
139
+
140
+ .type-box {
141
+ font-size: 12px !important;
142
+ line-height: 20px;
143
+ padding: 0 10px !important;
144
+ padding-bottom: 2px;
145
+ border-radius: 40px !important;
146
+ text-transform: capitalize;
147
+ border: 1px solid;
148
+ }
149
+
150
+ .values-wrapper {
151
+ display: flex !important;
152
+ justify-content: flex-end !important;
153
+ border: none !important;
154
+ margin: 0 !important;
155
+ padding: 0 !important;
156
+ align-items: unset !important;
157
+ }
158
+
159
+ @each $section, $styles in $section-styles {
160
+ .section-#{$section} {
161
+ .type-box {
162
+ color: map-get($styles, color);
163
+ background: map-get($styles, background) !important;
164
+ border-color: map-get($styles, border-color);
165
+ text-transform: lowercase;
166
+ }
167
+ }
168
+ }
169
+ </style>
@@ -0,0 +1,213 @@
1
+ <template>
2
+ <div class="d-flex flex-column gap-6">
3
+ <div class="d-flex flex-column">
4
+ <div class="alert alert-info mb-2" role="alert" v-if="schema.properties?.$beta">
5
+ <p>
6
+ This plugin is currently in beta. While it is considered safe for use, please be aware that its API
7
+ could change in ways that are not compatible with earlier versions in future releases, or it might
8
+ become unsupported.
9
+ </p>
10
+ </div>
11
+
12
+ <div v-if="schema.properties?.title" class="plugin-title markdown">
13
+ <slot name="markdown" :content="schema.properties.title.replace(/ *:(?![ /])/g, ': ')" />
14
+ </div>
15
+ <div v-if="schema.properties?.description" class="markdown">
16
+ <slot name="markdown" :content="schema.properties.description.replace(/ *:(?![ /])/g, ': ')" />
17
+ </div>
18
+
19
+ <SchemaToCode :highlighter="highlighter" language="yaml" :theme="codeTheme" :code="`type: &quot;${pluginType}&quot;`" :key="pluginType" />
20
+ </div>
21
+
22
+ <div class="d-flex flex-column" :key="pluginType">
23
+ <Collapsible class="plugin-section" v-if="examples" title="Examples" href="examples" :no-url-change>
24
+ <template #content>
25
+ <div class="d-flex flex-column gap-4">
26
+ <template v-for="(example, index) in examples" :key="pluginType + '-' + index">
27
+ <div class="d-flex flex-column">
28
+ <div class="markdown">
29
+ <slot v-if="example.title" :content="example.title.replace(/ *:(?![ /])/g, ': ')" name="markdown" />
30
+ </div>
31
+ <SchemaToCode
32
+ :highlighter="highlighter"
33
+ :language="example.lang ?? 'yaml'"
34
+ :theme="codeTheme"
35
+ :code="generateExampleCode(example)"
36
+ v-if="example.code"
37
+ />
38
+ </div>
39
+ <hr class="w-100 align-self-center" v-if="index < examples.length - 1">
40
+ </template>
41
+ </div>
42
+ </template>
43
+ </Collapsible>
44
+
45
+ <CollapsibleProperties
46
+ v-if="schema.properties?.properties"
47
+ class="plugin-section"
48
+ :properties="schema.properties.properties"
49
+ section-name="Properties"
50
+ href="properties"
51
+ :initially-expanded="propsInitiallyExpanded"
52
+ :force-include="forceIncludeProperties"
53
+ :definitions="schema.definitions"
54
+ :no-url-change
55
+ >
56
+ <template #markdown="{content}">
57
+ <div class="markdown">
58
+ <slot name="markdown" :content="content" />
59
+ </div>
60
+ </template>
61
+ </CollapsibleProperties>
62
+
63
+ <CollapsibleProperties
64
+ v-if="schema.outputs?.properties && Object.keys(schema.outputs.properties).length > 0"
65
+ class="plugin-section"
66
+ :properties="schema.outputs.properties"
67
+ section-name="Outputs"
68
+ href="outputs"
69
+ :show-dynamic="false"
70
+ :definitions="schema.definitions"
71
+ :no-url-change
72
+ >
73
+ <template #markdown="{content}">
74
+ <div class="markdown">
75
+ <slot name="markdown" :content="content" />
76
+ </div>
77
+ </template>
78
+ </CollapsibleProperties>
79
+
80
+ <CollapsibleProperties
81
+ v-if="schema.properties?.$metrics"
82
+ class="plugin-section"
83
+ :properties="metrics"
84
+ section-name="Metrics"
85
+ href="metrics"
86
+ :show-dynamic="false"
87
+ :definitions="schema.definitions"
88
+ :no-url-change
89
+ >
90
+ <template #markdown="{content}">
91
+ <div class="markdown">
92
+ <slot name="markdown" :content="content" />
93
+ </div>
94
+ </template>
95
+ </CollapsibleProperties>
96
+ </div>
97
+ </div>
98
+ </template>
99
+
100
+ <script setup lang="ts">
101
+ import {computed, ref} from "vue";
102
+ import type {HighlighterCore} from "shiki/core";
103
+ import SchemaToCode from "../plugins/SchemaToCode.vue";
104
+ import type {JSONProperty, JSONSchema} from "../../utils/schemaUtils.ts";
105
+ import Collapsible from "./CollapsibleV2.vue";
106
+ import CollapsibleProperties from "./CollapsiblePropertiesV2.vue";
107
+
108
+ const props = withDefaults(defineProps<{
109
+ schema: JSONSchema,
110
+ pluginType: string,
111
+ darkMode?: boolean,
112
+ propsInitiallyExpanded?: boolean,
113
+ forceIncludeProperties?: string[],
114
+ noUrlChange?: boolean
115
+ }>(), {
116
+ darkMode: true,
117
+ propsInitiallyExpanded: false,
118
+ forceIncludeProperties: () => [],
119
+ noUrlChange: false
120
+ });
121
+
122
+ const generateExampleCode = (example: NonNullable<NonNullable<JSONSchema["properties"]>["$examples"]>[number]) => {
123
+ if (!example?.full) {
124
+ const fullCode = `id: "${props.pluginType.split(".").reverse()[0]?.toLowerCase()}"\ntype: "${props.pluginType}"\n`;
125
+ return fullCode.concat(example.code)
126
+ }
127
+
128
+ return example.code
129
+ }
130
+
131
+ const highlighter = ref<HighlighterCore | undefined>();
132
+
133
+ const examples = computed(() => props.schema.properties?.["$examples"]);
134
+
135
+ const metrics = computed(() => Object.fromEntries(
136
+ props.schema.properties?.["$metrics"]?.map(metric => ([metric.name, {...metric, name: undefined}])) as [string, JSONProperty][]
137
+ ));
138
+
139
+ const {getHighlighterCore} = await import("../plugins/shikiToolset");
140
+
141
+ highlighter.value = await getHighlighterCore();
142
+
143
+ const codeTheme = "github-" + (props.darkMode ? "dark" : "light");
144
+ </script>
145
+
146
+ <style scoped lang="scss">
147
+ @use "../../scss/variables" as variables;
148
+ @use "../../scss/color-palette" as color-palette;
149
+
150
+ .plugin-title :deep(p) {
151
+ font-size: 1rem;
152
+ margin: 1rem 0;
153
+ }
154
+
155
+ :deep(.markdown) {
156
+
157
+ pre,
158
+ .code-block {
159
+ margin: 0;
160
+ }
161
+
162
+ >ol,
163
+ >ul,
164
+ >dl {
165
+ margin-top: 0;
166
+ margin-bottom: 0;
167
+ }
168
+ }
169
+
170
+ :deep(.plugin-section) {
171
+ border-bottom: 1px solid variables.$black-3;
172
+ padding: 2rem 0;
173
+
174
+ @media (min-width: 992px) {
175
+ margin-left: -2rem;
176
+ margin-right: -2rem;
177
+ padding: 2rem;
178
+ }
179
+
180
+ &:first-child {
181
+ border-top: 1px solid variables.$black-3;
182
+ }
183
+
184
+ &:last-child {
185
+ border-bottom: none;
186
+ padding-bottom: 0;
187
+ }
188
+
189
+ .material-design-icon > .material-design-icon__svg {
190
+ height: 1.35rem;
191
+ width: 1.35rem;
192
+ }
193
+
194
+ .material-design-icon:not(.text-danger):not(.text-info):not(.text-warning):not(.text-success):not(.text-primary):not(.text-secondary) {
195
+ &,
196
+ & * {
197
+ height: 1.5rem;
198
+ width: 1.5rem;
199
+ bottom: 0;
200
+ color: variables.$black-10 !important;
201
+ }
202
+ }
203
+
204
+ .material-design-icon:not(.property .material-design-icon):not(.text-danger):not(.text-info):not(.text-warning):not(.text-success):not(.text-primary):not(.text-secondary) {
205
+ &,
206
+ & * {
207
+ height: 1.5rem;
208
+ width: 1.5rem;
209
+ color: color-palette.$base-gray-300 !important;
210
+ }
211
+ }
212
+ }
213
+ </style>
@@ -0,0 +1,16 @@
1
+ import {computed, unref, type Ref} from "vue";
2
+ import {extractPluginElements, type Plugin} from "../utils/plugins";
3
+
4
+ /**
5
+ * Composable to compute plugin element counts and groupings.
6
+ * Provides reactive computed values for elements by type and total count.
7
+ * @param plugin - The plugin to analyze.
8
+ * @returns Object with elementsByType (computed) and total (computed) counts.
9
+ */
10
+ export function usePluginElementCounts(plugin: Plugin | Ref<Plugin>) {
11
+ const elementsByType = computed(() => extractPluginElements(unref(plugin)));
12
+
13
+ const total = computed(() => Object.values(elementsByType.value).reduce((sum, arr) => sum + arr.length, 0));
14
+
15
+ return {elementsByType, total} as const;
16
+ }
package/src/index.ts CHANGED
@@ -7,10 +7,11 @@ export {default as getMDCParser} from "./composables/getMDCParser";
7
7
  export * from "./utils/constants";
8
8
  export * from "./utils/url";
9
9
  export * from "./utils/plugins";
10
+ export {usePluginElementCounts} from "./composables/usePluginElementCounts";
10
11
  export {default as RotatingDotsIcon} from "./assets/icons/RotatingDots.vue";
11
12
 
12
13
  export type {YamlElement} from "./utils/YamlUtilsLegacy";
13
- export type {Plugin} from "./utils/plugins";
14
+ export type {Plugin, PluginMetadata, PluginElement} from "./utils/plugins";
14
15
  export type {JSONSchema, JSONProperty} from "./utils/schemaUtils";
15
16
 
16
17
  import "./scss/ks-theme-light.scss";
@@ -38,6 +38,75 @@ $white-3: #B9B9BA;
38
38
  $black-2: #161617;
39
39
  $black-3: #252526;
40
40
 
41
+ $primary-1: #4B0AAA !default;
42
+
43
+ // extended whites
44
+ $white-1: #E1E1E1 !default;
45
+ $white-2: #E5E4F7 !default;
46
+ $white-4: #CCC6D2 !default;
47
+ $white-5: #7C7C7C !default;
48
+ $white-6: #F0F0FF !default;
49
+
50
+ // extended blacks
51
+ $black-1: #070708 !default;
52
+ $black-4: #111113 !default;
53
+ $black-5: #333336 !default;
54
+ $black-6: #3D3D3F !default;
55
+ $black-7: #0D0D0C !default;
56
+ $black-8: #8B8B8D !default;
57
+ $black-9: #1D1D1E !default;
58
+ $black-10: #646465 !default;
59
+
60
+ // greens/blues
61
+ $green-1: #BFE1B0 !default;
62
+ $indigo-1: #1B0229 !default;
63
+
64
+ // extended purples (many small variant tokens used across docs)
65
+ $purple-1: #382369 !default;
66
+ $purple-2: #FBC7F4 !default;
67
+ $purple-3: #9580EE !default;
68
+ $purple-4: linear-gradient(160.34deg, rgba(130, 0, 255, 0.12) 5.3%, rgba(130, 0, 255, 0) 75.43%), #201838 !default;
69
+ $purple-5: #362762 !default;
70
+ $purple-6: #6113BC !default;
71
+ $purple-7: #1A1223 !default;
72
+ $purple-8: #EEEDFF !default;
73
+ $purple-10: #150E1C !default;
74
+ $purple-11: #332C3B !default;
75
+ $purple-12: #432A71 !default;
76
+ $purple-13: #e5e4f7 !default;
77
+ $purple-14: #8e20f9 !default;
78
+ $purple-15: #9237fb !default;
79
+ $purple-16: #281A35 !default;
80
+ $purple-17: #F5F5FF !default;
81
+ $purple-18: #7E719F !default;
82
+ $purple-19: conic-gradient(from 90deg at 50% 50%, #BE79FF 0deg, #7136F6 360deg) !default;
83
+ $purple-20: #291E39 !default;
84
+ $purple-21: #A42DCD !default;
85
+ $purple-22: #FCF7FE !default;
86
+ $purple-23: #EDE8F3 !default;
87
+ $purple-24: #15023F !default;
88
+ $purple-26: #DCCDEB !default;
89
+ $purple-27: #8200FF !default;
90
+ $purple-28: #2D313E !default;
91
+ $purple-29: #F1F5FF !default;
92
+ $purple-31: #2A1940 !default;
93
+ $purple-32: #CFCEFF !default;
94
+ $purple-33: #110221 !default;
95
+ $purple-34: #10051F !default;
96
+ $purple-35: #736BCD !default;
97
+ $purple-37: #A396FF !default;
98
+ $purple-38: #7078EF !default;
99
+ $purple-39: #817CFF !default;
100
+ $purple-40: #5818D8 !default;
101
+ $purple-41: #7A38FF !default;
102
+ $purple-42: #909AF6 !default;
103
+ $purple-43: #7733FF !default;
104
+
105
+ // gray variant used in some places (palette value)
106
+ $gray-300-alt: #9797A6 !default;
107
+
108
+ $purple-50: #E0E0FF !default;
109
+
41
110
  // fonts
42
111
  $font-size-base: 1rem !default;
43
112
  $font-family-sans-serif: "Public Sans", sans-serif;
@@ -85,6 +85,10 @@ export function distinctFilter(value: any, index: number, array: any[]) {
85
85
  return array.indexOf(value) === index;
86
86
  }
87
87
 
88
+ export function sanitizeForMarkdown(str: string): string {
89
+ return str.replace(/(```)(?:bash|yaml|js|console|json)(\n) *([\s\S]*?```)/g, "$1$2$3").replace(/(?<!:):(?![: /])/g, ": ");
90
+ }
91
+
88
92
  export default {
89
93
  capitalize,
90
94
  dateFilter,
@@ -93,4 +97,5 @@ export default {
93
97
  humanDuration,
94
98
  afterLastDot,
95
99
  distinctFilter
100
+ , sanitizeForMarkdown
96
101
  };
@@ -176,7 +176,7 @@ export function generateDagreGraph(
176
176
  continue;
177
177
  }
178
178
  if (!edgeReplacer[cluster.cluster.uid]) {
179
- dagreGraph.setNode(cluster.cluster.uid, {clusterLabelPos: "top"});
179
+ dagreGraph.setNode(cluster.cluster.uid, {clusterLabelPos: "top"});
180
180
 
181
181
  for (const node of cluster.nodes || []) {
182
182
  if (!hiddenNodes.includes(node)) {
@@ -643,6 +643,14 @@ export function generateGraph(
643
643
  );
644
644
  if (newEdge) {
645
645
  const edgeColor = getEdgeColor(edge, nodeByUid, clusterByNodeUid);
646
+ const targetNodeType = nodeByUid[newEdge.target]?.type ?? "";
647
+ const sourceNodeType = nodeByUid[newEdge.source]?.type ?? "";
648
+ let edgeBoundary: "top" | "bottom" | undefined = undefined;
649
+ if (typeof targetNodeType === "string" && targetNodeType.endsWith("GraphClusterRoot")) {
650
+ edgeBoundary = "top";
651
+ } else if (typeof sourceNodeType === "string" && sourceNodeType.endsWith("GraphClusterEnd")) {
652
+ edgeBoundary = "bottom";
653
+ }
646
654
  elements.push({
647
655
  id: newEdge.source + "|" + newEdge.target,
648
656
  source: newEdge.source,
@@ -665,6 +673,7 @@ export function generateGraph(
665
673
  clusterRootTaskNodeUids,
666
674
  readOnlyUidPrefixes
667
675
  ),
676
+ edgeBoundary: edgeBoundary,
668
677
  haveDashArray:
669
678
  nodeByUid[edge.source].type.endsWith("GraphTrigger") ||
670
679
  nodeByUid[edge.target].type.endsWith("GraphTrigger") ||
@@ -682,7 +691,6 @@ export function generateGraph(
682
691
 
683
692
  return elements;
684
693
  }
685
-
686
694
  export function isClusterRootOrEnd(node: MinimalNode) {
687
695
  return ["GraphClusterRoot", "GraphClusterFinally", "GraphClusterAfterExecution", "GraphClusterEnd"].some((s) =>
688
696
  node.type.endsWith(s)