@riboseinc/paneron-registry-kit 2.2.6 → 2.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,6 +1,24 @@
1
+ import React from 'react';
1
2
  import type { Extension } from '@riboseinc/paneron-extension-kit/types';
2
3
  import type { ExtensionMakerProps } from '@riboseinc/paneron-extension-kit/types/extension-maker';
3
4
  import type { RegistryViewProps } from './types';
4
5
  export declare type RegistryExtensionMakerProps = Pick<ExtensionMakerProps, 'name'> & RegistryViewProps;
5
6
  export declare type RegistryExtensionMaker = (opts: RegistryExtensionMakerProps) => Promise<Extension>;
6
7
  export declare const makeRegistryExtension: RegistryExtensionMaker;
8
+ import { BrowserCtx } from './views/BrowserCtx';
9
+ import { itemRefToItemPath, incompleteItemRefToItemPathPrefix } from './views/itemPathUtils';
10
+ declare const _default: {
11
+ makeRegistryExtension: RegistryExtensionMaker;
12
+ itemRefToItemPath: typeof itemRefToItemPath;
13
+ incompleteItemRefToItemPathPrefix: typeof incompleteItemRefToItemPathPrefix;
14
+ BrowserCtx: React.Context<BrowserCtx>;
15
+ CRITERIA_CONFIGURATION: import("./views/FilterCriteria/models").CriteriaConfiguration;
16
+ GenericRelatedItemView: React.FC<import("./types").GenericRelatedItemViewProps>;
17
+ PropertyDetailView: React.FC<{
18
+ title: React.ReactNode;
19
+ secondaryTitle?: React.ReactNode;
20
+ inline?: boolean | undefined;
21
+ className?: string | undefined;
22
+ }>;
23
+ };
24
+ export default _default;
package/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.makeRegistryExtension = void 0;
6
+ exports.default = exports.makeRegistryExtension = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
@@ -13,6 +13,16 @@ var _initial = _interopRequireDefault(require("./migrations/initial"));
13
13
 
14
14
  var _views = require("./views");
15
15
 
16
+ var _BrowserCtx = require("./views/BrowserCtx");
17
+
18
+ var _itemPathUtils = require("./views/itemPathUtils");
19
+
20
+ var _GenericRelatedItemView = _interopRequireDefault(require("./views/GenericRelatedItemView"));
21
+
22
+ var _util = require("./views/util");
23
+
24
+ var _CRITERIA_CONFIGURATION = _interopRequireDefault(require("./views/FilterCriteria/CRITERIA_CONFIGURATION"));
25
+
16
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
27
 
18
28
  const makeRegistryExtension = function (opts) {
@@ -20,7 +30,7 @@ const makeRegistryExtension = function (opts) {
20
30
  name
21
31
  } = opts;
22
32
 
23
- const mainView = function () {
33
+ const mainView = function _RegistryView() {
24
34
  return _react.default.createElement(_views.RegistryView, {
25
35
  itemClassConfiguration: opts.itemClassConfiguration,
26
36
  subregisters: opts.subregisters
@@ -36,4 +46,14 @@ const makeRegistryExtension = function (opts) {
36
46
  });
37
47
  };
38
48
 
39
- exports.makeRegistryExtension = makeRegistryExtension;
49
+ exports.makeRegistryExtension = makeRegistryExtension;
50
+ var _default = {
51
+ makeRegistryExtension,
52
+ itemRefToItemPath: _itemPathUtils.itemRefToItemPath,
53
+ incompleteItemRefToItemPathPrefix: _itemPathUtils.incompleteItemRefToItemPathPrefix,
54
+ BrowserCtx: _BrowserCtx.BrowserCtx,
55
+ CRITERIA_CONFIGURATION: _CRITERIA_CONFIGURATION.default,
56
+ GenericRelatedItemView: _GenericRelatedItemView.default,
57
+ PropertyDetailView: _util.PropertyDetailView
58
+ };
59
+ exports.default = _default;
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAIjE,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,CAAC,MAAM,qBAAqB,GAA2B,UAAU,IAAI;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,MAAM,QAAQ,GAAoC;QAChD,OAAO,CACL,oBAAC,YAAY,IACX,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,EACnD,YAAY,EAAE,IAAI,CAAC,YAAY,GAC/B,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,aAAa,CAAC;QACnB,QAAQ;QACR,IAAI;QACJ,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,EAAE;QACrB,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { makeExtension } from '@riboseinc/paneron-extension-kit';\nimport type { Extension } from '@riboseinc/paneron-extension-kit/types';\nimport type { ExtensionMakerProps } from '@riboseinc/paneron-extension-kit/types/extension-maker';\nimport type { RegistryViewProps } from './types';\nimport datasetInitializer from './migrations/initial';\nimport { RegistryView } from './views';\n\nexport type RegistryExtensionMakerProps =\n Pick<ExtensionMakerProps, 'name'> & RegistryViewProps\n\nexport type RegistryExtensionMaker =\n (opts: RegistryExtensionMakerProps) => Promise<Extension>;\n\nexport const makeRegistryExtension: RegistryExtensionMaker = function (opts) {\n const { name } = opts;\n\n const mainView: ExtensionMakerProps[\"mainView\"] = function () {\n return (\n <RegistryView\n itemClassConfiguration={opts.itemClassConfiguration}\n subregisters={opts.subregisters}\n />\n );\n };\n\n return makeExtension({\n mainView,\n name,\n requiredHostAppVersion: '2.0.0',\n datasetMigrations: {},\n datasetInitializer,\n });\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAIjE,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,CAAC,MAAM,qBAAqB,GAA2B,UAAU,IAAI;IACzE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,MAAM,QAAQ,GAAoC,SAAS,aAAa;QACtE,OAAO,CACL,oBAAC,YAAY,IACX,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,EACnD,YAAY,EAAE,IAAI,CAAC,YAAY,GAC/B,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,aAAa,CAAC;QACnB,QAAQ;QACR,IAAI;QACJ,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,EAAE;QACrB,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC,CAAC;AAGF,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,sBAAsB,MAAM,+CAA+C,CAAC;AAEnF,eAAe;IACb,qBAAqB;IACrB,iBAAiB;IACjB,iCAAiC;IACjC,UAAU;IACV,sBAAsB;IACtB,sBAAsB;IACtB,kBAAkB;CACnB,CAAC","sourcesContent":["import React from 'react';\nimport { makeExtension } from '@riboseinc/paneron-extension-kit';\nimport type { Extension } from '@riboseinc/paneron-extension-kit/types';\nimport type { ExtensionMakerProps } from '@riboseinc/paneron-extension-kit/types/extension-maker';\nimport type { RegistryViewProps } from './types';\nimport datasetInitializer from './migrations/initial';\nimport { RegistryView } from './views';\n\nexport type RegistryExtensionMakerProps =\n Pick<ExtensionMakerProps, 'name'> & RegistryViewProps\n\nexport type RegistryExtensionMaker =\n (opts: RegistryExtensionMakerProps) => Promise<Extension>;\n\nexport const makeRegistryExtension: RegistryExtensionMaker = function (opts) {\n const { name } = opts;\n\n const mainView: ExtensionMakerProps[\"mainView\"] = function _RegistryView () {\n return (\n <RegistryView\n itemClassConfiguration={opts.itemClassConfiguration}\n subregisters={opts.subregisters}\n />\n );\n };\n\n return makeExtension({\n mainView,\n name,\n requiredHostAppVersion: '2.0.0',\n datasetMigrations: {},\n datasetInitializer,\n });\n};\n\n\nimport { BrowserCtx } from './views/BrowserCtx';\nimport { itemRefToItemPath, incompleteItemRefToItemPathPrefix } from './views/itemPathUtils';\nimport GenericRelatedItemView from './views/GenericRelatedItemView';\nimport { PropertyDetailView } from './views/util';\nimport CRITERIA_CONFIGURATION from './views/FilterCriteria/CRITERIA_CONFIGURATION';\n\nexport default {\n makeRegistryExtension,\n itemRefToItemPath,\n incompleteItemRefToItemPathPrefix,\n BrowserCtx,\n CRITERIA_CONFIGURATION,\n GenericRelatedItemView,\n PropertyDetailView,\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riboseinc/paneron-registry-kit",
3
- "version": "2.2.6",
3
+ "version": "2.2.7",
4
4
  "main": "index.js",
5
5
  "author": "Ribose Inc. <open.source@ribose.com>",
6
6
  "scripts": {
@@ -28,7 +28,7 @@
28
28
  "@blueprintjs/select": "~4.9.10",
29
29
  "@emotion/react": "^11.10.6",
30
30
  "@emotion/styled": "^11.10.6",
31
- "@riboseinc/paneron-extension-kit": "2.2.4",
31
+ "@riboseinc/paneron-extension-kit": "2.2.5",
32
32
  "@types/react": "17.0.53",
33
33
  "@types/react-dom": "^17.0.2",
34
34
  "@types/react-helmet": "^6.1.2",
package/types/item.d.ts CHANGED
@@ -10,7 +10,7 @@ export interface RegisterItemClass {
10
10
  id: string;
11
11
  title: string;
12
12
  description?: string;
13
- alternativeNames?: LocalizedAlternative<string>[];
13
+ alternativeNames?: Readonly<LocalizedAlternative<string>[]>;
14
14
  }
15
15
  interface ItemReference {
16
16
  registerID: string;
package/types/item.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"item.js","sourceRoot":"","sources":["../../src/types/item.ts"],"names":[],"mappings":"AAKA,MAAM,aAAa,GAAG;IACpB,WAAW;IACX,OAAO;IACP,YAAY;IACZ,SAAS;IACT,SAAS;CACD,CAAC;AA2BX,MAAM,UAAU,uBAAuB,CAAC,GAAQ;IAC9C,OAAO,CACL,GAAG;QACH,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC5B,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC;QAC7B,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ;QAChC,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAA0B;IAC9C,MAAM,EAAE,qBAAqB;IAC7B,OAAO,EAAE,sBAAsB;IAC/B,aAAa,EAAE,SAAS;CAChB,CAAC;AA0CX,MAAM,UAAU,cAAc,CAAC,GAAQ;IACrC,OAAO,CACL,GAAG;QACH,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC;QACxB,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC;QAC1B,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC5B,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CACvC,CAAC;AACJ,CAAC","sourcesContent":["import type { Citation, LocalizedAlternative } from './util';\n\n\nexport type Payload = Record<string, any>\n\nconst ITEM_STATUSES = [\n 'submitted',\n 'valid',\n 'superseded',\n 'retired',\n 'invalid',\n] as const;\n\nexport type ItemStatus = typeof ITEM_STATUSES[number];\n\n\nexport interface RegisterItemID {\n classID: string\n itemID: string\n}\n\n\nexport interface RegisterItemClass {\n id: string\n title: string\n description?: string\n alternativeNames?: LocalizedAlternative<string>[]\n}\n\ninterface ItemReference {\n registerID: string\n subregisterID?: string\n classID: string\n itemID: string\n}\n\nexport type InternalItemReference = Omit<ItemReference, 'registerID'>\n\nexport function isInternalItemReference(val: any): val is InternalItemReference {\n return (\n val &&\n val.hasOwnProperty('itemID') &&\n val.hasOwnProperty('classID') &&\n typeof val['itemID'] == 'string' &&\n typeof val['classID'] == 'string'\n );\n}\n\nexport const DUMMY_REF: InternalItemReference = {\n itemID: 'NONEXISTENT_ITEM_ID',\n classID: 'NONEXISTENT_CLASS_ID',\n subregisterID: undefined,\n} as const;\n\n\ninterface AbstractItemSource {\n type: string\n}\ninterface PaneronRegisterItemSource extends AbstractItemSource {\n type: 'paneron_register'\n itemRef: ItemReference\n}\ninterface ExternalSource extends AbstractItemSource {\n type: 'external'\n citation: Citation\n}\ntype RegisterItemSource = PaneronRegisterItemSource | ExternalSource\n\nexport interface RegisterItem<P extends Payload> {\n id: string // UUID\n\n status: ItemStatus\n\n dateAccepted: Date\n // This is a mandatory property, since until their acceptance items “live” as part of their corresponding change requests\n\n /** UUID of change request that defined the current version. */\n amendedInCR?: string\n\n // TODO: Denormalized, should be validated with consistency checks\n supersededBy?: InternalItemReference[]\n supersedes?: InternalItemReference[]\n\n /**\n * Register item data. Domain-specific. May include additional human-readable identifiers.\n * In ISO 19135-1 was represented by “definition”.\n */\n data: P\n\n source?: RegisterItemSource\n // TODO: Citations were suggested to be moved to proposals, as motivating/substantiating evidence.\n // TODO: Register item, however, should have a relationship that points to the original proto-item from another register.\n}\n\nexport function isRegisterItem(val: any): val is RegisterItem<any> {\n return (\n val &&\n val.hasOwnProperty('id') &&\n val.hasOwnProperty('data') &&\n val.hasOwnProperty('status') &&\n ITEM_STATUSES.indexOf(val.status) >= 0\n );\n}\n"]}
1
+ {"version":3,"file":"item.js","sourceRoot":"","sources":["../../src/types/item.ts"],"names":[],"mappings":"AAKA,MAAM,aAAa,GAAG;IACpB,WAAW;IACX,OAAO;IACP,YAAY;IACZ,SAAS;IACT,SAAS;CACD,CAAC;AA2BX,MAAM,UAAU,uBAAuB,CAAC,GAAQ;IAC9C,OAAO,CACL,GAAG;QACH,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC5B,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC;QAC7B,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ;QAChC,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAA0B;IAC9C,MAAM,EAAE,qBAAqB;IAC7B,OAAO,EAAE,sBAAsB;IAC/B,aAAa,EAAE,SAAS;CAChB,CAAC;AA0CX,MAAM,UAAU,cAAc,CAAC,GAAQ;IACrC,OAAO,CACL,GAAG;QACH,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC;QACxB,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC;QAC1B,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC;QAC5B,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CACvC,CAAC;AACJ,CAAC","sourcesContent":["import type { Citation, LocalizedAlternative } from './util';\n\n\nexport type Payload = Record<string, any>\n\nconst ITEM_STATUSES = [\n 'submitted',\n 'valid',\n 'superseded',\n 'retired',\n 'invalid',\n] as const;\n\nexport type ItemStatus = typeof ITEM_STATUSES[number];\n\n\nexport interface RegisterItemID {\n classID: string\n itemID: string\n}\n\n\nexport interface RegisterItemClass {\n id: string\n title: string\n description?: string\n alternativeNames?: Readonly<LocalizedAlternative<string>[]>\n}\n\ninterface ItemReference {\n registerID: string\n subregisterID?: string\n classID: string\n itemID: string\n}\n\nexport type InternalItemReference = Omit<ItemReference, 'registerID'>\n\nexport function isInternalItemReference(val: any): val is InternalItemReference {\n return (\n val &&\n val.hasOwnProperty('itemID') &&\n val.hasOwnProperty('classID') &&\n typeof val['itemID'] == 'string' &&\n typeof val['classID'] == 'string'\n );\n}\n\nexport const DUMMY_REF: InternalItemReference = {\n itemID: 'NONEXISTENT_ITEM_ID',\n classID: 'NONEXISTENT_CLASS_ID',\n subregisterID: undefined,\n} as const;\n\n\ninterface AbstractItemSource {\n type: string\n}\ninterface PaneronRegisterItemSource extends AbstractItemSource {\n type: 'paneron_register'\n itemRef: ItemReference\n}\ninterface ExternalSource extends AbstractItemSource {\n type: 'external'\n citation: Citation\n}\ntype RegisterItemSource = PaneronRegisterItemSource | ExternalSource\n\nexport interface RegisterItem<P extends Payload> {\n id: string // UUID\n\n status: ItemStatus\n\n dateAccepted: Date\n // This is a mandatory property, since until their acceptance items “live” as part of their corresponding change requests\n\n /** UUID of change request that defined the current version. */\n amendedInCR?: string\n\n // TODO: Denormalized, should be validated with consistency checks\n supersededBy?: InternalItemReference[]\n supersedes?: InternalItemReference[]\n\n /**\n * Register item data. Domain-specific. May include additional human-readable identifiers.\n * In ISO 19135-1 was represented by “definition”.\n */\n data: P\n\n source?: RegisterItemSource\n // TODO: Citations were suggested to be moved to proposals, as motivating/substantiating evidence.\n // TODO: Register item, however, should have a relationship that points to the original proto-item from another register.\n}\n\nexport function isRegisterItem(val: any): val is RegisterItem<any> {\n return (\n val &&\n val.hasOwnProperty('id') &&\n val.hasOwnProperty('data') &&\n val.hasOwnProperty('status') &&\n ITEM_STATUSES.indexOf(val.status) >= 0\n );\n}\n"]}
package/types/views.d.ts CHANGED
@@ -75,7 +75,7 @@ export interface ItemClassConfiguration<P extends Payload> {
75
75
  * Passed to useFilteredIndex().
76
76
  */
77
77
  keyExpression?: string;
78
- exportFormats?: ExportFormatConfiguration<P>[];
78
+ exportFormats?: Readonly<ExportFormatConfiguration<P>[]>;
79
79
  views: {
80
80
  listItemView: ItemListView<P>;
81
81
  editView: ItemEditView<P>;
@@ -1 +1 @@
1
- {"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/types/views.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\nimport type { ButtonProps, MenuItemProps } from '@blueprintjs/core';\nimport type { ObjectDatasetRequest, ObjectDatasetResponse, ValueHook } from '@riboseinc/paneron-extension-kit/types';\nimport type { InternalItemReference, Payload, RegisterItem, RegisterItemClass } from './item';\nimport type { CriteriaGroup } from '../views/FilterCriteria/models';\n\n\n// Hooks\n\n/**\n * Mostly a wrapper around useObjectData, but coerces value type\n * (TODO: validate!) and takes into account change request from any\n * wrapping change request context. If a change request is present,\n * will substitute proposed item data unless `ignoreActiveCR` is set.\n *\n * NOTE: Despite the name, returns the entire RegisterItem,\n * not just the `.data` property with item payload.\n */\nexport type RegisterItemDataHook<P extends Payload = Payload> =\n (opts: { itemPaths: string[], ignoreActiveCR?: true }) => ValueHook<Record<string, RegisterItem<P> | null>>;\n\n\n// Extension configuration\n\n// TODO: Obsolete?\n// export interface ExtensionContext {\n// getRelatedItemClassConfiguration: (classID: string) => RelatedItemClassConfiguration\n// useRegisterItemData: RegisterItemDataHook\n// onJump?: () => void\n// }\n\nexport interface RegisterConfiguration\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>> {\n /**\n * Configuration for all items in this register.\n * This includes items in subregisters.\n */\n itemClassConfiguration: Items\n\n /**\n * Default expression used to sort an item.\n * Passed to useFilteredIndex().\n */\n keyExpression?: string\n\n /** Subregister information. */\n subregisters?: Subregisters<Items>\n}\n\nexport type Subregisters\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>> = {\n [subregisterID: string]: {\n title: string\n\n /** Names of item classes that go in this subregister. */\n itemClasses: (keyof Items)[]\n }\n};\n\nexport type ItemClassConfigurationSet = {\n [itemClassID: string]: ItemClassConfiguration<any>\n};\n\n\n\nexport interface ExportFormatConfiguration<P extends Payload> {\n /** The name of the export format. */\n label: string\n\n /**\n * Trailing part of the filename to save export as;\n * must include at least extension (with separator),\n * must not include any path prefix.\n */\n filenameExtension: string\n\n /**\n * The function that takes register item data and some helper functions\n * and is expected to return a blob.\n */\n exportItem: (\n itemData: RegisterItem<P>,\n opts: {\n getObjectData: (opts: ObjectDatasetRequest) => Promise<ObjectDatasetResponse>,\n getBlob: (val: string) => Promise<Uint8Array>,\n logger?: { log: Console[\"log\"], error: Console[\"error\"], debug: Console[\"debug\"] },\n },\n ) => Promise<Uint8Array>\n}\n\n\nexport interface ItemClassConfiguration<P extends Payload/*, F extends Field*/> {\n meta: RegisterItemClass\n\n itemCanBeSuperseded?: boolean\n // If false, items of this class cannot be superseded, only retired.\n // Default is true.\n\n defaults?: RegistryItemPayloadDefaults<P>\n // Used to pre-populate item data e.g. when a new item is created.\n\n validatePayload?: (item: P) => Promise<boolean>\n sanitizePayload?: (item: P) => Promise<P>\n\n // XXX: Confirm if obsolete and remove\n itemSorter?: (a: P, b: P) => number\n\n /**\n * Expression used to sort an item of this class.\n * Passed to useFilteredIndex().\n */\n keyExpression?: string\n\n exportFormats?: ExportFormatConfiguration<P>[]\n\n views: {\n listItemView: ItemListView<P>\n editView: ItemEditView<P>\n detailView?: ItemDetailView<P>\n }\n}\n\n\nexport interface RegistryViewProps\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>>\nextends RegisterConfiguration<Items> {\n /**\n * When search is initially opened, have this query pre-defined.\n * Not very useful since there are also preset searches in the browser now.\n */\n // TODO: Obsoluete?\n defaultSearchCriteria?: CriteriaGroup\n\n customViews?: CustomViewConfiguration[]\n}\n\nexport interface CustomViewConfiguration {\n id: string\n label: string\n description: string\n view: React.FC<{\n /** View can support optional path for custom state/inner navigation (provisional). */\n path: string\n }>\n icon?: JSX.Element\n}\n\n\n// Item views\n\nexport interface ItemAction {\n getButtonProps:\n (item: RegisterItem<any>, itemClass: ItemClassConfiguration<any>, subregisterID?: string) =>\n ButtonProps | MenuItemProps\n}\n\nexport type RegistryView = React.FC<RegistryViewProps>\n\ntype RegistryItemPayloadDefaults<P extends Payload> =\n Partial<Omit<P, 'id'>>;\n\n/**\n * A small part of item class configuration,\n * useful e.g. for formatting related items.\n */\nexport type RelatedItemClassConfiguration = {\n title: string\n itemView: ItemListView<any>\n}\n\n\nexport interface RegistryItemViewProps<P extends Payload> {\n /**\n * Item reference.\n * Glossarist, for example, uses it to determine language subregister and set appropriate writing direction.\n */\n itemRef: Omit<InternalItemReference, 'itemID'> & { itemID?: InternalItemReference['itemID'] }\n\n /** Item data (payload). */\n itemData: P\n\n className?: string\n //subregisterID?: string\n\n /** Deprecated */\n useRegisterItemData?: any\n /** Deprecated */\n getRelatedItemClassConfiguration?: any\n}\n\nexport interface GenericRelatedItemViewProps {\n /** Currently selected item’s ref. */\n itemRef?: InternalItemReference\n\n /**\n * By default, clicking the item will spawn a tab via TabbedWorkspace context.\n * This prop can customize that behavior.\n */\n onJump?: () => void\n\n className?: string\n\n /**\n * Determines which item classes can be selected in the search dialog.\n * If undefined, *any* class can be chosen.\n * If empty list, no class can be chosen (weird).\n */\n availableClassIDs?: string[]\n\n // XXX: Check if obsolete, remove if unused\n itemSorter?: ItemClassConfiguration<any>[\"itemSorter\"]\n\n /** Called to auto-create an item (can’t auto-create if not provided) */\n onCreateNew?: () => Promise<InternalItemReference>\n\n /** Called when current item is cleared (can’t clear if not provided) */\n onClear?: () => void\n\n /** Called when a new item is selected (can’t change if not provided) */\n onChange?: (newRef: InternalItemReference) => void\n\n /** @deprecated subregisters no longer supported. */\n availableSubregisterIDs?: string[]\n\n /** @deprecated */\n useRegisterItemData?: any\n //useRegisterItemData: RegisterItemDataHook\n\n /** @deprecated */\n getRelatedItemClassConfiguration?: any\n //getRelatedItemClassConfiguration: ExtensionContext[\"getRelatedItemClassConfiguration\"]\n}\n\n\nexport type ItemEditView<P extends Payload> = React.FC<ItemEditViewProps<P>>;\n\nexport interface ItemEditViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n onChange?: (newData: P) => void\n onCreateRelatedItem?:\n (classID: string, subregisterID?: string) => Promise<InternalItemReference>\n}\n\nexport interface ItemDetailViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n //useRegisterItemData: RegisterItemDataHook\n}\n\nexport type ItemDetailView<P extends Payload> = React.FC<ItemDetailViewProps<P>>;\n\nexport interface ItemListViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n}\n\nexport type ItemListView<P extends Payload> = React.FC<ItemListViewProps<P>>;\n\nexport type LazyItemView = React.FC<{ itemID: string }>;\n"]}
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/types/views.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\nimport type { ButtonProps, MenuItemProps } from '@blueprintjs/core';\nimport type { ObjectDatasetRequest, ObjectDatasetResponse, ValueHook } from '@riboseinc/paneron-extension-kit/types';\nimport type { InternalItemReference, Payload, RegisterItem, RegisterItemClass } from './item';\nimport type { CriteriaGroup } from '../views/FilterCriteria/models';\n\n\n// Hooks\n\n/**\n * Mostly a wrapper around useObjectData, but coerces value type\n * (TODO: validate!) and takes into account change request from any\n * wrapping change request context. If a change request is present,\n * will substitute proposed item data unless `ignoreActiveCR` is set.\n *\n * NOTE: Despite the name, returns the entire RegisterItem,\n * not just the `.data` property with item payload.\n */\nexport type RegisterItemDataHook<P extends Payload = Payload> =\n (opts: { itemPaths: string[], ignoreActiveCR?: true }) => ValueHook<Record<string, RegisterItem<P> | null>>;\n\n\n// Extension configuration\n\n// TODO: Obsolete?\n// export interface ExtensionContext {\n// getRelatedItemClassConfiguration: (classID: string) => RelatedItemClassConfiguration\n// useRegisterItemData: RegisterItemDataHook\n// onJump?: () => void\n// }\n\nexport interface RegisterConfiguration\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>> {\n /**\n * Configuration for all items in this register.\n * This includes items in subregisters.\n */\n itemClassConfiguration: Items\n\n /**\n * Default expression used to sort an item.\n * Passed to useFilteredIndex().\n */\n keyExpression?: string\n\n /** Subregister information. */\n subregisters?: Subregisters<Items>\n}\n\nexport type Subregisters\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>> = {\n [subregisterID: string]: {\n title: string\n\n /** Names of item classes that go in this subregister. */\n itemClasses: (keyof Items)[]\n }\n};\n\nexport type ItemClassConfigurationSet = {\n [itemClassID: string]: ItemClassConfiguration<any>\n};\n\n\n\nexport interface ExportFormatConfiguration<P extends Payload> {\n /** The name of the export format. */\n label: string\n\n /**\n * Trailing part of the filename to save export as;\n * must include at least extension (with separator),\n * must not include any path prefix.\n */\n filenameExtension: string\n\n /**\n * The function that takes register item data and some helper functions\n * and is expected to return a blob.\n */\n exportItem: (\n itemData: RegisterItem<P>,\n opts: {\n getObjectData: (opts: ObjectDatasetRequest) => Promise<ObjectDatasetResponse>,\n getBlob: (val: string) => Promise<Uint8Array>,\n logger?: { log: Console[\"log\"], error: Console[\"error\"], debug: Console[\"debug\"] },\n },\n ) => Promise<Uint8Array>\n}\n\n\nexport interface ItemClassConfiguration<P extends Payload/*, F extends Field*/> {\n meta: RegisterItemClass\n\n itemCanBeSuperseded?: boolean\n // If false, items of this class cannot be superseded, only retired.\n // Default is true.\n\n defaults?: RegistryItemPayloadDefaults<P>\n // Used to pre-populate item data e.g. when a new item is created.\n\n validatePayload?: (item: P) => Promise<boolean>\n sanitizePayload?: (item: P) => Promise<P>\n\n // XXX: Confirm if obsolete and remove\n itemSorter?: (a: P, b: P) => number\n\n /**\n * Expression used to sort an item of this class.\n * Passed to useFilteredIndex().\n */\n keyExpression?: string\n\n exportFormats?: Readonly<ExportFormatConfiguration<P>[]>\n\n views: {\n listItemView: ItemListView<P>\n editView: ItemEditView<P>\n detailView?: ItemDetailView<P>\n }\n}\n\n\nexport interface RegistryViewProps\n<Items extends ItemClassConfigurationSet = Record<string, ItemClassConfiguration<any>>>\nextends RegisterConfiguration<Items> {\n /**\n * When search is initially opened, have this query pre-defined.\n * Not very useful since there are also preset searches in the browser now.\n */\n // TODO: Obsoluete?\n defaultSearchCriteria?: CriteriaGroup\n\n customViews?: CustomViewConfiguration[]\n}\n\nexport interface CustomViewConfiguration {\n id: string\n label: string\n description: string\n view: React.FC<{\n /** View can support optional path for custom state/inner navigation (provisional). */\n path: string\n }>\n icon?: JSX.Element\n}\n\n\n// Item views\n\nexport interface ItemAction {\n getButtonProps:\n (item: RegisterItem<any>, itemClass: ItemClassConfiguration<any>, subregisterID?: string) =>\n ButtonProps | MenuItemProps\n}\n\nexport type RegistryView = React.FC<RegistryViewProps>\n\ntype RegistryItemPayloadDefaults<P extends Payload> =\n Partial<Omit<P, 'id'>>;\n\n/**\n * A small part of item class configuration,\n * useful e.g. for formatting related items.\n */\nexport type RelatedItemClassConfiguration = {\n title: string\n itemView: ItemListView<any>\n}\n\n\nexport interface RegistryItemViewProps<P extends Payload> {\n /**\n * Item reference.\n * Glossarist, for example, uses it to determine language subregister and set appropriate writing direction.\n */\n itemRef: Omit<InternalItemReference, 'itemID'> & { itemID?: InternalItemReference['itemID'] }\n\n /** Item data (payload). */\n itemData: P\n\n className?: string\n //subregisterID?: string\n\n /** Deprecated */\n useRegisterItemData?: any\n /** Deprecated */\n getRelatedItemClassConfiguration?: any\n}\n\nexport interface GenericRelatedItemViewProps {\n /** Currently selected item’s ref. */\n itemRef?: InternalItemReference\n\n /**\n * By default, clicking the item will spawn a tab via TabbedWorkspace context.\n * This prop can customize that behavior.\n */\n onJump?: () => void\n\n className?: string\n\n /**\n * Determines which item classes can be selected in the search dialog.\n * If undefined, *any* class can be chosen.\n * If empty list, no class can be chosen (weird).\n */\n availableClassIDs?: string[]\n\n // XXX: Check if obsolete, remove if unused\n itemSorter?: ItemClassConfiguration<any>[\"itemSorter\"]\n\n /** Called to auto-create an item (can’t auto-create if not provided) */\n onCreateNew?: () => Promise<InternalItemReference>\n\n /** Called when current item is cleared (can’t clear if not provided) */\n onClear?: () => void\n\n /** Called when a new item is selected (can’t change if not provided) */\n onChange?: (newRef: InternalItemReference) => void\n\n /** @deprecated subregisters no longer supported. */\n availableSubregisterIDs?: string[]\n\n /** @deprecated */\n useRegisterItemData?: any\n //useRegisterItemData: RegisterItemDataHook\n\n /** @deprecated */\n getRelatedItemClassConfiguration?: any\n //getRelatedItemClassConfiguration: ExtensionContext[\"getRelatedItemClassConfiguration\"]\n}\n\n\nexport type ItemEditView<P extends Payload> = React.FC<ItemEditViewProps<P>>;\n\nexport interface ItemEditViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n onChange?: (newData: P) => void\n onCreateRelatedItem?:\n (classID: string, subregisterID?: string) => Promise<InternalItemReference>\n}\n\nexport interface ItemDetailViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n //useRegisterItemData: RegisterItemDataHook\n}\n\nexport type ItemDetailView<P extends Payload> = React.FC<ItemDetailViewProps<P>>;\n\nexport interface ItemListViewProps<P extends Payload> extends RegistryItemViewProps<P> {\n}\n\nexport type ItemListView<P extends Payload> = React.FC<ItemListViewProps<P>>;\n\nexport type LazyItemView = React.FC<{ itemID: string }>;\n"]}
@@ -1,7 +1,7 @@
1
1
  /** @jsx jsx */
2
2
  /** @jsxFrag React.Fragment */
3
3
  import React from 'react';
4
- import type { ChangeProposal, Clarification, InternalItemReference, Payload } from '../../types';
4
+ import type { ChangeProposal, Clarification, InternalItemReference, Payload, RegisterItem } from '../../types';
5
5
  import type { Drafted } from '../../types/cr';
6
6
  declare const Proposals: React.FC<{
7
7
  proposals: Drafted['items'];
@@ -12,8 +12,8 @@ interface ProposalProps<P extends ChangeProposal> {
12
12
  showDiff?: boolean;
13
13
  showOnlyChanged?: boolean;
14
14
  itemRef: InternalItemReference;
15
- itemData: Payload;
16
- itemDataBefore: P extends Clarification ? Payload : undefined;
15
+ item: RegisterItem<Payload>;
16
+ itemBefore: P extends Clarification ? RegisterItem<Payload> : undefined;
17
17
  onChange?: (newProposal: P) => void;
18
18
  }
19
19
  export declare const ProposalDetail: React.FC<ProposalProps<ChangeProposal>>;
@@ -17,15 +17,19 @@ var _select = require("@blueprintjs/select");
17
17
 
18
18
  var _HelpTooltip = _interopRequireDefault(require("@riboseinc/paneron-extension-kit/widgets/HelpTooltip"));
19
19
 
20
+ var _ErrorBoundary = _interopRequireDefault(require("@riboseinc/paneron-extension-kit/widgets/ErrorBoundary"));
21
+
20
22
  var _protocolRegistry = require("../protocolRegistry");
21
23
 
22
24
  var _BrowserCtx = require("../BrowserCtx");
23
25
 
24
26
  var _itemPathUtils = require("../itemPathUtils");
25
27
 
28
+ var _useItemClassConfig = _interopRequireDefault(require("../hooks/useItemClassConfig"));
29
+
26
30
  var _StructuredDiff = _interopRequireDefault(require("../diffing/StructuredDiff"));
27
31
 
28
- var _RegisterItem = _interopRequireDefault(require("../detail/RegisterItem"));
32
+ var _RegisterItem = require("../detail/RegisterItem");
29
33
 
30
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
35
 
@@ -36,6 +40,10 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
36
40
  /** @jsx jsx */
37
41
 
38
42
  /** @jsxFrag React.Fragment */
43
+ function stringifiedJSONEqual(i1, i2) {
44
+ return JSON.stringify(i1) === JSON.stringify(i2);
45
+ }
46
+
39
47
  const Proposals = function ({
40
48
  proposals,
41
49
  className
@@ -67,9 +75,9 @@ const Proposals = function ({
67
75
  }
68
76
  }
69
77
  }, [Object.keys(proposals), jumpTo]);
70
- const proposalBrowserCtx = { ...outerBrowserCtx,
78
+ const proposalBrowserCtx = (0, _react.useMemo)(() => ({ ...outerBrowserCtx,
71
79
  jumpTo: handleCRJump
72
- };
80
+ }), [handleCRJump, outerBrowserCtx]);
73
81
  const firstProposal = Object.keys(proposals)[0]; // Effective selected proposal
74
82
 
75
83
  const selectedProposal = (_b = (_a = _selectedProposal && proposals[_selectedProposal] ? _selectedProposal : null) !== null && _a !== void 0 ? _a : firstProposal) !== null && _b !== void 0 ? _b : undefined; // Force select available proposal
@@ -78,8 +86,8 @@ const Proposals = function ({
78
86
  if (firstProposal && (_selectedProposal === null || !proposals[_selectedProposal])) {
79
87
  selectProposal(firstProposal !== null && firstProposal !== void 0 ? firstProposal : null);
80
88
  }
81
- }, [firstProposal, _selectedProposal, JSON.stringify(proposals)]);
82
- const selectedItemRef = selectedProposal ? (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, selectedProposal) : null; // Data for proposed items
89
+ }, [firstProposal, _selectedProposal, proposals]);
90
+ const selectedItemRef = (0, _itemPathUtils.useItemRef)(subregisters !== undefined, selectedProposal); // Data for proposed items
83
91
 
84
92
  const proposedItemPaths = Object.entries(proposals).map(([itemPath, proposal]) => {
85
93
  if (proposal.type === 'clarification' || proposal.type === 'addition') {
@@ -96,116 +104,101 @@ const Proposals = function ({
96
104
  itemPaths: Object.keys(proposals),
97
105
  ignoreActiveCR: true
98
106
  });
99
-
100
- const getCurrentItemData = itemPath => {
107
+ const getCurrentItem = (0, _react.useCallback)(itemPath => {
108
+ var _a;
109
+
110
+ return (_a = currentItemDataReq.value[itemPath]) !== null && _a !== void 0 ? _a : null;
111
+ }, [currentItemDataReq.value]);
112
+ const getProposedItem = (0, _react.useCallback)(itemPath => {
113
+ var _a;
114
+
115
+ return (_a = proposedItemDataReq.value[itemPath]) !== null && _a !== void 0 ? _a : null;
116
+ }, [proposedItemDataReq.value]);
117
+ const selectedItemCurrent = getCurrentItem(selectedProposal);
118
+ const selectedItemProposed = getProposedItem(selectedProposal);
119
+ const handleItemSelect = (0, _react.useCallback)(item => selectProposal(item.itemPath), [selectProposal]);
120
+ const activeItem = (0, _react.useMemo)(() => selectedProposal ? {
121
+ itemPath: selectedProposal,
122
+ proposal: proposals[selectedProposal],
123
+ item: selectedItemProposed !== null && selectedItemProposed !== void 0 ? selectedItemProposed : selectedItemCurrent,
124
+ itemBefore: selectedItemCurrent !== null && selectedItemCurrent !== void 0 ? selectedItemCurrent : undefined,
125
+ itemRef: (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, selectedProposal)
126
+ } : null, [selectedProposal, proposals, subregisters]);
127
+ const allItems = (0, _react.useMemo)(() => Object.entries(proposals).map(([itemPath, proposal]) => {
101
128
  var _a, _b;
102
129
 
103
- return (_b = (_a = currentItemDataReq.value[itemPath]) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : null;
104
- };
105
-
106
- const getProposedItemData = itemPath => {
107
- var _a, _b;
108
-
109
- return (_b = (_a = proposedItemDataReq.value[itemPath]) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : null;
110
- };
111
-
112
- const selectedItemCurrentData = getCurrentItemData(selectedProposal);
113
- const selectedItemProposedData = getProposedItemData(selectedProposal);
130
+ return {
131
+ itemPath,
132
+ proposal,
133
+ item: (_b = (_a = getProposedItem(itemPath)) !== null && _a !== void 0 ? _a : getCurrentItem(itemPath)) !== null && _b !== void 0 ? _b : null,
134
+ itemBefore: undefined,
135
+ itemRef: (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, itemPath)
136
+ };
137
+ }).filter(cpi => cpi.item !== null), [proposals, getCurrentItem, getProposedItem]);
114
138
 
115
139
  if (selectedProposal && selectedItemRef && proposals[selectedProposal] && !currentItemDataReq.isUpdating && !proposedItemDataReq.isUpdating) {
116
- if (selectedItemCurrentData || selectedItemProposedData || true) {
117
- const selectedItemSummary = (0, _react2.jsx)(ProposalSummary, {
118
- itemRef: selectedItemRef,
119
- itemData: selectedItemProposedData !== null && selectedItemProposedData !== void 0 ? selectedItemProposedData : selectedItemCurrentData,
120
- itemDataBefore: selectedItemCurrentData !== null && selectedItemCurrentData !== void 0 ? selectedItemCurrentData : undefined,
121
- proposal: proposals[selectedProposal]
122
- });
123
- return (0, _react2.jsx)("div", {
124
- css: (0, _react2.css)`display: flex; flex-flow: column nowrap;`,
125
- className: className
126
- }, (0, _react2.jsx)("div", null, (0, _react2.jsx)(_core.ControlGroup, null, (0, _react2.jsx)(_core.Switch, {
127
- checked: showDiff,
128
- onChange: evt => setShowDiff(evt.currentTarget.checked),
129
- label: "View source",
130
- css: (0, _react2.css)`margin-right: 1em !important`
131
- }), (0, _react2.jsx)(_core.Switch, {
132
- checked: showDiff && showOnlyChanged,
133
- disabled: !showDiff,
134
- onChange: evt => setShowOnlyChanged(evt.currentTarget.checked),
135
- label: "Show clarified properties only"
136
- })), (0, _react2.jsx)(_core.ButtonGroup, null, (0, _react2.jsx)(_core.Button, {
137
- disabled: !jumpTo || ((_c = proposals[selectedProposal]) === null || _c === void 0 ? void 0 : _c.type) === 'addition',
138
- icon: 'locate',
139
- onClick: () => jumpTo === null || jumpTo === void 0 ? void 0 : jumpTo(`${_protocolRegistry.Protocols.ITEM_DETAILS}:${selectedProposal}`),
140
- title: "Open selected item in a new tab (not applicable to proposed additions)"
141
- }, "Reveal in registry"), Object.keys(proposals).length > 1 ? (0, _react2.jsx)(_react2.ClassNames, null, ({
142
- css: css2
143
- }) => (0, _react2.jsx)(_select.Select2, {
144
- filterable: false,
145
- itemsEqual: (i1, i2) => JSON.stringify(i1) === JSON.stringify(i2),
146
- menuProps: {
147
- className: css2(`height: 50vh; overflow-y: auto;`)
148
- },
149
- activeItem: {
150
- itemPath: selectedProposal,
151
- proposal: proposals[selectedProposal],
152
- itemData: selectedItemProposedData !== null && selectedItemProposedData !== void 0 ? selectedItemProposedData : selectedItemCurrentData,
153
- itemDataBefore: selectedItemCurrentData !== null && selectedItemCurrentData !== void 0 ? selectedItemCurrentData : undefined,
154
- itemRef: (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, selectedProposal)
155
- },
156
- items: Object.entries(proposals).map(([itemPath, proposal]) => {
157
- var _a, _b;
158
-
159
- return {
160
- itemPath,
161
- proposal,
162
- itemData: (_b = (_a = getProposedItemData(itemPath)) !== null && _a !== void 0 ? _a : getCurrentItemData(itemPath)) !== null && _b !== void 0 ? _b : null,
163
- itemDataBefore: undefined,
164
- itemRef: (0, _itemPathUtils.itemPathToItemRef)(subregisters !== undefined, itemPath)
165
- };
166
- }).filter(item => item.itemData !== null),
167
- popoverProps: {
168
- minimal: true
169
- },
170
- fill: true,
171
- itemRenderer: ChangeProposalItemView,
172
- onItemSelect: item => selectProposal(item.itemPath)
173
- }, (0, _react2.jsx)(_core.Button, {
174
- rightIcon: "chevron-down",
175
- icon: getProposalIcon(proposals[selectedProposal])
176
- }, selectedItemSummary))) : (0, _react2.jsx)(_core.Button, {
177
- fill: true,
178
- alignText: "left",
179
- icon: getProposalIcon(proposals[selectedProposal]),
180
- rightIcon: "chevron-down"
181
- }, selectedItemSummary))), (0, _react2.jsx)("div", {
182
- css: (0, _react2.css)`position: relative; flex: 1;`
183
- }, (0, _react2.jsx)(_BrowserCtx.BrowserCtx.Provider, {
184
- value: proposalBrowserCtx
185
- }, (0, _react2.jsx)(ProposalDetail, {
186
- itemRef: selectedItemRef,
187
- showDiff: showDiff,
188
- showOnlyChanged: showOnlyChanged,
189
- itemData: selectedItemProposedData !== null && selectedItemProposedData !== void 0 ? selectedItemProposedData : selectedItemCurrentData,
190
- itemDataBefore: selectedItemCurrentData !== null && selectedItemCurrentData !== void 0 ? selectedItemCurrentData : undefined,
191
- proposal: proposals[selectedProposal]
192
- }))));
193
- } else {
194
- return (0, _react2.jsx)(_core.NonIdealState, {
195
- icon: 'warning-sign',
196
- className: className,
197
- title: "Unable to retrieve proposed item data",
198
- description: (0, _react2.jsx)("div", {
199
- css: (0, _react2.css)`text-align: left;`
200
- }, "Attempted to retrieve data for ", (0, _react2.jsx)("code", null, selectedProposal), ", but failed.", (0, _react2.jsx)("br", null), "Perhaps selected item was removed, or there is a data integrity issue.", (0, _react2.jsx)("br", null), "This might be caused by a problem in the application, or repository contents having been edited outside of the application.", (0, _react2.jsx)("br", null), "The data should be recoverable by inspecting version control system commit history.", (0, _react2.jsx)("br", null), (0, _react2.jsx)("br", null), (0, _react2.jsx)(_core.ButtonGroup, null, (0, _react2.jsx)(_core.Button, {
201
- onClick: () => selectProposal(firstProposal !== null && firstProposal !== void 0 ? firstProposal : null)
202
- }, firstProposal ? "Go to first proposed item" : "Unselect proposal"), (0, _react2.jsx)(_core.Button, {
203
- intent: "danger",
204
- onClick: () => selectProposal(firstProposal !== null && firstProposal !== void 0 ? firstProposal : null),
205
- title: "This should help if there\u2019s an addition or clarification proposal with missing proposed item data. NOTE: It removes the proposal, so you may need to create it again."
206
- }, "Delete phantom proposal item")))
207
- });
208
- }
140
+ const selectedItemSummary = (0, _react2.jsx)(ProposalSummary, {
141
+ itemRef: selectedItemRef,
142
+ item: selectedItemProposed !== null && selectedItemProposed !== void 0 ? selectedItemProposed : selectedItemCurrent,
143
+ itemBefore: selectedItemCurrent !== null && selectedItemCurrent !== void 0 ? selectedItemCurrent : undefined,
144
+ proposal: proposals[selectedProposal]
145
+ });
146
+ return (0, _react2.jsx)("div", {
147
+ css: (0, _react2.css)`display: flex; flex-flow: column nowrap;`,
148
+ className: className
149
+ }, (0, _react2.jsx)("div", null, (0, _react2.jsx)(_core.ControlGroup, null, (0, _react2.jsx)(_core.Switch, {
150
+ checked: showDiff,
151
+ onChange: evt => setShowDiff(evt.currentTarget.checked),
152
+ label: "View source",
153
+ css: (0, _react2.css)`margin-right: 1em !important`
154
+ }), (0, _react2.jsx)(_core.Switch, {
155
+ checked: showDiff && showOnlyChanged,
156
+ disabled: !showDiff,
157
+ onChange: evt => setShowOnlyChanged(evt.currentTarget.checked),
158
+ label: "Show clarified properties only"
159
+ })), (0, _react2.jsx)(_core.ButtonGroup, null, (0, _react2.jsx)(_core.Button, {
160
+ disabled: !jumpTo || ((_c = proposals[selectedProposal]) === null || _c === void 0 ? void 0 : _c.type) === 'addition',
161
+ icon: 'locate',
162
+ onClick: () => jumpTo === null || jumpTo === void 0 ? void 0 : jumpTo(`${_protocolRegistry.Protocols.ITEM_DETAILS}:${selectedProposal}`),
163
+ title: "Open selected item in a new tab (not applicable to proposed additions)"
164
+ }, "Reveal in registry"), Object.keys(proposals).length > 1 ? (0, _react2.jsx)(_react2.ClassNames, null, ({
165
+ css: css2
166
+ }) => (0, _react2.jsx)(_select.Select2, {
167
+ filterable: false,
168
+ itemsEqual: stringifiedJSONEqual,
169
+ menuProps: {
170
+ className: css2(`height: 50vh; overflow-y: auto;`)
171
+ },
172
+ activeItem: activeItem,
173
+ items: allItems,
174
+ popoverProps: {
175
+ minimal: true
176
+ },
177
+ fill: true,
178
+ itemRenderer: ChangeProposalItemView,
179
+ onItemSelect: handleItemSelect
180
+ }, (0, _react2.jsx)(_core.Button, {
181
+ rightIcon: "chevron-down",
182
+ icon: getProposalIcon(proposals[selectedProposal])
183
+ }, selectedItemSummary))) : (0, _react2.jsx)(_core.Button, {
184
+ fill: true,
185
+ alignText: "left",
186
+ icon: getProposalIcon(proposals[selectedProposal]),
187
+ rightIcon: "chevron-down"
188
+ }, selectedItemSummary))), (0, _react2.jsx)("div", {
189
+ css: (0, _react2.css)`position: relative; flex: 1;`
190
+ }, (0, _react2.jsx)(_BrowserCtx.BrowserCtx.Provider, {
191
+ value: proposalBrowserCtx
192
+ }, (0, _react2.jsx)(_ErrorBoundary.default, {
193
+ viewName: "Proposal detail"
194
+ }, (0, _react2.jsx)(ProposalDetail, {
195
+ itemRef: selectedItemRef,
196
+ showDiff: showDiff,
197
+ showOnlyChanged: showOnlyChanged,
198
+ item: selectedItemProposed !== null && selectedItemProposed !== void 0 ? selectedItemProposed : selectedItemCurrent,
199
+ itemBefore: selectedItemCurrent !== null && selectedItemCurrent !== void 0 ? selectedItemCurrent : undefined,
200
+ proposal: proposals[selectedProposal]
201
+ })))));
209
202
  } else {
210
203
  return (0, _react2.jsx)(_core.NonIdealState, {
211
204
  icon: 'clean',
@@ -237,38 +230,46 @@ const ChangeProposalItemView = (item, {
237
230
  });
238
231
  };
239
232
 
240
- const ProposalDetail = function ({
233
+ const ProposalDetail = (0, _react.memo)(function ({
241
234
  proposal,
242
235
  showDiff,
243
236
  showOnlyChanged,
244
237
  itemRef,
245
- itemData,
246
- itemDataBefore,
238
+ item,
239
+ itemBefore,
247
240
  onChange
248
241
  }) {
249
- const ItemView = _RegisterItem.default.main;
242
+ var _a, _b;
243
+
244
+ const itemClass = (0, _useItemClassConfig.default)((_a = itemRef.classID) !== null && _a !== void 0 ? _a : 'NONEXISTENT_CLASS_ID');
245
+
246
+ if (!itemClass) {
247
+ throw new Error(`Unknown item class “${itemRef.classID}”!`);
248
+ }
249
+
250
250
  const view = showDiff ? (0, _react2.jsx)(MaximizedStructuredDiff, {
251
- item1: itemDataBefore !== null && itemDataBefore !== void 0 ? itemDataBefore : {},
252
- item2: itemData,
251
+ item1: (_b = itemBefore === null || itemBefore === void 0 ? void 0 : itemBefore.data) !== null && _b !== void 0 ? _b : ITEM_DATA_PLACEHOLDER,
252
+ item2: item.data,
253
253
  showUnchanged: !showOnlyChanged,
254
254
  css: (0, _react2.css)`background: white; border-radius: 2.5px; padding: 10px 0; margin: 10px 0;`,
255
255
  className: _core.Classes.ELEVATION_2
256
- }) : (0, _react2.jsx)(ItemView, {
257
- uri: (0, _itemPathUtils.itemRefToItemPath)(itemRef),
256
+ }) : (0, _react2.jsx)(_RegisterItem.ItemDetail, {
257
+ itemRef: itemRef,
258
+ item: item,
259
+ itemClass: itemClass,
258
260
  key: JSON.stringify(itemRef)
259
261
  });
260
262
  return (0, _react2.jsx)("div", {
261
263
  css: (0, _react2.css)`position: absolute; inset: 0; display: flex; flex-flow: column;`
262
264
  }, view);
263
- };
264
-
265
+ });
265
266
  exports.ProposalDetail = ProposalDetail;
266
267
 
267
268
  const ProposalSummary = function ({
268
269
  proposal,
269
270
  itemRef,
270
- itemData,
271
- itemDataBefore,
271
+ item,
272
+ itemBefore,
272
273
  onChange
273
274
  }) {
274
275
  const {
@@ -280,50 +281,50 @@ const ProposalSummary = function ({
280
281
  const ListItemView = itemClasses[classID].views.listItemView;
281
282
  return (0, _react2.jsx)(ListItemView, {
282
283
  itemRef: itemRef,
283
- itemData: itemData
284
+ itemData: item.data
284
285
  });
285
286
  };
286
287
 
287
288
  exports.ProposalSummary = ProposalSummary;
288
289
  const clarification = {
289
290
  hint: (0, _react2.jsx)(_react.default.Fragment, null, "altered to represent the same concept more clearly."),
290
- summary: ({
291
+ summary: (0, _react.memo)(({
291
292
  proposal,
292
- itemData,
293
+ item,
293
294
  itemRef
294
- }) => (0, _react2.jsx)(_react.default.Fragment, null, "Clarification")
295
+ }) => (0, _react2.jsx)(_react.default.Fragment, null, "Clarification"), () => true)
295
296
  };
296
297
  const addition = {
297
298
  hint: (0, _react2.jsx)(_react.default.Fragment, null, "added to this register."),
298
- summary: ({
299
+ summary: (0, _react.memo)(({
299
300
  proposal,
300
- itemData,
301
+ item,
301
302
  itemRef
302
- }) => (0, _react2.jsx)(_react.default.Fragment, null, "Addition")
303
+ }) => (0, _react2.jsx)(_react.default.Fragment, null, "Addition"), () => true)
303
304
  };
304
305
  const retirement = {
305
306
  hint: (0, _react2.jsx)(_react.default.Fragment, null, "marked as no longer current. (Note that this register is append-only, so the item cannot be removed altogether.)"),
306
- summary: ({
307
+ summary: (0, _react.memo)(({
307
308
  proposal,
308
309
  itemRef,
309
- itemData
310
- }) => (0, _react2.jsx)(_react.default.Fragment, null, "Retirement")
310
+ item
311
+ }) => (0, _react2.jsx)(_react.default.Fragment, null, "Retirement"), () => true)
311
312
  };
312
313
  const supersession = {
313
314
  hint: (0, _react2.jsx)(_react.default.Fragment, null, "removed from the register with another item recommended for use in its place. A relation between the superseding and superseded item will be created, though the exact semantics of that relation depend on the register."),
314
- summary: ({
315
+ summary: (0, _react.memo)(({
315
316
  proposal,
316
317
  itemRef,
317
- itemData
318
- }) => (0, _react2.jsx)(_react.default.Fragment, null, "Supersession")
318
+ item
319
+ }) => (0, _react2.jsx)(_react.default.Fragment, null, "Supersession"), () => true)
319
320
  };
320
321
  const invalidation = {
321
322
  hint: (0, _react2.jsx)(_react.default.Fragment, null, "marked as invalid. The exact semantics of invalidation depend on the register."),
322
- summary: ({
323
+ summary: (0, _react.memo)(({
323
324
  proposal,
324
325
  itemRef,
325
- itemData
326
- }) => (0, _react2.jsx)(_react.default.Fragment, null, "Invalidation")
326
+ item
327
+ }) => (0, _react2.jsx)(_react.default.Fragment, null, "Invalidation"), () => true)
327
328
  };
328
329
  const MaximizedStructuredDiff = (0, _styled.default)(_StructuredDiff.default)`
329
330
  position: absolute;
@@ -342,4 +343,5 @@ function getProposalIcon(proposal) {
342
343
  }
343
344
 
344
345
  var _default = Proposals;
345
- exports.default = _default;
346
+ exports.default = _default;
347
+ const ITEM_DATA_PLACEHOLDER = {};