@riboseinc/paneron-registry-kit 2.2.34 → 2.2.36
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/package.json +1 -1
- package/proposals/HistoryDrawer.js +1 -0
- package/proposals/HistoryDrawer.js.map +1 -1
- package/proposals/ProposalBrowser.d.ts +8 -1
- package/proposals/ProposalBrowser.js +2 -1
- package/proposals/ProposalBrowser.js.map +1 -1
- package/proposals/ProposalTab.js +1 -0
- package/proposals/ProposalTab.js.map +1 -1
- package/proposals/Search.js +16 -5
- package/proposals/Search.js.map +1 -1
- package/proposals/actionableGroups/Tree.js +7 -8
- package/proposals/actionableGroups/Tree.js.map +1 -1
- package/proposals/types.d.ts +1 -0
- package/proposals/types.js +5 -0
- package/proposals/types.js.map +1 -1
- package/views/sidebar/Registration/index.js +1 -0
- package/views/sidebar/Registration/index.js.map +1 -1
- package/views/util.js +1 -1
- package/views/util.js.map +1 -1
package/package.json
CHANGED
|
@@ -64,6 +64,7 @@ const ProposalHistoryDrawer = function ({
|
|
|
64
64
|
}
|
|
65
65
|
}, (0, _react.jsx)(ProposalList, {
|
|
66
66
|
queryExpression: query,
|
|
67
|
+
keyExpression: "(new Date()).getTime() * 100 - (typeof obj.timeDisposed === 'object' ? (obj.timeDisposed ?? new Date()) : new Date(obj.timeDisposed)).getTime() + Math.floor(Math.random() * 1000)",
|
|
67
68
|
selectedItemPath: selectedItemPath,
|
|
68
69
|
onSelectItem: setSelectedItemPath,
|
|
69
70
|
onOpenItem: (0, _react2.useCallback)(itemPath => spawnTab(`${_protocolRegistry.Protocols.CHANGE_REQUEST}:${itemPath}`), [spawnTab]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HistoryDrawer.js","sourceRoot":"","sources":["../../src/proposals/HistoryDrawer.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport { jsx } from '@emotion/react';\nimport React, { useCallback, useContext, useMemo, useState } from 'react';\nimport { Drawer } from '@blueprintjs/core';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport makeSearchResultList from '@riboseinc/paneron-extension-kit/widgets/SearchResultList';\nimport type { InternalItemReference } from '../types';\nimport { type SomeCR, State, hasSubmitterInput, isDisposed, hadBeenProposed } from '../proposals/types';\nimport { isProposal } from '../proposals/types';\nimport { ProposalType } from './ProposalType';\nimport { Datestamp } from '../views/util';\nimport { DISPOSED_CR_QUERY } from './queries';\nimport { Protocols } from '../views/protocolRegistry';\n\n\n/** History of changes affecting given item. */\nconst ProposalHistoryDrawer: React.FC<{\n itemPath: string\n isOpen: boolean\n onClose: () => void\n onChooseItem?: (itemRef: InternalItemReference) => void\n}> = function ({\n itemPath,\n isOpen, onClose,\n}) {\n const { spawnTab } = useContext(TabbedWorkspaceContext);\n const [ selectedItemPath, setSelectedItemPath ] = useState<string | null>(null);\n // Return disposed CRs\n // that were either accepted or accepted on appeal\n // and have the item in question.\n const query = `return (\n (${DISPOSED_CR_QUERY})\n && (obj.state === \"${State.ACCEPTED}\" || obj.state === \"${State.ACCEPTED_ON_APPEAL}\")\n && obj.items[\"${itemPath}\"] !== undefined\n )`;\n return (\n <Drawer\n isOpen={isOpen}\n onClose={onClose}\n enforceFocus={false}\n size=\"50vw\"\n style={{ padding: '0', width: 'unset' }}>\n <ProposalList\n\tqueryExpression={query}\n\tselectedItemPath={selectedItemPath}\n\tonSelectItem={setSelectedItemPath}\n\tonOpenItem={useCallback((itemPath =>\n\t spawnTab(`${Protocols.CHANGE_REQUEST}:${itemPath}`)\n\t), [spawnTab])}\n\textraItemViewData={useMemo(() => ({ itemPath }), [itemPath])}\n />\n </Drawer>\n );\n};\n\n\nconst ProposalHistoryItem: React.FC<{\n objectData: SomeCR,\n extraData?: { itemPath: string },\n objectPath: string,\n}> = function ({ objectData, extraData }) {\n const justification = hasSubmitterInput(objectData) ? objectData.justification : 'N/A';\n const change_ = extraData?.itemPath ? objectData.items[extraData?.itemPath] : undefined;\n const change = isProposal(change_) ? change_ : null;\n return <span title={`Accepted proposal “${justification}” (proposal ID: ${objectData.id})`}>\n {change ? <ProposalType proposal={change} /> : null}\n {isDisposed(objectData)\n ? <><Datestamp date={objectData.timeDisposed} title=\"Disposed\" />: </>\n : hadBeenProposed(objectData)\n ? <><Datestamp date={objectData.timeProposed} title=\"Proposed\" />: </>\n : null}\n {justification}\n </span>;\n};\n\n\nconst ProposalList = makeSearchResultList<SomeCR, { itemPath: string }>(ProposalHistoryItem, (objPath) => ({\n name: 'Prp.',\n iconProps: {\n icon: 'lightbulb',\n title: objPath,\n htmlTitle: `icon for proposal at ${objPath}`,\n },\n}));\n\n\nexport default ProposalHistoryDrawer;\n"]}
|
|
1
|
+
{"version":3,"file":"HistoryDrawer.js","sourceRoot":"","sources":["../../src/proposals/HistoryDrawer.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kEAAkE,CAAC;AAC1G,OAAO,oBAAoB,MAAM,2DAA2D,CAAC;AAE7F,OAAO,EAAe,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxG,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,+CAA+C;AAC/C,MAAM,qBAAqB,GAKtB,UAAU,EACb,QAAQ,EACR,MAAM,EAAE,OAAO,GAChB;IACC,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;IACxD,MAAM,CAAE,gBAAgB,EAAE,mBAAmB,CAAE,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAChF,sBAAsB;IACtB,kDAAkD;IAClD,iCAAiC;IACjC,MAAM,KAAK,GAAG;OACT,iBAAiB;yBACC,KAAK,CAAC,QAAQ,uBAAuB,KAAK,CAAC,kBAAkB;oBAClE,QAAQ;IACxB,CAAC;IACH,OAAO,CACL,IAAC,MAAM,IACH,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,KAAK,EACnB,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;QACzC,IAAC,YAAY,IAClB,eAAe,EAAE,KAAK,EACtB,aAAa,EAAC,oLAAoL,EAClM,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,mBAAmB,EACjC,UAAU,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,CAClC,QAAQ,CAAC,GAAG,SAAS,CAAC,cAAc,IAAI,QAAQ,EAAE,CAAC,CACpD,EAAE,CAAC,QAAQ,CAAC,CAAC,EACd,iBAAiB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GACrD,CACK,CACV,CAAC;AACJ,CAAC,CAAC;AAGF,MAAM,mBAAmB,GAIpB,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE;IACtC,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;IACvF,MAAM,OAAO,GAAG,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,EAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,OAAO,cAAM,KAAK,EAAE,sBAAsB,aAAa,mBAAmB,UAAU,CAAC,EAAE,GAAG;QACvF,MAAM,CAAC,CAAC,CAAC,IAAC,YAAY,IAAC,QAAQ,EAAE,MAAM,GAAI,CAAC,CAAC,CAAC,IAAI;QAClD,UAAU,CAAC,UAAU,CAAC;YACrB,CAAC,CAAC;gBAAE,IAAC,SAAS,IAAC,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,KAAK,EAAC,UAAU,GAAG;qBAAK;YACtE,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC;gBAC3B,CAAC,CAAC;oBAAE,IAAC,SAAS,IAAC,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,KAAK,EAAC,UAAU,GAAG;yBAAK;gBACtE,CAAC,CAAC,IAAI;QACT,aAAa,CACT,CAAC;AACV,CAAC,CAAC;AAGF,MAAM,YAAY,GAAG,oBAAoB,CAA+B,mBAAmB,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzG,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE;QACT,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,wBAAwB,OAAO,EAAE;KAC7C;CACF,CAAC,CAAC,CAAC;AAGJ,eAAe,qBAAqB,CAAC","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport { jsx } from '@emotion/react';\nimport React, { useCallback, useContext, useMemo, useState } from 'react';\nimport { Drawer } from '@blueprintjs/core';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport makeSearchResultList from '@riboseinc/paneron-extension-kit/widgets/SearchResultList';\nimport type { InternalItemReference } from '../types';\nimport { type SomeCR, State, hasSubmitterInput, isDisposed, hadBeenProposed } from '../proposals/types';\nimport { isProposal } from '../proposals/types';\nimport { ProposalType } from './ProposalType';\nimport { Datestamp } from '../views/util';\nimport { DISPOSED_CR_QUERY } from './queries';\nimport { Protocols } from '../views/protocolRegistry';\n\n\n/** History of changes affecting given item. */\nconst ProposalHistoryDrawer: React.FC<{\n itemPath: string\n isOpen: boolean\n onClose: () => void\n onChooseItem?: (itemRef: InternalItemReference) => void\n}> = function ({\n itemPath,\n isOpen, onClose,\n}) {\n const { spawnTab } = useContext(TabbedWorkspaceContext);\n const [ selectedItemPath, setSelectedItemPath ] = useState<string | null>(null);\n // Return disposed CRs\n // that were either accepted or accepted on appeal\n // and have the item in question.\n const query = `return (\n (${DISPOSED_CR_QUERY})\n && (obj.state === \"${State.ACCEPTED}\" || obj.state === \"${State.ACCEPTED_ON_APPEAL}\")\n && obj.items[\"${itemPath}\"] !== undefined\n )`;\n return (\n <Drawer\n isOpen={isOpen}\n onClose={onClose}\n enforceFocus={false}\n size=\"50vw\"\n style={{ padding: '0', width: 'unset' }}>\n <ProposalList\n\tqueryExpression={query}\n\tkeyExpression=\"(new Date()).getTime() * 100 - (typeof obj.timeDisposed === 'object' ? (obj.timeDisposed ?? new Date()) : new Date(obj.timeDisposed)).getTime() + Math.floor(Math.random() * 1000)\"\n\tselectedItemPath={selectedItemPath}\n\tonSelectItem={setSelectedItemPath}\n\tonOpenItem={useCallback((itemPath =>\n\t spawnTab(`${Protocols.CHANGE_REQUEST}:${itemPath}`)\n\t), [spawnTab])}\n\textraItemViewData={useMemo(() => ({ itemPath }), [itemPath])}\n />\n </Drawer>\n );\n};\n\n\nconst ProposalHistoryItem: React.FC<{\n objectData: SomeCR,\n extraData?: { itemPath: string },\n objectPath: string,\n}> = function ({ objectData, extraData }) {\n const justification = hasSubmitterInput(objectData) ? objectData.justification : 'N/A';\n const change_ = extraData?.itemPath ? objectData.items[extraData?.itemPath] : undefined;\n const change = isProposal(change_) ? change_ : null;\n return <span title={`Accepted proposal “${justification}” (proposal ID: ${objectData.id})`}>\n {change ? <ProposalType proposal={change} /> : null}\n {isDisposed(objectData)\n ? <><Datestamp date={objectData.timeDisposed} title=\"Disposed\" />: </>\n : hadBeenProposed(objectData)\n ? <><Datestamp date={objectData.timeProposed} title=\"Proposed\" />: </>\n : null}\n {justification}\n </span>;\n};\n\n\nconst ProposalList = makeSearchResultList<SomeCR, { itemPath: string }>(ProposalHistoryItem, (objPath) => ({\n name: 'Prp.',\n iconProps: {\n icon: 'lightbulb',\n title: objPath,\n htmlTitle: `icon for proposal at ${objPath}`,\n },\n}));\n\n\nexport default ProposalHistoryDrawer;\n"]}
|
|
@@ -4,6 +4,13 @@ import { jsx } from '@emotion/react';
|
|
|
4
4
|
import type { Drafted } from './types';
|
|
5
5
|
interface ProposalBrowserProps<CR extends Drafted> {
|
|
6
6
|
proposals: CR['items'];
|
|
7
|
+
/**
|
|
8
|
+
* Whether the proposal had been accepted.
|
|
9
|
+
* Influences the jump to current version of the item behavior
|
|
10
|
+
* (for non-accepted proposals, jumping to additions is not allowed
|
|
11
|
+
* since they would not be present in the registry).
|
|
12
|
+
*/
|
|
13
|
+
hadBeenAccepted?: boolean;
|
|
7
14
|
selectedItem?: (string & keyof CR['items']) | null;
|
|
8
15
|
onSelectItem: (selectedItem: (string & keyof CR['items']) | null) => void;
|
|
9
16
|
/**
|
|
@@ -18,5 +25,5 @@ interface ProposalBrowserProps<CR extends Drafted> {
|
|
|
18
25
|
*
|
|
19
26
|
* If no proposals exist, returns null.
|
|
20
27
|
*/
|
|
21
|
-
export declare function ProposalBrowser<CR extends Drafted>({ proposals, onDeleteProposalForItemAtPath, selectedItem, onSelectItem: selectProposal }: ProposalBrowserProps<CR>): jsx.JSX.Element;
|
|
28
|
+
export declare function ProposalBrowser<CR extends Drafted>({ proposals, hadBeenAccepted, onDeleteProposalForItemAtPath, selectedItem, onSelectItem: selectProposal }: ProposalBrowserProps<CR>): jsx.JSX.Element;
|
|
22
29
|
export default ProposalBrowser;
|
|
@@ -46,6 +46,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
46
46
|
*/
|
|
47
47
|
function ProposalBrowser({
|
|
48
48
|
proposals,
|
|
49
|
+
hadBeenAccepted,
|
|
49
50
|
onDeleteProposalForItemAtPath,
|
|
50
51
|
selectedItem,
|
|
51
52
|
onSelectItem: selectProposal
|
|
@@ -168,7 +169,7 @@ function ProposalBrowser({
|
|
|
168
169
|
size: _core.DrawerSize.LARGE,
|
|
169
170
|
enforceFocus: false
|
|
170
171
|
}, proposalCount > 0 && haveSelectedItem ? (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.ButtonGroup, null, (0, _react2.jsx)(_core.Button, {
|
|
171
|
-
disabled: !jumpTo || ((_a = proposals[selectedProposal]) === null || _a === void 0 ? void 0 : _a.type) === 'addition',
|
|
172
|
+
disabled: !jumpTo || ((_a = proposals[selectedProposal]) === null || _a === void 0 ? void 0 : _a.type) === 'addition' && !hadBeenAccepted,
|
|
172
173
|
icon: 'open-application',
|
|
173
174
|
onClick: () => jumpTo === null || jumpTo === void 0 ? void 0 : jumpTo(`${_protocolRegistry.Protocols.ITEM_DETAILS}:${selectedProposal}`),
|
|
174
175
|
title: "Open selected item in a new tab (not applicable to proposed additions)"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProposalBrowser.js","sourceRoot":"","sources":["../../src/proposals/ProposalBrowser.tsx"],"names":[],"mappings":"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","sourcesContent":["\n/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useCallback, useMemo } from 'react';\nimport { ClassNames, jsx, css } from '@emotion/react';\nimport { Select2 as Select } from '@blueprintjs/select';\nimport { ButtonGroup, Button, Drawer, DrawerSize } from '@blueprintjs/core';\n\nimport ErrorBoundary from '@riboseinc/paneron-extension-kit/widgets/ErrorBoundary';\n\nimport { useItemRef, itemPathToItemRef } from '../views/itemPathUtils';\nimport { BrowserCtx, type BrowserCtx as BrowserCtxType } from '../views/BrowserCtx';\nimport { Protocols, type Protocol } from '../views/protocolRegistry';\n\nimport type { Drafted } from './types';\nimport { type ChangeProposalItem, ChangeProposalItemView, getProposalIcon } from './ProposalItem';\nimport ProposalSummary from './ProposalSummary';\nimport ProposalDetail from './ProposalDetail';\n\n\ninterface ProposalBrowserProps<CR extends Drafted> {\n proposals: CR['items']\n\n selectedItem?: (string & keyof CR['items']) | null\n onSelectItem: (selectedItem: (string & keyof CR['items']) | null) => void\n\n /**\n * If provided, button to delete each proposed change\n * is shown in change card list mode.\n */\n onDeleteProposalForItemAtPath?: (itemPath: string) => void\n}\n/**\n * Shows a list of individual proposed changes as cards by default,\n * allowing to expand a proposal and view item details.\n *\n * If no proposals exist, returns null.\n */\nexport function ProposalBrowser<CR extends Drafted>\n({ proposals, onDeleteProposalForItemAtPath, selectedItem, onSelectItem: selectProposal }:\nProposalBrowserProps<CR>) {\n const selectedProposal = selectedItem ?? null;\n\n // TODO: Temporarily unsupported\n // (limitations of current change annotation implementation)\n //const [ showOnlyChanged, setShowOnlyChanged ] = useState(true);\n\n const outerBrowserCtx = useContext(BrowserCtx);\n const { jumpTo, subregisters, useRegisterItemData } = outerBrowserCtx;\n\n /**\n * When jumping to an item affected by current CR,\n * jump in-CR instead of spawning tab.\n */\n const handleCRJump = useCallback(function _handleCRJump(uri: `${Protocol}:${string}`): void {\n if (uri.startsWith(Protocols.ITEM_DETAILS)) {\n const itemPath = uri.split(':')[1];\n if (proposals[itemPath]) {\n selectProposal(itemPath);\n } else {\n jumpTo?.(uri);\n }\n }\n }, [Object.keys(proposals), jumpTo]);\n\n const proposalBrowserCtx: BrowserCtxType = useMemo((() => ({\n ...outerBrowserCtx,\n jumpTo: handleCRJump,\n })), [handleCRJump, outerBrowserCtx]);\n\n /** Paths of register items in proposal. */\n const proposedItemPaths = Object.entries(proposals).map(([itemPath, proposal]) => {\n if (proposal.type === 'clarification' || proposal.type === 'addition') {\n return itemPath;\n } else {\n return undefined;\n }\n }).filter(s => s !== undefined) as string[];\n\n /** Proposed data of register items in proposal. */\n const proposedItemDataReq = useRegisterItemData({\n itemPaths: proposedItemPaths,\n });\n\n /** Pre-existing data of register items in proposal. */\n const currentItemDataReq = useRegisterItemData({\n itemPaths: Object.keys(proposals),\n ignoreActiveCR: true,\n });\n\n const getCurrentItem = useCallback(\n ((itemPath: string) => currentItemDataReq.value[itemPath] ?? null),\n [currentItemDataReq.value]);\n const getProposedItem = useCallback(\n ((itemPath: string) => proposedItemDataReq.value[itemPath] ?? null),\n [proposedItemDataReq.value]);\n\n /** Current register item (if any) corresponding to selected proposal. */\n const selectedItemCurrent = selectedProposal ? getCurrentItem(selectedProposal) : null;\n\n /** Proposed register item corresponding to selected proposal. */\n const selectedItemProposed = selectedProposal ? getProposedItem(selectedProposal) : null;\n\n const selectedItemRef = useItemRef(subregisters !== undefined, selectedProposal);\n\n const handleItemSelect = useCallback(\n ((item: ChangeProposalItem) => selectProposal(item.itemPath)),\n [selectProposal]);\n\n const activeItem: ChangeProposalItem | null = useMemo((() =>\n selectedProposal\n ? ({\n itemPath: selectedProposal,\n proposal: proposals[selectedProposal],\n item: (selectedItemProposed ?? selectedItemCurrent)!,\n itemBefore: selectedItemCurrent ?? undefined,\n itemRef: itemPathToItemRef(subregisters !== undefined, selectedProposal),\n })\n : null\n ), [selectedProposal, proposals, subregisters]);\n\n const allItems: ChangeProposalItem[] = useMemo((() =>\n Object.entries(proposals).map(([itemPath, proposal]) => ({\n itemPath,\n proposal,\n item: (getProposedItem(itemPath) ?? getCurrentItem(itemPath))! ?? null,\n itemBefore: undefined,\n itemRef: itemPathToItemRef(subregisters !== undefined, itemPath),\n }))\n ), [proposals, getCurrentItem, getProposedItem, subregisters !== undefined]);\n\n const haveSelectedItem =\n selectedProposal\n && selectedItemRef\n && proposals[selectedProposal]\n && (selectedItemProposed || selectedItemCurrent);\n\n const proposalCount = Object.keys(proposals).length;\n\n //useEffect(() => {\n // // if (!selectedProposal) {\n // // const firstProposal = Object.keys(proposals)[0];\n // // if (firstProposal) {\n // // if (getCurrentItem(firstProposal) || getProposedItem(firstProposal)) {\n // // selectProposal(firstProposal);\n // // }\n // // }\n // // }\n // if (selectedProposal) {\n // if (selectedProposalDetailRef.current) {\n // selectedProposalDetailRef.current.scrollIntoView({ block: 'center' });\n // }\n // }\n //}, [selectedProposal === null]);\n\n const selectedItemSummary = haveSelectedItem\n ? <ProposalSummary\n itemRef={selectedItemRef}\n item={(selectedItemProposed ?? selectedItemCurrent)!}\n itemBefore={selectedItemCurrent ?? undefined}\n proposal={proposals[selectedProposal]}\n />\n : <>Select item…</>;\n const icon = haveSelectedItem\n ? getProposalIcon(proposals[selectedProposal])\n : undefined;\n\n const selectedItemDrawer = useMemo((() =>\n <Drawer\n isOpen={proposalCount > 0 && haveSelectedItem ? true : false}\n onClose={() => selectProposal(null)}\n size={DrawerSize.LARGE}\n enforceFocus={false}>\n {proposalCount > 0 && haveSelectedItem\n ? <>\n <ButtonGroup>\n <Button\n disabled={!jumpTo || proposals[selectedProposal]?.type === 'addition'}\n icon='open-application'\n onClick={() => jumpTo?.(`${Protocols.ITEM_DETAILS}:${selectedProposal}`)}\n title=\"Open selected item in a new tab (not applicable to proposed additions)\"\n />\n <ClassNames>\n {(({ css: css2 }) =>\n <Select<ChangeProposalItem>\n filterable={false}\n itemsEqual={stringifiedJSONEqual}\n menuProps={{ className: css2(`max-height: 50vh; overflow-y: auto;`) }}\n activeItem={activeItem}\n items={allItems}\n popoverProps={{ minimal: true, matchTargetWidth: true }}\n fill\n itemRenderer={ChangeProposalItemView}\n onItemSelect={handleItemSelect}>\n <Button\n fill\n rightIcon=\"chevron-down\"\n icon={icon}\n title=\"Switch between items in this proposal\"\n css={css`white-space: nowrap;`}>\n {selectedItemSummary}\n </Button>\n </Select>\n )}\n </ClassNames>\n <Button\n onClick={() => selectProposal(null)}\n icon=\"minimize\"\n title=\"Minimize proposed change view\"\n text=\"Minimize\"\n />\n </ButtonGroup>\n <div css={css`position: relative; flex: 1;`}>\n <BrowserCtx.Provider value={proposalBrowserCtx}>\n <ErrorBoundary viewName=\"Proposal detail\">\n <ProposalDetail\n itemRef={selectedItemRef}\n //showOnlyChanged={showOnlyChanged}\n item={(selectedItemProposed ?? selectedItemCurrent)!}\n itemBefore={selectedItemCurrent ?? undefined}\n proposal={proposals[selectedProposal]}\n />\n </ErrorBoundary>\n </BrowserCtx.Provider>\n </div>\n </>\n : null}\n </Drawer>\n ), [proposalCount > 0, haveSelectedItem, selectedItemProposed, selectedItemCurrent, jumpTo, handleItemSelect, selectedProposal && proposals[selectedProposal]]);\n\n return (\n <>\n {selectedItemDrawer}\n </>\n );\n};\n\nfunction stringifiedJSONEqual(i1: any, i2: any): boolean {\n return JSON.stringify(i1) === JSON.stringify(i2);\n}\n\nexport default ProposalBrowser;\n"]}
|
|
1
|
+
{"version":3,"file":"ProposalBrowser.js","sourceRoot":"","sources":["../../src/proposals/ProposalBrowser.tsx"],"names":[],"mappings":"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","sourcesContent":["\n/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useCallback, useMemo } from 'react';\nimport { ClassNames, jsx, css } from '@emotion/react';\nimport { Select2 as Select } from '@blueprintjs/select';\nimport { ButtonGroup, Button, Drawer, DrawerSize } from '@blueprintjs/core';\n\nimport ErrorBoundary from '@riboseinc/paneron-extension-kit/widgets/ErrorBoundary';\n\nimport { useItemRef, itemPathToItemRef } from '../views/itemPathUtils';\nimport { BrowserCtx, type BrowserCtx as BrowserCtxType } from '../views/BrowserCtx';\nimport { Protocols, type Protocol } from '../views/protocolRegistry';\n\nimport type { Drafted } from './types';\nimport { type ChangeProposalItem, ChangeProposalItemView, getProposalIcon } from './ProposalItem';\nimport ProposalSummary from './ProposalSummary';\nimport ProposalDetail from './ProposalDetail';\n\n\ninterface ProposalBrowserProps<CR extends Drafted> {\n proposals: CR['items']\n\n /**\n * Whether the proposal had been accepted.\n * Influences the jump to current version of the item behavior\n * (for non-accepted proposals, jumping to additions is not allowed\n * since they would not be present in the registry).\n */\n hadBeenAccepted?: boolean\n\n selectedItem?: (string & keyof CR['items']) | null\n onSelectItem: (selectedItem: (string & keyof CR['items']) | null) => void\n\n /**\n * If provided, button to delete each proposed change\n * is shown in change card list mode.\n */\n onDeleteProposalForItemAtPath?: (itemPath: string) => void\n}\n/**\n * Shows a list of individual proposed changes as cards by default,\n * allowing to expand a proposal and view item details.\n *\n * If no proposals exist, returns null.\n */\nexport function ProposalBrowser<CR extends Drafted>\n({ proposals, hadBeenAccepted, onDeleteProposalForItemAtPath, selectedItem, onSelectItem: selectProposal }:\nProposalBrowserProps<CR>) {\n const selectedProposal = selectedItem ?? null;\n\n // TODO: Temporarily unsupported\n // (limitations of current change annotation implementation)\n //const [ showOnlyChanged, setShowOnlyChanged ] = useState(true);\n\n const outerBrowserCtx = useContext(BrowserCtx);\n const { jumpTo, subregisters, useRegisterItemData } = outerBrowserCtx;\n\n /**\n * When jumping to an item affected by current CR,\n * jump in-CR instead of spawning tab.\n */\n const handleCRJump = useCallback(function _handleCRJump(uri: `${Protocol}:${string}`): void {\n if (uri.startsWith(Protocols.ITEM_DETAILS)) {\n const itemPath = uri.split(':')[1];\n if (proposals[itemPath]) {\n selectProposal(itemPath);\n } else {\n jumpTo?.(uri);\n }\n }\n }, [Object.keys(proposals), jumpTo]);\n\n const proposalBrowserCtx: BrowserCtxType = useMemo((() => ({\n ...outerBrowserCtx,\n jumpTo: handleCRJump,\n })), [handleCRJump, outerBrowserCtx]);\n\n /** Paths of register items in proposal. */\n const proposedItemPaths = Object.entries(proposals).map(([itemPath, proposal]) => {\n if (proposal.type === 'clarification' || proposal.type === 'addition') {\n return itemPath;\n } else {\n return undefined;\n }\n }).filter(s => s !== undefined) as string[];\n\n /** Proposed data of register items in proposal. */\n const proposedItemDataReq = useRegisterItemData({\n itemPaths: proposedItemPaths,\n });\n\n /** Pre-existing data of register items in proposal. */\n const currentItemDataReq = useRegisterItemData({\n itemPaths: Object.keys(proposals),\n ignoreActiveCR: true,\n });\n\n const getCurrentItem = useCallback(\n ((itemPath: string) => currentItemDataReq.value[itemPath] ?? null),\n [currentItemDataReq.value]);\n const getProposedItem = useCallback(\n ((itemPath: string) => proposedItemDataReq.value[itemPath] ?? null),\n [proposedItemDataReq.value]);\n\n /** Current register item (if any) corresponding to selected proposal. */\n const selectedItemCurrent = selectedProposal ? getCurrentItem(selectedProposal) : null;\n\n /** Proposed register item corresponding to selected proposal. */\n const selectedItemProposed = selectedProposal ? getProposedItem(selectedProposal) : null;\n\n const selectedItemRef = useItemRef(subregisters !== undefined, selectedProposal);\n\n const handleItemSelect = useCallback(\n ((item: ChangeProposalItem) => selectProposal(item.itemPath)),\n [selectProposal]);\n\n const activeItem: ChangeProposalItem | null = useMemo((() =>\n selectedProposal\n ? ({\n itemPath: selectedProposal,\n proposal: proposals[selectedProposal],\n item: (selectedItemProposed ?? selectedItemCurrent)!,\n itemBefore: selectedItemCurrent ?? undefined,\n itemRef: itemPathToItemRef(subregisters !== undefined, selectedProposal),\n })\n : null\n ), [selectedProposal, proposals, subregisters]);\n\n const allItems: ChangeProposalItem[] = useMemo((() =>\n Object.entries(proposals).map(([itemPath, proposal]) => ({\n itemPath,\n proposal,\n item: (getProposedItem(itemPath) ?? getCurrentItem(itemPath))! ?? null,\n itemBefore: undefined,\n itemRef: itemPathToItemRef(subregisters !== undefined, itemPath),\n }))\n ), [proposals, getCurrentItem, getProposedItem, subregisters !== undefined]);\n\n const haveSelectedItem =\n selectedProposal\n && selectedItemRef\n && proposals[selectedProposal]\n && (selectedItemProposed || selectedItemCurrent);\n\n const proposalCount = Object.keys(proposals).length;\n\n //useEffect(() => {\n // // if (!selectedProposal) {\n // // const firstProposal = Object.keys(proposals)[0];\n // // if (firstProposal) {\n // // if (getCurrentItem(firstProposal) || getProposedItem(firstProposal)) {\n // // selectProposal(firstProposal);\n // // }\n // // }\n // // }\n // if (selectedProposal) {\n // if (selectedProposalDetailRef.current) {\n // selectedProposalDetailRef.current.scrollIntoView({ block: 'center' });\n // }\n // }\n //}, [selectedProposal === null]);\n\n const selectedItemSummary = haveSelectedItem\n ? <ProposalSummary\n itemRef={selectedItemRef}\n item={(selectedItemProposed ?? selectedItemCurrent)!}\n itemBefore={selectedItemCurrent ?? undefined}\n proposal={proposals[selectedProposal]}\n />\n : <>Select item…</>;\n const icon = haveSelectedItem\n ? getProposalIcon(proposals[selectedProposal])\n : undefined;\n\n const selectedItemDrawer = useMemo((() =>\n <Drawer\n isOpen={proposalCount > 0 && haveSelectedItem ? true : false}\n onClose={() => selectProposal(null)}\n size={DrawerSize.LARGE}\n enforceFocus={false}>\n {proposalCount > 0 && haveSelectedItem\n ? <>\n <ButtonGroup>\n <Button\n disabled={!jumpTo || (proposals[selectedProposal]?.type === 'addition' && !hadBeenAccepted)}\n icon='open-application'\n onClick={() => jumpTo?.(`${Protocols.ITEM_DETAILS}:${selectedProposal}`)}\n title=\"Open selected item in a new tab (not applicable to proposed additions)\"\n />\n <ClassNames>\n {(({ css: css2 }) =>\n <Select<ChangeProposalItem>\n filterable={false}\n itemsEqual={stringifiedJSONEqual}\n menuProps={{ className: css2(`max-height: 50vh; overflow-y: auto;`) }}\n activeItem={activeItem}\n items={allItems}\n popoverProps={{ minimal: true, matchTargetWidth: true }}\n fill\n itemRenderer={ChangeProposalItemView}\n onItemSelect={handleItemSelect}>\n <Button\n fill\n rightIcon=\"chevron-down\"\n icon={icon}\n title=\"Switch between items in this proposal\"\n css={css`white-space: nowrap;`}>\n {selectedItemSummary}\n </Button>\n </Select>\n )}\n </ClassNames>\n <Button\n onClick={() => selectProposal(null)}\n icon=\"minimize\"\n title=\"Minimize proposed change view\"\n text=\"Minimize\"\n />\n </ButtonGroup>\n <div css={css`position: relative; flex: 1;`}>\n <BrowserCtx.Provider value={proposalBrowserCtx}>\n <ErrorBoundary viewName=\"Proposal detail\">\n <ProposalDetail\n itemRef={selectedItemRef}\n //showOnlyChanged={showOnlyChanged}\n item={(selectedItemProposed ?? selectedItemCurrent)!}\n itemBefore={selectedItemCurrent ?? undefined}\n proposal={proposals[selectedProposal]}\n />\n </ErrorBoundary>\n </BrowserCtx.Provider>\n </div>\n </>\n : null}\n </Drawer>\n ), [proposalCount > 0, haveSelectedItem, selectedItemProposed, selectedItemCurrent, jumpTo, handleItemSelect, selectedProposal && proposals[selectedProposal]]);\n\n return (\n <>\n {selectedItemDrawer}\n </>\n );\n};\n\nfunction stringifiedJSONEqual(i1: any, i2: any): boolean {\n return JSON.stringify(i1) === JSON.stringify(i2);\n}\n\nexport default ProposalBrowser;\n"]}
|
package/proposals/ProposalTab.js
CHANGED
|
@@ -92,6 +92,7 @@ const ProposalTab = function ({
|
|
|
92
92
|
stakeholder: stakeholder,
|
|
93
93
|
onOpenItem: selectItem
|
|
94
94
|
}), (0, _react2.jsx)(_ProposalBrowser.default, {
|
|
95
|
+
hadBeenAccepted: (0, _types.hadBeenAccepted)(proposal),
|
|
95
96
|
proposals: proposal.items,
|
|
96
97
|
onSelectItem: selectItem,
|
|
97
98
|
selectedItem: selectedItem
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProposalTab.js","sourceRoot":"","sources":["../../src/proposals/ProposalTab.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,EAAE,GAGH,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAqB,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ProposalTab.js","sourceRoot":"","sources":["../../src/proposals/ProposalTab.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useMemo, useState } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport {\n UL,\n type Intent,\n type IconName,\n} from '@blueprintjs/core';\n\nimport type { Register, RegisterStakeholder } from '../types';\nimport { TabContentsWithHeader, Datestamp } from '../views/util';\nimport { type SomeCR as CR, isDisposed, hadBeenProposed, hadBeenAccepted } from './types';\n\nimport Workspace from './ProposalWorkspace';\nimport ProposalBrowser from './ProposalBrowser';\n\n\nconst ProposalTab: React.VoidFunctionComponent<{\n proposal: CR\n onDelete?: () => void\n register: Register\n stakeholder?: RegisterStakeholder\n}> = function ({ proposal, onDelete, register, stakeholder }) {\n const pending = !isDisposed(proposal);\n const proposedMarker = <>\n Proposed: {hadBeenProposed(proposal)\n ? <Datestamp date={proposal.timeProposed} />\n : 'not yet'}\n </>;\n const disposedMarker = <>\n Disposed: {!pending\n ? <Datestamp date={proposal.timeDisposed} />\n : 'not yet'}\n </>;\n const editedMarker = <>Edited: <Datestamp date={proposal.timeEdited} /></>;\n const classification = useMemo(() => {\n return [{\n icon: 'lightbulb' as IconName,\n children: \"Proposal\",\n tooltip: {\n icon: 'info-sign' as IconName,\n content: <UL css={css`margin: 0;`}>\n <li>Proposal ID: {proposal.id}</li>\n </UL>,\n },\n }, {\n children: pending\n ? <>pending</>\n : <>disposed</>,\n }, {\n children: proposal.state?.replaceAll('-', ' ') || 'N/A',\n tooltip: {\n icon: 'history' as IconName,\n content: <UL css={css`margin: 0;`}>\n <li>{editedMarker}</li>\n <li>{proposedMarker}</li>\n <li>{disposedMarker}</li>\n </UL>,\n },\n intent: proposal.state === 'accepted'\n ? 'success'\n : proposal.state === 'returned-for-clarification'\n ? 'warning'\n : proposal.state === 'withdrawn' || proposal.state === 'rejected'\n ? 'danger'\n : proposal.state === 'draft'\n ? undefined\n : 'primary' as Intent,\n }];\n }, [\n proposal.state,\n pending,\n editedMarker, proposedMarker, disposedMarker,\n ]);\n\n const [selectedItem, selectItem] = useState<string | null>(null);\n\n const actions = useMemo(() => {\n const actions = [];\n if (onDelete) {\n actions.push({\n text: \"Delete this proposal\",\n onClick: onDelete,\n });\n }\n return actions;\n }, [onDelete]);\n\n return (\n <TabContentsWithHeader\n title={<>{proposal.justification}</>}\n classification={classification}\n actions={actions}>\n <Workspace\n proposal={proposal}\n register={register}\n stakeholder={stakeholder}\n onOpenItem={selectItem}\n />\n <ProposalBrowser\n hadBeenAccepted={hadBeenAccepted(proposal)}\n proposals={proposal.items}\n onSelectItem={selectItem}\n selectedItem={selectedItem}\n />\n </TabContentsWithHeader>\n );\n\n};\n\nexport default ProposalTab;\n"]}
|
package/proposals/Search.js
CHANGED
|
@@ -38,9 +38,9 @@ const ProposalItem = function ({
|
|
|
38
38
|
const registerItem = (_a = extraData.extraItemViewData.itemData[itemPath]) !== null && _a !== void 0 ? _a : null;
|
|
39
39
|
const itemRef = (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, itemPath);
|
|
40
40
|
const clsConfig = getRelatedItemClassConfiguration(itemRef.classID);
|
|
41
|
-
const ListItemView = clsConfig.itemView;
|
|
41
|
+
const ListItemView = clsConfig === null || clsConfig === void 0 ? void 0 : clsConfig.itemView;
|
|
42
42
|
const itemPayload = (_b = registerItem === null || registerItem === void 0 ? void 0 : registerItem.data) !== null && _b !== void 0 ? _b : null;
|
|
43
|
-
const itemView = itemPayload ? (0, _react2.jsx)(_react.default.Fragment, null, clsConfig.title, "\u2003", (0, _react2.jsx)(ListItemView, {
|
|
43
|
+
const itemView = itemPayload && ListItemView ? (0, _react2.jsx)(_react.default.Fragment, null, clsConfig.title, "\u2003", (0, _react2.jsx)(ListItemView, {
|
|
44
44
|
itemData: itemPayload,
|
|
45
45
|
itemRef: itemRef
|
|
46
46
|
})) : (0, _react2.jsx)("span", {
|
|
@@ -67,10 +67,12 @@ const ProposalSearchResultList = (0, _react.memo)(function ({
|
|
|
67
67
|
className
|
|
68
68
|
}) {
|
|
69
69
|
const {
|
|
70
|
-
useRegisterItemData
|
|
70
|
+
useRegisterItemData,
|
|
71
|
+
keyExpression
|
|
71
72
|
} = (0, _react.useContext)(_BrowserCtx.BrowserCtx);
|
|
72
73
|
const proposal = extraItemViewData.proposal;
|
|
73
74
|
const expressionParsed = new Function('objPath', 'obj', queryExpression);
|
|
75
|
+
const keyExpressionParsed = keyExpression ? new Function('obj', `return ${keyExpression}`) : null;
|
|
74
76
|
const proposedItemDataReq = useRegisterItemData({
|
|
75
77
|
itemPaths: Object.keys(proposal.items)
|
|
76
78
|
});
|
|
@@ -79,8 +81,17 @@ const ProposalSearchResultList = (0, _react.memo)(function ({
|
|
|
79
81
|
const objPathInCR = (0, _itemPathUtils.itemPathInCR)(objPath, extraItemViewData.proposal.id);
|
|
80
82
|
return expressionParsed(objPath, itemData[objPath]) || expressionParsed(objPath, obj) || expressionParsed(objPathInCR, itemData[objPath]) || expressionParsed(objPathInCR, obj);
|
|
81
83
|
}, [queryExpression, itemData]);
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
+
const matchingItems = Object.entries(proposal.items).filter(predicate);
|
|
85
|
+
const matchingItemsWithKeys = keyExpressionParsed && !proposedItemDataReq.isUpdating ? matchingItems.map(([p]) => {
|
|
86
|
+
try {
|
|
87
|
+
return [p, keyExpressionParsed(itemData[p])];
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.debug("Failed to run key expression", keyExpression, p, itemData[p], e);
|
|
90
|
+
return [p, p];
|
|
91
|
+
}
|
|
92
|
+
}) : matchingItems.map(([p]) => [p, p]);
|
|
93
|
+
matchingItemsWithKeys.sort((pair1, pair2) => typeof pair1[1] === 'string' ? pair1[1].localeCompare(pair2[1]) : typeof pair1[1] === 'number' ? pair1[1] - pair2[1] : 0);
|
|
94
|
+
const matchingItemIDs = matchingItemsWithKeys.map(([p]) => p);
|
|
84
95
|
const extraData = (0, _react.useMemo)(() => ({
|
|
85
96
|
extraItemViewData: {
|
|
86
97
|
proposal,
|
package/proposals/Search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Search.js","sourceRoot":"","sources":["../../src/proposals/Search.tsx"],"names":[],"mappings":"AAAA,eAAe;AACf,8BAA8B;AAE9B,OAAO,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,QAAQ,EAAE,EAAkB,gBAAgB,EAAiB,MAAM,+CAA+C,CAAC;AAG1H,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAsBjD,MAAM,YAAY,GAClB,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE;;IAC1D,MAAM,EAAE,YAAY,EAAE,gCAAgC,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAElF,MAAM,YAAY,GAAG,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,MAAA,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,mCAAI,IAAI,CAAC;IAE5E,MAAM,OAAO,GAAG,iBAAiB,CAAC,YAAY,KAAK,SAAS,EAAE,QAAQ,CAAC,CAAC;IAExE,MAAM,SAAS,GAAG,gCAAgC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"Search.js","sourceRoot":"","sources":["../../src/proposals/Search.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { memo, useContext, useCallback, useMemo } from 'react';\nimport { jsx, css } from '@emotion/react';\nimport makeList, { type ItemProps, LabelledListIcon, type ListData } from '@riboseinc/paneron-extension-kit/widgets/List';\n\nimport type { RegisterItem } from '../types/item';\nimport { itemPathInCR, itemPathToItemRef } from '../views/itemPathUtils';\nimport { BrowserCtx } from '../views/BrowserCtx';\n\nimport type { SomeCR } from './types';\nimport type { ChangeProposal } from './types';\n\n\nexport interface ProposalListData {\n selectedItemPath: string | null;\n extraItemViewData: { proposal: SomeCR, itemData: Record<string, RegisterItem<any> | null> }\n}\n\nexport interface SearchResultListProps {\n queryExpression: string;\n selectedItemPath: string | null;\n onSelectItem: (itemPath: string | null) => void;\n onOpenItem?: (itemPath: string) => void;\n keyExpression?: string;\n extraItemViewData: { proposal: SomeCR, itemData: Record<string, RegisterItem<any> | null> }\n className?: string;\n}\n\n\nconst ProposalItem: React.FC<ItemProps<ProposalListData>> =\nfunction ({ onSelect, onOpen, extraData, itemRef: itemPath }) {\n const { subregisters, getRelatedItemClassConfiguration } = useContext(BrowserCtx);\n\n const proposalItem = extraData.extraItemViewData.proposal.items[itemPath];\n const registerItem = extraData.extraItemViewData.itemData[itemPath] ?? null;\n\n const itemRef = itemPathToItemRef(subregisters !== undefined, itemPath);\n\n const clsConfig = getRelatedItemClassConfiguration(itemRef.classID);\n const ListItemView = clsConfig?.itemView;\n const itemPayload: Record<string, any> | null = registerItem?.data ?? null;\n \n const itemView = itemPayload && ListItemView\n ? <>\n {clsConfig.title}\n  \n <ListItemView\n itemData={itemPayload}\n itemRef={itemRef}\n />\n </>\n : <span css={css`opacity: .4`}>\n (missing item data at {itemPath})\n </span>;\n\n return (\n <LabelledListIcon\n isSelected={extraData.selectedItemPath === itemPath}\n onSelect={onSelect}\n onOpen={onOpen}\n //contentClassName={(isUpdating && !objData) ? Classes.SKELETON : undefined}\n entityType={{ name: proposalItem.type }}\n >\n {itemView}\n </LabelledListIcon>\n );\n};\n\nconst List = makeList<ProposalListData>(ProposalItem);\n\nexport const ProposalSearchResultList: React.FC<SearchResultListProps> =\nmemo(function ({ extraItemViewData, queryExpression, selectedItemPath, onSelectItem, onOpenItem, className }) {\n const { useRegisterItemData, keyExpression } = useContext(BrowserCtx);\n const proposal = extraItemViewData.proposal;\n\n const expressionParsed =\n new Function('objPath', 'obj', queryExpression) as (objPath: string, obj: null | RegisterItem<any> | ChangeProposal) => boolean;\n\n const keyExpressionParsed = keyExpression\n ? new Function('obj', `return ${keyExpression}`) as (obj: RegisterItem<any>) => any\n : null;\n\n const proposedItemDataReq = useRegisterItemData({\n itemPaths: Object.keys(proposal.items),\n });\n\n const itemData = proposedItemDataReq.value;\n\n const predicate = useCallback(([objPath, obj]: [string, ChangeProposal]) => {\n const objPathInCR = itemPathInCR(objPath, extraItemViewData.proposal.id);\n return (\n expressionParsed(objPath, itemData[objPath])\n || expressionParsed(objPath, obj)\n || expressionParsed(objPathInCR, itemData[objPath])\n || expressionParsed(objPathInCR, obj)\n );\n }, [queryExpression, itemData]);\n\n const matchingItems = Object.entries(proposal.items).filter(predicate);\n\n const matchingItemsWithKeys = keyExpressionParsed && !proposedItemDataReq.isUpdating\n ? matchingItems.map(([p, ]) => {\n try {\n return [p, keyExpressionParsed(itemData[p]!)];\n } catch (e) {\n console.debug(\"Failed to run key expression\", keyExpression, p, itemData[p], e);\n return [p, p];\n }\n })\n : matchingItems.map(([p, ]) => [p, p]);\n\n matchingItemsWithKeys.sort((pair1, pair2) =>\n typeof pair1[1] === 'string'\n ? pair1[1].localeCompare(pair2[1])\n : typeof pair1[1] === 'number'\n ? pair1[1] - pair2[1]\n : 0);\n\n const matchingItemIDs = matchingItemsWithKeys.map(([p, ]) => p);\n\n const extraData: ProposalListData = useMemo((() => ({\n extraItemViewData: { proposal, itemData },\n selectedItemPath,\n })), [selectedItemPath, proposal, itemData]);\n\n const getListData = useCallback(function _getListData(): ListData<ProposalListData> | null {\n return {\n items: matchingItemIDs,\n selectedItem: selectedItemPath,\n selectItem: onSelectItem,\n openItem: onOpenItem,\n itemHeight: 32,\n padding: 0,\n extraData,\n };\n }, [matchingItemIDs.join(','), extraData, onOpenItem, onSelectItem]);\n\n return <List\n className={className}\n getListData={getListData}\n />;\n});\n\n\nexport default ProposalSearchResultList;\n"]}
|
|
@@ -129,15 +129,14 @@ const ActionableCRTree = function ({
|
|
|
129
129
|
}) => proposals !== null && proposals !== void 0 ? proposals : []).find(p => p.id === state.selectedItemID) ? state.selectedItemID : undefined : undefined
|
|
130
130
|
}), [activeCR === null || activeCR === void 0 ? void 0 : activeCR.id, setActiveChangeRequestID, actionableProposals, state.selectedItemID, state.expandedFolderIDs.join(',')]);
|
|
131
131
|
const activate = (0, _react.useCallback)(proposalID => {
|
|
132
|
-
if (proposalID
|
|
133
|
-
//setActiveChangeRequestID?.(null);
|
|
134
|
-
} else {
|
|
135
|
-
// activate & open proposal dashboard
|
|
132
|
+
if (proposalID !== (activeCR === null || activeCR === void 0 ? void 0 : activeCR.id)) {
|
|
136
133
|
setActiveChangeRequestID === null || setActiveChangeRequestID === void 0 ? void 0 : setActiveChangeRequestID(proposalID);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
} // open proposal dashboard regardless
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
spawnTab(_protocolRegistry.Protocols.PROPOSAL_WORK, {
|
|
138
|
+
atIdx: 0
|
|
139
|
+
});
|
|
141
140
|
}, [activeCR === null || activeCR === void 0 ? void 0 : activeCR.id, setActiveChangeRequestID, spawnTab]);
|
|
142
141
|
const eventHandlers = (0, _react.useMemo)(() => ({
|
|
143
142
|
onNodeClick: node => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tree.js","sourceRoot":"","sources":["../../../src/proposals/actionableGroups/Tree.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useCallback, 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 { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { SomeCR as CR } from '../types';\nimport { ChangeRequestContext } from '../ChangeRequestContext';\nimport { BrowserCtx } from '../../views/BrowserCtx';\nimport { getActionableProposalGroupsForRoles } from './queries';\nimport { Protocols } from '../../views/protocolRegistry';\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 const { spawnTab } = useContext(TabbedWorkspaceContext);\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 onActivateCR: setActiveChangeRequestID,\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, setActiveChangeRequestID, actionableProposals, state.selectedItemID, state.expandedFolderIDs.join(',')]);\n\n const activate = useCallback(((proposalID: string) => {\n if (proposalID === activeCR?.id) {\n // deactivate\n //setActiveChangeRequestID?.(null);\n } else {\n // activate & open proposal dashboard\n setActiveChangeRequestID?.(proposalID as string)\n spawnTab(Protocols.PROPOSAL_WORK, { atIdx: 0 });\n }\n }), [activeCR?.id, setActiveChangeRequestID, spawnTab]);\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 : activate(node.id as string),\n })), [dispatch, activate]);\n\n return <Tree\n className={className}\n contents={nodes}\n {...eventHandlers}\n />;\n}\n\nexport default ActionableCRTree;\n"]}
|
|
1
|
+
{"version":3,"file":"Tree.js","sourceRoot":"","sources":["../../../src/proposals/actionableGroups/Tree.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useCallback, 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 { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\nimport type { SomeCR as CR } from '../types';\nimport { ChangeRequestContext } from '../ChangeRequestContext';\nimport { BrowserCtx } from '../../views/BrowserCtx';\nimport { getActionableProposalGroupsForRoles } from './queries';\nimport { Protocols } from '../../views/protocolRegistry';\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 const { spawnTab } = useContext(TabbedWorkspaceContext);\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 onActivateCR: setActiveChangeRequestID,\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, setActiveChangeRequestID, actionableProposals, state.selectedItemID, state.expandedFolderIDs.join(',')]);\n\n const activate = useCallback(((proposalID: string) => {\n if (proposalID !== activeCR?.id) {\n setActiveChangeRequestID?.(proposalID as string)\n }\n // open proposal dashboard regardless\n spawnTab(Protocols.PROPOSAL_WORK, { atIdx: 0 });\n }), [activeCR?.id, setActiveChangeRequestID, spawnTab]);\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 : activate(node.id as string),\n })), [dispatch, activate]);\n\n return <Tree\n className={className}\n contents={nodes}\n {...eventHandlers}\n />;\n}\n\nexport default ActionableCRTree;\n"]}
|
package/proposals/types.d.ts
CHANGED
|
@@ -169,6 +169,7 @@ export declare function isWithdrawn(cr: Base): cr is Withdrawn;
|
|
|
169
169
|
export declare function hadBeenProposed(cr: Base): cr is Base & {
|
|
170
170
|
timeProposed: Date;
|
|
171
171
|
};
|
|
172
|
+
export declare function hadBeenAccepted(cr: Base): cr is Accepted | AcceptedOnAppeal;
|
|
172
173
|
/** A proposal that had been disposed is not pending, not actionable. */
|
|
173
174
|
export declare function isDisposed(cr: Base): cr is Base & {
|
|
174
175
|
timeDisposed: Date;
|
package/proposals/types.js
CHANGED
|
@@ -23,6 +23,7 @@ exports.isDrafted = isDrafted;
|
|
|
23
23
|
exports.isProposed = isProposed;
|
|
24
24
|
exports.isWithdrawn = isWithdrawn;
|
|
25
25
|
exports.hadBeenProposed = hadBeenProposed;
|
|
26
|
+
exports.hadBeenAccepted = hadBeenAccepted;
|
|
26
27
|
exports.isDisposed = isDisposed;
|
|
27
28
|
exports.isSubmittedForControlBodyReview = isSubmittedForControlBodyReview;
|
|
28
29
|
exports.isReturnedForClarification = isReturnedForClarification;
|
|
@@ -182,6 +183,10 @@ function isWithdrawn(cr) {
|
|
|
182
183
|
function hadBeenProposed(cr) {
|
|
183
184
|
return cr && cr.hasOwnProperty('timeProposed') && !!cr.timeProposed;
|
|
184
185
|
}
|
|
186
|
+
|
|
187
|
+
function hadBeenAccepted(cr) {
|
|
188
|
+
return isDisposed(cr) && (isAccepted(cr) || isAcceptedOnAppeal(cr));
|
|
189
|
+
}
|
|
185
190
|
/** A proposal that had been disposed is not pending, not actionable. */
|
|
186
191
|
|
|
187
192
|
|
package/proposals/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proposals/types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proposals, group proposals,\n * group proposal states and state transitions.\n */\n\nimport type React from 'react';\nimport type { DatasetContext } from '@riboseinc/paneron-extension-kit/types/renderer';\n\nimport type {\n InternalItemReference,\n Payload,\n RegisterItem,\n} from '../types';\n\nimport type { RegisterStakeholder } from '../types/stakeholder';\nimport type { Citation } from '../types/util';\n\n\n// Proposal items\n// ==============\n\n/**\n * Item paths in proposal set must start with a slash\n * and will be treated relative to dataset root.\n * Object paths should conform to registry item path shape\n * of `/<classID>/<itemID>.yaml`.\n * (the `[/subregisterID]/<classID>/<itemID>.yaml` is acceptable\n * but deprecated, as subregisters are deprecated).\n */\nexport type ProposalSet = {\n [objectPath: string]: ChangeProposal\n}\n\nexport const ChangeProposalType = {\n ADDITION: 'addition',\n CLARIFICATION: 'clarification',\n AMENDMENT: 'amendment',\n} as const;\nexport const PROPOSAL_TYPES = [\n ChangeProposalType.ADDITION,\n ChangeProposalType.CLARIFICATION,\n ChangeProposalType.AMENDMENT,\n] as const;\n\ninterface BaseProposal {\n //itemID: RegisterItemID\n disposition?: 'accepted' | 'notAccepted'\n type: typeof PROPOSAL_TYPES[number]\n sources?: Citation[]\n}\n\nexport interface Addition extends BaseProposal {\n type: typeof ChangeProposalType.ADDITION\n ///** New item data. */\n //payload: Payload\n}\n\nexport interface Clarification extends BaseProposal {\n type: typeof ChangeProposalType.CLARIFICATION\n ///** Updated item data */\n //payload: Payload\n}\n\nexport const AmendmentType = {\n SUPERSESSION: 'supersession',\n RETIREMENT: 'retirement',\n INVALIDATION: 'invalidation',\n} as const;\nexport type AmendmentTypeType = typeof AmendmentType[keyof typeof AmendmentType];\nexport const AMENDMENT_TYPES = [\n AmendmentType.SUPERSESSION,\n AmendmentType.RETIREMENT,\n AmendmentType.INVALIDATION,\n] as const;\n\ninterface BaseAmendment extends BaseProposal {\n type: typeof ChangeProposalType.AMENDMENT\n amendmentType: AmendmentTypeType\n}\nexport interface Retirement extends BaseAmendment {\n amendmentType: typeof AmendmentType.RETIREMENT\n}\nexport interface Supersession extends BaseAmendment {\n amendmentType: typeof AmendmentType.SUPERSESSION\n supersedingItemIDs: string[]\n}\nexport interface Invalidation extends BaseAmendment {\n amendmentType: typeof AmendmentType.INVALIDATION\n}\nexport type Amendment = Supersession | Retirement | Invalidation\n\nexport type ChangeProposal = Amendment | Clarification | Addition\n\nexport function isBaseProposal(val: any): val is BaseProposal {\n return PROPOSAL_TYPES.indexOf(val?.type) >= 0;\n}\nexport function isProposal(val: any): val is ChangeProposal {\n return (isBaseProposal(val) && (\n isAddition(val)\n || isClarification(val)\n || isAmendment(val)));\n}\nexport function isAddition(val: BaseProposal): val is Addition {\n return (val.type === ChangeProposalType.ADDITION);\n}\nexport function isClarification(val: BaseProposal): val is Clarification {\n return (val.type === ChangeProposalType.CLARIFICATION);\n}\nexport function isBaseAmendment(val: BaseProposal): val is BaseAmendment {\n return (\n val.type === ChangeProposalType.AMENDMENT\n && AMENDMENT_TYPES.indexOf((val as Amendment).amendmentType) >= 0);\n}\nexport function isAmendment(val: any): val is Amendment {\n return (isBaseAmendment(val) && (\n isRetirement(val)\n || isSupersession(val)\n || isInvalidation(val)));\n}\nexport function isRetirement(val: BaseAmendment): val is Retirement {\n return val.amendmentType === AmendmentType.RETIREMENT;\n}\nexport function isSupersession(val: BaseAmendment): val is Supersession {\n return val.amendmentType === AmendmentType.SUPERSESSION;\n}\nexport function isInvalidation(val: BaseAmendment): val is Invalidation {\n return val.amendmentType === AmendmentType.INVALIDATION;\n}\n\n\n// Change request types, states and state transitions.\n\nexport function isSubmittedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n //isSubmitter(stakeholder) &&\n stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n}\n\n\ntype ItemDataset = Record<string, RegisterItem<any> | null>;\n\n\n// =====================\n// Change request states\n// =====================\n\n/** Used in place of enum for convenience. */\nexport const State = {\n DRAFT: 'draft',\n PROPOSED: 'proposed',\n SUBMITTED_FOR_CONTROL_BODY_REVIEW: 'pending-control-body-review',\n RETURNED_FOR_CLARIFICATION: 'returned-for-clarification',\n WITHDRAWN: 'withdrawn',\n ACCEPTED: 'accepted',\n REJECTED: 'rejected',\n APPEALED: 'rejection-appealed-to-owner',\n ACCEPTED_ON_APPEAL: 'accepted-on-appeal',\n REJECTION_UPHELD_ON_APPEAL: 'rejection-upheld-on-appeal',\n APPEAL_WITHDRAWN: 'appeal-withdrawn',\n} as const;\n\nexport type StateType = typeof State[keyof typeof State];\n\nexport function isState(val: string): val is StateType {\n return Object.values(State).indexOf(val as StateType) >= 0;\n}\n\n/** A subset of `State` that represents editable states. */\nexport const EditableState = [\n State.DRAFT,\n State.RETURNED_FOR_CLARIFICATION,\n] as const;\n\nexport type EditableStateType = StateType & typeof EditableState[number];\n\nexport function isEditableState(state: StateType): state is EditableStateType {\n return EditableState.indexOf(state as EditableStateType) >= 0;\n}\n\n\n\n// ======================\n// Change request classes\n// ======================\n\n/**\n * Base change request type.\n *\n * Note that e.g. type Base<typeof State.DRAFT> does not equal to Drafted\n * because Drafted includes additional information (namely, SubmitterInput).\n *\n * If the state of a CR matters, this type should not be used directly\n * and concrete types should be used instead.\n */\nexport interface Base<S extends StateType = StateType>\n{\n id: string;\n // decision: typeof Decision[keyof typeof Decision]\n // disposition?: typeof Disposition[keyof typeof Disposition]\n state: S;\n\n /**\n * Used to match against stakeholders declared in register metadata.\n */\n submittingStakeholderGitServerUsername: string;\n\n items: ProposalSet;\n\n /**\n * Against which register version changes were proposed.\n */\n registerVersion: string;\n\n /**\n * A link to external discussion.\n */\n externalDiscussionURI?: string;\n\n pastTransitions?: TransitionEntry[];\n}\n\n\nexport interface TransitionEntry {\n /** Verb in past tense. */\n label: string;\n\n timestamp: Date;\n fromState: StateType;\n toState: StateType;\n stakeholder: RegisterStakeholder;\n input: StateInput;\n}\n\n\nexport function isCreatedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return stakeholder.gitServerUsername?.trim() !== '' && stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername;\n}\n\n/** Whether given `cr` can be edited (as in, items changed) by specified stakeholder. */\nexport function canBeEditedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return isCreatedBy(stakeholder, cr) && isEditableState(cr.state);\n}\n\n/**\n * Whether given `cr` can be deleted by given stakeholder.\n * Unlike editing, deletion is possible only if there are no items\n * and CR was never proposed.\n */\nexport function canBeDeletedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n isCreatedBy(stakeholder, cr)\n && isDrafted(cr)\n //&& Object.keys(cr.items).length < 1 // Only allow deleting empty CRs\n && !hadBeenProposed(cr) // If it had been proposed, it should be withdrawn instead.\n );\n}\n\n\n/** Proposal structure for single-file proposal import format. */\nexport interface ImportableCR {\n /** Proposal data. */\n proposalDraft: Drafted,\n /** Register item data for additions & clarifications. */\n itemPayloads: ItemDataset,\n // TODO: Rename ImportableCR.itemPayloads to newItemData\n}\nexport function isImportableCR(val: any): val is ImportableCR {\n // TODO: More complete check\n return (\n val.proposalDraft.id\n && isDrafted(val.proposalDraft as Base)\n && Object.keys(val.itemPayloads).length > 0);\n}\n\n\n/**\n * A change request in any state.\n * Contains a superset of all possible properties, but all optional.\n * XXX: ^^^ This is a lie. Should be changed from | to & with Partial<>?\n */\nexport type SomeCR = \n | Drafted\n | Proposed\n | Withdrawn\n | ReturnedForClarificationByManager\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByControlBody\n | Accepted\n | Rejected\n | RejectionUpheld\n | AcceptedOnAppeal\n | RejectedWithAppealWithdrawn;\n\nexport type Withdrawable =\n | Proposed\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Proposable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type SomeEditable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Disposed =\n | Withdrawn\n | Accepted\n | Rejected\n | AcceptedOnAppeal\n | RejectionUpheld;\n\n\n// More specific change request types.\n// TODO: Refactor to avoid confusiong between current state e.g. Proposed)\n// and type (Proposed, to which all inheriting classes also conform)\n\nexport interface Drafted extends\n SubmitterInput,\n Base<typeof State.DRAFT> { timeStarted: Date, timeEdited: Date }\nexport function isDrafted(cr: Base): cr is Drafted {\n return isInState(cr, State.DRAFT);\n}\n\nexport interface Proposed extends\n Omit<Drafted, 'state'>,\n Base<typeof State.PROPOSED> { timeProposed: Date }\nexport function isProposed(cr: Base): cr is Proposed {\n return isInState(cr, State.PROPOSED);\n}\n\nexport interface Withdrawn extends\n Omit<Withdrawable, 'state'>,\n Base<typeof State.WITHDRAWN> { timeDisposed: Date }\nexport function isWithdrawn(cr: Base): cr is Withdrawn {\n return isInState(cr, State.WITHDRAWN);\n}\n\n/** CR was proposed at least once. */\nexport function hadBeenProposed(cr: Base): cr is Base & { timeProposed: Date } {\n return cr && cr.hasOwnProperty('timeProposed') && !!(cr as Proposed).timeProposed;\n}\n/** A proposal that had been disposed is not pending, not actionable. */\nexport function isDisposed(cr: Base): cr is Base & { timeDisposed: Date } {\n return cr && cr.hasOwnProperty('timeDisposed') && !!(cr as Disposed).timeDisposed;\n // TODO: include status checks, too?\n //return [\n // State.WITHDRAWN,\n // State.ACCEPTED,\n // State.REJECTED,\n // State.REJECTION_UPHELD_ON_APPEAL,\n // State.ACCEPTED_ON_APPEAL,\n //].some(s => cr.state === s);\n}\n\nexport interface SubmittedForControlBodyReview extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW> {}\n\nexport function isSubmittedForControlBodyReview(cr: Base): cr is SubmittedForControlBodyReview {\n return isInState(cr, State.SUBMITTED_FOR_CONTROL_BODY_REVIEW)\n}\n\nexport interface ReturnedForClarificationByManager extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface ReturnedForClarificationByControlBody extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport function isReturnedForClarification(cr: Base): cr is (ReturnedForClarificationByManager | ReturnedForClarificationByControlBody) {\n return isInState(cr, State.RETURNED_FOR_CLARIFICATION)\n}\n\nexport interface Accepted extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.ACCEPTED> { timeDisposed: Date }\nexport function isAccepted(cr: Base): cr is Accepted {\n return isInState(cr, State.ACCEPTED);\n}\n\nexport interface Rejected extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.REJECTED> { timeDisposed: Date }\nexport function isRejected(cr: Base): cr is Rejected {\n return isInState(cr, State.REJECTED);\n}\n\nexport interface Appealed extends\n Omit<Rejected, 'state' | 'timeDisposed'>,\n AppealRequest,\n Base<typeof State.APPEALED> { timeDisposed: undefined }\nexport function isAppealed(cr: Base): cr is Appealed {\n return isInState(cr, State.APPEALED);\n}\n\nexport interface RejectionUpheld extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.REJECTION_UPHELD_ON_APPEAL> { timeDisposed: Date }\nexport function isRejectedOnAppeal(cr: Base): cr is RejectionUpheld {\n return isInState(cr, State.REJECTION_UPHELD_ON_APPEAL);\n}\n\nexport interface AcceptedOnAppeal extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.ACCEPTED_ON_APPEAL> { timeDisposed: Date }\nexport function isAcceptedOnAppeal(cr: Base): cr is AcceptedOnAppeal {\n return isInState(cr, State.ACCEPTED_ON_APPEAL);\n}\n\nexport interface RejectedWithAppealWithdrawn extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n Base<typeof State.APPEAL_WITHDRAWN> { timeDisposed: Date }\nexport function isRejectedWithAppealWithdrawn(cr: Base): cr is RejectedWithAppealWithdrawn {\n return isInState(cr, State.APPEAL_WITHDRAWN);\n}\n\n\n\n// Input required when transitioning to different states\n\nexport interface SubmitterInput {\n justification: string;\n}\nexport function hasSubmitterInput(val: any): val is SubmitterInput {\n return val.hasOwnProperty('justification') && typeof val.justification === 'string';\n}\nexport interface RegisterManagerInput {\n registerManagerNotes: string;\n}\nexport function hasRegisterManagerInput(val: any): val is RegisterManagerInput {\n return val.hasOwnProperty('registerManagerNotes') && typeof val.registerManagerNotes === 'string';\n}\nexport interface ControlBodyInput {\n controlBodyNotes: string;\n controlBodyDecisionEvent: string;\n}\nexport function hasControlBodyInput(val: any): val is ControlBodyInput {\n return (\n val.hasOwnProperty('controlBodyNotes') && typeof val.controlBodyNotes === 'string' &&\n val.hasOwnProperty('controlBodyDecisionEvent') && typeof val.controlBodyDecisionEvent === 'string');\n}\nexport interface AppealRequest {\n appealReason: string;\n}\nexport function hasAppealRequest(val: any): val is AppealRequest {\n return val.hasOwnProperty('appealReason') && typeof val.appealReason === 'string';\n}\nexport interface RegisterOwnerInput {\n registerOwnerNotes: string;\n}\nexport function hasRegisterOwnerInput(val: any): val is RegisterOwnerInput {\n return val.hasOwnProperty('registerOwnerNotes') && typeof val.registerOwnerNotes === 'string';\n}\n\nexport type StateInput =\n | SubmitterInput\n | RegisterManagerInput\n | ControlBodyInput\n | AppealRequest\n | RegisterOwnerInput;\n\n\n/** \n * CR type guard helper.\n * Normally you would not use it directly and instead use\n * more specific is[Type]() helper from this module.\n *\n * Checks CR type using the `state` property.\n * Does not validate other properties.\n *\n * Usage:\n *\n * @example\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.DRAFT)) {\n * // Can assume someCR is Drafted\n * }\n * ```\n *\n * It’ll try to tell you if you mismatch those.\n *\n * @example\n * Will not compile:\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.PROPOSED)) {\n * // Compile error\n * // because State.PROPOSED is not a possible value of Drafted[\"state\"]\n * }\n * ```\n *\n * @example\n * Incorrect usage (do not do this):\n * ```ts\n * let someCR;\n * if (isInState(someCR, State.DRAFT)) {\n * // Can NOT assume someCR is Drafted\n * // The compiler must know the expected concrete CR type\n * }\n * ```\n */\nfunction isInState<CR extends Base>(cr: Base, s: CR[\"state\"]): cr is CR {\n return cr.state === s;\n}\n\n\n\n\n// ===========\n// Transitions\n// ===========\n\n/**\n * A function that transitions CR1 to CR2.\n *\n * The function is declared to return the object\n * without the `state` field, it is set\n * by common wrapper function to reduce duplication.\n */\nexport type Transition<\n /** From CR of this subtype */\n CR1 extends Base,\n /** To CR of this subtype */\n CR2 extends Base,\n /** Using this extra information */\n P extends Record<string, any> | null = null,\n> = (cr: CR1, payload: P) => Omit<CR2, 'state'>;\n\n\nexport type AlterApprovedCR = (\n crID: string,\n proposals: ProposalSet,\n origItemData: ItemDataset,\n newItemData: ItemDataset,\n opts: Pick<DatasetContext, 'getMapReducedData'>,\n) => Promise<{\n proposals: ProposalSet,\n origItemData: ItemDataset,\n newItemData: ItemDataset,\n}>\n\n\n/**\n * Describes a transition.\n *\n * @typeParam CR1: Change request source state type\n * @typeParam CR2: Change request target state type\n * @typeParam P: Extra input needed to transition, if any\n */\nexport interface TransitionConfig<CR1 extends Base, CR2 extends Base, P extends Record<string, any> | null = null> {\n /**\n * Function that implements the transition.\n * Takes a CR in the original state and returns CR in the new state.\n * Additionally, takes appropriate payload, if any, for the transition\n * (e.g., register manager or control body notes).\n *\n * For function implementor:\n *\n * - Function MUST NOT modify CR in place.\n * - Function should throw if submitted payload does not conform to requirements.\n */\n func: Transition<CR1, CR2, P>;\n\n targetState: CR2[\"state\"];\n\n /** Title. Use verb. */\n title: string;\n\n hint?: string | JSX.Element;\n\n /** Widget that can be used to view or enter extra input. */\n Widget: P extends null ? null : React.FC<{ value: P, onChange?: (userInput: P) => void }>;\n\n /**\n * Function that returns true\n * if given stakeholder can perform this transition on given CR.\n */\n canBeTransitionedBy: (stakeholder: RegisterStakeholder, cr: CR1) => boolean;\n}\n\n\n// type TransitionSpec = {\n// [S1 in StateType]?: {\n// [S2 in StateType]?: Transition<Base<S1>, Base<S2>, Record<string, any>>\n// }\n// }\n\n\n/**\n * Source of truth for available transitions.\n * When updating change request business logic,\n * this is the type that should be modified.\n *\n * It will cause compile errors until transition implementation\n * is updated correspondingly.\n */\nexport type Transitions = {\n [State.DRAFT]: {\n // [State.DRAFT]:\n // TransitionConfig<Drafted, Drafted, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.PROPOSED]:\n TransitionConfig<Drafted, Proposed, SubmitterInput>;\n };\n [State.PROPOSED]: {\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]:\n TransitionConfig<Proposed, SubmittedForControlBodyReview, RegisterManagerInput>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<Proposed, ReturnedForClarificationByManager, RegisterManagerInput>;\n };\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [State.WITHDRAWN]:\n TransitionConfig<SubmittedForControlBodyReview, Withdrawn>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<SubmittedForControlBodyReview, ReturnedForClarificationByControlBody, ControlBodyInput>;\n [State.REJECTED]:\n TransitionConfig<SubmittedForControlBodyReview, Rejected, ControlBodyInput>;\n [State.ACCEPTED]:\n TransitionConfig<SubmittedForControlBodyReview, Accepted, ControlBodyInput>;\n };\n [State.RETURNED_FOR_CLARIFICATION]: {\n [State.PROPOSED]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Proposed, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Withdrawn>;\n };\n [State.REJECTED]: {\n [State.APPEALED]:\n TransitionConfig<Rejected, Appealed, AppealRequest>;\n };\n [State.APPEALED]: {\n [State.APPEAL_WITHDRAWN]:\n TransitionConfig<Appealed, RejectedWithAppealWithdrawn>;\n [State.ACCEPTED_ON_APPEAL]:\n TransitionConfig<Appealed, AcceptedOnAppeal, RegisterOwnerInput>;\n [State.REJECTION_UPHELD_ON_APPEAL]:\n TransitionConfig<Appealed, RejectionUpheld, RegisterOwnerInput>;\n };\n}\n\n\n// Utility\n// =======\n\nexport interface ProposalProps<P extends ChangeProposal> {\n proposal: P\n\n /** Highlight changes. */\n showDiff?: boolean\n\n /** In diff mode, only show changed data. (Provisional.) */\n showOnlyChanged?: boolean\n\n itemRef: InternalItemReference\n item: RegisterItem<Payload>\n itemBefore: P extends Clarification ? RegisterItem<Payload> : undefined\n onChange?: (newProposal: P) => void\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proposals/types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Proposals, group proposals,\n * group proposal states and state transitions.\n */\n\nimport type React from 'react';\nimport type { DatasetContext } from '@riboseinc/paneron-extension-kit/types/renderer';\n\nimport type {\n InternalItemReference,\n Payload,\n RegisterItem,\n} from '../types';\n\nimport type { RegisterStakeholder } from '../types/stakeholder';\nimport type { Citation } from '../types/util';\n\n\n// Proposal items\n// ==============\n\n/**\n * Item paths in proposal set must start with a slash\n * and will be treated relative to dataset root.\n * Object paths should conform to registry item path shape\n * of `/<classID>/<itemID>.yaml`.\n * (the `[/subregisterID]/<classID>/<itemID>.yaml` is acceptable\n * but deprecated, as subregisters are deprecated).\n */\nexport type ProposalSet = {\n [objectPath: string]: ChangeProposal\n}\n\nexport const ChangeProposalType = {\n ADDITION: 'addition',\n CLARIFICATION: 'clarification',\n AMENDMENT: 'amendment',\n} as const;\nexport const PROPOSAL_TYPES = [\n ChangeProposalType.ADDITION,\n ChangeProposalType.CLARIFICATION,\n ChangeProposalType.AMENDMENT,\n] as const;\n\ninterface BaseProposal {\n //itemID: RegisterItemID\n disposition?: 'accepted' | 'notAccepted'\n type: typeof PROPOSAL_TYPES[number]\n sources?: Citation[]\n}\n\nexport interface Addition extends BaseProposal {\n type: typeof ChangeProposalType.ADDITION\n ///** New item data. */\n //payload: Payload\n}\n\nexport interface Clarification extends BaseProposal {\n type: typeof ChangeProposalType.CLARIFICATION\n ///** Updated item data */\n //payload: Payload\n}\n\nexport const AmendmentType = {\n SUPERSESSION: 'supersession',\n RETIREMENT: 'retirement',\n INVALIDATION: 'invalidation',\n} as const;\nexport type AmendmentTypeType = typeof AmendmentType[keyof typeof AmendmentType];\nexport const AMENDMENT_TYPES = [\n AmendmentType.SUPERSESSION,\n AmendmentType.RETIREMENT,\n AmendmentType.INVALIDATION,\n] as const;\n\ninterface BaseAmendment extends BaseProposal {\n type: typeof ChangeProposalType.AMENDMENT\n amendmentType: AmendmentTypeType\n}\nexport interface Retirement extends BaseAmendment {\n amendmentType: typeof AmendmentType.RETIREMENT\n}\nexport interface Supersession extends BaseAmendment {\n amendmentType: typeof AmendmentType.SUPERSESSION\n supersedingItemIDs: string[]\n}\nexport interface Invalidation extends BaseAmendment {\n amendmentType: typeof AmendmentType.INVALIDATION\n}\nexport type Amendment = Supersession | Retirement | Invalidation\n\nexport type ChangeProposal = Amendment | Clarification | Addition\n\nexport function isBaseProposal(val: any): val is BaseProposal {\n return PROPOSAL_TYPES.indexOf(val?.type) >= 0;\n}\nexport function isProposal(val: any): val is ChangeProposal {\n return (isBaseProposal(val) && (\n isAddition(val)\n || isClarification(val)\n || isAmendment(val)));\n}\nexport function isAddition(val: BaseProposal): val is Addition {\n return (val.type === ChangeProposalType.ADDITION);\n}\nexport function isClarification(val: BaseProposal): val is Clarification {\n return (val.type === ChangeProposalType.CLARIFICATION);\n}\nexport function isBaseAmendment(val: BaseProposal): val is BaseAmendment {\n return (\n val.type === ChangeProposalType.AMENDMENT\n && AMENDMENT_TYPES.indexOf((val as Amendment).amendmentType) >= 0);\n}\nexport function isAmendment(val: any): val is Amendment {\n return (isBaseAmendment(val) && (\n isRetirement(val)\n || isSupersession(val)\n || isInvalidation(val)));\n}\nexport function isRetirement(val: BaseAmendment): val is Retirement {\n return val.amendmentType === AmendmentType.RETIREMENT;\n}\nexport function isSupersession(val: BaseAmendment): val is Supersession {\n return val.amendmentType === AmendmentType.SUPERSESSION;\n}\nexport function isInvalidation(val: BaseAmendment): val is Invalidation {\n return val.amendmentType === AmendmentType.INVALIDATION;\n}\n\n\n// Change request types, states and state transitions.\n\nexport function isSubmittedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n //isSubmitter(stakeholder) &&\n stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername);\n}\n\n\ntype ItemDataset = Record<string, RegisterItem<any> | null>;\n\n\n// =====================\n// Change request states\n// =====================\n\n/** Used in place of enum for convenience. */\nexport const State = {\n DRAFT: 'draft',\n PROPOSED: 'proposed',\n SUBMITTED_FOR_CONTROL_BODY_REVIEW: 'pending-control-body-review',\n RETURNED_FOR_CLARIFICATION: 'returned-for-clarification',\n WITHDRAWN: 'withdrawn',\n ACCEPTED: 'accepted',\n REJECTED: 'rejected',\n APPEALED: 'rejection-appealed-to-owner',\n ACCEPTED_ON_APPEAL: 'accepted-on-appeal',\n REJECTION_UPHELD_ON_APPEAL: 'rejection-upheld-on-appeal',\n APPEAL_WITHDRAWN: 'appeal-withdrawn',\n} as const;\n\nexport type StateType = typeof State[keyof typeof State];\n\nexport function isState(val: string): val is StateType {\n return Object.values(State).indexOf(val as StateType) >= 0;\n}\n\n/** A subset of `State` that represents editable states. */\nexport const EditableState = [\n State.DRAFT,\n State.RETURNED_FOR_CLARIFICATION,\n] as const;\n\nexport type EditableStateType = StateType & typeof EditableState[number];\n\nexport function isEditableState(state: StateType): state is EditableStateType {\n return EditableState.indexOf(state as EditableStateType) >= 0;\n}\n\n\n\n// ======================\n// Change request classes\n// ======================\n\n/**\n * Base change request type.\n *\n * Note that e.g. type Base<typeof State.DRAFT> does not equal to Drafted\n * because Drafted includes additional information (namely, SubmitterInput).\n *\n * If the state of a CR matters, this type should not be used directly\n * and concrete types should be used instead.\n */\nexport interface Base<S extends StateType = StateType>\n{\n id: string;\n // decision: typeof Decision[keyof typeof Decision]\n // disposition?: typeof Disposition[keyof typeof Disposition]\n state: S;\n\n /**\n * Used to match against stakeholders declared in register metadata.\n */\n submittingStakeholderGitServerUsername: string;\n\n items: ProposalSet;\n\n /**\n * Against which register version changes were proposed.\n */\n registerVersion: string;\n\n /**\n * A link to external discussion.\n */\n externalDiscussionURI?: string;\n\n pastTransitions?: TransitionEntry[];\n}\n\n\nexport interface TransitionEntry {\n /** Verb in past tense. */\n label: string;\n\n timestamp: Date;\n fromState: StateType;\n toState: StateType;\n stakeholder: RegisterStakeholder;\n input: StateInput;\n}\n\n\nexport function isCreatedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return stakeholder.gitServerUsername?.trim() !== '' && stakeholder.gitServerUsername === cr.submittingStakeholderGitServerUsername;\n}\n\n/** Whether given `cr` can be edited (as in, items changed) by specified stakeholder. */\nexport function canBeEditedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return isCreatedBy(stakeholder, cr) && isEditableState(cr.state);\n}\n\n/**\n * Whether given `cr` can be deleted by given stakeholder.\n * Unlike editing, deletion is possible only if there are no items\n * and CR was never proposed.\n */\nexport function canBeDeletedBy(stakeholder: RegisterStakeholder, cr: Base): boolean {\n return (\n isCreatedBy(stakeholder, cr)\n && isDrafted(cr)\n //&& Object.keys(cr.items).length < 1 // Only allow deleting empty CRs\n && !hadBeenProposed(cr) // If it had been proposed, it should be withdrawn instead.\n );\n}\n\n\n/** Proposal structure for single-file proposal import format. */\nexport interface ImportableCR {\n /** Proposal data. */\n proposalDraft: Drafted,\n /** Register item data for additions & clarifications. */\n itemPayloads: ItemDataset,\n // TODO: Rename ImportableCR.itemPayloads to newItemData\n}\nexport function isImportableCR(val: any): val is ImportableCR {\n // TODO: More complete check\n return (\n val.proposalDraft.id\n && isDrafted(val.proposalDraft as Base)\n && Object.keys(val.itemPayloads).length > 0);\n}\n\n\n/**\n * A change request in any state.\n * Contains a superset of all possible properties, but all optional.\n * XXX: ^^^ This is a lie. Should be changed from | to & with Partial<>?\n */\nexport type SomeCR = \n | Drafted\n | Proposed\n | Withdrawn\n | ReturnedForClarificationByManager\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByControlBody\n | Accepted\n | Rejected\n | RejectionUpheld\n | AcceptedOnAppeal\n | RejectedWithAppealWithdrawn;\n\nexport type Withdrawable =\n | Proposed\n | SubmittedForControlBodyReview\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Proposable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type SomeEditable =\n | Drafted\n | ReturnedForClarificationByManager\n | ReturnedForClarificationByControlBody;\n\nexport type Disposed =\n | Withdrawn\n | Accepted\n | Rejected\n | AcceptedOnAppeal\n | RejectionUpheld;\n\n\n// More specific change request types.\n// TODO: Refactor to avoid confusiong between current state e.g. Proposed)\n// and type (Proposed, to which all inheriting classes also conform)\n\nexport interface Drafted extends\n SubmitterInput,\n Base<typeof State.DRAFT> { timeStarted: Date, timeEdited: Date }\nexport function isDrafted(cr: Base): cr is Drafted {\n return isInState(cr, State.DRAFT);\n}\n\nexport interface Proposed extends\n Omit<Drafted, 'state'>,\n Base<typeof State.PROPOSED> { timeProposed: Date }\nexport function isProposed(cr: Base): cr is Proposed {\n return isInState(cr, State.PROPOSED);\n}\n\nexport interface Withdrawn extends\n Omit<Withdrawable, 'state'>,\n Base<typeof State.WITHDRAWN> { timeDisposed: Date }\nexport function isWithdrawn(cr: Base): cr is Withdrawn {\n return isInState(cr, State.WITHDRAWN);\n}\n\n/** CR was proposed at least once. */\nexport function hadBeenProposed(cr: Base): cr is Base & { timeProposed: Date } {\n return cr && cr.hasOwnProperty('timeProposed') && !!(cr as Proposed).timeProposed;\n}\nexport function hadBeenAccepted(cr: Base): cr is Accepted | AcceptedOnAppeal {\n return isDisposed(cr) && (isAccepted(cr) || isAcceptedOnAppeal(cr));\n}\n/** A proposal that had been disposed is not pending, not actionable. */\nexport function isDisposed(cr: Base): cr is Base & { timeDisposed: Date } {\n return cr && cr.hasOwnProperty('timeDisposed') && !!(cr as Disposed).timeDisposed;\n // TODO: include status checks, too?\n //return [\n // State.WITHDRAWN,\n // State.ACCEPTED,\n // State.REJECTED,\n // State.REJECTION_UPHELD_ON_APPEAL,\n // State.ACCEPTED_ON_APPEAL,\n //].some(s => cr.state === s);\n}\n\nexport interface SubmittedForControlBodyReview extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.SUBMITTED_FOR_CONTROL_BODY_REVIEW> {}\n\nexport function isSubmittedForControlBodyReview(cr: Base): cr is SubmittedForControlBodyReview {\n return isInState(cr, State.SUBMITTED_FOR_CONTROL_BODY_REVIEW)\n}\n\nexport interface ReturnedForClarificationByManager extends\n Omit<Proposed, 'state'>,\n RegisterManagerInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport interface ReturnedForClarificationByControlBody extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.RETURNED_FOR_CLARIFICATION> {}\n\nexport function isReturnedForClarification(cr: Base): cr is (ReturnedForClarificationByManager | ReturnedForClarificationByControlBody) {\n return isInState(cr, State.RETURNED_FOR_CLARIFICATION)\n}\n\nexport interface Accepted extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.ACCEPTED> { timeDisposed: Date }\nexport function isAccepted(cr: Base): cr is Accepted {\n return isInState(cr, State.ACCEPTED);\n}\n\nexport interface Rejected extends\n Omit<SubmittedForControlBodyReview, 'state'>,\n ControlBodyInput,\n Base<typeof State.REJECTED> { timeDisposed: Date }\nexport function isRejected(cr: Base): cr is Rejected {\n return isInState(cr, State.REJECTED);\n}\n\nexport interface Appealed extends\n Omit<Rejected, 'state' | 'timeDisposed'>,\n AppealRequest,\n Base<typeof State.APPEALED> { timeDisposed: undefined }\nexport function isAppealed(cr: Base): cr is Appealed {\n return isInState(cr, State.APPEALED);\n}\n\nexport interface RejectionUpheld extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.REJECTION_UPHELD_ON_APPEAL> { timeDisposed: Date }\nexport function isRejectedOnAppeal(cr: Base): cr is RejectionUpheld {\n return isInState(cr, State.REJECTION_UPHELD_ON_APPEAL);\n}\n\nexport interface AcceptedOnAppeal extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n RegisterOwnerInput,\n Base<typeof State.ACCEPTED_ON_APPEAL> { timeDisposed: Date }\nexport function isAcceptedOnAppeal(cr: Base): cr is AcceptedOnAppeal {\n return isInState(cr, State.ACCEPTED_ON_APPEAL);\n}\n\nexport interface RejectedWithAppealWithdrawn extends\n Omit<Appealed, 'state' | 'timeDisposed'>,\n Base<typeof State.APPEAL_WITHDRAWN> { timeDisposed: Date }\nexport function isRejectedWithAppealWithdrawn(cr: Base): cr is RejectedWithAppealWithdrawn {\n return isInState(cr, State.APPEAL_WITHDRAWN);\n}\n\n\n\n// Input required when transitioning to different states\n\nexport interface SubmitterInput {\n justification: string;\n}\nexport function hasSubmitterInput(val: any): val is SubmitterInput {\n return val.hasOwnProperty('justification') && typeof val.justification === 'string';\n}\nexport interface RegisterManagerInput {\n registerManagerNotes: string;\n}\nexport function hasRegisterManagerInput(val: any): val is RegisterManagerInput {\n return val.hasOwnProperty('registerManagerNotes') && typeof val.registerManagerNotes === 'string';\n}\nexport interface ControlBodyInput {\n controlBodyNotes: string;\n controlBodyDecisionEvent: string;\n}\nexport function hasControlBodyInput(val: any): val is ControlBodyInput {\n return (\n val.hasOwnProperty('controlBodyNotes') && typeof val.controlBodyNotes === 'string' &&\n val.hasOwnProperty('controlBodyDecisionEvent') && typeof val.controlBodyDecisionEvent === 'string');\n}\nexport interface AppealRequest {\n appealReason: string;\n}\nexport function hasAppealRequest(val: any): val is AppealRequest {\n return val.hasOwnProperty('appealReason') && typeof val.appealReason === 'string';\n}\nexport interface RegisterOwnerInput {\n registerOwnerNotes: string;\n}\nexport function hasRegisterOwnerInput(val: any): val is RegisterOwnerInput {\n return val.hasOwnProperty('registerOwnerNotes') && typeof val.registerOwnerNotes === 'string';\n}\n\nexport type StateInput =\n | SubmitterInput\n | RegisterManagerInput\n | ControlBodyInput\n | AppealRequest\n | RegisterOwnerInput;\n\n\n/** \n * CR type guard helper.\n * Normally you would not use it directly and instead use\n * more specific is[Type]() helper from this module.\n *\n * Checks CR type using the `state` property.\n * Does not validate other properties.\n *\n * Usage:\n *\n * @example\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.DRAFT)) {\n * // Can assume someCR is Drafted\n * }\n * ```\n *\n * It’ll try to tell you if you mismatch those.\n *\n * @example\n * Will not compile:\n * ```ts\n * let someCR;\n * if (isInState<Drafted>(someCR, State.PROPOSED)) {\n * // Compile error\n * // because State.PROPOSED is not a possible value of Drafted[\"state\"]\n * }\n * ```\n *\n * @example\n * Incorrect usage (do not do this):\n * ```ts\n * let someCR;\n * if (isInState(someCR, State.DRAFT)) {\n * // Can NOT assume someCR is Drafted\n * // The compiler must know the expected concrete CR type\n * }\n * ```\n */\nfunction isInState<CR extends Base>(cr: Base, s: CR[\"state\"]): cr is CR {\n return cr.state === s;\n}\n\n\n\n\n// ===========\n// Transitions\n// ===========\n\n/**\n * A function that transitions CR1 to CR2.\n *\n * The function is declared to return the object\n * without the `state` field, it is set\n * by common wrapper function to reduce duplication.\n */\nexport type Transition<\n /** From CR of this subtype */\n CR1 extends Base,\n /** To CR of this subtype */\n CR2 extends Base,\n /** Using this extra information */\n P extends Record<string, any> | null = null,\n> = (cr: CR1, payload: P) => Omit<CR2, 'state'>;\n\n\nexport type AlterApprovedCR = (\n crID: string,\n proposals: ProposalSet,\n origItemData: ItemDataset,\n newItemData: ItemDataset,\n opts: Pick<DatasetContext, 'getMapReducedData'>,\n) => Promise<{\n proposals: ProposalSet,\n origItemData: ItemDataset,\n newItemData: ItemDataset,\n}>\n\n\n/**\n * Describes a transition.\n *\n * @typeParam CR1: Change request source state type\n * @typeParam CR2: Change request target state type\n * @typeParam P: Extra input needed to transition, if any\n */\nexport interface TransitionConfig<CR1 extends Base, CR2 extends Base, P extends Record<string, any> | null = null> {\n /**\n * Function that implements the transition.\n * Takes a CR in the original state and returns CR in the new state.\n * Additionally, takes appropriate payload, if any, for the transition\n * (e.g., register manager or control body notes).\n *\n * For function implementor:\n *\n * - Function MUST NOT modify CR in place.\n * - Function should throw if submitted payload does not conform to requirements.\n */\n func: Transition<CR1, CR2, P>;\n\n targetState: CR2[\"state\"];\n\n /** Title. Use verb. */\n title: string;\n\n hint?: string | JSX.Element;\n\n /** Widget that can be used to view or enter extra input. */\n Widget: P extends null ? null : React.FC<{ value: P, onChange?: (userInput: P) => void }>;\n\n /**\n * Function that returns true\n * if given stakeholder can perform this transition on given CR.\n */\n canBeTransitionedBy: (stakeholder: RegisterStakeholder, cr: CR1) => boolean;\n}\n\n\n// type TransitionSpec = {\n// [S1 in StateType]?: {\n// [S2 in StateType]?: Transition<Base<S1>, Base<S2>, Record<string, any>>\n// }\n// }\n\n\n/**\n * Source of truth for available transitions.\n * When updating change request business logic,\n * this is the type that should be modified.\n *\n * It will cause compile errors until transition implementation\n * is updated correspondingly.\n */\nexport type Transitions = {\n [State.DRAFT]: {\n // [State.DRAFT]:\n // TransitionConfig<Drafted, Drafted, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.PROPOSED]:\n TransitionConfig<Drafted, Proposed, SubmitterInput>;\n };\n [State.PROPOSED]: {\n [State.WITHDRAWN]:\n TransitionConfig<Proposed, Withdrawn>;\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]:\n TransitionConfig<Proposed, SubmittedForControlBodyReview, RegisterManagerInput>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<Proposed, ReturnedForClarificationByManager, RegisterManagerInput>;\n };\n [State.SUBMITTED_FOR_CONTROL_BODY_REVIEW]: {\n [State.WITHDRAWN]:\n TransitionConfig<SubmittedForControlBodyReview, Withdrawn>;\n [State.RETURNED_FOR_CLARIFICATION]:\n TransitionConfig<SubmittedForControlBodyReview, ReturnedForClarificationByControlBody, ControlBodyInput>;\n [State.REJECTED]:\n TransitionConfig<SubmittedForControlBodyReview, Rejected, ControlBodyInput>;\n [State.ACCEPTED]:\n TransitionConfig<SubmittedForControlBodyReview, Accepted, ControlBodyInput>;\n };\n [State.RETURNED_FOR_CLARIFICATION]: {\n [State.PROPOSED]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Proposed, SubmitterInput>;\n [State.WITHDRAWN]:\n TransitionConfig<ReturnedForClarificationByManager | ReturnedForClarificationByControlBody, Withdrawn>;\n };\n [State.REJECTED]: {\n [State.APPEALED]:\n TransitionConfig<Rejected, Appealed, AppealRequest>;\n };\n [State.APPEALED]: {\n [State.APPEAL_WITHDRAWN]:\n TransitionConfig<Appealed, RejectedWithAppealWithdrawn>;\n [State.ACCEPTED_ON_APPEAL]:\n TransitionConfig<Appealed, AcceptedOnAppeal, RegisterOwnerInput>;\n [State.REJECTION_UPHELD_ON_APPEAL]:\n TransitionConfig<Appealed, RejectionUpheld, RegisterOwnerInput>;\n };\n}\n\n\n// Utility\n// =======\n\nexport interface ProposalProps<P extends ChangeProposal> {\n proposal: P\n\n /** Highlight changes. */\n showDiff?: boolean\n\n /** In diff mode, only show changed data. (Provisional.) */\n showOnlyChanged?: boolean\n\n itemRef: InternalItemReference\n item: RegisterItem<Payload>\n itemBefore: P extends Clarification ? RegisterItem<Payload> : undefined\n onChange?: (newProposal: P) => void\n}\n"]}
|
|
@@ -110,6 +110,7 @@ const ChangeRequestListBlock = function ({
|
|
|
110
110
|
return (0, _react2.jsx)(ChangeRequestSearchResultList, {
|
|
111
111
|
queryExpression: query,
|
|
112
112
|
selectedItemPath: state.selectedItemPath,
|
|
113
|
+
keyExpression: "(new Date()).getTime() * 100 - (typeof obj.timeDisposed === 'object' ? (obj.timeDisposed ?? new Date()) : new Date(obj.timeDisposed)).getTime() + Math.floor(Math.random() * 1000)",
|
|
113
114
|
onSelectItem: (0, _react.useCallback)(itemPath => dispatch({
|
|
114
115
|
type: 'select-item',
|
|
115
116
|
payload: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/sidebar/Registration/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useEffect, useMemo, useCallback, useContext } from 'react';\nimport { jsx } from '@emotion/react';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\n//import { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport makeSearchResultList from '@riboseinc/paneron-extension-kit/widgets/SearchResultList';\nimport { type Base as BaseCR, type SomeCR } from '../../../proposals/types';\nimport { CR_BASE_QUERY, DISPOSED_CR_QUERY } from '../../../proposals/queries';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { itemRefToItemPath } from '../../itemPathUtils';\nimport { ProposalAsListItem } from '../../../proposals/ListItem';\nimport { Protocols } from '../../protocolRegistry';\n\n\nexport const PendingChangeRequestsBlock: React.FC<Record<never, never>> = function () {\n const { stakeholder } = useContext(BrowserCtx);\n const stakeholderUsername = stakeholder?.gitServerUsername;\n const stakeholderCondition = stakeholderUsername\n ? `obj.submittingStakeholderGitServerUsername === \"${stakeholderUsername}\"`\n : 'false';\n // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.\n const query = `!obj.timeDisposed && (obj.state !== \"draft\" || ${stakeholderCondition})`;\n\n return <ChangeRequestListBlock impliedQuery={query} />;\n};\n\n\nexport const ChangeRequestHistoryBlock: React.FC<Record<never, never>> = function () {\n return <ChangeRequestListBlock impliedQuery={DISPOSED_CR_QUERY} />;\n};\n\ninterface ChangeRequestBlockState {\n quickSubstringQuery: string;\n selectedItemPath: string | null;\n}\nconst initialState: ChangeRequestBlockState = {\n quickSubstringQuery: '',\n selectedItemPath: null,\n} as const;\ntype ChangeRequestBlockAction =\n | { type: 'update-quick-substring-query'; payload: { substring: string; }; }\n | { type: 'select-item'; payload: { itemPath: string | null; }; }\n\nexport const ChangeRequestListBlock: React.FC<{ impliedQuery: string, itemPath?: string }> = function ({ impliedQuery, itemPath: _itemPath }) {\n const { usePersistentDatasetStateReducer } = useContext(DatasetContext);\n const { spawnTab, focusedTabURI } = useContext(TabbedWorkspaceContext);\n const { selectedRegisterItem } = useContext(BrowserCtx);\n\n const itemPath = _itemPath ?? (\n selectedRegisterItem\n ? itemRefToItemPath(selectedRegisterItem.ref)\n : selectedRegisterItem);\n // ^ Adopt undefined value if no data is available, null if item is not selected\n\n const [ state, dispatch, ] = (usePersistentDatasetStateReducer as PersistentStateReducerHook<ChangeRequestBlockState, ChangeRequestBlockAction>)(\n `change-request-list-block-${itemPath === null ? 'global' : itemPath}-${impliedQuery}`,\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'update-quick-substring-query':\n return {\n ...prevState,\n quickSubstringQuery: action.payload.substring,\n };\n case 'select-item':\n return {\n ...prevState,\n selectedItemPath: action.payload.itemPath,\n };\n default:\n throw new Error(\"Unexpected search state\");\n }\n },\n initialState,\n null);\n\n const query = useMemo((() => itemPath\n ? `return ${CR_BASE_QUERY} && ${impliedQuery} && obj.items[\"${itemPath}\"] !== undefined`\n : itemPath === null\n ? `return ${CR_BASE_QUERY} && ${impliedQuery}`\n // If item data is loading or unavailable, don’t show any CRs\n // to avoid flashing all CRs during item switching.\n : `return false`\n ), [impliedQuery, itemPath]);\n\n useEffect(() => {\n const selectedCRPath: string | null =\n focusedTabURI && focusedTabURI.startsWith(`${Protocols.CHANGE_REQUEST}:`)\n ? focusedTabURI.split(':')[1]\n : null;\n if (itemPath !== undefined && selectedCRPath) {\n setTimeout(() => {\n dispatch({ type: 'select-item', payload: { itemPath: selectedCRPath } });\n }, 500);\n }\n }, [dispatch, itemPath, focusedTabURI]);\n\n return (\n <ChangeRequestSearchResultList\n queryExpression={query}\n selectedItemPath={state.selectedItemPath}\n onSelectItem={useCallback((itemPath =>\n dispatch({\n type: 'select-item',\n payload: { itemPath },\n })\n ), [dispatch])}\n onOpenItem={useCallback((itemPath =>\n spawnTab(`${Protocols.CHANGE_REQUEST}:${itemPath}`)\n ), [spawnTab])}\n />\n )\n};\n\n\nconst CRHistoryItem: React.FC<{\n objectData: BaseCR,\n objectPath: string,\n}> = function ({ objectData }) {\n return <ProposalAsListItem proposal={objectData as SomeCR} />;\n};\n\n\nconst ChangeRequestSearchResultList = makeSearchResultList<BaseCR>(CRHistoryItem, (objPath) => ({\n name: 'Prp.',\n iconProps: {\n icon: 'lightbulb',\n title: objPath,\n htmlTitle: `icon for proposal at ${objPath}`,\n },\n}));\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/sidebar/Registration/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useEffect, useMemo, useCallback, useContext } from 'react';\nimport { jsx } from '@emotion/react';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport type { PersistentStateReducerHook } from '@riboseinc/paneron-extension-kit/usePersistentStateReducer';\n//import { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport makeSearchResultList from '@riboseinc/paneron-extension-kit/widgets/SearchResultList';\nimport { type Base as BaseCR, type SomeCR } from '../../../proposals/types';\nimport { CR_BASE_QUERY, DISPOSED_CR_QUERY } from '../../../proposals/queries';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { itemRefToItemPath } from '../../itemPathUtils';\nimport { ProposalAsListItem } from '../../../proposals/ListItem';\nimport { Protocols } from '../../protocolRegistry';\n\n\nexport const PendingChangeRequestsBlock: React.FC<Record<never, never>> = function () {\n const { stakeholder } = useContext(BrowserCtx);\n const stakeholderUsername = stakeholder?.gitServerUsername;\n const stakeholderCondition = stakeholderUsername\n ? `obj.submittingStakeholderGitServerUsername === \"${stakeholderUsername}\"`\n : 'false';\n // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.\n const query = `!obj.timeDisposed && (obj.state !== \"draft\" || ${stakeholderCondition})`;\n\n return <ChangeRequestListBlock impliedQuery={query} />;\n};\n\n\nexport const ChangeRequestHistoryBlock: React.FC<Record<never, never>> = function () {\n return <ChangeRequestListBlock impliedQuery={DISPOSED_CR_QUERY} />;\n};\n\ninterface ChangeRequestBlockState {\n quickSubstringQuery: string;\n selectedItemPath: string | null;\n}\nconst initialState: ChangeRequestBlockState = {\n quickSubstringQuery: '',\n selectedItemPath: null,\n} as const;\ntype ChangeRequestBlockAction =\n | { type: 'update-quick-substring-query'; payload: { substring: string; }; }\n | { type: 'select-item'; payload: { itemPath: string | null; }; }\n\nexport const ChangeRequestListBlock: React.FC<{ impliedQuery: string, itemPath?: string }> = function ({ impliedQuery, itemPath: _itemPath }) {\n const { usePersistentDatasetStateReducer } = useContext(DatasetContext);\n const { spawnTab, focusedTabURI } = useContext(TabbedWorkspaceContext);\n const { selectedRegisterItem } = useContext(BrowserCtx);\n\n const itemPath = _itemPath ?? (\n selectedRegisterItem\n ? itemRefToItemPath(selectedRegisterItem.ref)\n : selectedRegisterItem);\n // ^ Adopt undefined value if no data is available, null if item is not selected\n\n const [ state, dispatch, ] = (usePersistentDatasetStateReducer as PersistentStateReducerHook<ChangeRequestBlockState, ChangeRequestBlockAction>)(\n `change-request-list-block-${itemPath === null ? 'global' : itemPath}-${impliedQuery}`,\n undefined,\n undefined,\n (prevState, action) => {\n switch (action.type) {\n case 'update-quick-substring-query':\n return {\n ...prevState,\n quickSubstringQuery: action.payload.substring,\n };\n case 'select-item':\n return {\n ...prevState,\n selectedItemPath: action.payload.itemPath,\n };\n default:\n throw new Error(\"Unexpected search state\");\n }\n },\n initialState,\n null);\n\n const query = useMemo((() => itemPath\n ? `return ${CR_BASE_QUERY} && ${impliedQuery} && obj.items[\"${itemPath}\"] !== undefined`\n : itemPath === null\n ? `return ${CR_BASE_QUERY} && ${impliedQuery}`\n // If item data is loading or unavailable, don’t show any CRs\n // to avoid flashing all CRs during item switching.\n : `return false`\n ), [impliedQuery, itemPath]);\n\n useEffect(() => {\n const selectedCRPath: string | null =\n focusedTabURI && focusedTabURI.startsWith(`${Protocols.CHANGE_REQUEST}:`)\n ? focusedTabURI.split(':')[1]\n : null;\n if (itemPath !== undefined && selectedCRPath) {\n setTimeout(() => {\n dispatch({ type: 'select-item', payload: { itemPath: selectedCRPath } });\n }, 500);\n }\n }, [dispatch, itemPath, focusedTabURI]);\n\n return (\n <ChangeRequestSearchResultList\n queryExpression={query}\n selectedItemPath={state.selectedItemPath}\n keyExpression=\"(new Date()).getTime() * 100 - (typeof obj.timeDisposed === 'object' ? (obj.timeDisposed ?? new Date()) : new Date(obj.timeDisposed)).getTime() + Math.floor(Math.random() * 1000)\"\n onSelectItem={useCallback((itemPath =>\n dispatch({\n type: 'select-item',\n payload: { itemPath },\n })\n ), [dispatch])}\n onOpenItem={useCallback((itemPath =>\n spawnTab(`${Protocols.CHANGE_REQUEST}:${itemPath}`)\n ), [spawnTab])}\n />\n )\n};\n\n\nconst CRHistoryItem: React.FC<{\n objectData: BaseCR,\n objectPath: string,\n}> = function ({ objectData }) {\n return <ProposalAsListItem proposal={objectData as SomeCR} />;\n};\n\n\nconst ChangeRequestSearchResultList = makeSearchResultList<BaseCR>(CRHistoryItem, (objPath) => ({\n name: 'Prp.',\n iconProps: {\n icon: 'lightbulb',\n title: objPath,\n htmlTitle: `icon for proposal at ${objPath}`,\n },\n}));\n"]}
|
package/views/util.js
CHANGED
|
@@ -148,7 +148,7 @@ function formatDate(date, opts) {
|
|
|
148
148
|
const fmt = (opts === null || opts === void 0 ? void 0 : opts.showTime) ? 'yyyy-MM-dd HH:mm:ss' : 'yyyy-MM-dd';
|
|
149
149
|
|
|
150
150
|
try {
|
|
151
|
-
return (opts === null || opts === void 0 ? void 0 : opts.useUTC) ? `${formatInTimeZone(date, fmt, 'UTC')} UTC` : (0, _format.default)(date, fmt);
|
|
151
|
+
return (opts === null || opts === void 0 ? void 0 : opts.useUTC) ? `${formatInTimeZone(date, fmt, 'UTC')}${(opts === null || opts === void 0 ? void 0 : opts.showTime) ? ' UTC' : ''}` : (0, _format.default)(date, fmt);
|
|
152
152
|
} catch (e) {
|
|
153
153
|
console.error("Failed to format date", date, typeof date);
|
|
154
154
|
return `Invalid date (${e})`;
|
package/views/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/views/util.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\n//import log from 'electron-log';\nimport format from 'date-fns/format';\nimport { format as formatTZ, utcToZonedTime } from 'date-fns-tz';\n\nimport React, { memo, useContext } from 'react';\nimport { Helmet, type HelmetProps } from 'react-helmet';\nimport { css, jsx } from '@emotion/react';\nimport {\n Card, type CardProps,\n Classes,\n FormGroup, type FormGroupProps,\n H3, H4,\n Button as BaseButton, type ButtonProps,\n Menu, MenuDivider, MenuItem,\n ButtonGroup,\n Tag, type TagProps,\n Colors,\n} from '@blueprintjs/core';\nimport { Popover2 as Popover } from '@blueprintjs/popover2';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport HelpTooltip, { type HelpTooltipProps } from '@riboseinc/paneron-extension-kit/widgets/HelpTooltip';\nimport { BrowserCtx } from './BrowserCtx';\nimport type { ItemClassConfiguration, RelatedItemClassConfiguration } from '../types';\nexport { GenericRelatedItemView } from './GenericRelatedItemView';\n\n\n/**\n * Get give string truncated & with ellipsis appended\n * if its length exceeds given number of characters.\n */\nexport function maybeEllipsizeString(\n str: string,\n maxLength: number = 20,\n): string {\n return str.length > maxLength\n ? `${str.slice(0, maxLength)}…`\n : str;\n}\n\n\nexport const RegisterHelmet: React.FC<HelmetProps> = memo(function (props) {\n const { title: datasetTitle } = useContext(DatasetContext);\n const { registerMetadata } = useContext(BrowserCtx);\n\n return (\n <Helmet\n titleTemplate={`%s in ${registerMetadata?.name ?? datasetTitle}`}\n defaultTitle={`${registerMetadata?.name ?? datasetTitle}`}>\n {props.children}\n </Helmet>\n );\n});\n\n\n/**\n * A wrapper to show property data with its label(s).\n */\nexport const PropertyDetailView: React.FC<FormGroupProps & {\n /** @deprecated use `label` instead */\n title?: FormGroupProps[\"label\"]\n /** @deprecated use `labelInfo` instead */\n secondaryTitle?: FormGroupProps[\"labelInfo\"]\n}> = function ({\n label, labelInfo,\n title, secondaryTitle,\n ...props }) {\n return (\n <FormGroup\n label={label || title ? `${label ?? title}:` : undefined}\n labelInfo={labelInfo ?? secondaryTitle}\n css={css`\n &, &.bp4-inline {\n label.bp4-label {\n /*\n * Since it’s in flex container, label expands to fill its width,\n * and due to the mechanics of how labels work (?)\n * any button (e.g., for deletion) within labelInfo\n * would responds to events of the entire label\n * (meaning you can hover space to the right of the label and labelInfo\n * and the button would still be clickable).\n * This makes the label not fill flex container width.\n */\n align-self: flex-start;\n\n font-weight: bold;\n line-height: unset;\n text-transform: capitalize;\n .bp4-text-muted {\n text-transform: none;\n }\n }\n }\n `}\n {...props}\n />\n );\n};\n\n\n/** Formats given date as a span with tooltip set to full ISO date & time. */\nexport const Datestamp: React.FC<{\n date: Date\n useUTC?: boolean\n showTime?: boolean\n title?: string\n className?: string\n}> = function ({ date, useUTC, showTime, title, className }) {\n const asString = formatDate(date, { useUTC, showTime });\n return <span\n className={className}\n title={`${title ? `${title}: ` : ''}${date?.toString() ?? 'N/A'}`}>\n {asString}\n </span>;\n};\n\n\nfunction formatInTimeZone(date: Date, fmt: string, tz: string) {\n return formatTZ(\n utcToZonedTime(date, tz), \n fmt, \n { timeZone: tz });\n}\n\n\n/** Foramts given date as plain text. */\nexport function formatDate(\n date: Date,\n opts?: { useUTC?: boolean, showTime?: boolean },\n): string {\n const fmt = opts?.showTime\n ? 'yyyy-MM-dd HH:mm:ss'\n : 'yyyy-MM-dd';\n try {\n return opts?.useUTC\n ? `${formatInTimeZone(date, fmt, 'UTC')} UTC`\n : format(date, fmt);\n } catch (e) {\n console.error(\"Failed to format date\", date, typeof date);\n return `Invalid date (${e})`;\n }\n}\n\n\nexport const _getRelatedClass = (classes: Record<string, ItemClassConfiguration<any>>) => {\n return (clsID: string): RelatedItemClassConfiguration => {\n const cfg = classes[clsID];\n return {\n title: cfg.meta.title,\n // TODO: The itemView/listItemView inconsistency is annoying\n itemView: cfg.views.listItemView,\n };\n };\n};\n\n\n// /**\n// * Suitable for use as tab contents for TabbedWorkspace.\n// * Provides top bar with actions and main content.\n// */\n// export const TabContentsWithActions: React.FC<{\n// actions: JSX.Element;\n// main: JSX.Element;\n// gapPx?: number;\n// className?: string;\n// }> = function ({ actions, gapPx: _gapPx, main, className }) {\n// const gapPx = _gapPx ?? 10;\n// return (\n// <div css={css`\n// position: absolute; inset: 0;\n// display: flex; flex-flow: column nowrap;\n// `} className={className}>\n// <div css={css`flex: 0; padding: ${gapPx}px; display: flex; flex-flow: row wrap; gap: ${gapPx}px;`}>\n// {actions}\n// </div>\n// <div css={css`\n// position: relative;\n// flex: 1;\n// padding: ${gapPx}px;\n// overflow-y: auto;\n// background: ${Colors.GRAY5};\n// .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n// `}>\n// {main}\n// </div>\n// </div>\n// );\n// };\n\n\nexport type ClassificationEntry = TagProps & { tooltip?: HelpTooltipProps };\nexport interface TabContentsWithHeaderProps {\n title: JSX.Element | string\n smallTitle?: boolean\n classification?: ClassificationEntry[]\n actions?: (ActionProps | ActionProps[])[]\n tooltip?: HelpTooltipProps\n className?: string\n\n /**\n * CSS to apply to child contents wrapper div.\n *\n * If 'card-grid', children would be expected to be cards\n * (e.g., `FormGroupAsCardInGrid` or `CardInGrid`)\n *\n * 'card-grid' implies 'scrollable'.\n */\n layout?: undefined | 'card-grid' | 'scrollable'\n layoutOptions?: Record<string, unknown>\n}\ninterface Grid extends TabContentsWithHeaderProps {\n layout: 'card-grid'\n layoutOptions?: {\n gapPx?: number\n stretch?: boolean\n }\n}\ninterface Scrollable extends TabContentsWithHeaderProps {\n layout: 'scrollable'\n layoutOptions?: never\n}\ninterface NoLayout extends TabContentsWithHeaderProps {\n layout?: undefined\n layoutOptions?: never\n}\nconst paddingPx = 11;\nfunction findEnabledActions\n<T extends ButtonProps | ButtonProps[] = ButtonProps | ButtonProps[]>\n(props: T[]): ButtonProps[] {\n return props.map(props =>\n (props as ButtonProps[]).length !== undefined\n ? (props as ButtonProps[]).filter(p => !p.disabled)\n : !(props as ButtonProps).disabled\n ? props\n : []\n ).flat();\n}\nexport const TabContentsWithHeader: React.FC<Grid | Scrollable | NoLayout> =\nfunction ({ title, smallTitle, classification, actions, layout, layoutOptions, className, children }) {\n const hasClassification = (classification ?? []).length > 0;\n\n const enabledActions = actions ? findEnabledActions(actions) : [];\n const hasActions = enabledActions.length > 0;\n\n // if (enabledActions.length === 1 && !enabledActions[0].intent) {\n // enabledActions[0].intent = 'primary';\n // }\n\n return (\n <div css={css`\n position: absolute; inset: 0;\n padding-top: ${paddingPx}px;\n ${hasActions ? `padding-bottom: ${paddingPx}px;` : ''}\n display: flex; flex-flow: column nowrap;\n gap: ${paddingPx}px;\n `} className={className}>\n {smallTitle\n ? <H4 css={css`margin: 0 ${paddingPx}px;`}>{title}</H4>\n : <H3 css={css`margin: 0 ${paddingPx}px;`}>{title}</H3>}\n {hasClassification\n ? <div css={css`\n flex: 0;\n margin: 0 ${paddingPx}px;\n display: flex;\n flex-flow: row wrap;\n gap: ${paddingPx}px;\n `}>\n {classification!.map((p, idx) =>\n <Tag\n key={idx}\n minimal\n {...p}\n large={!smallTitle}\n rightIcon={p.tooltip\n ? <HelpTooltip {...p.tooltip} />\n : undefined}\n />\n )}\n </div>\n : null}\n <div css={css`\n position: relative;\n flex: 1;\n overflow-y: auto;\n\n ${layout === undefined\n ? `\n > :only-child { position: absolute; inset: 0 }\n box-shadow: black 0 0 20px -10px;\n `\n : `\n padding: 0 10px;\n &::after, &::before {\n pointer-events: none;\n content: \" \";\n display: block;\n position: sticky;\n width: 100%;\n height: 1px;\n background: ${Colors.GRAY5};\n .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n z-index: 10;\n }\n &::before {\n top: 0;\n box-shadow: ${Colors.GRAY5} 0 -20px 20px 20px;\n .bp4-dark & {\n box-shadow: ${Colors.DARK_GRAY2} 0 -20px 20px 20px;\n }\n }\n &::after {\n bottom: 0;\n box-shadow: ${Colors.GRAY5} 0 20px 20px 20px;\n .bp4-dark & {\n box-shadow: ${Colors.DARK_GRAY2} 0 20px 20px 20px;\n }\n }\n `}\n\n ${layout === 'scrollable' || layout === 'card-grid'\n ? `\n background: ${Colors.GRAY5};\n .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n `\n : ''}\n\n ${layout === 'card-grid'\n ? `\n display: flex;\n flex-flow: row wrap;\n align-content: flex-start;\n ${layoutOptions?.stretch\n ? 'align-items: stretch;'\n : 'align-items: flex-start;'}\n gap: ${layoutOptions?.gapPx ?? 10}px;\n `\n : ''}\n `}>\n {children}\n </div>\n\n {hasActions\n ? <div css={css`\n margin: 0 ${paddingPx}px;\n flex: 0; display: flex; flex-flow: row wrap; gap: ${paddingPx}px;\n `}>\n {actions!.map((props, idx) => {\n if (props.hasOwnProperty('length') && (props as ButtonProps[]).length !== undefined) {\n return (\n <ButtonGroup key={idx}>\n {(props as ButtonProps[]).map((p, idx) =>\n <Action {...p} key={idx} />\n )}\n </ButtonGroup>\n );\n } else {\n return <Action key={idx} {...(props as ButtonProps)} />;\n }\n })}\n </div>\n : null}\n </div>\n );\n};\n\n\nexport type ActionProps = ButtonProps & ({ popup?: JSX.Element, tooltip?: string });\n/** Mostly a button, but with an optional popup. */\nconst Action: React.FC<ActionProps & { key?: number | string }> = function ({ popup, tooltip, ...props }) {\n const btn = <BaseButton\n {...props}\n intent={props.disabled ? undefined : props.intent}\n onClick={props.disabled ? undefined : props.onClick}\n disabled={props.active ? false : props.disabled}\n title={tooltip}\n rightIcon={popup ? 'more' : undefined}\n />;\n\n if (popup && !props.disabled) {\n return (\n <Popover key={props.key} content={popup} placement=\"top\" minimal interactionKind=\"click\">\n {btn}\n </Popover>\n );\n } else {\n return btn;\n }\n};\n\n\nexport const CardInGrid: React.FC<{ description: string } & CardProps> =\nfunction ({ description, className, ...props }) {\n return (\n <Card\n css={css`border-radius: 5px;`}\n title={description}\n className={!props.interactive\n ? `${Classes.ELEVATION_3} ${className ?? ''}`\n : className}\n {...props}\n />\n );\n};\n\n\n/** Useful in case of tab “card-grid” layout. */\nexport const FormGroupAsCardInGrid: React.FC<FormGroupProps & { paddingPx?: number }> =\nfunction ({ paddingPx, ...props }) {\n const paddingPx_ = paddingPx ?? 11;\n return (\n <FormGroup\n {...props}\n css={css`\n margin: 0;\n\n border-radius: 5px;\n padding: ${paddingPx_}px;\n\n > label.bp4-label {\n font-weight: bold;\n margin-bottom: ${paddingPx_}px;\n }\n > .bp4-form-content {\n display: flex;\n flex-flow: column nowrap;\n gap: ${paddingPx_}px;\n\n > .bp4-form-group {\n margin: 0;\n }\n }\n\n /* Note: these colors are picked to work with some form widgets, date input widget specifically. */\n background: ${Colors.WHITE};\n .bp4-dark & { background: ${Colors.DARK_GRAY3}; }\n `}\n className={`${Classes.ELEVATION_3} ${props.className}`}\n />\n );\n};\n\n\nexport const MoreMenu: React.FC<Record<never, never>> = memo(function ({ children }) {\n return (\n <Popover minimal content={<>{children}</>}>\n <BaseButton icon=\"more\" small minimal />\n </Popover>\n );\n});\n\n\nexport const ItemClassMenu: React.FC<{\n cfg: ItemClassConfiguration<any>;\n onCreate?: () => void;\n}> = memo(function ({ cfg, onCreate }) {\n return (\n <Menu>\n <MenuDivider title=\"About this class\" />\n <MenuItem multiline disabled css={css`max-width: 400px`} text={cfg.meta.description} />\n {onCreate\n ? <>\n <MenuDivider title=\"Quick actions\" />\n <MenuItem\n text=\"Propose new\"\n intent=\"primary\"\n onClick={onCreate} icon=\"plus\"\n />\n </>\n : null}\n </Menu>\n );\n});\n"]}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/views/util.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\n//import log from 'electron-log';\nimport format from 'date-fns/format';\nimport { format as formatTZ, utcToZonedTime } from 'date-fns-tz';\n\nimport React, { memo, useContext } from 'react';\nimport { Helmet, type HelmetProps } from 'react-helmet';\nimport { css, jsx } from '@emotion/react';\nimport {\n Card, type CardProps,\n Classes,\n FormGroup, type FormGroupProps,\n H3, H4,\n Button as BaseButton, type ButtonProps,\n Menu, MenuDivider, MenuItem,\n ButtonGroup,\n Tag, type TagProps,\n Colors,\n} from '@blueprintjs/core';\nimport { Popover2 as Popover } from '@blueprintjs/popover2';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport HelpTooltip, { type HelpTooltipProps } from '@riboseinc/paneron-extension-kit/widgets/HelpTooltip';\nimport { BrowserCtx } from './BrowserCtx';\nimport type { ItemClassConfiguration, RelatedItemClassConfiguration } from '../types';\nexport { GenericRelatedItemView } from './GenericRelatedItemView';\n\n\n/**\n * Get give string truncated & with ellipsis appended\n * if its length exceeds given number of characters.\n */\nexport function maybeEllipsizeString(\n str: string,\n maxLength: number = 20,\n): string {\n return str.length > maxLength\n ? `${str.slice(0, maxLength)}…`\n : str;\n}\n\n\nexport const RegisterHelmet: React.FC<HelmetProps> = memo(function (props) {\n const { title: datasetTitle } = useContext(DatasetContext);\n const { registerMetadata } = useContext(BrowserCtx);\n\n return (\n <Helmet\n titleTemplate={`%s in ${registerMetadata?.name ?? datasetTitle}`}\n defaultTitle={`${registerMetadata?.name ?? datasetTitle}`}>\n {props.children}\n </Helmet>\n );\n});\n\n\n/**\n * A wrapper to show property data with its label(s).\n */\nexport const PropertyDetailView: React.FC<FormGroupProps & {\n /** @deprecated use `label` instead */\n title?: FormGroupProps[\"label\"]\n /** @deprecated use `labelInfo` instead */\n secondaryTitle?: FormGroupProps[\"labelInfo\"]\n}> = function ({\n label, labelInfo,\n title, secondaryTitle,\n ...props }) {\n return (\n <FormGroup\n label={label || title ? `${label ?? title}:` : undefined}\n labelInfo={labelInfo ?? secondaryTitle}\n css={css`\n &, &.bp4-inline {\n label.bp4-label {\n /*\n * Since it’s in flex container, label expands to fill its width,\n * and due to the mechanics of how labels work (?)\n * any button (e.g., for deletion) within labelInfo\n * would responds to events of the entire label\n * (meaning you can hover space to the right of the label and labelInfo\n * and the button would still be clickable).\n * This makes the label not fill flex container width.\n */\n align-self: flex-start;\n\n font-weight: bold;\n line-height: unset;\n text-transform: capitalize;\n .bp4-text-muted {\n text-transform: none;\n }\n }\n }\n `}\n {...props}\n />\n );\n};\n\n\n/** Formats given date as a span with tooltip set to full ISO date & time. */\nexport const Datestamp: React.FC<{\n date: Date\n useUTC?: boolean\n showTime?: boolean\n title?: string\n className?: string\n}> = function ({ date, useUTC, showTime, title, className }) {\n const asString = formatDate(date, { useUTC, showTime });\n return <span\n className={className}\n title={`${title ? `${title}: ` : ''}${date?.toString() ?? 'N/A'}`}>\n {asString}\n </span>;\n};\n\n\nfunction formatInTimeZone(date: Date, fmt: string, tz: string) {\n return formatTZ(\n utcToZonedTime(date, tz), \n fmt, \n { timeZone: tz });\n}\n\n\n/** Foramts given date as plain text. */\nexport function formatDate(\n date: Date,\n opts?: { useUTC?: boolean, showTime?: boolean },\n): string {\n const fmt = opts?.showTime\n ? 'yyyy-MM-dd HH:mm:ss'\n : 'yyyy-MM-dd';\n try {\n return opts?.useUTC\n ? `${formatInTimeZone(date, fmt, 'UTC')}${opts?.showTime ? ' UTC' : ''}`\n : format(date, fmt);\n } catch (e) {\n console.error(\"Failed to format date\", date, typeof date);\n return `Invalid date (${e})`;\n }\n}\n\n\nexport const _getRelatedClass = (classes: Record<string, ItemClassConfiguration<any>>) => {\n return (clsID: string): RelatedItemClassConfiguration => {\n const cfg = classes[clsID];\n return {\n title: cfg.meta.title,\n // TODO: The itemView/listItemView inconsistency is annoying\n itemView: cfg.views.listItemView,\n };\n };\n};\n\n\n// /**\n// * Suitable for use as tab contents for TabbedWorkspace.\n// * Provides top bar with actions and main content.\n// */\n// export const TabContentsWithActions: React.FC<{\n// actions: JSX.Element;\n// main: JSX.Element;\n// gapPx?: number;\n// className?: string;\n// }> = function ({ actions, gapPx: _gapPx, main, className }) {\n// const gapPx = _gapPx ?? 10;\n// return (\n// <div css={css`\n// position: absolute; inset: 0;\n// display: flex; flex-flow: column nowrap;\n// `} className={className}>\n// <div css={css`flex: 0; padding: ${gapPx}px; display: flex; flex-flow: row wrap; gap: ${gapPx}px;`}>\n// {actions}\n// </div>\n// <div css={css`\n// position: relative;\n// flex: 1;\n// padding: ${gapPx}px;\n// overflow-y: auto;\n// background: ${Colors.GRAY5};\n// .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n// `}>\n// {main}\n// </div>\n// </div>\n// );\n// };\n\n\nexport type ClassificationEntry = TagProps & { tooltip?: HelpTooltipProps };\nexport interface TabContentsWithHeaderProps {\n title: JSX.Element | string\n smallTitle?: boolean\n classification?: ClassificationEntry[]\n actions?: (ActionProps | ActionProps[])[]\n tooltip?: HelpTooltipProps\n className?: string\n\n /**\n * CSS to apply to child contents wrapper div.\n *\n * If 'card-grid', children would be expected to be cards\n * (e.g., `FormGroupAsCardInGrid` or `CardInGrid`)\n *\n * 'card-grid' implies 'scrollable'.\n */\n layout?: undefined | 'card-grid' | 'scrollable'\n layoutOptions?: Record<string, unknown>\n}\ninterface Grid extends TabContentsWithHeaderProps {\n layout: 'card-grid'\n layoutOptions?: {\n gapPx?: number\n stretch?: boolean\n }\n}\ninterface Scrollable extends TabContentsWithHeaderProps {\n layout: 'scrollable'\n layoutOptions?: never\n}\ninterface NoLayout extends TabContentsWithHeaderProps {\n layout?: undefined\n layoutOptions?: never\n}\nconst paddingPx = 11;\nfunction findEnabledActions\n<T extends ButtonProps | ButtonProps[] = ButtonProps | ButtonProps[]>\n(props: T[]): ButtonProps[] {\n return props.map(props =>\n (props as ButtonProps[]).length !== undefined\n ? (props as ButtonProps[]).filter(p => !p.disabled)\n : !(props as ButtonProps).disabled\n ? props\n : []\n ).flat();\n}\nexport const TabContentsWithHeader: React.FC<Grid | Scrollable | NoLayout> =\nfunction ({ title, smallTitle, classification, actions, layout, layoutOptions, className, children }) {\n const hasClassification = (classification ?? []).length > 0;\n\n const enabledActions = actions ? findEnabledActions(actions) : [];\n const hasActions = enabledActions.length > 0;\n\n // if (enabledActions.length === 1 && !enabledActions[0].intent) {\n // enabledActions[0].intent = 'primary';\n // }\n\n return (\n <div css={css`\n position: absolute; inset: 0;\n padding-top: ${paddingPx}px;\n ${hasActions ? `padding-bottom: ${paddingPx}px;` : ''}\n display: flex; flex-flow: column nowrap;\n gap: ${paddingPx}px;\n `} className={className}>\n {smallTitle\n ? <H4 css={css`margin: 0 ${paddingPx}px;`}>{title}</H4>\n : <H3 css={css`margin: 0 ${paddingPx}px;`}>{title}</H3>}\n {hasClassification\n ? <div css={css`\n flex: 0;\n margin: 0 ${paddingPx}px;\n display: flex;\n flex-flow: row wrap;\n gap: ${paddingPx}px;\n `}>\n {classification!.map((p, idx) =>\n <Tag\n key={idx}\n minimal\n {...p}\n large={!smallTitle}\n rightIcon={p.tooltip\n ? <HelpTooltip {...p.tooltip} />\n : undefined}\n />\n )}\n </div>\n : null}\n <div css={css`\n position: relative;\n flex: 1;\n overflow-y: auto;\n\n ${layout === undefined\n ? `\n > :only-child { position: absolute; inset: 0 }\n box-shadow: black 0 0 20px -10px;\n `\n : `\n padding: 0 10px;\n &::after, &::before {\n pointer-events: none;\n content: \" \";\n display: block;\n position: sticky;\n width: 100%;\n height: 1px;\n background: ${Colors.GRAY5};\n .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n z-index: 10;\n }\n &::before {\n top: 0;\n box-shadow: ${Colors.GRAY5} 0 -20px 20px 20px;\n .bp4-dark & {\n box-shadow: ${Colors.DARK_GRAY2} 0 -20px 20px 20px;\n }\n }\n &::after {\n bottom: 0;\n box-shadow: ${Colors.GRAY5} 0 20px 20px 20px;\n .bp4-dark & {\n box-shadow: ${Colors.DARK_GRAY2} 0 20px 20px 20px;\n }\n }\n `}\n\n ${layout === 'scrollable' || layout === 'card-grid'\n ? `\n background: ${Colors.GRAY5};\n .bp4-dark & { background: ${Colors.DARK_GRAY2}; }\n `\n : ''}\n\n ${layout === 'card-grid'\n ? `\n display: flex;\n flex-flow: row wrap;\n align-content: flex-start;\n ${layoutOptions?.stretch\n ? 'align-items: stretch;'\n : 'align-items: flex-start;'}\n gap: ${layoutOptions?.gapPx ?? 10}px;\n `\n : ''}\n `}>\n {children}\n </div>\n\n {hasActions\n ? <div css={css`\n margin: 0 ${paddingPx}px;\n flex: 0; display: flex; flex-flow: row wrap; gap: ${paddingPx}px;\n `}>\n {actions!.map((props, idx) => {\n if (props.hasOwnProperty('length') && (props as ButtonProps[]).length !== undefined) {\n return (\n <ButtonGroup key={idx}>\n {(props as ButtonProps[]).map((p, idx) =>\n <Action {...p} key={idx} />\n )}\n </ButtonGroup>\n );\n } else {\n return <Action key={idx} {...(props as ButtonProps)} />;\n }\n })}\n </div>\n : null}\n </div>\n );\n};\n\n\nexport type ActionProps = ButtonProps & ({ popup?: JSX.Element, tooltip?: string });\n/** Mostly a button, but with an optional popup. */\nconst Action: React.FC<ActionProps & { key?: number | string }> = function ({ popup, tooltip, ...props }) {\n const btn = <BaseButton\n {...props}\n intent={props.disabled ? undefined : props.intent}\n onClick={props.disabled ? undefined : props.onClick}\n disabled={props.active ? false : props.disabled}\n title={tooltip}\n rightIcon={popup ? 'more' : undefined}\n />;\n\n if (popup && !props.disabled) {\n return (\n <Popover key={props.key} content={popup} placement=\"top\" minimal interactionKind=\"click\">\n {btn}\n </Popover>\n );\n } else {\n return btn;\n }\n};\n\n\nexport const CardInGrid: React.FC<{ description: string } & CardProps> =\nfunction ({ description, className, ...props }) {\n return (\n <Card\n css={css`border-radius: 5px;`}\n title={description}\n className={!props.interactive\n ? `${Classes.ELEVATION_3} ${className ?? ''}`\n : className}\n {...props}\n />\n );\n};\n\n\n/** Useful in case of tab “card-grid” layout. */\nexport const FormGroupAsCardInGrid: React.FC<FormGroupProps & { paddingPx?: number }> =\nfunction ({ paddingPx, ...props }) {\n const paddingPx_ = paddingPx ?? 11;\n return (\n <FormGroup\n {...props}\n css={css`\n margin: 0;\n\n border-radius: 5px;\n padding: ${paddingPx_}px;\n\n > label.bp4-label {\n font-weight: bold;\n margin-bottom: ${paddingPx_}px;\n }\n > .bp4-form-content {\n display: flex;\n flex-flow: column nowrap;\n gap: ${paddingPx_}px;\n\n > .bp4-form-group {\n margin: 0;\n }\n }\n\n /* Note: these colors are picked to work with some form widgets, date input widget specifically. */\n background: ${Colors.WHITE};\n .bp4-dark & { background: ${Colors.DARK_GRAY3}; }\n `}\n className={`${Classes.ELEVATION_3} ${props.className}`}\n />\n );\n};\n\n\nexport const MoreMenu: React.FC<Record<never, never>> = memo(function ({ children }) {\n return (\n <Popover minimal content={<>{children}</>}>\n <BaseButton icon=\"more\" small minimal />\n </Popover>\n );\n});\n\n\nexport const ItemClassMenu: React.FC<{\n cfg: ItemClassConfiguration<any>;\n onCreate?: () => void;\n}> = memo(function ({ cfg, onCreate }) {\n return (\n <Menu>\n <MenuDivider title=\"About this class\" />\n <MenuItem multiline disabled css={css`max-width: 400px`} text={cfg.meta.description} />\n {onCreate\n ? <>\n <MenuDivider title=\"Quick actions\" />\n <MenuItem\n text=\"Propose new\"\n intent=\"primary\"\n onClick={onCreate} icon=\"plus\"\n />\n </>\n : null}\n </Menu>\n );\n});\n"]}
|