@raclettejs/core 0.1.11 → 0.1.13
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 +53 -0
- package/dist/cli.js +97 -97
- package/dist/cli.js.map +7 -0
- package/dist/index.js +4 -4
- package/dist/index.js.map +7 -0
- package/package.json +4 -3
- package/services/backend/package.json +1 -0
- package/services/backend/src/core/payload/payloadTypes.ts +7 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.getAll.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.model.ts +5 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.schema.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.service.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.getAll.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/helpers/payload.ts +6 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.getAll.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.getAll.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/index.ts +2 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.getAll.ts +6 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/tag.service.ts +22 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.get.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.getAll.ts +1 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.remove.ts +3 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/user.service.ts +1 -2
- package/services/backend/src/corePlugins/raclette__core/frontend/generated-config.ts +12 -12
- package/services/backend/src/domains/index.ts +3 -0
- package/services/backend/src/domains/system/collections.service.ts +119 -0
- package/services/backend/src/domains/system/index.ts +8 -0
- package/services/backend/src/domains/system/routes/index.ts +5 -0
- package/services/backend/src/domains/system/routes/route.collection.getAll.ts +61 -0
- package/services/backend/src/domains/system/routes/route.collection.remove.ts +93 -0
- package/services/backend/src/types/custom-fastify.d.ts +1 -0
- package/services/backend/src/utils/request.utils.ts +28 -1
- package/services/backend/yarn.lock +11 -2
- package/services/frontend/package.json +1 -0
- package/services/frontend/src/core/constants/ApiClient.ts +6 -1
- package/services/frontend/src/core/lib/data/dataApi.ts +8 -1
- package/services/frontend/src/core/lib/data/fetchDataHandler.ts +58 -27
- package/services/frontend/src/core/lib/data/queryApi.ts +29 -8
- package/services/frontend/src/core/lib/data/responseTypeHandler.ts +27 -4
- package/services/frontend/src/core/lib/data/writeDataHandler.ts +1 -1
- package/services/frontend/src/core/lib/dataHelper.ts +8 -1
- package/services/frontend/src/core/lib/easteregg.ts +1 -1
- package/services/frontend/src/core/lib/eventEmitter.ts +1 -0
- package/services/frontend/src/core/lib/eventWhitelist.ts +11 -1
- package/services/frontend/src/core/lib/logger.ts +11 -3
- package/services/frontend/src/core/lib/userNotifier.ts +17 -17
- package/services/frontend/src/core/main.ts +3 -3
- package/services/frontend/src/core/setup/plugin-system/api/wrappers.ts +18 -1
- package/services/frontend/src/core/setup/plugin-system/registration/index.ts +1 -1
- package/services/frontend/src/core/setup/socketClient.ts +2 -2
- package/services/frontend/src/core/setup/socketEvents.ts +2 -2
- package/services/frontend/src/core/store/reducers/compositions/selectors.ts +2 -2
- package/services/frontend/src/core/store/reducers/data/index.ts +1 -1
- package/services/frontend/src/core/store/reducers/data/reducers.ts +3 -3
- package/services/frontend/src/core/store/reducers/queries/effects.ts +20 -1
- package/services/frontend/src/core/store/reducers/queries/index.ts +1 -0
- package/services/frontend/src/core/store/reducers/queries/reducers.ts +28 -1
- package/services/frontend/src/core/store/reducers/queriesCache/queryCacheHelper.ts +5 -4
- package/services/frontend/src/core/store/reducers/queriesCache/reducers.ts +4 -3
- package/services/frontend/src/core/store/state.ts +1 -1
- package/services/frontend/src/core/types/ApiClient.ts +1 -1
- package/services/frontend/src/core/types/DataApi.ts +4 -0
- package/services/frontend/src/core/types/Queries.ts +1 -0
- package/services/frontend/src/orchestrator/ProductOrchestrator.vue +19 -7
- package/services/frontend/src/orchestrator/WelcomeScreen.vue +40 -42
- package/services/frontend/src/orchestrator/assets/styles/tailwindStyles.css +3 -0
- package/services/frontend/src/orchestrator/assets/styles/themes/dark.ts +2 -2
- package/services/frontend/src/orchestrator/components/composition/CompositionOverlay.vue +11 -2
- package/services/frontend/src/orchestrator/components/composition/WidgetsLayoutLoader.vue +167 -58
- package/services/frontend/src/orchestrator/components/menu/DevIndicator.vue +122 -7
- package/services/frontend/src/orchestrator/components/menu/UserMenu.vue +38 -20
- package/services/frontend/src/orchestrator/components/snackbar/SnackStack.vue +17 -5
- package/services/frontend/src/orchestrator/composables/useCurrentComposition.ts +32 -4
- package/services/frontend/src/orchestrator/composables/usePageNavigation.ts +5 -1
- package/services/frontend/src/orchestrator/composables/usePluginApi.ts +113 -63
- package/services/frontend/src/orchestrator/composables/useRouteState.ts +0 -1
- package/services/frontend/src/orchestrator/composables/useVueQueryObservableHelper.ts +2 -0
- package/services/frontend/src/orchestrator/composables/useVueWriteOperationHelper.ts +5 -3
- package/services/frontend/src/orchestrator/composables/useWidgets/helperFunctions.ts +4 -1
- package/services/frontend/src/orchestrator/helpers/loginUserNotifications.ts +1 -1
- package/services/frontend/src/orchestrator/helpers/uiHelper.ts +1 -1
- package/services/frontend/src/orchestrator/i18n/de-DE.json +1 -0
- package/services/frontend/src/orchestrator/i18n/en-EU.json +1 -0
- package/services/frontend/src/orchestrator/i18n/sk.json +1 -0
- package/services/frontend/src/orchestrator/router/routeParserHelper.ts +4 -1
- package/services/frontend/src/orchestrator/router/routeStore.ts +78 -11
- package/services/frontend/tsconfig.app.json +1 -0
- package/services/frontend/yarn.lock +5 -0
- package/yarn.lock +4 -4
|
@@ -5,18 +5,42 @@ import { useVueWriteOperationHelper } from "@racletteOrchestrator/composables/us
|
|
|
5
5
|
import { useVueStateObservableHelper } from "@racletteOrchestrator/composables/useVueStateObservableHelper"
|
|
6
6
|
import { getCurrentInstance, onUnmounted } from "vue"
|
|
7
7
|
import { clone } from "ramda"
|
|
8
|
-
import { $store } from "@racletteCore"
|
|
9
|
-
import type {
|
|
10
|
-
import
|
|
8
|
+
import { $store, createStableHash } from "@racletteCore"
|
|
9
|
+
import type { pluginKey } from "@racletteCore"
|
|
10
|
+
import {
|
|
11
|
+
useRouteState,
|
|
12
|
+
type PluginApi,
|
|
13
|
+
type PluginApiParams,
|
|
14
|
+
} from "@racletteOrchestrator"
|
|
11
15
|
import { useNamespacedI18n } from "@racletteOrchestrator/composables/useNamespacedI18n"
|
|
12
|
-
import {
|
|
16
|
+
import { getCompositionByPath } from "@racletteCore/store/reducers/compositions/selectors"
|
|
17
|
+
|
|
18
|
+
//TODO move this into a $store api module
|
|
19
|
+
const findWidgetUUIDs = (obj: any): string[] => {
|
|
20
|
+
const uuids: string[] = []
|
|
21
|
+
|
|
22
|
+
const recurse = (value: any): void => {
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
value.forEach(recurse)
|
|
25
|
+
} else if (value && typeof value === "object") {
|
|
26
|
+
if (value.widget?.uuid) {
|
|
27
|
+
uuids.push(value.widget.uuid)
|
|
28
|
+
}
|
|
29
|
+
Object.values(value).forEach(recurse)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
recurse(obj.widgetsLayout)
|
|
34
|
+
return uuids
|
|
35
|
+
}
|
|
13
36
|
|
|
14
37
|
export const usePluginApi = (
|
|
15
|
-
params:
|
|
38
|
+
params: pluginKey | PluginApiParams = {},
|
|
16
39
|
): PluginApi => {
|
|
17
|
-
const subscribers$ = {}
|
|
18
40
|
const instance = getCurrentInstance()
|
|
19
41
|
const getState = useVueStateObservableHelper()
|
|
42
|
+
|
|
43
|
+
const routeState = useRouteState()
|
|
20
44
|
let pluginKeyOverride: string | undefined
|
|
21
45
|
let actionIdOverride: string | undefined
|
|
22
46
|
|
|
@@ -80,36 +104,66 @@ export const usePluginApi = (
|
|
|
80
104
|
}
|
|
81
105
|
$instanceApi.$i18n = useNamespacedI18n(pluginKeyOverride ?? pluginKey)
|
|
82
106
|
if (!pluginKeyOverride) {
|
|
107
|
+
const getSiblingWidgetStates = (compositionId: string = "byRoute") => {
|
|
108
|
+
const currentSlotType = instance.props?.slotType
|
|
109
|
+
let siblingWidgetIds = []
|
|
110
|
+
const activeCompositionPaths = []
|
|
111
|
+
|
|
112
|
+
if (compositionId === "byRoute") {
|
|
113
|
+
const { compositionSlots } = routeState
|
|
114
|
+
compositionSlots.value.forEach((slot) => {
|
|
115
|
+
if (currentSlotType) {
|
|
116
|
+
if (slot.slotName === currentSlotType) {
|
|
117
|
+
activeCompositionPaths.push(slot.slotValue)
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
activeCompositionPaths.push(slot.slotValue)
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
activeCompositionPaths?.forEach((path) => {
|
|
124
|
+
const composition = getCompositionByPath(path)
|
|
125
|
+
siblingWidgetIds = siblingWidgetIds.concat(
|
|
126
|
+
findWidgetUUIDs(composition),
|
|
127
|
+
)
|
|
128
|
+
})
|
|
129
|
+
} else {
|
|
130
|
+
// TODO implement widget retrieval from state via compositionId
|
|
131
|
+
console.log("not implemented yet")
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!siblingWidgetIds.length) {
|
|
135
|
+
console.error("There is no sibling widgets")
|
|
136
|
+
return {}
|
|
137
|
+
} else {
|
|
138
|
+
const getResult = () => {
|
|
139
|
+
const { state } = getState(["widgets", siblingWidgetIds])
|
|
140
|
+
return state
|
|
141
|
+
}
|
|
142
|
+
return getResult()
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const getWidgetId = () => {
|
|
146
|
+
return instance?.props?.widgetId || instance?.props?.uuid || ""
|
|
147
|
+
}
|
|
83
148
|
$instanceApi.$store = {
|
|
149
|
+
hasChanges: $store.hasChanges,
|
|
150
|
+
getSiblingWidgetStates,
|
|
84
151
|
/* Store getter */
|
|
85
|
-
getWidgetState: (widgetId: string =
|
|
152
|
+
getWidgetState: (widgetId: string = getWidgetId()) => {
|
|
86
153
|
if (!widgetId.length) {
|
|
87
154
|
console.error("No widgetId was provided")
|
|
88
155
|
return {}
|
|
89
156
|
} else {
|
|
90
|
-
let lastSubscriber$ = subscribers$["$store_getWidgetState"]
|
|
91
157
|
const getResult = () => {
|
|
92
|
-
const { state
|
|
93
|
-
if (lastSubscriber$) {
|
|
94
|
-
lastSubscriber$.unsubscribe()
|
|
95
|
-
}
|
|
96
|
-
lastSubscriber$ = observable$
|
|
97
|
-
subscribers$["$store_getWidgetState"] = lastSubscriber$
|
|
98
|
-
|
|
158
|
+
const { state } = getState(["widgets", widgetId])
|
|
99
159
|
return state
|
|
100
160
|
}
|
|
101
161
|
return getResult()
|
|
102
162
|
}
|
|
103
163
|
},
|
|
104
164
|
getUiState: () => {
|
|
105
|
-
let lastSubscriber$ = subscribers$["$store_getUiState"]
|
|
106
165
|
const getResult = () => {
|
|
107
|
-
const { state
|
|
108
|
-
if (lastSubscriber$) {
|
|
109
|
-
lastSubscriber$.unsubscribe()
|
|
110
|
-
}
|
|
111
|
-
lastSubscriber$ = observable$
|
|
112
|
-
subscribers$["$store_getUiState"] = lastSubscriber$
|
|
166
|
+
const { state } = getState(["ui"])
|
|
113
167
|
|
|
114
168
|
return state
|
|
115
169
|
}
|
|
@@ -117,14 +171,9 @@ export const usePluginApi = (
|
|
|
117
171
|
},
|
|
118
172
|
|
|
119
173
|
getQueryState: (actionId) => {
|
|
120
|
-
|
|
174
|
+
if (!actionId) return {}
|
|
121
175
|
const getResult = () => {
|
|
122
|
-
const { state
|
|
123
|
-
if (lastSubscriber$) {
|
|
124
|
-
lastSubscriber$.unsubscribe()
|
|
125
|
-
}
|
|
126
|
-
lastSubscriber$ = observable$
|
|
127
|
-
subscribers$["$store_store_getQueryStateget"] = lastSubscriber$
|
|
176
|
+
const { state } = getState(["queries", actionId])
|
|
128
177
|
|
|
129
178
|
return state
|
|
130
179
|
}
|
|
@@ -132,17 +181,13 @@ export const usePluginApi = (
|
|
|
132
181
|
},
|
|
133
182
|
|
|
134
183
|
getQueryData: (actionId) => {
|
|
184
|
+
if (!actionId) return {}
|
|
135
185
|
console.error("not implemented yet")
|
|
136
186
|
},
|
|
137
187
|
get: (pathArray, filter) => {
|
|
138
|
-
|
|
188
|
+
const cacheString = createStableHash({ pathArray, filter })
|
|
139
189
|
const getResult = () => {
|
|
140
|
-
const { state
|
|
141
|
-
if (lastSubscriber$) {
|
|
142
|
-
lastSubscriber$.unsubscribe()
|
|
143
|
-
}
|
|
144
|
-
lastSubscriber$ = observable$
|
|
145
|
-
subscribers$["$store_get"] = lastSubscriber$
|
|
190
|
+
const { state } = getState(pathArray, filter)
|
|
146
191
|
return state
|
|
147
192
|
}
|
|
148
193
|
return getResult()
|
|
@@ -153,20 +198,18 @@ export const usePluginApi = (
|
|
|
153
198
|
type: "ui/update",
|
|
154
199
|
payload,
|
|
155
200
|
}),
|
|
156
|
-
setWidgetState: (payload, widgetId =
|
|
157
|
-
const _widgetId =
|
|
158
|
-
widgetId.length > 0 ? widgetId : instance?.props?.uuid || false
|
|
159
|
-
|
|
201
|
+
setWidgetState: (payload, widgetId = getWidgetId()) => {
|
|
160
202
|
$store.dispatch({
|
|
161
203
|
type: "widgets/update",
|
|
162
|
-
uuid:
|
|
163
|
-
|
|
204
|
+
uuid: widgetId,
|
|
205
|
+
override: true,
|
|
206
|
+
payload,
|
|
164
207
|
})
|
|
165
208
|
},
|
|
166
209
|
|
|
167
210
|
updateWidgetState: (
|
|
168
211
|
payload: object,
|
|
169
|
-
widgetId: string =
|
|
212
|
+
widgetId: string = getWidgetId(),
|
|
170
213
|
) => {
|
|
171
214
|
if (!widgetId) return false
|
|
172
215
|
$store.dispatch({
|
|
@@ -175,10 +218,7 @@ export const usePluginApi = (
|
|
|
175
218
|
payload: payload,
|
|
176
219
|
})
|
|
177
220
|
},
|
|
178
|
-
updateConfig: (
|
|
179
|
-
payload: object,
|
|
180
|
-
widgetId: string = instance?.props?.uuid || "",
|
|
181
|
-
) => {
|
|
221
|
+
updateConfig: (payload: object, widgetId: string = getWidgetId()) => {
|
|
182
222
|
if (!widgetId) return false
|
|
183
223
|
$store.dispatch({
|
|
184
224
|
type: "widgets/update",
|
|
@@ -188,29 +228,45 @@ export const usePluginApi = (
|
|
|
188
228
|
},
|
|
189
229
|
})
|
|
190
230
|
},
|
|
191
|
-
updatePublic: (
|
|
231
|
+
updatePublic: (payload: object, widgetId: string = getWidgetId()) => {
|
|
232
|
+
if (!widgetId) return false
|
|
233
|
+
$store.dispatch({
|
|
234
|
+
type: "widgets/update",
|
|
235
|
+
uuid: widgetId,
|
|
236
|
+
payload: {
|
|
237
|
+
public: payload,
|
|
238
|
+
},
|
|
239
|
+
})
|
|
240
|
+
},
|
|
241
|
+
publishWorkingState: (
|
|
192
242
|
payload: object,
|
|
193
|
-
widgetId: string =
|
|
243
|
+
widgetId: string = getWidgetId(),
|
|
194
244
|
) => {
|
|
195
245
|
if (!widgetId) return false
|
|
196
246
|
$store.dispatch({
|
|
197
247
|
type: "widgets/update",
|
|
198
248
|
uuid: widgetId,
|
|
199
249
|
payload: {
|
|
200
|
-
|
|
250
|
+
workingState: payload,
|
|
201
251
|
},
|
|
202
252
|
})
|
|
203
253
|
},
|
|
254
|
+
updateDataItem: (
|
|
255
|
+
uuid: string,
|
|
256
|
+
payload: object,
|
|
257
|
+
override: boolean = false,
|
|
258
|
+
) => {
|
|
259
|
+
$store.dispatch({
|
|
260
|
+
type: "data/update",
|
|
261
|
+
docId: uuid,
|
|
262
|
+
override,
|
|
263
|
+
payload: payload,
|
|
264
|
+
})
|
|
265
|
+
},
|
|
204
266
|
}
|
|
205
267
|
}
|
|
206
268
|
const getUser = () => {
|
|
207
|
-
|
|
208
|
-
const { state, observable$ } = getState("user")
|
|
209
|
-
if (lastSubscriber$) {
|
|
210
|
-
lastSubscriber$.unsubscribe()
|
|
211
|
-
}
|
|
212
|
-
lastSubscriber$ = observable$
|
|
213
|
-
subscribers$["$user"] = lastSubscriber$
|
|
269
|
+
const { state } = getState("user")
|
|
214
270
|
return state
|
|
215
271
|
}
|
|
216
272
|
if (plugin.initEventbus) {
|
|
@@ -220,12 +276,6 @@ export const usePluginApi = (
|
|
|
220
276
|
// Retrieve the user for the api
|
|
221
277
|
$instanceApi.$user = getUser()
|
|
222
278
|
onUnmounted(() => {
|
|
223
|
-
if (subscribers$.length) {
|
|
224
|
-
subscribers$.forEach((subscriber) => {
|
|
225
|
-
subscriber.unsubscribe()
|
|
226
|
-
})
|
|
227
|
-
}
|
|
228
|
-
|
|
229
279
|
if ($instanceApi.$socket?.registeredListeners?.length) {
|
|
230
280
|
// Clean up socket events
|
|
231
281
|
$instanceApi.$socket.registeredListeners.forEach((listener) => {
|
|
@@ -84,7 +84,6 @@ export const useRouteState = () => {
|
|
|
84
84
|
const currentSlotParams =
|
|
85
85
|
compositionSlots.value.find((slot) => slot.slotName === targetSlotName)
|
|
86
86
|
?.slotParams ?? {}
|
|
87
|
-
|
|
88
87
|
// Merge current and requested parameters, then filter to only allowed ones
|
|
89
88
|
const allowedParams = interactionLink.queryParameters ?? []
|
|
90
89
|
const mergedParams = mergeDeepRight(currentSlotParams, requestedParams)
|
|
@@ -66,13 +66,13 @@ export const useVueWriteOperationHelper = (
|
|
|
66
66
|
subscriberCounter[instanceActionId] -= 1
|
|
67
67
|
if (subscriberCounter[instanceActionId] === 0) {
|
|
68
68
|
// Clean up the observable subject
|
|
69
|
-
if (subscriber$[instanceActionId]?.
|
|
70
|
-
subscriber$[instanceActionId].
|
|
69
|
+
if (subscriber$[instanceActionId]?.remove) {
|
|
70
|
+
subscriber$[instanceActionId].remove()
|
|
71
71
|
}
|
|
72
72
|
delete subscriber$[instanceActionId]
|
|
73
73
|
delete subscriberCounter[instanceActionId]
|
|
74
74
|
}
|
|
75
|
-
writeOperation.
|
|
75
|
+
writeOperation.remove()
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
const operationObject = {
|
|
@@ -85,6 +85,8 @@ export const useVueWriteOperationHelper = (
|
|
|
85
85
|
}),
|
|
86
86
|
response: responseRef,
|
|
87
87
|
execute: writeOperation.execute,
|
|
88
|
+
remove: writeOperation.remove,
|
|
89
|
+
clear: writeOperation.clear,
|
|
88
90
|
error: computed(() => {
|
|
89
91
|
return errorObservable.value
|
|
90
92
|
}),
|
|
@@ -19,7 +19,10 @@ const WIDGET_COMPONENT_FILES = import.meta.glob(
|
|
|
19
19
|
[
|
|
20
20
|
"@racletteCore/../../external-app-plugins/**/frontend/widgets/**/*Widget.vue",
|
|
21
21
|
],
|
|
22
|
-
{
|
|
22
|
+
{
|
|
23
|
+
eager: false,
|
|
24
|
+
as: "url",
|
|
25
|
+
},
|
|
23
26
|
)
|
|
24
27
|
|
|
25
28
|
// Discover widget setup files for metadata
|
|
@@ -10,7 +10,7 @@ export default () => {
|
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
if (checkTokenNotifications.length) {
|
|
13
|
-
$eventbus.emit("
|
|
13
|
+
$eventbus.emit("ui/addToSnackbar", checkTokenNotifications[0].message)
|
|
14
14
|
$store.dispatch({
|
|
15
15
|
type: "notifications/markAllAsRead",
|
|
16
16
|
})
|
|
@@ -2,7 +2,7 @@ import { $eventbus } from "@racletteCore/main"
|
|
|
2
2
|
|
|
3
3
|
const copyToClipboard = (name: string, value: string) => {
|
|
4
4
|
navigator.clipboard.writeText(value)
|
|
5
|
-
$eventbus.emit("
|
|
5
|
+
$eventbus.emit("ui/addToSnackbar", {
|
|
6
6
|
i18n: "core.copiedToClipboard$name",
|
|
7
7
|
content: { name },
|
|
8
8
|
color: "info",
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { compose, type ComposedRouteState } from "./routeParser"
|
|
2
2
|
import { $store } from "@racletteCore"
|
|
3
3
|
|
|
4
|
+
export type WidgetLayoutType = "default" | "spaced" | "card" | "border" | "full"
|
|
5
|
+
|
|
4
6
|
export interface CompositionSlot {
|
|
5
7
|
slotName: string
|
|
6
8
|
slotValue: string
|
|
7
9
|
slotParams?: Record<string, string>
|
|
10
|
+
slotLayout?: WidgetLayoutType
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
// TODO: transform this to an array
|
|
11
14
|
export const DEFAULT_SLOT_NAME = "page"
|
|
12
15
|
export const DEFAULT_MODAL_SLOT_NAME = "modal"
|
|
16
|
+
export const DEFAULT_INLINE_SLOT_NAME = "inline"
|
|
13
17
|
|
|
14
18
|
export const parseRouteToCompositionSlots = (
|
|
15
19
|
route: string,
|
|
@@ -17,7 +21,6 @@ export const parseRouteToCompositionSlots = (
|
|
|
17
21
|
addDefaultSlotIfMissing = false,
|
|
18
22
|
) => {
|
|
19
23
|
const composed = compose(route)
|
|
20
|
-
|
|
21
24
|
return parseComposedToCompositionSlots(
|
|
22
25
|
composed,
|
|
23
26
|
defaultSlotName,
|
|
@@ -3,8 +3,8 @@ import type { RouteLocationNormalized } from "vue-router"
|
|
|
3
3
|
import {
|
|
4
4
|
DEFAULT_SLOT_NAME,
|
|
5
5
|
parseRouteToCompositionSlots,
|
|
6
|
+
type CompositionSlot,
|
|
6
7
|
} from "@racletteOrchestrator/router/routeParserHelper"
|
|
7
|
-
import { difference } from "ramda"
|
|
8
8
|
import { getCompositionIdByPath } from "@racletteCore/store/reducers/compositions/selectors"
|
|
9
9
|
|
|
10
10
|
// TODO: find better filename
|
|
@@ -46,6 +46,59 @@ export const dispatchSetCompositionAs = (
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Compares two arrays of composition slots and returns the differences
|
|
51
|
+
* Returns an object with three arrays: toRemove, toAdd, toUpdate
|
|
52
|
+
*/
|
|
53
|
+
const getCompositionSlotChanges = (
|
|
54
|
+
oldSlots: CompositionSlot[],
|
|
55
|
+
newSlots: CompositionSlot[],
|
|
56
|
+
) => {
|
|
57
|
+
// Helper: Create a comparison key for slots (ignoring slotParams)
|
|
58
|
+
const getSlotKey = (slot: CompositionSlot) =>
|
|
59
|
+
`${slot.slotName}:${slot.slotValue}`
|
|
60
|
+
|
|
61
|
+
// Helper: Check if slotParams are different
|
|
62
|
+
const hasDifferentSlotParams = (
|
|
63
|
+
slotA: CompositionSlot,
|
|
64
|
+
slotB: CompositionSlot,
|
|
65
|
+
) => {
|
|
66
|
+
const paramsA = slotA.slotParams || {}
|
|
67
|
+
const paramsB = slotB.slotParams || {}
|
|
68
|
+
return JSON.stringify(paramsA) !== JSON.stringify(paramsB)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const oldSlotMap = new Map(oldSlots.map((slot) => [getSlotKey(slot), slot]))
|
|
72
|
+
const newSlotMap = new Map(newSlots.map((slot) => [getSlotKey(slot), slot]))
|
|
73
|
+
|
|
74
|
+
const toRemove: CompositionSlot[] = []
|
|
75
|
+
const toAdd: CompositionSlot[] = []
|
|
76
|
+
const toUpdate: CompositionSlot[] = []
|
|
77
|
+
|
|
78
|
+
// Find slots to remove (exist in old but not in new)
|
|
79
|
+
for (const [key, oldSlot] of oldSlotMap) {
|
|
80
|
+
if (!newSlotMap.has(key)) {
|
|
81
|
+
toRemove.push(oldSlot)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Find slots to add or update (exist in new)
|
|
86
|
+
for (const [key, newSlot] of newSlotMap) {
|
|
87
|
+
if (!oldSlotMap.has(key)) {
|
|
88
|
+
// Completely new slot
|
|
89
|
+
toAdd.push(newSlot)
|
|
90
|
+
} else {
|
|
91
|
+
// Slot exists in both, check if slotParams changed
|
|
92
|
+
const oldSlot = oldSlotMap.get(key)!
|
|
93
|
+
if (hasDifferentSlotParams(oldSlot, newSlot)) {
|
|
94
|
+
toUpdate.push(newSlot)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { toRemove, toAdd, toUpdate }
|
|
100
|
+
}
|
|
101
|
+
|
|
49
102
|
export const updateActiveCompositions = (
|
|
50
103
|
to: RouteLocationNormalized,
|
|
51
104
|
from: RouteLocationNormalized,
|
|
@@ -54,7 +107,6 @@ export const updateActiveCompositions = (
|
|
|
54
107
|
const hasToPageIdParameter = Boolean(to.params.pageId?.length)
|
|
55
108
|
const hasFromPageIdParameter = Boolean(from.params.pageId?.length)
|
|
56
109
|
|
|
57
|
-
// TODO: write helper method to combine compose & parseRouteToCompositionSlots
|
|
58
110
|
const compositionSlots = parseRouteToCompositionSlots(
|
|
59
111
|
to.fullPath,
|
|
60
112
|
undefined,
|
|
@@ -67,21 +119,36 @@ export const updateActiveCompositions = (
|
|
|
67
119
|
!isInitialRouting && !hasFromPageIdParameter,
|
|
68
120
|
)
|
|
69
121
|
|
|
70
|
-
const
|
|
122
|
+
const { toRemove, toAdd, toUpdate } = getCompositionSlotChanges(
|
|
71
123
|
beforeCompositionSlots,
|
|
72
124
|
compositionSlots,
|
|
73
125
|
)
|
|
74
|
-
const compositionSlotsToAdd = difference(
|
|
75
|
-
compositionSlots,
|
|
76
|
-
beforeCompositionSlots,
|
|
77
|
-
)
|
|
78
126
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
127
|
+
// Remove slots that are no longer needed
|
|
128
|
+
toRemove.forEach((slot) => dispatchSetCompositionAs(slot.slotName))
|
|
129
|
+
|
|
130
|
+
// Add completely new slots
|
|
131
|
+
toAdd.forEach((slot) =>
|
|
83
132
|
dispatchSetCompositionAs(slot.slotName, slot.slotValue, slot.slotParams),
|
|
84
133
|
)
|
|
134
|
+
|
|
135
|
+
// Update existing slots with new slotParams (without removing/adding)
|
|
136
|
+
toUpdate.forEach((slot) => {
|
|
137
|
+
const compositionId = getCompositionIdByPath(slot.slotValue)
|
|
138
|
+
if (
|
|
139
|
+
compositionId &&
|
|
140
|
+
slot.slotParams &&
|
|
141
|
+
Object.keys(slot.slotParams).length
|
|
142
|
+
) {
|
|
143
|
+
$store.dispatch({
|
|
144
|
+
type: "compositions/update",
|
|
145
|
+
payload: {
|
|
146
|
+
compositionId,
|
|
147
|
+
compositionParams: slot.slotParams,
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
})
|
|
85
152
|
}
|
|
86
153
|
|
|
87
154
|
export const handleRouteChange = (
|
|
@@ -596,6 +596,11 @@
|
|
|
596
596
|
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
|
|
597
597
|
integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==
|
|
598
598
|
|
|
599
|
+
"@sinclair/typebox@0.34.41":
|
|
600
|
+
version "0.34.41"
|
|
601
|
+
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.41.tgz#aa51a6c1946df2c5a11494a2cdb9318e026db16c"
|
|
602
|
+
integrity sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==
|
|
603
|
+
|
|
599
604
|
"@socket.io/component-emitter@~3.1.0":
|
|
600
605
|
version "3.1.2"
|
|
601
606
|
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2"
|
package/yarn.lock
CHANGED
|
@@ -295,10 +295,10 @@
|
|
|
295
295
|
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b"
|
|
296
296
|
integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==
|
|
297
297
|
|
|
298
|
-
"@raclettejs/types
|
|
299
|
-
version "0.1.
|
|
300
|
-
resolved "https://registry.yarnpkg.com/@raclettejs/types/-/types-0.1.
|
|
301
|
-
integrity sha512-
|
|
298
|
+
"@raclettejs/types@^0.1.13":
|
|
299
|
+
version "0.1.13"
|
|
300
|
+
resolved "https://registry.yarnpkg.com/@raclettejs/types/-/types-0.1.13.tgz#16fbe78f3e9d6e1ea4ae3c5e1537ba5f7335f9a6"
|
|
301
|
+
integrity sha512-AbYVlo0AI+hqgIxEY6rb5UYq8tX+yQvr/yeOvT0rhgITgXGXwUoaJXIKXAVtoSrHkX9zBeCWaTSq5iroCTXBwg==
|
|
302
302
|
dependencies:
|
|
303
303
|
"@types/node" "24.5.2"
|
|
304
304
|
fastify "5.6.0"
|