@jbrowse/product-core 4.2.1 → 5.0.0-beta.1
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/esm/RootModel/BaseRootModel.d.ts +629 -304
- package/esm/RootModel/BaseRootModel.js +138 -14
- package/esm/RootModel/HierarchicalConfig.d.ts +57 -21
- package/esm/RootModel/HierarchicalConfig.js +36 -0
- package/esm/RootModel/InternetAccounts.d.ts +18 -1
- package/esm/RootModel/InternetAccounts.js +120 -22
- package/esm/RootModel/PreferencesConfig.d.ts +53 -0
- package/esm/RootModel/PreferencesConfig.js +61 -0
- package/esm/RootModel/createConfigModel.d.ts +232 -0
- package/esm/RootModel/createConfigModel.js +56 -0
- package/esm/RootModel/index.d.ts +10 -5
- package/esm/RootModel/index.js +10 -5
- package/esm/RootModel/menuItems.d.ts +24 -0
- package/esm/RootModel/menuItems.js +143 -0
- package/esm/Session/BaseSession.d.ts +310 -11
- package/esm/Session/BaseSession.js +448 -14
- package/esm/Session/Connections.d.ts +114 -8
- package/esm/Session/Connections.js +195 -74
- package/esm/Session/DrawerWidgets.d.ts +115 -12
- package/esm/Session/DrawerWidgets.js +161 -42
- package/esm/Session/MultipleViews.d.ts +1266 -1128
- package/esm/Session/MultipleViews.js +357 -66
- package/esm/Session/Preferences.d.ts +1665 -0
- package/esm/Session/Preferences.js +54 -0
- package/esm/Session/ReferenceManagement.d.ts +28 -3
- package/esm/Session/ReferenceManagement.js +56 -41
- package/esm/Session/SessionTracks.d.ts +1275 -1138
- package/esm/Session/SessionTracks.js +532 -35
- package/esm/Session/Themes.d.ts +87 -2
- package/esm/Session/Themes.js +156 -23
- package/esm/Session/TrackMenu.d.ts +112 -0
- package/esm/Session/TrackMenu.js +200 -0
- package/esm/Session/TrackMenuSessionMixin.d.ts +27 -0
- package/esm/Session/TrackMenuSessionMixin.js +41 -0
- package/esm/Session/Tracks.d.ts +1169 -1117
- package/esm/Session/Tracks.js +160 -20
- package/esm/Session/assertSessionModel.d.ts +21 -0
- package/esm/Session/assertSessionModel.js +1 -0
- package/esm/Session/finalizeSession.d.ts +16 -0
- package/esm/Session/finalizeSession.js +29 -0
- package/esm/Session/index.d.ts +22 -10
- package/esm/Session/index.js +13 -10
- package/esm/Session/shareableSnapshot.d.ts +77 -0
- package/esm/Session/shareableSnapshot.js +196 -0
- package/esm/Session/temporaryAssemblyTracks.d.ts +23 -0
- package/esm/Session/temporaryAssemblyTracks.js +38 -0
- package/esm/assertExtends.d.ts +55 -0
- package/esm/assertExtends.js +1 -0
- package/esm/controllerTracks.d.ts +56 -0
- package/esm/controllerTracks.js +77 -0
- package/esm/destroyViewState.d.ts +21 -0
- package/esm/destroyViewState.js +29 -0
- package/esm/index.d.ts +31 -4
- package/esm/index.js +31 -4
- package/esm/loadPlugins.d.ts +33 -0
- package/esm/loadPlugins.js +38 -0
- package/esm/localFiles.d.ts +74 -0
- package/esm/localFiles.js +156 -0
- package/esm/observeSession.d.ts +56 -0
- package/esm/observeSession.js +91 -0
- package/esm/pluginInput.d.ts +32 -0
- package/esm/pluginInput.js +19 -0
- package/esm/pruneUnbuildableNodes.d.ts +109 -0
- package/esm/pruneUnbuildableNodes.js +568 -0
- package/esm/resolveAssemblies.d.ts +44 -0
- package/esm/resolveAssemblies.js +55 -0
- package/esm/rpcWorker.d.ts +26 -0
- package/esm/rpcWorker.js +96 -15
- package/esm/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/scheduleDetachedDestroy.js +24 -0
- package/esm/sessionMigrations/index.d.ts +53 -0
- package/esm/sessionMigrations/index.js +432 -0
- package/esm/sessionUrl.d.ts +41 -0
- package/esm/sessionUrl.js +53 -0
- package/esm/sessionUtils.d.ts +69 -0
- package/esm/sessionUtils.js +613 -0
- package/esm/siblingCast.d.ts +14 -0
- package/esm/siblingCast.js +16 -0
- package/esm/snapshotUtils.d.ts +8 -0
- package/esm/snapshotUtils.js +12 -0
- package/esm/ui/AboutDialog.d.ts +3 -6
- package/esm/ui/AboutDialog.js +4 -4
- package/esm/ui/AboutDialogContents.d.ts +2 -6
- package/esm/ui/AboutDialogContents.js +34 -13
- package/esm/ui/AssemblyInfoPanel.d.ts +5 -0
- package/esm/ui/AssemblyInfoPanel.js +69 -0
- package/esm/ui/DisplayDefaultsSection.d.ts +36 -0
- package/esm/ui/DisplayDefaultsSection.js +65 -0
- package/esm/ui/Drawer.d.ts +21 -0
- package/esm/ui/Drawer.js +60 -0
- package/esm/ui/DrawerControls.d.ts +5 -0
- package/esm/ui/DrawerControls.js +28 -0
- package/esm/ui/DrawerHeader.d.ts +6 -0
- package/esm/ui/DrawerHeader.js +36 -0
- package/esm/ui/DrawerWidget.d.ts +5 -0
- package/esm/ui/DrawerWidget.js +12 -0
- package/esm/ui/DrawerWidgetSelector.d.ts +5 -0
- package/esm/ui/DrawerWidgetSelector.js +40 -0
- package/esm/ui/FileInfoPanel.d.ts +3 -6
- package/esm/ui/FileInfoPanel.js +35 -26
- package/esm/ui/HeaderButtons.d.ts +7 -1
- package/esm/ui/HeaderButtons.js +23 -18
- package/esm/ui/ModalWidget.d.ts +12 -0
- package/esm/ui/ModalWidget.js +33 -0
- package/esm/ui/ModalWidgetAppBar.d.ts +8 -0
- package/esm/ui/ModalWidgetAppBar.js +9 -0
- package/esm/ui/PreferencesDialog.d.ts +56 -0
- package/esm/ui/PreferencesDialog.js +145 -0
- package/esm/ui/PreferencesResetDialog.d.ts +8 -0
- package/esm/ui/PreferencesResetDialog.js +19 -0
- package/esm/ui/RefNameAliasesDialog.d.ts +9 -0
- package/esm/ui/RefNameAliasesDialog.js +65 -0
- package/esm/ui/RefNameInfoDialog.d.ts +3 -6
- package/esm/ui/RefNameInfoDialog.js +57 -63
- package/esm/ui/WidgetBody.d.ts +18 -0
- package/esm/ui/WidgetBody.js +22 -0
- package/esm/ui/WidgetHeading.d.ts +7 -0
- package/esm/ui/WidgetHeading.js +7 -0
- package/esm/ui/drawerLayout.d.ts +18 -0
- package/esm/ui/drawerLayout.js +22 -0
- package/esm/ui/index.d.ts +13 -1
- package/esm/ui/index.js +12 -1
- package/esm/ui/util.d.ts +37 -4
- package/esm/ui/util.js +35 -38
- package/esm/useEngineLifecycle.d.ts +13 -0
- package/esm/useEngineLifecycle.js +22 -0
- package/package.json +11 -15
- package/esm/RootModel/FormatAbout.d.ts +0 -12
- package/esm/RootModel/FormatAbout.js +0 -15
- package/esm/RootModel/FormatDetails.d.ts +0 -24
- package/esm/RootModel/FormatDetails.js +0 -27
- package/esm/Session/DialogQueue.d.ts +0 -17
- package/esm/Session/DialogQueue.js +0 -31
package/esm/ui/AboutDialog.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare function AboutDialog({ config, session, handleClose, }: {
|
|
4
|
-
config: AnyConfigurationModel | Record<string, unknown>;
|
|
5
|
-
session: AbstractSessionModel;
|
|
1
|
+
import type { AboutPanelProps } from './util.ts';
|
|
2
|
+
export default function AboutDialog({ config, session, handleClose, }: AboutPanelProps & {
|
|
6
3
|
handleClose: () => void;
|
|
7
|
-
}): import("react
|
|
4
|
+
}): import("react").JSX.Element;
|
package/esm/ui/AboutDialog.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PluggableComponent } from '@jbrowse/core/ui';
|
|
2
3
|
import Dialog from '@jbrowse/core/ui/Dialog';
|
|
3
4
|
import { getEnv } from '@jbrowse/core/util';
|
|
4
5
|
import { getTrackName } from '@jbrowse/core/util/tracks';
|
|
5
|
-
import AboutContents from
|
|
6
|
-
export function AboutDialog({ config, session, handleClose, }) {
|
|
6
|
+
import AboutContents from './AboutDialogContents.js';
|
|
7
|
+
export default function AboutDialog({ config, session, handleClose, }) {
|
|
7
8
|
const trackName = getTrackName(config, session);
|
|
8
9
|
const { pluginManager } = getEnv(session);
|
|
9
|
-
|
|
10
|
-
return (_jsx(Dialog, { open: true, onClose: handleClose, title: trackName, maxWidth: "xl", children: _jsx(AboutComponent, { config: config, session: session }) }));
|
|
10
|
+
return (_jsx(Dialog, { open: true, onClose: handleClose, title: trackName, maxWidth: "xl", children: _jsx(PluggableComponent, { pluginManager: pluginManager, name: "Core-replaceAbout", component: AboutContents, props: { config, session } }) }));
|
|
11
11
|
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
declare const AboutDialogContents: ({ config, session, }: {
|
|
4
|
-
config: AnyConfigurationModel | Record<string, unknown>;
|
|
5
|
-
session: AbstractSessionModel;
|
|
6
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
import type { AboutPanelProps } from './util.ts';
|
|
2
|
+
declare const AboutDialogContents: ({ config, session, }: AboutPanelProps) => import("react").JSX.Element;
|
|
7
3
|
export default AboutDialogContents;
|
|
@@ -2,35 +2,56 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import Attributes from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/Attributes';
|
|
4
4
|
import BaseCard from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard';
|
|
5
|
-
import {
|
|
5
|
+
import { getTrackConfigWithPromotables, hydrateTrackConfig, } from '@jbrowse/core/configuration';
|
|
6
|
+
import PluggableComponents from '@jbrowse/core/ui/PluggableComponents';
|
|
6
7
|
import { getEnv } from '@jbrowse/core/util';
|
|
7
8
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
8
|
-
import {
|
|
9
|
+
import { isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
9
10
|
import { observer } from 'mobx-react';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
11
|
+
import AssemblyInfoPanel from './AssemblyInfoPanel.js';
|
|
12
|
+
import FileInfoPanel from './FileInfoPanel.js';
|
|
13
|
+
import HeaderButtons from './HeaderButtons.js';
|
|
14
|
+
import RefNameInfoDialog from './RefNameInfoDialog.js';
|
|
15
|
+
import { getAboutDialogConfig } from './util.js';
|
|
14
16
|
const useStyles = makeStyles()({
|
|
15
17
|
content: {
|
|
16
18
|
minWidth: 800,
|
|
17
19
|
},
|
|
18
20
|
});
|
|
21
|
+
const hideFields = ['displays', 'baseUri', 'refNames', 'formatAbout'];
|
|
19
22
|
const AboutDialogContents = observer(function AboutDialogContents({ config, session, }) {
|
|
20
|
-
const conf = isStateTreeNode(config) ? getSnapshot(config) : config;
|
|
21
23
|
const { classes } = useStyles();
|
|
22
24
|
const [showRefNames, setShowRefNames] = useState(false);
|
|
23
|
-
const hideUris = getConf(session, ['formatAbout', 'hideUris']) ||
|
|
24
|
-
readConf(config, ['formatAbout', 'hideUris']);
|
|
25
25
|
const { pluginManager } = getEnv(session);
|
|
26
|
-
|
|
26
|
+
// "Copy config" output leaves the cascade for good (a user pastes it into a
|
|
27
|
+
// config.json), so promotable slots are resolved rather than left stripped —
|
|
28
|
+
// otherwise the copied config renders differently from the track it came from.
|
|
29
|
+
// `fromDisplayTypeDefaults` names what that folded in, so materializing a
|
|
30
|
+
// session-wide preference into a track config isn't silent.
|
|
31
|
+
//
|
|
32
|
+
// The two menus that open this dialog hand over different things: the in-view
|
|
33
|
+
// track label passes `track.configuration`, a live node, while the
|
|
34
|
+
// hierarchical selector passes a `session.tracks` entry, which is a
|
|
35
|
+
// `types.frozen` plain object until something references the track. Resolving
|
|
36
|
+
// only the first meant the same track copied a different config depending on
|
|
37
|
+
// which menu you came from — and the selector is the one you can reach
|
|
38
|
+
// without opening the track at all. Hydrating converges them; it returns
|
|
39
|
+
// undefined for a config no plugin can build, and that falls back to copying
|
|
40
|
+
// it as authored.
|
|
41
|
+
const live = isStateTreeNode(config)
|
|
42
|
+
? config
|
|
43
|
+
: hydrateTrackConfig(pluginManager, config);
|
|
44
|
+
const { config: conf, fromDisplayTypeDefaults } = live
|
|
45
|
+
? getTrackConfigWithPromotables(session, live)
|
|
46
|
+
: { config, fromDisplayTypeDefaults: [] };
|
|
47
|
+
const { config: shown, hideUris } = getAboutDialogConfig({
|
|
27
48
|
config,
|
|
28
49
|
session,
|
|
29
50
|
pluginManager,
|
|
30
51
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
52
|
+
return (_jsxs("div", { className: classes.content, children: [_jsxs(BaseCard, { title: "Configuration", children: [_jsx(HeaderButtons, { conf: conf, hideUris: hideUris, fromDisplayTypeDefaults: fromDisplayTypeDefaults, setShowRefNames: setShowRefNames }), _jsx(Attributes, { attributes: shown, omit: [...hideFields, 'metadata'], hideUris: hideUris })] }), shown.metadata ? (_jsx(BaseCard, { title: "Metadata", children: _jsx(Attributes, { attributes: shown.metadata, hideUris: hideUris }) })) : null, _jsx(AssemblyInfoPanel, { config: config, session: session, hideUris: hideUris }), _jsx(PluggableComponents, { pluginManager: pluginManager,
|
|
53
|
+
/** #extensionPoint Core-extraAboutPanel | sync | Add extra panels to a track's About dialog */
|
|
54
|
+
name: "Core-extraAboutPanel", props: { session, config } }), hideUris ? null : _jsx(FileInfoPanel, { config: config, session: session }), showRefNames ? (_jsx(RefNameInfoDialog, { session: session, config: config, onClose: () => {
|
|
34
55
|
setShowRefNames(false);
|
|
35
56
|
} })) : null] }));
|
|
36
57
|
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import Attributes from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/Attributes';
|
|
4
|
+
import BaseCard from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard';
|
|
5
|
+
import { readConfObject, readConfSlot } from '@jbrowse/core/configuration';
|
|
6
|
+
import { CopyToClipboardButton } from '@jbrowse/core/ui';
|
|
7
|
+
import { stripBaseUris } from '@jbrowse/core/util/addRelativeUris';
|
|
8
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
9
|
+
import { getParent, hasParent, isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
10
|
+
import { Button } from '@mui/material';
|
|
11
|
+
import { observer } from 'mobx-react';
|
|
12
|
+
import RefNameAliasesDialog from './RefNameAliasesDialog.js';
|
|
13
|
+
// `Attributes` omits these at every depth, which is what reaches the two that
|
|
14
|
+
// are nested:
|
|
15
|
+
// - `sequence` is the config of the very track this dialog is about, in the
|
|
16
|
+
// card above
|
|
17
|
+
// - `features` is an inline adapter's whole data payload. An assembly whose
|
|
18
|
+
// aliases or cytobands are written into the config rather than fetched from a
|
|
19
|
+
// file rendered them here as a spreadsheet of the raw rows, which buried the
|
|
20
|
+
// four lines anyone opened the card for — and it is the same data the alias
|
|
21
|
+
// listing shows resolved, one button over
|
|
22
|
+
// - `adapterId` is a generated hash, and `baseUri` is where the config was
|
|
23
|
+
// loaded from rather than anything about the assembly
|
|
24
|
+
//
|
|
25
|
+
// Nothing is hidden from "Copy assembly config", which copies the config whole.
|
|
26
|
+
const hideFields = ['sequence', 'features', 'adapterId', 'baseUri'];
|
|
27
|
+
const useStyles = makeStyles()(theme => ({
|
|
28
|
+
buttons: {
|
|
29
|
+
float: 'right',
|
|
30
|
+
display: 'flex',
|
|
31
|
+
gap: theme.spacing(1),
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
/**
|
|
35
|
+
* The assembly config a `ReferenceSequenceTrack` config hangs off, and
|
|
36
|
+
* undefined for every other track.
|
|
37
|
+
*
|
|
38
|
+
* A reference sequence track declares no `assemblyNames` slot — the config node
|
|
39
|
+
* holding it *is* its assembly, the same walk `getConfAssemblyNames` makes.
|
|
40
|
+
* Compared by identity against that node's `sequence`, so the card is the
|
|
41
|
+
* assembly of the track the dialog is already showing.
|
|
42
|
+
*
|
|
43
|
+
* Both menus that open this dialog hand over a live node here: the hierarchical
|
|
44
|
+
* selector reads `assemblyManager.get(name).configuration.sequence`, and the
|
|
45
|
+
* in-view track label's `track.configuration` resolves to that same node
|
|
46
|
+
* through `getTrackById`. The frozen `session.tracks` entry the rest of the
|
|
47
|
+
* dialog has to cope with is never a reference sequence track.
|
|
48
|
+
*/
|
|
49
|
+
function getAssemblyConf(config) {
|
|
50
|
+
const parent = isStateTreeNode(config) && hasParent(config)
|
|
51
|
+
? getParent(config)
|
|
52
|
+
: undefined;
|
|
53
|
+
return parent?.sequence === config ? parent : undefined;
|
|
54
|
+
}
|
|
55
|
+
const AssemblyCard = observer(function AssemblyCard({ assemblyConf, session, hideUris, }) {
|
|
56
|
+
const { classes } = useStyles();
|
|
57
|
+
const [showAliases, setShowAliases] = useState(false);
|
|
58
|
+
const conf = readConfObject(assemblyConf);
|
|
59
|
+
return (_jsxs(BaseCard, { title: "Assembly", children: [_jsxs("span", { className: classes.buttons, children: [_jsx(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
60
|
+
setShowAliases(true);
|
|
61
|
+
}, children: "Show ref name aliases" }), hideUris ? null : (_jsx(CopyToClipboardButton, { variant: "contained", value: () => JSON.stringify(stripBaseUris(structuredClone(conf)), null, 2), children: "Copy assembly config" }))] }), _jsx(Attributes, { attributes: conf, omit: hideFields, hideUris: hideUris }), showAliases ? (_jsx(RefNameAliasesDialog, { assemblyName: readConfSlot(assemblyConf, 'name'), session: session, onClose: () => {
|
|
62
|
+
setShowAliases(false);
|
|
63
|
+
} })) : null] }));
|
|
64
|
+
});
|
|
65
|
+
const AssemblyInfoPanel = observer(function AssemblyInfoPanel({ config, session, hideUris, }) {
|
|
66
|
+
const assemblyConf = getAssemblyConf(config);
|
|
67
|
+
return assemblyConf ? (_jsx(AssemblyCard, { assemblyConf: assemblyConf, session: session, hideUris: hideUris })) : null;
|
|
68
|
+
});
|
|
69
|
+
export default AssemblyInfoPanel;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
+
export interface DisplayDefaultsSession {
|
|
3
|
+
getDisplayTypeDefaults: () => {
|
|
4
|
+
displayType: string;
|
|
5
|
+
slot: string;
|
|
6
|
+
value: unknown;
|
|
7
|
+
}[];
|
|
8
|
+
setDisplayTypeDefault: (displayType: string, slot: string, value: unknown) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The inventory of session-wide display-type defaults: every value the user has
|
|
12
|
+
* pinned from a track menu, what it overrides, and a button to clear one.
|
|
13
|
+
*
|
|
14
|
+
* The pin is easy to set and, until this, hard to find again. A pinned default
|
|
15
|
+
* shows on the track-selector badge of any **open** track it moves — but one
|
|
16
|
+
* affecting nothing currently open, one promoted to a value equal to the slot's
|
|
17
|
+
* base, and one that no longer resolves at all (a stale value the cascade
|
|
18
|
+
* refuses, or a display type whose plugin is gone) appear nowhere. The only
|
|
19
|
+
* place that listed them was the "Reset preferences to defaults" confirmation,
|
|
20
|
+
* which is a destructive dialog to have to open in order to read something.
|
|
21
|
+
*
|
|
22
|
+
* The empty state is deliberate rather than rendering nothing: it is the one
|
|
23
|
+
* place the app says the capability exists to someone who has never used it.
|
|
24
|
+
*
|
|
25
|
+
* **The slot keeps its schema name**, while the display type gets its authored
|
|
26
|
+
* one. A slot has no menu label to borrow — which row a setting is offered on is
|
|
27
|
+
* a menu fact and declaring the slot promotable is a schema fact, and nothing
|
|
28
|
+
* joins them (that split is why `promotableSlotsWithoutPin` has to walk a built
|
|
29
|
+
* menu at all). A raw slot name is also what the config editor labels its fields
|
|
30
|
+
* with, so the two surfaces agree.
|
|
31
|
+
*/
|
|
32
|
+
declare const DisplayDefaultsSection: ({ session, pluginManager, }: {
|
|
33
|
+
session: DisplayDefaultsSession;
|
|
34
|
+
pluginManager: PluginManager;
|
|
35
|
+
}) => import("react").JSX.Element;
|
|
36
|
+
export default DisplayDefaultsSection;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { getConfigurationSchemaDefinition, isSlotDefinitionEntry, } from '@jbrowse/core/configuration';
|
|
3
|
+
import { SettingsChangesTable } from '@jbrowse/core/ui';
|
|
4
|
+
import { Typography } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
// The registered display types, by name.
|
|
7
|
+
//
|
|
8
|
+
// **Built rather than reached through `getDisplayType`, which THROWS** on a name
|
|
9
|
+
// no plugin registers — an optional chain over it guards nothing. A default left
|
|
10
|
+
// behind by a plugin that has since been uninstalled is exactly a row this
|
|
11
|
+
// section has to render, so reaching for that getter would crash the whole
|
|
12
|
+
// Preferences dialog for the one user whose pins most need clearing.
|
|
13
|
+
function displayTypesByName(pluginManager) {
|
|
14
|
+
return new Map(pluginManager.getDisplayElements().map(d => [d.name, d]));
|
|
15
|
+
}
|
|
16
|
+
// What a track sitting at the bottom of the cascade shows for this slot — the
|
|
17
|
+
// value clearing the pin would restore. Read off the display type's schema
|
|
18
|
+
// rather than off the session, which holds only what was promoted. Undefined
|
|
19
|
+
// for a display type that is gone, whose row then reads "(default)" like any
|
|
20
|
+
// other unknown.
|
|
21
|
+
function promotedBaseOf(configSchema, slot) {
|
|
22
|
+
const def = configSchema
|
|
23
|
+
? getConfigurationSchemaDefinition(configSchema)?.[slot]
|
|
24
|
+
: undefined;
|
|
25
|
+
return isSlotDefinitionEntry(def) ? def.promotedBase : undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The inventory of session-wide display-type defaults: every value the user has
|
|
29
|
+
* pinned from a track menu, what it overrides, and a button to clear one.
|
|
30
|
+
*
|
|
31
|
+
* The pin is easy to set and, until this, hard to find again. A pinned default
|
|
32
|
+
* shows on the track-selector badge of any **open** track it moves — but one
|
|
33
|
+
* affecting nothing currently open, one promoted to a value equal to the slot's
|
|
34
|
+
* base, and one that no longer resolves at all (a stale value the cascade
|
|
35
|
+
* refuses, or a display type whose plugin is gone) appear nowhere. The only
|
|
36
|
+
* place that listed them was the "Reset preferences to defaults" confirmation,
|
|
37
|
+
* which is a destructive dialog to have to open in order to read something.
|
|
38
|
+
*
|
|
39
|
+
* The empty state is deliberate rather than rendering nothing: it is the one
|
|
40
|
+
* place the app says the capability exists to someone who has never used it.
|
|
41
|
+
*
|
|
42
|
+
* **The slot keeps its schema name**, while the display type gets its authored
|
|
43
|
+
* one. A slot has no menu label to borrow — which row a setting is offered on is
|
|
44
|
+
* a menu fact and declaring the slot promotable is a schema fact, and nothing
|
|
45
|
+
* joins them (that split is why `promotableSlotsWithoutPin` has to walk a built
|
|
46
|
+
* menu at all). A raw slot name is also what the config editor labels its fields
|
|
47
|
+
* with, so the two surfaces agree.
|
|
48
|
+
*/
|
|
49
|
+
const DisplayDefaultsSection = observer(function DisplayDefaultsSection({ session, pluginManager, }) {
|
|
50
|
+
const byName = displayTypesByName(pluginManager);
|
|
51
|
+
const changes = session
|
|
52
|
+
.getDisplayTypeDefaults()
|
|
53
|
+
.map(({ displayType, slot, value }) => ({
|
|
54
|
+
// the address this section's own reset uses, so it depends on nothing the
|
|
55
|
+
// session's preference-key layout does
|
|
56
|
+
path: [displayType, slot],
|
|
57
|
+
label: `${byName.get(displayType)?.displayName ?? displayType} › ${slot}`,
|
|
58
|
+
from: promotedBaseOf(byName.get(displayType)?.configSchema, slot),
|
|
59
|
+
to: value,
|
|
60
|
+
}));
|
|
61
|
+
return changes.length ? (_jsxs(_Fragment, { children: [_jsx(Typography, { children: "These apply to every track of a display type that hasn't set its own value. Clear one to put those tracks back on the setting's default." }), _jsx(SettingsChangesTable, { changes: changes, onResetRow: change => {
|
|
62
|
+
session.setDisplayTypeDefault(change.path[0], change.path[1], undefined);
|
|
63
|
+
} })] })) : (_jsx(Typography, { children: "None set. The pin beside a setting in a track menu makes that value the default for every track of the same display type." }));
|
|
64
|
+
});
|
|
65
|
+
export default DisplayDefaultsSection;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DrawerPosition } from '@jbrowse/core/util';
|
|
2
|
+
/**
|
|
3
|
+
* All the chrome needs of a session, narrowed the way
|
|
4
|
+
* `PreferencesDialogSession` is: the drawer is the one widget surface an
|
|
5
|
+
* embedder can mount against a session of their own shape.
|
|
6
|
+
*/
|
|
7
|
+
export interface DrawerChromeSession {
|
|
8
|
+
drawerPosition: DrawerPosition;
|
|
9
|
+
resizeDrawer: (distance: number, availableWidth?: number) => number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The drawer's chrome: the paper it sits on and the handle that resizes it.
|
|
13
|
+
* Focus tracking is left to the caller through `ref`, since only the app shell
|
|
14
|
+
* has a focused-view concept to wire it to.
|
|
15
|
+
*/
|
|
16
|
+
declare const Drawer: ({ session, children, ref, }: {
|
|
17
|
+
session: DrawerChromeSession;
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
20
|
+
}) => import("react").JSX.Element;
|
|
21
|
+
export default Drawer;
|
package/esm/ui/Drawer.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import ResizeHandle from '@jbrowse/core/ui/ResizeHandle';
|
|
4
|
+
import { DRAWER_Z_INDEX } from '@jbrowse/core/ui/zIndexes';
|
|
5
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
|
+
import { Paper } from '@mui/material';
|
|
7
|
+
import { observer } from 'mobx-react';
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
|
+
// The grid item, and the handle's containing block. Its own box rather than
|
|
10
|
+
// the Paper's because the Paper is the thing that SCROLLS: a handle
|
|
11
|
+
// positioned against it starts at the top of the scrolled content and rides
|
|
12
|
+
// away with it, and one taken out of flow with `position: fixed` is measured
|
|
13
|
+
// against the window instead — which is the same box only in a full-window
|
|
14
|
+
// app, and put a page-tall col-resize strip down an embedded view's page.
|
|
15
|
+
root: {
|
|
16
|
+
// the drawer places itself, so a host renders it once wherever it likes
|
|
17
|
+
// rather than on the side matching `drawerPosition` (see
|
|
18
|
+
// `drawerGridTemplateColumns`)
|
|
19
|
+
gridColumn: 'drawer',
|
|
20
|
+
position: 'relative',
|
|
21
|
+
height: '100%',
|
|
22
|
+
minWidth: 0,
|
|
23
|
+
},
|
|
24
|
+
paper: {
|
|
25
|
+
overflowY: 'auto',
|
|
26
|
+
height: '100%',
|
|
27
|
+
// widgets position their own overlays against this
|
|
28
|
+
position: 'relative',
|
|
29
|
+
zIndex: DRAWER_Z_INDEX,
|
|
30
|
+
outline: 'none',
|
|
31
|
+
background: theme.palette.background.default,
|
|
32
|
+
},
|
|
33
|
+
resizeHandle: {
|
|
34
|
+
position: 'absolute',
|
|
35
|
+
top: 0,
|
|
36
|
+
zIndex: DRAWER_Z_INDEX + 1,
|
|
37
|
+
},
|
|
38
|
+
// whichever edge faces the main content
|
|
39
|
+
handleForLeftDrawer: { right: 0 },
|
|
40
|
+
handleForRightDrawer: { left: 0 },
|
|
41
|
+
}));
|
|
42
|
+
/**
|
|
43
|
+
* The drawer's chrome: the paper it sits on and the handle that resizes it.
|
|
44
|
+
* Focus tracking is left to the caller through `ref`, since only the app shell
|
|
45
|
+
* has a focused-view concept to wire it to.
|
|
46
|
+
*/
|
|
47
|
+
const Drawer = observer(function Drawer({ session, children, ref, }) {
|
|
48
|
+
const { drawerPosition } = session;
|
|
49
|
+
const { classes, cx } = useStyles();
|
|
50
|
+
const rootRef = useRef(null);
|
|
51
|
+
return (_jsxs("div", { ref: rootRef, className: classes.root, children: [_jsx(Paper, { ref: ref, className: classes.paper, elevation: 16, square: true, "data-testid": "drawer-widget", children: children }), _jsx(ResizeHandle, { onDrag: distance => {
|
|
52
|
+
// the width the drawer and the main area share: both are columns of
|
|
53
|
+
// the grid this is an item of, and the clamp needs the container
|
|
54
|
+
// rather than the window
|
|
55
|
+
session.resizeDrawer(distance, rootRef.current?.parentElement?.clientWidth);
|
|
56
|
+
}, className: cx(classes.resizeHandle, drawerPosition === 'left'
|
|
57
|
+
? classes.handleForLeftDrawer
|
|
58
|
+
: classes.handleForRightDrawer), vertical: true, bar: true })] }));
|
|
59
|
+
});
|
|
60
|
+
export default Drawer;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
4
|
+
import MinimizeIcon from '@mui/icons-material/Minimize';
|
|
5
|
+
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
6
|
+
import { IconButton, Menu, MenuItem, Tooltip } from '@mui/material';
|
|
7
|
+
import { observer } from 'mobx-react';
|
|
8
|
+
const drawerPositionOptions = ['left', 'right'];
|
|
9
|
+
const DrawerControls = observer(function DrawerControls({ session, }) {
|
|
10
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
11
|
+
const { drawerPosition, visibleWidget } = session;
|
|
12
|
+
return (_jsxs(_Fragment, { children: [_jsx(Tooltip, { title: "Drawer position", children: _jsx(IconButton, { "data-testid": "drawer-position-button", color: "inherit", onClick: event => {
|
|
13
|
+
setAnchorEl(event.currentTarget);
|
|
14
|
+
}, children: _jsx(MoreVertIcon, {}) }) }), _jsx(Tooltip, { title: "Minimize drawer", children: _jsx(IconButton, { "data-testid": "drawer-minimize", color: "inherit", onClick: () => {
|
|
15
|
+
session.notify(`Drawer minimized, click button on ${drawerPosition} side of screen to re-open`, 'info');
|
|
16
|
+
session.minimizeWidgetDrawer();
|
|
17
|
+
}, children: _jsx(MinimizeIcon, {}) }) }), _jsx(Tooltip, { title: "Close drawer", children: _jsx(IconButton, { color: "inherit", onClick: () => {
|
|
18
|
+
if (visibleWidget) {
|
|
19
|
+
session.hideWidget(visibleWidget);
|
|
20
|
+
}
|
|
21
|
+
}, children: _jsx(CloseIcon, {}) }) }), _jsx(Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: () => {
|
|
22
|
+
setAnchorEl(null);
|
|
23
|
+
}, children: drawerPositionOptions.map(option => (_jsx(MenuItem, { selected: drawerPosition === option, onClick: () => {
|
|
24
|
+
session.setDrawerPosition(option);
|
|
25
|
+
setAnchorEl(null);
|
|
26
|
+
}, children: option }, option))) })] }));
|
|
27
|
+
});
|
|
28
|
+
export default DrawerControls;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SessionWithDrawerWidgets } from '@jbrowse/core/util';
|
|
2
|
+
declare const DrawerHeader: ({ session, setToolbarHeight, }: {
|
|
3
|
+
session: SessionWithDrawerWidgets;
|
|
4
|
+
setToolbarHeight: (arg: number) => void;
|
|
5
|
+
}) => import("react").JSX.Element;
|
|
6
|
+
export default DrawerHeader;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import { AppBar, Toolbar } from '@mui/material';
|
|
5
|
+
import { observer } from 'mobx-react';
|
|
6
|
+
import DrawerControls from './DrawerControls.js';
|
|
7
|
+
import DrawerWidgetSelector from './DrawerWidgetSelector.js';
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
|
+
appBar: {
|
|
10
|
+
background: theme.palette.secondary.main,
|
|
11
|
+
},
|
|
12
|
+
spacer: {
|
|
13
|
+
flexGrow: 1,
|
|
14
|
+
},
|
|
15
|
+
}));
|
|
16
|
+
const DrawerHeader = observer(function DrawerHeader({ session, setToolbarHeight, }) {
|
|
17
|
+
const { classes } = useStyles();
|
|
18
|
+
// Measured, and re-measured: the toolbar's height is the room a virtualized
|
|
19
|
+
// widget subtracts from the box it is given, and it changes without this
|
|
20
|
+
// component re-rendering -- MUI's Toolbar is 56px under the `sm` breakpoint
|
|
21
|
+
// and 64 above it, and grows again with the root font size. Read once at
|
|
22
|
+
// mount, a widget's list was that much too tall for the rest of the session.
|
|
23
|
+
const appBarRef = useCallback((node) => {
|
|
24
|
+
const publish = () => {
|
|
25
|
+
setToolbarHeight(node.getBoundingClientRect().height);
|
|
26
|
+
};
|
|
27
|
+
publish();
|
|
28
|
+
const observer = new ResizeObserver(publish);
|
|
29
|
+
observer.observe(node);
|
|
30
|
+
return () => {
|
|
31
|
+
observer.disconnect();
|
|
32
|
+
};
|
|
33
|
+
}, [setToolbarHeight]);
|
|
34
|
+
return (_jsx(AppBar, { position: "sticky", className: classes.appBar, ref: appBarRef, children: _jsxs(Toolbar, { disableGutters: true, children: [_jsx(DrawerWidgetSelector, { session: session }), _jsx("div", { className: classes.spacer }), _jsx(DrawerControls, { session: session })] }) }));
|
|
35
|
+
});
|
|
36
|
+
export default DrawerHeader;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
import Drawer from './Drawer.js';
|
|
5
|
+
import DrawerHeader from './DrawerHeader.js';
|
|
6
|
+
import WidgetBody from './WidgetBody.js';
|
|
7
|
+
const DrawerWidget = observer(function DrawerWidget({ session, }) {
|
|
8
|
+
const { visibleWidget } = session;
|
|
9
|
+
const [toolbarHeight, setToolbarHeight] = useState(0);
|
|
10
|
+
return (_jsxs(Drawer, { session: session, children: [_jsx(DrawerHeader, { session: session, setToolbarHeight: setToolbarHeight }), visibleWidget ? (_jsx(WidgetBody, { session: session, widget: visibleWidget, toolbarHeight: toolbarHeight })) : null] }));
|
|
11
|
+
});
|
|
12
|
+
export default DrawerWidget;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { getEnv } from '@jbrowse/core/util';
|
|
3
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
4
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
5
|
+
import { FormControl, IconButton, MenuItem, Select, Typography, } from '@mui/material';
|
|
6
|
+
import { observer } from 'mobx-react';
|
|
7
|
+
import WidgetHeading from './WidgetHeading.js';
|
|
8
|
+
const useStyles = makeStyles()(theme => ({
|
|
9
|
+
formControl: {
|
|
10
|
+
margin: 0,
|
|
11
|
+
},
|
|
12
|
+
drawerSelect: {
|
|
13
|
+
margin: 0,
|
|
14
|
+
color: theme.palette.secondary.contrastText,
|
|
15
|
+
},
|
|
16
|
+
dropDownIcon: {
|
|
17
|
+
color: theme.palette.secondary.contrastText,
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
const DrawerWidgetSelector = observer(function DrawerWidgetSelector({ session, }) {
|
|
21
|
+
const { visibleWidget, activeWidgets } = session;
|
|
22
|
+
const { classes } = useStyles();
|
|
23
|
+
const { pluginManager } = getEnv(session);
|
|
24
|
+
return (_jsx(FormControl, { className: classes.formControl, children: _jsx(Select, { value: visibleWidget?.id ?? '', "data-testid": "widget-drawer-selects", className: classes.drawerSelect, classes: { icon: classes.dropDownIcon }, renderValue: widgetId => {
|
|
25
|
+
const widget = session.activeWidgets.get(widgetId);
|
|
26
|
+
return widget ? (_jsx(WidgetHeading, { pluginManager: pluginManager, widget: widget })) : (_jsx(Typography, { variant: "h6", color: "inherit", children: "Unknown widget" }));
|
|
27
|
+
}, onChange: e => {
|
|
28
|
+
const w = session.activeWidgets.get(e.target.value);
|
|
29
|
+
if (w) {
|
|
30
|
+
session.showWidget(w);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
session.notify(`Widget not found ${e.target.value}`, 'warning');
|
|
34
|
+
}
|
|
35
|
+
}, children: [...activeWidgets.values()].map(widget => (_jsxs(MenuItem, { "data-testid": `widget-drawer-selects-item-${widget.type}`, value: widget.id, children: [_jsx(WidgetHeading, { pluginManager: pluginManager, widget: widget }), _jsx(IconButton, { "data-testid": `${widget.type}-drawer-delete`, color: "inherit", "aria-label": "Delete", onClick: e => {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
session.hideWidget(widget);
|
|
38
|
+
}, children: _jsx(DeleteIcon, {}) })] }, widget.id))) }) }));
|
|
39
|
+
});
|
|
40
|
+
export default DrawerWidgetSelector;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export default
|
|
4
|
-
config: AnyConfigurationModel | Record<string, unknown>;
|
|
5
|
-
session: AbstractSessionModel;
|
|
6
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
import type { AboutPanelProps } from './util.ts';
|
|
2
|
+
declare const FileInfoPanel: ({ config, session, }: AboutPanelProps) => import("react").JSX.Element | null;
|
|
3
|
+
export default FileInfoPanel;
|
package/esm/ui/FileInfoPanel.js
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
3
2
|
import Attributes from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/Attributes';
|
|
4
3
|
import BaseCard from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import { readConfSlot } from '@jbrowse/core/configuration';
|
|
5
|
+
import { ErrorBanner, LoadingEllipses } from '@jbrowse/core/ui';
|
|
6
|
+
import { statusProgressLabel } from '@jbrowse/core/util';
|
|
7
|
+
import { useFetch } from '@jbrowse/core/util/useFetch';
|
|
8
|
+
import { observer } from 'mobx-react';
|
|
9
|
+
// Inline `observer(function(){})`, not a bare declaration: this reads
|
|
10
|
+
// observables (session.rpcManager, and config slots off what is usually a live
|
|
11
|
+
// MST node), and babel-plugin-react-compiler compiles the bare form and can
|
|
12
|
+
// memoize such a read into staleness. RefNameInfoDialog beside it is written
|
|
13
|
+
// the same way; see the React Compiler x MobX note in CLAUDE.md
|
|
14
|
+
const FileInfoPanel = observer(function FileInfoPanel({ config, session, }) {
|
|
10
15
|
const { rpcManager } = session;
|
|
11
|
-
const trackId =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
catch (e) {
|
|
23
|
-
console.error(e);
|
|
24
|
-
setError(e);
|
|
25
|
-
}
|
|
26
|
-
})();
|
|
27
|
-
}, [config, rpcManager, trackId]);
|
|
16
|
+
const trackId = readConfSlot(config, 'trackId');
|
|
17
|
+
const { data: info, error, isLoading, status, } = useFetch(['CoreGetInfo', trackId],
|
|
18
|
+
// reading a header can mean walking a v8 .hic's norm-vector index or a
|
|
19
|
+
// multi-megabyte VCF header, so it gets both handles: closing the About
|
|
20
|
+
// dialog stops it, and the wait says what it is
|
|
21
|
+
async (_name, _trackId, stopToken, statusCallback) => (await rpcManager.call(trackId, 'CoreGetInfo', {
|
|
22
|
+
adapterConfig: readConfSlot(config, 'adapter'),
|
|
23
|
+
stopToken,
|
|
24
|
+
statusCallback,
|
|
25
|
+
})));
|
|
28
26
|
const details = typeof info === 'string'
|
|
29
27
|
? {
|
|
30
28
|
header: `<pre>${info
|
|
29
|
+
.replaceAll('&', '&')
|
|
31
30
|
.replaceAll('<', '<')
|
|
32
31
|
.replaceAll('>', '>')}</pre>`,
|
|
33
32
|
}
|
|
34
|
-
: info
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
: (info ?? {});
|
|
34
|
+
// `BaseFeatureDataAdapter.getHeader` returns null unless an adapter overrides
|
|
35
|
+
// it, and `CoreGetInfo` returns null outright for anything that isn't a
|
|
36
|
+
// feature adapter — so most tracks reached this with nothing to say and got a
|
|
37
|
+
// FILE INFO heading with blank space under it. A panel with no content is not
|
|
38
|
+
// a panel
|
|
39
|
+
const empty = Object.values(details).every(v => v == null);
|
|
40
|
+
if (!error && !isLoading && empty) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return (_jsx(BaseCard, { title: "File info", children: error ? (_jsx(ErrorBanner, { error: error })) : isLoading ? (_jsx(LoadingEllipses, { message: statusProgressLabel(status) || 'Loading file data' })) : (_jsx(Attributes, { attributes: details })) }));
|
|
44
|
+
});
|
|
45
|
+
export default FileInfoPanel;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
interface HeaderButtonsProps {
|
|
2
2
|
conf: Record<string, unknown>;
|
|
3
|
+
hideUris?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* `<displayType>.<slot>` for each value the copied config inherited from a
|
|
6
|
+
* session-wide display-type default rather than from the config itself
|
|
7
|
+
*/
|
|
8
|
+
fromDisplayTypeDefaults?: string[];
|
|
3
9
|
setShowRefNames: (show: boolean) => void;
|
|
4
10
|
}
|
|
5
|
-
declare function HeaderButtons({ conf, setShowRefNames }: HeaderButtonsProps): import("react
|
|
11
|
+
declare function HeaderButtons({ conf, hideUris, fromDisplayTypeDefaults, setShowRefNames, }: HeaderButtonsProps): import("react").JSX.Element;
|
|
6
12
|
export default HeaderButtons;
|