@jbrowse/product-core 5.0.0-beta.11 → 5.0.0-beta.13
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/PreferencesConfig.d.ts +0 -5
- package/esm/RootModel/PreferencesConfig.js +0 -11
- package/esm/RootModel/createConfigModel.d.ts +0 -10
- package/esm/RootModel/index.d.ts +1 -1
- package/esm/RootModel/index.js +1 -1
- package/esm/RootModel/menuItems.d.ts +0 -2
- package/esm/RootModel/menuItems.js +0 -18
- package/esm/Session/BaseSession.d.ts +1 -4
- package/esm/Session/BaseSession.js +1 -4
- package/esm/Session/DrawerWidgets.js +23 -14
- package/esm/Session/MultipleViews.d.ts +5 -54
- package/esm/Session/MultipleViews.js +3 -61
- package/esm/Session/Preferences.js +4 -2
- package/esm/Session/SessionTracks.d.ts +14 -14
- package/esm/Session/SessionTracks.js +4 -10
- package/esm/Session/Themes.d.ts +13 -2
- package/esm/Session/Themes.js +23 -5
- package/esm/Session/TrackMenu.d.ts +4 -4
- package/esm/Session/TrackMenuSessionMixin.d.ts +2 -2
- package/esm/Session/Tracks.d.ts +11 -11
- package/esm/Session/Tracks.js +2 -2
- package/esm/Session/copyTrackSnapshot.d.ts +2 -2
- package/esm/Session/index.d.ts +1 -1
- package/esm/Session/index.js +1 -1
- package/esm/Session/pluginExtraTrackItems.d.ts +2 -2
- package/esm/Session/shareableSnapshot.d.ts +3 -19
- package/esm/Session/shareableSnapshot.js +4 -61
- package/esm/index.d.ts +2 -2
- package/esm/index.js +2 -2
- package/esm/sessionUrl.d.ts +0 -4
- package/esm/sessionUrl.js +0 -4
- package/esm/sessionUtils.js +1 -1
- package/esm/ui/AboutDialogContents.js +4 -4
- package/esm/ui/GeneralPreferencesTab.d.ts +1 -0
- package/esm/ui/GeneralPreferencesTab.js +3 -1
- package/esm/ui/ViewPreferencesTab.d.ts +0 -2
- package/esm/ui/ViewPreferencesTab.js +0 -2
- package/esm/ui/aboutTestUtils.d.ts +105 -0
- package/esm/ui/aboutTestUtils.js +15 -1
- package/esm/ui/preferencesReset.d.ts +0 -3
- package/esm/ui/preferencesReset.js +0 -13
- package/esm/ui/util.d.ts +5 -6
- package/esm/ui/util.js +8 -11
- package/package.json +4 -4
package/esm/Session/Themes.js
CHANGED
|
@@ -3,7 +3,7 @@ import { resolvePalette, resolveThemeSelection } from '@jbrowse/core/ui/palette'
|
|
|
3
3
|
import { resolveStyleTheme } from '@jbrowse/core/ui/styleTheme';
|
|
4
4
|
import { createJBrowseThemeFromArgs, defaultThemes, } from '@jbrowse/core/ui/theme';
|
|
5
5
|
import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util';
|
|
6
|
-
import { onColorSchemeChange, prefersDarkColorScheme, } from '@jbrowse/core/util/systemColorScheme';
|
|
6
|
+
import { darkReaderIsDark, onColorSchemeChange, onDarkReaderChange, prefersDarkColorScheme, } from '@jbrowse/core/util/systemColorScheme';
|
|
7
7
|
import { addDisposer, types } from '@jbrowse/mobx-state-tree';
|
|
8
8
|
import { autorun } from 'mobx';
|
|
9
9
|
import { asSession } from '../siblingCast.js';
|
|
@@ -70,6 +70,7 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
70
70
|
.volatile(() => ({
|
|
71
71
|
...storedSelection(),
|
|
72
72
|
systemPrefersDark: prefersDarkColorScheme(),
|
|
73
|
+
darkReaderDark: darkReaderIsDark(),
|
|
73
74
|
}))
|
|
74
75
|
.views(s => {
|
|
75
76
|
const self = asSession(s);
|
|
@@ -101,15 +102,23 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
101
102
|
},
|
|
102
103
|
/**
|
|
103
104
|
* #getter
|
|
104
|
-
* Light or dark,
|
|
105
|
-
* the toolbar's hold
|
|
105
|
+
* Light or dark as the reader chose it, `system` resolved against the
|
|
106
|
+
* OS or the toolbar's hold. What a file leaves the session in, since
|
|
107
|
+
* Dark Reader never touches the file.
|
|
106
108
|
*/
|
|
107
|
-
get
|
|
109
|
+
get selectedThemeMode() {
|
|
108
110
|
return this.themeMode === 'system'
|
|
109
111
|
? (self.systemThemeOverride ??
|
|
110
112
|
(self.systemPrefersDark ? 'dark' : 'light'))
|
|
111
113
|
: this.themeMode;
|
|
112
114
|
},
|
|
115
|
+
/**
|
|
116
|
+
* #getter
|
|
117
|
+
* `selectedThemeMode`, but dark while Dark Reader darkens the page.
|
|
118
|
+
*/
|
|
119
|
+
get effectiveThemeMode() {
|
|
120
|
+
return self.darkReaderDark ? 'dark' : this.selectedThemeMode;
|
|
121
|
+
},
|
|
113
122
|
/**
|
|
114
123
|
* #getter
|
|
115
124
|
* Whether what is drawn right now is dark. Read off the resolved
|
|
@@ -195,7 +204,7 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
195
204
|
const selection = resolveThemeSelection(name ?? this.themeName, undefined, all);
|
|
196
205
|
const themeName = resolveThemeName(all, selection.themeName);
|
|
197
206
|
const theme = all[themeName];
|
|
198
|
-
const mode = theme?.palette?.mode ?? selection.mode ?? this.
|
|
207
|
+
const mode = theme?.palette?.mode ?? selection.mode ?? this.selectedThemeMode;
|
|
199
208
|
if (themeName !== 'default') {
|
|
200
209
|
return { ...theme, palette: { ...theme?.palette, mode } };
|
|
201
210
|
}
|
|
@@ -231,6 +240,12 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
231
240
|
self.systemThemeOverride = undefined;
|
|
232
241
|
}
|
|
233
242
|
},
|
|
243
|
+
/**
|
|
244
|
+
* #action
|
|
245
|
+
*/
|
|
246
|
+
noteDarkReader() {
|
|
247
|
+
self.darkReaderDark = darkReaderIsDark();
|
|
248
|
+
},
|
|
234
249
|
/**
|
|
235
250
|
* #action
|
|
236
251
|
*/
|
|
@@ -273,6 +288,9 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
273
288
|
addDisposer(self, onColorSchemeChange(() => {
|
|
274
289
|
self.setSystemPrefersDark(prefersDarkColorScheme());
|
|
275
290
|
}));
|
|
291
|
+
addDisposer(self, onDarkReaderChange(() => {
|
|
292
|
+
self.noteDarkReader();
|
|
293
|
+
}));
|
|
276
294
|
addDisposer(self, autorun(function themeNameAutorun() {
|
|
277
295
|
// persist the raw selection, not the coerced themeName, so a
|
|
278
296
|
// theme registered later isn't clobbered with 'default'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
2
|
+
import type { AnyConfigurationModel, AnyTrackConfig } from '@jbrowse/core/configuration';
|
|
3
3
|
import type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes';
|
|
4
4
|
import type { MenuItem } from '@jbrowse/core/ui';
|
|
5
5
|
import type { DialogComponentType } from '@jbrowse/core/util';
|
|
@@ -11,7 +11,7 @@ interface TrackActionSession<C> {
|
|
|
11
11
|
expandedDisplayId?: string;
|
|
12
12
|
}) => void;
|
|
13
13
|
publishTrackConf: (conf: C) => unknown;
|
|
14
|
-
deleteTrackConf: (conf:
|
|
14
|
+
deleteTrackConf: (conf: AnyTrackConfig) => void;
|
|
15
15
|
resetTrackConfiguration?: (trackId: string) => void;
|
|
16
16
|
/**
|
|
17
17
|
* Declared here, though only the copy guard below reads it, so a session that
|
|
@@ -41,7 +41,7 @@ export declare function trackActionItems<C extends {
|
|
|
41
41
|
trackId: string;
|
|
42
42
|
}>({ session, config, view, canEdit, isSessionOverride, makeCopy, }: {
|
|
43
43
|
session: TrackActionSession<C>;
|
|
44
|
-
config:
|
|
44
|
+
config: AnyTrackConfig;
|
|
45
45
|
view?: TrackActionView;
|
|
46
46
|
canEdit: boolean;
|
|
47
47
|
isSessionOverride?: boolean;
|
|
@@ -75,7 +75,7 @@ export declare function TrackMenuItemsSessionMixin(pluginManager: PluginManager)
|
|
|
75
75
|
* #method
|
|
76
76
|
* flattened menu items for use in hierarchical track selector
|
|
77
77
|
*/
|
|
78
|
-
getTrackListMenuItems(config:
|
|
78
|
+
getTrackListMenuItems(config: AnyTrackConfig, view?: TrackActionView): MenuItem[];
|
|
79
79
|
/**
|
|
80
80
|
* #method
|
|
81
81
|
* track menu with About + "Track actions" submenu for the in-view label
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
2
|
+
import type { AnyConfigurationModel, AnyTrackConfig } from '@jbrowse/core/configuration';
|
|
3
3
|
import type { MenuItem } from '@jbrowse/core/ui';
|
|
4
4
|
import type { TrackActionView } from '@jbrowse/core/util/types';
|
|
5
5
|
/**
|
|
@@ -16,7 +16,7 @@ export declare function TrackMenuSessionMixin(pluginManager: PluginManager): imp
|
|
|
16
16
|
* #method
|
|
17
17
|
* flattened menu items for use in hierarchical track selector
|
|
18
18
|
*/
|
|
19
|
-
getTrackListMenuItems(config:
|
|
19
|
+
getTrackListMenuItems(config: AnyTrackConfig, view?: TrackActionView): MenuItem[];
|
|
20
20
|
/**
|
|
21
21
|
* #method
|
|
22
22
|
*/
|
package/esm/Session/Tracks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
import type { AnyConfiguration,
|
|
2
|
+
import type { AnyConfiguration, AnyTrackConfig, TrackConfigEntry } from '@jbrowse/core/configuration';
|
|
3
3
|
import type { IAnyStateTreeNode, Instance } from '@jbrowse/mobx-state-tree';
|
|
4
4
|
/**
|
|
5
5
|
* #stateModel TracksManagerSessionMixin
|
|
@@ -376,8 +376,8 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
376
376
|
getRefNameMismatch(adapterCacheKey: string): import("@jbrowse/core/assemblyManager/assembly").RefNameMismatch | undefined;
|
|
377
377
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>) | undefined;
|
|
378
378
|
readonly assemblyNamesList: string[];
|
|
379
|
-
readonly confByName: Map<string, AnyConfigurationModel>;
|
|
380
|
-
readonly assemblyList: AnyConfigurationModel[];
|
|
379
|
+
readonly confByName: Map<string, import("@jbrowse/core/configuration").AnyConfigurationModel>;
|
|
380
|
+
readonly assemblyList: import("@jbrowse/core/configuration").AnyConfigurationModel[];
|
|
381
381
|
readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
|
|
382
382
|
} & {
|
|
383
383
|
settleAssemblyResolution(assemblyName: string): Promise<void>;
|
|
@@ -1031,8 +1031,8 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1031
1031
|
getRefNameMismatch(adapterCacheKey: string): import("@jbrowse/core/assemblyManager/assembly").RefNameMismatch | undefined;
|
|
1032
1032
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>) | undefined;
|
|
1033
1033
|
readonly assemblyNamesList: string[];
|
|
1034
|
-
readonly confByName: Map<string, AnyConfigurationModel>;
|
|
1035
|
-
readonly assemblyList: AnyConfigurationModel[];
|
|
1034
|
+
readonly confByName: Map<string, import("@jbrowse/core/configuration").AnyConfigurationModel>;
|
|
1035
|
+
readonly assemblyList: import("@jbrowse/core/configuration").AnyConfigurationModel[];
|
|
1036
1036
|
readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
|
|
1037
1037
|
} & {
|
|
1038
1038
|
settleAssemblyResolution(assemblyName: string): Promise<void>;
|
|
@@ -1393,17 +1393,17 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1393
1393
|
* Each track's base by trackId: the entry its edits diff against. Here
|
|
1394
1394
|
* the config.json entry, which an edit writes directly.
|
|
1395
1395
|
*/
|
|
1396
|
-
readonly trackBasesById: Map<string,
|
|
1396
|
+
readonly trackBasesById: Map<string, TrackConfigEntry>;
|
|
1397
1397
|
/**
|
|
1398
1398
|
* #method
|
|
1399
1399
|
* A track's base as the session resolves it, its edits applied. Here the
|
|
1400
1400
|
* base itself.
|
|
1401
1401
|
*/
|
|
1402
|
-
withTrackEdits(base:
|
|
1402
|
+
withTrackEdits(base: TrackConfigEntry): TrackConfigEntry;
|
|
1403
1403
|
/**
|
|
1404
1404
|
* #getter
|
|
1405
1405
|
*/
|
|
1406
|
-
readonly tracks:
|
|
1406
|
+
readonly tracks: TrackConfigEntry[];
|
|
1407
1407
|
} & {
|
|
1408
1408
|
afterAttach(): void;
|
|
1409
1409
|
} & {
|
|
@@ -1415,7 +1415,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1415
1415
|
* subscribes only to its own id, so one track's settings edit doesn't
|
|
1416
1416
|
* re-render the others.
|
|
1417
1417
|
*/
|
|
1418
|
-
getTrackById(id: string):
|
|
1418
|
+
getTrackById(id: string): AnyTrackConfig | undefined;
|
|
1419
1419
|
/**
|
|
1420
1420
|
* #method
|
|
1421
1421
|
* Every track config the session can resolve, keyed by trackId.
|
|
@@ -1426,7 +1426,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1426
1426
|
*
|
|
1427
1427
|
* @deprecated
|
|
1428
1428
|
*/
|
|
1429
|
-
getTracksById(): Record<string,
|
|
1429
|
+
getTracksById(): Record<string, AnyTrackConfig>;
|
|
1430
1430
|
} & {
|
|
1431
1431
|
/**
|
|
1432
1432
|
* #action
|
|
@@ -1487,7 +1487,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1487
1487
|
/**
|
|
1488
1488
|
* #action
|
|
1489
1489
|
*/
|
|
1490
|
-
deleteTrackConf(trackConf:
|
|
1490
|
+
deleteTrackConf(trackConf: AnyTrackConfig): any;
|
|
1491
1491
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
|
|
1492
1492
|
/** Session mixin MST type for a session that has tracks */
|
|
1493
1493
|
export type SessionWithTracksType = ReturnType<typeof TracksManagerSessionMixin>;
|
package/esm/Session/Tracks.js
CHANGED
|
@@ -218,8 +218,8 @@ export function TracksManagerSessionMixin(pluginManager) {
|
|
|
218
218
|
updateTrackConfiguration(trackConf) {
|
|
219
219
|
// an opened connection track lives in connectionTrackConfigs, not
|
|
220
220
|
// jbrowse.tracks; persist its edit there (jbrowse.updateTrackConf would
|
|
221
|
-
// no-op, since the track isn't in the config).
|
|
222
|
-
//
|
|
221
|
+
// no-op, since the track isn't in the config). SessionTracks defers a
|
|
222
|
+
// connection track's edit here, so without this branch it is lost on
|
|
223
223
|
// reload.
|
|
224
224
|
if (isSessionWithConnections(self) &&
|
|
225
225
|
trackConf.trackId in self.connectionTrackConfigs) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AnyTrackConfig } from '@jbrowse/core/configuration';
|
|
2
2
|
type TrackCopySnapshot = {
|
|
3
3
|
trackId: string;
|
|
4
4
|
name?: string;
|
|
@@ -15,7 +15,7 @@ type TrackCopySnapshot = {
|
|
|
15
15
|
* `${trackId}-${type}` form baseTrackConfig auto-injects — keeping them unique
|
|
16
16
|
* (displayId is a types.identifier, so a collision would crash MST).
|
|
17
17
|
*/
|
|
18
|
-
export declare function copyTrackSnapshot(config:
|
|
18
|
+
export declare function copyTrackSnapshot(config: AnyTrackConfig, opts: {
|
|
19
19
|
clearCategory: boolean;
|
|
20
20
|
}): TrackCopySnapshot;
|
|
21
21
|
export {};
|
package/esm/Session/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export { SessionTracksManagerSessionMixin } from './SessionTracks.ts';
|
|
|
18
18
|
export type { EditableTrackConfig, PlainTrackConfig, SessionWithSessionTracks, SessionWithSessionTracksType, } from './SessionTracks.ts';
|
|
19
19
|
export { hydratedForms } from './hydratedForms.ts';
|
|
20
20
|
export type { HydratedForms } from './hydratedForms.ts';
|
|
21
|
-
export {
|
|
21
|
+
export { getShareableSessionSnapshot } from './shareableSnapshot.ts';
|
|
22
22
|
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './TrackMenu.ts';
|
|
23
23
|
export { copyTrackSnapshot } from './copyTrackSnapshot.ts';
|
|
24
24
|
export { pluginExtraTrackItems } from './pluginExtraTrackItems.ts';
|
package/esm/Session/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export { PreferencesSessionMixin } from './Preferences.js';
|
|
|
8
8
|
export { BaseSessionModel, isBaseSession, isSession } from './BaseSession.js';
|
|
9
9
|
export { SessionTracksManagerSessionMixin } from './SessionTracks.js';
|
|
10
10
|
export { hydratedForms } from './hydratedForms.js';
|
|
11
|
-
export {
|
|
11
|
+
export { getShareableSessionSnapshot } from './shareableSnapshot.js';
|
|
12
12
|
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './TrackMenu.js';
|
|
13
13
|
export { copyTrackSnapshot } from './copyTrackSnapshot.js';
|
|
14
14
|
export { pluginExtraTrackItems } from './pluginExtraTrackItems.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SessionWithDialog } from './TrackMenu.ts';
|
|
2
2
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AnyTrackConfig } from '@jbrowse/core/configuration';
|
|
4
4
|
import type { MenuItem } from '@jbrowse/core/ui';
|
|
5
5
|
import type { TrackActionView } from '@jbrowse/core/util/types';
|
|
6
6
|
/**
|
|
@@ -8,4 +8,4 @@ import type { TrackActionView } from '@jbrowse/core/util/types';
|
|
|
8
8
|
* both the hierarchical selector and the in-view label menu so plugins reach
|
|
9
9
|
* every track menu consistently
|
|
10
10
|
*/
|
|
11
|
-
export declare function pluginExtraTrackItems(pluginManager: PluginManager, session: SessionWithDialog, config:
|
|
11
|
+
export declare function pluginExtraTrackItems(pluginManager: PluginManager, session: SessionWithDialog, config: AnyTrackConfig, view?: TrackActionView): MenuItem[];
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import type { AbstractSessionModel } from '@jbrowse/core/util';
|
|
2
2
|
/**
|
|
3
|
-
* The session snapshot to hand to anyone else
|
|
4
|
-
* `session.json
|
|
5
|
-
*
|
|
6
|
-
* outgoing snapshot (see `bakeSessionCascades`), and three of the four
|
|
7
|
-
* boundaries were spelling the two steps out identically.
|
|
8
|
-
*
|
|
9
|
-
* The fourth (desktop `ExportToWebDialog`) bakes a *transformed* snapshot from
|
|
10
|
-
* `planWebExport`, so it calls `bakeSessionCascades` directly.
|
|
3
|
+
* The session snapshot to hand to anyone else: a share link, an exported
|
|
4
|
+
* `session.json`. The one place an outgoing snapshot is taken, so anything the
|
|
5
|
+
* live session resolves against state that stays behind has a place to go.
|
|
11
6
|
*/
|
|
12
7
|
export declare function getShareableSessionSnapshot(session: AbstractSessionModel): Record<string, unknown>;
|
|
13
|
-
/**
|
|
14
|
-
* Everything an outgoing snapshot has to resolve because the live session
|
|
15
|
-
* resolves it at read time against state that is staying behind — currently the
|
|
16
|
-
* workspaces intent alone.
|
|
17
|
-
*
|
|
18
|
-
* It keeps its own entry point rather than being inlined into the one caller
|
|
19
|
-
* because the failure of a boundary that performs half of them is invisible at
|
|
20
|
-
* that boundary: the export succeeds, and what is missing only shows up on
|
|
21
|
-
* someone else's screen.
|
|
22
|
-
*/
|
|
23
|
-
export declare function bakeSessionCascades(session: AbstractSessionModel, snapshot: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -1,66 +1,9 @@
|
|
|
1
1
|
import { getSnapshot } from '@jbrowse/mobx-state-tree';
|
|
2
2
|
/**
|
|
3
|
-
* The session snapshot to hand to anyone else
|
|
4
|
-
* `session.json
|
|
5
|
-
*
|
|
6
|
-
* outgoing snapshot (see `bakeSessionCascades`), and three of the four
|
|
7
|
-
* boundaries were spelling the two steps out identically.
|
|
8
|
-
*
|
|
9
|
-
* The fourth (desktop `ExportToWebDialog`) bakes a *transformed* snapshot from
|
|
10
|
-
* `planWebExport`, so it calls `bakeSessionCascades` directly.
|
|
3
|
+
* The session snapshot to hand to anyone else: a share link, an exported
|
|
4
|
+
* `session.json`. The one place an outgoing snapshot is taken, so anything the
|
|
5
|
+
* live session resolves against state that stays behind has a place to go.
|
|
11
6
|
*/
|
|
12
7
|
export function getShareableSessionSnapshot(session) {
|
|
13
|
-
return
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Everything an outgoing snapshot has to resolve because the live session
|
|
17
|
-
* resolves it at read time against state that is staying behind — currently the
|
|
18
|
-
* workspaces intent alone.
|
|
19
|
-
*
|
|
20
|
-
* It keeps its own entry point rather than being inlined into the one caller
|
|
21
|
-
* because the failure of a boundary that performs half of them is invisible at
|
|
22
|
-
* that boundary: the export succeeds, and what is missing only shows up on
|
|
23
|
-
* someone else's screen.
|
|
24
|
-
*/
|
|
25
|
-
export function bakeSessionCascades(session, snapshot) {
|
|
26
|
-
const snap = structuredClone(snapshot);
|
|
27
|
-
bakeWorkspacesIntent(session, snap);
|
|
28
|
-
return snap;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* The workspaces cascade: session property -> user preference -> admin
|
|
32
|
-
* `configuration.preferences.useWorkspaces`, of which only the first is in the
|
|
33
|
-
* snapshot.
|
|
34
|
-
*
|
|
35
|
-
* So a sender whose workspace is on because *their admin turned it on* exports
|
|
36
|
-
* a fully arranged `layout` with no statement that it is a workspace at all,
|
|
37
|
-
* and a recipient resolving their own cascade to false renders the classic
|
|
38
|
-
* stack: the arrangement arrives intact and invisible, with nothing to say it
|
|
39
|
-
* was dropped.
|
|
40
|
-
*
|
|
41
|
-
* Only the on case is baked. At `false` there is no arrangement to carry, so
|
|
42
|
-
* stamping it would be a sender with nothing to say overriding a recipient who
|
|
43
|
-
* prefers workspaces.
|
|
44
|
-
*
|
|
45
|
-
* The paths that build a layout through an explicit user intent already set the
|
|
46
|
-
* property themselves (`setUseWorkspacesPreference`, ViewMenu's move-view-out,
|
|
47
|
-
* a spec `layout`), which is exactly what hides this: every arrangement made by
|
|
48
|
-
* a *drag* — split a cell, drag a tab into it, open a new tab — goes through
|
|
49
|
-
* `WorkspaceLayoutMixin` alone, which owns the tree and knows nothing about the
|
|
50
|
-
* preference.
|
|
51
|
-
*
|
|
52
|
-
* `effectiveUseWorkspaces` is read behind an `in` guard because
|
|
53
|
-
* `AbstractSessionModel` cannot name it (it lives on MultipleViewsSessionMixin,
|
|
54
|
-
* one layer up), so renaming that getter silently stops the bake rather than
|
|
55
|
-
* failing to compile — the hazard app-core/src/WorkspaceLayout/CLAUDE.md describes for
|
|
56
|
-
* `setPendingMove`. jbrowse-web's `sessionModel/exportLayout.test.ts` is the
|
|
57
|
-
* canary, since the bake needs a real session to have a cascade at all.
|
|
58
|
-
*/
|
|
59
|
-
function bakeWorkspacesIntent(session, snap) {
|
|
60
|
-
if (snap.useWorkspaces === undefined &&
|
|
61
|
-
'effectiveUseWorkspaces' in session &&
|
|
62
|
-
session.effectiveUseWorkspaces ===
|
|
63
|
-
true) {
|
|
64
|
-
snap.useWorkspaces = true;
|
|
65
|
-
}
|
|
8
|
+
return structuredClone(getSnapshot(session));
|
|
66
9
|
}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type { AssertExtends, AssertNotAny } from './assertExtends.ts';
|
|
2
2
|
export { asRoot, asSession } from './siblingCast.ts';
|
|
3
3
|
export { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
4
|
-
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem,
|
|
4
|
+
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem, } from './RootModel/index.ts';
|
|
5
5
|
export type { BaseRootModel, BaseRootModelType, RootConfigurationSnapshot, RootModelWithInternetAccounts, RootModelWithInternetAccountsType, } from './RootModel/index.ts';
|
|
6
|
-
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem,
|
|
6
|
+
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem, getShareableSessionSnapshot, copyTrackSnapshot, finalizeSession, hydratedForms, isBaseSession, isSession, isSessionWithConnections, isSessionWithDrawerWidgets, isSessionWithMultipleViews, isSessionWithReferenceManagement, isSessionWithThemes, isSessionWithTracks, pluginExtraTrackItems, storedThemeArgs, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './Session/index.ts';
|
|
7
7
|
export type { AssertSessionModel, BaseSession, BaseSessionType, ConnectionTrackConfigEntry, EditableTrackConfig, HydratedForms, PlainTrackConfig, ReferringNode, SessionWithConnections, SessionWithConnectionsType, SessionWithDrawerWidgets, SessionWithDrawerWidgetsType, SessionWithMultipleViews, SessionWithMultipleViewsType, SessionWithReferenceManagement, SessionWithReferenceManagementType, SessionWithSessionTracks, SessionWithSessionTracksType, SessionWithThemes, SessionWithThemesType, SessionWithTracks, SessionWithTracksType, ThemeModeSelection, } from './Session/index.ts';
|
|
8
8
|
export { AboutDialog, AppReadyMarker, Drawer, DrawerControls, DrawerHeader, DrawerWidget, DrawerWidgetSelector, ModalWidget, ModalWidgetAppBar, PreferencesDialog, WidgetBody, WidgetHeading, drawerGridTemplateColumns, } from './ui/index.ts';
|
|
9
9
|
export type { AboutPanelProps, PreferencesDialogSession, PreferencesPanelDescriptor, } from './ui/index.ts';
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { asRoot, asSession } from './siblingCast.js';
|
|
2
2
|
export { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
3
|
-
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem,
|
|
4
|
-
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem,
|
|
3
|
+
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem, } from './RootModel/index.js';
|
|
4
|
+
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem, getShareableSessionSnapshot, copyTrackSnapshot, finalizeSession, hydratedForms, isBaseSession, isSession, isSessionWithConnections, isSessionWithDrawerWidgets, isSessionWithMultipleViews, isSessionWithReferenceManagement, isSessionWithThemes, isSessionWithTracks, pluginExtraTrackItems, storedThemeArgs, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './Session/index.js';
|
|
5
5
|
export { AboutDialog, AppReadyMarker, Drawer, DrawerControls, DrawerHeader, DrawerWidget, DrawerWidgetSelector, ModalWidget, ModalWidgetAppBar, PreferencesDialog, WidgetBody, WidgetHeading, drawerGridTemplateColumns, } from './ui/index.js';
|
|
6
6
|
export { initializeWorker } from './rpcWorker.js';
|
|
7
7
|
export { toPluginLoadRecord } from './pluginInput.js';
|
package/esm/sessionUrl.d.ts
CHANGED
|
@@ -12,10 +12,6 @@ export interface SessionSnapshot {
|
|
|
12
12
|
* hash fragment. Deflated then base64url-encoded, so it survives a URL intact
|
|
13
13
|
* and stays far smaller than raw JSON.
|
|
14
14
|
*
|
|
15
|
-
* Not a plain `getSnapshot`: a workspace arrangement turned on by the sender's
|
|
16
|
-
* preference is not in the snapshot, so a raw one renders as a classic stack
|
|
17
|
-
* for whoever opens the link. `getShareableSessionSnapshot` stamps it first.
|
|
18
|
-
*
|
|
19
15
|
* The session travels but the config does not — the receiving app supplies its
|
|
20
16
|
* own assembly/tracks. Put the result somewhere the server never sees (the hash
|
|
21
17
|
* fragment) if it may be long: a query string can exceed the request-line limit
|
package/esm/sessionUrl.js
CHANGED
|
@@ -5,10 +5,6 @@ import { getShareableSessionSnapshot } from './Session/shareableSnapshot.js';
|
|
|
5
5
|
* hash fragment. Deflated then base64url-encoded, so it survives a URL intact
|
|
6
6
|
* and stays far smaller than raw JSON.
|
|
7
7
|
*
|
|
8
|
-
* Not a plain `getSnapshot`: a workspace arrangement turned on by the sender's
|
|
9
|
-
* preference is not in the snapshot, so a raw one renders as a classic stack
|
|
10
|
-
* for whoever opens the link. `getShareableSessionSnapshot` stamps it first.
|
|
11
|
-
*
|
|
12
8
|
* The session travels but the config does not — the receiving app supplies its
|
|
13
9
|
* own assembly/tracks. Put the result somewhere the server never sees (the hash
|
|
14
10
|
* fragment) if it may be long: a query string can exceed the request-line limit
|
package/esm/sessionUtils.js
CHANGED
|
@@ -312,7 +312,7 @@ function nonPortableUserTracks(report, droppable) {
|
|
|
312
312
|
// place, keeping the base trackId, and persists the whole config). So a track the
|
|
313
313
|
// hub itself changed since then also lands in `editDeltas`, pinning the recipient
|
|
314
314
|
// to the values the sender is looking at. That is the export's stated intent —
|
|
315
|
-
// reproduce the sender's screen
|
|
315
|
+
// reproduce the sender's screen —
|
|
316
316
|
// but the delta channel it travels in means "user override" on the far side, and
|
|
317
317
|
// a delta masks later admin changes to that track. Telling the two apart needs
|
|
318
318
|
// the base as it was at session creation, which nothing persists.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import Attributes from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/Attributes';
|
|
3
|
+
import Attributes, { hasAttributeRows, withoutLocations, } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/Attributes';
|
|
4
4
|
import BaseCard from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard';
|
|
5
|
-
import { readConfObject } from '@jbrowse/core/configuration';
|
|
6
5
|
import PluggableComponents from '@jbrowse/core/ui/PluggableComponents';
|
|
7
6
|
import { getEnv } from '@jbrowse/core/util';
|
|
8
7
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
@@ -24,8 +23,9 @@ const AboutDialogContents = observer(function AboutDialogContents({ config, sess
|
|
|
24
23
|
const { classes } = useStyles();
|
|
25
24
|
const [showRefNames, setShowRefNames] = useState(false);
|
|
26
25
|
const { pluginManager } = getEnv(session);
|
|
27
|
-
const { config: shown, hideUris } = getAboutDialogConfig({ config, session });
|
|
28
|
-
|
|
26
|
+
const { conf, config: shown, advanced, hideUris, } = getAboutDialogConfig({ config, session });
|
|
27
|
+
const advancedShown = hideUris ? withoutLocations(advanced) : advanced;
|
|
28
|
+
return (_jsxs("div", { className: classes.content, children: [_jsxs(BaseCard, { title: "Configuration", children: [_jsx(HeaderButtons, { conf: conf, hideUris: hideUris, setShowRefNames: setShowRefNames }), _jsx(Attributes, { attributes: shown, omit: [...hideFields, 'metadata'], hideUris: hideUris })] }), hasAttributeRows(advancedShown, hideFields) ? (_jsx(BaseCard, { title: "Advanced", defaultExpanded: false, children: _jsx(Attributes, { attributes: advancedShown, omit: hideFields }) })) : null, shown.metadata ? (_jsx(BaseCard, { title: "Metadata", children: _jsx(Attributes, { attributes: omitTrackDescription(shown.metadata), hideUris: hideUris }) })) : null, _jsx(DescriptionPanel, { config: config, session: session }), _jsx(AssemblyInfoPanel, { config: config, session: session, hideUris: hideUris }), _jsx(PluggableComponents, { pluginManager: pluginManager,
|
|
29
29
|
/** #extensionPoint Core-extraAboutPanel | sync | Add extra panels to a track's About dialog */
|
|
30
30
|
name: "Core-extraAboutPanel", props: { session, config } }), hideUris ? null : _jsx(FileInfoPanel, { config: config, session: session }), showRefNames ? (_jsx(RefNameInfoDialog, { session: session, config: config, onClose: () => {
|
|
31
31
|
setShowRefNames(false);
|
|
@@ -7,6 +7,7 @@ export interface GeneralPreferencesSession {
|
|
|
7
7
|
setThemeName: (arg: string) => void;
|
|
8
8
|
themeMode: ThemeModeSelection;
|
|
9
9
|
setThemeMode: (arg: ThemeModeSelection) => void;
|
|
10
|
+
darkReaderDark?: boolean;
|
|
10
11
|
animationMode: AnimationMode;
|
|
11
12
|
numberGrouping: boolean;
|
|
12
13
|
setPreferenceOverride: (key: string, value: unknown) => void;
|
|
@@ -23,7 +23,9 @@ const GeneralPreferencesTab = observer(function GeneralPreferencesTab({ session,
|
|
|
23
23
|
const { classes } = useStyles();
|
|
24
24
|
return (_jsxs(_Fragment, { children: [_jsx(TextField, { select: true, variant: "outlined", className: classes.field, label: "Theme", value: session.themeName, onChange: event => {
|
|
25
25
|
session.setThemeName(event.target.value);
|
|
26
|
-
}, children: Object.entries(session.allThemes()).map(([key, val]) => (_jsx(MenuItem, { value: key, children: val.name || '(Unknown name)' }, key))) }), _jsx(TextField, { select: true, variant: "outlined", className: classes.field, label: "Light/dark", value: session.themeMode,
|
|
26
|
+
}, children: Object.entries(session.allThemes()).map(([key, val]) => (_jsx(MenuItem, { value: key, children: val.name || '(Unknown name)' }, key))) }), _jsx(TextField, { select: true, variant: "outlined", className: classes.field, label: "Light/dark", value: session.themeMode, helperText: session.darkReaderDark
|
|
27
|
+
? 'Dark while Dark Reader darkens this page'
|
|
28
|
+
: undefined, onChange: event => {
|
|
27
29
|
session.setThemeMode(event.target.value);
|
|
28
30
|
}, children: THEME_MODES.map(opt => (_jsx(MenuItem, { value: opt.value, children: opt.label }, opt.value))) }), _jsx(TextField, { select: true, variant: "outlined", className: classes.field, label: "Animations", value: session.animationMode, onChange: event => {
|
|
29
31
|
session.setPreferenceOverride('animationMode', event.target.value);
|
|
@@ -3,8 +3,6 @@ export interface ViewPreferencesSession {
|
|
|
3
3
|
setScrollZoom: (flag: boolean) => void;
|
|
4
4
|
stickyViewHeaders: boolean;
|
|
5
5
|
setStickyViewHeaders: (sticky: boolean) => void;
|
|
6
|
-
effectiveUseWorkspaces: boolean;
|
|
7
|
-
setUseWorkspacesPreference: (useWorkspaces: boolean) => void;
|
|
8
6
|
}
|
|
9
7
|
declare const ViewPreferencesTab: ({ session, }: {
|
|
10
8
|
session: ViewPreferencesSession;
|
|
@@ -8,8 +8,6 @@ const ViewPreferencesTab = observer(function ViewPreferencesTab({ session, }) {
|
|
|
8
8
|
session.setScrollZoom(checked);
|
|
9
9
|
} }), _jsx(PreferenceCheckbox, { checked: session.stickyViewHeaders, label: "Keep view header visible", help: "The view header stays at the top of the page while its tracks scroll under it.", onChange: checked => {
|
|
10
10
|
session.setStickyViewHeaders(checked);
|
|
11
|
-
} }), _jsx(PreferenceCheckbox, { checked: session.effectiveUseWorkspaces, label: "Use workspaces", help: "Views open as tabs and tiles instead of stacking down the page.", onChange: checked => {
|
|
12
|
-
session.setUseWorkspacesPreference(checked);
|
|
13
11
|
} })] }));
|
|
14
12
|
});
|
|
15
13
|
export default ViewPreferencesTab;
|