@riboseinc/paneron-registry-kit 2.0.0-dev9 → 2.0.0
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/common.d.ts +1 -1
- package/common.js +1 -1
- package/common.js.map +1 -1
- package/index.d.ts +3 -3
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/package.json +26 -19
- package/types/cr.d.ts +216 -0
- package/types/cr.js +175 -0
- package/types/cr.js.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.js +19 -0
- package/types/index.js.map +1 -1
- package/types/item.d.ts +13 -3
- package/types/item.js +11 -1
- package/types/item.js.map +1 -1
- package/types/proposal.d.ts +31 -14
- package/types/proposal.js +1 -1
- package/types/proposal.js.map +1 -1
- package/types/register.d.ts +6 -5
- package/types/register.js +19 -1
- package/types/register.js.map +1 -1
- package/types/registry.d.ts +8 -3
- package/types/registry.js +8 -1
- package/types/registry.js.map +1 -1
- package/types/stakeholder.d.ts +40 -16
- package/types/stakeholder.js +47 -3
- package/types/stakeholder.js.map +1 -1
- package/types/views.d.ts +98 -24
- package/types/views.js.map +1 -1
- package/views/AnnotatedChange.d.ts +7 -0
- package/views/AnnotatedChange.js +91 -0
- package/views/AnnotatedChange.js.map +1 -0
- package/views/BrowserCtx.d.ts +66 -2
- package/views/BrowserCtx.js +13 -2
- package/views/BrowserCtx.js.map +1 -1
- package/views/FilterCriteria/CRITERIA_CONFIGURATION.d.ts +13 -1
- package/views/FilterCriteria/CRITERIA_CONFIGURATION.js +178 -85
- package/views/FilterCriteria/CRITERIA_CONFIGURATION.js.map +1 -1
- package/views/FilterCriteria/criteriaGroupToQueryExpression.d.ts +4 -0
- package/views/FilterCriteria/criteriaGroupToQueryExpression.js +10 -3
- package/views/FilterCriteria/criteriaGroupToQueryExpression.js.map +1 -1
- package/views/FilterCriteria/criteriaGroupToSummary.js +7 -7
- package/views/FilterCriteria/criteriaGroupToSummary.js.map +1 -1
- package/views/FilterCriteria/criteriaToNodes.d.ts +9 -0
- package/views/FilterCriteria/criteriaToNodes.js +42 -28
- package/views/FilterCriteria/criteriaToNodes.js.map +1 -1
- package/views/FilterCriteria/index.d.ts +1 -0
- package/views/FilterCriteria/index.js +29 -21
- package/views/FilterCriteria/index.js.map +1 -1
- package/views/FilterCriteria/models.d.ts +29 -2
- package/views/FilterCriteria/models.js +17 -10
- package/views/FilterCriteria/models.js.map +1 -1
- package/views/FilterCriteria/mutateGroup.d.ts +4 -1
- package/views/FilterCriteria/mutateGroup.js +4 -3
- package/views/FilterCriteria/mutateGroup.js.map +1 -1
- package/views/GenericRelatedItemView.d.ts +1 -1
- package/views/GenericRelatedItemView.js +142 -102
- package/views/GenericRelatedItemView.js.map +1 -1
- package/views/RegisterStakeholder.d.ts +9 -0
- package/views/RegisterStakeholder.js +40 -0
- package/views/RegisterStakeholder.js.map +1 -0
- package/views/RegisterVersion.d.ts +9 -0
- package/views/RegisterVersion.js +41 -0
- package/views/RegisterVersion.js.map +1 -0
- package/views/SearchQuery.d.ts +13 -0
- package/views/SearchQuery.js +137 -0
- package/views/SearchQuery.js.map +1 -0
- package/views/change-request/ChangeRequestContext.d.ts +20 -0
- package/views/change-request/ChangeRequestContext.js +56 -0
- package/views/change-request/ChangeRequestContext.js.map +1 -0
- package/views/change-request/Proposals.d.ts +21 -0
- package/views/change-request/Proposals.js +331 -0
- package/views/change-request/Proposals.js.map +1 -0
- package/views/change-request/objectChangeset.d.ts +31 -0
- package/views/change-request/objectChangeset.js +229 -0
- package/views/change-request/objectChangeset.js.map +1 -0
- package/views/detail/ChangeRequest/Proposal.d.ts +0 -0
- package/views/detail/ChangeRequest/Proposal.js +142 -0
- package/views/detail/ChangeRequest/Proposal.js.map +1 -0
- package/views/detail/ChangeRequest/index.d.ts +13 -0
- package/views/detail/ChangeRequest/index.js +207 -0
- package/views/detail/ChangeRequest/index.js.map +1 -0
- package/views/detail/ChangeRequest/transitions.d.ts +28 -0
- package/views/detail/ChangeRequest/transitions.js +530 -0
- package/views/detail/ChangeRequest/transitions.js.map +1 -0
- package/views/detail/CustomView/index.d.ts +13 -0
- package/views/detail/CustomView/index.js +68 -0
- package/views/detail/CustomView/index.js.map +1 -0
- package/views/detail/RegisterHome/index.d.ts +5 -0
- package/views/detail/RegisterHome/index.js +128 -0
- package/views/detail/RegisterHome/index.js.map +1 -0
- package/views/detail/RegisterItem/RelatedItems.d.ts +13 -0
- package/views/detail/RegisterItem/RelatedItems.js +61 -0
- package/views/detail/RegisterItem/RelatedItems.js.map +1 -0
- package/views/detail/RegisterItem/SupersedingItemMenu.d.ts +13 -0
- package/views/detail/RegisterItem/SupersedingItemMenu.js +56 -0
- package/views/detail/RegisterItem/SupersedingItemMenu.js.map +1 -0
- package/views/detail/RegisterItem/index.d.ts +13 -0
- package/views/detail/RegisterItem/index.js +356 -0
- package/views/detail/RegisterItem/index.js.map +1 -0
- package/views/detail/RegisterMeta/RegisterMetaForm.d.ts +10 -0
- package/views/detail/RegisterMeta/RegisterMetaForm.js +331 -0
- package/views/detail/RegisterMeta/RegisterMetaForm.js.map +1 -0
- package/views/detail/RegisterMeta/index.d.ts +10 -0
- package/views/detail/RegisterMeta/index.js +111 -0
- package/views/detail/RegisterMeta/index.js.map +1 -0
- package/views/detail/index.d.ts +1 -0
- package/views/detail/index.js +24 -0
- package/views/detail/index.js.map +1 -0
- package/views/diffing/InlineDiff.d.ts +12 -0
- package/views/diffing/InlineDiff.js +58 -0
- package/views/diffing/InlineDiff.js.map +1 -0
- package/views/diffing/StructuredDiff.d.ts +11 -0
- package/views/diffing/StructuredDiff.js +65 -0
- package/views/diffing/StructuredDiff.js.map +1 -0
- package/views/hooks/useCustomView.d.ts +3 -0
- package/views/hooks/useCustomView.js +24 -0
- package/views/hooks/useCustomView.js.map +1 -0
- package/views/hooks/useItemClassConfig.d.ts +3 -0
- package/views/hooks/useItemClassConfig.js +24 -0
- package/views/hooks/useItemClassConfig.js.map +1 -0
- package/views/hooks/useItemRef.d.ts +3 -0
- package/views/hooks/useItemRef.js +39 -0
- package/views/hooks/useItemRef.js.map +1 -0
- package/views/hooks/useSingleRegisterItemData.d.ts +3 -0
- package/views/hooks/useSingleRegisterItemData.js +32 -0
- package/views/hooks/useSingleRegisterItemData.js.map +1 -0
- package/views/index.d.ts +2 -2
- package/views/index.js +161 -130
- package/views/index.js.map +1 -1
- package/views/itemPathUtils.d.ts +45 -2
- package/views/itemPathUtils.js +101 -14
- package/views/itemPathUtils.js.map +1 -1
- package/views/itemQueryUtils.d.ts +11 -0
- package/views/itemQueryUtils.js +48 -0
- package/views/itemQueryUtils.js.map +1 -0
- package/views/protocolRegistry.d.ts +12 -0
- package/views/protocolRegistry.js +42 -0
- package/views/protocolRegistry.js.map +1 -0
- package/views/sidebar/Browse/index.d.ts +11 -0
- package/views/sidebar/Browse/index.js +453 -0
- package/views/sidebar/Browse/index.js.map +1 -0
- package/views/sidebar/Export/index.d.ts +5 -0
- package/views/sidebar/Export/index.js +94 -0
- package/views/sidebar/Export/index.js.map +1 -0
- package/views/sidebar/ListItem.d.ts +10 -0
- package/views/sidebar/ListItem.js +43 -0
- package/views/sidebar/ListItem.js.map +1 -0
- package/views/sidebar/Registration/index.d.ts +5 -0
- package/views/sidebar/Registration/index.js +163 -0
- package/views/sidebar/Registration/index.js.map +1 -0
- package/views/sidebar/Search/index.d.ts +18 -0
- package/views/sidebar/Search/index.js +177 -0
- package/views/sidebar/Search/index.js.map +1 -0
- package/views/sidebar/index.d.ts +6 -0
- package/views/sidebar/index.js +104 -0
- package/views/sidebar/index.js.map +1 -0
- package/views/util.d.ts +29 -5
- package/views/util.js +92 -6
- package/views/util.js.map +1 -1
- package/views/ChangeRequest.d.ts +0 -12
- package/views/ChangeRequest.js +0 -689
- package/views/ChangeRequest.js.map +0 -1
- package/views/ItemBrowser.d.ts +0 -12
- package/views/ItemBrowser.js +0 -258
- package/views/ItemBrowser.js.map +0 -1
- package/views/ItemDetails.d.ts +0 -14
- package/views/ItemDetails.js +0 -128
- package/views/ItemDetails.js.map +0 -1
- package/views/MainView.d.ts +0 -8
- package/views/MainView.js +0 -34
- package/views/MainView.js.map +0 -1
- package/views/RegisterInformation.d.ts +0 -7
- package/views/RegisterInformation.js +0 -264
- package/views/RegisterInformation.js.map +0 -1
- package/views/RegisterItemGrid.d.ts +0 -25
- package/views/RegisterItemGrid.js +0 -276
- package/views/RegisterItemGrid.js.map +0 -1
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getPastTransitions = getPastTransitions;
|
|
7
|
+
exports.getTransitions = getTransitions;
|
|
8
|
+
exports.isFinalState = isFinalState;
|
|
9
|
+
exports.STATE_INTENT = exports.TransitionOptions = void 0;
|
|
10
|
+
|
|
11
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
12
|
+
|
|
13
|
+
var _react2 = require("@emotion/react");
|
|
14
|
+
|
|
15
|
+
var _core = require("@blueprintjs/core");
|
|
16
|
+
|
|
17
|
+
var _popover = require("@blueprintjs/popover2");
|
|
18
|
+
|
|
19
|
+
var _context = require("@riboseinc/paneron-extension-kit/context");
|
|
20
|
+
|
|
21
|
+
var _BrowserCtx = require("../../BrowserCtx");
|
|
22
|
+
|
|
23
|
+
var _itemPathUtils = require("../../itemPathUtils");
|
|
24
|
+
|
|
25
|
+
var CR = _interopRequireWildcard(require("../../../types/cr"));
|
|
26
|
+
|
|
27
|
+
var _objectChangeset = require("../../change-request/objectChangeset");
|
|
28
|
+
|
|
29
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
30
|
+
|
|
31
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
32
|
+
|
|
33
|
+
/** @jsx jsx */
|
|
34
|
+
|
|
35
|
+
/** @jsxFrag React.Fragment */
|
|
36
|
+
//export const TransitionOptions: C extends CR.Base ? C["state"] extends keyof CR.Transitions ? React.FC<{ cr: CR.Base }> : never : never = function ({ cr }) {
|
|
37
|
+
const TransitionOptions = function ({
|
|
38
|
+
cr,
|
|
39
|
+
className
|
|
40
|
+
}) {
|
|
41
|
+
var _transitions$find;
|
|
42
|
+
|
|
43
|
+
const {
|
|
44
|
+
stakeholder,
|
|
45
|
+
subregisters
|
|
46
|
+
} = (0, _react.useContext)(_BrowserCtx.BrowserCtx);
|
|
47
|
+
const {
|
|
48
|
+
getObjectData,
|
|
49
|
+
updateObjects,
|
|
50
|
+
performOperation,
|
|
51
|
+
operationKey,
|
|
52
|
+
usePersistentDatasetStateReducer
|
|
53
|
+
} = (0, _react.useContext)(_context.DatasetContext);
|
|
54
|
+
const isBusy = operationKey !== undefined;
|
|
55
|
+
const transitions = (0, _react.useMemo)(() => stakeholder ? getTransitions(cr, stakeholder) : [], [JSON.stringify(stakeholder), cr === null || cr === void 0 ? void 0 : cr.id, cr === null || cr === void 0 ? void 0 : cr.state]);
|
|
56
|
+
const initialState = {
|
|
57
|
+
// Pre-select next state to first available transition
|
|
58
|
+
chosenNextState: transitions.length > 0 ? transitions[0][0] : undefined,
|
|
59
|
+
stateInput: {}
|
|
60
|
+
};
|
|
61
|
+
const [state, dispatch, stateRecalled] = usePersistentDatasetStateReducer(`${cr.id}-${cr.state}`, undefined, undefined, (prevState, action) => {
|
|
62
|
+
switch (action.type) {
|
|
63
|
+
case 'unset-next-state':
|
|
64
|
+
return { ...prevState,
|
|
65
|
+
chosenNextState: undefined
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
case 'choose-next-state':
|
|
69
|
+
return { ...prevState,
|
|
70
|
+
chosenNextState: action.payload.state
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
case 'update-next-state-input':
|
|
74
|
+
return { ...prevState,
|
|
75
|
+
stateInput: action.payload
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
throw new Error("Unexpected state");
|
|
80
|
+
}
|
|
81
|
+
}, initialState, null);
|
|
82
|
+
const selectedTransitionCfg = (stateRecalled && state.chosenNextState ? (_transitions$find = transitions.find(([t]) => t === state.chosenNextState)) === null || _transitions$find === void 0 ? void 0 : _transitions$find[1] : undefined) ?? undefined;
|
|
83
|
+
(0, _react.useEffect)(() => {
|
|
84
|
+
if (stateRecalled && state.chosenNextState) {
|
|
85
|
+
if (!selectedTransitionCfg) {
|
|
86
|
+
dispatch({
|
|
87
|
+
type: 'unset-next-state'
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, [stateRecalled, state.chosenNextState, JSON.stringify(selectedTransitionCfg)]);
|
|
92
|
+
const [validatedStateInput, stateInputValidationErrors] = (0, _react.useMemo)(() => {
|
|
93
|
+
if (cr && selectedTransitionCfg) {
|
|
94
|
+
try {
|
|
95
|
+
selectedTransitionCfg.func(cr, state.stateInput);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
return [undefined, e.message ?? `${e}`];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return [state.stateInput, undefined];
|
|
101
|
+
} else {
|
|
102
|
+
return [undefined, "no CR or no transition selected"];
|
|
103
|
+
}
|
|
104
|
+
}, [JSON.stringify(cr), JSON.stringify(selectedTransitionCfg), JSON.stringify(state.stateInput)]);
|
|
105
|
+
const getItemChangesetAsApproved = (0, _react.useCallback)(async function (cr) {
|
|
106
|
+
const origItemData = (await getObjectData({
|
|
107
|
+
objectPaths: [...Object.entries(cr.items).filter(([, prop]) => prop.type !== 'addition').map(([itemPath]) => itemPath), ...Object.values(cr.items).filter(prop => prop.type === 'amendment' && prop.amendmentType === 'supersession').flatMap(prop => prop.supersedingItemIDs)]
|
|
108
|
+
})).data;
|
|
109
|
+
console.debug("Got orig item data", origItemData);
|
|
110
|
+
const newItemData = (await getObjectData({
|
|
111
|
+
objectPaths: Object.entries(cr.items).filter(([, prop]) => prop.type === 'clarification' || prop.type === 'addition').map(([itemPath]) => (0, _itemPathUtils.itemPathInCR)(itemPath, cr.id))
|
|
112
|
+
})).data;
|
|
113
|
+
console.debug("Got new item data", newItemData);
|
|
114
|
+
return await (0, _objectChangeset.proposalsToObjectChangeset)(cr.id, subregisters !== undefined, cr.items, origItemData, newItemData);
|
|
115
|
+
}, [JSON.stringify(cr), JSON.stringify(subregisters)]);
|
|
116
|
+
const handleTransition = (0, _react.useCallback)(async function (transitionCfg, stateInput) {
|
|
117
|
+
if (transitionCfg && updateObjects && stakeholder && transitionCfg.canBeTransitionedBy(stakeholder, cr)) {
|
|
118
|
+
const newCR = { ...transitionCfg.func(cr, stateInput),
|
|
119
|
+
state: transitionCfg.targetState
|
|
120
|
+
}; //console.debug("Transitioning CR", JSON.stringify(cr), JSON.stringify(newCR));
|
|
121
|
+
|
|
122
|
+
const changeset = {
|
|
123
|
+
[(0, _itemPathUtils.crIDToCRPath)(cr.id)]: {
|
|
124
|
+
oldValue: cr,
|
|
125
|
+
newValue: newCR
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (CR.isAccepted(newCR) || CR.isAcceptedOnAppeal(newCR)) {
|
|
130
|
+
Object.assign(changeset, await getItemChangesetAsApproved(newCR));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
await updateObjects({
|
|
134
|
+
commitMessage: `${transitionCfg.title} CR`,
|
|
135
|
+
objectChangeset: changeset
|
|
136
|
+
});
|
|
137
|
+
} else {
|
|
138
|
+
throw new Error("Either transition is not specified or dataset is read-only");
|
|
139
|
+
}
|
|
140
|
+
}, [updateObjects, JSON.stringify(stakeholder), JSON.stringify(cr)]);
|
|
141
|
+
const canTransition = selectedTransitionCfg !== undefined && !isBusy && validatedStateInput !== undefined;
|
|
142
|
+
return (0, _react2.jsx)("div", {
|
|
143
|
+
css: (0, _react2.css)`display: flex; flex-flow: column nowrap;`,
|
|
144
|
+
className: className
|
|
145
|
+
}, transitions.length > 0 ? (0, _react2.jsx)(_core.RadioGroup, {
|
|
146
|
+
selectedValue: state.chosenNextState,
|
|
147
|
+
onChange: evt => CR.isState(evt.currentTarget.value) ? dispatch({
|
|
148
|
+
type: 'choose-next-state',
|
|
149
|
+
payload: {
|
|
150
|
+
state: evt.currentTarget.value
|
|
151
|
+
}
|
|
152
|
+
}) : void 0
|
|
153
|
+
}, transitions.map(([state, cfg]) => (0, _react2.jsx)(_core.Radio, {
|
|
154
|
+
key: state,
|
|
155
|
+
label: cfg.title,
|
|
156
|
+
value: state,
|
|
157
|
+
disabled: isBusy,
|
|
158
|
+
large: true
|
|
159
|
+
}))) : null, selectedTransitionCfg !== null && selectedTransitionCfg !== void 0 && selectedTransitionCfg.Widget ? (0, _react2.jsx)(_popover.Tooltip2, {
|
|
160
|
+
isOpen: stateInputValidationErrors !== undefined,
|
|
161
|
+
placement: 'bottom',
|
|
162
|
+
targetTagName: 'div',
|
|
163
|
+
intent: 'warning',
|
|
164
|
+
content: (0, _react2.jsx)(_react.default.Fragment, null, stateInputValidationErrors)
|
|
165
|
+
}, (0, _react2.jsx)(selectedTransitionCfg.Widget, {
|
|
166
|
+
value: Object.keys(state.stateInput).length > 0 ? state.stateInput : cr,
|
|
167
|
+
onChange: !isBusy ? payload => dispatch({
|
|
168
|
+
type: 'update-next-state-input',
|
|
169
|
+
payload
|
|
170
|
+
}) : undefined
|
|
171
|
+
})) : null, selectedTransitionCfg ? (0, _react2.jsx)(_core.Button, {
|
|
172
|
+
disabled: !canTransition,
|
|
173
|
+
intent: canTransition ? 'primary' : undefined,
|
|
174
|
+
onClick: () => validatedStateInput ? performOperation('transitioning CR state', handleTransition)(selectedTransitionCfg, validatedStateInput) : void 0
|
|
175
|
+
}, selectedTransitionCfg.title) : null);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
exports.TransitionOptions = TransitionOptions;
|
|
179
|
+
|
|
180
|
+
function getPastTransitions(cr) {
|
|
181
|
+
const els = [];
|
|
182
|
+
|
|
183
|
+
if (CR.hasSubmitterInput(cr)) {
|
|
184
|
+
els.push(['Submitter input', (0, _react2.jsx)(_react.default.Fragment, null, cr.justification)]);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (CR.hasRegisterManagerInput(cr)) {
|
|
188
|
+
els.push(['Register manager notes', (0, _react2.jsx)(_react.default.Fragment, null, cr.registerManagerNotes)]);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (CR.hasControlBodyInput(cr)) {
|
|
192
|
+
els.push(['Control body input', (0, _react2.jsx)(_react.default.Fragment, null, cr.controlBodyNotes, (0, _react2.jsx)("br", null), (0, _react2.jsx)("em", {
|
|
193
|
+
css: (0, _react2.css)`display: block;`
|
|
194
|
+
}, "Decision event: ", cr.controlBodyDecisionEvent))]);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (CR.hasAppealRequest(cr)) {
|
|
198
|
+
els.push(['Reason for appeal', (0, _react2.jsx)(_react.default.Fragment, null, cr.appealReason)]);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (CR.hasRegisterOwnerInput(cr)) {
|
|
202
|
+
els.push(['Register owner notes', (0, _react2.jsx)(_react.default.Fragment, null, cr.registerOwnerNotes)]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return els;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Returns a list of transitions
|
|
209
|
+
* that can be performed on given CR by given stakeholder.
|
|
210
|
+
*/
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
function getTransitions(cr, stakeholder) {
|
|
214
|
+
const possibleTransitions = TRANSITIONS[cr.state];
|
|
215
|
+
|
|
216
|
+
if (possibleTransitions) {
|
|
217
|
+
return Object.entries(possibleTransitions).filter(([, t]) => t.canBeTransitionedBy(stakeholder, cr));
|
|
218
|
+
} else {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Returns True if there is no possible transition for given state.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
function isFinalState(state) {
|
|
228
|
+
return Object.keys(TRANSITIONS[state] ?? {}).length < 1;
|
|
229
|
+
} // Transition runtime implementation
|
|
230
|
+
// const draft: CR.Transition<
|
|
231
|
+
// | CR.ReturnedForClarificationByControlBody
|
|
232
|
+
// | CR.ReturnedForClarificationByManager
|
|
233
|
+
// | CR.Drafted,
|
|
234
|
+
// CR.Drafted,
|
|
235
|
+
// CR.SubmitterInput> =
|
|
236
|
+
// function (cr, { justification, items }) {
|
|
237
|
+
// return {
|
|
238
|
+
// ...cr,
|
|
239
|
+
// justification,
|
|
240
|
+
// timeEdited: new Date(),
|
|
241
|
+
// items,
|
|
242
|
+
// };
|
|
243
|
+
// }
|
|
244
|
+
//
|
|
245
|
+
// const withdraw: CR.Transition<
|
|
246
|
+
// CR.Proposed
|
|
247
|
+
// | CR.SubmittedForControlBodyReview
|
|
248
|
+
// | CR.ReturnedForClarificationByControlBody
|
|
249
|
+
// | CR.ReturnedForClarificationByManager,
|
|
250
|
+
// CR.Withdrawn> =
|
|
251
|
+
// function withdraw (cr) {
|
|
252
|
+
// return {
|
|
253
|
+
// ...cr,
|
|
254
|
+
// timeDisposed: new Date(),
|
|
255
|
+
// };
|
|
256
|
+
// }
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
const applyRegisterManagerDecision = function applyRegisterManagerDecision(cr, {
|
|
260
|
+
registerManagerNotes
|
|
261
|
+
}) {
|
|
262
|
+
if (!(registerManagerNotes !== null && registerManagerNotes !== void 0 && registerManagerNotes.trim())) {
|
|
263
|
+
throw new Error("Register manager note is required.");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return { ...cr,
|
|
267
|
+
registerManagerNotes
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const applyControlBodyDecision = function applyControlBodyDecision(cr, {
|
|
272
|
+
controlBodyNotes,
|
|
273
|
+
controlBodyDecisionEvent
|
|
274
|
+
}) {
|
|
275
|
+
if (!(controlBodyNotes !== null && controlBodyNotes !== void 0 && controlBodyNotes.trim()) || !(controlBodyDecisionEvent !== null && controlBodyDecisionEvent !== void 0 && controlBodyDecisionEvent.trim())) {
|
|
276
|
+
throw new Error("Control body notes and decision event are required.");
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return { ...cr,
|
|
280
|
+
controlBodyNotes,
|
|
281
|
+
controlBodyDecisionEvent
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const applyAppeal = function applyRegisterManagerDecision(cr, {
|
|
286
|
+
appealReason
|
|
287
|
+
}) {
|
|
288
|
+
if (!(appealReason !== null && appealReason !== void 0 && appealReason.trim())) {
|
|
289
|
+
throw new Error("Appeal reason is required.");
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return { ...cr,
|
|
293
|
+
appealReason,
|
|
294
|
+
timeDisposed: undefined
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const applyRegisterOwnerDecision = function applyRegisterManagerDecision(cr, {
|
|
299
|
+
registerOwnerNotes
|
|
300
|
+
}) {
|
|
301
|
+
if (!(registerOwnerNotes !== null && registerOwnerNotes !== void 0 && registerOwnerNotes.trim())) {
|
|
302
|
+
throw new Error("Register owner note is required.");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return { ...cr,
|
|
306
|
+
registerOwnerNotes,
|
|
307
|
+
timeDisposed: new Date()
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const WITHDRAWAL_TRANSITION = {
|
|
312
|
+
title: "Withdraw",
|
|
313
|
+
targetState: CR.State.WITHDRAWN,
|
|
314
|
+
Widget: null,
|
|
315
|
+
canBeTransitionedBy: CR.isSubmittedBy,
|
|
316
|
+
func: cr => ({ ...cr,
|
|
317
|
+
timeDisposed: new Date()
|
|
318
|
+
})
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const SubmitterInputWidget = function ({
|
|
322
|
+
value,
|
|
323
|
+
onChange
|
|
324
|
+
}) {
|
|
325
|
+
return (0, _react2.jsx)(_core.FormGroup, {
|
|
326
|
+
label: "Justification:"
|
|
327
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
328
|
+
required: true,
|
|
329
|
+
value: value.justification,
|
|
330
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
331
|
+
justification: evt.currentTarget.value
|
|
332
|
+
})
|
|
333
|
+
}));
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const TransitionInputTextArea = function (props) {
|
|
337
|
+
return (0, _react2.jsx)(_core.TextArea, {
|
|
338
|
+
fill: true,
|
|
339
|
+
css: (0, _react2.css)`resize: vertical;`,
|
|
340
|
+
readOnly: !props.onChange,
|
|
341
|
+
...props
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const PROPOSAL_TRANSITION = {
|
|
346
|
+
title: "Propose",
|
|
347
|
+
targetState: CR.State.PROPOSED,
|
|
348
|
+
canBeTransitionedBy: (stakeholder, cr) => CR.isSubmittedBy(stakeholder, cr) && Object.keys(cr.items).length > 0,
|
|
349
|
+
Widget: SubmitterInputWidget,
|
|
350
|
+
func: (cr, submitterInput) => {
|
|
351
|
+
var _submitterInput$justi;
|
|
352
|
+
|
|
353
|
+
if (!(submitterInput !== null && submitterInput !== void 0 && (_submitterInput$justi = submitterInput.justification) !== null && _submitterInput$justi !== void 0 && _submitterInput$justi.trim())) {
|
|
354
|
+
throw new Error("Justification is required.");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return { ...cr,
|
|
358
|
+
...submitterInput,
|
|
359
|
+
timeProposed: new Date()
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const RegisterManagerNotesWidget = function ({
|
|
365
|
+
value,
|
|
366
|
+
onChange
|
|
367
|
+
}) {
|
|
368
|
+
return (0, _react2.jsx)(_core.FormGroup, {
|
|
369
|
+
label: "Register manager notes:"
|
|
370
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
371
|
+
value: value.registerManagerNotes,
|
|
372
|
+
required: true,
|
|
373
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
374
|
+
registerManagerNotes: evt.currentTarget.value
|
|
375
|
+
})
|
|
376
|
+
}));
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const ControlBodyNotesWidget = function ({
|
|
380
|
+
value,
|
|
381
|
+
onChange
|
|
382
|
+
}) {
|
|
383
|
+
return (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.FormGroup, {
|
|
384
|
+
label: "Control body notes:"
|
|
385
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
386
|
+
value: value.controlBodyNotes,
|
|
387
|
+
required: true,
|
|
388
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
389
|
+
controlBodyNotes: evt.currentTarget.value,
|
|
390
|
+
controlBodyDecisionEvent: value.controlBodyDecisionEvent
|
|
391
|
+
})
|
|
392
|
+
})), (0, _react2.jsx)(_core.FormGroup, {
|
|
393
|
+
label: "Control body decision event:"
|
|
394
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
395
|
+
value: value.controlBodyDecisionEvent,
|
|
396
|
+
required: true,
|
|
397
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
398
|
+
controlBodyNotes: value.controlBodyNotes,
|
|
399
|
+
controlBodyDecisionEvent: evt.currentTarget.value
|
|
400
|
+
})
|
|
401
|
+
})));
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
const AppealRequestWidget = function ({
|
|
405
|
+
value,
|
|
406
|
+
onChange
|
|
407
|
+
}) {
|
|
408
|
+
return (0, _react2.jsx)(_core.FormGroup, {
|
|
409
|
+
label: "Appeal reasoning:"
|
|
410
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
411
|
+
value: value.appealReason,
|
|
412
|
+
required: true,
|
|
413
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
414
|
+
appealReason: evt.currentTarget.value
|
|
415
|
+
})
|
|
416
|
+
}));
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const RegisterOwnerNotesWidget = function ({
|
|
420
|
+
value,
|
|
421
|
+
onChange
|
|
422
|
+
}) {
|
|
423
|
+
return (0, _react2.jsx)(_core.FormGroup, {
|
|
424
|
+
label: "Register owner notes:"
|
|
425
|
+
}, (0, _react2.jsx)(TransitionInputTextArea, {
|
|
426
|
+
value: value.registerOwnerNotes,
|
|
427
|
+
required: true,
|
|
428
|
+
onChange: evt => onChange === null || onChange === void 0 ? void 0 : onChange({
|
|
429
|
+
registerOwnerNotes: evt.currentTarget.value
|
|
430
|
+
})
|
|
431
|
+
}));
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const STATE_INTENT = {
|
|
435
|
+
[CR.State.PROPOSED]: 'primary',
|
|
436
|
+
[CR.State.RETURNED_FOR_CLARIFICATION]: 'primary',
|
|
437
|
+
[CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: 'primary',
|
|
438
|
+
[CR.State.APPEALED]: 'warning'
|
|
439
|
+
};
|
|
440
|
+
/** Associates transition implementation with source/target states. */
|
|
441
|
+
|
|
442
|
+
exports.STATE_INTENT = STATE_INTENT;
|
|
443
|
+
const TRANSITIONS = {
|
|
444
|
+
[CR.State.DRAFT]: {
|
|
445
|
+
[CR.State.PROPOSED]: PROPOSAL_TRANSITION
|
|
446
|
+
},
|
|
447
|
+
[CR.State.PROPOSED]: {
|
|
448
|
+
[CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,
|
|
449
|
+
[CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {
|
|
450
|
+
title: "Submit for control body review",
|
|
451
|
+
targetState: CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,
|
|
452
|
+
canBeTransitionedBy: stakeholder => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,
|
|
453
|
+
Widget: RegisterManagerNotesWidget,
|
|
454
|
+
func: applyRegisterManagerDecision
|
|
455
|
+
},
|
|
456
|
+
[CR.State.RETURNED_FOR_CLARIFICATION]: {
|
|
457
|
+
title: "Return for clarification",
|
|
458
|
+
targetState: CR.State.RETURNED_FOR_CLARIFICATION,
|
|
459
|
+
canBeTransitionedBy: stakeholder => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,
|
|
460
|
+
Widget: RegisterManagerNotesWidget,
|
|
461
|
+
func: applyRegisterManagerDecision
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
[CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {
|
|
465
|
+
[CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,
|
|
466
|
+
[CR.State.RETURNED_FOR_CLARIFICATION]: {
|
|
467
|
+
title: "Return for clarification",
|
|
468
|
+
targetState: CR.State.RETURNED_FOR_CLARIFICATION,
|
|
469
|
+
canBeTransitionedBy: stakeholder => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,
|
|
470
|
+
Widget: ControlBodyNotesWidget,
|
|
471
|
+
func: applyControlBodyDecision
|
|
472
|
+
},
|
|
473
|
+
[CR.State.ACCEPTED]: {
|
|
474
|
+
title: "Accept",
|
|
475
|
+
targetState: CR.State.ACCEPTED,
|
|
476
|
+
canBeTransitionedBy: stakeholder => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,
|
|
477
|
+
Widget: ControlBodyNotesWidget,
|
|
478
|
+
func: (cr, controlBodyInput) => ({ ...applyControlBodyDecision(cr, controlBodyInput),
|
|
479
|
+
timeDisposed: new Date()
|
|
480
|
+
})
|
|
481
|
+
},
|
|
482
|
+
[CR.State.REJECTED]: {
|
|
483
|
+
title: "Reject",
|
|
484
|
+
targetState: CR.State.REJECTED,
|
|
485
|
+
canBeTransitionedBy: stakeholder => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,
|
|
486
|
+
Widget: ControlBodyNotesWidget,
|
|
487
|
+
func: (cr, controlBodyInput) => ({ ...applyControlBodyDecision(cr, controlBodyInput),
|
|
488
|
+
timeDisposed: new Date()
|
|
489
|
+
})
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
[CR.State.RETURNED_FOR_CLARIFICATION]: {
|
|
493
|
+
[CR.State.PROPOSED]: PROPOSAL_TRANSITION,
|
|
494
|
+
[CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION
|
|
495
|
+
},
|
|
496
|
+
[CR.State.REJECTED]: {
|
|
497
|
+
[CR.State.APPEALED]: {
|
|
498
|
+
title: "Appeal",
|
|
499
|
+
targetState: CR.State.APPEALED,
|
|
500
|
+
canBeTransitionedBy: CR.isSubmittedBy,
|
|
501
|
+
Widget: AppealRequestWidget,
|
|
502
|
+
func: applyAppeal
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
[CR.State.APPEALED]: {
|
|
506
|
+
[CR.State.APPEAL_WITHDRAWN]: {
|
|
507
|
+
title: "Withdraw appeal",
|
|
508
|
+
targetState: CR.State.APPEAL_WITHDRAWN,
|
|
509
|
+
canBeTransitionedBy: CR.isSubmittedBy,
|
|
510
|
+
Widget: null,
|
|
511
|
+
func: cr => ({ ...cr,
|
|
512
|
+
timeDisposed: new Date()
|
|
513
|
+
})
|
|
514
|
+
},
|
|
515
|
+
[CR.State.ACCEPTED_ON_APPEAL]: {
|
|
516
|
+
title: "Accept on appeal",
|
|
517
|
+
targetState: CR.State.ACCEPTED_ON_APPEAL,
|
|
518
|
+
canBeTransitionedBy: stakeholder => stakeholder.role === 'owner',
|
|
519
|
+
Widget: RegisterOwnerNotesWidget,
|
|
520
|
+
func: applyRegisterOwnerDecision
|
|
521
|
+
},
|
|
522
|
+
[CR.State.REJECTION_UPHELD_ON_APPEAL]: {
|
|
523
|
+
title: "Uphold rejection",
|
|
524
|
+
targetState: CR.State.REJECTION_UPHELD_ON_APPEAL,
|
|
525
|
+
canBeTransitionedBy: stakeholder => stakeholder.role === 'owner',
|
|
526
|
+
Widget: RegisterOwnerNotesWidget,
|
|
527
|
+
func: applyRegisterOwnerDecision
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../../../src/views/detail/ChangeRequest/transitions.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useEffect, useMemo, useCallback } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport { Button, RadioGroup, Radio, FormGroup, TextArea, TextAreaProps, Intent } from '@blueprintjs/core';\nimport { Tooltip2 as Tooltip } from '@blueprintjs/popover2';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { ObjectChangeset } from '@riboseinc/paneron-extension-kit/types/objects';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport type { RegisterItem, RegisterStakeholder, Supersession } from '../../../types';\nimport { itemPathInCR, crIDToCRPath } from '../../itemPathUtils';\nimport * as CR from '../../../types/cr';\nimport { proposalsToObjectChangeset } from '../../change-request/objectChangeset';\n\n\n// XXX: simplify\n//type TransitionInputWidget<TO extends BaseCR, FROM extends BaseCR> =\n// TO[\"state\"] extends keyof Transitions\n// ? FROM[\"state\"] extends keyof Transitions[TO[\"state\"]]\n// ? Transitions[TO[\"state\"]][FROM[\"state\"]] extends Transition<any, any, infer P>\n// ? React.FC<{\n// inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// : never\n// : never\n// : never\n\n// type TransitionInputWidget<P extends Record<string, any> | undefined> =\n// React.FC<{\n// //inputData: P;\n// onConfirm: (inputData: P) => Promise<void>;\n// }>\n// \n// \n// type TransitionWidgetConfiguration<T> =\n// T extends Transition<infer C, infer C2, infer P>\n// ? {\n// title: JSX.Element | string\n// hint?: JSX.Element | string\n// Widget: TransitionInputWidget<P>;\n// stakeholderCanTransition: (stakeholder: RegisterStakeholder, cr: C) => boolean;\n// typeGuard: (c: BaseCR) => c is C;\n// targetState: C2[\"state\"];\n// }\n// : never\n// \n// //const SubmitterInput: TransitionInputWidget<SubmitterInput> = function ({ inputData, onConfirm }) {\n// // return <></>;\n// //}\n// \n// const ProposalInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const DraftInput: TransitionInputWidget<SubmitterInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// const SubmitToControlBodyInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return <></>;\n// };\n// \n// //type C = Transitions[typeof State.DRAFT][typeof State.PROPOSED]\n// \n// const propose: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.PROPOSED]> = {\n// Widget: ProposalInput,\n// title: \"Propose\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.PROPOSED,\n// };\n// const updateDraft: TransitionWidgetConfiguration<Transitions[typeof State.DRAFT][typeof State.DRAFT]> = {\n// Widget: DraftInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isDrafted,\n// targetState: State.DRAFT,\n// };\n// const submitToControlBody: TransitionWidgetConfiguration<Transitions[typeof State.PROPOSED][typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]> = {\n// Widget: SubmitToControlBodyInput,\n// title: \"Update draft\",\n// stakeholderCanTransition: isSubmitter,\n// typeGuard: isProposed,\n// targetState: State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n// };\n// \n// const options = [updateDraft, propose, submitToControlBody];\n// \n// const RegisterManagerInput: TransitionInputWidget<RegisterManagerInput> = function ({ onConfirm }) {\n// return (\n// <FormGroup label=\"Content summary:\">\n// <TextArea\n// fill\n// value={value.contentSummary || ''} readOnly={!onChange}\n// onChange={handleSummaryChange} />\n// </FormGroup>\n// );\n// }\n//type TransitionWidgetsConfiguration = {\n// [Statuses in `${keyof Transitions}_${keyof Transitions}`]:\n// Statuses extends `${infer F}_${infer T}`\n// ? F extends keyof Transitions\n// ? T extends keyof Transitions[F]\n// ? TransitionWidgetConfiguration<Transitions[F][T]>\n// : never\n// : never\n// : never\n//}\n\ninterface State {\n chosenNextState?: CR.StateType;\n\n /**\n * Can contain any fields. Upon transition,\n * they will be validated against selected `chosenNextState`.\n */\n stateInput: Partial<CR.StateInput>;\n}\n\ntype Action =\n | { type: 'unset-next-state' }\n | { type: 'choose-next-state'; payload: { state: CR.StateType } }\n | { type: 'update-next-state-input'; payload: Record<string, any> }\n\n//export const TransitionOptions: C extends CR.Base ? C[\"state\"] extends keyof CR.Transitions ? React.FC<{ cr: CR.Base }> : never : never = function ({ cr }) {\nexport const TransitionOptions: React.FC<{ cr: CR.Base, className?: string }> =\nfunction ({ cr, className }) {\n const { stakeholder, subregisters } = useContext(BrowserCtx);\n const {\n getObjectData,\n updateObjects,\n performOperation,\n operationKey,\n usePersistentDatasetStateReducer,\n } = useContext(DatasetContext);\n\n const isBusy = operationKey !== undefined;\n\n const transitions = useMemo((\n () => stakeholder\n ? getTransitions(cr, stakeholder)\n : []\n ), [JSON.stringify(stakeholder), cr?.id, cr?.state]);\n\n const initialState: State = {\n // Pre-select next state to first available transition\n chosenNextState: transitions.length > 0\n ? transitions[0][0]\n : undefined,\n stateInput: {},\n };\n\n const [ state, dispatch, stateRecalled ] =\n (usePersistentDatasetStateReducer as PersistentStateReducerHook<State, Action>)(\n `${cr.id}-${cr.state}`,\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'unset-next-state':\n return {\n ...prevState,\n chosenNextState: undefined,\n };\n case 'choose-next-state':\n return {\n ...prevState,\n chosenNextState: action.payload.state,\n };\n case 'update-next-state-input':\n return {\n ...prevState,\n stateInput: action.payload,\n };\n default:\n throw new Error(\"Unexpected state\");\n }\n },\n initialState,\n null);\n\n const selectedTransitionCfg = (stateRecalled && state.chosenNextState\n ? transitions.find(([t, ]) => t === state.chosenNextState)?.[1]\n : undefined\n ) ?? undefined;\n\n useEffect(() => {\n if (stateRecalled && state.chosenNextState) {\n if (!selectedTransitionCfg) {\n dispatch({ type: 'unset-next-state' });\n }\n }\n }, [\n stateRecalled,\n state.chosenNextState,\n JSON.stringify(selectedTransitionCfg),\n ]);\n\n const [validatedStateInput, stateInputValidationErrors]:\n [CR.StateInput, undefined] | [undefined, string] =\n useMemo(() => {\n if (cr && selectedTransitionCfg) {\n try {\n selectedTransitionCfg.func(cr, state.stateInput);\n } catch (e) {\n return [undefined, (e as any).message ?? `${e}`];\n }\n return [state.stateInput as CR.StateInput, undefined];\n } else {\n return [undefined, \"no CR or no transition selected\"];\n }\n }, [JSON.stringify(cr), JSON.stringify(selectedTransitionCfg), JSON.stringify(state.stateInput)]);\n\n const getItemChangesetAsApproved = useCallback(\n async function (cr: CR.Accepted | CR.AcceptedOnAppeal): Promise<ObjectChangeset> {\n const origItemData = (await getObjectData({\n objectPaths: [\n ...Object.entries(cr.items).\n filter(([, prop]) => prop.type !== 'addition').\n map(([itemPath, ]) => itemPath),\n ...Object.values(cr.items).\n filter(prop => prop.type === 'amendment' && prop.amendmentType === 'supersession').\n flatMap(prop => (prop as Supersession).supersedingItemIDs),\n ],\n })).data as Record<string, RegisterItem<any> | null>;\n console.debug(\"Got orig item data\", origItemData);\n const newItemData = (await getObjectData({\n objectPaths: Object.entries(cr.items).\n filter(([, prop]) => prop.type === 'clarification' || prop.type === 'addition').\n map(([itemPath, ]) => itemPathInCR(itemPath, cr.id)),\n })).data as Record<string, RegisterItem<any> | null>;\n console.debug(\"Got new item data\", newItemData);\n return await proposalsToObjectChangeset(\n cr.id,\n subregisters !== undefined,\n cr.items,\n origItemData,\n newItemData);\n }, [JSON.stringify(cr), JSON.stringify(subregisters)]);\n\n const handleTransition = useCallback(\n async function (transitionCfg: typeof selectedTransitionCfg, stateInput: CR.StateInput) {\n if (transitionCfg && updateObjects && stakeholder && transitionCfg.canBeTransitionedBy(stakeholder, cr)) {\n const newCR = {\n ...(transitionCfg.func(cr, stateInput) as Omit<CR.SomeCR, 'state'>),\n state: transitionCfg.targetState,\n };\n //console.debug(\"Transitioning CR\", JSON.stringify(cr), JSON.stringify(newCR));\n const changeset: ObjectChangeset = {\n [crIDToCRPath(cr.id)]: {\n oldValue: cr,\n newValue: newCR,\n },\n };\n if (CR.isAccepted(newCR) || CR.isAcceptedOnAppeal(newCR)) {\n Object.assign(changeset, await getItemChangesetAsApproved(newCR));\n }\n await updateObjects({\n commitMessage: `${transitionCfg.title} CR`,\n objectChangeset: changeset,\n });\n } else {\n throw new Error(\"Either transition is not specified or dataset is read-only\");\n }\n }, [updateObjects, JSON.stringify(stakeholder), JSON.stringify(cr)]);\n\n const canTransition = selectedTransitionCfg !== undefined && !isBusy && validatedStateInput !== undefined;\n\n return (\n <div css={css`display: flex; flex-flow: column nowrap;`} className={className}>\n {transitions.length > 0\n ? <RadioGroup\n selectedValue={state.chosenNextState}\n onChange={(evt) => CR.isState(evt.currentTarget.value)\n ? dispatch({\n type: 'choose-next-state',\n payload: { state: evt.currentTarget.value },\n })\n : void 0}>\n {transitions.map(([state, cfg]) => \n <Radio\n key={state}\n label={cfg.title}\n value={state}\n disabled={isBusy}\n large\n />\n )}\n </RadioGroup>\n : null}\n {selectedTransitionCfg?.Widget\n ? <Tooltip\n isOpen={stateInputValidationErrors !== undefined}\n placement='bottom'\n targetTagName='div'\n intent='warning'\n content={<>{stateInputValidationErrors}</>}>\n <selectedTransitionCfg.Widget\n value={Object.keys(state.stateInput).length > 0\n ? state.stateInput\n : cr}\n onChange={!isBusy\n ? (payload) => dispatch({\n type: 'update-next-state-input',\n payload,\n })\n : undefined}\n />\n </Tooltip>\n : null}\n {selectedTransitionCfg\n ? <Button\n disabled={!canTransition}\n intent={canTransition ? 'primary' : undefined}\n onClick={() =>\n validatedStateInput\n ? performOperation('transitioning CR state', handleTransition)\n (selectedTransitionCfg, validatedStateInput)\n : void 0\n }>\n {selectedTransitionCfg.title}\n </Button>\n : null}\n </div>\n );\n};\n\n\nexport function getPastTransitions(cr: CR.Base): [key: string, el: JSX.Element][] {\n const els: [key: string, el: JSX.Element][] = [];\n if (CR.hasSubmitterInput(cr)) {\n els.push(['Submitter input', <>{cr.justification}</>]);\n }\n if (CR.hasRegisterManagerInput(cr)) {\n els.push(['Register manager notes', <>{cr.registerManagerNotes}</>]);\n }\n if (CR.hasControlBodyInput(cr)) {\n els.push([\n 'Control body input',\n <>\n {cr.controlBodyNotes}\n <br />\n <em css={css`display: block;`}>Decision event: {cr.controlBodyDecisionEvent}</em>\n </>\n ]);\n }\n if (CR.hasAppealRequest(cr)) {\n els.push(['Reason for appeal', <>{cr.appealReason}</>]);\n }\n if (CR.hasRegisterOwnerInput(cr)) {\n els.push(['Register owner notes', <>{cr.registerOwnerNotes}</>]);\n }\n return els;\n}\n\n//export const PastTransitions: React.FC<{ cr: CR.Base }> = function ({ cr }) {\n// const els: JSX.Element[] = [];\n// if (CR.hasSubmitterInput(cr)) {\n// els.push(<SubmitterInputWidget value={cr} />);\n// }\n// if (CR.hasRegisterManagerInput(cr)) {\n// els.push(<RegisterManagerNotesWidget value={cr} />);\n// }\n// if (CR.hasControlBodyInput(cr)) {\n// els.push(<ControlBodyNotesWidget value={cr} />);\n// }\n// if (CR.hasAppealRequest(cr)) {\n// els.push(<AppealRequestWidget value={cr} />);\n// }\n// if (CR.hasRegisterOwnerInput(cr)) {\n// els.push(<RegisterOwnerNotesWidget value={cr} />);\n// }\n// return <>{els}</>;\n//}\n\n\ntype PossibleTransitionForCR<CR extends CR.Base> = [\n targetState: CR.StateType,\n cfg: CR.TransitionConfig<CR, CR.SomeCR, any>,\n];\n\n/**\n * Returns a list of transitions\n * that can be performed on given CR by given stakeholder.\n */\nexport function getTransitions<CR extends CR.Base>(\n cr: CR,\n stakeholder: RegisterStakeholder,\n): PossibleTransitionForCR<CR>[] {\n const possibleTransitions = TRANSITIONS[cr.state as keyof CR.Transitions];\n if (possibleTransitions) {\n return (\n (Object.entries(possibleTransitions) as PossibleTransitionForCR<CR>[]).\n filter(([, t]) => t.canBeTransitionedBy(stakeholder, cr))\n );\n } else {\n return [];\n }\n}\n\n\n/**\n * Returns True if there is no possible transition for given state.\n */\nexport function isFinalState(state: CR.StateType): boolean {\n return (Object.keys(TRANSITIONS[state as keyof CR.Transitions] ?? {})).length < 1;\n}\n\n\n// Transition runtime implementation\n\n// const draft: CR.Transition<\n// | CR.ReturnedForClarificationByControlBody\n// | CR.ReturnedForClarificationByManager\n// | CR.Drafted,\n// CR.Drafted,\n// CR.SubmitterInput> =\n// function (cr, { justification, items }) {\n// return {\n// ...cr,\n// justification,\n// timeEdited: new Date(),\n// items,\n// };\n// }\n// \n// const withdraw: CR.Transition<\n// CR.Proposed\n// | CR.SubmittedForControlBodyReview\n// | CR.ReturnedForClarificationByControlBody\n// | CR.ReturnedForClarificationByManager,\n// CR.Withdrawn> =\n// function withdraw (cr) {\n// return {\n// ...cr,\n// timeDisposed: new Date(),\n// };\n// }\n\n\nconst applyRegisterManagerDecision: CR.Transition<\n CR.Proposed,\n CR.SubmittedForControlBodyReview\n| CR.ReturnedForClarificationByManager,\n CR.RegisterManagerInput> =\nfunction applyRegisterManagerDecision (cr, { registerManagerNotes }) {\n if (!registerManagerNotes?.trim()) {\n throw new Error(\"Register manager note is required.\");\n }\n return {\n ...cr,\n registerManagerNotes,\n };\n}\n\n\nconst applyControlBodyDecision: CR.Transition<\n CR.SubmittedForControlBodyReview,\n CR.Accepted\n| CR.Rejected\n| CR.ReturnedForClarificationByControlBody,\n CR.ControlBodyInput> =\nfunction applyControlBodyDecision (cr, { controlBodyNotes, controlBodyDecisionEvent }) {\n if (!controlBodyNotes?.trim() || !controlBodyDecisionEvent?.trim()) {\n throw new Error(\"Control body notes and decision event are required.\");\n }\n return {\n ...cr,\n controlBodyNotes,\n controlBodyDecisionEvent,\n };\n}\n\n\nconst applyAppeal: CR.Transition<\n CR.Rejected,\n CR.Appealed,\n CR.AppealRequest> =\nfunction applyRegisterManagerDecision (cr, { appealReason }) {\n if (!appealReason?.trim()) {\n throw new Error(\"Appeal reason is required.\");\n }\n return {\n ...cr,\n appealReason,\n timeDisposed: undefined,\n };\n}\n\n\nconst applyRegisterOwnerDecision: CR.Transition<\n CR.Appealed,\n CR.AcceptedOnAppeal\n| CR.RejectionUpheld,\n CR.RegisterOwnerInput> =\nfunction applyRegisterManagerDecision (cr, { registerOwnerNotes }) {\n if (!registerOwnerNotes?.trim()) {\n throw new Error(\"Register owner note is required.\");\n }\n return {\n ...cr,\n registerOwnerNotes,\n timeDisposed: new Date(),\n };\n}\n\n\nconst WITHDRAWAL_TRANSITION:\nCR.TransitionConfig<CR.Withdrawable, CR.Withdrawn, null> = {\n title: \"Withdraw\",\n targetState: CR.State.WITHDRAWN,\n Widget: null,\n canBeTransitionedBy: CR.isSubmittedBy,\n func: (cr: CR.Withdrawable) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n} as const;\n\n\nconst SubmitterInputWidget: React.FC<{\n value: CR.SubmitterInput\n onChange?: (newVal: CR.SubmitterInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Justification:\">\n <TransitionInputTextArea\n required\n value={value.justification}\n onChange={(evt) =>\n onChange?.({ justification: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst TransitionInputTextArea: React.FC<TextAreaProps> = function (props) {\n return <TextArea\n fill\n css={css`resize: vertical;`}\n readOnly={!props.onChange}\n {...props}\n />;\n};\n\n\nconst PROPOSAL_TRANSITION:\nCR.TransitionConfig<CR.Proposable, CR.Proposed, CR.SubmitterInput> = {\n title: \"Propose\",\n targetState: CR.State.PROPOSED,\n canBeTransitionedBy: ((stakeholder, cr) =>\n CR.isSubmittedBy(stakeholder, cr) && Object.keys(cr.items).length > 0\n ),\n Widget: SubmitterInputWidget,\n func: (cr, submitterInput) => {\n if (!submitterInput?.justification?.trim()) {\n throw new Error(\"Justification is required.\");\n }\n return {\n ...cr,\n ...submitterInput,\n timeProposed: new Date(),\n }\n },\n}\n\n\nconst RegisterManagerNotesWidget: React.FC<{\n value: CR.RegisterManagerInput\n onChange?: (newVal: CR.RegisterManagerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register manager notes:\">\n <TransitionInputTextArea\n value={value.registerManagerNotes}\n required\n onChange={evt =>\n onChange?.({ registerManagerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst ControlBodyNotesWidget: React.FC<{\n value: CR.ControlBodyInput\n onChange?: (newVal: CR.ControlBodyInput) => void\n}> = function ({ value, onChange }) {\n return (\n <>\n <FormGroup label=\"Control body notes:\">\n <TransitionInputTextArea\n value={value.controlBodyNotes}\n required\n onChange={evt =>\n onChange?.({\n controlBodyNotes: evt.currentTarget.value,\n controlBodyDecisionEvent: value.controlBodyDecisionEvent,\n })\n }\n />\n </FormGroup>\n <FormGroup label=\"Control body decision event:\">\n <TransitionInputTextArea\n value={value.controlBodyDecisionEvent}\n required\n onChange={evt =>\n onChange?.({\n controlBodyNotes: value.controlBodyNotes,\n controlBodyDecisionEvent: evt.currentTarget.value,\n })\n }\n />\n </FormGroup>\n </>\n );\n};\n\n\nconst AppealRequestWidget: React.FC<{\n value: CR.AppealRequest\n onChange?: (newVal: CR.AppealRequest) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Appeal reasoning:\">\n <TransitionInputTextArea\n value={value.appealReason}\n required\n onChange={evt =>\n onChange?.({ appealReason: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nconst RegisterOwnerNotesWidget: React.FC<{\n value: CR.RegisterOwnerInput\n onChange?: (newVal: CR.RegisterOwnerInput) => void\n}> = function ({ value, onChange }) {\n return (\n <FormGroup label=\"Register owner notes:\">\n <TransitionInputTextArea\n value={value.registerOwnerNotes}\n required\n onChange={evt =>\n onChange?.({ registerOwnerNotes: evt.currentTarget.value })\n }\n />\n </FormGroup>\n );\n};\n\n\nexport const STATE_INTENT: { [key in CR.StateType]?: Intent } = {\n [CR.State.PROPOSED]: 'primary',\n [CR.State.RETURNED_FOR_CLARIFICATION]: 'primary',\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: 'primary',\n [CR.State.APPEALED]: 'warning',\n};\n\n\n\n/** Associates transition implementation with source/target states. */\nconst TRANSITIONS: CR.Transitions = {\n [CR.State.DRAFT]: {\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n },\n [CR.State.PROPOSED]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n title: \"Submit for control body review\",\n targetState: CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: applyRegisterManagerDecision,\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'manager'].indexOf(stakeholder.role) >= 0,\n Widget: RegisterManagerNotesWidget,\n func: applyRegisterManagerDecision,\n },\n },\n [CR.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n title: \"Return for clarification\",\n targetState: CR.State.RETURNED_FOR_CLARIFICATION,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: applyControlBodyDecision,\n },\n [CR.State.ACCEPTED]: {\n title: \"Accept\",\n targetState: CR.State.ACCEPTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n [CR.State.REJECTED]: {\n title: \"Reject\",\n targetState: CR.State.REJECTED,\n canBeTransitionedBy: (stakeholder) => ['owner', 'control-body'].indexOf(stakeholder.role) >= 0,\n Widget: ControlBodyNotesWidget,\n func: (cr, controlBodyInput) => ({\n ...applyControlBodyDecision(cr, controlBodyInput),\n timeDisposed: new Date(),\n }),\n },\n },\n [CR.State.RETURNED_FOR_CLARIFICATION]: {\n [CR.State.PROPOSED]: PROPOSAL_TRANSITION,\n [CR.State.WITHDRAWN]: WITHDRAWAL_TRANSITION,\n },\n [CR.State.REJECTED]: {\n [CR.State.APPEALED]: {\n title: \"Appeal\",\n targetState: CR.State.APPEALED,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: AppealRequestWidget,\n func: applyAppeal,\n },\n },\n [CR.State.APPEALED]: {\n [CR.State.APPEAL_WITHDRAWN]: {\n title: \"Withdraw appeal\",\n targetState: CR.State.APPEAL_WITHDRAWN,\n canBeTransitionedBy: CR.isSubmittedBy,\n Widget: null,\n func: (cr) => ({\n ...cr,\n timeDisposed: new Date(),\n }),\n },\n [CR.State.ACCEPTED_ON_APPEAL]: {\n title: \"Accept on appeal\",\n targetState: CR.State.ACCEPTED_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n [CR.State.REJECTION_UPHELD_ON_APPEAL]: {\n title: \"Uphold rejection\",\n targetState: CR.State.REJECTION_UPHELD_ON_APPEAL,\n canBeTransitionedBy: (stakeholder) => stakeholder.role === 'owner',\n Widget: RegisterOwnerNotesWidget,\n func: applyRegisterOwnerDecision,\n },\n },\n} as const;\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
/** @jsxFrag React.Fragment */
|
|
3
|
+
import React from 'react';
|
|
4
|
+
declare const _default: {
|
|
5
|
+
main: React.FC<{
|
|
6
|
+
uri: string;
|
|
7
|
+
}>;
|
|
8
|
+
title: React.FC<{
|
|
9
|
+
uri: string;
|
|
10
|
+
}>;
|
|
11
|
+
plainTitle: () => Promise<string>;
|
|
12
|
+
};
|
|
13
|
+
export default _default;
|