This repository has been archived by the owner on Jan 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
autosave.ts
98 lines (95 loc) · 3.46 KB
/
autosave.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { WidgetMeta } from '../interfaces/widget'
import { $do } from '../actions/actions'
import { OperationTypeCrud } from '../interfaces/operation'
import { Store as CoreStore } from '../interfaces/store'
import { AnyAction, Dispatch, MiddlewareAPI } from 'redux'
/**
* Performs mechanism of autosave
*
* @param action
* @param store
* @param next
* @category Utils
*/
export function autosaveRoutine(action: AnyAction, store: MiddlewareAPI<Dispatch<AnyAction>, CoreStore>, next: Dispatch) {
const state = store.getState()
const dispatch = store.dispatch
const pendingDataChanges = state.view.pendingDataChanges
const bcList = Object.keys(pendingDataChanges)
/**
* Here we need to find BC with unsaved changes called `baseBcName`
* because current action will be dispatched after `baseBcName` saving.
* 1. We need to check out if bcName of current action is suitable for that aim
* 2. Otherwise find first unsaved bcName
*/
const baseBcNameIndex =
action.payload?.bcName &&
bcHasPendingAutosaveChanges(state, action.payload.bcName, state.screen.bo.bc[action.payload.bcName]?.cursor)
? bcList.findIndex(bcName => bcName === action.payload?.bcName)
: bcList.findIndex(bcName => bcHasPendingAutosaveChanges(state, bcName, state.screen.bo.bc[bcName]?.cursor))
const baseBcName = bcList[baseBcNameIndex]
/**
* Here we need to form a list of rest BC names.
* We exclude `baseBcName` from `bcList`
*/
if (baseBcNameIndex > -1) {
bcList.splice(baseBcNameIndex, 1)
}
/**
* Saving process
*/
if (baseBcName) {
/**
* Save all BCs except `baseBcName`
*/
bcList.forEach(bcName => {
const widget = state.view.widgets.find((v: WidgetMeta) => v.bcName === bcName)
const cursor = state.screen.bo.bc[bcName]?.cursor
if (bcHasPendingAutosaveChanges(state, bcName, cursor)) {
dispatch(
$do.sendOperation({
bcName: bcName,
operationType: OperationTypeCrud.save,
widgetName: widget.name
})
)
}
})
/**
* save `baseBcName`'s BC
*/
const baseWidget = state.view.widgets.find((v: WidgetMeta) => v.bcName === baseBcName)
return next(
$do.sendOperation({
bcName: baseBcName,
operationType: OperationTypeCrud.save,
widgetName: baseWidget.name,
onSuccessAction: action
})
)
}
return next(action)
}
/**
* Checks presence of pending changes suitable for autosave
*
* @param store
* @param bcName
* @param cursor
*/
export function bcHasPendingAutosaveChanges(store: CoreStore, bcName: string, cursor: string) {
const pendingChanges = store.view.pendingDataChanges
const cursorChanges = pendingChanges[bcName]?.[cursor]
const result = cursorChanges && !Object.keys(cursorChanges).includes('_associate') && Object.values(cursorChanges).length > 0
return result
}
/**
* Checks presence of unsaved data for specified BC
*
* @param store
* @param bcName
*/
export function checkUnsavedChangesOfBc(store: CoreStore, bcName: string) {
const pendingCursors = Object.keys(store.view.pendingDataChanges?.[bcName] ?? {})
return pendingCursors.some(cursor => bcHasPendingAutosaveChanges(store, bcName, cursor))
}