@knime/hub-features 1.13.0 → 1.14.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 +11 -0
- package/package.json +2 -2
- package/src/components/versions/components/CreateVersionForm.vue +166 -0
- package/src/components/versions/{CurrentState.vue → components/CurrentState.vue} +2 -2
- package/src/components/versions/{LabelList.vue → components/LabelList.vue} +2 -3
- package/src/components/versions/{ManageVersions.vue → components/ManageVersions.vue} +6 -5
- package/src/components/versions/{VersionHistory.vue → components/VersionHistory.vue} +2 -1
- package/src/components/versions/{VersionItem.vue → components/VersionItem.vue} +2 -2
- package/src/components/versions/{VersionLimitInfo.vue → components/VersionLimitInfo.vue} +1 -1
- package/src/components/versions/{useVersionsApi.ts → composables/useVersionsApi.ts} +1 -1
- package/src/components/versions/index.ts +3 -3
- package/src/components/versions/CreateVersionForm.vue +0 -150
- /package/src/components/versions/{NoVersionItem.vue → components/NoVersionItem.vue} +0 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knime/hub-features",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Vue components & composables for shared hub features",
|
|
5
5
|
"homepage": "https://knime.github.io/webapps-common/",
|
|
6
6
|
"license": "GPL 3 and Additional Permissions according to Sec. 7 (SEE the file LICENSE)",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"lodash-es": "4.17.21",
|
|
32
32
|
"ofetch": "^1.4.1",
|
|
33
33
|
"typescript": "^5.8.3",
|
|
34
|
-
"@knime/components": "1.
|
|
34
|
+
"@knime/components": "1.36.0",
|
|
35
35
|
"@knime/styles": "1.11.1",
|
|
36
36
|
"@knime/utils": "1.5.5"
|
|
37
37
|
},
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, nextTick, onMounted, ref } from "vue";
|
|
3
|
+
import { useTextareaAutosize } from "@vueuse/core";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Button,
|
|
7
|
+
InputField,
|
|
8
|
+
Label,
|
|
9
|
+
LoadingIcon,
|
|
10
|
+
SideDrawerHeader,
|
|
11
|
+
TextArea,
|
|
12
|
+
} from "@knime/components";
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
isCreationPending?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
withDefaults(defineProps<Props>(), { isCreationPending: false });
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits<{
|
|
21
|
+
create: [{ name: string; description: string }];
|
|
22
|
+
cancel: [hasUnsavedChanges: boolean];
|
|
23
|
+
}>();
|
|
24
|
+
|
|
25
|
+
const versionName = ref("");
|
|
26
|
+
const versionDescription = ref("");
|
|
27
|
+
|
|
28
|
+
const descriptionEditor = ref<InstanceType<typeof TextArea> | null>(null);
|
|
29
|
+
|
|
30
|
+
onMounted(() => {
|
|
31
|
+
useTextareaAutosize({
|
|
32
|
+
element: descriptionEditor.value?.$el.getElementsByTagName("textarea")[0],
|
|
33
|
+
input: versionDescription,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const doValidate = ref(false);
|
|
38
|
+
|
|
39
|
+
const isVersionNameInvalid = computed(() => {
|
|
40
|
+
return doValidate.value && versionName.value.length <= 0;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const hasUnsavedChanges = computed(() => {
|
|
44
|
+
return versionName.value !== "" || versionDescription.value !== "";
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const onCreate = async () => {
|
|
48
|
+
doValidate.value = true;
|
|
49
|
+
await nextTick();
|
|
50
|
+
|
|
51
|
+
if (!isVersionNameInvalid.value) {
|
|
52
|
+
emit("create", {
|
|
53
|
+
name: versionName.value,
|
|
54
|
+
description: versionDescription.value,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<template>
|
|
61
|
+
<div class="create-version-form">
|
|
62
|
+
<SideDrawerHeader
|
|
63
|
+
title="Create Version"
|
|
64
|
+
description="Give your version a name and description. Versions can be used to create a deployment.
|
|
65
|
+
"
|
|
66
|
+
:is-sub-drawer="true"
|
|
67
|
+
@close="$emit('cancel', hasUnsavedChanges)"
|
|
68
|
+
/>
|
|
69
|
+
<div class="form-content">
|
|
70
|
+
<Label text="Version name">
|
|
71
|
+
<InputField
|
|
72
|
+
v-model="versionName"
|
|
73
|
+
type="text"
|
|
74
|
+
required
|
|
75
|
+
:is-valid="!isVersionNameInvalid"
|
|
76
|
+
/>
|
|
77
|
+
<div v-if="isVersionNameInvalid" class="error">
|
|
78
|
+
Please enter at least 1 character.
|
|
79
|
+
</div>
|
|
80
|
+
</Label>
|
|
81
|
+
<Label text="Description">
|
|
82
|
+
<TextArea
|
|
83
|
+
ref="descriptionEditor"
|
|
84
|
+
v-model="versionDescription"
|
|
85
|
+
class="description"
|
|
86
|
+
/>
|
|
87
|
+
</Label>
|
|
88
|
+
<div class="controls">
|
|
89
|
+
<Button
|
|
90
|
+
with-border
|
|
91
|
+
compact
|
|
92
|
+
class="button cancel"
|
|
93
|
+
@click="$emit('cancel', hasUnsavedChanges)"
|
|
94
|
+
>
|
|
95
|
+
<strong>Cancel</strong>
|
|
96
|
+
</Button>
|
|
97
|
+
<Button
|
|
98
|
+
primary
|
|
99
|
+
compact
|
|
100
|
+
class="button create"
|
|
101
|
+
:disabled="isVersionNameInvalid || isCreationPending"
|
|
102
|
+
@click="onCreate"
|
|
103
|
+
>
|
|
104
|
+
<LoadingIcon v-if="isCreationPending" />
|
|
105
|
+
<strong v-if="!isCreationPending">Create</strong>
|
|
106
|
+
</Button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
111
|
+
|
|
112
|
+
<style lang="postcss" scoped>
|
|
113
|
+
.create-version-form {
|
|
114
|
+
height: 100%;
|
|
115
|
+
max-height: 100%;
|
|
116
|
+
width: 100%;
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
|
|
120
|
+
& .form-content {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-direction: column;
|
|
123
|
+
height: 100%;
|
|
124
|
+
padding: 30px 30px 0;
|
|
125
|
+
gap: 30px;
|
|
126
|
+
overscroll-behavior: none;
|
|
127
|
+
isolation: isolate;
|
|
128
|
+
overflow: auto;
|
|
129
|
+
z-index: 1;
|
|
130
|
+
background-color: var(--knime-gray-ultra-light);
|
|
131
|
+
|
|
132
|
+
& .description {
|
|
133
|
+
width: 100%;
|
|
134
|
+
max-width: unset;
|
|
135
|
+
display: flex;
|
|
136
|
+
|
|
137
|
+
& :deep(textarea) {
|
|
138
|
+
width: 100%;
|
|
139
|
+
box-sizing: content-box;
|
|
140
|
+
max-height: 200px;
|
|
141
|
+
resize: none;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
& .error {
|
|
146
|
+
position: absolute;
|
|
147
|
+
word-break: keep-all;
|
|
148
|
+
margin-top: 6px;
|
|
149
|
+
font-weight: 300;
|
|
150
|
+
font-size: 13px;
|
|
151
|
+
color: var(--theme-color-error);
|
|
152
|
+
line-height: 18px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
& .controls {
|
|
156
|
+
border-top: 1px solid var(--knime-silver-sand);
|
|
157
|
+
display: flex;
|
|
158
|
+
margin: 0 -30px;
|
|
159
|
+
padding: 10px 20px;
|
|
160
|
+
gap: 10px;
|
|
161
|
+
justify-content: space-between;
|
|
162
|
+
margin-top: auto;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
</style>
|
|
@@ -5,10 +5,10 @@ import { Button, LocalDateTime, SubMenu } from "@knime/components";
|
|
|
5
5
|
import MenuIcon from "@knime/styles/img/icons/menu-options.svg";
|
|
6
6
|
import WrenchIcon from "@knime/styles/img/icons/wrench.svg";
|
|
7
7
|
|
|
8
|
-
import HubAvatar from "
|
|
8
|
+
import HubAvatar from "../../avatars/HubAvatar.vue";
|
|
9
|
+
import type { ItemSavepoint, WithAvatar, WithLabels } from "../types";
|
|
9
10
|
|
|
10
11
|
import LabelList from "./LabelList.vue";
|
|
11
|
-
import type { ItemSavepoint, WithAvatar, WithLabels } from "./types";
|
|
12
12
|
|
|
13
13
|
const props = defineProps<{
|
|
14
14
|
isSelected: boolean;
|
|
@@ -7,9 +7,8 @@ import { isEqual } from "lodash-es"; // eslint-disable-line depend/ban-dependenc
|
|
|
7
7
|
import { FunctionButton } from "@knime/components";
|
|
8
8
|
import { truncateString } from "@knime/utils";
|
|
9
9
|
|
|
10
|
-
import Popover from "
|
|
11
|
-
|
|
12
|
-
import type { AssignedLabel } from "./types";
|
|
10
|
+
import Popover from "../../Popover.vue";
|
|
11
|
+
import type { AssignedLabel } from "../types";
|
|
13
12
|
|
|
14
13
|
type PopoverElement = HTMLElement & {
|
|
15
14
|
closeMenu: () => void;
|
|
@@ -6,17 +6,18 @@ import { FunctionButton } from "@knime/components";
|
|
|
6
6
|
import CloseIcon from "@knime/styles/img/icons/close.svg";
|
|
7
7
|
import HistoryIcon from "@knime/styles/img/icons/history.svg";
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
import VersionHistory from "./VersionHistory.vue";
|
|
11
|
-
import VersionLimitInfo from "./VersionLimitInfo.vue";
|
|
12
|
-
import { CURRENT_STATE_VERSION } from "./constants";
|
|
9
|
+
import { CURRENT_STATE_VERSION } from "../constants";
|
|
13
10
|
import type {
|
|
14
11
|
ItemSavepoint,
|
|
15
12
|
NamedItemVersion,
|
|
16
13
|
VersionLimit,
|
|
17
14
|
WithAvatar,
|
|
18
15
|
WithLabels,
|
|
19
|
-
} from "
|
|
16
|
+
} from "../types";
|
|
17
|
+
|
|
18
|
+
import CurrentState from "./CurrentState.vue";
|
|
19
|
+
import VersionHistory from "./VersionHistory.vue";
|
|
20
|
+
import VersionLimitInfo from "./VersionLimitInfo.vue";
|
|
20
21
|
|
|
21
22
|
type ManageVersionsProps = {
|
|
22
23
|
hasUnversionedChanges: boolean;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { IdleReadyButton } from "@knime/components";
|
|
3
3
|
|
|
4
|
+
import type { NamedItemVersion, WithAvatar, WithLabels } from "../types";
|
|
5
|
+
|
|
4
6
|
import NoVersionItem from "./NoVersionItem.vue";
|
|
5
7
|
import VersionItem from "./VersionItem.vue";
|
|
6
|
-
import type { NamedItemVersion, WithAvatar, WithLabels } from "./types";
|
|
7
8
|
|
|
8
9
|
defineProps<{
|
|
9
10
|
selectedVersion: NamedItemVersion["version"] | null;
|
|
@@ -6,10 +6,10 @@ import { LocalDateTime, SubMenu, Tooltip } from "@knime/components";
|
|
|
6
6
|
import MenuIcon from "@knime/styles/img/icons/menu-options.svg";
|
|
7
7
|
import { truncateString } from "@knime/utils";
|
|
8
8
|
|
|
9
|
-
import HubAvatar from "
|
|
9
|
+
import HubAvatar from "../../avatars/HubAvatar.vue";
|
|
10
|
+
import type { NamedItemVersion, WithAvatar, WithLabels } from "../types";
|
|
10
11
|
|
|
11
12
|
import LabelList from "./LabelList.vue";
|
|
12
|
-
import type { NamedItemVersion, WithAvatar, WithLabels } from "./types";
|
|
13
13
|
|
|
14
14
|
const DESCRIPTION_TRUNCATE_LENGTH = 120;
|
|
15
15
|
|
|
@@ -3,7 +3,7 @@ import { computed } from "vue";
|
|
|
3
3
|
|
|
4
4
|
import { InlineMessage } from "@knime/components";
|
|
5
5
|
|
|
6
|
-
import type { VersionLimit } from "
|
|
6
|
+
import type { VersionLimit } from "../types";
|
|
7
7
|
|
|
8
8
|
const { versionLimit, upgradeUrl = undefined } = defineProps<{
|
|
9
9
|
versionLimit: Required<VersionLimit>;
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
WithLabels,
|
|
14
14
|
} from "@knime/hub-features/versions";
|
|
15
15
|
|
|
16
|
-
import { getFetchClient } from "
|
|
16
|
+
import { getFetchClient } from "../../../common/ofetchClient";
|
|
17
17
|
|
|
18
18
|
type UseVersionsApiOptions = {
|
|
19
19
|
customFetchClientOptions?: FetchOptions;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import CreateVersionForm from "./CreateVersionForm.vue";
|
|
2
|
-
import ManageVersions from "./ManageVersions.vue";
|
|
1
|
+
import CreateVersionForm from "./components/CreateVersionForm.vue";
|
|
2
|
+
import ManageVersions from "./components/ManageVersions.vue";
|
|
3
3
|
|
|
4
4
|
export { CreateVersionForm, ManageVersions };
|
|
5
5
|
export type * from "./types";
|
|
6
6
|
export * from "./constants";
|
|
7
|
-
export * from "./useVersionsApi";
|
|
7
|
+
export * from "./composables/useVersionsApi";
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, nextTick, onMounted, ref } from "vue";
|
|
3
|
-
import { useTextareaAutosize } from "@vueuse/core";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
Button,
|
|
7
|
-
InputField,
|
|
8
|
-
Label,
|
|
9
|
-
LoadingIcon,
|
|
10
|
-
TextArea,
|
|
11
|
-
} from "@knime/components";
|
|
12
|
-
|
|
13
|
-
type Props = {
|
|
14
|
-
isCreationPending?: boolean;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
withDefaults(defineProps<Props>(), { isCreationPending: false });
|
|
18
|
-
|
|
19
|
-
const emit = defineEmits<{
|
|
20
|
-
create: [{ name: string; description: string }];
|
|
21
|
-
cancel: [hasUnsavedChanges: boolean];
|
|
22
|
-
}>();
|
|
23
|
-
|
|
24
|
-
const versionName = ref("");
|
|
25
|
-
const versionDescription = ref("");
|
|
26
|
-
|
|
27
|
-
const descriptionEditor = ref<InstanceType<typeof TextArea> | null>(null);
|
|
28
|
-
|
|
29
|
-
onMounted(() => {
|
|
30
|
-
useTextareaAutosize({
|
|
31
|
-
element: descriptionEditor.value?.$el.getElementsByTagName("textarea")[0],
|
|
32
|
-
input: versionDescription,
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const doValidate = ref(false);
|
|
37
|
-
|
|
38
|
-
const isVersionNameInvalid = computed(() => {
|
|
39
|
-
return versionName.value.length <= 0 && doValidate.value;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const hasUnsavedChanges = computed(() => {
|
|
43
|
-
return versionName.value !== "" || versionDescription.value !== "";
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const onCreate = async () => {
|
|
47
|
-
doValidate.value = true;
|
|
48
|
-
await nextTick();
|
|
49
|
-
|
|
50
|
-
if (!isVersionNameInvalid.value) {
|
|
51
|
-
emit("create", {
|
|
52
|
-
name: versionName.value,
|
|
53
|
-
description: versionDescription.value,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
</script>
|
|
58
|
-
|
|
59
|
-
<template>
|
|
60
|
-
<div class="create-version-form">
|
|
61
|
-
<Label text="Version name">
|
|
62
|
-
<InputField
|
|
63
|
-
v-model="versionName"
|
|
64
|
-
type="text"
|
|
65
|
-
required
|
|
66
|
-
:is-valid="!isVersionNameInvalid"
|
|
67
|
-
/>
|
|
68
|
-
<div v-if="isVersionNameInvalid" class="error">
|
|
69
|
-
Please enter at least 1 character.
|
|
70
|
-
</div>
|
|
71
|
-
</Label>
|
|
72
|
-
<Label text="Description">
|
|
73
|
-
<TextArea
|
|
74
|
-
ref="descriptionEditor"
|
|
75
|
-
v-model="versionDescription"
|
|
76
|
-
class="description"
|
|
77
|
-
/>
|
|
78
|
-
</Label>
|
|
79
|
-
<div class="controls">
|
|
80
|
-
<Button
|
|
81
|
-
with-border
|
|
82
|
-
compact
|
|
83
|
-
class="button cancel"
|
|
84
|
-
@click="$emit('cancel', hasUnsavedChanges)"
|
|
85
|
-
>
|
|
86
|
-
<strong>Cancel</strong>
|
|
87
|
-
</Button>
|
|
88
|
-
<Button
|
|
89
|
-
primary
|
|
90
|
-
compact
|
|
91
|
-
class="button create"
|
|
92
|
-
:disabled="isVersionNameInvalid || isCreationPending"
|
|
93
|
-
@click="onCreate"
|
|
94
|
-
>
|
|
95
|
-
<LoadingIcon v-if="isCreationPending" />
|
|
96
|
-
<strong v-if="!isCreationPending">Create</strong>
|
|
97
|
-
</Button>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
</template>
|
|
101
|
-
|
|
102
|
-
<style lang="postcss" scoped>
|
|
103
|
-
.create-version-form {
|
|
104
|
-
height: 100%;
|
|
105
|
-
max-height: 100%;
|
|
106
|
-
width: 100%;
|
|
107
|
-
display: flex;
|
|
108
|
-
flex-direction: column;
|
|
109
|
-
padding: 30px 30px 0;
|
|
110
|
-
gap: 30px;
|
|
111
|
-
overscroll-behavior: none;
|
|
112
|
-
isolation: isolate;
|
|
113
|
-
overflow: auto;
|
|
114
|
-
z-index: 1;
|
|
115
|
-
background-color: var(--knime-gray-ultra-light);
|
|
116
|
-
|
|
117
|
-
& .description {
|
|
118
|
-
width: 100%;
|
|
119
|
-
max-width: unset;
|
|
120
|
-
display: flex;
|
|
121
|
-
|
|
122
|
-
& :deep(textarea) {
|
|
123
|
-
width: 100%;
|
|
124
|
-
box-sizing: content-box;
|
|
125
|
-
max-height: 200px;
|
|
126
|
-
resize: none;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
& .error {
|
|
131
|
-
position: absolute;
|
|
132
|
-
word-break: keep-all;
|
|
133
|
-
margin-top: 6px;
|
|
134
|
-
font-weight: 300;
|
|
135
|
-
font-size: 13px;
|
|
136
|
-
color: var(--theme-color-error);
|
|
137
|
-
line-height: 18px;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
& .controls {
|
|
141
|
-
border-top: 1px solid var(--knime-silver-sand);
|
|
142
|
-
display: flex;
|
|
143
|
-
margin: 0 -30px;
|
|
144
|
-
padding: 10px 20px;
|
|
145
|
-
gap: 10px;
|
|
146
|
-
justify-content: space-between;
|
|
147
|
-
margin-top: auto;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
</style>
|
|
File without changes
|