@raclettejs/core 0.1.37 → 0.1.39
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 +22 -9
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/services/backend/package.json +1 -1
- package/services/frontend/src/core/lib/scheduleTask.ts +35 -0
- package/services/frontend/src/core/store/index.ts +5 -1
- package/services/frontend/src/core/store/reducers/compositionSlots/reducers.ts +1 -5
- package/services/frontend/src/core/store/reducers/data/reducers.ts +101 -65
- package/services/frontend/src/core/store/reducers/metaReducer.ts +23 -0
- package/services/frontend/src/core/store/reducers/notifications/reducers.ts +39 -47
- package/services/frontend/src/core/store/reducers/queries/effects.ts +55 -2
- package/services/frontend/src/core/store/reducers/queries/reducers.ts +60 -62
- package/services/frontend/src/core/store/reducers/queriesCache/effects.ts +105 -0
- package/services/frontend/src/core/store/reducers/queriesCache/index.ts +2 -1
- package/services/frontend/src/core/store/reducers/queriesCache/queryCacheHelper.ts +79 -9
- package/services/frontend/src/core/store/reducers/queriesCache/reducers.ts +95 -100
- package/services/frontend/src/orchestrator/components/CompositionLoadingState.vue +28 -0
- package/services/frontend/src/orchestrator/components/composition/CompositionOverlay.vue +5 -7
- package/services/frontend/src/orchestrator/components/composition/WidgetsLayoutLoader.vue +171 -39
- package/services/frontend/src/orchestrator/components/dataTable/BaseDataTable.vue +311 -54
- package/services/frontend/src/orchestrator/components/dataTable/BaseDataTableConfirmDeleteBtn.vue +27 -0
- package/services/frontend/src/orchestrator/components/dataTable/BaseDataTableFilterDrawerShell.vue +72 -0
- package/services/frontend/src/orchestrator/components/index.ts +4 -0
- package/services/frontend/src/orchestrator/composables/index.ts +1 -0
- package/services/frontend/src/orchestrator/composables/useBaseDataTableDeleteConfirm.ts +23 -0
- package/services/frontend/src/orchestrator/composables/useWidgetLifecycle.ts +53 -23
- package/services/frontend/src/orchestrator/constants/widgetSlotType.ts +4 -0
- package/services/frontend/src/orchestrator/i18n/de-DE.json +7 -1
- package/services/frontend/src/orchestrator/i18n/en-EU.json +7 -1
- package/services/frontend/src/orchestrator/i18n/sk.json +7 -1
- package/services/frontend/src/orchestrator/router/routerHooks/afterEach.ts +15 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raclettejs/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"description": "racletteJS core package",
|
|
5
5
|
"repository": "https://gitlab.com/raclettejs/core",
|
|
6
6
|
"author": "Pacifico Digital Explorations GmbH <info@raclettejs.com>",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@emnapi/core": "1.9.2",
|
|
84
84
|
"@emnapi/runtime": "1.9.2",
|
|
85
85
|
"@eslint/js": "9.35.0",
|
|
86
|
-
"@raclettejs/types": "0.1.
|
|
86
|
+
"@raclettejs/types": "0.1.39",
|
|
87
87
|
"@types/fs-extra": "11.0.4",
|
|
88
88
|
"@types/js-yaml": "4.0.9",
|
|
89
89
|
"@types/node": "25.5.0",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"build": "tsc --project tsconfig.build.json || true",
|
|
14
14
|
"postbuild": "yarn run build:alias && yarn run build:assets",
|
|
15
15
|
"build:alias": "tsc-alias -p tsconfig.build.json",
|
|
16
|
-
"build:assets:src": "copyfiles -u 1 'src/**/*.{json,js,yml,yaml,env*}' dist",
|
|
16
|
+
"build:assets:src": "copyfiles -u 1 'src/**/*.{init,json,js,yml,yaml,env*}' dist",
|
|
17
17
|
"build:assets:root": "copyfiles -u 0 'raclette.config.js' dist",
|
|
18
18
|
"build:assets": "npm run build:assets:src && npm run build:assets:root",
|
|
19
19
|
"lint": "eslint .",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type IdleDeadline = {
|
|
2
|
+
didTimeout: boolean
|
|
3
|
+
timeRemaining: () => number
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Run work after the next paint so timer handlers stay lightweight.
|
|
8
|
+
*/
|
|
9
|
+
export function scheduleAfterPaint(callback: () => void): void {
|
|
10
|
+
if (typeof requestAnimationFrame === "function") {
|
|
11
|
+
requestAnimationFrame(() => {
|
|
12
|
+
requestAnimationFrame(callback)
|
|
13
|
+
})
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setTimeout(callback, 0)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Run non-urgent work during idle time (falls back to a macrotask).
|
|
22
|
+
*/
|
|
23
|
+
export function scheduleIdleWork(
|
|
24
|
+
callback: () => void,
|
|
25
|
+
options?: { timeout?: number },
|
|
26
|
+
): void {
|
|
27
|
+
const timeout = options?.timeout ?? 2000
|
|
28
|
+
|
|
29
|
+
if (typeof requestIdleCallback === "function") {
|
|
30
|
+
requestIdleCallback((_deadline: IdleDeadline) => callback(), { timeout })
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setTimeout(callback, 0)
|
|
35
|
+
}
|
|
@@ -41,7 +41,10 @@ import {
|
|
|
41
41
|
} from "./reducers/compositions"
|
|
42
42
|
import backendReducers from "./reducers/backend"
|
|
43
43
|
import { queriesEffects, queriesReducers } from "./reducers/queries"
|
|
44
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
queriesCacheEffects,
|
|
46
|
+
queriesCacheReducers,
|
|
47
|
+
} from "./reducers/queriesCache"
|
|
45
48
|
import log from "@racletteCore/lib/logger"
|
|
46
49
|
import type { RacletteStore, StoreHelperGetState } from "@racletteCore"
|
|
47
50
|
|
|
@@ -179,6 +182,7 @@ const registerStoreEffects = (store) => {
|
|
|
179
182
|
compositionsEffects(store).forEach((effect) => effects.push(effect))
|
|
180
183
|
interactionLinksEffects(store).forEach((effect) => effects.push(effect))
|
|
181
184
|
queriesEffects(store).forEach((effect) => effects.push(effect))
|
|
185
|
+
queriesCacheEffects(store).forEach((effect) => effects.push(effect))
|
|
182
186
|
|
|
183
187
|
effects.forEach((effect) => store.effect(effect))
|
|
184
188
|
}
|
|
@@ -30,10 +30,6 @@ const compositionsSet = (state, action) => {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/* update page */
|
|
33
|
-
const compositionsUpdate = (state, action) =>
|
|
34
|
-
console.warn("Implement: compositionsUpdate()")
|
|
35
|
-
|
|
36
|
-
return state
|
|
37
|
-
}
|
|
33
|
+
const compositionsUpdate = (state, action) => state
|
|
38
34
|
|
|
39
35
|
export { addCompositionSlot, compositionsUpdate, projectInit, compositionsSet }
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
handleParentChildCountChange,
|
|
9
9
|
handleDataIdPrefixing,
|
|
10
10
|
} from "@racletteCore/lib/dataHelper"
|
|
11
|
-
import { mergeDeepRight, clone, difference } from "ramda"
|
|
11
|
+
import { mergeDeepRight, clone, difference, equals } from "ramda"
|
|
12
12
|
import { v4 as uuidv4 } from "uuid"
|
|
13
13
|
import * as dbItems from "./dbItems/index"
|
|
14
14
|
|
|
15
15
|
const addDataToDataStore = (state, action, remote = false) => {
|
|
16
16
|
const { result, actionIdentifier } = action.payload
|
|
17
17
|
const { actionId, cacheKey } = actionIdentifier
|
|
18
|
-
const newState =
|
|
18
|
+
const newState = { ...state }
|
|
19
19
|
|
|
20
20
|
result.forEach((_item) => {
|
|
21
21
|
const item = structuredClone(_item)
|
|
@@ -28,20 +28,25 @@ const addDataToDataStore = (state, action, remote = false) => {
|
|
|
28
28
|
)
|
|
29
29
|
if (!state[item._id] || remote) {
|
|
30
30
|
// if the item is completely new to the cache, or from a remote query we'll just add it
|
|
31
|
-
|
|
31
|
+
newState[item._id] = item
|
|
32
|
+
return
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
const existing = state[item._id]
|
|
35
|
+
if (!item._updatedAt && !existing._updatedAt) {
|
|
36
|
+
newState[item._id] = item
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
if (
|
|
40
|
+
item._updatedAt &&
|
|
41
|
+
existing._updatedAt &&
|
|
42
|
+
new Date(item._updatedAt) > new Date(existing._updatedAt)
|
|
43
|
+
) {
|
|
44
|
+
newState[item._id] = item
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
newState[item._id] = {
|
|
48
|
+
...existing,
|
|
49
|
+
__requestedFor: item.__requestedFor,
|
|
45
50
|
}
|
|
46
51
|
})
|
|
47
52
|
|
|
@@ -59,11 +64,7 @@ const addDataToDataStore = (state, action, remote = false) => {
|
|
|
59
64
|
*/
|
|
60
65
|
const applyItemTemplate = (item, type) => {
|
|
61
66
|
// TODO add dynamic plugin datatype schema retrieval here
|
|
62
|
-
|
|
63
|
-
if (!itemTemplate) {
|
|
64
|
-
console.warn(`no dbItem template for ${type} found`)
|
|
65
|
-
}
|
|
66
|
-
itemTemplate = dbItems.defaultItem(type, item)
|
|
67
|
+
const itemTemplate = dbItems.defaultItem(type, item)
|
|
67
68
|
|
|
68
69
|
return itemTemplate
|
|
69
70
|
}
|
|
@@ -118,26 +119,23 @@ const handleRequestActionIdRegistry = (
|
|
|
118
119
|
* we currently have in our dataStore.
|
|
119
120
|
* */
|
|
120
121
|
const updateDataCache = (oldCache, newItems) => {
|
|
121
|
-
const newCache =
|
|
122
|
+
const newCache = { ...oldCache }
|
|
122
123
|
|
|
123
124
|
newItems.forEach((item) => {
|
|
124
125
|
const oldItem = oldCache[item._id]
|
|
125
126
|
|
|
126
127
|
// Tickets will just get updated if they have already been in the data Store due to a query
|
|
127
|
-
if (oldItem) {
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
// apply the requestAction registry handler
|
|
131
|
-
if (newCache[item._id]) {
|
|
132
|
-
newCache[item._id].__requestedFor = handleRequestActionIdRegistry(
|
|
133
|
-
newCache[item._id],
|
|
134
|
-
oldItem,
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
// we will always delete the offline flag as this function will only be called by the dataRead which retrieves synced backend items
|
|
138
|
-
if (newCache[item._id]) {
|
|
139
|
-
delete newCache[item._id]._offline
|
|
128
|
+
if (!oldItem) {
|
|
129
|
+
return
|
|
140
130
|
}
|
|
131
|
+
|
|
132
|
+
const updatedItem = { ...item }
|
|
133
|
+
updatedItem.__requestedFor = handleRequestActionIdRegistry(
|
|
134
|
+
updatedItem,
|
|
135
|
+
oldItem,
|
|
136
|
+
)
|
|
137
|
+
delete updatedItem._offline
|
|
138
|
+
newCache[item._id] = updatedItem
|
|
141
139
|
})
|
|
142
140
|
|
|
143
141
|
return newCache
|
|
@@ -197,8 +195,6 @@ const dataRead = (state, action) => {
|
|
|
197
195
|
return state
|
|
198
196
|
}
|
|
199
197
|
if (!Array.isArray(payload)) {
|
|
200
|
-
console.error("data push needs to be an array!")
|
|
201
|
-
|
|
202
198
|
return state
|
|
203
199
|
}
|
|
204
200
|
|
|
@@ -324,10 +320,7 @@ const dataUpdate = (state, action) => {
|
|
|
324
320
|
} else {
|
|
325
321
|
item._source = mergeDeepRight(item._source, payload)
|
|
326
322
|
}
|
|
327
|
-
if (
|
|
328
|
-
payload.tags &&
|
|
329
|
-
clone(payload.tags) !== clone(oldItem._source.tags || [])
|
|
330
|
-
) {
|
|
323
|
+
if (payload.tags && !equals(payload.tags, oldItem._source.tags || [])) {
|
|
331
324
|
// we have a change in tags, so let's find out what happened and change the childCount values for the tags accordingly
|
|
332
325
|
const tagsAdded = difference(payload.tags, oldItem._source.tags || [])
|
|
333
326
|
const tagsRemoved = difference(oldItem._source.tags || [], payload.tags)
|
|
@@ -438,33 +431,76 @@ const dataDelete = (state, action) => {
|
|
|
438
431
|
* @param {String} action.actionId - The Id of the query which requested the items
|
|
439
432
|
* @returns {Object} - Returns the new state after removing the data from the cache.
|
|
440
433
|
*/
|
|
434
|
+
const removeRequestedForFromItem = (dataItems, uuid, actionId) => {
|
|
435
|
+
if (!dataItems[uuid]) {
|
|
436
|
+
return
|
|
437
|
+
}
|
|
438
|
+
if (!dataItems[uuid].__requestedFor) {
|
|
439
|
+
delete dataItems[uuid]
|
|
440
|
+
return
|
|
441
|
+
}
|
|
442
|
+
if (dataItems[uuid].__requestedFor[actionId]) {
|
|
443
|
+
delete dataItems[uuid].__requestedFor[actionId]
|
|
444
|
+
}
|
|
445
|
+
if (!Object.keys(dataItems[uuid].__requestedFor).length) {
|
|
446
|
+
delete dataItems[uuid]
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
441
450
|
const deleteFromCache = (state, action) => {
|
|
442
451
|
const { payload, actionId } = action
|
|
443
|
-
const dataItems = clone(state)
|
|
444
452
|
|
|
445
|
-
if (actionId) {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
})
|
|
453
|
+
if (!actionId) {
|
|
454
|
+
return state
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const uuids = payload?.uuids?.length ? payload.uuids : null
|
|
458
|
+
|
|
459
|
+
if (uuids) {
|
|
460
|
+
const needsUpdate = uuids.some((uuid) => {
|
|
461
|
+
const item = state[uuid]
|
|
462
|
+
if (!item) {
|
|
463
|
+
return false
|
|
464
|
+
}
|
|
465
|
+
if (!item.__requestedFor) {
|
|
466
|
+
return true
|
|
467
|
+
}
|
|
468
|
+
return Boolean(item.__requestedFor[actionId])
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
if (!needsUpdate) {
|
|
472
|
+
return state
|
|
467
473
|
}
|
|
474
|
+
|
|
475
|
+
const dataItems = { ...state }
|
|
476
|
+
uuids.forEach((uuid) => {
|
|
477
|
+
if (!dataItems[uuid]) {
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
if (!dataItems[uuid].__requestedFor) {
|
|
481
|
+
delete dataItems[uuid]
|
|
482
|
+
return
|
|
483
|
+
}
|
|
484
|
+
if (!dataItems[uuid].__requestedFor[actionId]) {
|
|
485
|
+
return
|
|
486
|
+
}
|
|
487
|
+
const updatedItem = clone(dataItems[uuid])
|
|
488
|
+
delete updatedItem.__requestedFor[actionId]
|
|
489
|
+
if (!Object.keys(updatedItem.__requestedFor).length) {
|
|
490
|
+
delete dataItems[uuid]
|
|
491
|
+
} else {
|
|
492
|
+
dataItems[uuid] = updatedItem
|
|
493
|
+
}
|
|
494
|
+
})
|
|
495
|
+
return dataItems
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const dataItems = clone(state)
|
|
499
|
+
const iterateItems = Object.keys(dataItems)
|
|
500
|
+
if (iterateItems.length) {
|
|
501
|
+
iterateItems.forEach((uuid) => {
|
|
502
|
+
removeRequestedForFromItem(dataItems, uuid, actionId)
|
|
503
|
+
})
|
|
468
504
|
}
|
|
469
505
|
|
|
470
506
|
return dataItems
|
|
@@ -493,13 +529,13 @@ const dataMove = (state, action) => {
|
|
|
493
529
|
}
|
|
494
530
|
|
|
495
531
|
if (!item) {
|
|
496
|
-
|
|
532
|
+
return state
|
|
497
533
|
}
|
|
498
534
|
if (!item._meta) {
|
|
499
535
|
item._meta = {}
|
|
500
536
|
}
|
|
501
537
|
if (!item?._meta?.path) {
|
|
502
|
-
|
|
538
|
+
return state
|
|
503
539
|
}
|
|
504
540
|
const updateObj = {}
|
|
505
541
|
|
|
@@ -37,6 +37,29 @@ interface ActionResult {
|
|
|
37
37
|
deleted: any[]
|
|
38
38
|
resolved: any[]
|
|
39
39
|
}
|
|
40
|
+
dataCacheCleanup?: {
|
|
41
|
+
actionId: string
|
|
42
|
+
uuids: string[]
|
|
43
|
+
}
|
|
44
|
+
queryDeleted?: {
|
|
45
|
+
actionId: string
|
|
46
|
+
query: Record<string, unknown>
|
|
47
|
+
}
|
|
48
|
+
cacheEviction?: {
|
|
49
|
+
cacheKey: string
|
|
50
|
+
uuids: string[]
|
|
51
|
+
}
|
|
52
|
+
cacheGraceEviction?: {
|
|
53
|
+
cacheKey: string
|
|
54
|
+
actionId: string
|
|
55
|
+
}
|
|
56
|
+
cacheGraceCancel?: {
|
|
57
|
+
cacheKey: string
|
|
58
|
+
}
|
|
59
|
+
cacheRemoveCancelled?: {
|
|
60
|
+
cacheKey: string
|
|
61
|
+
childCount: number
|
|
62
|
+
}
|
|
40
63
|
}
|
|
41
64
|
const decorateAction = (reducer) => (state, action) => {
|
|
42
65
|
action.storeLookup = {
|
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { applicationState } from "../../state"
|
|
5
5
|
import { clone, mergeDeepRight } from "ramda"
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
/**
|
|
8
8
|
* add notifcation
|
|
9
9
|
*/
|
|
10
10
|
const notificationsAdd = (state, action) => {
|
|
11
11
|
const items = clone(state.items)
|
|
12
12
|
const notificationTime = new Date()
|
|
13
|
-
const notificationEntry =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const notificationEntry = {
|
|
14
|
+
...action.payload,
|
|
15
|
+
time: notificationTime,
|
|
16
|
+
state: "unread",
|
|
17
|
+
}
|
|
17
18
|
// as we just want updates pushed to the notification que per item and editor each 5min
|
|
18
19
|
const notificationTimeThreshold = 1000 * 60 * 5
|
|
19
20
|
const notificationKeyTime = new Date(
|
|
@@ -47,16 +48,11 @@ const notificationsMarkAllAsSeen = (state, action) => {
|
|
|
47
48
|
item.state = "seen"
|
|
48
49
|
}
|
|
49
50
|
})
|
|
50
|
-
$store.dispatch({
|
|
51
|
-
type: "notifications/update",
|
|
52
|
-
payload: {
|
|
53
|
-
unreadCount: 0,
|
|
54
|
-
},
|
|
55
|
-
})
|
|
56
51
|
|
|
57
52
|
return {
|
|
58
53
|
...state,
|
|
59
54
|
items,
|
|
55
|
+
unreadCount: 0,
|
|
60
56
|
}
|
|
61
57
|
}
|
|
62
58
|
|
|
@@ -71,16 +67,11 @@ const notificationsMarkAllAsRead = (state, action) => {
|
|
|
71
67
|
item.state = "read"
|
|
72
68
|
}
|
|
73
69
|
})
|
|
74
|
-
$store.dispatch({
|
|
75
|
-
type: "notifications/update",
|
|
76
|
-
payload: {
|
|
77
|
-
unreadCount: 0,
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
70
|
|
|
81
71
|
return {
|
|
82
72
|
...state,
|
|
83
73
|
items,
|
|
74
|
+
unreadCount: 0,
|
|
84
75
|
}
|
|
85
76
|
}
|
|
86
77
|
|
|
@@ -88,23 +79,20 @@ const notificationsMarkAllAsRead = (state, action) => {
|
|
|
88
79
|
* mark notification as read
|
|
89
80
|
*/
|
|
90
81
|
const notificationsMarkAsRead = (state, action) => {
|
|
91
|
-
const
|
|
82
|
+
const queKey = action.payload.queKey
|
|
83
|
+
const item = state.items[queKey]
|
|
92
84
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
if (state.unreadCount > 0) {
|
|
96
|
-
$store.dispatch({
|
|
97
|
-
type: "notifications/update",
|
|
98
|
-
payload: {
|
|
99
|
-
unreadCount: state.unreadCount - 1,
|
|
100
|
-
},
|
|
101
|
-
})
|
|
102
|
-
}
|
|
85
|
+
if (!item || item.state === "read") {
|
|
86
|
+
return state
|
|
103
87
|
}
|
|
104
88
|
|
|
105
89
|
return {
|
|
106
90
|
...state,
|
|
107
|
-
items:
|
|
91
|
+
items: {
|
|
92
|
+
...state.items,
|
|
93
|
+
[queKey]: { ...item, state: "read" },
|
|
94
|
+
},
|
|
95
|
+
unreadCount: state.unreadCount > 0 ? state.unreadCount - 1 : state.unreadCount,
|
|
108
96
|
}
|
|
109
97
|
}
|
|
110
98
|
|
|
@@ -112,21 +100,20 @@ const notificationsMarkAsRead = (state, action) => {
|
|
|
112
100
|
* mark notifcation as unread
|
|
113
101
|
*/
|
|
114
102
|
const notificationsMarkUnread = (state, action) => {
|
|
115
|
-
const
|
|
103
|
+
const queKey = action.payload.queKey
|
|
104
|
+
const item = state.items[queKey]
|
|
116
105
|
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
$store.dispatch({
|
|
120
|
-
type: "notifications/update",
|
|
121
|
-
payload: {
|
|
122
|
-
unreadCount: state.unreadCount + 1,
|
|
123
|
-
},
|
|
124
|
-
})
|
|
106
|
+
if (!item || item.state === "unread") {
|
|
107
|
+
return state
|
|
125
108
|
}
|
|
126
109
|
|
|
127
110
|
return {
|
|
128
111
|
...state,
|
|
129
|
-
items:
|
|
112
|
+
items: {
|
|
113
|
+
...state.items,
|
|
114
|
+
[queKey]: { ...item, state: "unread" },
|
|
115
|
+
},
|
|
116
|
+
unreadCount: state.unreadCount + 1,
|
|
130
117
|
}
|
|
131
118
|
}
|
|
132
119
|
|
|
@@ -135,15 +122,20 @@ const notificationsMarkUnread = (state, action) => {
|
|
|
135
122
|
*/
|
|
136
123
|
const notificationsToggle = (state, action) => {
|
|
137
124
|
if (action.payload.toggled === false && state.toggled === true) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
$store.dispatch({
|
|
145
|
-
type: "notifications/markAllAsSeen",
|
|
125
|
+
const items = clone(state.items)
|
|
126
|
+
|
|
127
|
+
Object.values(items).forEach((item) => {
|
|
128
|
+
if (item.state !== "read") {
|
|
129
|
+
item.state = "seen"
|
|
130
|
+
}
|
|
146
131
|
})
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
...state,
|
|
135
|
+
...action.payload,
|
|
136
|
+
items,
|
|
137
|
+
unreadCount: 0,
|
|
138
|
+
}
|
|
147
139
|
}
|
|
148
140
|
|
|
149
141
|
return {
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
import { tap, distinctUntilChanged, ignoreElements } from "rxjs/operators"
|
|
2
2
|
import { actions$, ofType } from "mini-rx-store"
|
|
3
3
|
import { getData } from "@racletteCore/lib/data/dataApi"
|
|
4
|
-
import
|
|
4
|
+
import { scheduleIdleWork } from "@racletteCore/lib/scheduleTask"
|
|
5
|
+
import { $eventbus } from "@racletteCore/main"
|
|
6
|
+
|
|
7
|
+
const dispatchDataCacheCleanup = (store, cleanup) => {
|
|
8
|
+
if (!cleanup?.uuids?.length || !cleanup?.actionId) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
scheduleIdleWork(() => {
|
|
13
|
+
store.dispatch({
|
|
14
|
+
type: "data/deleteFromCache",
|
|
15
|
+
payload: { uuids: cleanup.uuids },
|
|
16
|
+
actionId: cleanup.actionId,
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
5
21
|
const queriesEffects = (store) => {
|
|
6
22
|
const queriesAddExecute = actions$.pipe(
|
|
7
23
|
ofType("queries/add/execute"),
|
|
@@ -22,6 +38,7 @@ const queriesEffects = (store) => {
|
|
|
22
38
|
),
|
|
23
39
|
ignoreElements(),
|
|
24
40
|
)
|
|
41
|
+
|
|
25
42
|
const queriesExecute = actions$.pipe(
|
|
26
43
|
ofType("queries/execute"),
|
|
27
44
|
distinctUntilChanged((prev, curr) => !store.hasChanges(prev, curr)),
|
|
@@ -35,6 +52,7 @@ const queriesEffects = (store) => {
|
|
|
35
52
|
}),
|
|
36
53
|
ignoreElements(),
|
|
37
54
|
)
|
|
55
|
+
|
|
38
56
|
const queryiesSetCacheKey = actions$.pipe(
|
|
39
57
|
ofType("queries/setCacheKey"),
|
|
40
58
|
distinctUntilChanged((prev, curr) => !store.hasChanges(prev, curr)),
|
|
@@ -54,7 +72,42 @@ const queriesEffects = (store) => {
|
|
|
54
72
|
}),
|
|
55
73
|
ignoreElements(),
|
|
56
74
|
)
|
|
57
|
-
|
|
75
|
+
|
|
76
|
+
const queriesUpdateItemsCleanup = actions$.pipe(
|
|
77
|
+
ofType("queries/updateItems"),
|
|
78
|
+
distinctUntilChanged((prev, curr) => !store.hasChanges(prev, curr)),
|
|
79
|
+
|
|
80
|
+
tap((action) => {
|
|
81
|
+
dispatchDataCacheCleanup(store, action.actionResult?.dataCacheCleanup)
|
|
82
|
+
}),
|
|
83
|
+
ignoreElements(),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
const queriesRemoveSideEffects = actions$.pipe(
|
|
87
|
+
ofType("queries/remove"),
|
|
88
|
+
distinctUntilChanged((prev, curr) => !store.hasChanges(prev, curr)),
|
|
89
|
+
|
|
90
|
+
tap((action) => {
|
|
91
|
+
dispatchDataCacheCleanup(store, action.actionResult?.dataCacheCleanup)
|
|
92
|
+
|
|
93
|
+
const deleted = action.actionResult?.queryDeleted as
|
|
94
|
+
| { actionId: string; query: Record<string, unknown> }
|
|
95
|
+
| undefined
|
|
96
|
+
|
|
97
|
+
if (deleted?.actionId) {
|
|
98
|
+
$eventbus.emit("query_deleted_" + deleted.actionId, deleted.query)
|
|
99
|
+
}
|
|
100
|
+
}),
|
|
101
|
+
ignoreElements(),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
return [
|
|
105
|
+
queriesAddExecute,
|
|
106
|
+
queriesExecute,
|
|
107
|
+
queryiesSetCacheKey,
|
|
108
|
+
queriesUpdateItemsCleanup,
|
|
109
|
+
queriesRemoveSideEffects,
|
|
110
|
+
]
|
|
58
111
|
}
|
|
59
112
|
|
|
60
113
|
export default queriesEffects
|