@riboseinc/paneron-registry-kit 2.2.10 → 2.2.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.
Files changed (102) hide show
  1. package/index.d.ts +2 -4
  2. package/index.js +18 -0
  3. package/index.js.map +1 -1
  4. package/package.json +2 -2
  5. package/site-builder/index.d.ts +3 -0
  6. package/site-builder/index.js +75 -0
  7. package/site-builder/index.js.map +1 -0
  8. package/site-builder/jsx-runtime.d.ts +18 -0
  9. package/site-builder/jsx-runtime.js +107 -0
  10. package/site-builder/jsx-runtime.js.map +1 -0
  11. package/site-builder/page.d.ts +6 -0
  12. package/site-builder/page.js +24 -0
  13. package/site-builder/page.js.map +1 -0
  14. package/types/cr.d.ts +22 -0
  15. package/types/cr.js +41 -1
  16. package/types/cr.js.map +1 -1
  17. package/types/item.d.ts +1 -1
  18. package/types/item.js.map +1 -1
  19. package/types/stakeholder.d.ts +3 -1
  20. package/types/stakeholder.js +20 -0
  21. package/types/stakeholder.js.map +1 -1
  22. package/types/util.d.ts +2 -0
  23. package/types/util.js.map +1 -1
  24. package/types/views.d.ts +22 -0
  25. package/types/views.js.map +1 -1
  26. package/views/AnnotatedChange.js +7 -5
  27. package/views/AnnotatedChange.js.map +1 -1
  28. package/views/BrowserCtx.d.ts +3 -11
  29. package/views/BrowserCtx.js +1 -0
  30. package/views/BrowserCtx.js.map +1 -1
  31. package/views/FilterCriteria/criteriaGroupToQueryExpression.d.ts +1 -1
  32. package/views/FilterCriteria/criteriaGroupToQueryExpression.js.map +1 -1
  33. package/views/FilterCriteria/models.d.ts +1 -1
  34. package/views/FilterCriteria/models.js.map +1 -1
  35. package/views/GenericRelatedItemView.js +11 -51
  36. package/views/GenericRelatedItemView.js.map +1 -1
  37. package/views/ItemDrawer.d.ts +11 -0
  38. package/views/ItemDrawer.js +69 -0
  39. package/views/ItemDrawer.js.map +1 -0
  40. package/views/SearchQuery.js +25 -14
  41. package/views/SearchQuery.js.map +1 -1
  42. package/views/change-request/ChangeProposalContext.d.ts +3 -0
  43. package/views/change-request/ChangeProposalContext.js +4 -0
  44. package/views/change-request/ChangeProposalContext.js.map +1 -0
  45. package/views/change-request/ChangeRequestContext.d.ts +18 -2
  46. package/views/change-request/ChangeRequestContext.js +29 -5
  47. package/views/change-request/ChangeRequestContext.js.map +1 -1
  48. package/views/change-request/Proposals.d.ts +2 -0
  49. package/views/change-request/Proposals.js +116 -80
  50. package/views/change-request/Proposals.js.map +1 -1
  51. package/views/change-request/State.d.ts +0 -0
  52. package/views/change-request/State.js +1 -0
  53. package/views/change-request/State.js.map +1 -0
  54. package/views/change-request/Summary.d.ts +12 -0
  55. package/views/change-request/Summary.js +59 -0
  56. package/views/change-request/Summary.js.map +1 -0
  57. package/views/change-request/TransitionHistory.d.ts +30 -0
  58. package/views/change-request/TransitionHistory.js +307 -0
  59. package/views/change-request/TransitionHistory.js.map +1 -0
  60. package/views/change-request/TransitionOptions.d.ts +38 -0
  61. package/views/{detail/ChangeRequest/transitions.js → change-request/TransitionOptions.js} +61 -51
  62. package/views/change-request/TransitionOptions.js.map +1 -0
  63. package/views/change-request/objectChangeset.d.ts +7 -4
  64. package/views/change-request/objectChangeset.js +60 -23
  65. package/views/change-request/objectChangeset.js.map +1 -1
  66. package/views/detail/ChangeRequest/index.js +129 -142
  67. package/views/detail/ChangeRequest/index.js.map +1 -1
  68. package/views/detail/RegisterHome/ActiveProposalDetails.d.ts +15 -0
  69. package/views/detail/RegisterHome/ActiveProposalDetails.js +104 -0
  70. package/views/detail/RegisterHome/ActiveProposalDetails.js.map +1 -0
  71. package/views/detail/RegisterHome/Block.d.ts +19 -0
  72. package/views/detail/RegisterHome/Block.js +49 -0
  73. package/views/detail/RegisterHome/Block.js.map +1 -0
  74. package/views/detail/RegisterHome/MetaSummary.d.ts +9 -0
  75. package/views/detail/RegisterHome/MetaSummary.js +39 -0
  76. package/views/detail/RegisterHome/MetaSummary.js.map +1 -0
  77. package/views/detail/RegisterHome/Proposal.d.ts +14 -0
  78. package/views/detail/RegisterHome/Proposal.js +296 -0
  79. package/views/detail/RegisterHome/Proposal.js.map +1 -0
  80. package/views/detail/RegisterHome/index.js +345 -141
  81. package/views/detail/RegisterHome/index.js.map +1 -1
  82. package/views/detail/RegisterItem/index.d.ts +2 -3
  83. package/views/detail/RegisterItem/index.js +238 -140
  84. package/views/detail/RegisterItem/index.js.map +1 -1
  85. package/views/detail/RegisterMeta/RegisterMetaForm.js +37 -45
  86. package/views/detail/RegisterMeta/RegisterMetaForm.js.map +1 -1
  87. package/views/detail/RegisterMeta/index.js +14 -11
  88. package/views/detail/RegisterMeta/index.js.map +1 -1
  89. package/views/diffing/InlineDiff.d.ts +27 -1
  90. package/views/diffing/InlineDiff.js +113 -2
  91. package/views/diffing/InlineDiff.js.map +1 -1
  92. package/views/hooks/useCustomView.js +1 -1
  93. package/views/hooks/useCustomView.js.map +1 -1
  94. package/views/index.js +4 -2
  95. package/views/index.js.map +1 -1
  96. package/views/sidebar/Search/index.js +12 -2
  97. package/views/sidebar/Search/index.js.map +1 -1
  98. package/views/util.d.ts +43 -6
  99. package/views/util.js +240 -11
  100. package/views/util.js.map +1 -1
  101. package/views/detail/ChangeRequest/transitions.d.ts +0 -28
  102. package/views/detail/ChangeRequest/transitions.js.map +0 -1
@@ -5,200 +5,404 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _react = _interopRequireWildcard(require("react"));
8
+ var _react = require("react");
9
9
 
10
10
  var _react2 = require("@emotion/react");
11
11
 
12
- var _core = require("@blueprintjs/core");
13
-
14
12
  var _context = require("@riboseinc/paneron-extension-kit/context");
15
13
 
16
14
  var _context2 = require("@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context");
17
15
 
18
16
  var _BrowserCtx = require("../../BrowserCtx");
19
17
 
20
- var _RegisterStakeholder = require("../../RegisterStakeholder");
18
+ var _ChangeRequestContext = require("../../change-request/ChangeRequestContext");
19
+
20
+ var _itemPathUtils = require("../../itemPathUtils");
21
21
 
22
22
  var _objectChangeset = require("../../change-request/objectChangeset");
23
23
 
24
24
  var _cr = require("../../../types/cr");
25
25
 
26
+ var _stakeholder = require("../../../types/stakeholder");
27
+
26
28
  var _protocolRegistry = require("../../protocolRegistry");
27
29
 
28
- var _itemPathUtils = require("../../itemPathUtils");
30
+ var _MetaSummary = _interopRequireDefault(require("./MetaSummary"));
31
+
32
+ var _util = require("../../util");
33
+
34
+ var _Proposal = require("./Proposal");
29
35
 
30
- 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); }
36
+ var _Block = _interopRequireDefault(require("./Block"));
31
37
 
32
- 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; }
38
+ var _ActiveProposalDetails = _interopRequireDefault(require("./ActiveProposalDetails"));
39
+
40
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
41
 
34
42
  /** @jsx jsx */
35
43
 
36
44
  /** @jsxFrag React.Fragment */
37
45
  //import { Helmet } from 'react-helmet';
38
46
  const RegisterHome = function () {
39
- var _a, _b, _c, _d;
47
+ var _a;
40
48
 
41
49
  const {
42
50
  spawnTab
43
51
  } = (0, _react.useContext)(_context2.TabbedWorkspaceContext);
44
52
  const {
45
- customViews,
46
53
  registerMetadata,
47
54
  stakeholder,
48
- offline,
49
- itemClasses
55
+ itemClasses,
56
+ setActiveChangeRequestID
50
57
  } = (0, _react.useContext)(_BrowserCtx.BrowserCtx);
58
+ const {
59
+ changeRequest: activeCR,
60
+ canDelete,
61
+ deleteCR
62
+ } = (0, _react.useContext)(_ChangeRequestContext.ChangeRequestContext);
51
63
  const {
52
64
  requestFileFromFilesystem,
53
65
  makeRandomID,
54
66
  getObjectData,
55
67
  updateObjects,
56
68
  performOperation,
57
- getMapReducedData
69
+ isBusy,
70
+ getMapReducedData,
71
+ useMapReducedData
58
72
  } = (0, _react.useContext)(_context.DatasetContext);
59
- const [newProposalIdea, setNewProposalIdea] = (0, _react.useState)('');
60
73
  const registerVersion = registerMetadata === null || registerMetadata === void 0 ? void 0 : registerMetadata.version;
61
- const canCreateCR = stakeholder && stakeholder.role && ((_a = stakeholder.gitServerUsername) === null || _a === void 0 ? void 0 : _a.trim()) !== '' && makeRandomID && updateObjects && ((_b = registerVersion === null || registerVersion === void 0 ? void 0 : registerVersion.id) !== null && _b !== void 0 ? _b : '').trim() !== '';
62
-
63
- async function createCR(justification) {
64
- if (canCreateCR) {
65
- const id = await makeRandomID();
66
- await updateObjects({
67
- commitMessage: "start new proposal",
68
- objectChangeset: (0, _objectChangeset.newCRObjectChangeset)(id, justification, registerVersion, stakeholder.gitServerUsername)
69
- });
70
- return id;
74
+ const getNewEmptyCRChangeset = (0, _react.useMemo)(() => {
75
+ if (makeRandomID && stakeholder && (0, _stakeholder.canCreateCR)(stakeholder)) {
76
+ return async function getNewEmptyCRChangeset(newIdea) {
77
+ const crID = await makeRandomID();
78
+ return [(0, _objectChangeset.newCRObjectChangeset)(crID, newIdea, registerVersion, stakeholder.gitServerUsername), crID];
79
+ };
71
80
  } else {
72
- throw new Error("Unable to create proposal: read-only dataset");
81
+ return undefined;
73
82
  }
74
- }
83
+ }, [makeRandomID, stakeholder, registerVersion]);
84
+ const getImportedCRChangeset = (0, _react.useMemo)(() => {
85
+ if (requestFileFromFilesystem && stakeholder && (0, _stakeholder.canImportCR)(stakeholder)) {
86
+ return async function getImportedCRChangeset() {
87
+ const data = await requestFileFromFilesystem({
88
+ prompt: "Select one register proposal JSON file",
89
+ filters: [{
90
+ name: "JSON files",
91
+ extensions: ['.json']
92
+ }]
93
+ });
94
+ const fileData = Object.values(data)[0];
75
95
 
76
- async function handleNewProposal() {
77
- if (newProposalIdea) {
78
- const crID = await performOperation("creating proposal", createCR)(newProposalIdea);
79
- setNewProposalIdea('');
80
- spawnTab(`${_protocolRegistry.Protocols.CHANGE_REQUEST}:${(0, _itemPathUtils.crIDToCRPath)(crID)}`);
81
- }
82
- }
96
+ if (!fileData) {
97
+ throw new Error("No file was selected");
98
+ }
83
99
 
84
- async function getCRImportChangeset() {
85
- if (!requestFileFromFilesystem) {
86
- throw new Error("Cannot request file from filesystem");
87
- }
100
+ if ((0, _cr.isImportableCR)(fileData)) {
101
+ try {
102
+ const [changeset, crID] = await (0, _objectChangeset.importedProposalToCRObjectChangeset)(fileData, itemClasses, stakeholder.gitServerUsername, getObjectData, async function resolvePredicates(predicates) {
103
+ const mapReduceChains = [...predicates.values()].map(predicate => ({
104
+ [predicate]: {
105
+ mapFunc: `
106
+ const data = value.data;
107
+ if (!key.startsWith('/proposals/') && data && (${predicate})) {
108
+ emit({ objectPath: key, objectData: value });
109
+ }
110
+ `
111
+ }
112
+ })).reduce((prev, curr) => ({ ...prev,
113
+ ...curr
114
+ }), {});
115
+ const result = await getMapReducedData({
116
+ chains: mapReduceChains
117
+ });
118
+ return Object.entries(result).map(([chainLabel, chainResult]) => {
119
+ const objects = Array.isArray(chainResult) ? chainResult : [];
88
120
 
89
- const data = await requestFileFromFilesystem({
90
- prompt: "Select one register proposal JSON file",
91
- filters: [{
92
- name: "JSON files",
93
- extensions: ['.json']
94
- }]
95
- });
96
- const fileData = Object.values(data)[0];
97
-
98
- if (!fileData) {
99
- throw new Error("No file was selected");
121
+ if (objects.length < 1) {
122
+ throw new Error(`Unable to resolve predicate to item UUID: no item found matching predicate ${chainLabel}`);
123
+ } else if (objects.length > 1) {
124
+ const objectOverview = objects.map(o => JSON.stringify(o)).join(', ');
125
+ throw new Error(`Unable to resolve predicate to item UUID: more than one item matches predicate ${chainLabel}: ${objectOverview}`);
126
+ } else {
127
+ return {
128
+ // There’s just one item anyway, hence `objects[0]`.
129
+ [chainLabel]: (0, _itemPathUtils.itemPathToItemRef)(false, objects[0].objectPath)
130
+ };
131
+ }
132
+ }).reduce((prev, curr) => ({ ...prev,
133
+ ...curr
134
+ }), {});
135
+ });
136
+ return [changeset, crID];
137
+ } catch (e) {
138
+ console.error("Error reading proposal data", e);
139
+ throw new Error("Error reading proposal data");
140
+ }
141
+ } else {
142
+ throw new Error("Invalid proposal format");
143
+ }
144
+ };
145
+ } else {
146
+ return undefined;
100
147
  }
148
+ }, [getMapReducedData, requestFileFromFilesystem, getObjectData, stakeholder]);
149
+ const [importCR, createCR] = (0, _react.useMemo)(() => {
150
+ if (updateObjects && setActiveChangeRequestID && !isBusy) {
151
+ return [getImportedCRChangeset ? performOperation('importing proposal', async function () {
152
+ const [objectChangeset, crID] = await getImportedCRChangeset();
153
+ await updateObjects({
154
+ commitMessage: 'import proposal',
155
+ objectChangeset
156
+ });
157
+ setActiveChangeRequestID(crID);
158
+ }) : undefined, getNewEmptyCRChangeset ? performOperation('creating blank proposal', async function (newIdea) {
159
+ const [objectChangeset, crID] = await getNewEmptyCRChangeset(newIdea);
160
+ await updateObjects({
161
+ commitMessage: `start new empty proposal ${newIdea}`,
162
+ objectChangeset
163
+ });
164
+ setActiveChangeRequestID(crID);
165
+ }) : undefined];
166
+ } else {
167
+ return [undefined, undefined];
168
+ }
169
+ }, [isBusy, performOperation, updateObjects, getImportedCRChangeset, getNewEmptyCRChangeset]); // Actionable proposals v2
101
170
 
102
- if ((0, _cr.isImportableCR)(fileData)) {
103
- const crID = fileData.proposalDraft.id;
104
-
105
- try {
106
- const changeset = await (0, _objectChangeset.importedProposalToCRObjectChangeset)(fileData, itemClasses, stakeholder.gitServerUsername, getObjectData, async function findObjects(predicate) {
107
- const result = await getMapReducedData({
108
- chains: {
109
- _: {
110
- mapFunc: `
111
- const data = value.data;
112
- if (data && (${predicate})) {
113
- emit({ objectPath: key, objectData: value });
114
- }
115
- `
116
- }
117
- }
118
- }); // NOTE: map returns an empty object if there’re no items,
119
- // but we promise to return a list.
120
-
121
- if (!Array.isArray(result._)) {
122
- return [];
123
- }
171
+ const proposalGroups = (0, _react.useMemo)(() => (stakeholder === null || stakeholder === void 0 ? void 0 : stakeholder.role) ? getActionableProposalGroupsForRole(stakeholder.role) : null, [stakeholder === null || stakeholder === void 0 ? void 0 : stakeholder.role]);
172
+ const actionableProposalsResult = useMapReducedData({
173
+ chains: (proposalGroups !== null && proposalGroups !== void 0 ? proposalGroups : []).map(([label,, queryGetter]) => {
174
+ const query = queryGetter(stakeholder);
175
+ const predicateFunc = `
176
+ const objPath = key, obj = value;
177
+ return ((${CR_BASE_QUERY}) && (${query}));
178
+ `;
179
+ const mapFunc = `emit(value);`;
180
+ return {
181
+ [label]: {
182
+ mapFunc,
183
+ predicateFunc
184
+ }
185
+ };
186
+ }).reduce((prev, curr) => ({ ...prev,
187
+ ...curr
188
+ }), {})
189
+ });
190
+ const actionableProposals = (0, _react.useMemo)(() => Object.entries(actionableProposalsResult.value).map(([chainID, chainResult]) => [chainID, (Array.isArray(chainResult) ? chainResult : undefined) || undefined]), [actionableProposalsResult.value]);
191
+ const handleRefreshProposals = actionableProposalsResult.refresh; // TODO: Move to action bar
192
+ // const customActions = useMemo(() => customViews.map(cv => ({
193
+ // key: cv.id,
194
+ // text: cv.label,
195
+ // title: cv.description,
196
+ // icon: cv.icon,
197
+ // onClick: () => spawnTab(`${Protocols.CUSTOM_VIEW}:${cv.id}/index`),
198
+ // })), [spawnTab, customViews]);
124
199
 
125
- return result._;
200
+ const [createMode, setCreateMode] = (0, _react.useState)(false); //const canStakeholderCreateCRs = stakeholder && canCreateCR(stakeholder);
201
+
202
+ const handleSelectProposal = (0, _react.useMemo)(() => {
203
+ return setActiveChangeRequestID && !isBusy ? function (crid) {
204
+ setActiveChangeRequestID === null || setActiveChangeRequestID === void 0 ? void 0 : setActiveChangeRequestID(crid);
205
+ } : undefined;
206
+ }, [setActiveChangeRequestID, isBusy]);
207
+ const proposalBlockActions = (0, _react.useMemo)(() => {
208
+ const actions = [];
209
+
210
+ if (activeCR) {
211
+ actions.push({
212
+ text: "Export proposal",
213
+ onClick: () => void 0,
214
+ icon: 'export',
215
+ disabled: true
216
+ });
217
+ actions.push({
218
+ text: "Exit proposal",
219
+ icon: 'log-out',
220
+ intent: 'danger',
221
+ disabled: isBusy,
222
+ onClick: setActiveChangeRequestID ? () => setActiveChangeRequestID === null || setActiveChangeRequestID === void 0 ? void 0 : setActiveChangeRequestID(null) : undefined
223
+ });
224
+ } else {
225
+ if (stakeholder && (0, _stakeholder.canCreateCR)(stakeholder)) {
226
+ actions.push({
227
+ text: "Create blank proposal",
228
+ onClick: !createMode ? () => setCreateMode(true) : undefined,
229
+ disabled: !createCR,
230
+ active: createMode,
231
+ selected: createMode,
232
+ icon: 'add',
233
+ intent: actionableProposals.length < 1 ? 'primary' : undefined
234
+ });
235
+ }
236
+
237
+ if (stakeholder && (0, _stakeholder.canImportCR)(stakeholder)) {
238
+ actions.push({
239
+ text: "Import proposal",
240
+ onClick: importCR,
241
+ disabled: !importCR || createMode,
242
+ icon: 'import',
243
+ intent: actionableProposals.length < 1 ? 'primary' : undefined
126
244
  });
127
- return [changeset, crID];
128
- } catch (e) {
129
- throw new Error("Error reading proposal data");
130
245
  }
131
- } else {
132
- throw new Error("Invalid proposal format");
133
246
  }
134
- }
135
247
 
136
- async function handleImportProposal() {
137
- const [objectChangeset, crID] = await performOperation('reading proposal data', getCRImportChangeset)();
138
- await performOperation('creating proposal', updateObjects !== null && updateObjects !== void 0 ? updateObjects : async () => {
139
- throw new Error("Read-only dataset");
140
- })({
141
- commitMessage: "import proposal",
142
- objectChangeset
143
- });
144
- setNewProposalIdea('');
145
- spawnTab(`${_protocolRegistry.Protocols.CHANGE_REQUEST}:${(0, _itemPathUtils.crIDToCRPath)(crID)}`);
146
- }
248
+ return actions;
249
+ }, [!activeCR, createMode, importCR, createCR, isBusy, actionableProposals.length < 1]);
250
+ const handleCreate = (0, _react.useMemo)(() => createCR && createMode ? async function (idea) {
251
+ if (idea && createCR) {
252
+ await createCR(idea);
253
+ }
147
254
 
148
- const menu = (0, _react2.jsx)(_core.Menu, {
149
- css: (0, _react2.css)`margin: 10px;`
150
- }, (0, _react2.jsx)(_core.MenuDivider, {
151
- title: "Quick links"
152
- }), customViews.map((cv, _) => (0, _react2.jsx)(_core.MenuItem, {
153
- key: cv.id,
154
- text: cv.label,
155
- title: cv.description,
156
- icon: cv.icon,
157
- onClick: () => spawnTab(`${_protocolRegistry.Protocols.CUSTOM_VIEW}:${cv.id}/index`)
158
- })), customViews.length > 0 ? (0, _react2.jsx)(_core.MenuDivider, null) : null, (0, _react2.jsx)(_core.MenuItem, {
159
- text: `Propose a change to version ${(_d = (_c = registerMetadata === null || registerMetadata === void 0 ? void 0 : registerMetadata.version) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : '(missing)'}`,
160
- disabled: !canCreateCR,
161
- icon: "lightbulb",
162
- title: canCreateCR ? "A blank proposal will be created and opened in a new tab." : undefined
163
- }, (0, _react2.jsx)(_core.InputGroup, {
164
- value: newProposalIdea || undefined,
165
- placeholder: "Your idea\u2026",
166
- title: "Justification draft (you can change this later)",
167
- onChange: evt => setNewProposalIdea(evt.currentTarget.value),
168
- rightElement: (0, _react2.jsx)(_core.Button, {
169
- small: true,
170
- intent: newProposalIdea ? 'primary' : undefined,
171
- disabled: !newProposalIdea,
172
- onClick: handleNewProposal,
173
- icon: "tick"
174
- })
175
- })), (0, _react2.jsx)(_core.MenuItem, {
176
- text: "Import proposal",
177
- icon: "import",
178
- disabled: !canCreateCR,
179
- onClick: handleImportProposal
180
- }), (0, _react2.jsx)(_core.MenuItem, {
181
- text: "View register metadata",
182
- icon: "properties",
183
- onClick: () => spawnTab(_protocolRegistry.Protocols.REGISTER_META)
184
- }));
185
- const intro = (0, _react2.jsx)(_core.Callout, {
186
- intent: "primary",
187
- css: (0, _react2.css)`text-align: left;`
188
- }, stakeholder ? (0, _react2.jsx)(_react.default.Fragment, null, "You can create proposals as ", (0, _RegisterStakeholder.registerStakeholderPlain)(stakeholder), ".") : offline ? (0, _react2.jsx)(_react.default.Fragment, null, "Because this repository is offline (no remote configured), and remote username is currently required for proposal, you cannot create proposals.") : (0, _react2.jsx)(_react.default.Fragment, null, "Since your remote username is not in the list of stakeholders, you cannot create proposals currently."));
189
- const greeting = registerMetadata ? (0, _react2.jsx)(_core.NonIdealState, {
190
- title: `Welcome to ${registerMetadata.name}`,
191
- description: (0, _react2.jsx)(_react.default.Fragment, null, intro, menu)
192
- }) : registerMetadata === undefined ? (0, _react2.jsx)(_core.NonIdealState, {
193
- icon: (0, _react2.jsx)(_core.Spinner, null),
194
- description: "Loading register information\u2026"
195
- }) : (0, _react2.jsx)(_core.NonIdealState, {
196
- icon: "heart-broken",
197
- title: "Register metadata is missing or invalid.",
198
- description: (0, _react2.jsx)(_react.default.Fragment, null, menu)
199
- });
200
- return greeting;
255
+ setCreateMode(false);
256
+ } : undefined, [createMode, createCR]);
257
+ const proposalBlock = (0, _react.useMemo)(() => {
258
+ if (registerMetadata
259
+ /*&& actionableProposals.find(p => p[1] && p[1].length > 0)*/
260
+ ) {
261
+ return (0, _react2.jsx)(_Block.default, {
262
+ View: _Proposal.Proposals,
263
+ key: "proposal dashboard",
264
+ description: "Actionable proposals",
265
+ css: (0, _react2.css)`
266
+ height: 300px;
267
+ flex-basis: calc(50% - 10px);
268
+ flex-grow: 1;
269
+ `,
270
+ props: {
271
+ register: registerMetadata,
272
+ actionableProposals,
273
+ createMode,
274
+ onCreate: handleCreate,
275
+ onRefreshProposals: handleRefreshProposals,
276
+ onSelectProposal: handleSelectProposal
277
+ },
278
+ actions: proposalBlockActions
279
+ });
280
+ } else {
281
+ return null;
282
+ }
283
+ }, [createMode, registerMetadata, proposalBlockActions, handleSelectProposal, handleCreate, handleRefreshProposals, actionableProposals]);
284
+ const handleOpenProposal = (0, _react.useMemo)(() => {
285
+ return activeCR ? async () => spawnTab(`${_protocolRegistry.Protocols.CHANGE_REQUEST}:${(0, _itemPathUtils.crIDToCRPath)(activeCR.id)}`) : undefined;
286
+ }, [spawnTab, activeCR === null || activeCR === void 0 ? void 0 : activeCR.id]);
287
+ const activeCRBlock = (0, _react.useMemo)(() => {
288
+ if (activeCR && registerMetadata) {
289
+ return (0, _react2.jsx)(_ActiveProposalDetails.default, {
290
+ proposal: activeCR,
291
+ stakeholder: stakeholder,
292
+ register: registerMetadata,
293
+ onOpen: handleOpenProposal,
294
+ onDelete: deleteCR,
295
+ canDelete: canDelete,
296
+ css: (0, _react2.css)`
297
+ height: 300px;
298
+ flex-basis: calc(50% - 10px);
299
+ flex-grow: 1;
300
+ `
301
+ });
302
+ } else {
303
+ return null;
304
+ }
305
+ }, [activeCR, registerMetadata, canDelete, deleteCR, handleOpenProposal, stakeholder]);
306
+ const registerMetaBlock = (0, _react.useMemo)(() => {
307
+ if (!activeCRBlock && stakeholder) {
308
+ return (0, _react2.jsx)(_Block.default, {
309
+ View: _MetaSummary.default,
310
+ description: "Register summary",
311
+ props: registerMetadata ? {
312
+ register: registerMetadata,
313
+ style: {
314
+ padding: '10px 12px 0 12px',
315
+ flexGrow: 1,
316
+ overflowY: 'auto'
317
+ }
318
+ } : registerMetadata,
319
+ error: registerMetadata === null ? "Failed to load register metadata" : undefined,
320
+ css: (0, _react2.css)`
321
+ height: 300px;
322
+ flex-basis: calc(50% - 10px);
323
+ flex-grow: 1;
324
+ `,
325
+ actions: [{
326
+ text: "View or edit register metadata",
327
+ onClick: () => spawnTab(_protocolRegistry.Protocols.REGISTER_META),
328
+ icon: 'properties'
329
+ }]
330
+ });
331
+ } else {
332
+ return null;
333
+ }
334
+ }, [!activeCRBlock, registerMetadata, stakeholder]);
335
+ return (0, _react2.jsx)(_util.TabContentsWithHeader, {
336
+ title: (_a = registerMetadata === null || registerMetadata === void 0 ? void 0 : registerMetadata.name) !== null && _a !== void 0 ? _a : 'Register',
337
+ layout: "card-grid"
338
+ }, activeCRBlock !== null && activeCRBlock !== void 0 ? activeCRBlock : registerMetaBlock, proposalBlock);
201
339
  };
202
340
 
203
341
  var _default = RegisterHome;
204
- exports.default = _default;
342
+ exports.default = _default;
343
+
344
+ function getActionableProposalGroupsForRole(role) {
345
+ return CR_QUERIES_FOR_ROLES.filter(([, roles]) => roles.has(role));
346
+ }
347
+
348
+ const CR_BASE_QUERY = 'objPath.indexOf("/proposals/") === 0 && objPath.endsWith("main.yaml")';
349
+ const CR_QUERIES_FOR_ROLES = [['My Drafts', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
350
+ if (stakeholder && stakeholder.gitServerUsername) {
351
+ const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
352
+ const query = `(obj.state === "${_cr.State.DRAFT}" || obj.state === "${_cr.State.RETURNED_FOR_CLARIFICATION}") && (${stakeholderCondition})`;
353
+ return query;
354
+ } else {
355
+ return 'false';
356
+ }
357
+ }], ['My Rejected', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
358
+ // Rejections are actionable because they can be appealed by the submitter.
359
+ if (stakeholder && stakeholder.gitServerUsername) {
360
+ const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
361
+ const query = `(obj.state === "${_cr.State.REJECTED}") && (${stakeholderCondition})`;
362
+ return query;
363
+ } else {
364
+ return 'false';
365
+ }
366
+ }], ['Everyone’s Drafts or Returned', new Set(['manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
367
+ if (stakeholder && stakeholder.gitServerUsername) {
368
+ const stakeholderCondition = `obj.submittingStakeholderGitServerUsername !== "${stakeholder.gitServerUsername}"`;
369
+ const query = `(obj.state === "${_cr.State.DRAFT}" || obj.state === "${_cr.State.RETURNED_FOR_CLARIFICATION}") && (${stakeholderCondition})`;
370
+ return query;
371
+ } else {
372
+ return 'false';
373
+ }
374
+ }], // ['latest reviewed', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
375
+ // // TODO: Should filter only rejected perhaps?
376
+ // // Approved/accepted proposals can be shown in another (public) area.
377
+ // if (stakeholder && stakeholder.gitServerUsername) {
378
+ // const stakeholderCondition = stakeholder?.role !== 'submitter'
379
+ // ? 'true'
380
+ // : `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
381
+ // // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.
382
+ // const query = `(obj.state === "${State.ACCEPTED} || obj.state === "${State.REJECTED} || obj.state === "${State.REJECTION_UPHELD_ON_APPEAL}"") && ${stakeholderCondition}`;
383
+ // return query;
384
+ // } else {
385
+ // return 'false';
386
+ // }
387
+ // // TODO: Implement limit
388
+ // }],
389
+ // ['latest withdrawn', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
390
+ // if (stakeholder && stakeholder.gitServerUsername) {
391
+ // const stakeholderCondition = stakeholder?.role !== 'submitter'
392
+ // ? 'true'
393
+ // : `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
394
+ // // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.
395
+ // const query = `(obj.state === "${State.WITHDRAWN}" || obj.state === "${State.APPEAL_WITHDRAWN}") && ${stakeholderCondition}`;
396
+ // return query;
397
+ // } else {
398
+ // return 'false';
399
+ // }
400
+ // // TODO: Implement limit
401
+ // }],
402
+ ['Pending Owner Appeal Review', new Set(['owner']), function ownerProposals() {
403
+ return `obj.state === "${_cr.State.APPEALED}"`;
404
+ }], ['Pending Control Body Review', new Set(['control-body', 'owner']), function cbProposals() {
405
+ return `obj.state === "${_cr.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW}"`;
406
+ }], ['Pending Manager Review', new Set(['manager', 'control-body', 'owner']), function managerProposals() {
407
+ return `obj.state === "${_cr.State.PROPOSED}"`;
408
+ }]];