@knime/product-features 6.0.0 → 6.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @knime/product-features
2
2
 
3
+ ## 6.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 76338e2: `VersionHistory`: add the `restoreOption` prop to make it possible to disable the "Restore this version" action on every version. The reason is shown as the subtext of the disabled menu item.
8
+
9
+ ## 6.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - d088e14: `NodeDescriptionTabs`: remove trailing full stop from the default `emptyText` headline.
14
+
3
15
  ## 6.0.0
4
16
 
5
17
  ### Major Changes
package/README.md CHANGED
@@ -6,12 +6,44 @@ This package contains composition patterns that combine KNIME Design System comp
6
6
 
7
7
  It's published as npm package: [@knime/product-features]
8
8
 
9
+ Unlike the `@knime/kds-*` packages it is **versioned independently** and is not
10
+ part of their shared Changesets release group.
11
+
9
12
  ## Installation
10
13
 
11
14
  ```bash
12
15
  pnpm add @knime/product-features
13
16
  ```
14
17
 
18
+ Peer dependencies: `@knime/kds-components`, `@knime/kds-styles`, `@vueuse/core`,
19
+ `es-toolkit`, `ofetch` and `vue`.
20
+
21
+ ## Usage
22
+
23
+ This package has **no root export** — import from one of the subpath entry
24
+ points, so consumers only pull in the feature area they use:
25
+
26
+ | Entry point | Source | Contents |
27
+ | -------------------------------------------- | -------------------------- | --------------------------------------------------------------------------- |
28
+ | `@knime/product-features/ai` | `src/ai` | AI assistant building blocks (`KdsPromptInput`) |
29
+ | `@knime/product-features/analytics` | `src/analytics` | Typed analytics event builders ([README](src/analytics/README.md)) |
30
+ | `@knime/product-features/auth-utils` | `src/authUtils` | KNIME Hub auth refresher and auth state ([README](src/authUtils/README.md)) |
31
+ | `@knime/product-features/data-transfer` | `src/dataTransfer` | File upload/download progress panels and composables |
32
+ | `@knime/product-features/data-transfer/core` | `src/dataTransfer/core.ts` | Framework-agnostic upload managers and upload client |
33
+ | `@knime/product-features/embedding-sdk` | `src/embeddingSDK` | Host/guest messaging for embedding an application in an iframe |
34
+ | `@knime/product-features/nodes` | `src/nodes` | Node description tabs and node preview |
35
+ | `@knime/product-features/rfc-errors` | `src/rfcErrors` | RFC 9457 problem-details error handling and error toasts |
36
+ | `@knime/product-features/toasts` | `src/toasts` | Toast notifications |
37
+ | `@knime/product-features/versions` | `src/versions` | Version history and create-version form |
38
+
39
+ ```ts
40
+ // ✅ import from a subpath
41
+ import { useToasts } from "@knime/product-features/toasts";
42
+
43
+ // ❌ fails — there is no "." export
44
+ import { useToasts } from "@knime/product-features";
45
+ ```
46
+
15
47
  ## Using with Vitest, Nuxt, or Vite SSR
16
48
 
17
49
  The published JavaScript imports its CSS as a side effect (e.g.
package/dist/nodes.css CHANGED
@@ -64,11 +64,11 @@
64
64
  font: var(--kds-font-base-title-small-strong);
65
65
  }
66
66
 
67
- .content[data-v-d2eb8e2e] {
67
+ .content[data-v-d037b8f7] {
68
68
  padding: var(--kds-spacing-container-0-5x) 0;
69
69
  color: var(--kds-color-text-and-icon-neutral);
70
70
  }
71
- .empty-state[data-v-d2eb8e2e] {
71
+ .empty-state[data-v-d037b8f7] {
72
72
  margin: 0 auto;
73
73
  }
74
74
 
package/dist/nodes.js CHANGED
@@ -239,7 +239,7 @@ var NodeDescriptionTabs_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
239
239
  dynamicOutputPorts: { default: () => [] },
240
240
  optionsData: { default: () => [] },
241
241
  viewsData: { default: () => [] },
242
- emptyText: { default: "No ports, options or views available." },
242
+ emptyText: { default: "No ports, options or views available" },
243
243
  renderAsHtml: {
244
244
  type: Boolean,
245
245
  default: false
@@ -345,7 +345,7 @@ var NodeDescriptionTabs_default = /*#__PURE__*/ _plugin_vue_export_helper_defaul
345
345
  ])]);
346
346
  };
347
347
  }
348
- }), [["__scopeId", "data-v-d2eb8e2e"]]);
348
+ }), [["__scopeId", "data-v-d037b8f7"]]);
349
349
  //#endregion
350
350
  //#region src/nodes/NodePreview/SVGNodeTorso.vue?vue&type=script&setup=true&lang.ts
351
351
  var _hoisted_1$1 = ["d", "data-type"];
package/dist/nodes.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.js","names":[],"sources":["../src/nodes/NodeDescriptionTabs/OptionsTab.vue","../src/nodes/NodeDescriptionTabs/OptionsTab.vue","../src/nodes/NodeDescriptionTabs/PortTemplateInfo.vue","../src/nodes/NodeDescriptionTabs/PortTemplateInfo.vue","../src/nodes/NodeDescriptionTabs/PortGroup.vue","../src/nodes/NodeDescriptionTabs/PortGroup.vue","../src/nodes/NodeDescriptionTabs/PortsTab.vue","../src/nodes/NodeDescriptionTabs/PortsTab.vue","../src/nodes/NodeDescriptionTabs/ViewsTab.vue","../src/nodes/NodeDescriptionTabs/ViewsTab.vue","../src/nodes/NodeDescriptionTabs/NodeDescriptionTabs.vue","../src/nodes/NodeDescriptionTabs/NodeDescriptionTabs.vue","../src/nodes/NodePreview/SVGNodeTorso.vue","../src/nodes/NodePreview/SVGNodeTorso.vue","../src/nodes/NodePreview/NodePreview.vue","../src/nodes/NodePreview/NodePreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsAccordion,\n type KdsAccordionItem,\n KdsDescription,\n} from \"@knime/kds-components\";\n\nimport type { NodeDescriptionOptions } from \"./types\";\n\ntype Props = {\n options: Array<NodeDescriptionOptions>;\n renderAsHtml?: boolean;\n};\n\nconst { options, renderAsHtml } = defineProps<Props>();\n\ntype AccordionItemWithContent = KdsAccordionItem & {\n description?: string;\n content: NodeDescriptionOptions[\"fields\"];\n};\n\nconst accordionItems = computed<AccordionItemWithContent[]>(() => {\n return options.map(\n (option, index) =>\n ({\n id: `section-${index}`,\n headline: option.sectionName,\n description: option.sectionDescription,\n content: option.fields,\n }) satisfies AccordionItemWithContent,\n );\n});\n\nconst modelValue = ref<string[]>([]);\n</script>\n\n<template>\n <div>\n <KdsAccordion\n v-if=\"options.length > 1\"\n v-model=\"modelValue\"\n :items=\"accordionItems\"\n >\n <template v-for=\"item in accordionItems\" :key=\"item.id\" #[item.id]>\n <KdsDescription\n v-if=\"item.description\"\n :text=\"item.description\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in item.content\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </template>\n </KdsAccordion>\n\n <div v-if=\"options.length === 1\" class=\"single-option-wrapper\">\n <KdsDescription\n v-if=\"options[0].sectionDescription\"\n :text=\"options[0].sectionDescription\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in options[0].fields\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.section-description {\n margin-bottom: var(--kds-spacing-container-1x);\n}\n\n.single-option-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.option-content {\n & .name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsAccordion,\n type KdsAccordionItem,\n KdsDescription,\n} from \"@knime/kds-components\";\n\nimport type { NodeDescriptionOptions } from \"./types\";\n\ntype Props = {\n options: Array<NodeDescriptionOptions>;\n renderAsHtml?: boolean;\n};\n\nconst { options, renderAsHtml } = defineProps<Props>();\n\ntype AccordionItemWithContent = KdsAccordionItem & {\n description?: string;\n content: NodeDescriptionOptions[\"fields\"];\n};\n\nconst accordionItems = computed<AccordionItemWithContent[]>(() => {\n return options.map(\n (option, index) =>\n ({\n id: `section-${index}`,\n headline: option.sectionName,\n description: option.sectionDescription,\n content: option.fields,\n }) satisfies AccordionItemWithContent,\n );\n});\n\nconst modelValue = ref<string[]>([]);\n</script>\n\n<template>\n <div>\n <KdsAccordion\n v-if=\"options.length > 1\"\n v-model=\"modelValue\"\n :items=\"accordionItems\"\n >\n <template v-for=\"item in accordionItems\" :key=\"item.id\" #[item.id]>\n <KdsDescription\n v-if=\"item.description\"\n :text=\"item.description\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in item.content\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </template>\n </KdsAccordion>\n\n <div v-if=\"options.length === 1\" class=\"single-option-wrapper\">\n <KdsDescription\n v-if=\"options[0].sectionDescription\"\n :text=\"options[0].sectionDescription\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in options[0].fields\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.section-description {\n margin-bottom: var(--kds-spacing-container-1x);\n}\n\n.single-option-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.option-content {\n & .name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription, KdsPortIcon } from \"@knime/kds-components\";\n\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n port: PortTemplate;\n showDescription: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"wrapper\">\n <div class=\"icon\">\n <KdsPortIcon\n :type=\"port.type\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n />\n </div>\n <span class=\"title\">Type: {{ port.typeDisplayName }}</span>\n\n <span class=\"name title\">Name: {{ port.name }}</span>\n\n <KdsDescription\n v-if=\"showDescription\"\n class=\"description\"\n :text=\"port.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.wrapper {\n display: grid;\n grid-template-columns: var(--kds-spacing-container-0-5x) 1fr;\n gap: var(--kds-spacing-container-0-5x);\n}\n\n.icon {\n display: flex;\n align-items: center;\n}\n\n.name,\n.description {\n grid-column: 2;\n}\n\n.title {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription, KdsPortIcon } from \"@knime/kds-components\";\n\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n port: PortTemplate;\n showDescription: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"wrapper\">\n <div class=\"icon\">\n <KdsPortIcon\n :type=\"port.type\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n />\n </div>\n <span class=\"title\">Type: {{ port.typeDisplayName }}</span>\n\n <span class=\"name title\">Name: {{ port.name }}</span>\n\n <KdsDescription\n v-if=\"showDescription\"\n class=\"description\"\n :text=\"port.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.wrapper {\n display: grid;\n grid-template-columns: var(--kds-spacing-container-0-5x) 1fr;\n gap: var(--kds-spacing-container-0-5x);\n}\n\n.icon {\n display: flex;\n align-items: center;\n}\n\n.name,\n.description {\n grid-column: 2;\n}\n\n.title {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport PortTemplateInfo from \"./PortTemplateInfo.vue\";\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n name: string;\n description?: string;\n ports: Array<PortTemplate>;\n isDynamicGroup?: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-group-card\">\n <span class=\"group-name\">{{ name }}</span>\n\n <KdsDescription v-if=\"description\" :text=\"description\" render-as-html />\n\n <template v-for=\"port in ports\" :key=\"port.id\">\n <PortTemplateInfo :port=\"port\" :show-description=\"!isDynamicGroup\" />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-group-card {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n\n & .group-name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport PortTemplateInfo from \"./PortTemplateInfo.vue\";\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n name: string;\n description?: string;\n ports: Array<PortTemplate>;\n isDynamicGroup?: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-group-card\">\n <span class=\"group-name\">{{ name }}</span>\n\n <KdsDescription v-if=\"description\" :text=\"description\" render-as-html />\n\n <template v-for=\"port in ports\" :key=\"port.id\">\n <PortTemplateInfo :port=\"port\" :show-description=\"!isDynamicGroup\" />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-group-card {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n\n & .group-name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport PortGroup from \"./PortGroup.vue\";\nimport type { DynamicPortGroup, PortTemplate } from \"./types\";\n\ntype Props = {\n inputPorts: Array<PortTemplate>;\n outputPorts: Array<PortTemplate>;\n dynamicInputGroups?: Array<DynamicPortGroup>;\n dynamicOutputGroups?: Array<DynamicPortGroup>;\n};\n\nconst { dynamicInputGroups = [], dynamicOutputGroups = [] } =\n defineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-list\">\n <PortGroup\n v-if=\"inputPorts.length > 0\"\n name=\"Input ports\"\n :ports=\"inputPorts\"\n />\n\n <PortGroup\n v-if=\"outputPorts.length > 0\"\n name=\"Output ports\"\n :ports=\"outputPorts\"\n />\n\n <template v-for=\"group in dynamicInputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Inport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n\n <template v-for=\"group in dynamicOutputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Outport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-list {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport PortGroup from \"./PortGroup.vue\";\nimport type { DynamicPortGroup, PortTemplate } from \"./types\";\n\ntype Props = {\n inputPorts: Array<PortTemplate>;\n outputPorts: Array<PortTemplate>;\n dynamicInputGroups?: Array<DynamicPortGroup>;\n dynamicOutputGroups?: Array<DynamicPortGroup>;\n};\n\nconst { dynamicInputGroups = [], dynamicOutputGroups = [] } =\n defineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-list\">\n <PortGroup\n v-if=\"inputPorts.length > 0\"\n name=\"Input ports\"\n :ports=\"inputPorts\"\n />\n\n <PortGroup\n v-if=\"outputPorts.length > 0\"\n name=\"Output ports\"\n :ports=\"outputPorts\"\n />\n\n <template v-for=\"group in dynamicInputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Inport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n\n <template v-for=\"group in dynamicOutputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Outport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-list {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport type { NodeDescriptionView } from \"./types\";\n\ntype Props = {\n views: Array<NodeDescriptionView>;\n};\n\nconst props = defineProps<Props>();\n\nconst viewsWithId = computed<Array<NodeDescriptionView & { id: string }>>(() =>\n props.views.map((view, index) => {\n const id = `view-${index}`;\n return { id, ...view };\n }),\n);\n</script>\n\n<template>\n <div v-for=\"view in viewsWithId\" :key=\"view.id\" class=\"card-wrapper\">\n <span class=\"name\">{{ view.name }}</span>\n <KdsDescription\n v-if=\"view.description\"\n :text=\"view.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.card-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n margin-bottom: var(--kds-spacing-container-0-25x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.name {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport type { NodeDescriptionView } from \"./types\";\n\ntype Props = {\n views: Array<NodeDescriptionView>;\n};\n\nconst props = defineProps<Props>();\n\nconst viewsWithId = computed<Array<NodeDescriptionView & { id: string }>>(() =>\n props.views.map((view, index) => {\n const id = `view-${index}`;\n return { id, ...view };\n }),\n);\n</script>\n\n<template>\n <div v-for=\"view in viewsWithId\" :key=\"view.id\" class=\"card-wrapper\">\n <span class=\"name\">{{ view.name }}</span>\n <KdsDescription\n v-if=\"view.description\"\n :text=\"view.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.card-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n margin-bottom: var(--kds-spacing-container-0-25x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.name {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsEmptyState,\n KdsTabBar,\n type KdsTabBarItem,\n} from \"@knime/kds-components\";\n\nimport OptionsTab from \"./OptionsTab.vue\";\nimport PortsTab from \"./PortsTab.vue\";\nimport ViewsTab from \"./ViewsTab.vue\";\nimport type { NodeDescriptionTabsProps } from \"./types\";\n\nconst {\n inputPorts = [],\n outputPorts = [],\n dynamicInputPorts = [],\n dynamicOutputPorts = [],\n optionsData = [],\n viewsData = [],\n emptyText = \"No ports, options or views available.\",\n renderAsHtml = false,\n tabBarFullWidth = false,\n} = defineProps<NodeDescriptionTabsProps>();\n\nconst TAB_IDS = {\n PORTS: \"ports\",\n OPTIONS: \"options\",\n VIEW: \"view\",\n} as const;\n\ntype TabIds = (typeof TAB_IDS)[keyof typeof TAB_IDS];\n\nconst activeTab = ref<TabIds | undefined>();\n\nconst hasPorts = computed(\n () =>\n inputPorts.length > 0 ||\n outputPorts.length > 0 ||\n dynamicInputPorts.length > 0 ||\n dynamicOutputPorts.length > 0,\n);\n\nconst tabs = computed<KdsTabBarItem[]>(() => [\n {\n id: \"tab-ports\",\n value: TAB_IDS.PORTS,\n label: \"Ports\",\n panelId: \"panel-ports\",\n accessory: {\n type: \"icon\",\n name: \"connection\",\n },\n disabled: !hasPorts.value,\n },\n {\n id: \"tab-options\",\n value: TAB_IDS.OPTIONS,\n label: \"Options\",\n panelId: \"panel-options\",\n accessory: {\n type: \"icon\",\n name: \"parameter\",\n },\n disabled: optionsData.length < 1,\n },\n {\n id: \"tab-view\",\n value: TAB_IDS.VIEW,\n label: \"View\",\n panelId: \"panel-view\",\n accessory: {\n type: \"icon\",\n name: \"eye\",\n },\n disabled: viewsData.length < 1,\n },\n]);\n</script>\n\n<template>\n <div>\n <KdsTabBar\n v-model=\"activeTab\"\n :full-width=\"tabBarFullWidth\"\n size=\"small\"\n :tabs=\"tabs\"\n />\n\n <div class=\"content\">\n <PortsTab\n v-if=\"activeTab === TAB_IDS.PORTS\"\n id=\"panel-ports\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-ports\"\n tabindex=\"0\"\n :input-ports=\"inputPorts\"\n :output-ports=\"outputPorts\"\n :dynamic-input-groups=\"dynamicInputPorts\"\n :dynamic-output-groups=\"dynamicOutputPorts\"\n />\n\n <OptionsTab\n v-if=\"activeTab === TAB_IDS.OPTIONS\"\n id=\"panel-options\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-options\"\n tabindex=\"0\"\n :options=\"optionsData\"\n :render-as-html=\"renderAsHtml\"\n />\n\n <ViewsTab\n v-if=\"activeTab === TAB_IDS.VIEW\"\n id=\"panel-view\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-view\"\n tabindex=\"0\"\n :views=\"viewsData\"\n />\n\n <KdsEmptyState\n v-if=\"!activeTab\"\n :headline=\"emptyText\"\n class=\"empty-state\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.content {\n padding: var(--kds-spacing-container-0-5x) 0;\n color: var(--kds-color-text-and-icon-neutral);\n}\n\n.empty-state {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsEmptyState,\n KdsTabBar,\n type KdsTabBarItem,\n} from \"@knime/kds-components\";\n\nimport OptionsTab from \"./OptionsTab.vue\";\nimport PortsTab from \"./PortsTab.vue\";\nimport ViewsTab from \"./ViewsTab.vue\";\nimport type { NodeDescriptionTabsProps } from \"./types\";\n\nconst {\n inputPorts = [],\n outputPorts = [],\n dynamicInputPorts = [],\n dynamicOutputPorts = [],\n optionsData = [],\n viewsData = [],\n emptyText = \"No ports, options or views available.\",\n renderAsHtml = false,\n tabBarFullWidth = false,\n} = defineProps<NodeDescriptionTabsProps>();\n\nconst TAB_IDS = {\n PORTS: \"ports\",\n OPTIONS: \"options\",\n VIEW: \"view\",\n} as const;\n\ntype TabIds = (typeof TAB_IDS)[keyof typeof TAB_IDS];\n\nconst activeTab = ref<TabIds | undefined>();\n\nconst hasPorts = computed(\n () =>\n inputPorts.length > 0 ||\n outputPorts.length > 0 ||\n dynamicInputPorts.length > 0 ||\n dynamicOutputPorts.length > 0,\n);\n\nconst tabs = computed<KdsTabBarItem[]>(() => [\n {\n id: \"tab-ports\",\n value: TAB_IDS.PORTS,\n label: \"Ports\",\n panelId: \"panel-ports\",\n accessory: {\n type: \"icon\",\n name: \"connection\",\n },\n disabled: !hasPorts.value,\n },\n {\n id: \"tab-options\",\n value: TAB_IDS.OPTIONS,\n label: \"Options\",\n panelId: \"panel-options\",\n accessory: {\n type: \"icon\",\n name: \"parameter\",\n },\n disabled: optionsData.length < 1,\n },\n {\n id: \"tab-view\",\n value: TAB_IDS.VIEW,\n label: \"View\",\n panelId: \"panel-view\",\n accessory: {\n type: \"icon\",\n name: \"eye\",\n },\n disabled: viewsData.length < 1,\n },\n]);\n</script>\n\n<template>\n <div>\n <KdsTabBar\n v-model=\"activeTab\"\n :full-width=\"tabBarFullWidth\"\n size=\"small\"\n :tabs=\"tabs\"\n />\n\n <div class=\"content\">\n <PortsTab\n v-if=\"activeTab === TAB_IDS.PORTS\"\n id=\"panel-ports\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-ports\"\n tabindex=\"0\"\n :input-ports=\"inputPorts\"\n :output-ports=\"outputPorts\"\n :dynamic-input-groups=\"dynamicInputPorts\"\n :dynamic-output-groups=\"dynamicOutputPorts\"\n />\n\n <OptionsTab\n v-if=\"activeTab === TAB_IDS.OPTIONS\"\n id=\"panel-options\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-options\"\n tabindex=\"0\"\n :options=\"optionsData\"\n :render-as-html=\"renderAsHtml\"\n />\n\n <ViewsTab\n v-if=\"activeTab === TAB_IDS.VIEW\"\n id=\"panel-view\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-view\"\n tabindex=\"0\"\n :views=\"viewsData\"\n />\n\n <KdsEmptyState\n v-if=\"!activeTab\"\n :headline=\"emptyText\"\n class=\"empty-state\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.content {\n padding: var(--kds-spacing-container-0-5x) 0;\n color: var(--kds-color-text-and-icon-neutral);\n}\n\n.empty-state {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodeTorsoProps } from \"./types\";\n\n/**\n * Draws the Torso (colored rounded rectangle with icon) of a Node or Component\n * This vue component only draws regular Nodes/Components, no Metanodes, no Unknown nor Missing Nodes\n * Only works inside of a <svg> element.\n */\nconst backgroundPaths: Record<string, string> = {\n default:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0l26.3,0C30.7,0,32,1.3,32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H2.8C1.3,32,0,30.\" +\n \"7,0,29.2z\",\n LoopEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n LoopStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n ScopeEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n ScopeStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n VirtualIn:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H6.5L0,25.9l5.2-10L0.7,7.2L6.5,0l22.7,0C30.7,0,32,1.3,32,2.8z\",\n VirtualOut:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-5.8,7.2l4.5,8.7l-5.2,10L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n};\n\nconst componentBackgroundPortion = 0.75;\n\nconst {\n type = null,\n isComponent = false,\n icon = null,\n} = defineProps<NodeTorsoProps>();\n\nconst backgroundPath = computed(\n () => (type && backgroundPaths[type]) || backgroundPaths.default,\n);\n\nconst componentBackgroundTransformation = computed(() => {\n const offset = NODE_SIZE / 2;\n const scaleFactor = componentBackgroundPortion;\n return `translate(${offset}, ${offset}) scale(${scaleFactor}) translate(-${offset}, -${offset})`;\n});\n</script>\n\n<template>\n <g>\n <path\n :d=\"backgroundPath\"\n :class=\"['bg', { component: isComponent }]\"\n :data-type=\"isComponent ? null : type\"\n />\n <!-- components may have two layers of background. This is the inner part, a shrunk version of the outer frame -->\n <path\n v-if=\"isComponent && type\"\n :d=\"backgroundPath\"\n class=\"bg\"\n :data-type=\"type\"\n :transform=\"componentBackgroundTransformation\"\n />\n <image\n v-if=\"icon\"\n :xlink:href=\"icon\"\n x=\"8\"\n y=\"8\"\n width=\"16\"\n height=\"16\"\n pointer-events=\"none\"\n />\n </g>\n</template>\n\n<style scoped>\n.bg {\n /** default color is unknown */\n fill: var(--kds-color-nodes-and-variables-unknown);\n\n &.component {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n\n &[data-type=\"Configuration\"] {\n fill: var(--kds-color-nodes-and-variables-configuration);\n }\n\n &[data-type=\"Container\"] {\n fill: var(--kds-color-nodes-and-variables-container);\n }\n\n &[data-type=\"Learner\"] {\n fill: var(--kds-color-nodes-and-variables-learner);\n }\n\n &[data-type=\"Loop\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopEnd\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopStart\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"Manipulator\"] {\n fill: var(--kds-color-nodes-and-variables-manipulator);\n }\n\n &[data-type=\"Other\"] {\n fill: var(--kds-color-nodes-and-variables-other);\n }\n\n &[data-type=\"Predictor\"] {\n fill: var(--kds-color-nodes-and-variables-predictor);\n }\n\n &[data-type=\"ScopeEnd\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"ScopeStart\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"Sink\"] {\n fill: var(--kds-color-nodes-and-variables-sink);\n }\n\n &[data-type=\"Source\"] {\n fill: var(--kds-color-nodes-and-variables-source);\n }\n\n &[data-type=\"Visualizer\"] {\n fill: var(--kds-color-nodes-and-variables-visualizer);\n }\n\n &[data-type=\"QuickForm\"] {\n fill: var(--kds-color-nodes-and-variables-quickform);\n }\n\n &[data-type=\"Widget\"] {\n fill: var(--kds-color-nodes-and-variables-widget);\n }\n\n /** Virtual = Components */\n &[data-type=\"VirtualIn\"],\n &[data-type=\"VirtualOut\"] {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodeTorsoProps } from \"./types\";\n\n/**\n * Draws the Torso (colored rounded rectangle with icon) of a Node or Component\n * This vue component only draws regular Nodes/Components, no Metanodes, no Unknown nor Missing Nodes\n * Only works inside of a <svg> element.\n */\nconst backgroundPaths: Record<string, string> = {\n default:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0l26.3,0C30.7,0,32,1.3,32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H2.8C1.3,32,0,30.\" +\n \"7,0,29.2z\",\n LoopEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n LoopStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n ScopeEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n ScopeStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n VirtualIn:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H6.5L0,25.9l5.2-10L0.7,7.2L6.5,0l22.7,0C30.7,0,32,1.3,32,2.8z\",\n VirtualOut:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-5.8,7.2l4.5,8.7l-5.2,10L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n};\n\nconst componentBackgroundPortion = 0.75;\n\nconst {\n type = null,\n isComponent = false,\n icon = null,\n} = defineProps<NodeTorsoProps>();\n\nconst backgroundPath = computed(\n () => (type && backgroundPaths[type]) || backgroundPaths.default,\n);\n\nconst componentBackgroundTransformation = computed(() => {\n const offset = NODE_SIZE / 2;\n const scaleFactor = componentBackgroundPortion;\n return `translate(${offset}, ${offset}) scale(${scaleFactor}) translate(-${offset}, -${offset})`;\n});\n</script>\n\n<template>\n <g>\n <path\n :d=\"backgroundPath\"\n :class=\"['bg', { component: isComponent }]\"\n :data-type=\"isComponent ? null : type\"\n />\n <!-- components may have two layers of background. This is the inner part, a shrunk version of the outer frame -->\n <path\n v-if=\"isComponent && type\"\n :d=\"backgroundPath\"\n class=\"bg\"\n :data-type=\"type\"\n :transform=\"componentBackgroundTransformation\"\n />\n <image\n v-if=\"icon\"\n :xlink:href=\"icon\"\n x=\"8\"\n y=\"8\"\n width=\"16\"\n height=\"16\"\n pointer-events=\"none\"\n />\n </g>\n</template>\n\n<style scoped>\n.bg {\n /** default color is unknown */\n fill: var(--kds-color-nodes-and-variables-unknown);\n\n &.component {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n\n &[data-type=\"Configuration\"] {\n fill: var(--kds-color-nodes-and-variables-configuration);\n }\n\n &[data-type=\"Container\"] {\n fill: var(--kds-color-nodes-and-variables-container);\n }\n\n &[data-type=\"Learner\"] {\n fill: var(--kds-color-nodes-and-variables-learner);\n }\n\n &[data-type=\"Loop\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopEnd\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopStart\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"Manipulator\"] {\n fill: var(--kds-color-nodes-and-variables-manipulator);\n }\n\n &[data-type=\"Other\"] {\n fill: var(--kds-color-nodes-and-variables-other);\n }\n\n &[data-type=\"Predictor\"] {\n fill: var(--kds-color-nodes-and-variables-predictor);\n }\n\n &[data-type=\"ScopeEnd\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"ScopeStart\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"Sink\"] {\n fill: var(--kds-color-nodes-and-variables-sink);\n }\n\n &[data-type=\"Source\"] {\n fill: var(--kds-color-nodes-and-variables-source);\n }\n\n &[data-type=\"Visualizer\"] {\n fill: var(--kds-color-nodes-and-variables-visualizer);\n }\n\n &[data-type=\"QuickForm\"] {\n fill: var(--kds-color-nodes-and-variables-quickform);\n }\n\n &[data-type=\"Widget\"] {\n fill: var(--kds-color-nodes-and-variables-widget);\n }\n\n /** Virtual = Components */\n &[data-type=\"VirtualIn\"],\n &[data-type=\"VirtualOut\"] {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsIcon, KdsPortIcon, PORT_SIZE } from \"@knime/kds-components\";\n\nimport SVGNodeTorso from \"./SVGNodeTorso.vue\";\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodePreviewProps, Port } from \"./types\";\n\n/**\n * SVG icon preview for a node or component, generated from its attributes\n */\nconst {\n type = null,\n isComponent = false,\n inPorts = [],\n outPorts = [],\n hidePorts = false,\n hideIndicators = false,\n size = \"xlarge\",\n indicatorIcon = undefined,\n icon = null,\n} = defineProps<NodePreviewProps>();\n\nconst horizontalSpaceForPorts = computed(() => (hidePorts ? 0 : PORT_SIZE));\n\nconst width = computed(() => NODE_SIZE + 2 * horizontalSpaceForPorts.value);\nconst height = NODE_SIZE;\nconst viewBox = computed(\n () => `-${horizontalSpaceForPorts.value} 0 ${width.value} ${height}`,\n);\n\n// top edge of port icon relative to 32x32 background\nfunction yPortShift(index: number, total: number): number {\n /* eslint-disable no-magic-numbers */\n let spacing = 1;\n if (total === 2) {\n spacing = 12;\n } else if (total === 3) {\n spacing = 2;\n }\n /* eslint-enable no-magic-numbers */\n\n const totalHeight = total * PORT_SIZE + (total - 1) * spacing;\n const delta = (NODE_SIZE - totalHeight) / 2;\n return (spacing + PORT_SIZE) * index + delta + PORT_SIZE / 2;\n}\n\nconst maxShownPorts = 3;\n\nconst cutOffPorts = (ports: Port[]) => {\n if (ports.length > maxShownPorts) {\n return [...ports.slice(0, maxShownPorts)];\n }\n return ports;\n};\n\nconst visibleInPorts = computed(() => cutOffPorts(inPorts));\nconst visibleOutPorts = computed(() => cutOffPorts(outPorts));\nconst numberOfHiddenPorts = computed(\n () =>\n inPorts.length -\n visibleInPorts.value.length +\n outPorts.length -\n visibleOutPorts.value.length,\n);\n</script>\n\n<template>\n <div class=\"node-preview\" :data-size=\"size\">\n <svg :viewBox=\"viewBox\" :width=\"width\" :height=\"height\">\n <SVGNodeTorso :type=\"type\" :icon=\"icon\" :is-component=\"isComponent\" />\n <template v-if=\"!hidePorts\">\n <KdsPortIcon\n v-for=\"(port, index) in visibleInPorts\"\n :key=\"`in-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(-${PORT_SIZE / 2}, ${yPortShift(index, visibleInPorts.length)})`\"\n />\n <KdsPortIcon\n v-for=\"(port, index) in visibleOutPorts\"\n :key=\"`out-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(${NODE_SIZE + PORT_SIZE / 2}, ${yPortShift(index, visibleOutPorts.length)})`\"\n />\n </template>\n </svg>\n <div v-if=\"!hideIndicators\" class=\"indicators\">\n <KdsIcon v-if=\"indicatorIcon\" :name=\"indicatorIcon\" size=\"small\" />\n <KdsIcon\n v-if=\"numberOfHiddenPorts > 0 && !hidePorts\"\n name=\"more-connections\"\n aria-label=\"Indication that some ports are hidden\"\n size=\"small\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.node-preview {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-25x);\n width: calc(v-bind(width) * 1px);\n\n /*\n * `zoom` is used instead of `transform: scale()` so that the shrunk size\n * is also reflected in the layout box, e.g. when placed in a flex or grid\n * container alongside other elements.\n */\n &[data-size=\"small\"] {\n zoom: calc(12 / v-bind(NODE_SIZE));\n }\n\n &[data-size=\"medium\"] {\n zoom: 0.5;\n }\n\n & .indicators {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n justify-content: center;\n height: var(--kds-dimension-icon-0-75x);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsIcon, KdsPortIcon, PORT_SIZE } from \"@knime/kds-components\";\n\nimport SVGNodeTorso from \"./SVGNodeTorso.vue\";\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodePreviewProps, Port } from \"./types\";\n\n/**\n * SVG icon preview for a node or component, generated from its attributes\n */\nconst {\n type = null,\n isComponent = false,\n inPorts = [],\n outPorts = [],\n hidePorts = false,\n hideIndicators = false,\n size = \"xlarge\",\n indicatorIcon = undefined,\n icon = null,\n} = defineProps<NodePreviewProps>();\n\nconst horizontalSpaceForPorts = computed(() => (hidePorts ? 0 : PORT_SIZE));\n\nconst width = computed(() => NODE_SIZE + 2 * horizontalSpaceForPorts.value);\nconst height = NODE_SIZE;\nconst viewBox = computed(\n () => `-${horizontalSpaceForPorts.value} 0 ${width.value} ${height}`,\n);\n\n// top edge of port icon relative to 32x32 background\nfunction yPortShift(index: number, total: number): number {\n /* eslint-disable no-magic-numbers */\n let spacing = 1;\n if (total === 2) {\n spacing = 12;\n } else if (total === 3) {\n spacing = 2;\n }\n /* eslint-enable no-magic-numbers */\n\n const totalHeight = total * PORT_SIZE + (total - 1) * spacing;\n const delta = (NODE_SIZE - totalHeight) / 2;\n return (spacing + PORT_SIZE) * index + delta + PORT_SIZE / 2;\n}\n\nconst maxShownPorts = 3;\n\nconst cutOffPorts = (ports: Port[]) => {\n if (ports.length > maxShownPorts) {\n return [...ports.slice(0, maxShownPorts)];\n }\n return ports;\n};\n\nconst visibleInPorts = computed(() => cutOffPorts(inPorts));\nconst visibleOutPorts = computed(() => cutOffPorts(outPorts));\nconst numberOfHiddenPorts = computed(\n () =>\n inPorts.length -\n visibleInPorts.value.length +\n outPorts.length -\n visibleOutPorts.value.length,\n);\n</script>\n\n<template>\n <div class=\"node-preview\" :data-size=\"size\">\n <svg :viewBox=\"viewBox\" :width=\"width\" :height=\"height\">\n <SVGNodeTorso :type=\"type\" :icon=\"icon\" :is-component=\"isComponent\" />\n <template v-if=\"!hidePorts\">\n <KdsPortIcon\n v-for=\"(port, index) in visibleInPorts\"\n :key=\"`in-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(-${PORT_SIZE / 2}, ${yPortShift(index, visibleInPorts.length)})`\"\n />\n <KdsPortIcon\n v-for=\"(port, index) in visibleOutPorts\"\n :key=\"`out-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(${NODE_SIZE + PORT_SIZE / 2}, ${yPortShift(index, visibleOutPorts.length)})`\"\n />\n </template>\n </svg>\n <div v-if=\"!hideIndicators\" class=\"indicators\">\n <KdsIcon v-if=\"indicatorIcon\" :name=\"indicatorIcon\" size=\"small\" />\n <KdsIcon\n v-if=\"numberOfHiddenPorts > 0 && !hidePorts\"\n name=\"more-connections\"\n aria-label=\"Indication that some ports are hidden\"\n size=\"small\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.node-preview {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-25x);\n width: calc(v-bind(width) * 1px);\n\n /*\n * `zoom` is used instead of `transform: scale()` so that the shrunk size\n * is also reflected in the layout box, e.g. when placed in a flex or grid\n * container alongside other elements.\n */\n &[data-size=\"small\"] {\n zoom: calc(12 / v-bind(NODE_SIZE));\n }\n\n &[data-size=\"medium\"] {\n zoom: 0.5;\n }\n\n & .indicators {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n justify-content: center;\n height: var(--kds-dimension-icon-0-75x);\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"nodes.js","names":[],"sources":["../src/nodes/NodeDescriptionTabs/OptionsTab.vue","../src/nodes/NodeDescriptionTabs/OptionsTab.vue","../src/nodes/NodeDescriptionTabs/PortTemplateInfo.vue","../src/nodes/NodeDescriptionTabs/PortTemplateInfo.vue","../src/nodes/NodeDescriptionTabs/PortGroup.vue","../src/nodes/NodeDescriptionTabs/PortGroup.vue","../src/nodes/NodeDescriptionTabs/PortsTab.vue","../src/nodes/NodeDescriptionTabs/PortsTab.vue","../src/nodes/NodeDescriptionTabs/ViewsTab.vue","../src/nodes/NodeDescriptionTabs/ViewsTab.vue","../src/nodes/NodeDescriptionTabs/NodeDescriptionTabs.vue","../src/nodes/NodeDescriptionTabs/NodeDescriptionTabs.vue","../src/nodes/NodePreview/SVGNodeTorso.vue","../src/nodes/NodePreview/SVGNodeTorso.vue","../src/nodes/NodePreview/NodePreview.vue","../src/nodes/NodePreview/NodePreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsAccordion,\n type KdsAccordionItem,\n KdsDescription,\n} from \"@knime/kds-components\";\n\nimport type { NodeDescriptionOptions } from \"./types\";\n\ntype Props = {\n options: Array<NodeDescriptionOptions>;\n renderAsHtml?: boolean;\n};\n\nconst { options, renderAsHtml } = defineProps<Props>();\n\ntype AccordionItemWithContent = KdsAccordionItem & {\n description?: string;\n content: NodeDescriptionOptions[\"fields\"];\n};\n\nconst accordionItems = computed<AccordionItemWithContent[]>(() => {\n return options.map(\n (option, index) =>\n ({\n id: `section-${index}`,\n headline: option.sectionName,\n description: option.sectionDescription,\n content: option.fields,\n }) satisfies AccordionItemWithContent,\n );\n});\n\nconst modelValue = ref<string[]>([]);\n</script>\n\n<template>\n <div>\n <KdsAccordion\n v-if=\"options.length > 1\"\n v-model=\"modelValue\"\n :items=\"accordionItems\"\n >\n <template v-for=\"item in accordionItems\" :key=\"item.id\" #[item.id]>\n <KdsDescription\n v-if=\"item.description\"\n :text=\"item.description\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in item.content\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </template>\n </KdsAccordion>\n\n <div v-if=\"options.length === 1\" class=\"single-option-wrapper\">\n <KdsDescription\n v-if=\"options[0].sectionDescription\"\n :text=\"options[0].sectionDescription\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in options[0].fields\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.section-description {\n margin-bottom: var(--kds-spacing-container-1x);\n}\n\n.single-option-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.option-content {\n & .name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsAccordion,\n type KdsAccordionItem,\n KdsDescription,\n} from \"@knime/kds-components\";\n\nimport type { NodeDescriptionOptions } from \"./types\";\n\ntype Props = {\n options: Array<NodeDescriptionOptions>;\n renderAsHtml?: boolean;\n};\n\nconst { options, renderAsHtml } = defineProps<Props>();\n\ntype AccordionItemWithContent = KdsAccordionItem & {\n description?: string;\n content: NodeDescriptionOptions[\"fields\"];\n};\n\nconst accordionItems = computed<AccordionItemWithContent[]>(() => {\n return options.map(\n (option, index) =>\n ({\n id: `section-${index}`,\n headline: option.sectionName,\n description: option.sectionDescription,\n content: option.fields,\n }) satisfies AccordionItemWithContent,\n );\n});\n\nconst modelValue = ref<string[]>([]);\n</script>\n\n<template>\n <div>\n <KdsAccordion\n v-if=\"options.length > 1\"\n v-model=\"modelValue\"\n :items=\"accordionItems\"\n >\n <template v-for=\"item in accordionItems\" :key=\"item.id\" #[item.id]>\n <KdsDescription\n v-if=\"item.description\"\n :text=\"item.description\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in item.content\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </template>\n </KdsAccordion>\n\n <div v-if=\"options.length === 1\" class=\"single-option-wrapper\">\n <KdsDescription\n v-if=\"options[0].sectionDescription\"\n :text=\"options[0].sectionDescription\"\n :render-as-html=\"renderAsHtml\"\n class=\"section-description\"\n />\n\n <template v-for=\"field in options[0].fields\" :key=\"field.name\">\n <div class=\"option-content\">\n <span class=\"name\">\n {{ field.name }} {{ field.optional ? \"(optional)\" : \"\" }}\n </span>\n\n <KdsDescription\n :text=\"field.description\"\n :render-as-html=\"renderAsHtml\"\n />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.section-description {\n margin-bottom: var(--kds-spacing-container-1x);\n}\n\n.single-option-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.option-content {\n & .name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription, KdsPortIcon } from \"@knime/kds-components\";\n\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n port: PortTemplate;\n showDescription: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"wrapper\">\n <div class=\"icon\">\n <KdsPortIcon\n :type=\"port.type\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n />\n </div>\n <span class=\"title\">Type: {{ port.typeDisplayName }}</span>\n\n <span class=\"name title\">Name: {{ port.name }}</span>\n\n <KdsDescription\n v-if=\"showDescription\"\n class=\"description\"\n :text=\"port.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.wrapper {\n display: grid;\n grid-template-columns: var(--kds-spacing-container-0-5x) 1fr;\n gap: var(--kds-spacing-container-0-5x);\n}\n\n.icon {\n display: flex;\n align-items: center;\n}\n\n.name,\n.description {\n grid-column: 2;\n}\n\n.title {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription, KdsPortIcon } from \"@knime/kds-components\";\n\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n port: PortTemplate;\n showDescription: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"wrapper\">\n <div class=\"icon\">\n <KdsPortIcon\n :type=\"port.type\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n />\n </div>\n <span class=\"title\">Type: {{ port.typeDisplayName }}</span>\n\n <span class=\"name title\">Name: {{ port.name }}</span>\n\n <KdsDescription\n v-if=\"showDescription\"\n class=\"description\"\n :text=\"port.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.wrapper {\n display: grid;\n grid-template-columns: var(--kds-spacing-container-0-5x) 1fr;\n gap: var(--kds-spacing-container-0-5x);\n}\n\n.icon {\n display: flex;\n align-items: center;\n}\n\n.name,\n.description {\n grid-column: 2;\n}\n\n.title {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport PortTemplateInfo from \"./PortTemplateInfo.vue\";\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n name: string;\n description?: string;\n ports: Array<PortTemplate>;\n isDynamicGroup?: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-group-card\">\n <span class=\"group-name\">{{ name }}</span>\n\n <KdsDescription v-if=\"description\" :text=\"description\" render-as-html />\n\n <template v-for=\"port in ports\" :key=\"port.id\">\n <PortTemplateInfo :port=\"port\" :show-description=\"!isDynamicGroup\" />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-group-card {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n\n & .group-name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport PortTemplateInfo from \"./PortTemplateInfo.vue\";\nimport type { PortTemplate } from \"./types\";\n\ntype Props = {\n name: string;\n description?: string;\n ports: Array<PortTemplate>;\n isDynamicGroup?: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-group-card\">\n <span class=\"group-name\">{{ name }}</span>\n\n <KdsDescription v-if=\"description\" :text=\"description\" render-as-html />\n\n <template v-for=\"port in ports\" :key=\"port.id\">\n <PortTemplateInfo :port=\"port\" :show-description=\"!isDynamicGroup\" />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-group-card {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n padding: var(--kds-spacing-container-1x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n\n & .group-name {\n font: var(--kds-font-base-title-small-strong);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport PortGroup from \"./PortGroup.vue\";\nimport type { DynamicPortGroup, PortTemplate } from \"./types\";\n\ntype Props = {\n inputPorts: Array<PortTemplate>;\n outputPorts: Array<PortTemplate>;\n dynamicInputGroups?: Array<DynamicPortGroup>;\n dynamicOutputGroups?: Array<DynamicPortGroup>;\n};\n\nconst { dynamicInputGroups = [], dynamicOutputGroups = [] } =\n defineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-list\">\n <PortGroup\n v-if=\"inputPorts.length > 0\"\n name=\"Input ports\"\n :ports=\"inputPorts\"\n />\n\n <PortGroup\n v-if=\"outputPorts.length > 0\"\n name=\"Output ports\"\n :ports=\"outputPorts\"\n />\n\n <template v-for=\"group in dynamicInputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Inport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n\n <template v-for=\"group in dynamicOutputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Outport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-list {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport PortGroup from \"./PortGroup.vue\";\nimport type { DynamicPortGroup, PortTemplate } from \"./types\";\n\ntype Props = {\n inputPorts: Array<PortTemplate>;\n outputPorts: Array<PortTemplate>;\n dynamicInputGroups?: Array<DynamicPortGroup>;\n dynamicOutputGroups?: Array<DynamicPortGroup>;\n};\n\nconst { dynamicInputGroups = [], dynamicOutputGroups = [] } =\n defineProps<Props>();\n</script>\n\n<template>\n <div class=\"port-list\">\n <PortGroup\n v-if=\"inputPorts.length > 0\"\n name=\"Input ports\"\n :ports=\"inputPorts\"\n />\n\n <PortGroup\n v-if=\"outputPorts.length > 0\"\n name=\"Output ports\"\n :ports=\"outputPorts\"\n />\n\n <template v-for=\"group in dynamicInputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Inport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n\n <template v-for=\"group in dynamicOutputGroups\" :key=\"group.name\">\n <PortGroup\n v-if=\"group.types.length > 0\"\n :name=\"group.name + ' (Dynamic Outport)'\"\n :description=\"group.description\"\n :ports=\"group.types\"\n is-dynamic-group\n />\n </template>\n </div>\n</template>\n\n<style scoped>\n.port-list {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport type { NodeDescriptionView } from \"./types\";\n\ntype Props = {\n views: Array<NodeDescriptionView>;\n};\n\nconst props = defineProps<Props>();\n\nconst viewsWithId = computed<Array<NodeDescriptionView & { id: string }>>(() =>\n props.views.map((view, index) => {\n const id = `view-${index}`;\n return { id, ...view };\n }),\n);\n</script>\n\n<template>\n <div v-for=\"view in viewsWithId\" :key=\"view.id\" class=\"card-wrapper\">\n <span class=\"name\">{{ view.name }}</span>\n <KdsDescription\n v-if=\"view.description\"\n :text=\"view.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.card-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n margin-bottom: var(--kds-spacing-container-0-25x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.name {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsDescription } from \"@knime/kds-components\";\n\nimport type { NodeDescriptionView } from \"./types\";\n\ntype Props = {\n views: Array<NodeDescriptionView>;\n};\n\nconst props = defineProps<Props>();\n\nconst viewsWithId = computed<Array<NodeDescriptionView & { id: string }>>(() =>\n props.views.map((view, index) => {\n const id = `view-${index}`;\n return { id, ...view };\n }),\n);\n</script>\n\n<template>\n <div v-for=\"view in viewsWithId\" :key=\"view.id\" class=\"card-wrapper\">\n <span class=\"name\">{{ view.name }}</span>\n <KdsDescription\n v-if=\"view.description\"\n :text=\"view.description\"\n render-as-html\n />\n </div>\n</template>\n\n<style scoped>\n.card-wrapper {\n display: flex;\n flex-direction: column;\n padding: var(--kds-spacing-container-1x);\n margin-bottom: var(--kds-spacing-container-0-25x);\n background: var(--kds-color-surface-muted);\n border-radius: var(--kds-border-radius-container-0-37x);\n}\n\n.name {\n font: var(--kds-font-base-title-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsEmptyState,\n KdsTabBar,\n type KdsTabBarItem,\n} from \"@knime/kds-components\";\n\nimport OptionsTab from \"./OptionsTab.vue\";\nimport PortsTab from \"./PortsTab.vue\";\nimport ViewsTab from \"./ViewsTab.vue\";\nimport type { NodeDescriptionTabsProps } from \"./types\";\n\nconst {\n inputPorts = [],\n outputPorts = [],\n dynamicInputPorts = [],\n dynamicOutputPorts = [],\n optionsData = [],\n viewsData = [],\n emptyText = \"No ports, options or views available\",\n renderAsHtml = false,\n tabBarFullWidth = false,\n} = defineProps<NodeDescriptionTabsProps>();\n\nconst TAB_IDS = {\n PORTS: \"ports\",\n OPTIONS: \"options\",\n VIEW: \"view\",\n} as const;\n\ntype TabIds = (typeof TAB_IDS)[keyof typeof TAB_IDS];\n\nconst activeTab = ref<TabIds | undefined>();\n\nconst hasPorts = computed(\n () =>\n inputPorts.length > 0 ||\n outputPorts.length > 0 ||\n dynamicInputPorts.length > 0 ||\n dynamicOutputPorts.length > 0,\n);\n\nconst tabs = computed<KdsTabBarItem[]>(() => [\n {\n id: \"tab-ports\",\n value: TAB_IDS.PORTS,\n label: \"Ports\",\n panelId: \"panel-ports\",\n accessory: {\n type: \"icon\",\n name: \"connection\",\n },\n disabled: !hasPorts.value,\n },\n {\n id: \"tab-options\",\n value: TAB_IDS.OPTIONS,\n label: \"Options\",\n panelId: \"panel-options\",\n accessory: {\n type: \"icon\",\n name: \"parameter\",\n },\n disabled: optionsData.length < 1,\n },\n {\n id: \"tab-view\",\n value: TAB_IDS.VIEW,\n label: \"View\",\n panelId: \"panel-view\",\n accessory: {\n type: \"icon\",\n name: \"eye\",\n },\n disabled: viewsData.length < 1,\n },\n]);\n</script>\n\n<template>\n <div>\n <KdsTabBar\n v-model=\"activeTab\"\n :full-width=\"tabBarFullWidth\"\n size=\"small\"\n :tabs=\"tabs\"\n />\n\n <div class=\"content\">\n <PortsTab\n v-if=\"activeTab === TAB_IDS.PORTS\"\n id=\"panel-ports\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-ports\"\n tabindex=\"0\"\n :input-ports=\"inputPorts\"\n :output-ports=\"outputPorts\"\n :dynamic-input-groups=\"dynamicInputPorts\"\n :dynamic-output-groups=\"dynamicOutputPorts\"\n />\n\n <OptionsTab\n v-if=\"activeTab === TAB_IDS.OPTIONS\"\n id=\"panel-options\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-options\"\n tabindex=\"0\"\n :options=\"optionsData\"\n :render-as-html=\"renderAsHtml\"\n />\n\n <ViewsTab\n v-if=\"activeTab === TAB_IDS.VIEW\"\n id=\"panel-view\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-view\"\n tabindex=\"0\"\n :views=\"viewsData\"\n />\n\n <KdsEmptyState\n v-if=\"!activeTab\"\n :headline=\"emptyText\"\n class=\"empty-state\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.content {\n padding: var(--kds-spacing-container-0-5x) 0;\n color: var(--kds-color-text-and-icon-neutral);\n}\n\n.empty-state {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n KdsEmptyState,\n KdsTabBar,\n type KdsTabBarItem,\n} from \"@knime/kds-components\";\n\nimport OptionsTab from \"./OptionsTab.vue\";\nimport PortsTab from \"./PortsTab.vue\";\nimport ViewsTab from \"./ViewsTab.vue\";\nimport type { NodeDescriptionTabsProps } from \"./types\";\n\nconst {\n inputPorts = [],\n outputPorts = [],\n dynamicInputPorts = [],\n dynamicOutputPorts = [],\n optionsData = [],\n viewsData = [],\n emptyText = \"No ports, options or views available\",\n renderAsHtml = false,\n tabBarFullWidth = false,\n} = defineProps<NodeDescriptionTabsProps>();\n\nconst TAB_IDS = {\n PORTS: \"ports\",\n OPTIONS: \"options\",\n VIEW: \"view\",\n} as const;\n\ntype TabIds = (typeof TAB_IDS)[keyof typeof TAB_IDS];\n\nconst activeTab = ref<TabIds | undefined>();\n\nconst hasPorts = computed(\n () =>\n inputPorts.length > 0 ||\n outputPorts.length > 0 ||\n dynamicInputPorts.length > 0 ||\n dynamicOutputPorts.length > 0,\n);\n\nconst tabs = computed<KdsTabBarItem[]>(() => [\n {\n id: \"tab-ports\",\n value: TAB_IDS.PORTS,\n label: \"Ports\",\n panelId: \"panel-ports\",\n accessory: {\n type: \"icon\",\n name: \"connection\",\n },\n disabled: !hasPorts.value,\n },\n {\n id: \"tab-options\",\n value: TAB_IDS.OPTIONS,\n label: \"Options\",\n panelId: \"panel-options\",\n accessory: {\n type: \"icon\",\n name: \"parameter\",\n },\n disabled: optionsData.length < 1,\n },\n {\n id: \"tab-view\",\n value: TAB_IDS.VIEW,\n label: \"View\",\n panelId: \"panel-view\",\n accessory: {\n type: \"icon\",\n name: \"eye\",\n },\n disabled: viewsData.length < 1,\n },\n]);\n</script>\n\n<template>\n <div>\n <KdsTabBar\n v-model=\"activeTab\"\n :full-width=\"tabBarFullWidth\"\n size=\"small\"\n :tabs=\"tabs\"\n />\n\n <div class=\"content\">\n <PortsTab\n v-if=\"activeTab === TAB_IDS.PORTS\"\n id=\"panel-ports\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-ports\"\n tabindex=\"0\"\n :input-ports=\"inputPorts\"\n :output-ports=\"outputPorts\"\n :dynamic-input-groups=\"dynamicInputPorts\"\n :dynamic-output-groups=\"dynamicOutputPorts\"\n />\n\n <OptionsTab\n v-if=\"activeTab === TAB_IDS.OPTIONS\"\n id=\"panel-options\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-options\"\n tabindex=\"0\"\n :options=\"optionsData\"\n :render-as-html=\"renderAsHtml\"\n />\n\n <ViewsTab\n v-if=\"activeTab === TAB_IDS.VIEW\"\n id=\"panel-view\"\n role=\"tabpanel\"\n aria-labelledby=\"tab-view\"\n tabindex=\"0\"\n :views=\"viewsData\"\n />\n\n <KdsEmptyState\n v-if=\"!activeTab\"\n :headline=\"emptyText\"\n class=\"empty-state\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.content {\n padding: var(--kds-spacing-container-0-5x) 0;\n color: var(--kds-color-text-and-icon-neutral);\n}\n\n.empty-state {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodeTorsoProps } from \"./types\";\n\n/**\n * Draws the Torso (colored rounded rectangle with icon) of a Node or Component\n * This vue component only draws regular Nodes/Components, no Metanodes, no Unknown nor Missing Nodes\n * Only works inside of a <svg> element.\n */\nconst backgroundPaths: Record<string, string> = {\n default:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0l26.3,0C30.7,0,32,1.3,32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H2.8C1.3,32,0,30.\" +\n \"7,0,29.2z\",\n LoopEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n LoopStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n ScopeEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n ScopeStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n VirtualIn:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H6.5L0,25.9l5.2-10L0.7,7.2L6.5,0l22.7,0C30.7,0,32,1.3,32,2.8z\",\n VirtualOut:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-5.8,7.2l4.5,8.7l-5.2,10L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n};\n\nconst componentBackgroundPortion = 0.75;\n\nconst {\n type = null,\n isComponent = false,\n icon = null,\n} = defineProps<NodeTorsoProps>();\n\nconst backgroundPath = computed(\n () => (type && backgroundPaths[type]) || backgroundPaths.default,\n);\n\nconst componentBackgroundTransformation = computed(() => {\n const offset = NODE_SIZE / 2;\n const scaleFactor = componentBackgroundPortion;\n return `translate(${offset}, ${offset}) scale(${scaleFactor}) translate(-${offset}, -${offset})`;\n});\n</script>\n\n<template>\n <g>\n <path\n :d=\"backgroundPath\"\n :class=\"['bg', { component: isComponent }]\"\n :data-type=\"isComponent ? null : type\"\n />\n <!-- components may have two layers of background. This is the inner part, a shrunk version of the outer frame -->\n <path\n v-if=\"isComponent && type\"\n :d=\"backgroundPath\"\n class=\"bg\"\n :data-type=\"type\"\n :transform=\"componentBackgroundTransformation\"\n />\n <image\n v-if=\"icon\"\n :xlink:href=\"icon\"\n x=\"8\"\n y=\"8\"\n width=\"16\"\n height=\"16\"\n pointer-events=\"none\"\n />\n </g>\n</template>\n\n<style scoped>\n.bg {\n /** default color is unknown */\n fill: var(--kds-color-nodes-and-variables-unknown);\n\n &.component {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n\n &[data-type=\"Configuration\"] {\n fill: var(--kds-color-nodes-and-variables-configuration);\n }\n\n &[data-type=\"Container\"] {\n fill: var(--kds-color-nodes-and-variables-container);\n }\n\n &[data-type=\"Learner\"] {\n fill: var(--kds-color-nodes-and-variables-learner);\n }\n\n &[data-type=\"Loop\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopEnd\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopStart\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"Manipulator\"] {\n fill: var(--kds-color-nodes-and-variables-manipulator);\n }\n\n &[data-type=\"Other\"] {\n fill: var(--kds-color-nodes-and-variables-other);\n }\n\n &[data-type=\"Predictor\"] {\n fill: var(--kds-color-nodes-and-variables-predictor);\n }\n\n &[data-type=\"ScopeEnd\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"ScopeStart\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"Sink\"] {\n fill: var(--kds-color-nodes-and-variables-sink);\n }\n\n &[data-type=\"Source\"] {\n fill: var(--kds-color-nodes-and-variables-source);\n }\n\n &[data-type=\"Visualizer\"] {\n fill: var(--kds-color-nodes-and-variables-visualizer);\n }\n\n &[data-type=\"QuickForm\"] {\n fill: var(--kds-color-nodes-and-variables-quickform);\n }\n\n &[data-type=\"Widget\"] {\n fill: var(--kds-color-nodes-and-variables-widget);\n }\n\n /** Virtual = Components */\n &[data-type=\"VirtualIn\"],\n &[data-type=\"VirtualOut\"] {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodeTorsoProps } from \"./types\";\n\n/**\n * Draws the Torso (colored rounded rectangle with icon) of a Node or Component\n * This vue component only draws regular Nodes/Components, no Metanodes, no Unknown nor Missing Nodes\n * Only works inside of a <svg> element.\n */\nconst backgroundPaths: Record<string, string> = {\n default:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0l26.3,0C30.7,0,32,1.3,32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H2.8C1.3,32,0,30.\" +\n \"7,0,29.2z\",\n LoopEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n LoopStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n ScopeEnd:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H4L0,16.1L4,0l25.2,0C30.7,0,32,1.3,32,2.8z\",\n ScopeStart:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-4,15.9L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n VirtualIn:\n \"M32,2.8v26.3c0,1.6-1.3,2.8-2.8,2.8H6.5L0,25.9l5.2-10L0.7,7.2L6.5,0l22.7,0C30.7,0,32,1.3,32,2.8z\",\n VirtualOut:\n \"M0,29.2L0,2.8C0,1.3,1.3,0,2.8,0L32,0l-5.8,7.2l4.5,8.7l-5.2,10L32,32H2.8C1.3,32,0,30.7,0,29.2z\",\n};\n\nconst componentBackgroundPortion = 0.75;\n\nconst {\n type = null,\n isComponent = false,\n icon = null,\n} = defineProps<NodeTorsoProps>();\n\nconst backgroundPath = computed(\n () => (type && backgroundPaths[type]) || backgroundPaths.default,\n);\n\nconst componentBackgroundTransformation = computed(() => {\n const offset = NODE_SIZE / 2;\n const scaleFactor = componentBackgroundPortion;\n return `translate(${offset}, ${offset}) scale(${scaleFactor}) translate(-${offset}, -${offset})`;\n});\n</script>\n\n<template>\n <g>\n <path\n :d=\"backgroundPath\"\n :class=\"['bg', { component: isComponent }]\"\n :data-type=\"isComponent ? null : type\"\n />\n <!-- components may have two layers of background. This is the inner part, a shrunk version of the outer frame -->\n <path\n v-if=\"isComponent && type\"\n :d=\"backgroundPath\"\n class=\"bg\"\n :data-type=\"type\"\n :transform=\"componentBackgroundTransformation\"\n />\n <image\n v-if=\"icon\"\n :xlink:href=\"icon\"\n x=\"8\"\n y=\"8\"\n width=\"16\"\n height=\"16\"\n pointer-events=\"none\"\n />\n </g>\n</template>\n\n<style scoped>\n.bg {\n /** default color is unknown */\n fill: var(--kds-color-nodes-and-variables-unknown);\n\n &.component {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n\n &[data-type=\"Configuration\"] {\n fill: var(--kds-color-nodes-and-variables-configuration);\n }\n\n &[data-type=\"Container\"] {\n fill: var(--kds-color-nodes-and-variables-container);\n }\n\n &[data-type=\"Learner\"] {\n fill: var(--kds-color-nodes-and-variables-learner);\n }\n\n &[data-type=\"Loop\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopEnd\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"LoopStart\"] {\n fill: var(--kds-color-nodes-and-variables-loop);\n }\n\n &[data-type=\"Manipulator\"] {\n fill: var(--kds-color-nodes-and-variables-manipulator);\n }\n\n &[data-type=\"Other\"] {\n fill: var(--kds-color-nodes-and-variables-other);\n }\n\n &[data-type=\"Predictor\"] {\n fill: var(--kds-color-nodes-and-variables-predictor);\n }\n\n &[data-type=\"ScopeEnd\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"ScopeStart\"] {\n fill: var(--kds-color-nodes-and-variables-scope);\n }\n\n &[data-type=\"Sink\"] {\n fill: var(--kds-color-nodes-and-variables-sink);\n }\n\n &[data-type=\"Source\"] {\n fill: var(--kds-color-nodes-and-variables-source);\n }\n\n &[data-type=\"Visualizer\"] {\n fill: var(--kds-color-nodes-and-variables-visualizer);\n }\n\n &[data-type=\"QuickForm\"] {\n fill: var(--kds-color-nodes-and-variables-quickform);\n }\n\n &[data-type=\"Widget\"] {\n fill: var(--kds-color-nodes-and-variables-widget);\n }\n\n /** Virtual = Components */\n &[data-type=\"VirtualIn\"],\n &[data-type=\"VirtualOut\"] {\n fill: var(--kds-color-nodes-and-variables-component);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsIcon, KdsPortIcon, PORT_SIZE } from \"@knime/kds-components\";\n\nimport SVGNodeTorso from \"./SVGNodeTorso.vue\";\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodePreviewProps, Port } from \"./types\";\n\n/**\n * SVG icon preview for a node or component, generated from its attributes\n */\nconst {\n type = null,\n isComponent = false,\n inPorts = [],\n outPorts = [],\n hidePorts = false,\n hideIndicators = false,\n size = \"xlarge\",\n indicatorIcon = undefined,\n icon = null,\n} = defineProps<NodePreviewProps>();\n\nconst horizontalSpaceForPorts = computed(() => (hidePorts ? 0 : PORT_SIZE));\n\nconst width = computed(() => NODE_SIZE + 2 * horizontalSpaceForPorts.value);\nconst height = NODE_SIZE;\nconst viewBox = computed(\n () => `-${horizontalSpaceForPorts.value} 0 ${width.value} ${height}`,\n);\n\n// top edge of port icon relative to 32x32 background\nfunction yPortShift(index: number, total: number): number {\n /* eslint-disable no-magic-numbers */\n let spacing = 1;\n if (total === 2) {\n spacing = 12;\n } else if (total === 3) {\n spacing = 2;\n }\n /* eslint-enable no-magic-numbers */\n\n const totalHeight = total * PORT_SIZE + (total - 1) * spacing;\n const delta = (NODE_SIZE - totalHeight) / 2;\n return (spacing + PORT_SIZE) * index + delta + PORT_SIZE / 2;\n}\n\nconst maxShownPorts = 3;\n\nconst cutOffPorts = (ports: Port[]) => {\n if (ports.length > maxShownPorts) {\n return [...ports.slice(0, maxShownPorts)];\n }\n return ports;\n};\n\nconst visibleInPorts = computed(() => cutOffPorts(inPorts));\nconst visibleOutPorts = computed(() => cutOffPorts(outPorts));\nconst numberOfHiddenPorts = computed(\n () =>\n inPorts.length -\n visibleInPorts.value.length +\n outPorts.length -\n visibleOutPorts.value.length,\n);\n</script>\n\n<template>\n <div class=\"node-preview\" :data-size=\"size\">\n <svg :viewBox=\"viewBox\" :width=\"width\" :height=\"height\">\n <SVGNodeTorso :type=\"type\" :icon=\"icon\" :is-component=\"isComponent\" />\n <template v-if=\"!hidePorts\">\n <KdsPortIcon\n v-for=\"(port, index) in visibleInPorts\"\n :key=\"`in-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(-${PORT_SIZE / 2}, ${yPortShift(index, visibleInPorts.length)})`\"\n />\n <KdsPortIcon\n v-for=\"(port, index) in visibleOutPorts\"\n :key=\"`out-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(${NODE_SIZE + PORT_SIZE / 2}, ${yPortShift(index, visibleOutPorts.length)})`\"\n />\n </template>\n </svg>\n <div v-if=\"!hideIndicators\" class=\"indicators\">\n <KdsIcon v-if=\"indicatorIcon\" :name=\"indicatorIcon\" size=\"small\" />\n <KdsIcon\n v-if=\"numberOfHiddenPorts > 0 && !hidePorts\"\n name=\"more-connections\"\n aria-label=\"Indication that some ports are hidden\"\n size=\"small\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.node-preview {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-25x);\n width: calc(v-bind(width) * 1px);\n\n /*\n * `zoom` is used instead of `transform: scale()` so that the shrunk size\n * is also reflected in the layout box, e.g. when placed in a flex or grid\n * container alongside other elements.\n */\n &[data-size=\"small\"] {\n zoom: calc(12 / v-bind(NODE_SIZE));\n }\n\n &[data-size=\"medium\"] {\n zoom: 0.5;\n }\n\n & .indicators {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n justify-content: center;\n height: var(--kds-dimension-icon-0-75x);\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsIcon, KdsPortIcon, PORT_SIZE } from \"@knime/kds-components\";\n\nimport SVGNodeTorso from \"./SVGNodeTorso.vue\";\nimport { NODE_SIZE } from \"./constants\";\nimport type { NodePreviewProps, Port } from \"./types\";\n\n/**\n * SVG icon preview for a node or component, generated from its attributes\n */\nconst {\n type = null,\n isComponent = false,\n inPorts = [],\n outPorts = [],\n hidePorts = false,\n hideIndicators = false,\n size = \"xlarge\",\n indicatorIcon = undefined,\n icon = null,\n} = defineProps<NodePreviewProps>();\n\nconst horizontalSpaceForPorts = computed(() => (hidePorts ? 0 : PORT_SIZE));\n\nconst width = computed(() => NODE_SIZE + 2 * horizontalSpaceForPorts.value);\nconst height = NODE_SIZE;\nconst viewBox = computed(\n () => `-${horizontalSpaceForPorts.value} 0 ${width.value} ${height}`,\n);\n\n// top edge of port icon relative to 32x32 background\nfunction yPortShift(index: number, total: number): number {\n /* eslint-disable no-magic-numbers */\n let spacing = 1;\n if (total === 2) {\n spacing = 12;\n } else if (total === 3) {\n spacing = 2;\n }\n /* eslint-enable no-magic-numbers */\n\n const totalHeight = total * PORT_SIZE + (total - 1) * spacing;\n const delta = (NODE_SIZE - totalHeight) / 2;\n return (spacing + PORT_SIZE) * index + delta + PORT_SIZE / 2;\n}\n\nconst maxShownPorts = 3;\n\nconst cutOffPorts = (ports: Port[]) => {\n if (ports.length > maxShownPorts) {\n return [...ports.slice(0, maxShownPorts)];\n }\n return ports;\n};\n\nconst visibleInPorts = computed(() => cutOffPorts(inPorts));\nconst visibleOutPorts = computed(() => cutOffPorts(outPorts));\nconst numberOfHiddenPorts = computed(\n () =>\n inPorts.length -\n visibleInPorts.value.length +\n outPorts.length -\n visibleOutPorts.value.length,\n);\n</script>\n\n<template>\n <div class=\"node-preview\" :data-size=\"size\">\n <svg :viewBox=\"viewBox\" :width=\"width\" :height=\"height\">\n <SVGNodeTorso :type=\"type\" :icon=\"icon\" :is-component=\"isComponent\" />\n <template v-if=\"!hidePorts\">\n <KdsPortIcon\n v-for=\"(port, index) in visibleInPorts\"\n :key=\"`in-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(-${PORT_SIZE / 2}, ${yPortShift(index, visibleInPorts.length)})`\"\n />\n <KdsPortIcon\n v-for=\"(port, index) in visibleOutPorts\"\n :key=\"`out-${index}`\"\n :color=\"port.color\"\n :optional=\"port.optional\"\n :type=\"port.type\"\n :standalone=\"false\"\n :transform=\"`translate(${NODE_SIZE + PORT_SIZE / 2}, ${yPortShift(index, visibleOutPorts.length)})`\"\n />\n </template>\n </svg>\n <div v-if=\"!hideIndicators\" class=\"indicators\">\n <KdsIcon v-if=\"indicatorIcon\" :name=\"indicatorIcon\" size=\"small\" />\n <KdsIcon\n v-if=\"numberOfHiddenPorts > 0 && !hidePorts\"\n name=\"more-connections\"\n aria-label=\"Indication that some ports are hidden\"\n size=\"small\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.node-preview {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-25x);\n width: calc(v-bind(width) * 1px);\n\n /*\n * `zoom` is used instead of `transform: scale()` so that the shrunk size\n * is also reflected in the layout box, e.g. when placed in a flex or grid\n * container alongside other elements.\n */\n &[data-size=\"small\"] {\n zoom: calc(12 / v-bind(NODE_SIZE));\n }\n\n &[data-size=\"medium\"] {\n zoom: 0.5;\n }\n\n & .indicators {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n justify-content: center;\n height: var(--kds-dimension-icon-0-75x);\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VersionHistory.vue.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/VersionHistory.vue"],"names":[],"mappings":"AAwIA,OAAO,KAAK,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAyQrE,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"VersionHistory.vue.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/VersionHistory.vue"],"names":[],"mappings":"AAyIA,OAAO,KAAK,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AA2QrE,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1,4 +1,4 @@
1
- import { NamedItemVersion, WithAvatar, WithLabels } from './types';
1
+ import { NamedItemVersion, RestoreOption, WithAvatar, WithLabels } from './types';
2
2
  type Props = {
3
3
  version: NamedItemVersion & WithAvatar & WithLabels;
4
4
  isSelected: boolean;
@@ -6,6 +6,7 @@ type Props = {
6
6
  hasEditCapability: boolean;
7
7
  isFirstItem: boolean;
8
8
  isLastItem: boolean;
9
+ restoreOption?: RestoreOption;
9
10
  };
10
11
  declare const __VLS_export: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
11
12
  select: (selectionStatus: boolean) => any;
@@ -1 +1 @@
1
- {"version":3,"file":"VersionItem.vue.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/VersionItem.vue"],"names":[],"mappings":"AAkIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAExE,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,gBAAgB,GAAG,UAAU,GAAG,UAAU,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AA0LF,QAAA,MAAM,YAAY;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"VersionItem.vue.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/VersionItem.vue"],"names":[],"mappings":"AA0IA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,UAAU,EACX,MAAM,SAAS,CAAC;AAEjB,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,gBAAgB,GAAG,UAAU,GAAG,UAAU,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AA4LF,QAAA,MAAM,YAAY;;;;;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -71,6 +71,10 @@ export type VersionLimit = {
71
71
  /** Maximum number of allowed versions. `undefined` means unlimited. */
72
72
  limit?: number;
73
73
  };
74
+ export type RestoreOption = {
75
+ disabled?: boolean;
76
+ subText?: string;
77
+ };
74
78
  export type VersionHistoryProps = {
75
79
  /** Whether the item has uncommitted/unversioned changes since the last savepoint. */
76
80
  hasUnversionedChanges: boolean;
@@ -94,6 +98,8 @@ export type VersionHistoryProps = {
94
98
  upgradeUrl?: string;
95
99
  /** Whether the item lives in a private space (affects limit messaging). */
96
100
  isPrivate?: boolean;
101
+ /** Props to pass to the restore version option. */
102
+ restoreOption?: RestoreOption;
97
103
  };
98
104
  export {};
99
105
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/versions/VersionHistory/types.ts"],"names":[],"mappings":"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"}
package/dist/versions.css CHANGED
@@ -80,24 +80,24 @@
80
80
  font: var(--kds-font-base-body-small-strong);
81
81
  }
82
82
 
83
- .content-wrapper[data-v-67c64c70] {
83
+ .content-wrapper[data-v-f6d78be1] {
84
84
  display: flex;
85
85
  flex-direction: column;
86
86
  gap: var(--kds-spacing-container-0-37x);
87
87
  }
88
- .labels-wrapper[data-v-67c64c70] {
88
+ .labels-wrapper[data-v-f6d78be1] {
89
89
  display: flex;
90
90
  flex-wrap: wrap;
91
91
  gap: var(--kds-spacing-container-0-25x) var(--kds-spacing-container-0-5x);
92
92
  align-items: center;
93
93
  }
94
94
 
95
- .version-history-wrapper[data-v-e775efff] {
95
+ .version-history-wrapper[data-v-a388b66e] {
96
96
  display: flex;
97
97
  flex-direction: column;
98
98
  gap: var(--kds-spacing-container-0-75x);
99
99
  }
100
- .load-more-button[data-v-e775efff] {
100
+ .load-more-button[data-v-a388b66e] {
101
101
  margin: 0 auto;
102
102
  }
103
103
 
package/dist/versions.js CHANGED
@@ -220,7 +220,8 @@ var VersionItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
220
220
  hasAdminRights: { type: Boolean },
221
221
  hasEditCapability: { type: Boolean },
222
222
  isFirstItem: { type: Boolean },
223
- isLastItem: { type: Boolean }
223
+ isLastItem: { type: Boolean },
224
+ restoreOption: {}
224
225
  },
225
226
  emits: [
226
227
  "select",
@@ -242,6 +243,8 @@ var VersionItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
242
243
  props.hasEditCapability && {
243
244
  id: "restore",
244
245
  text: "Restore this version",
246
+ subText: props.restoreOption?.subText,
247
+ disabled: props.restoreOption?.disabled,
245
248
  handler: () => emit("restore")
246
249
  },
247
250
  props.hasAdminRights && {
@@ -301,7 +304,7 @@ var VersionItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
301
304
  ]);
302
305
  };
303
306
  }
304
- }), [["__scopeId", "data-v-67c64c70"]]);
307
+ }), [["__scopeId", "data-v-f6d78be1"]]);
305
308
  //#endregion
306
309
  //#region src/versions/VersionHistory/VersionLimitInfo.vue?vue&type=script&setup=true&lang.ts
307
310
  var _hoisted_1$2 = { class: "content-wrapper" };
@@ -371,7 +374,8 @@ var VersionHistory_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
371
374
  hasEditCapability: { type: Boolean },
372
375
  versionLimit: {},
373
376
  upgradeUrl: {},
374
- isPrivate: { type: Boolean }
377
+ isPrivate: { type: Boolean },
378
+ restoreOption: {}
375
379
  },
376
380
  emits: [
377
381
  "close",
@@ -431,6 +435,7 @@ var VersionHistory_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
431
435
  "has-edit-capability": __props.hasEditCapability,
432
436
  "is-first-item": !__props.unversionedSavepoint && index === 0,
433
437
  "is-last-item": index === __props.versionHistory.length - 1 && __props.versionLimit?.limit === void 0,
438
+ "restore-option": __props.restoreOption,
434
439
  onDelete: ($event) => _ctx.$emit("delete", historyEvent.version),
435
440
  onRestore: ($event) => _ctx.$emit("restore", historyEvent.version),
436
441
  onSelect: ($event) => _ctx.$emit("select", $event ? historyEvent.version : unref(CURRENT_STATE_VERSION))
@@ -441,6 +446,7 @@ var VersionHistory_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
441
446
  "has-edit-capability",
442
447
  "is-first-item",
443
448
  "is-last-item",
449
+ "restore-option",
444
450
  "onDelete",
445
451
  "onRestore",
446
452
  "onSelect"
@@ -473,7 +479,7 @@ var VersionHistory_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
473
479
  }, 8, ["headline-trailing-actions"]);
474
480
  };
475
481
  }
476
- }), [["__scopeId", "data-v-e775efff"]]);
482
+ }), [["__scopeId", "data-v-a388b66e"]]);
477
483
  //#endregion
478
484
  //#region src/versions/CreateVersionForm/CreateVersionForm.vue?vue&type=script&setup=true&lang.ts
479
485
  var _hoisted_1 = { class: "create-version-form-wrapper" };
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","names":["$emit","$emit"],"sources":["../src/versions/VersionHistory/HistoryEvent.vue","../src/versions/VersionHistory/HistoryEvent.vue","../src/versions/VersionHistory/HistoryEventAuthor.vue","../src/versions/VersionHistory/HistoryEventAuthor.vue","../src/versions/VersionHistory/HistoryEventFooter.vue","../src/versions/VersionHistory/HistoryEventFooter.vue","../src/versions/VersionHistory/CurrentState.vue","../src/versions/VersionHistory/CurrentState.vue","../src/versions/VersionHistory/VersionLabel.vue","../src/versions/VersionHistory/VersionLabel.vue","../src/versions/VersionHistory/VersionItem.vue","../src/versions/VersionHistory/VersionItem.vue","../src/versions/VersionHistory/VersionLimitInfo.vue","../src/versions/VersionHistory/VersionLimitInfo.vue","../src/versions/VersionHistory/constants.ts","../src/versions/VersionHistory/VersionHistory.vue","../src/versions/VersionHistory/VersionHistory.vue","../src/versions/CreateVersionForm/CreateVersionForm.vue","../src/versions/CreateVersionForm/CreateVersionForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { KdsIcon } from \"@knime/kds-components\";\n\ntype Props = {\n isSelected: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"history-event-wrapper\">\n <div class=\"history-event-decorator\">\n <div v-if=\"!isFirstItem\" class=\"history-event-line-top\" />\n <KdsIcon\n class=\"history-event-icon\"\n :name=\"isSelected ? 'circle-success' : 'circle-unchecked'\"\n size=\"small\"\n />\n <div v-if=\"!isLastItem\" class=\"history-event-line-bottom\" />\n </div>\n\n <div class=\"card-wrapper\">\n <slot />\n </div>\n </div>\n</template>\n\n<style scoped>\n.history-event-wrapper {\n display: flex;\n}\n\n.history-event-decorator {\n position: relative;\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n width: var(--kds-dimension-component-width-0-75x);\n margin: 0 var(--kds-spacing-container-0-75x);\n}\n\n.history-event-line-top {\n position: absolute;\n top: calc(var(--kds-spacing-container-0-37x) * -1);\n height: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x)\n );\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-line-bottom {\n position: absolute;\n top: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x) +\n var(--kds-spacing-container-0-37x)\n );\n bottom: calc(var(--kds-spacing-container-0-37x) * -1);\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-icon {\n position: absolute;\n top: var(--kds-spacing-container-1x);\n}\n\n.card-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsIcon } from \"@knime/kds-components\";\n\ntype Props = {\n isSelected: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"history-event-wrapper\">\n <div class=\"history-event-decorator\">\n <div v-if=\"!isFirstItem\" class=\"history-event-line-top\" />\n <KdsIcon\n class=\"history-event-icon\"\n :name=\"isSelected ? 'circle-success' : 'circle-unchecked'\"\n size=\"small\"\n />\n <div v-if=\"!isLastItem\" class=\"history-event-line-bottom\" />\n </div>\n\n <div class=\"card-wrapper\">\n <slot />\n </div>\n </div>\n</template>\n\n<style scoped>\n.history-event-wrapper {\n display: flex;\n}\n\n.history-event-decorator {\n position: relative;\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n width: var(--kds-dimension-component-width-0-75x);\n margin: 0 var(--kds-spacing-container-0-75x);\n}\n\n.history-event-line-top {\n position: absolute;\n top: calc(var(--kds-spacing-container-0-37x) * -1);\n height: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x)\n );\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-line-bottom {\n position: absolute;\n top: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x) +\n var(--kds-spacing-container-0-37x)\n );\n bottom: calc(var(--kds-spacing-container-0-37x) * -1);\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-icon {\n position: absolute;\n top: var(--kds-spacing-container-1x);\n}\n\n.card-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsAvatar } from \"@knime/kds-components\";\n\nimport type { WithAvatar } from \"./types\";\n\ntype Props = WithAvatar & {\n author: string;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"avatar-and-name-wrapper\">\n <KdsAvatar v-bind=\"avatar\" />\n <span class=\"author-name\">{{ author }}</span>\n </div>\n</template>\n\n<style scoped>\n.avatar-and-name-wrapper {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n align-items: center;\n}\n\n.author-name {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-neutral);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsAvatar } from \"@knime/kds-components\";\n\nimport type { WithAvatar } from \"./types\";\n\ntype Props = WithAvatar & {\n author: string;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"avatar-and-name-wrapper\">\n <KdsAvatar v-bind=\"avatar\" />\n <span class=\"author-name\">{{ author }}</span>\n </div>\n</template>\n\n<style scoped>\n.avatar-and-name-wrapper {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n align-items: center;\n}\n\n.author-name {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-neutral);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { vKdsTooltip } from \"@knime/kds-components\";\nimport { formatDateTimeString, formatLocalDateTimeString } from \"@knime/utils\";\n\nimport type { NamedItemVersion } from \"./types\";\n\ntype Props = {\n date: string;\n version?: NamedItemVersion[\"version\"];\n};\n\nconst { version, date } = defineProps<Props>();\n\n// Render the hidden non-local format on the server / first paint to reserve the\n// space and avoid content jumping once the localized value swaps in after mount\nconst isMounted = ref(false);\nconst localDateTime = computed(() =>\n isMounted.value\n ? formatLocalDateTimeString(date, true)\n : formatDateTimeString(date, true),\n);\n\nonMounted(() => {\n isMounted.value = true;\n});\n</script>\n\n<template>\n <span class=\"history-event-footer\">\n Created on\n <time\n v-kds-tooltip=\"date\"\n :datetime=\"date\"\n :class=\"{ hidden: !isMounted }\"\n >{{ localDateTime }}</time\n >\n <template v-if=\"version\">– Version {{ version }}</template>\n </span>\n</template>\n\n<style scoped>\n.history-event-footer {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-subtle);\n}\n\n.hidden {\n visibility: hidden;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { vKdsTooltip } from \"@knime/kds-components\";\nimport { formatDateTimeString, formatLocalDateTimeString } from \"@knime/utils\";\n\nimport type { NamedItemVersion } from \"./types\";\n\ntype Props = {\n date: string;\n version?: NamedItemVersion[\"version\"];\n};\n\nconst { version, date } = defineProps<Props>();\n\n// Render the hidden non-local format on the server / first paint to reserve the\n// space and avoid content jumping once the localized value swaps in after mount\nconst isMounted = ref(false);\nconst localDateTime = computed(() =>\n isMounted.value\n ? formatLocalDateTimeString(date, true)\n : formatDateTimeString(date, true),\n);\n\nonMounted(() => {\n isMounted.value = true;\n});\n</script>\n\n<template>\n <span class=\"history-event-footer\">\n Created on\n <time\n v-kds-tooltip=\"date\"\n :datetime=\"date\"\n :class=\"{ hidden: !isMounted }\"\n >{{ localDateTime }}</time\n >\n <template v-if=\"version\">– Version {{ version }}</template>\n </span>\n</template>\n\n<style scoped>\n.history-event-footer {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-subtle);\n}\n\n.hidden {\n visibility: hidden;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport type { ItemSavepoint, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n currentSavepoint: ItemSavepoint & WithAvatar & WithLabels;\n isSelected: boolean;\n hasEditCapability: boolean;\n hasPreviousVersion: boolean;\n hasVersionLimit: boolean;\n isVersionLimitExceeded?: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n createVersion: [];\n discard: [];\n select: [];\n}>();\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n props.hasEditCapability && props.hasPreviousVersion\n ? [\n {\n id: \"discard\",\n text: \"Discard\",\n handler: () => emit(\"discard\"),\n },\n ]\n : [],\n);\n</script>\n\n<template>\n <HistoryEvent\n :is-selected\n is-first-item\n :is-last-item=\"!hasPreviousVersion && !hasVersionLimit\"\n >\n <KdsSelectableCard\n :model-value=\"isSelected\"\n headline=\"Draft\"\n ariaLabel=\"Savepoint history event\"\n @update:model-value=\"!isSelected && $emit('select')\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor\n :author=\"currentSavepoint.author\"\n :avatar=\"currentSavepoint.avatar\"\n />\n\n <HistoryEventFooter :date=\"currentSavepoint.lastEditedOn\" />\n </div>\n </KdsSelectableCard>\n\n <KdsButton\n v-if=\"hasEditCapability && !isVersionLimitExceeded\"\n label=\"Create version\"\n @click.stop=\"$emit('createVersion')\"\n />\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport type { ItemSavepoint, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n currentSavepoint: ItemSavepoint & WithAvatar & WithLabels;\n isSelected: boolean;\n hasEditCapability: boolean;\n hasPreviousVersion: boolean;\n hasVersionLimit: boolean;\n isVersionLimitExceeded?: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n createVersion: [];\n discard: [];\n select: [];\n}>();\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n props.hasEditCapability && props.hasPreviousVersion\n ? [\n {\n id: \"discard\",\n text: \"Discard\",\n handler: () => emit(\"discard\"),\n },\n ]\n : [],\n);\n</script>\n\n<template>\n <HistoryEvent\n :is-selected\n is-first-item\n :is-last-item=\"!hasPreviousVersion && !hasVersionLimit\"\n >\n <KdsSelectableCard\n :model-value=\"isSelected\"\n headline=\"Draft\"\n ariaLabel=\"Savepoint history event\"\n @update:model-value=\"!isSelected && $emit('select')\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor\n :author=\"currentSavepoint.author\"\n :avatar=\"currentSavepoint.avatar\"\n />\n\n <HistoryEventFooter :date=\"currentSavepoint.lastEditedOn\" />\n </div>\n </KdsSelectableCard>\n\n <KdsButton\n v-if=\"hasEditCapability && !isVersionLimitExceeded\"\n label=\"Create version\"\n @click.stop=\"$emit('createVersion')\"\n />\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPopover,\n type KdsPopoverExpose,\n KdsToggleButton,\n} from \"@knime/kds-components\";\n\nimport type { AssignedLabel } from \"./types\";\n\ntype Props = {\n label: AssignedLabel;\n};\n\ndefineProps<Props>();\n\nconst isPopoverOpen = defineModel<boolean>({ default: false });\nconst popoverEl = useTemplateRef<KdsPopoverExpose>(\"popover\");\n</script>\n\n<template>\n <KdsToggleButton\n v-model=\"isPopoverOpen\"\n data-kds-card-secondary-action\n :label=\"label.label.name\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isPopoverOpen\"\n :aria-controls=\"popoverEl?.popoverId\"\n size=\"xsmall\"\n :style=\"popoverEl?.anchorStyle\"\n />\n\n <KdsPopover\n ref=\"popover\"\n v-model=\"isPopoverOpen\"\n placement=\"bottom-left\"\n role=\"dialog\"\n aria-label=\"Label details\"\n >\n <div class=\"label-popover-container\">\n <div class=\"label-title\">{{ label.label.name }}</div>\n <KdsDescription :text=\"label.label.description\" />\n <KdsDescription v-if=\"label.message\" :text=\"label.message\" />\n </div>\n </KdsPopover>\n</template>\n\n<style scoped>\n.label-popover-container {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n align-items: flex-start;\n max-width: var(--kds-dimension-component-width-20x);\n max-height: var(--kds-dimension-component-height-20x);\n padding: var(--kds-spacing-container-0-75x) var(--kds-spacing-container-1x);\n overflow-y: auto;\n background-color: var(--kds-color-surface-default);\n border-radius: var(--kds-border-radius-container-0-50x);\n box-shadow: var(--kds-elevation-level-3);\n}\n\n.label-title {\n font: var(--kds-font-base-body-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPopover,\n type KdsPopoverExpose,\n KdsToggleButton,\n} from \"@knime/kds-components\";\n\nimport type { AssignedLabel } from \"./types\";\n\ntype Props = {\n label: AssignedLabel;\n};\n\ndefineProps<Props>();\n\nconst isPopoverOpen = defineModel<boolean>({ default: false });\nconst popoverEl = useTemplateRef<KdsPopoverExpose>(\"popover\");\n</script>\n\n<template>\n <KdsToggleButton\n v-model=\"isPopoverOpen\"\n data-kds-card-secondary-action\n :label=\"label.label.name\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isPopoverOpen\"\n :aria-controls=\"popoverEl?.popoverId\"\n size=\"xsmall\"\n :style=\"popoverEl?.anchorStyle\"\n />\n\n <KdsPopover\n ref=\"popover\"\n v-model=\"isPopoverOpen\"\n placement=\"bottom-left\"\n role=\"dialog\"\n aria-label=\"Label details\"\n >\n <div class=\"label-popover-container\">\n <div class=\"label-title\">{{ label.label.name }}</div>\n <KdsDescription :text=\"label.label.description\" />\n <KdsDescription v-if=\"label.message\" :text=\"label.message\" />\n </div>\n </KdsPopover>\n</template>\n\n<style scoped>\n.label-popover-container {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n align-items: flex-start;\n max-width: var(--kds-dimension-component-width-20x);\n max-height: var(--kds-dimension-component-height-20x);\n padding: var(--kds-spacing-container-0-75x) var(--kds-spacing-container-1x);\n overflow-y: auto;\n background-color: var(--kds-color-surface-default);\n border-radius: var(--kds-border-radius-container-0-50x);\n box-shadow: var(--kds-elevation-level-3);\n}\n\n.label-title {\n font: var(--kds-font-base-body-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsDescription,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport VersionLabel from \"./VersionLabel.vue\";\nimport type { NamedItemVersion, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n version: NamedItemVersion & WithAvatar & WithLabels;\n isSelected: boolean;\n hasAdminRights: boolean;\n hasEditCapability: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n select: [selectionStatus: boolean];\n delete: [];\n restore: [];\n}>();\n\nconst toggleVersionSelection = () => {\n emit(\"select\", !props.isSelected);\n};\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n [\n props.hasEditCapability && {\n id: \"show\",\n text: props.isSelected ? \"Deselect this version\" : \"Show this version\",\n handler: toggleVersionSelection,\n },\n props.hasEditCapability && {\n id: \"restore\",\n text: \"Restore this version\",\n handler: () => emit(\"restore\"),\n },\n props.hasAdminRights && {\n id: \"delete\",\n text: \"Delete this version\",\n handler: () => emit(\"delete\"),\n },\n ].filter((i) => i !== false),\n);\n</script>\n\n<template>\n <HistoryEvent :is-selected :is-first-item :is-last-item>\n <KdsSelectableCard\n :model-value=\"isSelected\"\n :headline=\"version.title\"\n ariaLabel=\"Version history event\"\n @update:model-value=\"toggleVersionSelection\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor :author=\"version.author\" :avatar=\"version.avatar\" />\n\n <KdsDescription\n v-if=\"version.description\"\n :text=\"version.description\"\n />\n\n <div class=\"labels-wrapper\">\n <VersionLabel\n v-for=\"label in version.labels\"\n :key=\"label.labelId\"\n :label=\"label\"\n />\n </div>\n\n <HistoryEventFooter\n :version=\"version.version\"\n :date=\"version.createdOn\"\n />\n </div>\n </KdsSelectableCard>\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n\n.labels-wrapper {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kds-spacing-container-0-25x) var(--kds-spacing-container-0-5x);\n align-items: center;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsDescription,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport VersionLabel from \"./VersionLabel.vue\";\nimport type { NamedItemVersion, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n version: NamedItemVersion & WithAvatar & WithLabels;\n isSelected: boolean;\n hasAdminRights: boolean;\n hasEditCapability: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n select: [selectionStatus: boolean];\n delete: [];\n restore: [];\n}>();\n\nconst toggleVersionSelection = () => {\n emit(\"select\", !props.isSelected);\n};\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n [\n props.hasEditCapability && {\n id: \"show\",\n text: props.isSelected ? \"Deselect this version\" : \"Show this version\",\n handler: toggleVersionSelection,\n },\n props.hasEditCapability && {\n id: \"restore\",\n text: \"Restore this version\",\n handler: () => emit(\"restore\"),\n },\n props.hasAdminRights && {\n id: \"delete\",\n text: \"Delete this version\",\n handler: () => emit(\"delete\"),\n },\n ].filter((i) => i !== false),\n);\n</script>\n\n<template>\n <HistoryEvent :is-selected :is-first-item :is-last-item>\n <KdsSelectableCard\n :model-value=\"isSelected\"\n :headline=\"version.title\"\n ariaLabel=\"Version history event\"\n @update:model-value=\"toggleVersionSelection\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor :author=\"version.author\" :avatar=\"version.avatar\" />\n\n <KdsDescription\n v-if=\"version.description\"\n :text=\"version.description\"\n />\n\n <div class=\"labels-wrapper\">\n <VersionLabel\n v-for=\"label in version.labels\"\n :key=\"label.labelId\"\n :label=\"label\"\n />\n </div>\n\n <HistoryEventFooter\n :version=\"version.version\"\n :date=\"version.createdOn\"\n />\n </div>\n </KdsSelectableCard>\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n\n.labels-wrapper {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kds-spacing-container-0-25x) var(--kds-spacing-container-0-5x);\n align-items: center;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsCard, KdsDescription, KdsLinkButton } from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport type { VersionLimit } from \"./types\";\n\nconst {\n versionLimit,\n upgradeUrl = undefined,\n isPrivate = false,\n} = defineProps<{\n versionLimit: Required<VersionLimit>;\n upgradeUrl?: string;\n isPrivate?: boolean;\n}>();\n\nconst isLimitReached = computed(\n () => versionLimit.currentUsage >= versionLimit.limit,\n);\n\nconst headline = computed(() => {\n if (isLimitReached.value) {\n return `You've reached the maximum of ${versionLimit.limit} versions.`;\n } else {\n return `Using ${versionLimit.currentUsage} of ${versionLimit.limit} versions.`;\n }\n});\n</script>\n\n<template>\n <HistoryEvent :is-selected=\"false\" :is-first-item=\"false\" is-last-item>\n <KdsCard variant=\"filled\" :headline=\"headline\">\n <template v-if=\"upgradeUrl\" #header-actions>\n <KdsLinkButton label=\"Upgrade\" :to=\"upgradeUrl\" />\n </template>\n\n <div class=\"content-wrapper\">\n <KdsDescription\n :text=\"`Upgrade to use unlimited versions${isPrivate ? ' for private items.' : '.'}`\"\n />\n </div>\n </KdsCard>\n </HistoryEvent>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsCard, KdsDescription, KdsLinkButton } from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport type { VersionLimit } from \"./types\";\n\nconst {\n versionLimit,\n upgradeUrl = undefined,\n isPrivate = false,\n} = defineProps<{\n versionLimit: Required<VersionLimit>;\n upgradeUrl?: string;\n isPrivate?: boolean;\n}>();\n\nconst isLimitReached = computed(\n () => versionLimit.currentUsage >= versionLimit.limit,\n);\n\nconst headline = computed(() => {\n if (isLimitReached.value) {\n return `You've reached the maximum of ${versionLimit.limit} versions.`;\n } else {\n return `Using ${versionLimit.currentUsage} of ${versionLimit.limit} versions.`;\n }\n});\n</script>\n\n<template>\n <HistoryEvent :is-selected=\"false\" :is-first-item=\"false\" is-last-item>\n <KdsCard variant=\"filled\" :headline=\"headline\">\n <template v-if=\"upgradeUrl\" #header-actions>\n <KdsLinkButton label=\"Upgrade\" :to=\"upgradeUrl\" />\n </template>\n\n <div class=\"content-wrapper\">\n <KdsDescription\n :text=\"`Upgrade to use unlimited versions${isPrivate ? ' for private items.' : '.'}`\"\n />\n </div>\n </KdsCard>\n </HistoryEvent>\n</template>\n","export const VERSION_DEFAULT_LIMIT = 10;\nexport const CURRENT_STATE_VERSION = \"current-state\";\nexport const MOST_RECENT_VERSION = \"most-recent\";\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n KdsPanel,\n type KdsPanelHeadlineTrailingAction,\n} from \"@knime/kds-components\";\n\nimport CurrentState from \"./CurrentState.vue\";\nimport VersionItem from \"./VersionItem.vue\";\nimport VersionLimitInfo from \"./VersionLimitInfo.vue\";\nimport { CURRENT_STATE_VERSION } from \"./constants\";\nimport type { NamedItemVersion, VersionHistoryProps } from \"./types\";\n\nconst props = defineProps<VersionHistoryProps>();\n\nconst emit = defineEmits<{\n close: [];\n loadAll: [];\n create: [];\n delete: [version: NamedItemVersion[\"version\"]];\n restore: [version: NamedItemVersion[\"version\"]];\n select: [version: NamedItemVersion[\"version\"]];\n discardCurrentState: [];\n}>();\n\nconst isVersionLimitExceeded = computed(() => {\n return (\n props.versionLimit?.limit !== undefined &&\n props.versionLimit.currentUsage >= props.versionLimit.limit\n );\n});\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"close\"),\n },\n ],\n);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Version history\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n >\n <div class=\"version-history-wrapper\">\n <CurrentState\n v-if=\"unversionedSavepoint\"\n :current-savepoint=\"unversionedSavepoint\"\n :is-selected=\"currentVersion === CURRENT_STATE_VERSION\"\n :has-edit-capability=\"hasEditCapability\"\n :has-previous-version=\"versionHistory.length > 0\"\n :has-version-limit=\"versionLimit?.limit !== undefined\"\n :is-version-limit-exceeded=\"isVersionLimitExceeded\"\n @select=\"$emit('select', CURRENT_STATE_VERSION)\"\n @create-version=\"$emit('create')\"\n @discard=\"$emit('discardCurrentState')\"\n />\n\n <VersionItem\n v-for=\"(historyEvent, index) in versionHistory\"\n :key=\"historyEvent.version\"\n :version=\"historyEvent\"\n :is-selected=\"historyEvent.version === currentVersion\"\n :has-admin-rights=\"hasAdminRights\"\n :has-edit-capability=\"hasEditCapability\"\n :is-first-item=\"!unversionedSavepoint && index === 0\"\n :is-last-item=\"\n index === versionHistory.length - 1 &&\n versionLimit?.limit === undefined\n \"\n @delete=\"$emit('delete', historyEvent.version)\"\n @restore=\"$emit('restore', historyEvent.version)\"\n @select=\"\n $emit('select', $event ? historyEvent.version : CURRENT_STATE_VERSION)\n \"\n />\n\n <VersionLimitInfo\n v-if=\"versionLimit?.limit !== undefined\"\n class=\"version-limit-info\"\n :version-limit=\"{\n limit: versionLimit.limit,\n currentUsage: versionLimit.currentUsage,\n }\"\n :upgrade-url\n :is-private\n />\n\n <KdsButton\n v-if=\"!hasLoadedAllVersions\"\n variant=\"transparent\"\n :disabled=\"loading\"\n :label=\"loading ? 'Loading...' : 'Load all'\"\n class=\"load-more-button\"\n @click=\"$emit('loadAll')\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.version-history-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n}\n\n.load-more-button {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n KdsPanel,\n type KdsPanelHeadlineTrailingAction,\n} from \"@knime/kds-components\";\n\nimport CurrentState from \"./CurrentState.vue\";\nimport VersionItem from \"./VersionItem.vue\";\nimport VersionLimitInfo from \"./VersionLimitInfo.vue\";\nimport { CURRENT_STATE_VERSION } from \"./constants\";\nimport type { NamedItemVersion, VersionHistoryProps } from \"./types\";\n\nconst props = defineProps<VersionHistoryProps>();\n\nconst emit = defineEmits<{\n close: [];\n loadAll: [];\n create: [];\n delete: [version: NamedItemVersion[\"version\"]];\n restore: [version: NamedItemVersion[\"version\"]];\n select: [version: NamedItemVersion[\"version\"]];\n discardCurrentState: [];\n}>();\n\nconst isVersionLimitExceeded = computed(() => {\n return (\n props.versionLimit?.limit !== undefined &&\n props.versionLimit.currentUsage >= props.versionLimit.limit\n );\n});\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"close\"),\n },\n ],\n);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Version history\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n >\n <div class=\"version-history-wrapper\">\n <CurrentState\n v-if=\"unversionedSavepoint\"\n :current-savepoint=\"unversionedSavepoint\"\n :is-selected=\"currentVersion === CURRENT_STATE_VERSION\"\n :has-edit-capability=\"hasEditCapability\"\n :has-previous-version=\"versionHistory.length > 0\"\n :has-version-limit=\"versionLimit?.limit !== undefined\"\n :is-version-limit-exceeded=\"isVersionLimitExceeded\"\n @select=\"$emit('select', CURRENT_STATE_VERSION)\"\n @create-version=\"$emit('create')\"\n @discard=\"$emit('discardCurrentState')\"\n />\n\n <VersionItem\n v-for=\"(historyEvent, index) in versionHistory\"\n :key=\"historyEvent.version\"\n :version=\"historyEvent\"\n :is-selected=\"historyEvent.version === currentVersion\"\n :has-admin-rights=\"hasAdminRights\"\n :has-edit-capability=\"hasEditCapability\"\n :is-first-item=\"!unversionedSavepoint && index === 0\"\n :is-last-item=\"\n index === versionHistory.length - 1 &&\n versionLimit?.limit === undefined\n \"\n @delete=\"$emit('delete', historyEvent.version)\"\n @restore=\"$emit('restore', historyEvent.version)\"\n @select=\"\n $emit('select', $event ? historyEvent.version : CURRENT_STATE_VERSION)\n \"\n />\n\n <VersionLimitInfo\n v-if=\"versionLimit?.limit !== undefined\"\n class=\"version-limit-info\"\n :version-limit=\"{\n limit: versionLimit.limit,\n currentUsage: versionLimit.currentUsage,\n }\"\n :upgrade-url\n :is-private\n />\n\n <KdsButton\n v-if=\"!hasLoadedAllVersions\"\n variant=\"transparent\"\n :disabled=\"loading\"\n :label=\"loading ? 'Loading...' : 'Load all'\"\n class=\"load-more-button\"\n @click=\"$emit('loadAll')\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.version-history-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n}\n\n.load-more-button {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPanel,\n type KdsPanelButtonAction,\n type KdsPanelHeadlineTrailingAction,\n KdsTextInput,\n KdsTextarea,\n} from \"@knime/kds-components\";\n\nimport type { CreateVersionFormProps } from \"./types\";\n\nconst { isCreationPending = false } = defineProps<CreateVersionFormProps>();\n\nconst emit = defineEmits<{\n create: [{ name: string; description: string }];\n cancel: [hasUnsavedChanges: boolean];\n}>();\n\nconst versionName = ref(\"\");\nconst versionDescription = ref(\"\");\n\nconst doValidate = ref(false);\n\nconst isVersionNameInvalid = computed(() => {\n return doValidate.value && versionName.value.trim().length <= 0;\n});\n\nconst hasUnsavedChanges = computed(() => {\n return versionName.value !== \"\" || versionDescription.value !== \"\";\n});\n\nconst onCreate = async () => {\n doValidate.value = true;\n await nextTick();\n\n if (!isVersionNameInvalid.value) {\n emit(\"create\", {\n name: versionName.value.trim(),\n description: versionDescription.value,\n });\n }\n};\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n ],\n);\n\nconst footerLeadingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Cancel\",\n variant: \"outlined\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n]);\n\nconst footerTrailingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Create\",\n variant: \"filled\",\n disabled: isVersionNameInvalid.value || isCreationPending,\n },\n onClick: onCreate,\n },\n]);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Create version\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n :footer-leading-actions=\"footerLeadingActions\"\n :footer-trailing-actions=\"footerTrailingActions\"\n >\n <div class=\"create-version-form-wrapper\">\n <KdsDescription\n text=\"Give your version a name and description. Versions can be used to create a deployment.\"\n class=\"create-version-form-description\"\n />\n\n <KdsTextInput\n v-model=\"versionName\"\n label=\"Version name\"\n type=\"text\"\n :error=\"isVersionNameInvalid\"\n :sub-text=\"\n isVersionNameInvalid\n ? 'Please enter at least 1 character.'\n : undefined\n \"\n />\n\n <KdsTextarea\n v-model=\"versionDescription\"\n label=\"Description\"\n class=\"description\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.create-version-form-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-1x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPanel,\n type KdsPanelButtonAction,\n type KdsPanelHeadlineTrailingAction,\n KdsTextInput,\n KdsTextarea,\n} from \"@knime/kds-components\";\n\nimport type { CreateVersionFormProps } from \"./types\";\n\nconst { isCreationPending = false } = defineProps<CreateVersionFormProps>();\n\nconst emit = defineEmits<{\n create: [{ name: string; description: string }];\n cancel: [hasUnsavedChanges: boolean];\n}>();\n\nconst versionName = ref(\"\");\nconst versionDescription = ref(\"\");\n\nconst doValidate = ref(false);\n\nconst isVersionNameInvalid = computed(() => {\n return doValidate.value && versionName.value.trim().length <= 0;\n});\n\nconst hasUnsavedChanges = computed(() => {\n return versionName.value !== \"\" || versionDescription.value !== \"\";\n});\n\nconst onCreate = async () => {\n doValidate.value = true;\n await nextTick();\n\n if (!isVersionNameInvalid.value) {\n emit(\"create\", {\n name: versionName.value.trim(),\n description: versionDescription.value,\n });\n }\n};\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n ],\n);\n\nconst footerLeadingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Cancel\",\n variant: \"outlined\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n]);\n\nconst footerTrailingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Create\",\n variant: \"filled\",\n disabled: isVersionNameInvalid.value || isCreationPending,\n },\n onClick: onCreate,\n },\n]);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Create version\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n :footer-leading-actions=\"footerLeadingActions\"\n :footer-trailing-actions=\"footerTrailingActions\"\n >\n <div class=\"create-version-form-wrapper\">\n <KdsDescription\n text=\"Give your version a name and description. Versions can be used to create a deployment.\"\n class=\"create-version-form-description\"\n />\n\n <KdsTextInput\n v-model=\"versionName\"\n label=\"Version name\"\n type=\"text\"\n :error=\"isVersionNameInvalid\"\n :sub-text=\"\n isVersionNameInvalid\n ? 'Please enter at least 1 character.'\n : undefined\n \"\n />\n\n <KdsTextarea\n v-model=\"versionDescription\"\n label=\"Description\"\n class=\"description\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.create-version-form-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-1x);\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"versions.js","names":["$emit","$emit"],"sources":["../src/versions/VersionHistory/HistoryEvent.vue","../src/versions/VersionHistory/HistoryEvent.vue","../src/versions/VersionHistory/HistoryEventAuthor.vue","../src/versions/VersionHistory/HistoryEventAuthor.vue","../src/versions/VersionHistory/HistoryEventFooter.vue","../src/versions/VersionHistory/HistoryEventFooter.vue","../src/versions/VersionHistory/CurrentState.vue","../src/versions/VersionHistory/CurrentState.vue","../src/versions/VersionHistory/VersionLabel.vue","../src/versions/VersionHistory/VersionLabel.vue","../src/versions/VersionHistory/VersionItem.vue","../src/versions/VersionHistory/VersionItem.vue","../src/versions/VersionHistory/VersionLimitInfo.vue","../src/versions/VersionHistory/VersionLimitInfo.vue","../src/versions/VersionHistory/constants.ts","../src/versions/VersionHistory/VersionHistory.vue","../src/versions/VersionHistory/VersionHistory.vue","../src/versions/CreateVersionForm/CreateVersionForm.vue","../src/versions/CreateVersionForm/CreateVersionForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { KdsIcon } from \"@knime/kds-components\";\n\ntype Props = {\n isSelected: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"history-event-wrapper\">\n <div class=\"history-event-decorator\">\n <div v-if=\"!isFirstItem\" class=\"history-event-line-top\" />\n <KdsIcon\n class=\"history-event-icon\"\n :name=\"isSelected ? 'circle-success' : 'circle-unchecked'\"\n size=\"small\"\n />\n <div v-if=\"!isLastItem\" class=\"history-event-line-bottom\" />\n </div>\n\n <div class=\"card-wrapper\">\n <slot />\n </div>\n </div>\n</template>\n\n<style scoped>\n.history-event-wrapper {\n display: flex;\n}\n\n.history-event-decorator {\n position: relative;\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n width: var(--kds-dimension-component-width-0-75x);\n margin: 0 var(--kds-spacing-container-0-75x);\n}\n\n.history-event-line-top {\n position: absolute;\n top: calc(var(--kds-spacing-container-0-37x) * -1);\n height: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x)\n );\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-line-bottom {\n position: absolute;\n top: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x) +\n var(--kds-spacing-container-0-37x)\n );\n bottom: calc(var(--kds-spacing-container-0-37x) * -1);\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-icon {\n position: absolute;\n top: var(--kds-spacing-container-1x);\n}\n\n.card-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsIcon } from \"@knime/kds-components\";\n\ntype Props = {\n isSelected: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"history-event-wrapper\">\n <div class=\"history-event-decorator\">\n <div v-if=\"!isFirstItem\" class=\"history-event-line-top\" />\n <KdsIcon\n class=\"history-event-icon\"\n :name=\"isSelected ? 'circle-success' : 'circle-unchecked'\"\n size=\"small\"\n />\n <div v-if=\"!isLastItem\" class=\"history-event-line-bottom\" />\n </div>\n\n <div class=\"card-wrapper\">\n <slot />\n </div>\n </div>\n</template>\n\n<style scoped>\n.history-event-wrapper {\n display: flex;\n}\n\n.history-event-decorator {\n position: relative;\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n width: var(--kds-dimension-component-width-0-75x);\n margin: 0 var(--kds-spacing-container-0-75x);\n}\n\n.history-event-line-top {\n position: absolute;\n top: calc(var(--kds-spacing-container-0-37x) * -1);\n height: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x)\n );\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-line-bottom {\n position: absolute;\n top: calc(\n var(--kds-spacing-container-1x) + var(--kds-spacing-container-0-37x) +\n var(--kds-spacing-container-0-37x)\n );\n bottom: calc(var(--kds-spacing-container-0-37x) * -1);\n border-left: var(--kds-border-base-subtle);\n}\n\n.history-event-icon {\n position: absolute;\n top: var(--kds-spacing-container-1x);\n}\n\n.card-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsAvatar } from \"@knime/kds-components\";\n\nimport type { WithAvatar } from \"./types\";\n\ntype Props = WithAvatar & {\n author: string;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"avatar-and-name-wrapper\">\n <KdsAvatar v-bind=\"avatar\" />\n <span class=\"author-name\">{{ author }}</span>\n </div>\n</template>\n\n<style scoped>\n.avatar-and-name-wrapper {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n align-items: center;\n}\n\n.author-name {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-neutral);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { KdsAvatar } from \"@knime/kds-components\";\n\nimport type { WithAvatar } from \"./types\";\n\ntype Props = WithAvatar & {\n author: string;\n};\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"avatar-and-name-wrapper\">\n <KdsAvatar v-bind=\"avatar\" />\n <span class=\"author-name\">{{ author }}</span>\n </div>\n</template>\n\n<style scoped>\n.avatar-and-name-wrapper {\n display: flex;\n gap: var(--kds-spacing-container-0-25x);\n align-items: center;\n}\n\n.author-name {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-neutral);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { vKdsTooltip } from \"@knime/kds-components\";\nimport { formatDateTimeString, formatLocalDateTimeString } from \"@knime/utils\";\n\nimport type { NamedItemVersion } from \"./types\";\n\ntype Props = {\n date: string;\n version?: NamedItemVersion[\"version\"];\n};\n\nconst { version, date } = defineProps<Props>();\n\n// Render the hidden non-local format on the server / first paint to reserve the\n// space and avoid content jumping once the localized value swaps in after mount\nconst isMounted = ref(false);\nconst localDateTime = computed(() =>\n isMounted.value\n ? formatLocalDateTimeString(date, true)\n : formatDateTimeString(date, true),\n);\n\nonMounted(() => {\n isMounted.value = true;\n});\n</script>\n\n<template>\n <span class=\"history-event-footer\">\n Created on\n <time\n v-kds-tooltip=\"date\"\n :datetime=\"date\"\n :class=\"{ hidden: !isMounted }\"\n >{{ localDateTime }}</time\n >\n <template v-if=\"version\">– Version {{ version }}</template>\n </span>\n</template>\n\n<style scoped>\n.history-event-footer {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-subtle);\n}\n\n.hidden {\n visibility: hidden;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { vKdsTooltip } from \"@knime/kds-components\";\nimport { formatDateTimeString, formatLocalDateTimeString } from \"@knime/utils\";\n\nimport type { NamedItemVersion } from \"./types\";\n\ntype Props = {\n date: string;\n version?: NamedItemVersion[\"version\"];\n};\n\nconst { version, date } = defineProps<Props>();\n\n// Render the hidden non-local format on the server / first paint to reserve the\n// space and avoid content jumping once the localized value swaps in after mount\nconst isMounted = ref(false);\nconst localDateTime = computed(() =>\n isMounted.value\n ? formatLocalDateTimeString(date, true)\n : formatDateTimeString(date, true),\n);\n\nonMounted(() => {\n isMounted.value = true;\n});\n</script>\n\n<template>\n <span class=\"history-event-footer\">\n Created on\n <time\n v-kds-tooltip=\"date\"\n :datetime=\"date\"\n :class=\"{ hidden: !isMounted }\"\n >{{ localDateTime }}</time\n >\n <template v-if=\"version\">– Version {{ version }}</template>\n </span>\n</template>\n\n<style scoped>\n.history-event-footer {\n font: var(--kds-font-base-subtext-small);\n color: var(--kds-color-text-and-icon-subtle);\n}\n\n.hidden {\n visibility: hidden;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport type { ItemSavepoint, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n currentSavepoint: ItemSavepoint & WithAvatar & WithLabels;\n isSelected: boolean;\n hasEditCapability: boolean;\n hasPreviousVersion: boolean;\n hasVersionLimit: boolean;\n isVersionLimitExceeded?: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n createVersion: [];\n discard: [];\n select: [];\n}>();\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n props.hasEditCapability && props.hasPreviousVersion\n ? [\n {\n id: \"discard\",\n text: \"Discard\",\n handler: () => emit(\"discard\"),\n },\n ]\n : [],\n);\n</script>\n\n<template>\n <HistoryEvent\n :is-selected\n is-first-item\n :is-last-item=\"!hasPreviousVersion && !hasVersionLimit\"\n >\n <KdsSelectableCard\n :model-value=\"isSelected\"\n headline=\"Draft\"\n ariaLabel=\"Savepoint history event\"\n @update:model-value=\"!isSelected && $emit('select')\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor\n :author=\"currentSavepoint.author\"\n :avatar=\"currentSavepoint.avatar\"\n />\n\n <HistoryEventFooter :date=\"currentSavepoint.lastEditedOn\" />\n </div>\n </KdsSelectableCard>\n\n <KdsButton\n v-if=\"hasEditCapability && !isVersionLimitExceeded\"\n label=\"Create version\"\n @click.stop=\"$emit('createVersion')\"\n />\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport type { ItemSavepoint, WithAvatar, WithLabels } from \"./types\";\n\ntype Props = {\n currentSavepoint: ItemSavepoint & WithAvatar & WithLabels;\n isSelected: boolean;\n hasEditCapability: boolean;\n hasPreviousVersion: boolean;\n hasVersionLimit: boolean;\n isVersionLimitExceeded?: boolean;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n createVersion: [];\n discard: [];\n select: [];\n}>();\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n props.hasEditCapability && props.hasPreviousVersion\n ? [\n {\n id: \"discard\",\n text: \"Discard\",\n handler: () => emit(\"discard\"),\n },\n ]\n : [],\n);\n</script>\n\n<template>\n <HistoryEvent\n :is-selected\n is-first-item\n :is-last-item=\"!hasPreviousVersion && !hasVersionLimit\"\n >\n <KdsSelectableCard\n :model-value=\"isSelected\"\n headline=\"Draft\"\n ariaLabel=\"Savepoint history event\"\n @update:model-value=\"!isSelected && $emit('select')\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor\n :author=\"currentSavepoint.author\"\n :avatar=\"currentSavepoint.avatar\"\n />\n\n <HistoryEventFooter :date=\"currentSavepoint.lastEditedOn\" />\n </div>\n </KdsSelectableCard>\n\n <KdsButton\n v-if=\"hasEditCapability && !isVersionLimitExceeded\"\n label=\"Create version\"\n @click.stop=\"$emit('createVersion')\"\n />\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPopover,\n type KdsPopoverExpose,\n KdsToggleButton,\n} from \"@knime/kds-components\";\n\nimport type { AssignedLabel } from \"./types\";\n\ntype Props = {\n label: AssignedLabel;\n};\n\ndefineProps<Props>();\n\nconst isPopoverOpen = defineModel<boolean>({ default: false });\nconst popoverEl = useTemplateRef<KdsPopoverExpose>(\"popover\");\n</script>\n\n<template>\n <KdsToggleButton\n v-model=\"isPopoverOpen\"\n data-kds-card-secondary-action\n :label=\"label.label.name\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isPopoverOpen\"\n :aria-controls=\"popoverEl?.popoverId\"\n size=\"xsmall\"\n :style=\"popoverEl?.anchorStyle\"\n />\n\n <KdsPopover\n ref=\"popover\"\n v-model=\"isPopoverOpen\"\n placement=\"bottom-left\"\n role=\"dialog\"\n aria-label=\"Label details\"\n >\n <div class=\"label-popover-container\">\n <div class=\"label-title\">{{ label.label.name }}</div>\n <KdsDescription :text=\"label.label.description\" />\n <KdsDescription v-if=\"label.message\" :text=\"label.message\" />\n </div>\n </KdsPopover>\n</template>\n\n<style scoped>\n.label-popover-container {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n align-items: flex-start;\n max-width: var(--kds-dimension-component-width-20x);\n max-height: var(--kds-dimension-component-height-20x);\n padding: var(--kds-spacing-container-0-75x) var(--kds-spacing-container-1x);\n overflow-y: auto;\n background-color: var(--kds-color-surface-default);\n border-radius: var(--kds-border-radius-container-0-50x);\n box-shadow: var(--kds-elevation-level-3);\n}\n\n.label-title {\n font: var(--kds-font-base-body-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useTemplateRef } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPopover,\n type KdsPopoverExpose,\n KdsToggleButton,\n} from \"@knime/kds-components\";\n\nimport type { AssignedLabel } from \"./types\";\n\ntype Props = {\n label: AssignedLabel;\n};\n\ndefineProps<Props>();\n\nconst isPopoverOpen = defineModel<boolean>({ default: false });\nconst popoverEl = useTemplateRef<KdsPopoverExpose>(\"popover\");\n</script>\n\n<template>\n <KdsToggleButton\n v-model=\"isPopoverOpen\"\n data-kds-card-secondary-action\n :label=\"label.label.name\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isPopoverOpen\"\n :aria-controls=\"popoverEl?.popoverId\"\n size=\"xsmall\"\n :style=\"popoverEl?.anchorStyle\"\n />\n\n <KdsPopover\n ref=\"popover\"\n v-model=\"isPopoverOpen\"\n placement=\"bottom-left\"\n role=\"dialog\"\n aria-label=\"Label details\"\n >\n <div class=\"label-popover-container\">\n <div class=\"label-title\">{{ label.label.name }}</div>\n <KdsDescription :text=\"label.label.description\" />\n <KdsDescription v-if=\"label.message\" :text=\"label.message\" />\n </div>\n </KdsPopover>\n</template>\n\n<style scoped>\n.label-popover-container {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-5x);\n align-items: flex-start;\n max-width: var(--kds-dimension-component-width-20x);\n max-height: var(--kds-dimension-component-height-20x);\n padding: var(--kds-spacing-container-0-75x) var(--kds-spacing-container-1x);\n overflow-y: auto;\n background-color: var(--kds-color-surface-default);\n border-radius: var(--kds-border-radius-container-0-50x);\n box-shadow: var(--kds-elevation-level-3);\n}\n\n.label-title {\n font: var(--kds-font-base-body-small-strong);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsDescription,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport VersionLabel from \"./VersionLabel.vue\";\nimport type {\n NamedItemVersion,\n RestoreOption,\n WithAvatar,\n WithLabels,\n} from \"./types\";\n\ntype Props = {\n version: NamedItemVersion & WithAvatar & WithLabels;\n isSelected: boolean;\n hasAdminRights: boolean;\n hasEditCapability: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n restoreOption?: RestoreOption;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n select: [selectionStatus: boolean];\n delete: [];\n restore: [];\n}>();\n\nconst toggleVersionSelection = () => {\n emit(\"select\", !props.isSelected);\n};\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n [\n props.hasEditCapability && {\n id: \"show\",\n text: props.isSelected ? \"Deselect this version\" : \"Show this version\",\n handler: toggleVersionSelection,\n },\n props.hasEditCapability && {\n id: \"restore\",\n text: \"Restore this version\",\n subText: props.restoreOption?.subText,\n disabled: props.restoreOption?.disabled,\n handler: () => emit(\"restore\"),\n },\n props.hasAdminRights && {\n id: \"delete\",\n text: \"Delete this version\",\n handler: () => emit(\"delete\"),\n },\n ].filter((i) => i !== false),\n);\n</script>\n\n<template>\n <HistoryEvent :is-selected :is-first-item :is-last-item>\n <KdsSelectableCard\n :model-value=\"isSelected\"\n :headline=\"version.title\"\n ariaLabel=\"Version history event\"\n @update:model-value=\"toggleVersionSelection\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor :author=\"version.author\" :avatar=\"version.avatar\" />\n\n <KdsDescription\n v-if=\"version.description\"\n :text=\"version.description\"\n />\n\n <div class=\"labels-wrapper\">\n <VersionLabel\n v-for=\"label in version.labels\"\n :key=\"label.labelId\"\n :label=\"label\"\n />\n </div>\n\n <HistoryEventFooter\n :version=\"version.version\"\n :date=\"version.createdOn\"\n />\n </div>\n </KdsSelectableCard>\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n\n.labels-wrapper {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kds-spacing-container-0-25x) var(--kds-spacing-container-0-5x);\n align-items: center;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsDescription,\n type KdsMenuActionItem,\n KdsMenuButton,\n KdsSelectableCard,\n} from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport HistoryEventAuthor from \"./HistoryEventAuthor.vue\";\nimport HistoryEventFooter from \"./HistoryEventFooter.vue\";\nimport VersionLabel from \"./VersionLabel.vue\";\nimport type {\n NamedItemVersion,\n RestoreOption,\n WithAvatar,\n WithLabels,\n} from \"./types\";\n\ntype Props = {\n version: NamedItemVersion & WithAvatar & WithLabels;\n isSelected: boolean;\n hasAdminRights: boolean;\n hasEditCapability: boolean;\n isFirstItem: boolean;\n isLastItem: boolean;\n restoreOption?: RestoreOption;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n select: [selectionStatus: boolean];\n delete: [];\n restore: [];\n}>();\n\nconst toggleVersionSelection = () => {\n emit(\"select\", !props.isSelected);\n};\n\nconst menuItems = computed<KdsMenuActionItem[]>(() =>\n [\n props.hasEditCapability && {\n id: \"show\",\n text: props.isSelected ? \"Deselect this version\" : \"Show this version\",\n handler: toggleVersionSelection,\n },\n props.hasEditCapability && {\n id: \"restore\",\n text: \"Restore this version\",\n subText: props.restoreOption?.subText,\n disabled: props.restoreOption?.disabled,\n handler: () => emit(\"restore\"),\n },\n props.hasAdminRights && {\n id: \"delete\",\n text: \"Delete this version\",\n handler: () => emit(\"delete\"),\n },\n ].filter((i) => i !== false),\n);\n</script>\n\n<template>\n <HistoryEvent :is-selected :is-first-item :is-last-item>\n <KdsSelectableCard\n :model-value=\"isSelected\"\n :headline=\"version.title\"\n ariaLabel=\"Version history event\"\n @update:model-value=\"toggleVersionSelection\"\n >\n <template v-if=\"menuItems.length\" #header-actions>\n <KdsMenuButton\n :items=\"menuItems\"\n variant=\"transparent\"\n leading-icon=\"more-actions\"\n ariaLabel=\"More actions\"\n />\n </template>\n\n <div class=\"content-wrapper\">\n <HistoryEventAuthor :author=\"version.author\" :avatar=\"version.avatar\" />\n\n <KdsDescription\n v-if=\"version.description\"\n :text=\"version.description\"\n />\n\n <div class=\"labels-wrapper\">\n <VersionLabel\n v-for=\"label in version.labels\"\n :key=\"label.labelId\"\n :label=\"label\"\n />\n </div>\n\n <HistoryEventFooter\n :version=\"version.version\"\n :date=\"version.createdOn\"\n />\n </div>\n </KdsSelectableCard>\n </HistoryEvent>\n</template>\n\n<style scoped>\n.content-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-37x);\n}\n\n.labels-wrapper {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kds-spacing-container-0-25x) var(--kds-spacing-container-0-5x);\n align-items: center;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsCard, KdsDescription, KdsLinkButton } from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport type { VersionLimit } from \"./types\";\n\nconst {\n versionLimit,\n upgradeUrl = undefined,\n isPrivate = false,\n} = defineProps<{\n versionLimit: Required<VersionLimit>;\n upgradeUrl?: string;\n isPrivate?: boolean;\n}>();\n\nconst isLimitReached = computed(\n () => versionLimit.currentUsage >= versionLimit.limit,\n);\n\nconst headline = computed(() => {\n if (isLimitReached.value) {\n return `You've reached the maximum of ${versionLimit.limit} versions.`;\n } else {\n return `Using ${versionLimit.currentUsage} of ${versionLimit.limit} versions.`;\n }\n});\n</script>\n\n<template>\n <HistoryEvent :is-selected=\"false\" :is-first-item=\"false\" is-last-item>\n <KdsCard variant=\"filled\" :headline=\"headline\">\n <template v-if=\"upgradeUrl\" #header-actions>\n <KdsLinkButton label=\"Upgrade\" :to=\"upgradeUrl\" />\n </template>\n\n <div class=\"content-wrapper\">\n <KdsDescription\n :text=\"`Upgrade to use unlimited versions${isPrivate ? ' for private items.' : '.'}`\"\n />\n </div>\n </KdsCard>\n </HistoryEvent>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { KdsCard, KdsDescription, KdsLinkButton } from \"@knime/kds-components\";\n\nimport HistoryEvent from \"./HistoryEvent.vue\";\nimport type { VersionLimit } from \"./types\";\n\nconst {\n versionLimit,\n upgradeUrl = undefined,\n isPrivate = false,\n} = defineProps<{\n versionLimit: Required<VersionLimit>;\n upgradeUrl?: string;\n isPrivate?: boolean;\n}>();\n\nconst isLimitReached = computed(\n () => versionLimit.currentUsage >= versionLimit.limit,\n);\n\nconst headline = computed(() => {\n if (isLimitReached.value) {\n return `You've reached the maximum of ${versionLimit.limit} versions.`;\n } else {\n return `Using ${versionLimit.currentUsage} of ${versionLimit.limit} versions.`;\n }\n});\n</script>\n\n<template>\n <HistoryEvent :is-selected=\"false\" :is-first-item=\"false\" is-last-item>\n <KdsCard variant=\"filled\" :headline=\"headline\">\n <template v-if=\"upgradeUrl\" #header-actions>\n <KdsLinkButton label=\"Upgrade\" :to=\"upgradeUrl\" />\n </template>\n\n <div class=\"content-wrapper\">\n <KdsDescription\n :text=\"`Upgrade to use unlimited versions${isPrivate ? ' for private items.' : '.'}`\"\n />\n </div>\n </KdsCard>\n </HistoryEvent>\n</template>\n","export const VERSION_DEFAULT_LIMIT = 10;\nexport const CURRENT_STATE_VERSION = \"current-state\";\nexport const MOST_RECENT_VERSION = \"most-recent\";\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n KdsPanel,\n type KdsPanelHeadlineTrailingAction,\n} from \"@knime/kds-components\";\n\nimport CurrentState from \"./CurrentState.vue\";\nimport VersionItem from \"./VersionItem.vue\";\nimport VersionLimitInfo from \"./VersionLimitInfo.vue\";\nimport { CURRENT_STATE_VERSION } from \"./constants\";\nimport type { NamedItemVersion, VersionHistoryProps } from \"./types\";\n\nconst props = defineProps<VersionHistoryProps>();\n\nconst emit = defineEmits<{\n close: [];\n loadAll: [];\n create: [];\n delete: [version: NamedItemVersion[\"version\"]];\n restore: [version: NamedItemVersion[\"version\"]];\n select: [version: NamedItemVersion[\"version\"]];\n discardCurrentState: [];\n}>();\n\nconst isVersionLimitExceeded = computed(() => {\n return (\n props.versionLimit?.limit !== undefined &&\n props.versionLimit.currentUsage >= props.versionLimit.limit\n );\n});\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"close\"),\n },\n ],\n);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Version history\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n >\n <div class=\"version-history-wrapper\">\n <CurrentState\n v-if=\"unversionedSavepoint\"\n :current-savepoint=\"unversionedSavepoint\"\n :is-selected=\"currentVersion === CURRENT_STATE_VERSION\"\n :has-edit-capability=\"hasEditCapability\"\n :has-previous-version=\"versionHistory.length > 0\"\n :has-version-limit=\"versionLimit?.limit !== undefined\"\n :is-version-limit-exceeded=\"isVersionLimitExceeded\"\n @select=\"$emit('select', CURRENT_STATE_VERSION)\"\n @create-version=\"$emit('create')\"\n @discard=\"$emit('discardCurrentState')\"\n />\n\n <VersionItem\n v-for=\"(historyEvent, index) in versionHistory\"\n :key=\"historyEvent.version\"\n :version=\"historyEvent\"\n :is-selected=\"historyEvent.version === currentVersion\"\n :has-admin-rights=\"hasAdminRights\"\n :has-edit-capability=\"hasEditCapability\"\n :is-first-item=\"!unversionedSavepoint && index === 0\"\n :is-last-item=\"\n index === versionHistory.length - 1 &&\n versionLimit?.limit === undefined\n \"\n :restore-option\n @delete=\"$emit('delete', historyEvent.version)\"\n @restore=\"$emit('restore', historyEvent.version)\"\n @select=\"\n $emit('select', $event ? historyEvent.version : CURRENT_STATE_VERSION)\n \"\n />\n\n <VersionLimitInfo\n v-if=\"versionLimit?.limit !== undefined\"\n class=\"version-limit-info\"\n :version-limit=\"{\n limit: versionLimit.limit,\n currentUsage: versionLimit.currentUsage,\n }\"\n :upgrade-url\n :is-private\n />\n\n <KdsButton\n v-if=\"!hasLoadedAllVersions\"\n variant=\"transparent\"\n :disabled=\"loading\"\n :label=\"loading ? 'Loading...' : 'Load all'\"\n class=\"load-more-button\"\n @click=\"$emit('loadAll')\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.version-history-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n}\n\n.load-more-button {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport {\n KdsButton,\n KdsPanel,\n type KdsPanelHeadlineTrailingAction,\n} from \"@knime/kds-components\";\n\nimport CurrentState from \"./CurrentState.vue\";\nimport VersionItem from \"./VersionItem.vue\";\nimport VersionLimitInfo from \"./VersionLimitInfo.vue\";\nimport { CURRENT_STATE_VERSION } from \"./constants\";\nimport type { NamedItemVersion, VersionHistoryProps } from \"./types\";\n\nconst props = defineProps<VersionHistoryProps>();\n\nconst emit = defineEmits<{\n close: [];\n loadAll: [];\n create: [];\n delete: [version: NamedItemVersion[\"version\"]];\n restore: [version: NamedItemVersion[\"version\"]];\n select: [version: NamedItemVersion[\"version\"]];\n discardCurrentState: [];\n}>();\n\nconst isVersionLimitExceeded = computed(() => {\n return (\n props.versionLimit?.limit !== undefined &&\n props.versionLimit.currentUsage >= props.versionLimit.limit\n );\n});\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"close\"),\n },\n ],\n);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Version history\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n >\n <div class=\"version-history-wrapper\">\n <CurrentState\n v-if=\"unversionedSavepoint\"\n :current-savepoint=\"unversionedSavepoint\"\n :is-selected=\"currentVersion === CURRENT_STATE_VERSION\"\n :has-edit-capability=\"hasEditCapability\"\n :has-previous-version=\"versionHistory.length > 0\"\n :has-version-limit=\"versionLimit?.limit !== undefined\"\n :is-version-limit-exceeded=\"isVersionLimitExceeded\"\n @select=\"$emit('select', CURRENT_STATE_VERSION)\"\n @create-version=\"$emit('create')\"\n @discard=\"$emit('discardCurrentState')\"\n />\n\n <VersionItem\n v-for=\"(historyEvent, index) in versionHistory\"\n :key=\"historyEvent.version\"\n :version=\"historyEvent\"\n :is-selected=\"historyEvent.version === currentVersion\"\n :has-admin-rights=\"hasAdminRights\"\n :has-edit-capability=\"hasEditCapability\"\n :is-first-item=\"!unversionedSavepoint && index === 0\"\n :is-last-item=\"\n index === versionHistory.length - 1 &&\n versionLimit?.limit === undefined\n \"\n :restore-option\n @delete=\"$emit('delete', historyEvent.version)\"\n @restore=\"$emit('restore', historyEvent.version)\"\n @select=\"\n $emit('select', $event ? historyEvent.version : CURRENT_STATE_VERSION)\n \"\n />\n\n <VersionLimitInfo\n v-if=\"versionLimit?.limit !== undefined\"\n class=\"version-limit-info\"\n :version-limit=\"{\n limit: versionLimit.limit,\n currentUsage: versionLimit.currentUsage,\n }\"\n :upgrade-url\n :is-private\n />\n\n <KdsButton\n v-if=\"!hasLoadedAllVersions\"\n variant=\"transparent\"\n :disabled=\"loading\"\n :label=\"loading ? 'Loading...' : 'Load all'\"\n class=\"load-more-button\"\n @click=\"$emit('loadAll')\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.version-history-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-0-75x);\n}\n\n.load-more-button {\n margin: 0 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPanel,\n type KdsPanelButtonAction,\n type KdsPanelHeadlineTrailingAction,\n KdsTextInput,\n KdsTextarea,\n} from \"@knime/kds-components\";\n\nimport type { CreateVersionFormProps } from \"./types\";\n\nconst { isCreationPending = false } = defineProps<CreateVersionFormProps>();\n\nconst emit = defineEmits<{\n create: [{ name: string; description: string }];\n cancel: [hasUnsavedChanges: boolean];\n}>();\n\nconst versionName = ref(\"\");\nconst versionDescription = ref(\"\");\n\nconst doValidate = ref(false);\n\nconst isVersionNameInvalid = computed(() => {\n return doValidate.value && versionName.value.trim().length <= 0;\n});\n\nconst hasUnsavedChanges = computed(() => {\n return versionName.value !== \"\" || versionDescription.value !== \"\";\n});\n\nconst onCreate = async () => {\n doValidate.value = true;\n await nextTick();\n\n if (!isVersionNameInvalid.value) {\n emit(\"create\", {\n name: versionName.value.trim(),\n description: versionDescription.value,\n });\n }\n};\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n ],\n);\n\nconst footerLeadingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Cancel\",\n variant: \"outlined\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n]);\n\nconst footerTrailingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Create\",\n variant: \"filled\",\n disabled: isVersionNameInvalid.value || isCreationPending,\n },\n onClick: onCreate,\n },\n]);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Create version\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n :footer-leading-actions=\"footerLeadingActions\"\n :footer-trailing-actions=\"footerTrailingActions\"\n >\n <div class=\"create-version-form-wrapper\">\n <KdsDescription\n text=\"Give your version a name and description. Versions can be used to create a deployment.\"\n class=\"create-version-form-description\"\n />\n\n <KdsTextInput\n v-model=\"versionName\"\n label=\"Version name\"\n type=\"text\"\n :error=\"isVersionNameInvalid\"\n :sub-text=\"\n isVersionNameInvalid\n ? 'Please enter at least 1 character.'\n : undefined\n \"\n />\n\n <KdsTextarea\n v-model=\"versionDescription\"\n label=\"Description\"\n class=\"description\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.create-version-form-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-1x);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref } from \"vue\";\n\nimport {\n KdsDescription,\n KdsPanel,\n type KdsPanelButtonAction,\n type KdsPanelHeadlineTrailingAction,\n KdsTextInput,\n KdsTextarea,\n} from \"@knime/kds-components\";\n\nimport type { CreateVersionFormProps } from \"./types\";\n\nconst { isCreationPending = false } = defineProps<CreateVersionFormProps>();\n\nconst emit = defineEmits<{\n create: [{ name: string; description: string }];\n cancel: [hasUnsavedChanges: boolean];\n}>();\n\nconst versionName = ref(\"\");\nconst versionDescription = ref(\"\");\n\nconst doValidate = ref(false);\n\nconst isVersionNameInvalid = computed(() => {\n return doValidate.value && versionName.value.trim().length <= 0;\n});\n\nconst hasUnsavedChanges = computed(() => {\n return versionName.value !== \"\" || versionDescription.value !== \"\";\n});\n\nconst onCreate = async () => {\n doValidate.value = true;\n await nextTick();\n\n if (!isVersionNameInvalid.value) {\n emit(\"create\", {\n name: versionName.value.trim(),\n description: versionDescription.value,\n });\n }\n};\n\nconst headlineTrailingActions = computed<KdsPanelHeadlineTrailingAction[]>(\n () => [\n {\n type: \"button\",\n props: {\n leadingIcon: \"x-close\",\n ariaLabel: \"Close\",\n variant: \"transparent\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n ],\n);\n\nconst footerLeadingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Cancel\",\n variant: \"outlined\",\n },\n onClick: () => emit(\"cancel\", hasUnsavedChanges.value),\n },\n]);\n\nconst footerTrailingActions = computed<KdsPanelButtonAction[]>(() => [\n {\n type: \"button\",\n props: {\n label: \"Create\",\n variant: \"filled\",\n disabled: isVersionNameInvalid.value || isCreationPending,\n },\n onClick: onCreate,\n },\n]);\n</script>\n\n<template>\n <KdsPanel\n headline=\"Create version\"\n :headline-trailing-actions=\"headlineTrailingActions\"\n :footer-leading-actions=\"footerLeadingActions\"\n :footer-trailing-actions=\"footerTrailingActions\"\n >\n <div class=\"create-version-form-wrapper\">\n <KdsDescription\n text=\"Give your version a name and description. Versions can be used to create a deployment.\"\n class=\"create-version-form-description\"\n />\n\n <KdsTextInput\n v-model=\"versionName\"\n label=\"Version name\"\n type=\"text\"\n :error=\"isVersionNameInvalid\"\n :sub-text=\"\n isVersionNameInvalid\n ? 'Please enter at least 1 character.'\n : undefined\n \"\n />\n\n <KdsTextarea\n v-model=\"versionDescription\"\n label=\"Description\"\n class=\"description\"\n />\n </div>\n </KdsPanel>\n</template>\n\n<style scoped>\n.create-version-form-wrapper {\n display: flex;\n flex-direction: column;\n gap: var(--kds-spacing-container-1x);\n}\n</style>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knime/product-features",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "description": "Package containing composition patterns of KDS Components and KNIME business logic",
5
5
  "repository": {
6
6
  "type": "git",
@@ -75,8 +75,8 @@
75
75
  "consola": "^3.4.2"
76
76
  },
77
77
  "devDependencies": {
78
- "@knime/kds-components": "^11.0.0",
79
- "@knime/kds-styles": "^11.0.0",
78
+ "@knime/kds-components": "^11.4.0",
79
+ "@knime/kds-styles": "^11.4.0",
80
80
  "@storybook/addon-docs": "^10.4.6",
81
81
  "@storybook/vue3-vite": "^10.4.6",
82
82
  "@vitejs/plugin-vue": "^6.0.8",
@@ -96,7 +96,7 @@
96
96
  "vite-plugin-dts": "^5.0.3",
97
97
  "vite-plugin-lib-inject-css": "^2.2.2",
98
98
  "vite-svg-loader": "^5.1.1",
99
- "vue": "3.5.40",
99
+ "vue": "3.5.42",
100
100
  "vue-tsc": "^3.3.8"
101
101
  },
102
102
  "engines": {