@raclettejs/workbench 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/.raclette/backend/raclette.config.js +519 -0
  2. package/{yarn.lock → .raclette/backend/yarn.lock} +1014 -796
  3. package/.raclette/frontend/raclette.config.js +47 -0
  4. package/.raclette/frontend/yarn.lock +3428 -0
  5. package/.raclette/raclette.config.js +643 -0
  6. package/.raclette/virtual/backend/README.md +172 -0
  7. package/.raclette/virtual/backend/raclette.config.js +519 -0
  8. package/.raclette/virtual/backend/yarn.lock +3773 -0
  9. package/.raclette/virtual/frontend/README.md +511 -0
  10. package/.raclette/virtual/frontend/raclette.config.js +47 -0
  11. package/.raclette/virtual/frontend/src/core/lib/eggs/readme.md +75 -0
  12. package/.raclette/virtual/frontend/yarn.lock +3428 -0
  13. package/CHANGELOG.md +7 -0
  14. package/i18n/de-DE.json +17 -1
  15. package/i18n/en-EU.json +17 -1
  16. package/i18n/sk-SK.json +17 -1
  17. package/package.json +4 -2
  18. package/packages.json +3 -1
  19. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/CompositionWidgetsLayout.vue +8 -3
  20. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetContextMenu.vue +60 -0
  21. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetIcon.vue +4 -7
  22. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetList.vue +34 -117
  23. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetListFlat.vue +20 -0
  24. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetListGrouped.vue +50 -0
  25. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetListHeader.vue +213 -0
  26. package/plugins/pacifico__compositions/frontend/components/compositionConfiguration/widgetsLayout/WidgetListItem.vue +56 -0
  27. package/plugins/pacifico__compositions/frontend/composables/useWidgetList.ts +288 -0
  28. package/raclette.config.js +4 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.21] - 2026-03-05 <a href="https://gitlab.com/raclettejs/core-dev/-/compare/v0.1.20...v0.1.21" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
11
+
12
+ ### Added
13
+
14
+ - widgetId is now configurable in composition layout screen
15
+ - WidgetList.vue (used in the Widget Layout) has a new design, and options for searching and filtering for widgets.
16
+
10
17
  ## [0.1.19] - 12.12.2025 <a href="https://gitlab.com/raclettejs/workbench/-/compare/v0.1.18...v0.1.19" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
11
18
 
12
19
  ### Added
package/i18n/de-DE.json CHANGED
@@ -100,6 +100,22 @@
100
100
  "slotLayout": {
101
101
  "title": "Slot Layout",
102
102
  "description": "Beschreibt das Zusammenspiel der einzelnen Widgets auf der Seite (Abstände sowie Rahmen pro Widget)"
103
+ },
104
+ "widgetLayout": {
105
+ "widgetList": {
106
+ "searchLabel": "Widgets durchsuchen",
107
+ "menuAriaLabel": "Liste filtern und sortieren",
108
+ "menuTitle": "Liste anpassen",
109
+ "sortingTitle": "Sortierung",
110
+ "pluginFilterTitle": "Plugins anzeigen",
111
+ "sortOptions": {
112
+ "group": "Gruppiert",
113
+ "name": "Nach Name",
114
+ "author": "Nach Autor"
115
+ },
116
+ "countAll": "{count} Widgets",
117
+ "countFiltered": "{visible} von {total} Widgets"
118
+ }
103
119
  }
104
120
  },
105
121
  "interactionLinkList": {
@@ -274,4 +290,4 @@
274
290
  }
275
291
  }
276
292
  }
277
- }
293
+ }
package/i18n/en-EU.json CHANGED
@@ -100,6 +100,22 @@
100
100
  "slotLayout": {
101
101
  "title": "Slot Layout",
102
102
  "description": "Describes the interaction of the individual widgets on the page (spacing and borders per widget)"
103
+ },
104
+ "widgetLayout": {
105
+ "widgetList": {
106
+ "searchLabel": "Search widgets",
107
+ "menuAriaLabel": "Filter and sort list",
108
+ "menuTitle": "Adjust list",
109
+ "sortingTitle": "Sorting",
110
+ "pluginFilterTitle": "Show plugins",
111
+ "sortOptions": {
112
+ "group": "Grouped",
113
+ "name": "By name",
114
+ "author": "By author"
115
+ },
116
+ "countAll": "{count} widgets",
117
+ "countFiltered": "{visible} of {total} widgets"
118
+ }
103
119
  }
104
120
  },
105
121
  "interactionLinkList": {
@@ -274,4 +290,4 @@
274
290
  }
275
291
  }
276
292
  }
277
- }
293
+ }
package/i18n/sk-SK.json CHANGED
@@ -95,6 +95,22 @@
95
95
  "pathname": {
96
96
  "title": "Cesta (Pathname)",
97
97
  "description": "Popisuje technický názov používaný ako URL cesta, parameter dotazu alebo iný odkaz. Nesmie obsahovať medzery."
98
+ },
99
+ "widgetLayout": {
100
+ "widgetList": {
101
+ "searchLabel": "Hľadať widgety",
102
+ "menuAriaLabel": "Filtrovať a triediť zoznam",
103
+ "menuTitle": "Upraviť zoznam",
104
+ "sortingTitle": "Triedenie",
105
+ "pluginFilterTitle": "Zobraziť pluginy",
106
+ "sortOptions": {
107
+ "group": "Zoskupené",
108
+ "name": "Podľa názvu",
109
+ "author": "Podľa autora"
110
+ },
111
+ "countAll": "{count} widgetov",
112
+ "countFiltered": "{visible} z {total} widgetov"
113
+ }
98
114
  }
99
115
  },
100
116
  "interactionLinkList": {
@@ -269,4 +285,4 @@
269
285
  }
270
286
  }
271
287
  }
272
- }
288
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raclettejs/workbench",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
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",
@@ -32,6 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@raclettejs/core": "0.1.19",
35
+ "@vueuse/integrations": "14.2.1",
36
+ "fuse.js": "7.1.0",
35
37
  "three": "0.180.0",
36
38
  "vanta": "0.5.24"
37
39
  },
@@ -64,4 +66,4 @@
64
66
  "vuetify": "3.10.2"
65
67
  },
66
68
  "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
67
- }
69
+ }
package/packages.json CHANGED
@@ -2,7 +2,9 @@
2
2
  "frontend": {
3
3
  "dependencies": {
4
4
  "three": "0.179.1",
5
- "vanta": "0.5.24"
5
+ "vanta": "0.5.24",
6
+ "@vueuse/integrations": "14.2.1",
7
+ "fuse.js": "7.1.0"
6
8
  },
7
9
  "devDependencies": {}
8
10
  },
@@ -26,7 +26,7 @@
26
26
  @resize="onResize($event, dropzoneIndex, widgetIndex)"
27
27
  @update-config="onConfigChanges($event, dropzoneIndex, widgetIndex)"
28
28
  @remove-widget="removeWidget(widgetSlot.widget.uuid)"
29
- @open-settings="showSettingsForWidget = widgetSlot.widget"
29
+ @open-settings="toggleSettings(widgetSlot.widget)"
30
30
  />
31
31
  </DropzoneElement>
32
32
  </div>
@@ -60,9 +60,14 @@ import DropzoneElement from "@raclettejs/core/orchestrator/components/dragAndDro
60
60
  const composition = defineModel<CompositionCreate | CompositionUpdate>({
61
61
  required: true,
62
62
  })
63
-
64
63
  const showSettingsForWidget = ref<WidgetBase | null>()
65
-
64
+ const toggleSettings = (widget) => {
65
+ if (showSettingsForWidget.value == widget) {
66
+ showSettingsForWidget.value = null
67
+ } else {
68
+ showSettingsForWidget.value = widget
69
+ }
70
+ }
66
71
  const createNewWidget = (widgetName: string, pluginKey: string) => ({
67
72
  column: 12,
68
73
  widget: {
@@ -1,6 +1,42 @@
1
1
  <template>
2
2
  <div class="tw:z-50">
3
3
  <div class="tw:flex tw:gap-1">
4
+ <!-- UUID Edit Button/Input -->
5
+ <div v-if="!isEditingUuid" class="tw:flex">
6
+ <v-btn
7
+ class="tw:rounded"
8
+ icon="mdi-identifier"
9
+ color="grey-darken-3"
10
+ @click="startEditingUuid()"
11
+ />
12
+ </div>
13
+ <div v-else class="tw:flex tw:gap-1 tw:items-center">
14
+ <v-text-field
15
+ v-model="editableUuid"
16
+ density="compact"
17
+ hide-details
18
+ class="tw:min-w-[200px]"
19
+ variant="outlined"
20
+ @keyup.enter="saveUuid()"
21
+ @keyup.esc="cancelEditingUuid()"
22
+ />
23
+ <v-btn
24
+ class="tw:rounded"
25
+ icon="mdi-check"
26
+ color="success"
27
+ size="small"
28
+ @click="saveUuid()"
29
+ />
30
+ <v-btn
31
+ class="tw:rounded"
32
+ icon="mdi-close"
33
+ color="grey"
34
+ size="small"
35
+ @click="cancelEditingUuid()"
36
+ />
37
+ </div>
38
+
39
+ <!-- Settings Button -->
4
40
  <v-btn
5
41
  v-if="Object.keys(configurableParameteters || {}).length"
6
42
  class="tw:rounded"
@@ -8,6 +44,8 @@
8
44
  color="grey-darken-3"
9
45
  @click="openWidgetSettings()"
10
46
  />
47
+
48
+ <!-- Delete Button -->
11
49
  <v-btn
12
50
  class="tw:rounded"
13
51
  icon="mdi-delete-outline"
@@ -45,6 +83,28 @@ const widget = computed(() => findWidgetByName(widgetConfig.widget.name))
45
83
  const configurableParameteters = computed(
46
84
  () => widget.value?.configurableParameters,
47
85
  )
86
+
87
+ // UUID editing state
88
+ const isEditingUuid = ref(false)
89
+ const editableUuid = ref("")
90
+
91
+ const startEditingUuid = () => {
92
+ editableUuid.value = widgetConfig.widget.uuid
93
+ isEditingUuid.value = true
94
+ }
95
+
96
+ const saveUuid = () => {
97
+ const updatedConfig = clone(editableConfig.value)
98
+ updatedConfig.widget.uuid = editableUuid.value
99
+ emit("updateConfig", updatedConfig)
100
+ isEditingUuid.value = false
101
+ }
102
+
103
+ const cancelEditingUuid = () => {
104
+ isEditingUuid.value = false
105
+ editableUuid.value = ""
106
+ }
107
+
48
108
  const openWidgetSettings = () => emit("openSettings")
49
109
 
50
110
  const removeWidget = () => emit("removeWidget")
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <div>
3
- <figure class="tw:flex tw:flex-col tw:items-center tw:gap-4">
3
+ <figure class="tw:flex tw:items-center tw:gap-2">
4
4
  <span
5
- class="tw:flex tw:h-24 tw:w-24 tw:items-center tw:justify-center tw:rounded tw:shadow-lg"
5
+ class="tw:flex tw:h-8 tw:w-8 tw:items-center tw:justify-center tw:rounded tw:shadow-none"
6
6
  :style="{
7
7
  backgroundColor: module.color,
8
8
  }"
9
9
  >
10
10
  <span
11
11
  v-if="svgContent"
12
- class="tw:flex tw:h-20 tw:w-20 tw:items-center tw:justify-center"
12
+ class="tw:flex tw:h-6 tw:w-6 tw:items-center tw:justify-center"
13
13
  :style="{
14
14
  '--highlight-color': module.color,
15
15
  '--base-color': baseColor,
@@ -21,12 +21,9 @@
21
21
  v-else
22
22
  :src="module.icon"
23
23
  :alt="`${module.title} icon`"
24
- class="tw:size-20"
24
+ class="tw:size-6"
25
25
  />
26
26
  </span>
27
- <figcaption class="tw:text-center tw:no-underline">
28
- {{ module.title }}
29
- </figcaption>
30
27
  </figure>
31
28
  </div>
32
29
  </template>
@@ -1,122 +1,39 @@
1
1
  <template>
2
- <v-list v-model:opened="openListItems">
3
- <v-list-subheader>Modules</v-list-subheader>
4
-
5
- <v-list-group
6
- v-for="(authorPlugins, authorName) in groupedWidgets"
7
- :key="authorName"
8
- :value="authorName"
9
- >
10
- <template #activator="{ props }">
11
- <v-list-item v-bind="props" :title="authorName" />
12
- </template>
13
- <v-list-group
14
- v-for="(pluginWidgets, pluginKey) in authorPlugins"
15
- :key="pluginKey"
16
- :value="pluginKey"
17
- >
18
- <template #activator="{ props }">
19
- <v-list-item
20
- v-bind="props"
21
- :title="deslugify(pluginKey.split('__')[1])"
22
- ></v-list-item>
23
- </template>
24
-
25
- <DraggableElement
26
- v-for="widget in pluginWidgets"
27
- :key="widget.title"
28
- class="tw:py-4"
29
- :draggable-config="{
30
- type: 'widget',
31
- widgetName: widget.name,
32
- pluginKey: widget.pluginKey,
33
- }"
34
- >
35
- <WidgetIcon :module="widget" />
36
- </DraggableElement>
37
- <v-divider></v-divider>
38
- </v-list-group>
39
- </v-list-group>
40
- </v-list>
2
+ <div>
3
+ <WidgetListHeader
4
+ v-model:searchQuery="searchQuery"
5
+ v-model:sortMode="sortMode"
6
+ v-model:visiblePluginKeys="visiblePluginKeys"
7
+ :sort-options="sortOptions"
8
+ :plugin-filter-options="pluginFilterOptions"
9
+ :widgets-count="widgetsCount"
10
+ :visible-widgets-count="visibleWidgetsCount"
11
+ />
12
+
13
+ <WidgetListGrouped
14
+ v-if="sortMode === 'group' && !(searchQuery ?? '').trim()"
15
+ :grouped-widgets="filteredGroupedWidgets"
16
+ />
17
+
18
+ <WidgetListFlat v-else :widgets="filteredWidgetsFlat" />
19
+ </div>
41
20
  </template>
42
21
 
43
22
  <script setup lang="ts">
44
- import { deslugify } from "@shared/helper/pluginHelper"
45
- import { computed, ref } from "vue"
46
- import useWidgets from "@raclettejs/core/orchestrator/composables/useWidgets"
47
- import { RegisteredWidgetDeclaration } from "@raclettejs/core"
48
- import WidgetIcon from "./WidgetIcon.vue"
49
- import DraggableElement from "@raclettejs/core/orchestrator/components/dragAndDrop/DraggableElement.vue"
50
-
51
- const { widgets } = useWidgets()
52
-
53
- const openListItems = ref(["Users"])
54
-
55
- const groupedWidgets = computed(() => {
56
- const unsortedResult: Record<
57
- string,
58
- Record<string, RegisteredWidgetDeclaration[]>
59
- > = {}
60
-
61
- widgets.value.forEach((widget) => {
62
- if (!unsortedResult[widget.author]) {
63
- unsortedResult[widget.author] = {}
64
- }
65
-
66
- if (!unsortedResult[widget.author][widget.pluginKey]) {
67
- unsortedResult[widget.author][widget.pluginKey] = []
68
- }
69
-
70
- unsortedResult[widget.author][widget.pluginKey].push(widget)
71
- })
72
-
73
- const sortedAuthors = Object.keys(unsortedResult).sort((a, b) => {
74
- if (a === "pacifico") {
75
- return 1
76
- }
77
- if (b === "pacifico") {
78
- return -1
79
- }
80
-
81
- return a.localeCompare(b)
82
- })
83
-
84
- const sortedResult: Record<
85
- string,
86
- Record<string, RegisteredWidgetDeclaration[]>
87
- > = {}
88
-
89
- sortedAuthors.forEach((author) => {
90
- const plugins = Object.keys(unsortedResult[author]).sort((a, b) => {
91
- if (a === "core") {
92
- return 1
93
- }
94
- if (b === "core") {
95
- return -1
96
- }
97
-
98
- return a.localeCompare(b)
99
- })
100
-
101
- sortedResult[author] = {}
102
- plugins.forEach((pluginKey) => {
103
- sortedResult[author][pluginKey] = unsortedResult[author][pluginKey]
104
- })
105
- })
106
-
107
- return sortedResult
108
- })
109
-
110
- const initOpenListItems = () => {
111
- const keys: string[] = []
112
-
113
- widgets.value.forEach((widget) => {
114
- keys.push(widget.author)
115
- keys.push(widget.pluginKey)
116
- })
117
-
118
- openListItems.value = [...new Set(keys)]
119
- }
120
-
121
- initOpenListItems()
23
+ import WidgetListHeader from "./WidgetListHeader.vue"
24
+ import WidgetListGrouped from "./WidgetListGrouped.vue"
25
+ import WidgetListFlat from "./WidgetListFlat.vue"
26
+ import { useWidgetList } from "../../../composables/useWidgetList"
27
+
28
+ const {
29
+ searchQuery,
30
+ sortMode,
31
+ visiblePluginKeys,
32
+ sortOptions,
33
+ pluginFilterOptions,
34
+ widgetsCount,
35
+ visibleWidgetsCount,
36
+ filteredWidgetsFlat,
37
+ filteredGroupedWidgets,
38
+ } = useWidgetList()
122
39
  </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <v-list>
3
+ <WidgetListItem
4
+ v-for="widget in widgets"
5
+ :key="widget.title"
6
+ :widget="widget"
7
+ outer-class="tw:py-2"
8
+ />
9
+ </v-list>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import type { RegisteredWidgetDeclaration } from "@raclettejs/core"
14
+ import WidgetListItem from "./WidgetListItem.vue"
15
+
16
+ const props = defineProps<{
17
+ widgets: RegisteredWidgetDeclaration[]
18
+ }>()
19
+ </script>
20
+
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <v-list>
3
+ <div
4
+ v-for="(authorPlugins, authorName) in groupedWidgets"
5
+ :key="authorName"
6
+ class="tw:mb-3"
7
+ >
8
+ <div
9
+ class="tw:px-3 tw:py-1 tw:text-[11px] tw:font-medium tw:uppercase tw:tracking-wide tw:text-slate-500"
10
+ >
11
+ {{ authorName }}
12
+ </div>
13
+
14
+ <div
15
+ v-for="(pluginWidgets, pluginKey) in authorPlugins"
16
+ :key="pluginKey"
17
+ class="tw:mb-1"
18
+ >
19
+ <div
20
+ class="tw:px-3 tw:py-0.5 tw:text-[11px] tw:uppercase tw:text-slate-400"
21
+ >
22
+ {{ pluginLabel(pluginKey) }}
23
+ </div>
24
+
25
+ <WidgetListItem
26
+ v-for="widget in pluginWidgets"
27
+ :key="widget.title"
28
+ :widget="widget"
29
+ outer-class="tw:py-1"
30
+ />
31
+ </div>
32
+ </div>
33
+ </v-list>
34
+ </template>
35
+
36
+ <script setup lang="ts">
37
+ import { deslugify } from "@shared/helper/pluginHelper"
38
+ import type { GroupedWidgets } from "../../../composables/useWidgetList"
39
+ import WidgetListItem from "./WidgetListItem.vue"
40
+
41
+ const props = defineProps<{
42
+ groupedWidgets: GroupedWidgets
43
+ }>()
44
+
45
+ const pluginLabel = (pluginKey: string) => {
46
+ const parts = pluginKey.split("__")
47
+ const slug = parts[1] ?? parts[0]
48
+ return deslugify(slug)
49
+ }
50
+ </script>