@riboseinc/paneron-registry-kit 2.2.29 → 2.2.31
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/index.d.ts +4 -1
- package/index.js +26 -0
- package/index.js.map +1 -1
- package/item-classes/Tree.d.ts +5 -0
- package/item-classes/Tree.js +115 -0
- package/item-classes/Tree.js.map +1 -0
- package/item-classes/treeNodes.d.ts +12 -0
- package/item-classes/treeNodes.js +68 -0
- package/item-classes/treeNodes.js.map +1 -0
- package/package.json +2 -2
- package/proposals/actionableGroups/Tree.d.ts +7 -0
- package/proposals/actionableGroups/Tree.js +179 -0
- package/proposals/actionableGroups/Tree.js.map +1 -0
- package/proposals/actionableGroups/queries.d.ts +5 -0
- package/proposals/actionableGroups/queries.js +81 -0
- package/proposals/actionableGroups/queries.js.map +1 -0
- package/proposals/actionableGroups/treeNodes.d.ts +26 -0
- package/proposals/actionableGroups/treeNodes.js +94 -0
- package/proposals/actionableGroups/treeNodes.js.map +1 -0
- package/proposals/actionableGroups/types.d.ts +6 -0
- package/proposals/actionableGroups/types.js +5 -0
- package/proposals/actionableGroups/types.js.map +1 -0
- package/types/cr.d.ts +2 -1
- package/types/cr.js.map +1 -1
- package/types/item.d.ts +4 -1
- package/types/item.js.map +1 -1
- package/types/register.d.ts +4 -1
- package/types/register.js.map +1 -1
- package/types/stakeholder.d.ts +24 -41
- package/types/stakeholder.js +48 -16
- package/types/stakeholder.js.map +1 -1
- package/types/views.d.ts +4 -0
- package/types/views.js.map +1 -1
- package/views/BrowserCtx.d.ts +1 -1
- package/views/BrowserCtx.js.map +1 -1
- package/views/GenericRelatedItemView.js +21 -8
- package/views/GenericRelatedItemView.js.map +1 -1
- package/views/ItemDetailsDrawer.d.ts +1 -0
- package/views/ItemDetailsDrawer.js +4 -2
- package/views/ItemDetailsDrawer.js.map +1 -1
- package/views/ItemSearchDrawer.js +1 -1
- package/views/ItemSearchDrawer.js.map +1 -1
- package/views/Party.d.ts +0 -0
- package/views/Party.js +154 -0
- package/views/Party.js.map +1 -0
- package/views/RegisterStakeholder.js +2 -2
- package/views/RegisterStakeholder.js.map +1 -1
- package/views/StatefulTree.d.ts +19 -0
- package/views/StatefulTree.js +128 -0
- package/views/StatefulTree.js.map +1 -0
- package/views/change-request/ChangeRequestContext.js.map +1 -1
- package/views/change-request/TransitionHistory.js +6 -3
- package/views/change-request/TransitionHistory.js.map +1 -1
- package/views/change-request/TransitionOptions.js +37 -13
- package/views/change-request/TransitionOptions.js.map +1 -1
- package/views/detail/RegisterHome/index.js +20 -79
- package/views/detail/RegisterHome/index.js.map +1 -1
- package/views/detail/RegisterItem/index.d.ts +2 -2
- package/views/detail/RegisterItem/index.js +21 -14
- package/views/detail/RegisterItem/index.js.map +1 -1
- package/views/detail/RegisterItemClass.d.ts +12 -0
- package/views/detail/RegisterItemClass.js +98 -0
- package/views/detail/RegisterItemClass.js.map +1 -0
- package/views/detail/RegisterMeta/RegisterMetaForm.js +272 -114
- package/views/detail/RegisterMeta/RegisterMetaForm.js.map +1 -1
- package/views/detail/RegisterMeta/index.js +1 -1
- package/views/detail/RegisterMeta/index.js.map +1 -1
- package/views/hooks/useStakeholder.d.ts +0 -0
- package/views/hooks/useStakeholder.js +1 -0
- package/views/hooks/useStakeholder.js.map +1 -0
- package/views/index.d.ts +1 -0
- package/views/index.js +71 -8
- package/views/index.js.map +1 -1
- package/views/protocolRegistry.d.ts +1 -0
- package/views/protocolRegistry.js +4 -0
- package/views/protocolRegistry.js.map +1 -1
- package/views/sidebar/Browse/index.js +8 -44
- package/views/sidebar/Browse/index.js.map +1 -1
- package/views/sidebar/Registration/index.js.map +1 -1
- package/views/sidebar/index.d.ts +2 -1
- package/views/sidebar/index.js +77 -62
- package/views/sidebar/index.js.map +1 -1
- package/views/util.d.ts +5 -0
- package/views/util.js +42 -4
- package/views/util.js.map +1 -1
package/index.d.ts
CHANGED
|
@@ -12,4 +12,7 @@ import CRITERIA_CONFIGURATION from './views/FilterCriteria/CRITERIA_CONFIGURATIO
|
|
|
12
12
|
import useSingleRegisterItemData from './views/hooks/useSingleRegisterItemData';
|
|
13
13
|
import { isAddition } from './types/proposal';
|
|
14
14
|
import type { Payload } from './types/item';
|
|
15
|
-
|
|
15
|
+
import { Protocols } from './views/protocolRegistry';
|
|
16
|
+
import { ChangeRequestContext } from './views/change-request/ChangeRequestContext';
|
|
17
|
+
import RegisterHome from './views/detail/RegisterHome';
|
|
18
|
+
export { itemRefToItemPath, itemPathToItemRef, itemPathInCR, incompleteItemRefToItemPathPrefix, BrowserCtx, CRITERIA_CONFIGURATION, GenericRelatedItemView, PropertyDetailView, useSingleRegisterItemData, isAddition, Payload, Protocols, ChangeRequestContext, RegisterHome, };
|
package/index.js
CHANGED
|
@@ -63,6 +63,24 @@ Object.defineProperty(exports, "isAddition", {
|
|
|
63
63
|
return _proposal.isAddition;
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
|
+
Object.defineProperty(exports, "Protocols", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _protocolRegistry.Protocols;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "ChangeRequestContext", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _ChangeRequestContext.ChangeRequestContext;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "RegisterHome", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _RegisterHome.default;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
66
84
|
exports.makeRegistryExtension = void 0;
|
|
67
85
|
|
|
68
86
|
var _react = _interopRequireDefault(require("react"));
|
|
@@ -89,6 +107,12 @@ var _useSingleRegisterItemData = _interopRequireDefault(require("./views/hooks/u
|
|
|
89
107
|
|
|
90
108
|
var _proposal = require("./types/proposal");
|
|
91
109
|
|
|
110
|
+
var _protocolRegistry = require("./views/protocolRegistry");
|
|
111
|
+
|
|
112
|
+
var _ChangeRequestContext = require("./views/change-request/ChangeRequestContext");
|
|
113
|
+
|
|
114
|
+
var _RegisterHome = _interopRequireDefault(require("./views/detail/RegisterHome"));
|
|
115
|
+
|
|
92
116
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
93
117
|
|
|
94
118
|
const makeRegistryExtension = function (opts) {
|
|
@@ -115,7 +139,9 @@ const makeRegistryExtension = function (opts) {
|
|
|
115
139
|
const mainView = function _RegistryView() {
|
|
116
140
|
return _react.default.createElement(_views.RegistryView, {
|
|
117
141
|
itemClassConfiguration: opts.itemClassConfiguration,
|
|
142
|
+
itemClassGroups: opts.itemClassGroups,
|
|
118
143
|
subregisters: opts.subregisters,
|
|
144
|
+
CustomWorkspace: opts.CustomWorkspace,
|
|
119
145
|
defaultSearchCriteria: opts.defaultSearchCriteria,
|
|
120
146
|
keyExpression: opts.keyExpression,
|
|
121
147
|
getQuickSearchPredicate: opts.getQuickSearchPredicate,
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEjE,OAAO,aAAa,MAAM,wDAAwD,CAAC;AAInF,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,CAAC,MAAM,qBAAqB,GAA2B,UAAU,IAAI;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE;QAC5D,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACtD,MAAM,IAAI,GAAG,IAAW,CAAC;YACzB,IAAI,IAAI,EAAE;gBACR,GAAG,CAAC,KAAK,CAAC,MAAoD,CAAC,GAAG,SAAS,uBAAuB,CAAC,KAAK;oBACtG,OAAO,CACL,oBAAC,aAAa,IACV,QAAQ,EAAE,mBAAmB,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAC7C,MAAM,EAAE,MAAM,KAAK,cAAc;wBACnC,oBAAC,IAAI,OAAK,KAAK,GAAI,CACL,CACjB,CAAC;gBACJ,CAAC,CAAC;aACH;SACF;KACF;IAED,MAAM,QAAQ,GAAoC,SAAS,aAAa;QACtE,OAAO,CACL,oBAAC,YAAY,IACX,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,EACnD,YAAY,EAAE,IAAI,CAAC,YAAY,EAC/B,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,EACjD,aAAa,EAAE,IAAI,CAAC,aAAa,EACjC,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EACrD,eAAe,EAAE,IAAI,CAAC,eAAe,GACrC,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,aAAa,CAAC;QACnB,QAAQ;QACR,IAAI;QACJ,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,EAAE;QACrB,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC,CAAC;AAGF,aAAa;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAC9H,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,sBAAsB,MAAM,+CAA+C,CAAC;AACnF,OAAO,yBAAyB,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEjE,OAAO,aAAa,MAAM,wDAAwD,CAAC;AAInF,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,CAAC,MAAM,qBAAqB,GAA2B,UAAU,IAAI;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE;QAC5D,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACtD,MAAM,IAAI,GAAG,IAAW,CAAC;YACzB,IAAI,IAAI,EAAE;gBACR,GAAG,CAAC,KAAK,CAAC,MAAoD,CAAC,GAAG,SAAS,uBAAuB,CAAC,KAAK;oBACtG,OAAO,CACL,oBAAC,aAAa,IACV,QAAQ,EAAE,mBAAmB,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAC7C,MAAM,EAAE,MAAM,KAAK,cAAc;wBACnC,oBAAC,IAAI,OAAK,KAAK,GAAI,CACL,CACjB,CAAC;gBACJ,CAAC,CAAC;aACH;SACF;KACF;IAED,MAAM,QAAQ,GAAoC,SAAS,aAAa;QACtE,OAAO,CACL,oBAAC,YAAY,IACX,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,EACnD,eAAe,EAAE,IAAI,CAAC,eAAe,EACrC,YAAY,EAAE,IAAI,CAAC,YAAY,EAC/B,eAAe,EAAE,IAAI,CAAC,eAAe,EACrC,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,EACjD,aAAa,EAAE,IAAI,CAAC,aAAa,EACjC,uBAAuB,EAAE,IAAI,CAAC,uBAAuB,EACrD,eAAe,EAAE,IAAI,CAAC,eAAe,GACrC,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,aAAa,CAAC;QACnB,QAAQ;QACR,IAAI;QACJ,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,EAAE;QACrB,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC,CAAC;AAGF,aAAa;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAC9H,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,sBAAsB,MAAM,+CAA+C,CAAC;AACnF,OAAO,yBAAyB,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,YAAY,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,iCAAiC,EACjC,UAAU,EACV,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,UAAU,EAEV,SAAS,EACT,oBAAoB,EACpB,YAAY,GACb,CAAC","sourcesContent":["import React from 'react';\nimport { makeExtension } from '@riboseinc/paneron-extension-kit';\nimport type { Extension } from '@riboseinc/paneron-extension-kit/types';\nimport ErrorBoundary from '@riboseinc/paneron-extension-kit/widgets/ErrorBoundary';\nimport type { ExtensionMakerProps } from '@riboseinc/paneron-extension-kit/types/extension-maker';\nimport type { RegistryViewProps } from './types';\nimport type { ItemClassConfiguration } from './types/views';\nimport datasetInitializer from './migrations/initial';\nimport { RegistryView } from './views';\n\nexport type RegistryExtensionMakerProps =\n Pick<ExtensionMakerProps, 'name'> & RegistryViewProps\n\nexport type RegistryExtensionMaker =\n (opts: RegistryExtensionMakerProps) => Promise<Extension>;\n\nexport const makeRegistryExtension: RegistryExtensionMaker = function (opts) {\n const { name } = opts;\n\n for (const cls of Object.values(opts.itemClassConfiguration)) {\n for (const [viewID, view] of Object.entries(cls.views)) {\n const View = view as any;\n if (View) {\n cls.views[viewID as keyof ItemClassConfiguration<any>[\"views\"]] = function WrappedRegisterItemView(props) {\n return (\n <ErrorBoundary\n viewName={`Detail view for ${cls.meta.title}`}\n inline={viewID === 'listItemView'}>\n <View {...props} />\n </ErrorBoundary>\n );\n };\n }\n }\n }\n\n const mainView: ExtensionMakerProps[\"mainView\"] = function _RegistryView () {\n return (\n <RegistryView\n itemClassConfiguration={opts.itemClassConfiguration}\n itemClassGroups={opts.itemClassGroups}\n subregisters={opts.subregisters}\n CustomWorkspace={opts.CustomWorkspace}\n defaultSearchCriteria={opts.defaultSearchCriteria}\n keyExpression={opts.keyExpression}\n getQuickSearchPredicate={opts.getQuickSearchPredicate}\n alterApprovedCR={opts.alterApprovedCR}\n />\n );\n };\n\n return makeExtension({\n mainView,\n name,\n requiredHostAppVersion: '2.0.0',\n datasetMigrations: {},\n datasetInitializer,\n });\n};\n\n\n// Re-exports\n\nimport { BrowserCtx } from './views/BrowserCtx';\nimport { itemPathInCR, itemPathToItemRef, itemRefToItemPath, incompleteItemRefToItemPathPrefix } from './views/itemPathUtils';\nimport GenericRelatedItemView from './views/GenericRelatedItemView';\nimport { PropertyDetailView } from './views/util';\nimport CRITERIA_CONFIGURATION from './views/FilterCriteria/CRITERIA_CONFIGURATION';\nimport useSingleRegisterItemData from './views/hooks/useSingleRegisterItemData';\nimport { isAddition } from './types/proposal';\nimport type { Payload } from './types/item';\nimport { Protocols } from './views/protocolRegistry';\nimport { ChangeRequestContext } from './views/change-request/ChangeRequestContext';\nimport RegisterHome from './views/detail/RegisterHome';\n\nexport {\n itemRefToItemPath,\n itemPathToItemRef,\n itemPathInCR,\n incompleteItemRefToItemPathPrefix,\n BrowserCtx,\n CRITERIA_CONFIGURATION,\n GenericRelatedItemView,\n PropertyDetailView,\n useSingleRegisterItemData,\n isAddition,\n Payload,\n Protocols,\n ChangeRequestContext,\n RegisterHome,\n};\n"]}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _react2 = require("@emotion/react");
|
|
11
|
+
|
|
12
|
+
var _context = require("@riboseinc/paneron-extension-kit/context");
|
|
13
|
+
|
|
14
|
+
var _context2 = require("@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context");
|
|
15
|
+
|
|
16
|
+
var _StatefulTree = _interopRequireDefault(require("../views/StatefulTree"));
|
|
17
|
+
|
|
18
|
+
var _ChangeRequestContext = require("../views/change-request/ChangeRequestContext");
|
|
19
|
+
|
|
20
|
+
var _objectChangeset = require("../views/change-request/objectChangeset");
|
|
21
|
+
|
|
22
|
+
var _BrowserCtx = require("../views/BrowserCtx");
|
|
23
|
+
|
|
24
|
+
var _itemPathUtils = require("../views/itemPathUtils");
|
|
25
|
+
|
|
26
|
+
var _protocolRegistry = require("../views/protocolRegistry");
|
|
27
|
+
|
|
28
|
+
var _treeNodes = require("./treeNodes");
|
|
29
|
+
|
|
30
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
|
+
|
|
32
|
+
/** @jsx jsx */
|
|
33
|
+
|
|
34
|
+
/** @jsxFrag React.Fragment */
|
|
35
|
+
const ItemClassTree = function () {
|
|
36
|
+
const {
|
|
37
|
+
performOperation,
|
|
38
|
+
updateObjects,
|
|
39
|
+
makeRandomID
|
|
40
|
+
} = (0, _react.useContext)(_context.DatasetContext);
|
|
41
|
+
const {
|
|
42
|
+
spawnTab
|
|
43
|
+
} = (0, _react.useContext)(_context2.TabbedWorkspaceContext);
|
|
44
|
+
const {
|
|
45
|
+
changeRequest: activeCR,
|
|
46
|
+
canEdit: activeCRIsEditable
|
|
47
|
+
} = (0, _react.useContext)(_ChangeRequestContext.ChangeRequestContext);
|
|
48
|
+
const {
|
|
49
|
+
subregisters,
|
|
50
|
+
itemClasses,
|
|
51
|
+
itemClassGroups
|
|
52
|
+
} = (0, _react.useContext)(_BrowserCtx.BrowserCtx);
|
|
53
|
+
const createItem = (0, _react.useCallback)(async function _createItem(classID, subregisterID) {
|
|
54
|
+
var _a;
|
|
55
|
+
|
|
56
|
+
if (!updateObjects || !makeRandomID || !activeCRIsEditable || !activeCR) {
|
|
57
|
+
throw new Error("Unable to create item: likely current proposal is not editable or dataset is read-only");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (subregisters && !subregisterID) {
|
|
61
|
+
throw new Error("Unable to create item: register uses subregisters, but subregister ID was not provided");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const clsConfig = itemClasses[classID];
|
|
65
|
+
|
|
66
|
+
if (!clsConfig) {
|
|
67
|
+
throw new Error("Unable to generate new item data: item class configuration is missing");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const initialItemData = (_a = clsConfig === null || clsConfig === void 0 ? void 0 : clsConfig.defaults) !== null && _a !== void 0 ? _a : {};
|
|
71
|
+
const itemID = await makeRandomID();
|
|
72
|
+
const ref = {
|
|
73
|
+
classID,
|
|
74
|
+
itemID,
|
|
75
|
+
subregisterID
|
|
76
|
+
};
|
|
77
|
+
const registerItem = {
|
|
78
|
+
id: itemID,
|
|
79
|
+
dateAccepted: new Date(),
|
|
80
|
+
status: 'valid',
|
|
81
|
+
data: initialItemData
|
|
82
|
+
};
|
|
83
|
+
const itemPath = (0, _itemPathUtils.itemRefToItemPath)(ref);
|
|
84
|
+
await updateObjects({
|
|
85
|
+
commitMessage: `propose to add new ${ref.classID}`,
|
|
86
|
+
objectChangeset: (0, _objectChangeset.updateCRObjectChangeset)(activeCR, {
|
|
87
|
+
[itemPath]: {
|
|
88
|
+
type: 'addition'
|
|
89
|
+
}
|
|
90
|
+
}, {
|
|
91
|
+
[itemPath]: registerItem
|
|
92
|
+
}),
|
|
93
|
+
_dangerouslySkipValidation: true
|
|
94
|
+
});
|
|
95
|
+
spawnTab(`${_protocolRegistry.Protocols.ITEM_DETAILS}:${(0, _itemPathUtils.itemRefToItemPath)(ref, activeCR.id)}`);
|
|
96
|
+
}, [activeCR, activeCRIsEditable, subregisters === undefined, spawnTab, updateObjects, makeRandomID]);
|
|
97
|
+
const handleAdd = (0, _react.useMemo)(() => !subregisters && activeCRIsEditable && performOperation ? clsID => performOperation('generating new item', createItem)(clsID) : undefined, [createItem, subregisters === undefined, activeCRIsEditable, performOperation]);
|
|
98
|
+
const getNodes = (0, _react.useCallback)(state => {
|
|
99
|
+
var _a;
|
|
100
|
+
|
|
101
|
+
return (0, _treeNodes.getMaybeGroupedItemClassesAsTreeNodes)(itemClasses, itemClassGroups, {
|
|
102
|
+
selectedItemID: (_a = state.selectedItemID) !== null && _a !== void 0 ? _a : undefined,
|
|
103
|
+
expandedGroupLabels: new Set(state.expandedItemIDs),
|
|
104
|
+
onProposeItem: handleAdd
|
|
105
|
+
});
|
|
106
|
+
}, [itemClasses, itemClassGroups, handleAdd]);
|
|
107
|
+
return (0, _react2.jsx)(_StatefulTree.default, {
|
|
108
|
+
getNodes: getNodes,
|
|
109
|
+
stateKey: "item-browser",
|
|
110
|
+
onItemDoubleClick: node => spawnTab(`${_protocolRegistry.Protocols.ITEM_CLASS}:${node.id}`)
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
var _default = ItemClassTree;
|
|
115
|
+
exports.default = _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tree.js","sourceRoot":"","sources":["../../src/item-classes/Tree.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B,OAAc,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kEAAkE,CAAC;AAE1G,OAAO,mBAAgD,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,OAAO,EAAE,qCAAqC,EAAE,MAAM,aAAa,CAAC;AAGpE,MAAM,aAAa,GAAsD;IAEvE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IACrF,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;IACxD,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAClG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAE9E,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,aAAsB;;QAC/F,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY,IAAI,CAAC,kBAAkB,IAAI,CAAC,QAAQ,EAAE;YACvE,MAAM,IAAI,KAAK,CAAC,wFAAwF,CAAC,CAAC;SAC3G;QACD,IAAI,YAAY,IAAI,CAAC,aAAa,EAAE;YAClC,MAAM,IAAI,KAAK,CAAC,wFAAwF,CAAC,CAAC;SAC3G;QACD,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,EAAE;YACd,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;SAC1F;QACD,MAAM,eAAe,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,mCAAI,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;QACpC,MAAM,GAAG,GAA0B,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACtE,MAAM,YAAY,GAAsB;YACtC,EAAE,EAAE,MAAM;YACV,YAAY,EAAE,IAAI,IAAI,EAAE;YACxB,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,eAAe;SACtB,CAAC;QACF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,aAAa,CAAC;YAClB,aAAa,EAAE,sBAAsB,GAAG,CAAC,OAAO,EAAE;YAClD,eAAe,EAAE,uBAAuB,CACtC,QAAe,EACf,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EACpC,EAAE,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,CAC7B;YACD,0BAA0B,EAAE,IAAI;SACjC,CAAC,CAAC;QACH,QAAQ,CAAC,GAAG,SAAS,CAAC,YAAY,IAAI,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,YAAY,KAAK,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;IAEtG,MAAM,SAAS,GAAmD,OAAO,CAAC,CAAC,GAAG,EAAE,CAC9E,CAAC,YAAY,IAAI,kBAAkB,IAAI,gBAAgB;QACrD,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC;QACvE,CAAC,CAAC,SAAS,CACd,EAAE,CAAC,UAAU,EAAE,YAAY,KAAK,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEnF,MAAM,QAAQ,GAAG,WAAW,CAC1B,CAAC,CAAC,KAAgB,EAAE,EAAE;;QACpB,OAAA,qCAAqC,CAAC,WAAW,EAAE,eAAe,EAAE;YAClE,cAAc,EAAE,MAAA,KAAK,CAAC,cAAc,mCAAI,SAAS;YACjD,mBAAmB,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC;YACnD,aAAa,EAAE,SAAS;SACzB,CAAC,CAAA;KAAA,CAAC,EACL,CAAC,WAAW,EAAE,eAAe,EAAE,SAAS,CAAC,CAC1C,CAAC;IAEF,OAAO,IAAC,mBAAmB,IACzB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAC,cAAc,EACvB,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,GAC3E,CAAC;AACL,CAAC,CAAC;AAGF,eAAe,aAAa,CAAC","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useMemo, useCallback } from 'react';\nimport { jsx } from '@emotion/react';\n\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\n\nimport GenericStatefulTree, { type State as TreeState } from '../views/StatefulTree';\nimport { ChangeRequestContext } from '../views/change-request/ChangeRequestContext';\nimport { updateCRObjectChangeset } from '../views/change-request/objectChangeset';\nimport { BrowserCtx } from '../views/BrowserCtx';\nimport type { RegisterItem, InternalItemReference } from '../types';\nimport { itemRefToItemPath } from '../views/itemPathUtils';\nimport { Protocols } from '../views/protocolRegistry';\n\nimport { getMaybeGroupedItemClassesAsTreeNodes } from './treeNodes';\n\n\nconst ItemClassTree: React.VoidFunctionComponent<Record<never, never>> = function () {\n\n const { performOperation, updateObjects, makeRandomID } = useContext(DatasetContext);\n const { spawnTab } = useContext(TabbedWorkspaceContext);\n const { changeRequest: activeCR, canEdit: activeCRIsEditable } = useContext(ChangeRequestContext);\n const { subregisters, itemClasses, itemClassGroups } = useContext(BrowserCtx);\n\n const createItem = useCallback(async function _createItem(classID: string, subregisterID?: string) {\n if (!updateObjects || !makeRandomID || !activeCRIsEditable || !activeCR) {\n throw new Error(\"Unable to create item: likely current proposal is not editable or dataset is read-only\");\n }\n if (subregisters && !subregisterID) {\n throw new Error(\"Unable to create item: register uses subregisters, but subregister ID was not provided\");\n }\n const clsConfig = itemClasses[classID];\n if (!clsConfig) {\n throw new Error(\"Unable to generate new item data: item class configuration is missing\");\n }\n const initialItemData = clsConfig?.defaults ?? {};\n const itemID = await makeRandomID();\n const ref: InternalItemReference = { classID, itemID, subregisterID };\n const registerItem: RegisterItem<any> = {\n id: itemID,\n dateAccepted: new Date(),\n status: 'valid',\n data: initialItemData,\n };\n const itemPath = itemRefToItemPath(ref);\n await updateObjects({\n commitMessage: `propose to add new ${ref.classID}`,\n objectChangeset: updateCRObjectChangeset(\n activeCR as any,\n { [itemPath]: { type: 'addition' } },\n { [itemPath]: registerItem },\n ),\n _dangerouslySkipValidation: true,\n });\n spawnTab(`${Protocols.ITEM_DETAILS}:${itemRefToItemPath(ref, activeCR.id)}`);\n }, [activeCR, activeCRIsEditable, subregisters === undefined, spawnTab, updateObjects, makeRandomID]);\n\n const handleAdd: undefined | ((clsID: string) => Promise<void>) = useMemo((() =>\n !subregisters && activeCRIsEditable && performOperation\n ? (clsID) => performOperation('generating new item', createItem)(clsID)\n : undefined\n ), [createItem, subregisters === undefined, activeCRIsEditable, performOperation]);\n\n const getNodes = useCallback(\n ((state: TreeState) =>\n getMaybeGroupedItemClassesAsTreeNodes(itemClasses, itemClassGroups, {\n selectedItemID: state.selectedItemID ?? undefined,\n expandedGroupLabels: new Set(state.expandedItemIDs),\n onProposeItem: handleAdd,\n })),\n [itemClasses, itemClassGroups, handleAdd],\n );\n\n return <GenericStatefulTree\n getNodes={getNodes}\n stateKey=\"item-browser\"\n onItemDoubleClick={(node) => spawnTab(`${Protocols.ITEM_CLASS}:${node.id}`)}\n />;\n};\n\n\nexport default ItemClassTree;\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
/** @jsxFrag React.Fragment */
|
|
3
|
+
import type { RegistryViewProps } from '../types/views';
|
|
4
|
+
import type { TreeNodeInfo } from '@blueprintjs/core';
|
|
5
|
+
export declare type ItemOrGroupTreeNode = TreeNodeInfo<{
|
|
6
|
+
type: 'group' | 'item';
|
|
7
|
+
}>;
|
|
8
|
+
export declare function getMaybeGroupedItemClassesAsTreeNodes<T extends RegistryViewProps>(itemClasses: T['itemClassConfiguration'], itemClassGroups: T['itemClassGroups'] | undefined, opts?: {
|
|
9
|
+
expandedGroupLabels?: Set<string>;
|
|
10
|
+
selectedItemID?: string;
|
|
11
|
+
onProposeItem?: (clsID: string) => Promise<void>;
|
|
12
|
+
}): ItemOrGroupTreeNode[];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getMaybeGroupedItemClassesAsTreeNodes = getMaybeGroupedItemClassesAsTreeNodes;
|
|
7
|
+
|
|
8
|
+
var _react = require("@emotion/react");
|
|
9
|
+
|
|
10
|
+
var _util = require("../views/util");
|
|
11
|
+
|
|
12
|
+
/** @jsx jsx */
|
|
13
|
+
|
|
14
|
+
/** @jsxFrag React.Fragment */
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Tools for rendering proposal groups as tree nodes.
|
|
18
|
+
* Each proposal group is top-level node, with proposals as nested nodes.
|
|
19
|
+
*/
|
|
20
|
+
//import React, { useContext, useMemo } from 'react';
|
|
21
|
+
function getMaybeGroupedItemClassesAsTreeNodes(itemClasses, itemClassGroups, opts) {
|
|
22
|
+
if (!itemClassGroups) {
|
|
23
|
+
return getItemClassesAsTreeNodes(itemClasses, Object.keys(itemClasses));
|
|
24
|
+
} else {
|
|
25
|
+
return Object.entries(itemClassGroups).map(([groupLabel, clsIDs]) => {
|
|
26
|
+
var _a;
|
|
27
|
+
|
|
28
|
+
const hasSelectedClass = (opts === null || opts === void 0 ? void 0 : opts.selectedItemID) && clsIDs.includes(opts.selectedItemID);
|
|
29
|
+
const isSelected = (opts === null || opts === void 0 ? void 0 : opts.selectedItemID) && groupLabel === opts.selectedItemID ? true : false;
|
|
30
|
+
const isExpanded = hasSelectedClass || ((_a = opts === null || opts === void 0 ? void 0 : opts.expandedGroupLabels) === null || _a === void 0 ? void 0 : _a.has(groupLabel));
|
|
31
|
+
return {
|
|
32
|
+
id: groupLabel,
|
|
33
|
+
label: groupLabel,
|
|
34
|
+
hasCaret: true,
|
|
35
|
+
isSelected,
|
|
36
|
+
isExpanded,
|
|
37
|
+
icon: isExpanded ? 'folder-open' : 'folder-close',
|
|
38
|
+
childNodes: isExpanded ? getItemClassesAsTreeNodes(itemClasses, clsIDs, opts) : [],
|
|
39
|
+
nodeData: {
|
|
40
|
+
type: 'group'
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getItemClassesAsTreeNodes(itemClasses,
|
|
48
|
+
/** Used for ordering. */
|
|
49
|
+
classIDs, opts) {
|
|
50
|
+
return classIDs.map(clsID => {
|
|
51
|
+
var _a;
|
|
52
|
+
|
|
53
|
+
const cls = itemClasses[clsID];
|
|
54
|
+
return {
|
|
55
|
+
id: clsID,
|
|
56
|
+
label: (_a = cls === null || cls === void 0 ? void 0 : cls.meta.title) !== null && _a !== void 0 ? _a : 'unknown class',
|
|
57
|
+
icon: 'folder-close',
|
|
58
|
+
isSelected: (opts === null || opts === void 0 ? void 0 : opts.selectedItemID) === clsID,
|
|
59
|
+
nodeData: {
|
|
60
|
+
type: 'item'
|
|
61
|
+
},
|
|
62
|
+
secondaryLabel: (0, _react.jsx)(_util.MoreMenu, null, (0, _react.jsx)(_util.ItemClassMenu, {
|
|
63
|
+
cfg: cls,
|
|
64
|
+
onCreate: (opts === null || opts === void 0 ? void 0 : opts.onProposeItem) ? () => opts.onProposeItem(clsID) : undefined
|
|
65
|
+
}))
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeNodes.js","sourceRoot":"","sources":["../../src/item-classes/treeNodes.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B;;;GAGG;AAEH,qDAAqD;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAGrC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAMxD,MAAM,UAAU,qCAAqC,CACnD,WAAwC,EACxC,eAAiD,EACjD,IAIC;IAED,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,yBAAyB,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;KACzE;SAAM;QACL,OAAO,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE;;YAClE,MAAM,gBAAgB,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,KAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACtF,MAAM,UAAU,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,KAAI,UAAU,KAAK,IAAI,CAAC,cAAc;gBAC3E,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,KAAK,CAAC;YACV,MAAM,UAAU,GAAG,gBAAgB,KAAI,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,0CAAE,GAAG,CAAC,UAAU,CAAC,CAAA,CAAC;YAClF,OAAO;gBACL,EAAE,EAAE,UAAU;gBACd,KAAK,EAAE,UAAU;gBACjB,QAAQ,EAAE,IAAI;gBACd,UAAU;gBACV,UAAU;gBACV,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAA0B;gBAC7D,UAAU,EAAE,UAAU;oBACpB,CAAC,CAAC,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC;oBACtD,CAAC,CAAC,EAAE;gBACN,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;aAC5B,CAAC;QACJ,CAAC,CAAC,CAAC;KACJ;AACH,CAAC;AAED,SAAS,yBAAyB,CAChC,WAAc;AACd,yBAAyB;AACzB,QAA8B,EAC9B,IAGC;IAED,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;;QAC1B,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO;YACL,EAAE,EAAE,KAAe;YACnB,KAAK,EAAE,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,CAAC,KAAK,mCAAI,eAAe;YACzC,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,MAAK,KAAK;YAC1C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YAC1B,cAAc,EACZ,IAAC,QAAQ;gBACP,IAAC,aAAa,IACZ,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,EAAC,CAAC;wBAC7B,GAAG,EAAE,CAAC,IAAI,CAAC,aAAc,CAAC,KAAe,CAAC;wBAC1C,CAAC,CAAC,SAAS,GACb,CACO;SACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\n/**\n * Tools for rendering proposal groups as tree nodes.\n * Each proposal group is top-level node, with proposals as nested nodes.\n */\n\n//import React, { useContext, useMemo } from 'react';\nimport { jsx } from '@emotion/react';\nimport type { RegistryViewProps } from '../types/views';\nimport type { TreeNodeInfo, IconName } from '@blueprintjs/core';\nimport { MoreMenu, ItemClassMenu } from '../views/util';\n\n\nexport type ItemOrGroupTreeNode = TreeNodeInfo<{ type: 'group' | 'item' }>;\n\n\nexport function getMaybeGroupedItemClassesAsTreeNodes<T extends RegistryViewProps>(\n itemClasses: T['itemClassConfiguration'],\n itemClassGroups: T['itemClassGroups'] | undefined,\n opts?: {\n expandedGroupLabels?: Set<string>\n selectedItemID?: string\n onProposeItem?: (clsID: string) => Promise<void>\n },\n): ItemOrGroupTreeNode[] {\n if (!itemClassGroups) {\n return getItemClassesAsTreeNodes(itemClasses, Object.keys(itemClasses));\n } else {\n return Object.entries(itemClassGroups).map(([groupLabel, clsIDs]) => {\n const hasSelectedClass = opts?.selectedItemID && clsIDs.includes(opts.selectedItemID);\n const isSelected = opts?.selectedItemID && groupLabel === opts.selectedItemID\n ? true\n : false;\n const isExpanded = hasSelectedClass || opts?.expandedGroupLabels?.has(groupLabel);\n return {\n id: groupLabel,\n label: groupLabel,\n hasCaret: true,\n isSelected,\n isExpanded,\n icon: isExpanded ? 'folder-open' : 'folder-close' as IconName,\n childNodes: isExpanded\n ? getItemClassesAsTreeNodes(itemClasses, clsIDs, opts)\n : [],\n nodeData: { type: 'group' },\n };\n });\n }\n}\n\nfunction getItemClassesAsTreeNodes<T extends RegistryViewProps['itemClassConfiguration']>(\n itemClasses: T,\n /** Used for ordering. */\n classIDs: readonly (keyof T)[],\n opts?: {\n selectedItemID?: string\n onProposeItem?: (clsID: string) => Promise<void>\n },\n): TreeNodeInfo<{ type: 'item' }>[] {\n return classIDs.map(clsID => {\n const cls = itemClasses[clsID];\n return {\n id: clsID as string,\n label: cls?.meta.title ?? 'unknown class',\n icon: 'folder-close',\n isSelected: opts?.selectedItemID === clsID,\n nodeData: { type: 'item' },\n secondaryLabel:\n <MoreMenu>\n <ItemClassMenu\n cfg={cls}\n onCreate={opts?.onProposeItem ?\n () => opts.onProposeItem!(clsID as string)\n : undefined}\n />\n </MoreMenu>,\n };\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riboseinc/paneron-registry-kit",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.31",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"author": "Ribose Inc. <open.source@ribose.com>",
|
|
6
6
|
"scripts": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@blueprintjs/select": "~4.9.10",
|
|
29
29
|
"@emotion/react": "^11.10.6",
|
|
30
30
|
"@emotion/styled": "^11.10.6",
|
|
31
|
-
"@riboseinc/paneron-extension-kit": "2.2.
|
|
31
|
+
"@riboseinc/paneron-extension-kit": "2.2.20",
|
|
32
32
|
"@types/react": "17.0.53",
|
|
33
33
|
"@types/react-dom": "^17.0.2",
|
|
34
34
|
"@types/react-helmet": "^6.1.2",
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _immutabilityHelper = _interopRequireDefault(require("immutability-helper"));
|
|
11
|
+
|
|
12
|
+
var _react2 = require("@emotion/react");
|
|
13
|
+
|
|
14
|
+
var _core = require("@blueprintjs/core");
|
|
15
|
+
|
|
16
|
+
var _paneronExtensionKit = require("@riboseinc/paneron-extension-kit");
|
|
17
|
+
|
|
18
|
+
var _ChangeRequestContext = require("../../views/change-request/ChangeRequestContext");
|
|
19
|
+
|
|
20
|
+
var _BrowserCtx = require("../../views/BrowserCtx");
|
|
21
|
+
|
|
22
|
+
var _queries = require("./queries");
|
|
23
|
+
|
|
24
|
+
var _treeNodes = require("./treeNodes");
|
|
25
|
+
|
|
26
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
|
+
|
|
28
|
+
/** @jsx jsx */
|
|
29
|
+
|
|
30
|
+
/** @jsxFrag React.Fragment */
|
|
31
|
+
const initialState = {
|
|
32
|
+
//selectedFolderID: null,
|
|
33
|
+
selectedItemID: null,
|
|
34
|
+
expandedFolderIDs: []
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const ActionableCRTree = function ({
|
|
38
|
+
className
|
|
39
|
+
}) {
|
|
40
|
+
var _a;
|
|
41
|
+
|
|
42
|
+
const {
|
|
43
|
+
changeRequest: activeCR
|
|
44
|
+
} = (0, _react.useContext)(_ChangeRequestContext.ChangeRequestContext);
|
|
45
|
+
const {
|
|
46
|
+
setActiveChangeRequestID,
|
|
47
|
+
stakeholder
|
|
48
|
+
} = (0, _react.useContext)(_BrowserCtx.BrowserCtx);
|
|
49
|
+
const {
|
|
50
|
+
usePersistentDatasetStateReducer,
|
|
51
|
+
useMapReducedData
|
|
52
|
+
} = (0, _react.useContext)(_paneronExtensionKit.DatasetContext);
|
|
53
|
+
const [state, dispatch] = usePersistentDatasetStateReducer('actionable-proposals', undefined, undefined, (prevState, action) => {
|
|
54
|
+
switch (action.type) {
|
|
55
|
+
case 'select-folder':
|
|
56
|
+
if (prevState.selectedItemID !== action.payload.folderID) {
|
|
57
|
+
return { ...prevState,
|
|
58
|
+
selectedItemID: action.payload.folderID
|
|
59
|
+
};
|
|
60
|
+
} else {
|
|
61
|
+
return prevState;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
case 'enter-folder':
|
|
65
|
+
if (!prevState.expandedFolderIDs.includes(action.payload.folderID)) {
|
|
66
|
+
return { ...prevState,
|
|
67
|
+
selectedItemID: action.payload.folderID,
|
|
68
|
+
expandedFolderIDs: (0, _immutabilityHelper.default)(prevState.expandedFolderIDs, {
|
|
69
|
+
$push: [action.payload.folderID]
|
|
70
|
+
})
|
|
71
|
+
};
|
|
72
|
+
} else {
|
|
73
|
+
return prevState;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
case 'exit-folder':
|
|
77
|
+
const idx = prevState.expandedFolderIDs.indexOf(action.payload.folderID);
|
|
78
|
+
|
|
79
|
+
if (idx >= 0) {
|
|
80
|
+
return { ...prevState,
|
|
81
|
+
selectedItemID: action.payload.folderID,
|
|
82
|
+
expandedFolderIDs: (0, _immutabilityHelper.default)(prevState.expandedFolderIDs, {
|
|
83
|
+
$splice: [[idx, 1]]
|
|
84
|
+
})
|
|
85
|
+
};
|
|
86
|
+
} else {
|
|
87
|
+
return prevState;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
case 'select-item':
|
|
91
|
+
if (prevState.selectedItemID !== action.payload.itemID) {
|
|
92
|
+
return { ...prevState,
|
|
93
|
+
selectedItemID: action.payload.itemID
|
|
94
|
+
};
|
|
95
|
+
} else {
|
|
96
|
+
return prevState;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
default:
|
|
100
|
+
throw new Error("Unexpected browse state");
|
|
101
|
+
}
|
|
102
|
+
}, initialState, null);
|
|
103
|
+
const groups = (0, _queries.getActionableProposalGroupsForRoles)((_a = stakeholder === null || stakeholder === void 0 ? void 0 : stakeholder.roles) !== null && _a !== void 0 ? _a : []);
|
|
104
|
+
const chains = stakeholder ? (0, _treeNodes.getMapReduceChainsForActionableProposalGroups)(groups, stakeholder) : {};
|
|
105
|
+
const actionableProposalsResult = useMapReducedData({
|
|
106
|
+
chains
|
|
107
|
+
});
|
|
108
|
+
const actionableProposals = (0, _react.useMemo)(() => Object.entries(actionableProposalsResult.value).map(([chainID, chainResult]) => ({
|
|
109
|
+
groupLabel: chainID,
|
|
110
|
+
proposals: (Array.isArray(chainResult) // TODO: Validate results
|
|
111
|
+
? chainResult : undefined) || undefined
|
|
112
|
+
})), [actionableProposalsResult.value]);
|
|
113
|
+
const nodes = (0, _react.useMemo)(() => (0, _treeNodes.getActionableProposalGroupsAsTreeNodes)(actionableProposals, {
|
|
114
|
+
activeCRID: activeCR === null || activeCR === void 0 ? void 0 : activeCR.id,
|
|
115
|
+
expandedGroupLabels: new Set(state.expandedFolderIDs),
|
|
116
|
+
selectedGroup: state.selectedItemID ? actionableProposals.find(({
|
|
117
|
+
groupLabel
|
|
118
|
+
}) => groupLabel === state.selectedItemID) ? state.selectedItemID : undefined : undefined,
|
|
119
|
+
selectedCRID: state.selectedItemID ? actionableProposals.flatMap(({
|
|
120
|
+
proposals
|
|
121
|
+
}) => proposals !== null && proposals !== void 0 ? proposals : []).find(p => p.id === state.selectedItemID) ? state.selectedItemID : undefined : undefined
|
|
122
|
+
}), [activeCR === null || activeCR === void 0 ? void 0 : activeCR.id, actionableProposals, state.selectedItemID, state.expandedFolderIDs.join(',')]);
|
|
123
|
+
const eventHandlers = (0, _react.useMemo)(() => ({
|
|
124
|
+
onNodeClick: node => {
|
|
125
|
+
var _a;
|
|
126
|
+
|
|
127
|
+
return ((_a = node.nodeData) === null || _a === void 0 ? void 0 : _a.type) === 'group' ? dispatch({
|
|
128
|
+
type: 'select-folder',
|
|
129
|
+
payload: {
|
|
130
|
+
folderID: node.id
|
|
131
|
+
}
|
|
132
|
+
}) : dispatch({
|
|
133
|
+
type: 'select-item',
|
|
134
|
+
payload: {
|
|
135
|
+
itemID: node.id
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
onNodeExpand: node => {
|
|
140
|
+
var _a;
|
|
141
|
+
|
|
142
|
+
return ((_a = node.nodeData) === null || _a === void 0 ? void 0 : _a.type) === 'group' ? dispatch({
|
|
143
|
+
type: 'enter-folder',
|
|
144
|
+
payload: {
|
|
145
|
+
folderID: node.id
|
|
146
|
+
}
|
|
147
|
+
}) : void 0;
|
|
148
|
+
},
|
|
149
|
+
onNodeCollapse: node => {
|
|
150
|
+
var _a;
|
|
151
|
+
|
|
152
|
+
return ((_a = node.nodeData) === null || _a === void 0 ? void 0 : _a.type) === 'group' ? dispatch({
|
|
153
|
+
type: 'exit-folder',
|
|
154
|
+
payload: {
|
|
155
|
+
folderID: node.id
|
|
156
|
+
}
|
|
157
|
+
}) : void 0;
|
|
158
|
+
},
|
|
159
|
+
onNodeDoubleClick: node => {
|
|
160
|
+
var _a;
|
|
161
|
+
|
|
162
|
+
return ((_a = node.nodeData) === null || _a === void 0 ? void 0 : _a.type) === 'group' ? dispatch({
|
|
163
|
+
type: 'enter-folder',
|
|
164
|
+
payload: {
|
|
165
|
+
folderID: node.id
|
|
166
|
+
}
|
|
167
|
+
}) // TODO: Do something like switch to home tab or proposal tab?
|
|
168
|
+
: node.id === (activeCR === null || activeCR === void 0 ? void 0 : activeCR.id) ? setActiveChangeRequestID === null || setActiveChangeRequestID === void 0 ? void 0 : setActiveChangeRequestID(null) : setActiveChangeRequestID === null || setActiveChangeRequestID === void 0 ? void 0 : setActiveChangeRequestID(node.id);
|
|
169
|
+
}
|
|
170
|
+
}), [dispatch, activeCR === null || activeCR === void 0 ? void 0 : activeCR.id]);
|
|
171
|
+
return (0, _react2.jsx)(_core.Tree, {
|
|
172
|
+
className: className,
|
|
173
|
+
contents: nodes,
|
|
174
|
+
...eventHandlers
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
var _default = ActionableCRTree;
|
|
179
|
+
exports.default = _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tree.js","sourceRoot":"","sources":["../../../src/proposals/actionableGroups/Tree.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B,OAAc,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAGlE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,mCAAmC,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAEL,6CAA6C,EAC7C,sCAAsC,GACvC,MAAM,aAAa,CAAC;AASrB,MAAM,YAAY,GAAU;IAC1B,yBAAyB;IACzB,cAAc,EAAE,IAAI;IACpB,iBAAiB,EAAE,EAAE;CACb,CAAC;AASX,MAAM,gBAAgB,GAGtB,UAAU,EAAE,SAAS,EAAE;;IACrB,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACrE,MAAM,EAAE,wBAAwB,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,EAAE,gCAAgC,EAAE,iBAAiB,EAAE,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAE3F,MAAM,CAAE,KAAK,EAAE,QAAQ,EAAG,GAAI,gCAA8E,CAC1G,sBAAsB,EACtB,SAAS,EACT,SAAS,EACT,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;QACpB,QAAQ,MAAM,CAAC,IAAI,EAAE;YACnB,KAAK,eAAe;gBAClB,IAAI,SAAS,CAAC,cAAc,KAAK,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE;oBACxD,OAAO;wBACL,GAAG,SAAS;wBACZ,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ;qBACxC,CAAC;iBACH;qBAAM;oBACL,OAAO,SAAS,CAAC;iBAClB;YACH,KAAK,cAAc;gBACjB,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;oBAClE,OAAO;wBACL,GAAG,SAAS;wBACZ,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ;wBACvC,iBAAiB,EAAE,MAAM,CACvB,SAAS,CAAC,iBAAiB,EAC3B,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;qBACxC,CAAC;iBACH;qBAAM;oBACL,OAAO,SAAS,CAAC;iBAClB;YACH,KAAK,aAAa;gBAChB,MAAM,GAAG,GAAG,SAAS,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzE,IAAI,GAAG,IAAI,CAAC,EAAE;oBACZ,OAAO;wBACL,GAAG,SAAS;wBACZ,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ;wBACvC,iBAAiB,EAAE,MAAM,CACvB,SAAS,CAAC,iBAAiB,EAC3B,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAC3B,CAAC;iBACH;qBAAM;oBACL,OAAO,SAAS,CAAC;iBAClB;YACH,KAAK,aAAa;gBAChB,IAAI,SAAS,CAAC,cAAc,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE;oBACtD,OAAO;wBACL,GAAG,SAAS;wBACZ,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;qBACtC,CAAC;iBACH;qBAAM;oBACL,OAAO,SAAS,CAAC;iBAClB;YACH;gBACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;SAC9C;IACH,CAAC,EACD,YAAY,EACZ,IAAI,CAAC,CAAC;IAER,MAAM,MAAM,GAAG,mCAAmC,CAAC,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,mCAAI,EAAE,CAAC,CAAC;IAE7E,MAAM,MAAM,GAAG,WAAW;QACxB,CAAC,CAAC,6CAA6C,CAAC,MAAM,EAAE,WAAW,CAAC;QACpE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhE,MAAM,mBAAmB,GAAG,OAAO,CACjC,CAAC,GAAG,EAAE,CACN,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,KAAK,CAAC;QAC7C,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/B,UAAU,EAAE,OAAO;QACnB,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YACpC,yBAAyB;YACzB,CAAC,CAAE,WAAoB;YACvB,CAAC,CAAC,SAAS,CAAC,IAAI,SAAS;KAC5B,CAAC,CAAC,CACJ,EACD,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;IAErC,MAAM,KAAK,GAAG,OAAO,CACnB,CAAC,GAAG,EAAE,CACJ,sCAAsC,CAAC,mBAAmB,EAAE;QAC1D,UAAU,EAAE,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,EAAE;QACxB,mBAAmB,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC;QACrD,aAAa,EAAE,KAAK,CAAC,cAAc;YACjC,CAAC,CAAC,mBAAmB;gBACnB,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,KAAK,KAAK,CAAC,cAAc,CAAC;gBAC3D,CAAC,CAAC,KAAK,CAAC,cAAc;gBACtB,CAAC,CAAC,SAAS;YACf,CAAC,CAAC,SAAS;QACb,YAAY,EAAE,KAAK,CAAC,cAAc;YAChC,CAAC,CAAC,mBAAmB;gBACnB,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC;gBAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC;gBACtC,CAAC,CAAC,KAAK,CAAC,cAAc;gBACtB,CAAC,CAAC,SAAS;YACf,CAAC,CAAC,SAAS;KACd,CAAC,CACH,EACD,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEhG,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,WAAW,EAAE,CAAC,IAAgC,EAAE,EAAE;;YAChD,OAAA,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,MAAK,OAAO;gBAC7B,CAAC,CAAC,QAAQ,CAAC;oBACP,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAY,EAAE;iBACzC,CAAC;gBACJ,CAAC,CAAC,QAAQ,CAAC;oBACP,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAY,EAAE;iBACvC,CAAC,CAAA;SAAA;QACR,YAAY,EAAE,CAAC,IAAgC,EAAE,EAAE;;YACjD,OAAA,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,MAAK,OAAO;gBAC7B,CAAC,CAAC,QAAQ,CAAC;oBACP,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAY,EAAE;iBACzC,CAAC;gBACJ,CAAC,CAAC,KAAK,CAAC,CAAA;SAAA;QACZ,cAAc,EAAE,CAAC,IAAgC,EAAE,EAAE;;YACnD,OAAA,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,MAAK,OAAO;gBAC7B,CAAC,CAAC,QAAQ,CAAC;oBACP,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAY,EAAE;iBACzC,CAAC;gBACJ,CAAC,CAAC,KAAK,CAAC,CAAA;SAAA;QACZ,iBAAiB,EAAE,CAAC,IAAgC,EAAE,EAAE;;YACtD,OAAA,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,MAAK,OAAO;gBAC7B,CAAC,CAAC,QAAQ,CAAC;oBACP,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAY,EAAE;iBACzC,CAAC;gBACJ,8DAA8D;gBAC9D,CAAC,CAAC,IAAI,CAAC,EAAE,MAAK,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,EAAE,CAAA;oBACxB,CAAC,CAAC,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAG,IAAI,CAAC;oBAClC,CAAC,CAAC,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAG,IAAI,CAAC,EAAY,CAAC,CAAA;SAAA;KACtD,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,EAAE,CAAC,CAAC,CAAC;IAE/B,OAAO,IAAC,IAAI,IACV,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,KAAK,KACX,aAAa,GACjB,CAAC;AACL,CAAC,CAAA;AAED,eAAe,gBAAgB,CAAC","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useMemo } from 'react';\nimport update from 'immutability-helper';\nimport { jsx } from '@emotion/react';\nimport { Tree } from '@blueprintjs/core';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { SomeCR as CR } from '../../types/cr';\nimport { ChangeRequestContext } from '../../views/change-request/ChangeRequestContext';\nimport { BrowserCtx } from '../../views/BrowserCtx';\nimport { getActionableProposalGroupsForRoles } from './queries';\nimport {\n type ActionableProposalTreeNode,\n getMapReduceChainsForActionableProposalGroups,\n getActionableProposalGroupsAsTreeNodes,\n} from './treeNodes';\n\n\ninterface State {\n //selectedFolderID: string | null\n selectedItemID: string | null\n expandedFolderIDs: readonly string[]\n}\n\nconst initialState: State = {\n //selectedFolderID: null,\n selectedItemID: null,\n expandedFolderIDs: [],\n} as const;\n\ntype Action =\n | { type: 'select-folder'; payload: { folderID: string | null; }; }\n | { type: 'enter-folder'; payload: { folderID: string; }; }\n | { type: 'exit-folder'; payload: { folderID: string; }; }\n | { type: 'select-item'; payload: { itemID: string | null; }; }\n\n\nconst ActionableCRTree: React.FC<{\n className?: string\n}> =\nfunction ({ className }) {\n const { changeRequest: activeCR } = useContext(ChangeRequestContext);\n const { setActiveChangeRequestID, stakeholder } = useContext(BrowserCtx);\n const { usePersistentDatasetStateReducer, useMapReducedData } = useContext(DatasetContext);\n\n const [ state, dispatch, ] = (usePersistentDatasetStateReducer as PersistentStateReducerHook<State, Action>)(\n 'actionable-proposals',\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'select-folder':\n if (prevState.selectedItemID !== action.payload.folderID) {\n return {\n ...prevState,\n selectedItemID: action.payload.folderID,\n };\n } else {\n return prevState;\n }\n case 'enter-folder':\n if (!prevState.expandedFolderIDs.includes(action.payload.folderID)) {\n return {\n ...prevState,\n selectedItemID: action.payload.folderID,\n expandedFolderIDs: update(\n prevState.expandedFolderIDs,\n { $push: [action.payload.folderID] }),\n };\n } else {\n return prevState;\n }\n case 'exit-folder':\n const idx = prevState.expandedFolderIDs.indexOf(action.payload.folderID);\n if (idx >= 0) {\n return {\n ...prevState,\n selectedItemID: action.payload.folderID,\n expandedFolderIDs: update(\n prevState.expandedFolderIDs,\n { $splice: [[idx, 1]] }),\n };\n } else {\n return prevState;\n }\n case 'select-item':\n if (prevState.selectedItemID !== action.payload.itemID) {\n return {\n ...prevState,\n selectedItemID: action.payload.itemID,\n };\n } else {\n return prevState;\n }\n default:\n throw new Error(\"Unexpected browse state\");\n }\n },\n initialState,\n null);\n\n const groups = getActionableProposalGroupsForRoles(stakeholder?.roles ?? []);\n\n const chains = stakeholder\n ? getMapReduceChainsForActionableProposalGroups(groups, stakeholder)\n : {};\n\n const actionableProposalsResult = useMapReducedData({ chains });\n\n const actionableProposals = useMemo(\n (() =>\n Object.entries(actionableProposalsResult.value).\n map(([chainID, chainResult]) => ({\n groupLabel: chainID,\n proposals: (Array.isArray(chainResult)\n // TODO: Validate results\n ? (chainResult as CR[])\n : undefined) || undefined\n }))\n ),\n [actionableProposalsResult.value]);\n\n const nodes = useMemo(\n (() =>\n getActionableProposalGroupsAsTreeNodes(actionableProposals, {\n activeCRID: activeCR?.id,\n expandedGroupLabels: new Set(state.expandedFolderIDs),\n selectedGroup: state.selectedItemID\n ? actionableProposals.\n find(({ groupLabel }) => groupLabel === state.selectedItemID)\n ? state.selectedItemID\n : undefined\n : undefined,\n selectedCRID: state.selectedItemID\n ? actionableProposals.\n flatMap(({ proposals }) => proposals ?? []).\n find(p => p.id === state.selectedItemID)\n ? state.selectedItemID\n : undefined\n : undefined,\n })\n ),\n [activeCR?.id, actionableProposals, state.selectedItemID, state.expandedFolderIDs.join(',')]);\n\n const eventHandlers = useMemo((() => ({\n onNodeClick: (node: ActionableProposalTreeNode) =>\n node.nodeData?.type === 'group'\n ? dispatch({\n type: 'select-folder',\n payload: { folderID: node.id as string },\n })\n : dispatch({\n type: 'select-item',\n payload: { itemID: node.id as string },\n }),\n onNodeExpand: (node: ActionableProposalTreeNode) =>\n node.nodeData?.type === 'group'\n ? dispatch({\n type: 'enter-folder',\n payload: { folderID: node.id as string },\n })\n : void 0,\n onNodeCollapse: (node: ActionableProposalTreeNode) =>\n node.nodeData?.type === 'group'\n ? dispatch({\n type: 'exit-folder',\n payload: { folderID: node.id as string },\n })\n : void 0,\n onNodeDoubleClick: (node: ActionableProposalTreeNode) =>\n node.nodeData?.type === 'group'\n ? dispatch({\n type: 'enter-folder',\n payload: { folderID: node.id as string },\n })\n // TODO: Do something like switch to home tab or proposal tab?\n : node.id === activeCR?.id\n ? setActiveChangeRequestID?.(null)\n : setActiveChangeRequestID?.(node.id as string),\n })), [dispatch, activeCR?.id]);\n\n return <Tree\n className={className}\n contents={nodes}\n {...eventHandlers}\n />;\n}\n\nexport default ActionableCRTree;\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { StakeholderRoleType } from '../../types';
|
|
2
|
+
import type { ActionableProposalGroup } from './types';
|
|
3
|
+
export declare function getActionableProposalGroupsForRole(role: StakeholderRoleType): readonly ActionableProposalGroup[];
|
|
4
|
+
export declare function getActionableProposalGroupsForRoles(roles: readonly StakeholderRoleType[]): readonly ActionableProposalGroup[];
|
|
5
|
+
export declare const CR_BASE_QUERY = "objPath.indexOf(\"/proposals/\") === 0 && objPath.endsWith(\"main.yaml\")";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getActionableProposalGroupsForRole = getActionableProposalGroupsForRole;
|
|
7
|
+
exports.getActionableProposalGroupsForRoles = getActionableProposalGroupsForRoles;
|
|
8
|
+
exports.CR_BASE_QUERY = void 0;
|
|
9
|
+
|
|
10
|
+
var _cr = require("../../types/cr");
|
|
11
|
+
|
|
12
|
+
function getActionableProposalGroupsForRole(role) {
|
|
13
|
+
return CR_QUERIES_FOR_ROLES.filter(([, roles]) => roles.has(role));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getActionableProposalGroupsForRoles(roles) {
|
|
17
|
+
return roles.flatMap(getActionableProposalGroupsForRole);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const CR_BASE_QUERY = 'objPath.indexOf("/proposals/") === 0 && objPath.endsWith("main.yaml")';
|
|
21
|
+
exports.CR_BASE_QUERY = CR_BASE_QUERY;
|
|
22
|
+
const CR_QUERIES_FOR_ROLES = [['My Drafts', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
|
|
23
|
+
if (stakeholder && stakeholder.gitServerUsername) {
|
|
24
|
+
const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
|
|
25
|
+
const query = `(obj.state === "${_cr.State.DRAFT}" || obj.state === "${_cr.State.RETURNED_FOR_CLARIFICATION}") && (${stakeholderCondition})`;
|
|
26
|
+
return query;
|
|
27
|
+
} else {
|
|
28
|
+
return 'false';
|
|
29
|
+
}
|
|
30
|
+
}], ['My Rejected', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
|
|
31
|
+
// Rejections are actionable because they can be appealed by the submitter.
|
|
32
|
+
if (stakeholder && stakeholder.gitServerUsername) {
|
|
33
|
+
const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
|
|
34
|
+
const query = `(obj.state === "${_cr.State.REJECTED}") && (${stakeholderCondition})`;
|
|
35
|
+
return query;
|
|
36
|
+
} else {
|
|
37
|
+
return 'false';
|
|
38
|
+
}
|
|
39
|
+
}], ['Everyone’s Drafts or Returned', new Set(['manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
|
|
40
|
+
if (stakeholder && stakeholder.gitServerUsername) {
|
|
41
|
+
const stakeholderCondition = `obj.submittingStakeholderGitServerUsername !== "${stakeholder.gitServerUsername}"`;
|
|
42
|
+
const query = `(obj.state === "${_cr.State.DRAFT}" || obj.state === "${_cr.State.RETURNED_FOR_CLARIFICATION}") && (${stakeholderCondition})`;
|
|
43
|
+
return query;
|
|
44
|
+
} else {
|
|
45
|
+
return 'false';
|
|
46
|
+
}
|
|
47
|
+
}], // ['latest reviewed', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
|
|
48
|
+
// // TODO: Should filter only rejected perhaps?
|
|
49
|
+
// // Approved/accepted proposals can be shown in another (public) area.
|
|
50
|
+
// if (stakeholder && stakeholder.gitServerUsername) {
|
|
51
|
+
// const stakeholderCondition = stakeholder?.role !== 'submitter'
|
|
52
|
+
// ? 'true'
|
|
53
|
+
// : `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
|
|
54
|
+
// // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.
|
|
55
|
+
// const query = `(obj.state === "${State.ACCEPTED} || obj.state === "${State.REJECTED} || obj.state === "${State.REJECTION_UPHELD_ON_APPEAL}"") && ${stakeholderCondition}`;
|
|
56
|
+
// return query;
|
|
57
|
+
// } else {
|
|
58
|
+
// return 'false';
|
|
59
|
+
// }
|
|
60
|
+
// // TODO: Implement limit
|
|
61
|
+
// }],
|
|
62
|
+
// ['latest withdrawn', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {
|
|
63
|
+
// if (stakeholder && stakeholder.gitServerUsername) {
|
|
64
|
+
// const stakeholderCondition = stakeholder?.role !== 'submitter'
|
|
65
|
+
// ? 'true'
|
|
66
|
+
// : `obj.submittingStakeholderGitServerUsername === "${stakeholder.gitServerUsername}"`;
|
|
67
|
+
// // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.
|
|
68
|
+
// const query = `(obj.state === "${State.WITHDRAWN}" || obj.state === "${State.APPEAL_WITHDRAWN}") && ${stakeholderCondition}`;
|
|
69
|
+
// return query;
|
|
70
|
+
// } else {
|
|
71
|
+
// return 'false';
|
|
72
|
+
// }
|
|
73
|
+
// // TODO: Implement limit
|
|
74
|
+
// }],
|
|
75
|
+
['Pending Owner Appeal Review', new Set(['owner']), function ownerProposals() {
|
|
76
|
+
return `obj.state === "${_cr.State.APPEALED}"`;
|
|
77
|
+
}], ['Pending Control Body Review', new Set(['control-body', 'owner']), function cbProposals() {
|
|
78
|
+
return `obj.state === "${_cr.State.SUBMITTED_FOR_CONTROL_BODY_REVIEW}"`;
|
|
79
|
+
}], ['Pending Manager Review', new Set(['manager', 'control-body', 'owner']), function managerProposals() {
|
|
80
|
+
return `obj.state === "${_cr.State.PROPOSED}"`;
|
|
81
|
+
}]];
|