@raclettejs/workbench 0.1.16 → 0.1.18
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 +15 -1
- package/config/compositions.js +18 -14
- package/config/interactionLinks.js +30 -10
- package/i18n/de-DE.json +27 -1
- package/i18n/en-EU.json +27 -1
- package/i18n/sk-SK.json +26 -0
- package/package.json +3 -3
- package/plugins/pacifico__compositions/frontend/widgets/CompositionListWidget.vue +31 -5
- package/plugins/pacifico__interactionLinks/frontend/widgets/InteractionLinkListWidget.vue +32 -4
- package/plugins/pacifico__project/frontend/components/ProjectConfiguration.vue +107 -0
- package/plugins/pacifico__project/frontend/widgets/ProjectDetailWidget.vue +34 -0
- package/plugins/pacifico__project/raclette.plugin.ts +8 -0
- package/plugins/pacifico__tags/frontend/widgets/TagListWidget.vue +31 -3
- package/plugins/pacifico__users/frontend/widgets/UserListWidget.vue +31 -5
- package/raclette.config.js +0 -3
- package/services/frontend/src/app/components/BaseDataTable.vue +11 -2
- package/services/frontend/src/app/components/dynamicForm/typedInputs/CompositionInput.vue +1 -0
- package/services/frontend/src/app/components/dynamicForm/typedInputs/TriggerInput.vue +4 -6
- package/yarn.lock +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [0.1.
|
|
10
|
+
## [0.1.18] - 05.12.2025 <a href="https://gitlab.com/raclettejs/workbench/-/compare/v0.1.17...v0.1.18" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
13
|
+
|
|
14
|
+
- Removed redundand authTokenExpiryDays config
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Interaction Links can now have a trigger in the appbar
|
|
19
|
+
- possibility to restore items
|
|
20
|
+
- possibility to add prepend and append actions to base table row items
|
|
21
|
+
- added project configuration interface
|
|
22
|
+
|
|
23
|
+
## [0.1.17] - 06.11.2025 <a href="https://gitlab.com/raclettejs/workbench/-/compare/v0.1.15...v0.1.17" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
|
|
11
24
|
|
|
12
25
|
### Added
|
|
13
26
|
|
|
14
27
|
- added isDeleted switch to lists
|
|
28
|
+
- added hard deletion to all core types
|
|
15
29
|
|
|
16
30
|
## [0.1.15] - 02.11.2025 <a href="https://gitlab.com/raclettejs/workbench/-/compare/v0.1.13...v0.1.15" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
|
|
17
31
|
|
package/config/compositions.js
CHANGED
|
@@ -2,7 +2,6 @@ export default [
|
|
|
2
2
|
// composition administration
|
|
3
3
|
{
|
|
4
4
|
_id: "compositionList",
|
|
5
|
-
description: "Ein Test",
|
|
6
5
|
pathname: {
|
|
7
6
|
default: "composition-list",
|
|
8
7
|
},
|
|
@@ -21,7 +20,6 @@ export default [
|
|
|
21
20
|
},
|
|
22
21
|
{
|
|
23
22
|
_id: "compositionCreate",
|
|
24
|
-
description: "Ein Test",
|
|
25
23
|
pathname: {
|
|
26
24
|
default: "composition-create",
|
|
27
25
|
},
|
|
@@ -41,7 +39,6 @@ export default [
|
|
|
41
39
|
},
|
|
42
40
|
{
|
|
43
41
|
_id: "compositionEdit",
|
|
44
|
-
description: "Ein Test",
|
|
45
42
|
pathname: {
|
|
46
43
|
default: "composition-edit",
|
|
47
44
|
},
|
|
@@ -63,7 +60,6 @@ export default [
|
|
|
63
60
|
// interactionLinks administration
|
|
64
61
|
{
|
|
65
62
|
_id: "interactionLinkList",
|
|
66
|
-
description: "Ein Test",
|
|
67
63
|
pathname: {
|
|
68
64
|
default: "interactionLink-list",
|
|
69
65
|
},
|
|
@@ -82,7 +78,6 @@ export default [
|
|
|
82
78
|
},
|
|
83
79
|
{
|
|
84
80
|
_id: "interactionLinkCreate",
|
|
85
|
-
description: "Ein Test",
|
|
86
81
|
pathname: {
|
|
87
82
|
default: "interactionLink-create",
|
|
88
83
|
},
|
|
@@ -101,7 +96,6 @@ export default [
|
|
|
101
96
|
},
|
|
102
97
|
{
|
|
103
98
|
_id: "interactionLinkEdit",
|
|
104
|
-
description: "Ein Test",
|
|
105
99
|
pathname: {
|
|
106
100
|
default: "interactionLink-edit",
|
|
107
101
|
},
|
|
@@ -123,7 +117,6 @@ export default [
|
|
|
123
117
|
// users administration
|
|
124
118
|
{
|
|
125
119
|
_id: "userList",
|
|
126
|
-
description: "Ein Test",
|
|
127
120
|
pathname: {
|
|
128
121
|
default: "user-list",
|
|
129
122
|
},
|
|
@@ -142,7 +135,6 @@ export default [
|
|
|
142
135
|
},
|
|
143
136
|
{
|
|
144
137
|
_id: "userCreate",
|
|
145
|
-
description: "Ein Test",
|
|
146
138
|
pathname: {
|
|
147
139
|
default: "user-create",
|
|
148
140
|
},
|
|
@@ -161,7 +153,6 @@ export default [
|
|
|
161
153
|
},
|
|
162
154
|
{
|
|
163
155
|
_id: "userEdit",
|
|
164
|
-
description: "Ein Test",
|
|
165
156
|
pathname: {
|
|
166
157
|
default: "user-edit",
|
|
167
158
|
},
|
|
@@ -182,7 +173,6 @@ export default [
|
|
|
182
173
|
// tags administration
|
|
183
174
|
{
|
|
184
175
|
_id: "tagList",
|
|
185
|
-
description: "Ein Test",
|
|
186
176
|
pathname: {
|
|
187
177
|
default: "tag-list",
|
|
188
178
|
},
|
|
@@ -201,7 +191,6 @@ export default [
|
|
|
201
191
|
},
|
|
202
192
|
{
|
|
203
193
|
_id: "tagCreate",
|
|
204
|
-
description: "Ein Test",
|
|
205
194
|
pathname: {
|
|
206
195
|
default: "tag-create",
|
|
207
196
|
},
|
|
@@ -220,7 +209,6 @@ export default [
|
|
|
220
209
|
},
|
|
221
210
|
{
|
|
222
211
|
_id: "tagEdit",
|
|
223
|
-
description: "Ein Test",
|
|
224
212
|
pathname: {
|
|
225
213
|
default: "tag-edit",
|
|
226
214
|
},
|
|
@@ -242,7 +230,6 @@ export default [
|
|
|
242
230
|
// plugins configuration
|
|
243
231
|
{
|
|
244
232
|
_id: "pluginList",
|
|
245
|
-
description: "Ein Test",
|
|
246
233
|
pathname: {
|
|
247
234
|
default: "plugin-list",
|
|
248
235
|
},
|
|
@@ -261,7 +248,6 @@ export default [
|
|
|
261
248
|
},
|
|
262
249
|
{
|
|
263
250
|
_id: "pluginDetail",
|
|
264
|
-
description: "Ein Test",
|
|
265
251
|
pathname: {
|
|
266
252
|
default: "plugin-detail",
|
|
267
253
|
},
|
|
@@ -279,4 +265,22 @@ export default [
|
|
|
279
265
|
],
|
|
280
266
|
queryParameters: ["id"],
|
|
281
267
|
},
|
|
268
|
+
{
|
|
269
|
+
_id: "projectDetail",
|
|
270
|
+
pathname: {
|
|
271
|
+
default: "project-detail",
|
|
272
|
+
},
|
|
273
|
+
widgetsLayout: [
|
|
274
|
+
[
|
|
275
|
+
{
|
|
276
|
+
column: 12,
|
|
277
|
+
widget: {
|
|
278
|
+
uuid: "ProjectDetail",
|
|
279
|
+
name: "ProjectDetail",
|
|
280
|
+
pluginKey: "pacifico__project",
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
],
|
|
285
|
+
},
|
|
282
286
|
] //satisfies Composition[]
|
|
@@ -45,8 +45,8 @@ export default [
|
|
|
45
45
|
settings: {
|
|
46
46
|
icon: "mdi-link-box-variant",
|
|
47
47
|
title: {
|
|
48
|
-
default: "
|
|
49
|
-
de: "
|
|
48
|
+
default: "Interaction Links",
|
|
49
|
+
de: "Interaktionslinks",
|
|
50
50
|
},
|
|
51
51
|
sortOrder: 1,
|
|
52
52
|
navigationBarType: "navItem",
|
|
@@ -78,8 +78,8 @@ export default [
|
|
|
78
78
|
settings: {
|
|
79
79
|
icon: "mdi-account-details",
|
|
80
80
|
title: {
|
|
81
|
-
default: "
|
|
82
|
-
de: "
|
|
81
|
+
default: "Users",
|
|
82
|
+
de: "Nutzer",
|
|
83
83
|
},
|
|
84
84
|
sortOrder: 2,
|
|
85
85
|
navigationBarType: "navItem",
|
|
@@ -111,10 +111,10 @@ export default [
|
|
|
111
111
|
settings: {
|
|
112
112
|
icon: "mdi-tag",
|
|
113
113
|
title: {
|
|
114
|
-
default: "
|
|
115
|
-
de: "
|
|
114
|
+
default: "Tags",
|
|
115
|
+
de: "Tags",
|
|
116
116
|
},
|
|
117
|
-
sortOrder:
|
|
117
|
+
sortOrder: 3,
|
|
118
118
|
navigationBarType: "navItem",
|
|
119
119
|
},
|
|
120
120
|
},
|
|
@@ -145,10 +145,10 @@ export default [
|
|
|
145
145
|
settings: {
|
|
146
146
|
icon: "mdi-puzzle",
|
|
147
147
|
title: {
|
|
148
|
-
default: "
|
|
149
|
-
de: "
|
|
148
|
+
default: "Plugins",
|
|
149
|
+
de: "Plugins",
|
|
150
150
|
},
|
|
151
|
-
sortOrder:
|
|
151
|
+
sortOrder: 4,
|
|
152
152
|
navigationBarType: "navItem",
|
|
153
153
|
},
|
|
154
154
|
},
|
|
@@ -161,4 +161,24 @@ export default [
|
|
|
161
161
|
triggers: [],
|
|
162
162
|
queryParameters: ["pluginKey"],
|
|
163
163
|
},
|
|
164
|
+
// project configuration
|
|
165
|
+
{
|
|
166
|
+
_id: "projectDetailInteractionLink",
|
|
167
|
+
composition: compositions[14]._id,
|
|
168
|
+
slotType: "page",
|
|
169
|
+
triggers: [
|
|
170
|
+
{
|
|
171
|
+
type: "page-navigation",
|
|
172
|
+
settings: {
|
|
173
|
+
icon: "mdi-application-cog",
|
|
174
|
+
title: {
|
|
175
|
+
default: "Project",
|
|
176
|
+
de: "Projekt",
|
|
177
|
+
},
|
|
178
|
+
sortOrder: 0,
|
|
179
|
+
navigationBarType: "footerItem",
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
164
184
|
] // satisfies Partial<InteractionLink>[]
|
package/i18n/de-DE.json
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"searchPlaceholder": "{dataName} durchsuchen",
|
|
43
43
|
"createDataButton": "{dataName} erstellen",
|
|
44
44
|
"deleteDataTitle": "{dataName} löschen",
|
|
45
|
+
"restoreDataTitle": "{dataName} widerherstellen",
|
|
45
46
|
"deleteDataConfirmMessage": "Bist du sicher, dass du {article} {dataName} <strong>{value}</strong> löschen willst?",
|
|
46
47
|
"deleteDataConfirmButton": "Löschen",
|
|
47
48
|
"deleteDataConfirmCancel": "Abbrechen"
|
|
@@ -246,6 +247,31 @@
|
|
|
246
247
|
"invalidEmail": "Bitte geben Sie eine gültige E-Mail-Adresse ein",
|
|
247
248
|
"invalidUrl": "Bitte geben Sie eine gültige URL ein"
|
|
248
249
|
}
|
|
250
|
+
},
|
|
251
|
+
"project": {
|
|
252
|
+
"formtitle": "Projekt bearbeiten",
|
|
253
|
+
"dataName": "Projekt",
|
|
254
|
+
"dividers": {
|
|
255
|
+
"general": "Allgemein",
|
|
256
|
+
"config": "Konfiguration"
|
|
257
|
+
},
|
|
258
|
+
"title": {
|
|
259
|
+
"title": "Projekt name",
|
|
260
|
+
"description": "Der Name des Projekts"
|
|
261
|
+
},
|
|
262
|
+
"tags": {
|
|
263
|
+
"title": "Tags",
|
|
264
|
+
"description": "Dieses Feld dient nur der internen Zuordnung der Komposition und wird nicht im Produkt angezeigt."
|
|
265
|
+
},
|
|
266
|
+
"description": {
|
|
267
|
+
"title": "Projekt Beschreibung",
|
|
268
|
+
"description": "Die Beschreibung des Portal/Platform Inhalts"
|
|
269
|
+
},
|
|
270
|
+
"config": "Projekt Konfiguration",
|
|
271
|
+
"railPageNavigation": {
|
|
272
|
+
"title": "Ausklappbare Navigation",
|
|
273
|
+
"description": "Wenn aktiviert wird die Seitennavigation automatisch ein- und aufgeklappt"
|
|
274
|
+
}
|
|
249
275
|
}
|
|
250
276
|
}
|
|
251
|
-
}
|
|
277
|
+
}
|
package/i18n/en-EU.json
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"searchPlaceholder": "Search {dataName}",
|
|
43
43
|
"createDataButton": "Create {dataName}",
|
|
44
44
|
"deleteDataTitle": "Delete {dataName}",
|
|
45
|
+
"restoreDataTitle": "Restore {dataName}",
|
|
45
46
|
"deleteDataConfirmMessage": "Are you sure you want to delete {article} {dataName} <strong>{value}</strong>?",
|
|
46
47
|
"deleteDataConfirmButton": "Delete",
|
|
47
48
|
"deleteDataConfirmCancel": "Cancel"
|
|
@@ -246,6 +247,31 @@
|
|
|
246
247
|
"invalidEmail": "Please enter a valid email address",
|
|
247
248
|
"invalidUrl": "Please enter a valid URL"
|
|
248
249
|
}
|
|
250
|
+
},
|
|
251
|
+
"project": {
|
|
252
|
+
"formtitle": "Edit Project",
|
|
253
|
+
"dataName": "Project",
|
|
254
|
+
"dividers": {
|
|
255
|
+
"general": "General",
|
|
256
|
+
"config": "Configuration"
|
|
257
|
+
},
|
|
258
|
+
"title": {
|
|
259
|
+
"title": "Project Name",
|
|
260
|
+
"description": "The name of the project"
|
|
261
|
+
},
|
|
262
|
+
"tags": {
|
|
263
|
+
"title": "Tags",
|
|
264
|
+
"description": "This field is only used for internal categorization of the composition and is not displayed in the product."
|
|
265
|
+
},
|
|
266
|
+
"description": {
|
|
267
|
+
"title": "Project Description",
|
|
268
|
+
"description": "The description of the portal/platform content"
|
|
269
|
+
},
|
|
270
|
+
"config": "Project Configuration",
|
|
271
|
+
"railPageNavigation": {
|
|
272
|
+
"title": "Collapsible Navigation",
|
|
273
|
+
"description": "When enabled, the page navigation is automatically collapsed and expanded"
|
|
274
|
+
}
|
|
249
275
|
}
|
|
250
276
|
}
|
|
251
|
-
}
|
|
277
|
+
}
|
package/i18n/sk-SK.json
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"searchPlaceholder": "Hľadať {dataName}",
|
|
43
43
|
"createDataButton": "Vytvoriť {dataName}",
|
|
44
44
|
"deleteDataTitle": "Odstrániť {dataName}",
|
|
45
|
+
"restoreDataTitle": "Obnoviť {dataName}",
|
|
45
46
|
"deleteDataConfirmMessage": "Naozaj chcete odstrániť {article} {dataName} <strong>{value}</strong>?",
|
|
46
47
|
"deleteDataConfirmButton": "Odstrániť",
|
|
47
48
|
"deleteDataConfirmCancel": "Zrušiť"
|
|
@@ -241,6 +242,31 @@
|
|
|
241
242
|
"invalidEmail": "Zadajte platnú emailovú adresu",
|
|
242
243
|
"invalidUrl": "Zadajte platnú URL adresu"
|
|
243
244
|
}
|
|
245
|
+
},
|
|
246
|
+
"project": {
|
|
247
|
+
"formtitle": "Upraviť projekt",
|
|
248
|
+
"dataName": "Projekt",
|
|
249
|
+
"dividers": {
|
|
250
|
+
"general": "Všeobecné",
|
|
251
|
+
"config": "Konfigurácia"
|
|
252
|
+
},
|
|
253
|
+
"title": {
|
|
254
|
+
"title": "Názov projektu",
|
|
255
|
+
"description": "Názov projektu"
|
|
256
|
+
},
|
|
257
|
+
"description": {
|
|
258
|
+
"title": "Popis projektu",
|
|
259
|
+
"description": "Popis obsahu portálu/platformy"
|
|
260
|
+
},
|
|
261
|
+
"config": "Projekt Konfigurácia",
|
|
262
|
+
"railPageNavigation": {
|
|
263
|
+
"title": "Sklopná navigácia",
|
|
264
|
+
"description": "Ak je povolená, stránková navigácia sa automaticky sklopí a rozbalí"
|
|
265
|
+
},
|
|
266
|
+
"tags": {
|
|
267
|
+
"title": "Značky",
|
|
268
|
+
"description": "Toto pole slúži len na internú kategorizáciu kompozície a nezobrazuje sa v produkte."
|
|
269
|
+
}
|
|
244
270
|
}
|
|
245
271
|
}
|
|
246
272
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raclettejs/workbench",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "racletteJS Workbench - used to configure your application, for dev and prod",
|
|
6
6
|
"repository": "https://gitlab.com/raclettejs/workbench",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
".": "./index.ts"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@raclettejs/core": "0.1.
|
|
34
|
+
"@raclettejs/core": "^0.1.18",
|
|
35
35
|
"three": "0.180.0",
|
|
36
36
|
"vanta": "0.5.24"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@eslint/js": "9.35.0",
|
|
40
|
-
"@raclettejs/types": "0.1.
|
|
40
|
+
"@raclettejs/types": "^0.1.18",
|
|
41
41
|
"@sinclair/typebox": "0.34.41",
|
|
42
42
|
"@types/ramda": "0.31.1",
|
|
43
43
|
"@vueuse/core": "13.9.0",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
:data-name="$t('workbench.compositionList.dataName')"
|
|
9
9
|
:data-article="$t('workbench.compositionList.dataArticle')"
|
|
10
10
|
@delete="deleteComposition"
|
|
11
|
+
:itemsDeleted="showDeleted"
|
|
11
12
|
>
|
|
12
13
|
<template #actions>
|
|
13
14
|
<v-tooltip
|
|
@@ -37,6 +38,20 @@
|
|
|
37
38
|
size="x-large"
|
|
38
39
|
/>
|
|
39
40
|
</template>
|
|
41
|
+
<template #prepend-row-actions="{ item }">
|
|
42
|
+
<v-icon
|
|
43
|
+
v-if="showDeleted"
|
|
44
|
+
color="green"
|
|
45
|
+
class="mr-2"
|
|
46
|
+
@click.stop.prevent="restore(item._id)"
|
|
47
|
+
:title="
|
|
48
|
+
$t('workbench.baseDataTable.restoreDataTitle', {
|
|
49
|
+
dataName: item.title,
|
|
50
|
+
})
|
|
51
|
+
"
|
|
52
|
+
icon="mdi-delete-restore"
|
|
53
|
+
/>
|
|
54
|
+
</template>
|
|
40
55
|
</BaseDataTable>
|
|
41
56
|
</template>
|
|
42
57
|
|
|
@@ -90,7 +105,6 @@ const {
|
|
|
90
105
|
execute,
|
|
91
106
|
isLoading: compositionsLoading,
|
|
92
107
|
} = $data.composition.getAll()
|
|
93
|
-
|
|
94
108
|
const { data: tags, isLoading: tagsLoading } = $data.tag.getAll({
|
|
95
109
|
options: { immediate: true },
|
|
96
110
|
})
|
|
@@ -100,7 +114,12 @@ const { data: users } = $data.user.getAll({
|
|
|
100
114
|
const { execute: executeDelete } = await $data.composition.delete({
|
|
101
115
|
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
102
116
|
})
|
|
103
|
-
|
|
117
|
+
const { execute: executeRestore } = await $data.composition.updateRestore({
|
|
118
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
119
|
+
})
|
|
120
|
+
const { execute: executeHardDelete } = await $data.composition.deleteHard({
|
|
121
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
122
|
+
})
|
|
104
123
|
const parsedCompositions = computed(() => {
|
|
105
124
|
if (compositions.value && tags.value) {
|
|
106
125
|
return Object.values(
|
|
@@ -144,9 +163,16 @@ const getStatusColor = (status: string) => {
|
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
|
|
147
|
-
const deleteComposition = async (composition: Composition) =>
|
|
148
|
-
|
|
149
|
-
|
|
166
|
+
const deleteComposition = async (composition: Composition) => {
|
|
167
|
+
if (showDeleted.value) {
|
|
168
|
+
await executeHardDelete({ _id: composition._id })
|
|
169
|
+
} else {
|
|
170
|
+
await executeDelete({ _id: composition._id })
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const restore = (_id: string) => {
|
|
174
|
+
executeRestore({ _id })
|
|
175
|
+
}
|
|
150
176
|
$socket.on("compositionCreated", () =>
|
|
151
177
|
execute({ isDeleted: showDeleted.value }),
|
|
152
178
|
)
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
:data-name="$t('workbench.interactionLinkList.dataName')"
|
|
9
9
|
:data-article="$t('workbench.interactionLinkList.dataArticle')"
|
|
10
10
|
@delete="deleteInteractionLink"
|
|
11
|
+
:itemsDeleted="showDeleted"
|
|
11
12
|
>
|
|
12
13
|
<template #actions>
|
|
13
14
|
<v-tooltip
|
|
@@ -36,6 +37,20 @@
|
|
|
36
37
|
<v-icon icon="mdi-link" />
|
|
37
38
|
</span>
|
|
38
39
|
</template>
|
|
40
|
+
<template #prepend-row-actions="{ item }">
|
|
41
|
+
<v-icon
|
|
42
|
+
v-if="showDeleted"
|
|
43
|
+
color="green"
|
|
44
|
+
class="mr-2"
|
|
45
|
+
@click="restore(item._id)"
|
|
46
|
+
:title="
|
|
47
|
+
$t('workbench.baseDataTable.restoreDataTitle', {
|
|
48
|
+
dataName: item.title,
|
|
49
|
+
})
|
|
50
|
+
"
|
|
51
|
+
icon="mdi-delete-restore"
|
|
52
|
+
/>
|
|
53
|
+
</template>
|
|
39
54
|
</BaseDataTable>
|
|
40
55
|
</template>
|
|
41
56
|
|
|
@@ -104,13 +119,19 @@ const { data: users } = $data.user.getAll({
|
|
|
104
119
|
})
|
|
105
120
|
|
|
106
121
|
const { data: compositions } = $data.composition.getAll({
|
|
122
|
+
params: { isDeleted: false },
|
|
107
123
|
options: { immediate: true },
|
|
108
124
|
})
|
|
109
125
|
|
|
110
126
|
const { execute: executeDelete } = $data.interactionLink.delete({
|
|
111
127
|
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
112
128
|
})
|
|
113
|
-
|
|
129
|
+
const { execute: executeHardDelete } = await $data.interactionLink.deleteHard({
|
|
130
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
131
|
+
})
|
|
132
|
+
const { execute: executeRestore } = await $data.interactionLink.updateRestore({
|
|
133
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
134
|
+
})
|
|
114
135
|
const parsedInteractionLinks = computed(() => {
|
|
115
136
|
if (interactionLinks.value && tags.value) {
|
|
116
137
|
return Object.values(
|
|
@@ -137,9 +158,16 @@ const parsedInteractionLinks = computed(() => {
|
|
|
137
158
|
|
|
138
159
|
return []
|
|
139
160
|
})
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
161
|
+
const restore = async (_id: string) => {
|
|
162
|
+
executeRestore({ _id })
|
|
163
|
+
}
|
|
164
|
+
const deleteInteractionLink = async (interactionLink: InteractionLink) => {
|
|
165
|
+
if (showDeleted.value) {
|
|
166
|
+
await executeHardDelete({ _id: interactionLink._id })
|
|
167
|
+
} else {
|
|
168
|
+
await executeDelete({ _id: interactionLink._id })
|
|
169
|
+
}
|
|
170
|
+
}
|
|
143
171
|
|
|
144
172
|
$socket.on("interactionLinkCreated", () =>
|
|
145
173
|
execute({ isDeleted: showDeleted.value }),
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<StepNavigator
|
|
3
|
+
:steps
|
|
4
|
+
:is-saving="disabled"
|
|
5
|
+
:show-save-button="isEditing"
|
|
6
|
+
@save="$emit('save')"
|
|
7
|
+
@save-and-finish="$emit('save-and-finish')"
|
|
8
|
+
>
|
|
9
|
+
<!-- @vue-generic {ProjectUpdate} -->
|
|
10
|
+
<DynamicForm
|
|
11
|
+
ref="dynamicFormRef"
|
|
12
|
+
v-model="project"
|
|
13
|
+
:data="projectInputFields"
|
|
14
|
+
:disabled
|
|
15
|
+
:title="$t('workbench.project.formtitle')"
|
|
16
|
+
/>
|
|
17
|
+
<DynamicForm
|
|
18
|
+
ref="dynamicFormRef"
|
|
19
|
+
v-model="project.config"
|
|
20
|
+
:data="configInputFields"
|
|
21
|
+
:disabled
|
|
22
|
+
/>
|
|
23
|
+
</StepNavigator>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import type { ProjectUpdate } from "@raclettejs/core"
|
|
28
|
+
import DynamicForm from "@app/components/dynamicForm/DynamicForm.vue"
|
|
29
|
+
import type { DynamicFormItem } from "@app/components/dynamicForm/DynamicFormTypes"
|
|
30
|
+
import { useI18n } from "vue-i18n"
|
|
31
|
+
import { computed, useTemplateRef } from "vue"
|
|
32
|
+
import { Step } from "@app/components/stepNavigator/StepNavigatorTypes"
|
|
33
|
+
import StepNavigator from "@app/components/stepNavigator/StepNavigator.vue"
|
|
34
|
+
|
|
35
|
+
defineProps<{ disabled?: boolean; isEditing?: boolean }>()
|
|
36
|
+
|
|
37
|
+
defineEmits<{
|
|
38
|
+
(e: "save"): void
|
|
39
|
+
(e: "save-and-finish"): void
|
|
40
|
+
}>()
|
|
41
|
+
|
|
42
|
+
const project = defineModel<ProjectUpdate>({ required: true })
|
|
43
|
+
|
|
44
|
+
const dynamicFormRef = useTemplateRef("dynamicFormRef")
|
|
45
|
+
|
|
46
|
+
const { t } = useI18n()
|
|
47
|
+
|
|
48
|
+
const projectInputFields = computed<DynamicFormItem<ProjectUpdate>[]>(() => [
|
|
49
|
+
{ divider: t("workbench.project.dividers.general") },
|
|
50
|
+
{
|
|
51
|
+
title: t("workbench.project.title.title"),
|
|
52
|
+
description: t("workbench.project.title.description"),
|
|
53
|
+
inputType: "textarea",
|
|
54
|
+
field: "title",
|
|
55
|
+
prependIcon: "text",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: t("workbench.project.description.title"),
|
|
59
|
+
description: t("workbench.project.description.description"),
|
|
60
|
+
inputType: "textarea",
|
|
61
|
+
field: "description",
|
|
62
|
+
prependIcon: "text",
|
|
63
|
+
},
|
|
64
|
+
/* {
|
|
65
|
+
title: t("workbench.interactionLinkConfiguration.tags.title"),
|
|
66
|
+
description: t("workbench.project.tags.description"),
|
|
67
|
+
inputType: "tags",
|
|
68
|
+
field: "tags",
|
|
69
|
+
prependIcon: "tag-multiple",
|
|
70
|
+
},*/
|
|
71
|
+
])
|
|
72
|
+
const configInputFields = computed<DynamicFormItem<ProjectUpdate["config"]>[]>(
|
|
73
|
+
() => [
|
|
74
|
+
{ divider: t("workbench.project.dividers.config") },
|
|
75
|
+
{
|
|
76
|
+
title: t("workbench.project.railPageNavigation.title"),
|
|
77
|
+
description: t("workbench.project.railPageNavigation.description"),
|
|
78
|
+
inputType: "switch",
|
|
79
|
+
field: "railPageNavigation",
|
|
80
|
+
},
|
|
81
|
+
/*{
|
|
82
|
+
title: t("workbench.project.tags.title"),
|
|
83
|
+
description: t("workbench.project.tags.description"),
|
|
84
|
+
inputType: "tags",
|
|
85
|
+
field: "tags",
|
|
86
|
+
prependIcon: "tag-multiple",
|
|
87
|
+
},*/
|
|
88
|
+
],
|
|
89
|
+
)
|
|
90
|
+
const validateForm = (): boolean => {
|
|
91
|
+
const validateAllFields = dynamicFormRef.value?.validateAllFields
|
|
92
|
+
|
|
93
|
+
if (validateAllFields) {
|
|
94
|
+
const isValid = !!validateAllFields()
|
|
95
|
+
|
|
96
|
+
return isValid
|
|
97
|
+
}
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const steps = computed<Step[]>(() => [
|
|
102
|
+
{
|
|
103
|
+
id: "config",
|
|
104
|
+
validator: validateForm,
|
|
105
|
+
},
|
|
106
|
+
])
|
|
107
|
+
</script>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ProjectConfiguration
|
|
3
|
+
v-if="editableProject"
|
|
4
|
+
v-model="editableProject"
|
|
5
|
+
:disabled="isLoading"
|
|
6
|
+
is-editing
|
|
7
|
+
@save="onSubmit"
|
|
8
|
+
/>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { clone } from "ramda"
|
|
13
|
+
import type { Project } from "@raclettejs/core"
|
|
14
|
+
import { usePluginApi } from "@raclettejs/core/orchestrator/composables"
|
|
15
|
+
import { onMounted, ref, toRaw } from "vue"
|
|
16
|
+
import ProjectConfiguration from "../components/ProjectConfiguration.vue"
|
|
17
|
+
|
|
18
|
+
const props = defineProps<{
|
|
19
|
+
uuid: string
|
|
20
|
+
}>()
|
|
21
|
+
|
|
22
|
+
const { $data } = usePluginApi("raclette__core")
|
|
23
|
+
const { $store } = usePluginApi()
|
|
24
|
+
const project = $store.get(["project"])
|
|
25
|
+
|
|
26
|
+
const { execute: executeUpdate, isLoading } = $data.project.update()
|
|
27
|
+
|
|
28
|
+
const editableProject = ref<Project>()
|
|
29
|
+
|
|
30
|
+
const onSubmit = async () => await executeUpdate(toRaw(editableProject.value))
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
editableProject.value = clone({ config: {}, ...project.value })
|
|
33
|
+
})
|
|
34
|
+
</script>
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
:data-name="$t('workbench.tagList.dataName')"
|
|
9
9
|
:data-article="$t('workbench.tagList.dataArticle')"
|
|
10
10
|
@delete="deleteTag"
|
|
11
|
+
:itemsDeleted="showDeleted"
|
|
11
12
|
>
|
|
12
13
|
<template #actions>
|
|
13
14
|
<v-tooltip
|
|
@@ -29,6 +30,20 @@
|
|
|
29
30
|
</template>
|
|
30
31
|
</v-tooltip>
|
|
31
32
|
</template>
|
|
33
|
+
<template #prepend-row-actions="{ item }">
|
|
34
|
+
<v-icon
|
|
35
|
+
v-if="showDeleted"
|
|
36
|
+
color="green"
|
|
37
|
+
class="mr-2"
|
|
38
|
+
@click="restore(item._id)"
|
|
39
|
+
:title="
|
|
40
|
+
$t('workbench.baseDataTable.restoreDataTitle', {
|
|
41
|
+
dataName: item.title,
|
|
42
|
+
})
|
|
43
|
+
"
|
|
44
|
+
icon="mdi-delete-restore"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
32
47
|
</BaseDataTable>
|
|
33
48
|
</template>
|
|
34
49
|
|
|
@@ -79,7 +94,12 @@ const {
|
|
|
79
94
|
const { execute: executeDelete } = $data.tag.delete({
|
|
80
95
|
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
81
96
|
})
|
|
82
|
-
|
|
97
|
+
const { execute: executeHardDelete } = await $data.tag.deleteHard({
|
|
98
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
99
|
+
})
|
|
100
|
+
const { execute: executeRestore } = await $data.tag.updateRestore({
|
|
101
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
102
|
+
})
|
|
83
103
|
const parsedTags = computed(() => {
|
|
84
104
|
if (tags.value) {
|
|
85
105
|
return Object.values(tags.value as { [key: string]: Tag }).map((tag) => ({
|
|
@@ -91,8 +111,16 @@ const parsedTags = computed(() => {
|
|
|
91
111
|
return []
|
|
92
112
|
})
|
|
93
113
|
|
|
94
|
-
const deleteTag = async (tag: Tag) =>
|
|
95
|
-
|
|
114
|
+
const deleteTag = async (tag: Tag) => {
|
|
115
|
+
if (showDeleted.value) {
|
|
116
|
+
await executeHardDelete({ _id: tag._id })
|
|
117
|
+
} else {
|
|
118
|
+
await executeDelete({ _id: tag._id })
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const restore = async (_id: string) => {
|
|
122
|
+
executeRestore({ _id })
|
|
123
|
+
}
|
|
96
124
|
$socket.on("tagCreated", () => execute({ isDeleted: showDeleted.value }))
|
|
97
125
|
watch(
|
|
98
126
|
showDeleted,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
:data-article="$t('workbench.userList.dataArticle')"
|
|
10
10
|
:delete-validator="(user) => user._id !== $user?._id"
|
|
11
11
|
@delete="deleteUser"
|
|
12
|
+
:itemsDeleted="showDeleted"
|
|
12
13
|
>
|
|
13
14
|
<template #actions>
|
|
14
15
|
<v-tooltip
|
|
@@ -30,6 +31,20 @@
|
|
|
30
31
|
</template>
|
|
31
32
|
</v-tooltip>
|
|
32
33
|
</template>
|
|
34
|
+
<template #prepend-row-actions="{ item }">
|
|
35
|
+
<v-icon
|
|
36
|
+
v-if="showDeleted"
|
|
37
|
+
color="green"
|
|
38
|
+
class="mr-2"
|
|
39
|
+
@click.stop.prevent="restore(item._id)"
|
|
40
|
+
:title="
|
|
41
|
+
$t('workbench.baseDataTable.restoreDataTitle', {
|
|
42
|
+
dataName: item.title,
|
|
43
|
+
})
|
|
44
|
+
"
|
|
45
|
+
icon="mdi-delete-restore"
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
33
48
|
</BaseDataTable>
|
|
34
49
|
</template>
|
|
35
50
|
|
|
@@ -78,11 +93,15 @@ const { data: users, execute, isLoading: usersLoading } = $data.user.getAll()
|
|
|
78
93
|
const { data: tags, isLoading: tagsLoading } = $data.tag.getAll({
|
|
79
94
|
options: { immediate: true },
|
|
80
95
|
})
|
|
81
|
-
|
|
82
96
|
const { execute: executeDelete } = $data.user.delete({
|
|
83
97
|
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
84
98
|
})
|
|
85
|
-
|
|
99
|
+
const { execute: executeHardDelete } = await $data.user.deleteHard({
|
|
100
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
101
|
+
})
|
|
102
|
+
const { execute: executeRestore } = await $data.user.updateRestore({
|
|
103
|
+
options: { cb: () => execute({ isDeleted: showDeleted.value }) },
|
|
104
|
+
})
|
|
86
105
|
const parsedUsers = computed(() => {
|
|
87
106
|
if (users.value && tags.value) {
|
|
88
107
|
return Object.values(users.value as { [key: string]: User }).map(
|
|
@@ -95,9 +114,16 @@ const parsedUsers = computed(() => {
|
|
|
95
114
|
}
|
|
96
115
|
return []
|
|
97
116
|
})
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
const deleteUser = async (user: User) => {
|
|
118
|
+
if (showDeleted.value) {
|
|
119
|
+
await executeHardDelete({ _id: user._id })
|
|
120
|
+
} else {
|
|
121
|
+
await executeDelete({ _id: user._id })
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const restore = async (_id: string) => {
|
|
125
|
+
executeRestore({ _id })
|
|
126
|
+
}
|
|
101
127
|
$socket.on("userCreated", () => execute({ isDeleted: showDeleted.value }))
|
|
102
128
|
watch(
|
|
103
129
|
showDeleted,
|
package/raclette.config.js
CHANGED
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
<!-- Additional action buttons slot -->
|
|
36
36
|
<slot name="actions" />
|
|
37
37
|
</div>
|
|
38
|
-
|
|
39
38
|
<!-- Data Table -->
|
|
40
39
|
<v-data-table
|
|
41
40
|
v-model:search="search"
|
|
@@ -47,6 +46,7 @@
|
|
|
47
46
|
:items="items"
|
|
48
47
|
:loading="loading"
|
|
49
48
|
@click:row="handleRowClick"
|
|
49
|
+
:class="{ itemsDeleted }"
|
|
50
50
|
>
|
|
51
51
|
<template
|
|
52
52
|
#item.color="{ item }"
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
<!-- Actions column template -->
|
|
83
83
|
<template #item.actions="{ item }" v-if="showActionsColumn">
|
|
84
|
+
<slot name="prepend-row-actions" :item="item"> </slot>
|
|
84
85
|
<slot name="row-actions" :item="item">
|
|
85
86
|
<!-- Default delete action -->
|
|
86
87
|
<v-icon
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
icon="mdi-delete"
|
|
97
98
|
/>
|
|
98
99
|
</slot>
|
|
100
|
+
<slot name="append-row-actions" :item="item"> </slot>
|
|
99
101
|
</template>
|
|
100
102
|
|
|
101
103
|
<!-- Loading template -->
|
|
@@ -168,7 +170,7 @@ export interface BaseDataTableProps<T> {
|
|
|
168
170
|
// Data props
|
|
169
171
|
items?: T[]
|
|
170
172
|
loading?: boolean
|
|
171
|
-
|
|
173
|
+
itemsDeleted?: boolean
|
|
172
174
|
// Table configuration
|
|
173
175
|
headers: Array<{
|
|
174
176
|
title: string
|
|
@@ -201,6 +203,7 @@ export interface BaseDataTableProps<T> {
|
|
|
201
203
|
const props = withDefaults(defineProps<BaseDataTableProps<T>>(), {
|
|
202
204
|
uuid: undefined,
|
|
203
205
|
items: () => [],
|
|
206
|
+
itemsDeleted: false,
|
|
204
207
|
itemsPerPage: 50,
|
|
205
208
|
showCreateButton: true,
|
|
206
209
|
showActionsColumn: true,
|
|
@@ -292,3 +295,9 @@ const isDeleteDisabled = (item: T): boolean => {
|
|
|
292
295
|
return props.deleteValidator ? !props.deleteValidator(item) : false
|
|
293
296
|
}
|
|
294
297
|
</script>
|
|
298
|
+
<style lang="css">
|
|
299
|
+
.itemsDeleted .v-data-table__tr {
|
|
300
|
+
background-color: rgb(233, 190, 190);
|
|
301
|
+
color: #000;
|
|
302
|
+
}
|
|
303
|
+
</style>
|
|
@@ -23,9 +23,7 @@
|
|
|
23
23
|
<div class="tw:grid tw:gap-2 tw:p-2">
|
|
24
24
|
<template
|
|
25
25
|
v-if="
|
|
26
|
-
['
|
|
27
|
-
trigger.type,
|
|
28
|
-
)
|
|
26
|
+
['app-bar', 'page-navigation', 'user-menu'].includes(trigger.type)
|
|
29
27
|
"
|
|
30
28
|
>
|
|
31
29
|
<IconInput v-model="trigger.settings.icon" v-bind="$attrs" />
|
|
@@ -96,8 +94,8 @@ defineOptions({
|
|
|
96
94
|
|
|
97
95
|
const modelValue = defineModel<Trigger[]>({ required: true })
|
|
98
96
|
|
|
99
|
-
// TODO readd
|
|
100
|
-
const triggerTypes = ["page-navigation", "user-menu"] as const
|
|
97
|
+
// TODO readd "shortcut" once they are implemented
|
|
98
|
+
const triggerTypes = ["page-navigation", "user-menu", "app-bar"] as const
|
|
101
99
|
const pageNavigationTypes = ["footerItem", "navItem"] as const
|
|
102
100
|
const virtualTrigger = ref<Trigger>({
|
|
103
101
|
type: "",
|
|
@@ -123,7 +121,7 @@ const createSettingsObject = (
|
|
|
123
121
|
): Trigger["settings"] => {
|
|
124
122
|
if (
|
|
125
123
|
triggerType === "page-navigation" ||
|
|
126
|
-
triggerType === "
|
|
124
|
+
triggerType === "app-bar" ||
|
|
127
125
|
triggerType === "user-menu"
|
|
128
126
|
) {
|
|
129
127
|
const clickLink = {
|
package/yarn.lock
CHANGED
|
@@ -476,10 +476,10 @@
|
|
|
476
476
|
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b"
|
|
477
477
|
integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==
|
|
478
478
|
|
|
479
|
-
"@raclettejs/core@^0.1.
|
|
480
|
-
version "0.1.
|
|
481
|
-
resolved "https://registry.yarnpkg.com/@raclettejs/core/-/core-0.1.
|
|
482
|
-
integrity sha512-
|
|
479
|
+
"@raclettejs/core@^0.1.18":
|
|
480
|
+
version "0.1.18"
|
|
481
|
+
resolved "https://registry.yarnpkg.com/@raclettejs/core/-/core-0.1.18.tgz#6bf2a7de62996b3e2bc038b35e572467d2871130"
|
|
482
|
+
integrity sha512-jftqZLGoUm3CxG8UZ8nsF0vrQiZ+mhFdOglu+AdECEqi0Jr+2MbStEkHsz5RRKau6TXiT4Prmtv9/x1ZS8aGbQ==
|
|
483
483
|
dependencies:
|
|
484
484
|
chalk "5.6.2"
|
|
485
485
|
chokidar "3.6.0"
|
|
@@ -492,10 +492,10 @@
|
|
|
492
492
|
ramda "0.31.3"
|
|
493
493
|
tsc-alias "1.8.16"
|
|
494
494
|
|
|
495
|
-
"@raclettejs/types@^0.1.
|
|
496
|
-
version "0.1.
|
|
497
|
-
resolved "https://registry.yarnpkg.com/@raclettejs/types/-/types-0.1.
|
|
498
|
-
integrity sha512-
|
|
495
|
+
"@raclettejs/types@^0.1.18":
|
|
496
|
+
version "0.1.18"
|
|
497
|
+
resolved "https://registry.yarnpkg.com/@raclettejs/types/-/types-0.1.18.tgz#7df0eb1b86db015694fabfafa089a277e654b350"
|
|
498
|
+
integrity sha512-mvQI2sO48z6+QKj/s5A5JMBKnY8piE+8D8N0soctfsU7tAKg8nEwlxOiQHZiqJyR1k+gX2p+VBMRGbxHCYAGFw==
|
|
499
499
|
dependencies:
|
|
500
500
|
"@types/node" "24.5.2"
|
|
501
501
|
fastify "5.6.0"
|