@riboseinc/paneron-registry-kit 2.2.9 → 2.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/index.js +18 -0
  2. package/index.js.map +1 -1
  3. package/package.json +2 -2
  4. package/types/cr.d.ts +18 -0
  5. package/types/cr.js +37 -1
  6. package/types/cr.js.map +1 -1
  7. package/types/item.d.ts +1 -1
  8. package/types/item.js.map +1 -1
  9. package/types/register.js +1 -2
  10. package/types/register.js.map +1 -1
  11. package/types/stakeholder.d.ts +3 -1
  12. package/types/stakeholder.js +20 -0
  13. package/types/stakeholder.js.map +1 -1
  14. package/views/AnnotatedChange.js +7 -5
  15. package/views/AnnotatedChange.js.map +1 -1
  16. package/views/GenericRelatedItemView.js +4 -47
  17. package/views/GenericRelatedItemView.js.map +1 -1
  18. package/views/ItemDrawer.d.ts +11 -0
  19. package/views/ItemDrawer.js +69 -0
  20. package/views/ItemDrawer.js.map +1 -0
  21. package/views/change-request/ChangeRequestContext.d.ts +17 -1
  22. package/views/change-request/ChangeRequestContext.js +29 -5
  23. package/views/change-request/ChangeRequestContext.js.map +1 -1
  24. package/views/change-request/Proposals.d.ts +2 -0
  25. package/views/change-request/Proposals.js +116 -80
  26. package/views/change-request/Proposals.js.map +1 -1
  27. package/views/change-request/Summary.d.ts +12 -0
  28. package/views/change-request/Summary.js +59 -0
  29. package/views/change-request/Summary.js.map +1 -0
  30. package/views/change-request/TransitionHistory.d.ts +30 -0
  31. package/views/change-request/TransitionHistory.js +307 -0
  32. package/views/change-request/TransitionHistory.js.map +1 -0
  33. package/views/change-request/TransitionOptions.d.ts +38 -0
  34. package/views/{detail/ChangeRequest/transitions.js → change-request/TransitionOptions.js} +61 -51
  35. package/views/change-request/TransitionOptions.js.map +1 -0
  36. package/views/change-request/objectChangeset.d.ts +1 -1
  37. package/views/change-request/objectChangeset.js +1 -1
  38. package/views/change-request/objectChangeset.js.map +1 -1
  39. package/views/detail/ChangeRequest/index.js +129 -142
  40. package/views/detail/ChangeRequest/index.js.map +1 -1
  41. package/views/detail/RegisterHome/MetaSummary.d.ts +9 -0
  42. package/views/detail/RegisterHome/MetaSummary.js +35 -0
  43. package/views/detail/RegisterHome/MetaSummary.js.map +1 -0
  44. package/views/detail/RegisterHome/Proposal.d.ts +24 -0
  45. package/views/detail/RegisterHome/Proposal.js +228 -0
  46. package/views/detail/RegisterHome/Proposal.js.map +1 -0
  47. package/views/detail/RegisterHome/index.js +427 -137
  48. package/views/detail/RegisterHome/index.js.map +1 -1
  49. package/views/detail/RegisterItem/index.d.ts +2 -3
  50. package/views/detail/RegisterItem/index.js +239 -140
  51. package/views/detail/RegisterItem/index.js.map +1 -1
  52. package/views/detail/RegisterMeta/RegisterMetaForm.js +37 -45
  53. package/views/detail/RegisterMeta/RegisterMetaForm.js.map +1 -1
  54. package/views/detail/RegisterMeta/index.js +14 -11
  55. package/views/detail/RegisterMeta/index.js.map +1 -1
  56. package/views/diffing/InlineDiff.d.ts +27 -1
  57. package/views/diffing/InlineDiff.js +113 -2
  58. package/views/diffing/InlineDiff.js.map +1 -1
  59. package/views/util.d.ts +36 -2
  60. package/views/util.js +203 -2
  61. package/views/util.js.map +1 -1
  62. package/views/detail/ChangeRequest/transitions.d.ts +0 -28
  63. package/views/detail/ChangeRequest/transitions.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/detail/RegisterHome/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, { useContext, useState } from 'react';\n//import { Helmet } from 'react-helmet';\nimport { jsx, css } from '@emotion/react';\nimport type { ObjectChangeset } from '@riboseinc/paneron-extension-kit/types/objects';\nimport { Menu, MenuDivider, MenuItem, InputGroup, Button, NonIdealState, Spinner, Callout } from '@blueprintjs/core';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { registerStakeholderPlain } from '../../RegisterStakeholder';\nimport { newCRObjectChangeset, importedProposalToCRObjectChangeset } from '../../change-request/objectChangeset';\nimport { isImportableCR } from '../../../types/cr';\nimport { Protocols } from '../../protocolRegistry';\nimport { crIDToCRPath } from '../../itemPathUtils';\n\n\nconst RegisterHome: React.VoidFunctionComponent<Record<never, never>> =\nfunction () {\n const { spawnTab } = useContext(TabbedWorkspaceContext);\n const { customViews, registerMetadata, stakeholder, offline, itemClasses } = useContext(BrowserCtx);\n const {\n requestFileFromFilesystem,\n makeRandomID,\n getObjectData,\n updateObjects,\n performOperation,\n getMapReducedData,\n } = useContext(DatasetContext);\n\n const [ newProposalIdea, setNewProposalIdea ] = useState<string>('');\n\n const registerVersion = registerMetadata?.version;\n const canCreateCR = (\n stakeholder &&\n stakeholder.role &&\n stakeholder.gitServerUsername?.trim() !== '' &&\n makeRandomID &&\n updateObjects &&\n (registerVersion?.id ?? '').trim() !== '');\n\n async function createCR(justification: string): Promise<string> {\n if (canCreateCR) {\n const id = await makeRandomID();\n await updateObjects({\n commitMessage: \"start new proposal\",\n objectChangeset: newCRObjectChangeset(\n id,\n justification,\n registerVersion!,\n stakeholder.gitServerUsername!,\n ),\n });\n return id;\n } else {\n throw new Error(\"Unable to create proposal: read-only dataset\");\n }\n }\n\n async function handleNewProposal() {\n if (newProposalIdea) {\n const crID = await performOperation(\"creating proposal\", createCR)(newProposalIdea);\n setNewProposalIdea('');\n spawnTab(`${Protocols.CHANGE_REQUEST}:${crIDToCRPath(crID)}`);\n }\n }\n\n async function getCRImportChangeset(): Promise<[ObjectChangeset, string]> {\n if (!requestFileFromFilesystem) {\n throw new Error(\"Cannot request file from filesystem\");\n }\n const data = await requestFileFromFilesystem({\n prompt: \"Select one register proposal JSON file\",\n filters: [\n { name: \"JSON files\", extensions: ['.json'] },\n ],\n });\n const fileData = Object.values(data)[0]!;\n if (!fileData) {\n throw new Error(\"No file was selected\");\n }\n if (isImportableCR(fileData)) {\n const crID = fileData.proposalDraft.id;\n try {\n const changeset = await importedProposalToCRObjectChangeset(\n fileData,\n itemClasses,\n stakeholder!.gitServerUsername!,\n getObjectData,\n async function findObjects(predicate: string) {\n const result = (await getMapReducedData({\n chains: {\n _: {\n mapFunc: `\n const data = value.data;\n if (data && (${predicate})) {\n emit({ objectPath: key, objectData: value });\n }\n `,\n },\n },\n }));\n // NOTE: map returns an empty object if there’re no items,\n // but we promise to return a list.\n if (!Array.isArray(result._)) {\n return [];\n }\n return result._;\n },\n );\n return [changeset, crID];\n } catch (e) {\n throw new Error(\"Error reading proposal data\");\n }\n } else {\n throw new Error(\"Invalid proposal format\");\n }\n }\n\n async function handleImportProposal() {\n const [objectChangeset, crID] = await performOperation(\n 'reading proposal data',\n getCRImportChangeset,\n )();\n\n await performOperation(\n 'creating proposal',\n updateObjects ?? (async () => { throw new Error(\"Read-only dataset\"); }),\n )({\n commitMessage: \"import proposal\",\n objectChangeset,\n });\n\n setNewProposalIdea('');\n spawnTab(`${Protocols.CHANGE_REQUEST}:${crIDToCRPath(crID)}`);\n }\n\n const menu = (\n <Menu css={css`margin: 10px;`}>\n <MenuDivider title=\"Quick links\" />\n {customViews.map((cv, _) => \n <MenuItem\n key={cv.id}\n text={cv.label}\n title={cv.description}\n icon={cv.icon}\n onClick={() => spawnTab(`${Protocols.CUSTOM_VIEW}:${cv.id}/index`)}\n />\n )}\n {customViews.length > 0 ? <MenuDivider /> : null}\n\n <MenuItem\n text={`Propose a change to version ${registerMetadata?.version?.id ?? '(missing)'}`}\n disabled={!canCreateCR}\n icon=\"lightbulb\"\n title={canCreateCR\n ? \"A blank proposal will be created and opened in a new tab.\"\n : undefined}>\n <InputGroup\n value={newProposalIdea || undefined}\n placeholder=\"Your idea…\"\n title=\"Justification draft (you can change this later)\"\n onChange={evt => setNewProposalIdea(evt.currentTarget.value)}\n rightElement={\n <Button\n small\n intent={newProposalIdea ? 'primary': undefined}\n disabled={!newProposalIdea}\n onClick={handleNewProposal}\n icon=\"tick\"\n />\n }\n />\n </MenuItem>\n <MenuItem\n text=\"Import proposal\"\n icon=\"import\"\n disabled={!canCreateCR}\n onClick={handleImportProposal}\n />\n <MenuItem\n text=\"View register metadata\"\n icon=\"properties\"\n onClick={() => spawnTab(Protocols.REGISTER_META)}\n />\n </Menu>\n );\n\n const intro = <Callout intent=\"primary\" css={css`text-align: left;`}>\n {stakeholder\n ? <>You can create proposals as {registerStakeholderPlain(stakeholder)}.</>\n : offline\n ? <>\n Because this repository is offline (no remote configured),\n and remote username is currently required for proposal,\n you cannot create proposals.</>\n : <>\n Since your remote username is not in the list of stakeholders,\n you cannot create proposals currently.\n </>}\n </Callout>\n\n const greeting = registerMetadata\n ? <NonIdealState\n title={`Welcome to ${registerMetadata.name}`}\n description={<>\n {intro}\n {menu}\n </>}\n />\n : registerMetadata === undefined\n ? <NonIdealState\n icon={<Spinner />}\n description=\"Loading register information…\"\n />\n : <NonIdealState\n icon=\"heart-broken\"\n title=\"Register metadata is missing or invalid.\"\n description={<>\n {menu}\n </>}\n />;\n\n return greeting;\n}\n\nexport default RegisterHome;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/views/detail/RegisterHome/index.tsx"],"names":[],"mappings":"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","sourcesContent":["/** @jsx jsx */\n/** @jsxFrag React.Fragment */\n\nimport React, {\n useMemo,\n useContext,\n //useCallback,\n //useEffect,\n useState,\n} from 'react';\n//import { Helmet } from 'react-helmet';\nimport { jsx, css } from '@emotion/react';\nimport type { ObjectChangeset } from '@riboseinc/paneron-extension-kit/types/objects';\nimport { Menu, MenuItem, type MenuItemProps, NonIdealState, Spinner } from '@blueprintjs/core';\nimport { DatasetContext } from '@riboseinc/paneron-extension-kit/context';\nimport { toJSONNormalized } from '@riboseinc/paneron-extension-kit/util';\nimport { TabbedWorkspaceContext } from '@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context';\nimport { BrowserCtx } from '../../BrowserCtx';\nimport { ChangeRequestContext } from '../../change-request/ChangeRequestContext';\nimport { crIDToCRPath } from '../../itemPathUtils';\nimport { newCRObjectChangeset, importedProposalToCRObjectChangeset } from '../../change-request/objectChangeset';\nimport { isImportableCR } from '../../../types/cr';\nimport type { RegisterStakeholder, StakeholderRoleType } from '../../../types';\nimport { type SomeCR as CR, State } from '../../../types/cr';\nimport { canBeTransitionedBy } from '../../change-request/TransitionOptions';\nimport { canImportCR, canCreateCR } from '../../../types/stakeholder';\nimport { Protocols } from '../../protocolRegistry';\nimport MetaSummary from './MetaSummary';\nimport { TabContentsWithHeader, CardInGrid } from '../../util';\nimport { Proposals, CurrentProposal } from './Proposal';\n\n\nconst RegisterHome: React.VoidFunctionComponent<Record<never, never>> =\nfunction () {\n const { spawnTab } = useContext(TabbedWorkspaceContext);\n const {\n //customViews,\n registerMetadata, stakeholder,\n // offline,\n itemClasses,\n setActiveChangeRequestID,\n } = useContext(BrowserCtx);\n const {\n changeRequest: activeCR,\n canDelete,\n deleteCR,\n } = useContext(ChangeRequestContext);\n const {\n requestFileFromFilesystem,\n makeRandomID,\n getObjectData,\n updateObjects,\n performOperation,\n isBusy,\n getMapReducedData,\n useMapReducedData,\n } = useContext(DatasetContext);\n\n const registerVersion = registerMetadata?.version;\n\n const getNewEmptyCRChangeset:\n undefined | ((idea: string) => Promise<[ObjectChangeset, string]>) =\n useMemo(() => {\n if (makeRandomID && stakeholder && canCreateCR(stakeholder)) {\n return async function getNewEmptyCRChangeset (newIdea: string) {\n const crID = await makeRandomID();\n return [newCRObjectChangeset(\n crID,\n newIdea,\n registerVersion!,\n stakeholder!.gitServerUsername!,\n ), crID];\n };\n } else {\n return undefined;\n }\n }, [makeRandomID, stakeholder, registerVersion]);\n\n const getImportedCRChangeset:\n undefined | (() => Promise<[ObjectChangeset, string]>) =\n useMemo(() => {\n if (requestFileFromFilesystem && stakeholder && canImportCR(stakeholder)) {\n return async function getImportedCRChangeset() {\n const data = await requestFileFromFilesystem({\n prompt: \"Select one register proposal JSON file\",\n filters: [\n { name: \"JSON files\", extensions: ['.json'] },\n ],\n });\n const fileData = Object.values(data)[0]!;\n if (!fileData) {\n throw new Error(\"No file was selected\");\n }\n if (isImportableCR(fileData)) {\n try {\n const [changeset, crID] = await importedProposalToCRObjectChangeset(\n fileData,\n itemClasses,\n stakeholder!.gitServerUsername!,\n getObjectData,\n async function findObjects(predicate: string) {\n const result = await getMapReducedData({\n chains: {\n _: {\n mapFunc: `\n const data = value.data;\n if (data && (${predicate})) {\n emit({ objectPath: key, objectData: value });\n }\n `,\n },\n },\n });\n // NOTE: map returns an empty object if there’re no items,\n // but we promise to return a list.\n if (!Array.isArray(result._)) {\n return [];\n }\n return result._;\n },\n );\n return [changeset, crID];\n } catch (e) {\n throw new Error(\"Error reading proposal data\");\n }\n } else {\n throw new Error(\"Invalid proposal format\");\n }\n }\n } else {\n return undefined;\n }\n }, [getMapReducedData, requestFileFromFilesystem, getObjectData, stakeholder]);\n\n const [importCR, createCR] = useMemo(() => {\n if (updateObjects && setActiveChangeRequestID && !isBusy) {\n return [\n getImportedCRChangeset\n ? performOperation('importing proposal', async function () {\n const [objectChangeset, crID] = await getImportedCRChangeset(); \n await updateObjects({\n commitMessage: 'import proposal',\n objectChangeset,\n });\n setActiveChangeRequestID(crID);\n })\n : undefined,\n getNewEmptyCRChangeset\n ? performOperation('creating blank proposal', async function (newIdea: string) {\n const [objectChangeset, crID] = await getNewEmptyCRChangeset(newIdea);\n await updateObjects({\n commitMessage: `start new empty proposal ${newIdea}`,\n objectChangeset,\n });\n setActiveChangeRequestID(crID);\n })\n : undefined,\n ];\n } else {\n return [undefined, undefined];\n }\n }, [isBusy, performOperation, updateObjects, getImportedCRChangeset, getNewEmptyCRChangeset]);\n\n // Actionable proposals v2\n const proposalGroups = useMemo(\n (() => stakeholder?.role\n ? getActionableProposalGroupsForRole(stakeholder.role)\n : null),\n [stakeholder?.role]);\n\n const actionableProposalsResult = useMapReducedData({\n chains:\n (proposalGroups ?? []).\n map(([label, , queryGetter]) => {\n const query = queryGetter(stakeholder);\n const predicateFunc = `\n const objPath = key, obj = value;\n return ((${CR_BASE_QUERY}) && (${query}));\n `;\n const mapFunc = `emit(value);`;\n return { [label]: { mapFunc, predicateFunc } };\n }).reduce((prev, curr) => ({ ...prev, ...curr }), {}),\n });\n\n const actionableProposals: [string, CR[] | undefined][] = useMemo(\n (() =>\n Object.entries(actionableProposalsResult.value).\n map(([chainID, chainResult]) =>\n [\n chainID,\n (Array.isArray(chainResult)\n ? (chainResult as CR[])\n : undefined) || undefined\n ]\n )\n ),\n [actionableProposalsResult.value]);\n\n const handleRefreshProposals = actionableProposalsResult.refresh;\n\n // Actionable proposals\n // const [actionableProposals, setActionableProposals] =\n // useState<[string, CR[] | undefined][]>([]);\n // const [reqCounter, setReqCounter] = useState(1);\n // useEffect(() => {\n // let cancelled = false;\n // if (stakeholder) {\n // const proposalGroups = getActionableProposalGroupsForRole(stakeholder.role);\n // setActionableProposals(proposalGroups.map(([groupLabel, ]) => [groupLabel, undefined]));\n\n // async function updateItems([ groupLabel, , queryGetter ]: ActionableProposalGroup) {\n // const query = queryGetter(stakeholder);\n\n // const mapFunc = `\n // const objPath = key, obj = value;\n // if ((${CR_BASE_QUERY}) && (${query})) {\n // emit(obj);\n // }\n // `;\n // const result = await getMapReducedData({\n // chains: { _: { mapFunc } },\n // });\n // if (!Array.isArray(result._)) {\n // console.error(\"Weird result\", result);\n // }\n // if (!cancelled) {\n // setActionableProposals(previousGroups =>\n // previousGroups.map(([previousGroupLabel, previousProposals]) =>\n // previousGroupLabel === groupLabel\n // ? [previousGroupLabel, Array.isArray(result._) ? result._ : []]\n // : [previousGroupLabel, previousProposals]\n // )\n // );\n // }\n\n // };\n // proposalGroups.map(updateItems);\n // } else {\n // setActionableProposals([]);\n // }\n // return function cleanUp() { cancelled = true; };\n // }, [stakeholder, reqCounter, getMapReducedData]);\n\n // const handleRefreshProposals = useCallback(\n // (() => setReqCounter(c => c + 1)),\n // [setReqCounter]);\n\n // TODO: Move to action bar\n // const customActions = useMemo(() => customViews.map(cv => ({\n // key: cv.id,\n // text: cv.label,\n // title: cv.description,\n // icon: cv.icon,\n // onClick: () => spawnTab(`${Protocols.CUSTOM_VIEW}:${cv.id}/index`),\n // })), [spawnTab, customViews]);\n\n const [createMode, setCreateMode] = useState(false);\n //const canStakeholderCreateCRs = stakeholder && canCreateCR(stakeholder);\n const handleSelectProposal = useMemo(() => {\n return (setActiveChangeRequestID && !isBusy\n ? function (crid: string) { setActiveChangeRequestID?.(crid) }\n : undefined);\n }, [setActiveChangeRequestID, isBusy]);\n\n const proposalBlockActions = useMemo(() => {\n const actions = [];\n if (activeCR) {\n actions.push({\n text: \"Export proposal\",\n onClick: () => void 0,\n icon: 'export',\n disabled: true,\n } as const);\n actions.push({\n text: \"Exit proposal\",\n icon: 'log-out',\n intent: 'danger',\n disabled: isBusy,\n onClick: setActiveChangeRequestID\n ? () => setActiveChangeRequestID?.(null)\n : undefined,\n } as const);\n } else {\n if (stakeholder && canCreateCR(stakeholder)) {\n actions.push({\n text: \"Create blank proposal\",\n onClick: !createMode ? (() => setCreateMode(true)) : undefined,\n disabled: !createCR,\n active: createMode,\n selected: createMode,\n icon: 'add',\n intent: actionableProposals.length < 1\n ? 'primary'\n : undefined,\n } as const);\n }\n if (stakeholder && canImportCR(stakeholder)) {\n actions.push({\n text: \"Import proposal\",\n onClick: importCR,\n disabled: !importCR || createMode,\n icon: 'import',\n intent: actionableProposals.length < 1\n ? 'primary'\n : undefined,\n } as const);\n }\n }\n return actions;\n }, [!activeCR, createMode, importCR, createCR, isBusy, actionableProposals.length < 1]);\n\n const handleCreate = useMemo((() =>\n createCR && createMode\n ? async function (idea: string | false) {\n if (idea && createCR) {\n await createCR(idea);\n }\n setCreateMode(false);\n }\n : undefined\n ), [createMode, createCR]);\n\n const proposalBlock = useMemo(() => {\n if (registerMetadata /*&& actionableProposals.find(p => p[1] && p[1].length > 0)*/) {\n return (\n <HomeBlock\n View={Proposals}\n key=\"proposal dashboard\"\n description=\"Actionable proposals\"\n css={css`\n height: 300px;\n flex-basis: calc(50% - 10px);\n flex-grow: 1;\n `}\n props={{\n register: registerMetadata,\n actionableProposals,\n createMode,\n onCreate: handleCreate,\n onRefreshProposals: handleRefreshProposals,\n onSelectProposal: handleSelectProposal,\n }}\n actions={proposalBlockActions}\n />\n );\n } else {\n return null;\n }\n }, [\n createMode, registerMetadata,\n proposalBlockActions,\n handleSelectProposal,\n handleCreate,\n toJSONNormalized(actionableProposals),\n ]);\n\n const activeCRBlock = useMemo(() => {\n if (activeCR && registerMetadata) {\n const actions: MenuItemProps[] = stakeholder && canBeTransitionedBy(stakeholder, activeCR)\n ? [/*{\n // Action is taken from within the widget.\n text: \"Take action\",\n onClick: () => void 0,\n icon: 'take-action',\n intent: 'primary',\n }*/]\n : canDelete\n ? [{\n text: \"Delete this proposal draft\",\n onClick: deleteCR,\n disabled: !deleteCR,\n icon: 'delete',\n intent: 'danger',\n }]\n : [];\n actions.push({\n text: \"Open in new window\",\n onClick: async () => spawnTab(`${Protocols.CHANGE_REQUEST}:${crIDToCRPath(activeCR.id)}`),\n });\n return (\n <HomeBlock\n View={CurrentProposal}\n description=\"Active proposal\"\n props={{ proposal: activeCR, stakeholder, register: registerMetadata }}\n css={css`\n height: 300px;\n flex-basis: calc(50% - 10px);\n flex-grow: 1;\n `}\n actions={actions}\n />\n );\n } else {\n return null;\n }\n }, [activeCR, registerMetadata, canDelete, deleteCR, stakeholder]);\n\n const registerMetaBlock = useMemo(() => {\n if (!activeCRBlock && stakeholder) {\n return (\n <HomeBlock\n View={MetaSummary}\n description=\"Register summary\"\n props={registerMetadata\n ? {\n register: registerMetadata,\n style: { padding: '10px 12px 0 12px', flexGrow: 1, flexShrink: 0 },\n }\n : registerMetadata}\n error={registerMetadata === null\n ? \"Failed to load register metadata\"\n : undefined}\n css={css`\n height: 300px;\n flex-basis: calc(50% - 10px);\n flex-grow: 1;\n `}\n actions={[{\n text: \"View or edit register metadata\",\n onClick: () => spawnTab(Protocols.REGISTER_META),\n icon: 'properties',\n }]}\n />\n );\n } else {\n return null;\n }\n }, [!activeCRBlock, registerMetadata, stakeholder]);\n\n return (\n <TabContentsWithHeader\n title={registerMetadata?.name ?? 'Register'}\n layout=\"card-grid\">\n\n {activeCRBlock ?? registerMetaBlock}\n\n {proposalBlock}\n\n {/* TODO: Move to action bar customActions.length > 0\n ? <HomeBlock\n description=\"Custom actions\"\n View={() => <></>}\n props={{}}\n actions={customActions}\n />\n : null*/}\n\n </TabContentsWithHeader>\n );\n}\n\nexport default RegisterHome;\n\n\ninterface HomeBlockProps<P extends Record<string, any>> {\n description: string,\n View: React.VoidFunctionComponent<P>,\n\n /** Props to pass the `View`. */\n props: P | null | undefined,\n\n /** Shown if `props` is `null`. */\n error?: string | JSX.Element,\n\n /** Shown beneath `View`. */\n actions?: MenuItemProps[],\n\n /** Applies to wrapper card div. */\n className?: string,\n}\nfunction HomeBlock<P extends Record<string, any>>(\n { View, description, props, error, actions, className }: HomeBlockProps<P>\n) {\n return (\n <CardInGrid\n css={css`\n padding: 5px;\n display: flex; flex-flow: column nowrap;\n overflow: hidden;\n transition:\n width .5s linear,\n height .5s linear;\n `}\n description={description}\n className={className}>\n {props\n ? <View {...props} />\n : props === undefined\n ? <NonIdealState icon={<Spinner />} />\n : <NonIdealState icon=\"heart-broken\" title=\"Failed to load\" description={error} />}\n {(actions?.length ?? 0) > 0\n ? <Menu css={css`background: none !important; flex-shrink: 0;`}>\n {actions!.map((mip, idx) => <MenuItem key={idx} {...mip }/>)}\n </Menu>\n : null}\n </CardInGrid>\n );\n}\n\n\nfunction getActionableProposalGroupsForRole(role: StakeholderRoleType): ActionableProposalGroup[] {\n return CR_QUERIES_FOR_ROLES.filter(([, roles]) => roles.has(role));\n}\n\n\nconst CR_BASE_QUERY = 'objPath.indexOf(\"/proposals/\") === 0 && objPath.endsWith(\"main.yaml\")';\ntype ActionableProposalGroup = readonly [\n label: string,\n roles: Set<StakeholderRoleType>,\n queryGetter: (stakeholder?: RegisterStakeholder) => string,\n];\nconst CR_QUERIES_FOR_ROLES: readonly ActionableProposalGroup[] =\n[\n ['My Drafts', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {\n if (stakeholder && stakeholder.gitServerUsername) {\n const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === \"${stakeholder.gitServerUsername}\"`;\n const query = `(obj.state === \"${State.DRAFT}\" || obj.state === \"${State.RETURNED_FOR_CLARIFICATION}\") && (${stakeholderCondition})`;\n return query;\n } else {\n return 'false';\n }\n }],\n ['My Rejected', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {\n // Rejections are actionable because they can be appealed by the submitter.\n if (stakeholder && stakeholder.gitServerUsername) {\n const stakeholderCondition = `obj.submittingStakeholderGitServerUsername === \"${stakeholder.gitServerUsername}\"`;\n const query = `(obj.state === \"${State.REJECTED}\") && (${stakeholderCondition})`;\n return query;\n } else {\n return 'false';\n }\n }],\n ['Everyone’s Drafts or Returned', new Set(['manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {\n if (stakeholder && stakeholder.gitServerUsername) {\n const stakeholderCondition = `obj.submittingStakeholderGitServerUsername !== \"${stakeholder.gitServerUsername}\"`;\n const query = `(obj.state === \"${State.DRAFT}\" || obj.state === \"${State.RETURNED_FOR_CLARIFICATION}\") && (${stakeholderCondition})`;\n return query;\n } else {\n return 'false';\n }\n }],\n // ['latest reviewed', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {\n // // TODO: Should filter only rejected perhaps?\n // // Approved/accepted proposals can be shown in another (public) area.\n // if (stakeholder && stakeholder.gitServerUsername) {\n // const stakeholderCondition = stakeholder?.role !== 'submitter'\n // ? 'true'\n // : `obj.submittingStakeholderGitServerUsername === \"${stakeholder.gitServerUsername}\"`;\n // // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.\n // const query = `(obj.state === \"${State.ACCEPTED} || obj.state === \"${State.REJECTED} || obj.state === \"${State.REJECTION_UPHELD_ON_APPEAL}\"\") && ${stakeholderCondition}`;\n // return query;\n // } else {\n // return 'false';\n // }\n // // TODO: Implement limit\n // }],\n // ['latest withdrawn', new Set(['submitter', 'manager', 'control-body', 'owner']), function submitterProposals(stakeholder) {\n // if (stakeholder && stakeholder.gitServerUsername) {\n // const stakeholderCondition = stakeholder?.role !== 'submitter'\n // ? 'true'\n // : `obj.submittingStakeholderGitServerUsername === \"${stakeholder.gitServerUsername}\"`;\n // // Don’t show drafts in the list of pending proposals, unless it’s user’s own drafts.\n // const query = `(obj.state === \"${State.WITHDRAWN}\" || obj.state === \"${State.APPEAL_WITHDRAWN}\") && ${stakeholderCondition}`;\n // return query;\n // } else {\n // return 'false';\n // }\n // // TODO: Implement limit\n // }],\n ['Pending Owner Appeal Review', new Set(['owner']), function ownerProposals() {\n return `obj.state === \"${State.APPEALED}\"`;\n }],\n ['Pending Control Body Review', new Set(['control-body', 'owner']), function cbProposals() {\n return `obj.state === \"${State.SUBMITTED_FOR_CONTROL_BODY_REVIEW}\"`;\n }],\n ['Pending Manager Review', new Set(['manager', 'control-body', 'owner']), function managerProposals() {\n return `obj.state === \"${State.PROPOSED}\"`;\n }],\n] as const;\n"]}
@@ -3,16 +3,15 @@
3
3
  import React from 'react';
4
4
  import { type RegisterItem, type InternalItemReference, type ItemClassConfiguration } from '../../../types';
5
5
  export declare const ItemDetail: React.VoidFunctionComponent<{
6
- item: RegisterItem<any>;
6
+ item: RegisterItem;
7
7
  itemRef: InternalItemReference;
8
8
  itemClass: ItemClassConfiguration<any>;
9
9
  className?: string;
10
- inProposalWithID?: string;
10
+ compactHeader?: boolean;
11
11
  }>;
12
12
  declare const _default: {
13
13
  main: React.VoidFunctionComponent<{
14
14
  uri: string;
15
- inProposalWithID?: string | undefined;
16
15
  }>;
17
16
  title: React.FC<{
18
17
  uri: string;
@@ -9,16 +9,12 @@ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _react2 = require("@emotion/react");
11
11
 
12
- var _styled = _interopRequireDefault(require("@emotion/styled"));
13
-
14
12
  var _core = require("@blueprintjs/core");
15
13
 
16
14
  var _context = require("@riboseinc/paneron-extension-kit/context");
17
15
 
18
16
  var _util = require("@riboseinc/paneron-extension-kit/util");
19
17
 
20
- var _HelpTooltip = _interopRequireDefault(require("@riboseinc/paneron-extension-kit/widgets/HelpTooltip"));
21
-
22
18
  var _context2 = require("@riboseinc/paneron-extension-kit/widgets/TabbedWorkspace/context");
23
19
 
24
20
  var _useSingleRegisterItemData = _interopRequireDefault(require("../../hooks/useSingleRegisterItemData"));
@@ -58,8 +54,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
58
54
  * is also reused within change request view.
59
55
  */
60
56
  const MaybeItemDetail = (0, _react.memo)(function ({
61
- uri,
62
- inProposalWithID
57
+ uri
63
58
  }) {
64
59
  var _a, _b, _c; //const { value: itemData } = useSingleRegisterItemData(ref);
65
60
 
@@ -98,8 +93,7 @@ const MaybeItemDetail = (0, _react.memo)(function ({
98
93
  return (0, _react2.jsx)(ItemDetail, {
99
94
  item: itemData,
100
95
  itemRef: itemRef,
101
- itemClass: itemClass,
102
- inProposalWithID: inProposalWithID
96
+ itemClass: itemClass
103
97
  });
104
98
  } else if (itemResponse.isUpdating) {
105
99
  return (0, _react2.jsx)("div", {
@@ -135,9 +129,9 @@ const ItemDetail = (0, _react.memo)(function ({
135
129
  itemRef,
136
130
  itemClass,
137
131
  className,
138
- inProposalWithID
132
+ compactHeader
139
133
  }) {
140
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
134
+ var _a, _b, _c, _d, _e, _f;
141
135
 
142
136
  const {
143
137
  subregisters,
@@ -156,12 +150,44 @@ const ItemDetail = (0, _react.memo)(function ({
156
150
  const {
157
151
  spawnTab
158
152
  } = (0, _react.useContext)(_context2.TabbedWorkspaceContext);
159
- const [editedClarification, setEditedClarification] = (0, _react.useState)(null); //const [ diffMode, setDiffMode ] = useState<boolean>(false);
153
+ const [editedItemData, setEditedItemData] = (0, _react.useState)(null);
154
+ const itemDataHasChanges = JSON.stringify(editedItemData) !== JSON.stringify(item.data); // Gather views
155
+
156
+ const ListItemView = itemClass.views.listItemView;
157
+ let details;
158
+
159
+ if (editedItemData !== null && activeCRIsEditable) {
160
+ const EditView = itemClass.views.editView;
161
+ details = (0, _react2.jsx)(EditView, {
162
+ itemData: editedItemData,
163
+ itemRef: itemRef,
164
+ onChange: !isBusy ? setEditedItemData : undefined
165
+ });
166
+ } else {
167
+ const DetailView = (_a = itemClass.views.detailView) !== null && _a !== void 0 ? _a : itemClass.views.editView;
168
+ details = (0, _react2.jsx)(DetailView, {
169
+ itemRef: itemRef,
170
+ itemData: item.data
171
+ });
172
+ }
173
+
174
+ console.debug("Rendering RegisterItem view");
175
+ const [isEditingProposal, setIsEditingProposal] = (0, _react.useState)(false); //const [ diffMode, setDiffMode ] = useState<boolean>(false);
160
176
  // TODO: Implement diff mode
161
177
 
162
178
  const diffMode = false;
163
179
  const itemPath = (0, _itemPathUtils.itemRefToItemPath)(itemRef);
164
- const proposal = (_a = activeCR && activeCR.items[itemPath] ? activeCR.items[itemPath] : null) !== null && _a !== void 0 ? _a : null;
180
+ /** Proposal for the current item. */
181
+
182
+ const proposal = (_b = activeCR && activeCR.items[itemPath] ? activeCR.items[itemPath] : null) !== null && _b !== void 0 ? _b : null; // It’s superseded (whether in current proposal or not)
183
+
184
+ const isSuperseded = item.status === 'superseded'; // Item is valid, proposal is editable, and no change to this item is proposed yet
185
+
186
+ const canBeSuperseded = activeCRIsEditable && !proposal && !editedItemData && item.status === 'valid'; // This item is being superseded in active proposal
187
+ // XXX: May be redundant with `isSuperseded`?
188
+
189
+ const isBeingSuperseded = (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession'; // Editing is possible for additions and clarifications.
190
+ //const itemDataCanBeEdited = activeCRIsEditable && proposal && proposal.type !== 'amendment';
165
191
 
166
192
  const handleClearProposal = () => performProposalOperation('clearing draft proposal', null);
167
193
 
@@ -185,14 +211,14 @@ const ItemDetail = (0, _react.memo)(function ({
185
211
  await performProposalOperation('proposing clarification', {
186
212
  type: 'clarification'
187
213
  });
188
- setEditedClarification(null);
214
+ setEditedItemData(null); // XXX: Redundant?
189
215
  };
190
216
 
191
217
  const handleEditAddition = async () => {
192
218
  await performProposalOperation('editing proposed addition', {
193
219
  type: 'addition'
194
220
  });
195
- setEditedClarification(null);
221
+ setEditedItemData(null); // XXX: Redundant?
196
222
  };
197
223
 
198
224
  async function performProposalOperation(summary, proposal) {
@@ -204,7 +230,7 @@ const ItemDetail = (0, _react.memo)(function ({
204
230
  throw new Error("Proposal isn’t editable");
205
231
  }
206
232
 
207
- if (proposal && (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'amendment' && !editedClarification) {
233
+ if (proposal && (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'amendment' && !editedItemData) {
208
234
  throw new Error("Missing item data");
209
235
  }
210
236
 
@@ -213,19 +239,21 @@ const ItemDetail = (0, _react.memo)(function ({
213
239
  objectChangeset: (0, _objectChangeset.updateCRObjectChangeset)( // TODO: We are sure it’s editable already, but casting should be avoided
214
240
  activeCR, {
215
241
  [itemPath]: proposal
216
- }, proposal && (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'amendment' && editedClarification ? {
242
+ }, proposal && (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'amendment' && editedItemData ? {
217
243
  [itemPath]: { ...item,
218
- data: editedClarification
244
+ data: editedItemData
219
245
  }
220
246
  } : {}),
221
247
  // We need this because updateCRObjectChangeset
222
248
  // omits oldValue for item data payloads.
223
249
  _dangerouslySkipValidation: true
224
250
  });
225
- }, [editedClarification, activeCRIsEditable, itemPath, item, activeCR, updateObjects]); // TODO: Very similar to `handleAdd()` in Browse sidebar menu; refactor?
251
+ setEditedItemData(null);
252
+ setIsEditingProposal(false);
253
+ }, [editedItemData, activeCRIsEditable, itemPath, item, activeCR, updateObjects]); // TODO: Very similar to `handleAdd()` in Browse sidebar menu; refactor?
226
254
 
227
255
  const handleProposeLikeThis = (0, _react.useCallback)(async function _handleProposeLikeThis() {
228
- if (!updateObjects || !makeRandomID || !activeCRIsEditable || !activeCR || !itemClass || !(0, _types.isRegisterItem)(item)) {
256
+ if (!updateObjects || !makeRandomID || !activeCRIsEditable || !activeCR) {
229
257
  throw new Error("Unable to create item: likely current proposal is not editable or dataset is read-only");
230
258
  }
231
259
 
@@ -267,109 +295,191 @@ const ItemDetail = (0, _react.memo)(function ({
267
295
  } else {
268
296
  throw new Error("Newly created item did not pass validation (this is likely a bug in RegistryKit");
269
297
  }
270
- }, [updateObjects, activeCRIsEditable, itemPath, activeCR === null || activeCR === void 0 ? void 0 : activeCR.id, activeCR === null || activeCR === void 0 ? void 0 : activeCR.state, Object.entries((_b = activeCR === null || activeCR === void 0 ? void 0 : activeCR.items) !== null && _b !== void 0 ? _b : {}).flat().map(i => JSON.stringify(i)).toString(), item ? JSON.stringify((0, _util.normalizeObject)(item)) : item]);
271
- let details;
272
-
273
- if (editedClarification !== null && activeCRIsEditable) {
274
- const EditView = itemClass.views.editView;
275
- details = (0, _react2.jsx)(EditView, {
276
- itemData: editedClarification,
277
- itemRef: itemRef,
278
- onChange: !isBusy ? setEditedClarification : undefined
279
- });
280
- } else {
281
- const DetailView = (_c = itemClass.views.detailView) !== null && _c !== void 0 ? _c : itemClass.views.editView;
282
- details = (0, _react2.jsx)(DetailView, {
283
- itemRef: itemRef,
284
- itemData: item.data
298
+ }, [updateObjects, activeCRIsEditable, itemPath, activeCR === null || activeCR === void 0 ? void 0 : activeCR.id, activeCR === null || activeCR === void 0 ? void 0 : activeCR.state, Object.entries((_c = activeCR === null || activeCR === void 0 ? void 0 : activeCR.items) !== null && _c !== void 0 ? _c : {}).flat().map(i => JSON.stringify(i)).toString(), item ? JSON.stringify((0, _util.normalizeObject)(item)) : item]);
299
+ const proposedSupersedingItemRefs = (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession' ? proposal.supersedingItemIDs.map(id => ({
300
+ itemID: id,
301
+ // Superseding items are always of the same class
302
+ classID: itemClass.meta.id,
303
+ // Superseding items are always in the same subregister
304
+ subregisterID: itemRef.subregisterID
305
+ })) : undefined;
306
+ const supersedingItemRefs = (_d = proposedSupersedingItemRefs !== null && proposedSupersedingItemRefs !== void 0 ? proposedSupersedingItemRefs : item.supersededBy) !== null && _d !== void 0 ? _d : [];
307
+ const supersedingItemRefsCacheKey = supersedingItemRefs.map(i => JSON.stringify(i)).toString();
308
+ const supersedingItemsTooltip = (0, _react.useMemo)(() => ({
309
+ icon: 'info-sign',
310
+ content: (0, _react2.jsx)(_RelatedItems.RelatedItems, {
311
+ css: (0, _react2.css)`background-color: ${_core.Colors.LIGHT_GRAY3}; padding: 5px;`,
312
+ availableClassIDs: [itemClass.meta.id],
313
+ itemRefs: supersedingItemRefs
314
+ })
315
+ }), [supersedingItemRefsCacheKey, itemClass.meta.id]);
316
+ const classification = (0, _react.useMemo)(() => {
317
+ var _a, _b, _c, _d;
318
+
319
+ const classification = [{
320
+ icon: 'document',
321
+ children: (0, _react2.jsx)(_react.default.Fragment, null, "Register item", itemRef.subregisterID ? (0, _react2.jsx)("span", {
322
+ title: "Subregister"
323
+ }, " in ", (_b = (_a = subregisters === null || subregisters === void 0 ? void 0 : subregisters[itemRef.subregisterID]) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : itemRef.subregisterID) : null),
324
+ tooltip: {
325
+ icon: 'info-sign',
326
+ content: (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.UL, {
327
+ css: (0, _react2.css)`margin: 0;`
328
+ }, (0, _react2.jsx)("li", null, "Class ID: ", itemClass.meta.id), (0, _react2.jsx)("li", null, "Subregister ID: ", (_c = itemRef.subregisterID) !== null && _c !== void 0 ? _c : 'N/A'), (0, _react2.jsx)("li", null, "UUID: ", itemRef.itemID)))
329
+ }
330
+ }, {
331
+ children: itemClass.meta.title,
332
+ tooltip: {
333
+ icon: 'info-sign',
334
+ content: (0, _react2.jsx)(_react.default.Fragment, null, (_d = itemClass.meta.description) !== null && _d !== void 0 ? _d : "No description is provided for this register item class.")
335
+ }
336
+ }];
337
+ classification.push({
338
+ children: item.status,
339
+ intent: item.status === 'valid' ? 'success' : undefined,
340
+ icon: item.status === 'invalid' ? 'ban-circle' : item.status === 'retired' ? 'warning-sign' : 'tick',
341
+ tooltip: isSuperseded ? supersedingItemsTooltip : undefined
285
342
  });
286
- }
287
343
 
288
- console.debug("Rendering RegisterItem view"); //const canAmend = activeCR && itemData.status === 'valid';
289
-
290
- const itemStatus = (0, _react2.jsx)(FormGroup, {
291
- inline: true,
292
- label: "status:",
293
- css: (0, _react2.css)`margin: 0;`
294
- }, (0, _react2.jsx)(_core.ControlGroup, {
295
- fill: true
296
- }, (0, _react2.jsx)(_core.InputGroup, {
297
- value: (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' ? `${proposal.amendmentType} proposed` : (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'addition' ? "addition proposed" : item.status,
298
- intent: (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' ? 'warning' : (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'addition' ? 'primary' : item.status === 'valid' ? 'success' : undefined,
299
- leftIcon: proposal && (proposal.type === 'amendment' || proposal.type === 'addition') ? 'asterisk' : item.status === 'valid' ? 'tick' : item.status === 'invalid' ? 'ban-circle' : 'warning-sign',
300
- readOnly: true
301
- }), activeCRIsEditable && !editedClarification ? (0, _react2.jsx)(_react.default.Fragment, null, (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'addition' ? (0, _react2.jsx)(_core.Button, {
302
- intent: "warning",
303
- title: "Remove the proposal to add this new item.",
304
- disabled: isBusy,
305
- onClick: handleClearProposal
306
- }, "Remove proposed addition") : null, (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' ? (0, _react2.jsx)(_core.Button, {
307
- intent: "warning",
308
- title: `Remove amendment (${proposal.amendmentType}) for this item from current proposal.`,
309
- disabled: isBusy,
310
- onClick: handleClearProposal
311
- }, "Clear proposed amendment") : !proposal && item.status === 'valid' ? (0, _react2.jsx)(_core.ButtonGroup, null, (0, _react2.jsx)(_core.Button, {
312
- intent: "primary",
313
- disabled: isBusy,
314
- onClick: handleRetire
315
- }, "Retire"), (0, _react2.jsx)(_core.Button, {
316
- intent: "primary",
317
- disabled: isBusy,
318
- onClick: handleInvalidate
319
- }, "Invalidate")) : null) : null)); // It’s superseded (whether in current proposal or not)
344
+ if (proposal) {
345
+ classification.push({
346
+ children: proposal.type === 'amendment' ? `${proposal.amendmentType} proposed` : proposal.type === 'addition' ? "addition proposed" : proposal.type === 'clarification' ? "clarification proposed" : "(unknown proposal type)",
347
+ intent: proposal.type === 'amendment' ? 'warning' : proposal.type === 'addition' || proposal.type === 'clarification' ? 'primary' : undefined,
348
+ icon: 'lightbulb',
349
+ minimal: false,
350
+ tooltip: canBeSuperseded || isBeingSuperseded ? supersedingItemsTooltip : undefined
351
+ });
352
+ }
320
353
 
321
- const isSuperseded = item.status === 'superseded'; // Item is valid, proposal is editable, and no change to this item is proposed yet
354
+ return classification;
355
+ }, [proposal === null || proposal === void 0 ? void 0 : proposal.type, itemClass.meta.id, item.status, isSuperseded, canBeSuperseded, isBeingSuperseded, supersedingItemsTooltip]);
356
+ const actions = (0, _react.useMemo)(() => {
357
+ const actions = [];
358
+ const isEditingItemData = editedItemData !== null;
359
+ const itemHasProposal = proposal !== null; //const canPropose = activeCRIsEditable && item.status === 'valid' && !isBusy;
322
360
 
323
- const canBeSuperseded = activeCRIsEditable && !proposal && !editedClarification && item.status === 'valid'; // This item is being superseded in active proposal
324
- // XXX: May be redundant with `isSuperseded`?
361
+ const itemIsProposable = item.status === 'valid';
362
+
363
+ if (activeCRIsEditable) {
364
+ actions.push({
365
+ children: "Propose another item like this",
366
+ icon: 'duplicate',
367
+ disabled: isBusy,
368
+ onClick: performOperation('adding duplicate item to current propposal', handleProposeLikeThis) //title="Propose a new item in current proposal, using this item as template."
325
369
 
326
- const isBeingSuperseded = (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession';
327
- const supersedingItems = isSuperseded || canBeSuperseded || isBeingSuperseded ? (0, _react2.jsx)(FormGroup, {
328
- inline: true,
329
- label: "superseded by: ",
330
- css: (0, _react2.css)`margin: 0;`
331
- }, (0, _react2.jsx)(_RelatedItems.RelatedItems, {
332
- availableClassIDs: [itemClass.meta.id],
333
- itemRefs: (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession' ? proposal.supersedingItemIDs.map(id => ({
334
- itemID: id,
335
- // Superseding items are always of the same class
336
- classID: itemClass.meta.id,
337
- // Superseding items are always in the same subregister
338
- subregisterID: itemRef.subregisterID
339
- })) : (_d = item.supersededBy) !== null && _d !== void 0 ? _d : [],
340
- onChange: !isBusy && activeCRIsEditable && ((proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession' || !proposal && item.status === 'valid') ? items => items.length > 0 ? handleSupersedeWith(items.map(ref => ref.itemID)) : handleClearProposal() : undefined
341
- })) : null;
342
- const clarificationHasChanges = JSON.stringify(editedClarification) !== JSON.stringify(item.data);
343
- const clarificationAction = proposal && (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'amendment' || activeCRIsEditable && !proposal && item.status === 'valid' ? (0, _react2.jsx)(FormGroup, {
344
- inline: true,
345
- label: `${(_e = proposal === null || proposal === void 0 ? void 0 : proposal.type) !== null && _e !== void 0 ? _e : "clarification"}: `,
346
- css: (0, _react2.css)`margin: 0;`
347
- }, activeCRIsEditable ? (0, _react2.jsx)(_core.ButtonGroup, null, editedClarification ? (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.Button, {
348
- intent: clarificationHasChanges ? "primary" : undefined,
349
- // TODO(perf): this is expensive if renders are frequent…
350
- disabled: !clarificationHasChanges || isBusy,
351
- onClick: !proposal || (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'clarification' ? handleClarify : handleEditAddition
352
- }, "Save"), (0, _react2.jsx)(_core.Button, {
353
- onClick: () => setEditedClarification(null)
354
- }, "Do not save")) : (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.Button, {
355
- disabled: diffMode || isBusy,
356
- intent: "primary",
357
- outlined: true,
358
- onClick: () => setEditedClarification(item.data)
359
- }, !proposal ? "Clarify" : "Edit"), (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'clarification' ? (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.Button, {
360
- disabled: diffMode || isBusy || (proposal === null || proposal === void 0 ? void 0 : proposal.type) !== 'clarification',
361
- intent: "warning",
362
- onClick: handleClearProposal
363
- }, "Clear")) : null)) : (0, _react2.jsx)(_core.Button, {
364
- disabled: true
365
- }, (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'clarification' ? "Clarified" : "Added", " in active proposal")) : null;
366
- const proposeLikeThis = activeCRIsEditable && !editedClarification ? (0, _react2.jsx)(_core.Button, {
367
- title: "Propose a new item in current proposal, using this item as template.",
368
- icon: 'plus',
369
- disabled: isBusy,
370
- outlined: true,
371
- onClick: performOperation('duplicating item', handleProposeLikeThis)
372
- }, "Propose another like this") : null; // If there’s a CR context without active CR,
370
+ });
371
+ const saveEditedItemDataButton = {
372
+ intent: 'primary',
373
+ disabled: isBusy || !itemDataHasChanges,
374
+ onClick: !proposal || proposal.type === 'clarification' ? handleClarify : handleEditAddition,
375
+ children: "Save changes"
376
+ };
377
+ const supersedingItemRefs = (proposal === null || proposal === void 0 ? void 0 : proposal.type) === 'amendment' && proposal.amendmentType === 'supersession' ? proposal.supersedingItemIDs.map(id => ({
378
+ itemID: id,
379
+ // Superseding items are always of the same class
380
+ classID: itemClass.meta.id,
381
+ // Superseding items are always in the same subregister
382
+ subregisterID: itemRef.subregisterID
383
+ })) : [];
384
+ const supersedingItems = (0, _react2.jsx)(_RelatedItems.RelatedItems, {
385
+ availableClassIDs: [itemClass.meta.id],
386
+ itemRefs: supersedingItemRefs,
387
+ onChange: !isBusy ? items => items.length > 0 ? handleSupersedeWith(items.map(ref => ref.itemID)) : handleClearProposal() : undefined
388
+ });
389
+
390
+ if (itemIsProposable) {
391
+ if (itemHasProposal) {
392
+ const proposeBtn = {
393
+ children: `Edit ${proposal.type === 'amendment' ? proposal.amendmentType : proposal.type} proposal for this item`,
394
+ icon: 'edit',
395
+ active: isEditingProposal,
396
+ disabled: isBusy,
397
+ onClick: () => {
398
+ if (isEditingProposal) {
399
+ setIsEditingProposal(false);
400
+ setEditedItemData(null);
401
+
402
+ if (proposal && proposal.type !== 'amendment') {}
403
+ } else {
404
+ setIsEditingProposal(true);
405
+
406
+ if (proposal && proposal.type !== 'amendment') {
407
+ setEditedItemData(item.data);
408
+ }
409
+ }
410
+ }
411
+ };
412
+
413
+ if (isEditingProposal) {
414
+ const editActions = [{
415
+ disabled: isBusy || itemDataHasChanges && proposal.type !== 'amendment',
416
+ onClick: handleClearProposal,
417
+ icon: 'trash',
418
+ children: "Remove",
419
+ tooltip: [`NOTE: Discarding this proposal `, `will discard ${proposal.type === 'addition' ? "new" : "changes to"} item’s data `, 'you provided as part of the proposal.'].join(''),
420
+ intent: proposal.type !== 'amendment' ? 'danger' : 'warning'
421
+ }];
422
+
423
+ if (isEditingItemData) {
424
+ editActions.push(saveEditedItemDataButton);
425
+ } else if (proposal.type === 'amendment' && proposal.amendmentType === 'supersession') {
426
+ editActions.push({
427
+ disabled: isBusy,
428
+ children: "Specify superseding items",
429
+ popup: (0, _react2.jsx)("div", {
430
+ css: (0, _react2.css)`padding: 10px;`
431
+ }, supersedingItems)
432
+ });
433
+ }
434
+
435
+ actions.push([proposeBtn, ...editActions]);
436
+ } else {
437
+ actions.push(proposeBtn);
438
+ }
439
+ } else {
440
+ const proposeBtn = {
441
+ children: "Propose to change this item",
442
+ icon: 'lightbulb',
443
+ active: isEditingProposal,
444
+ disabled: isBusy,
445
+ onClick: () => setIsEditingProposal(v => !v)
446
+ };
447
+
448
+ if (isEditingProposal) {
449
+ const proposalGroup = [proposeBtn, {
450
+ disabled: isBusy || itemHasProposal,
451
+ onClick: handleRetire,
452
+ children: "Retire"
453
+ }, {
454
+ disabled: isBusy || itemHasProposal,
455
+ onClick: handleInvalidate,
456
+ children: "Invalidate"
457
+ }, {
458
+ disabled: isBusy || itemHasProposal || isEditingItemData,
459
+ popup: supersedingItems,
460
+ children: "Supersede"
461
+ }, {
462
+ disabled: isBusy || diffMode,
463
+ active: isEditingItemData,
464
+ onClick: () => setEditedItemData(d => d === null ? item.data : null),
465
+ children: "Clarify"
466
+ }];
467
+
468
+ if (isEditingItemData && itemDataHasChanges) {
469
+ proposalGroup.push(saveEditedItemDataButton);
470
+ }
471
+
472
+ actions.push(proposalGroup);
473
+ } else {
474
+ actions.push(proposeBtn);
475
+ }
476
+ }
477
+ }
478
+ } // TODO: diff view
479
+
480
+
481
+ return actions;
482
+ }, [isBusy, itemClass.meta.id, proposal === null, proposal === null || proposal === void 0 ? void 0 : proposal.type, (_e = proposal === null || proposal === void 0 ? void 0 : proposal.supersedingItemIDs) === null || _e === void 0 ? void 0 : _e.toString(), activeCRIsEditable, editedItemData === null, itemDataHasChanges, isEditingProposal, performOperation, handleSetProposal]); // If there’s a CR context without active CR,
373
483
  // or active CR isn’t the same as the one in CR context,
374
484
  // then we can assume that the item is shown in proposal window
375
485
  // and we’d set window title to proposal’s title rather than item’s.
@@ -379,22 +489,17 @@ const ItemDetail = (0, _react.memo)(function ({
379
489
  // (makes sense because the user *is* technically viewing a proposal then).
380
490
 
381
491
  const windowTitle = activeCR && (!globallyActiveCRID || activeCR.id !== globallyActiveCRID || activeCR.items[itemPath]) ? `Proposal ${(0, _util2.maybeEllipsizeString)(activeCR.justification, 20)}…` : `${(_f = itemClass.meta.title) !== null && _f !== void 0 ? _f : 'register item'} #${item.id}`;
382
- return (0, _react2.jsx)(_util2.TabContentsWithActions, {
383
- actions: (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(FormGroup, {
384
- inline: true,
385
- labelInfo: (0, _react2.jsx)(_HelpTooltip.default, {
386
- icon: 'info-sign',
387
- content: (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)(_core.H5, null, itemClass.meta.title), (_g = itemClass.meta.description) !== null && _g !== void 0 ? _g : "No description is provided for this register item class.", (0, _react2.jsx)(_core.UL, null, (0, _react2.jsx)("li", null, "Class ID: ", itemClass.meta.id), (0, _react2.jsx)("li", null, "Subregister ID: ", (_h = itemRef.subregisterID) !== null && _h !== void 0 ? _h : 'N/A'), (0, _react2.jsx)("li", null, "UUID: ", itemRef.itemID)))
388
- }),
389
- label: (0, _react2.jsx)(_react.default.Fragment, null, (0, _react2.jsx)("strong", null, itemClass.meta.title), itemRef.subregisterID ? (0, _react2.jsx)("span", {
390
- title: "Subregister"
391
- }, " in ", (_k = (_j = subregisters === null || subregisters === void 0 ? void 0 : subregisters[itemRef.subregisterID]) === null || _j === void 0 ? void 0 : _j.title) !== null && _k !== void 0 ? _k : itemRef.subregisterID) : null),
392
- css: (0, _react2.css)`margin: 0; .bp4-form-content { display: flex; flex-flow: row wrap; gap: 10px; }`
393
- }, itemStatus, supersedingItems, clarificationAction, proposeLikeThis)),
394
- main: (0, _react2.jsx)(_core.Card, {
395
- css: (0, _react2.css)`position: absolute; inset: ${inProposalWithID ? '0' : '10px'}; overflow-y: auto;`
396
- }, (0, _react2.jsx)(_util2.RegisterHelmet, null, (0, _react2.jsx)("title", null, windowTitle)), details)
397
- });
492
+ return (0, _react2.jsx)(_util2.TabContentsWithHeader, {
493
+ smallTitle: compactHeader,
494
+ title: (0, _react2.jsx)(ListItemView, {
495
+ itemRef: itemRef,
496
+ itemData: item.data
497
+ }),
498
+ classification: classification,
499
+ actions: actions
500
+ }, (0, _react2.jsx)(_core.Card, {
501
+ css: (0, _react2.css)`position: absolute; border-radius: 0; inset: ${compactHeader ? '0' : '10px'}; overflow-y: auto;`
502
+ }, (0, _react2.jsx)(_util2.RegisterHelmet, null, (0, _react2.jsx)("title", null, windowTitle)), details));
398
503
  });
399
504
  exports.ItemDetail = ItemDetail;
400
505
 
@@ -427,10 +532,4 @@ var _default = {
427
532
  main: MaybeItemDetail,
428
533
  title: ItemTitle
429
534
  };
430
- exports.default = _default;
431
- const FormGroup = (0, _styled.default)(_core.FormGroup)`
432
- margin: 0;
433
- label.bp4-label {
434
- white-space: nowrap;
435
- }
436
- `;
535
+ exports.default = _default;