@raclettejs/core 0.1.11 → 0.1.12
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 +46 -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 +39 -41
- 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 +125 -26
- 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,44 @@ 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
40
|
const subscribers$ = {}
|
|
41
|
+
|
|
18
42
|
const instance = getCurrentInstance()
|
|
19
43
|
const getState = useVueStateObservableHelper()
|
|
44
|
+
|
|
45
|
+
const routeState = useRouteState()
|
|
20
46
|
let pluginKeyOverride: string | undefined
|
|
21
47
|
let actionIdOverride: string | undefined
|
|
22
48
|
|
|
@@ -80,21 +106,74 @@ export const usePluginApi = (
|
|
|
80
106
|
}
|
|
81
107
|
$instanceApi.$i18n = useNamespacedI18n(pluginKeyOverride ?? pluginKey)
|
|
82
108
|
if (!pluginKeyOverride) {
|
|
109
|
+
const getSiblingWidgetStates = (compositionId: string = "byRoute") => {
|
|
110
|
+
const currentSlotType = instance.props?.slotType
|
|
111
|
+
let siblingWidgetIds = []
|
|
112
|
+
const activeCompositionPaths = []
|
|
113
|
+
|
|
114
|
+
if (compositionId === "byRoute") {
|
|
115
|
+
const { compositionSlots } = routeState
|
|
116
|
+
compositionSlots.value.forEach((slot) => {
|
|
117
|
+
if (currentSlotType) {
|
|
118
|
+
if (slot.slotName === currentSlotType) {
|
|
119
|
+
activeCompositionPaths.push(slot.slotValue)
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
activeCompositionPaths.push(slot.slotValue)
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
activeCompositionPaths?.forEach((path) => {
|
|
126
|
+
const composition = getCompositionByPath(path)
|
|
127
|
+
siblingWidgetIds = siblingWidgetIds.concat(
|
|
128
|
+
findWidgetUUIDs(composition),
|
|
129
|
+
)
|
|
130
|
+
})
|
|
131
|
+
} else {
|
|
132
|
+
// TODO implement widget retrieval from state via compositionId
|
|
133
|
+
console.log("not implemented yet")
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!siblingWidgetIds.length) {
|
|
137
|
+
console.error("There is no sibling widgets")
|
|
138
|
+
return {}
|
|
139
|
+
} else {
|
|
140
|
+
let lastSubscriber$ =
|
|
141
|
+
subscribers$["$store_getSiblingWidgetStates_" + compositionId]
|
|
142
|
+
const getResult = () => {
|
|
143
|
+
const { state, observable$ } = getState(["widgets", siblingWidgetIds])
|
|
144
|
+
if (lastSubscriber$) {
|
|
145
|
+
lastSubscriber$.unsubscribe()
|
|
146
|
+
}
|
|
147
|
+
lastSubscriber$ = observable$
|
|
148
|
+
subscribers$["$store_getSiblingWidgetStates_" + compositionId] =
|
|
149
|
+
lastSubscriber$
|
|
150
|
+
|
|
151
|
+
return state
|
|
152
|
+
}
|
|
153
|
+
return getResult()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const getWidgetId = () => {
|
|
157
|
+
return instance?.props?.widgetId || instance?.props?.uuid || ""
|
|
158
|
+
}
|
|
83
159
|
$instanceApi.$store = {
|
|
160
|
+
hasChanges: $store.hasChanges,
|
|
161
|
+
getSiblingWidgetStates,
|
|
84
162
|
/* Store getter */
|
|
85
|
-
getWidgetState: (widgetId: string =
|
|
163
|
+
getWidgetState: (widgetId: string = getWidgetId()) => {
|
|
86
164
|
if (!widgetId.length) {
|
|
87
165
|
console.error("No widgetId was provided")
|
|
88
166
|
return {}
|
|
89
167
|
} else {
|
|
90
|
-
let lastSubscriber$ =
|
|
168
|
+
let lastSubscriber$ =
|
|
169
|
+
subscribers$["$store_getWidgetState_" + widgetId]
|
|
91
170
|
const getResult = () => {
|
|
92
171
|
const { state, observable$ } = getState(["widgets", widgetId])
|
|
93
172
|
if (lastSubscriber$) {
|
|
94
173
|
lastSubscriber$.unsubscribe()
|
|
95
174
|
}
|
|
96
175
|
lastSubscriber$ = observable$
|
|
97
|
-
subscribers$["$
|
|
176
|
+
subscribers$["$store_getWidgetState_" + widgetId] = lastSubscriber$
|
|
98
177
|
|
|
99
178
|
return state
|
|
100
179
|
}
|
|
@@ -117,14 +196,15 @@ export const usePluginApi = (
|
|
|
117
196
|
},
|
|
118
197
|
|
|
119
198
|
getQueryState: (actionId) => {
|
|
120
|
-
|
|
199
|
+
if (!actionId) return {}
|
|
200
|
+
let lastSubscriber$ = subscribers$["$store_getQueryState_" + actionId]
|
|
121
201
|
const getResult = () => {
|
|
122
202
|
const { state, observable$ } = getState(["queries", actionId])
|
|
123
203
|
if (lastSubscriber$) {
|
|
124
204
|
lastSubscriber$.unsubscribe()
|
|
125
205
|
}
|
|
126
206
|
lastSubscriber$ = observable$
|
|
127
|
-
subscribers$["$
|
|
207
|
+
subscribers$["$store_getQueryState_" + actionId] = lastSubscriber$
|
|
128
208
|
|
|
129
209
|
return state
|
|
130
210
|
}
|
|
@@ -132,17 +212,19 @@ export const usePluginApi = (
|
|
|
132
212
|
},
|
|
133
213
|
|
|
134
214
|
getQueryData: (actionId) => {
|
|
215
|
+
if (!actionId) return {}
|
|
135
216
|
console.error("not implemented yet")
|
|
136
217
|
},
|
|
137
218
|
get: (pathArray, filter) => {
|
|
138
|
-
|
|
219
|
+
const cacheString = createStableHash({ pathArray, filter })
|
|
220
|
+
let lastSubscriber$ = subscribers$["$store_get_" + cacheString]
|
|
139
221
|
const getResult = () => {
|
|
140
222
|
const { state, observable$ } = getState(pathArray, filter)
|
|
141
223
|
if (lastSubscriber$) {
|
|
142
224
|
lastSubscriber$.unsubscribe()
|
|
143
225
|
}
|
|
144
226
|
lastSubscriber$ = observable$
|
|
145
|
-
subscribers$["$
|
|
227
|
+
subscribers$["$store_get_" + cacheString] = lastSubscriber$
|
|
146
228
|
return state
|
|
147
229
|
}
|
|
148
230
|
return getResult()
|
|
@@ -153,20 +235,18 @@ export const usePluginApi = (
|
|
|
153
235
|
type: "ui/update",
|
|
154
236
|
payload,
|
|
155
237
|
}),
|
|
156
|
-
setWidgetState: (payload, widgetId =
|
|
157
|
-
const _widgetId =
|
|
158
|
-
widgetId.length > 0 ? widgetId : instance?.props?.uuid || false
|
|
159
|
-
|
|
238
|
+
setWidgetState: (payload, widgetId = getWidgetId()) => {
|
|
160
239
|
$store.dispatch({
|
|
161
240
|
type: "widgets/update",
|
|
162
|
-
uuid:
|
|
163
|
-
|
|
241
|
+
uuid: widgetId,
|
|
242
|
+
override: true,
|
|
243
|
+
payload,
|
|
164
244
|
})
|
|
165
245
|
},
|
|
166
246
|
|
|
167
247
|
updateWidgetState: (
|
|
168
248
|
payload: object,
|
|
169
|
-
widgetId: string =
|
|
249
|
+
widgetId: string = getWidgetId(),
|
|
170
250
|
) => {
|
|
171
251
|
if (!widgetId) return false
|
|
172
252
|
$store.dispatch({
|
|
@@ -175,10 +255,7 @@ export const usePluginApi = (
|
|
|
175
255
|
payload: payload,
|
|
176
256
|
})
|
|
177
257
|
},
|
|
178
|
-
updateConfig: (
|
|
179
|
-
payload: object,
|
|
180
|
-
widgetId: string = instance?.props?.uuid || "",
|
|
181
|
-
) => {
|
|
258
|
+
updateConfig: (payload: object, widgetId: string = getWidgetId()) => {
|
|
182
259
|
if (!widgetId) return false
|
|
183
260
|
$store.dispatch({
|
|
184
261
|
type: "widgets/update",
|
|
@@ -188,19 +265,41 @@ export const usePluginApi = (
|
|
|
188
265
|
},
|
|
189
266
|
})
|
|
190
267
|
},
|
|
191
|
-
updatePublic: (
|
|
268
|
+
updatePublic: (payload: object, widgetId: string = getWidgetId()) => {
|
|
269
|
+
if (!widgetId) return false
|
|
270
|
+
$store.dispatch({
|
|
271
|
+
type: "widgets/update",
|
|
272
|
+
uuid: widgetId,
|
|
273
|
+
payload: {
|
|
274
|
+
public: payload,
|
|
275
|
+
},
|
|
276
|
+
})
|
|
277
|
+
},
|
|
278
|
+
publishWorkingState: (
|
|
192
279
|
payload: object,
|
|
193
|
-
widgetId: string =
|
|
280
|
+
widgetId: string = getWidgetId(),
|
|
194
281
|
) => {
|
|
195
282
|
if (!widgetId) return false
|
|
196
283
|
$store.dispatch({
|
|
197
284
|
type: "widgets/update",
|
|
198
285
|
uuid: widgetId,
|
|
199
286
|
payload: {
|
|
200
|
-
|
|
287
|
+
workingState: payload,
|
|
201
288
|
},
|
|
202
289
|
})
|
|
203
290
|
},
|
|
291
|
+
updateDataItem: (
|
|
292
|
+
uuid: string,
|
|
293
|
+
payload: object,
|
|
294
|
+
override: boolean = false,
|
|
295
|
+
) => {
|
|
296
|
+
$store.dispatch({
|
|
297
|
+
type: "data/update",
|
|
298
|
+
docId: uuid,
|
|
299
|
+
override,
|
|
300
|
+
payload: payload,
|
|
301
|
+
})
|
|
302
|
+
},
|
|
204
303
|
}
|
|
205
304
|
}
|
|
206
305
|
const getUser = () => {
|
|
@@ -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.12":
|
|
299
|
+
version "0.1.12"
|
|
300
|
+
resolved "https://registry.yarnpkg.com/@raclettejs/types/-/types-0.1.12.tgz#5b8ddf2ff70333494abf96be2a3af118b3ca8afc"
|
|
301
|
+
integrity sha512-hN+mfnv23JMPDwcHodDoVGnM4tVsMyfS5BcUL/vxohYROp2xfBpIFnN7k9WbFbhLeGJhUackjRN/2EfWQi76eQ==
|
|
302
302
|
dependencies:
|
|
303
303
|
"@types/node" "24.5.2"
|
|
304
304
|
fastify "5.6.0"
|