@jbrowse/product-core 5.0.0-beta.2 → 5.0.0-beta.3
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.js +1 -1
- package/esm/Session/BaseSession.d.ts +9 -26
- package/esm/Session/BaseSession.js +10 -59
- package/esm/Session/MultipleViews.d.ts +0 -1
- package/esm/Session/MultipleViews.js +1 -2
- package/esm/Session/Preferences.d.ts +0 -1
- package/esm/Session/SessionTracks.d.ts +2 -1
- package/esm/Session/Tracks.d.ts +2 -5
- package/esm/Session/Tracks.js +103 -103
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/pruneUnbuildableNodes.js +5 -2
- package/esm/ui/AboutDialogContents.js +2 -1
- package/esm/ui/DescriptionPanel.d.ts +3 -0
- package/esm/ui/DescriptionPanel.js +24 -0
- package/esm/ui/DisplayDefaultsSection.d.ts +7 -20
- package/esm/ui/DisplayDefaultsSection.js +8 -46
- package/esm/ui/GeneralPreferencesTab.d.ts +14 -0
- package/esm/ui/GeneralPreferencesTab.js +27 -0
- package/esm/ui/PreferenceCheckbox.d.ts +6 -0
- package/esm/ui/PreferenceCheckbox.js +16 -0
- package/esm/ui/PreferencesDialog.d.ts +6 -27
- package/esm/ui/PreferencesDialog.js +38 -119
- package/esm/ui/ViewPreferencesTab.d.ts +12 -0
- package/esm/ui/ViewPreferencesTab.js +15 -0
- package/esm/ui/descriptionHtml.d.ts +26 -0
- package/esm/ui/descriptionHtml.js +66 -0
- package/esm/ui/displayDefaultChanges.d.ts +31 -0
- package/esm/ui/displayDefaultChanges.js +66 -0
- package/esm/ui/preferencesReset.d.ts +18 -0
- package/esm/ui/preferencesReset.js +64 -0
- package/package.json +3 -3
- package/esm/scheduleDetachedDestroy.d.ts +0 -18
- package/esm/scheduleDetachedDestroy.js +0 -24
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager';
|
|
2
2
|
import assemblyManagerFactory from '@jbrowse/core/assemblyManager';
|
|
3
3
|
import RpcManager from '@jbrowse/core/rpc/RpcManager';
|
|
4
|
+
import { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
4
5
|
import { cast, detach, getType, isStateTreeNode, types, } from '@jbrowse/mobx-state-tree';
|
|
5
6
|
import { describeUnbuildableNodes, pruneUnbuildableNodes, } from '../pruneUnbuildableNodes.js';
|
|
6
|
-
import { scheduleDetachedDestroy } from '../scheduleDetachedDestroy.js';
|
|
7
7
|
import { migrateSessionSnapshot } from '../sessionMigrations/index.js';
|
|
8
8
|
import { filterSessionInPlace } from '../sessionUtils.js';
|
|
9
9
|
// `session` is a `types.maybe(sessionModelType)` where `sessionModelType` is the
|
|
@@ -162,11 +162,8 @@ export declare function BaseSessionModel<ROOT_MODEL_TYPE extends BaseRootModelTy
|
|
|
162
162
|
* `{ displayType, slot, value }` — the inventory the Preferences dialog
|
|
163
163
|
* lists and clears one at a time (`setDisplayTypeDefault(…, undefined)`).
|
|
164
164
|
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* recognized these rows by matching the path head is exactly the coupling
|
|
168
|
-
* `DISPLAY_TYPE_DEFAULTS_PATH_HEAD` stopped being exported over, where a
|
|
169
|
-
* rename on one side alone silently no-ops the other.
|
|
165
|
+
* Parsed here rather than by the dialog, because the composite-key
|
|
166
|
+
* layout is this file's and nothing outside it should depend on it.
|
|
170
167
|
*/
|
|
171
168
|
getDisplayTypeDefaults(): {
|
|
172
169
|
displayType: string;
|
|
@@ -175,14 +172,13 @@ export declare function BaseSessionModel<ROOT_MODEL_TYPE extends BaseRootModelTy
|
|
|
175
172
|
}[];
|
|
176
173
|
/**
|
|
177
174
|
* #method
|
|
178
|
-
* every
|
|
179
|
-
* config/admin default, as `{ path, from, to }` rows
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* state, so `from` reads "(default)".
|
|
175
|
+
* every scalar preference override that currently differs from its
|
|
176
|
+
* config/admin default, as `{ path, from, to }` rows whose path is the
|
|
177
|
+
* override's own key. A scalar pref (animationMode, scrollZoom) whose
|
|
178
|
+
* override equals the default is omitted, since reverting it is a no-op.
|
|
179
|
+
* Promoted display-type defaults share the map but are not here: they
|
|
180
|
+
* are `getDisplayTypeDefaults`, and the Preferences dialog lists them
|
|
181
|
+
* through one builder on both of its surfaces.
|
|
186
182
|
*/
|
|
187
183
|
getPreferenceChanges(): TrackConfigChange[];
|
|
188
184
|
} & {
|
|
@@ -261,19 +257,6 @@ export declare function BaseSessionModel<ROOT_MODEL_TYPE extends BaseRootModelTy
|
|
|
261
257
|
* Preferences dialog "Reset to defaults" confirmation.
|
|
262
258
|
*/
|
|
263
259
|
clearPreferenceOverride(key: string): void;
|
|
264
|
-
/**
|
|
265
|
-
* #action
|
|
266
|
-
* revert one row emitted by `getPreferenceChanges`, addressed by its
|
|
267
|
-
* display `path`. Backs the per-entry reset in the Preferences dialog's
|
|
268
|
-
* "Reset to defaults" confirmation.
|
|
269
|
-
*
|
|
270
|
-
* Lives here rather than in that dialog because this model owns both path
|
|
271
|
-
* shapes it has to undo: a promoted per-display-type default, whose row
|
|
272
|
-
* path is a readable label over a flat composite storage key, and every
|
|
273
|
-
* other override, whose path *is* its key. The dialog used to re-derive
|
|
274
|
-
* the first case from an exported path-head constant.
|
|
275
|
-
*/
|
|
276
|
-
resetPreferenceChange(path: string[]): void;
|
|
277
260
|
/**
|
|
278
261
|
* #action
|
|
279
262
|
* set the global scroll-to-zoom preference (see the `scrollZoom` getter)
|
|
@@ -39,18 +39,6 @@ function parseDisplayTypeDefaultKey(key) {
|
|
|
39
39
|
const [displayType, slot] = rest.split('\0');
|
|
40
40
|
return displayType && slot ? { displayType, slot } : undefined;
|
|
41
41
|
}
|
|
42
|
-
// Head of the display path a promoted default takes in a `getPreferenceChanges`
|
|
43
|
-
// row: `[DISPLAY_TYPE_DEFAULTS_PATH_HEAD, displayType, slot]`. Purely a
|
|
44
|
-
// readable row label, deliberately distinct from the flat
|
|
45
|
-
// `DISPLAY_TYPE_DEFAULT_PREFIX` storage key above.
|
|
46
|
-
//
|
|
47
|
-
// Module-private, like the storage key: both the producer
|
|
48
|
-
// (`getPreferenceChanges`) and the consumer (`resetPreferenceChange`) are
|
|
49
|
-
// methods on this model, so the two path shapes this file emits are the only
|
|
50
|
-
// ones it has to undo. It used to be exported for the Preferences dialog to
|
|
51
|
-
// match on and re-route back through `setDisplayTypeDefault`, which meant a
|
|
52
|
-
// rename on one side alone would silently no-op that dialog's per-row reset.
|
|
53
|
-
const DISPLAY_TYPE_DEFAULTS_PATH_HEAD = 'displayTypeDefaults';
|
|
54
42
|
/**
|
|
55
43
|
* #stateModel BaseSessionModel
|
|
56
44
|
*
|
|
@@ -245,11 +233,8 @@ export function BaseSessionModel(_pluginManager) {
|
|
|
245
233
|
* `{ displayType, slot, value }` — the inventory the Preferences dialog
|
|
246
234
|
* lists and clears one at a time (`setDisplayTypeDefault(…, undefined)`).
|
|
247
235
|
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* recognized these rows by matching the path head is exactly the coupling
|
|
251
|
-
* `DISPLAY_TYPE_DEFAULTS_PATH_HEAD` stopped being exported over, where a
|
|
252
|
-
* rename on one side alone silently no-ops the other.
|
|
236
|
+
* Parsed here rather than by the dialog, because the composite-key
|
|
237
|
+
* layout is this file's and nothing outside it should depend on it.
|
|
253
238
|
*/
|
|
254
239
|
getDisplayTypeDefaults() {
|
|
255
240
|
const found = [];
|
|
@@ -263,31 +248,18 @@ export function BaseSessionModel(_pluginManager) {
|
|
|
263
248
|
},
|
|
264
249
|
/**
|
|
265
250
|
* #method
|
|
266
|
-
* every
|
|
267
|
-
* config/admin default, as `{ path, from, to }` rows
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* state, so `from` reads "(default)".
|
|
251
|
+
* every scalar preference override that currently differs from its
|
|
252
|
+
* config/admin default, as `{ path, from, to }` rows whose path is the
|
|
253
|
+
* override's own key. A scalar pref (animationMode, scrollZoom) whose
|
|
254
|
+
* override equals the default is omitted, since reverting it is a no-op.
|
|
255
|
+
* Promoted display-type defaults share the map but are not here: they
|
|
256
|
+
* are `getDisplayTypeDefaults`, and the Preferences dialog lists them
|
|
257
|
+
* through one builder on both of its surfaces.
|
|
274
258
|
*/
|
|
275
259
|
getPreferenceChanges() {
|
|
276
260
|
const changes = [];
|
|
277
261
|
for (const [key, value] of self.preferencesOverrides.entries()) {
|
|
278
|
-
|
|
279
|
-
if (dtd) {
|
|
280
|
-
changes.push({
|
|
281
|
-
path: [
|
|
282
|
-
DISPLAY_TYPE_DEFAULTS_PATH_HEAD,
|
|
283
|
-
dtd.displayType,
|
|
284
|
-
dtd.slot,
|
|
285
|
-
],
|
|
286
|
-
from: undefined,
|
|
287
|
-
to: value,
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
262
|
+
if (!key.startsWith(DISPLAY_TYPE_DEFAULT_PREFIX)) {
|
|
291
263
|
const dflt = this.getPreferenceDefault(key);
|
|
292
264
|
if (value !== dflt) {
|
|
293
265
|
changes.push({
|
|
@@ -418,27 +390,6 @@ export function BaseSessionModel(_pluginManager) {
|
|
|
418
390
|
clearPreferenceOverride(key) {
|
|
419
391
|
self.preferencesOverrides.delete(key);
|
|
420
392
|
},
|
|
421
|
-
/**
|
|
422
|
-
* #action
|
|
423
|
-
* revert one row emitted by `getPreferenceChanges`, addressed by its
|
|
424
|
-
* display `path`. Backs the per-entry reset in the Preferences dialog's
|
|
425
|
-
* "Reset to defaults" confirmation.
|
|
426
|
-
*
|
|
427
|
-
* Lives here rather than in that dialog because this model owns both path
|
|
428
|
-
* shapes it has to undo: a promoted per-display-type default, whose row
|
|
429
|
-
* path is a readable label over a flat composite storage key, and every
|
|
430
|
-
* other override, whose path *is* its key. The dialog used to re-derive
|
|
431
|
-
* the first case from an exported path-head constant.
|
|
432
|
-
*/
|
|
433
|
-
resetPreferenceChange(path) {
|
|
434
|
-
const [head, displayType, slot] = path;
|
|
435
|
-
if (head === DISPLAY_TYPE_DEFAULTS_PATH_HEAD && displayType && slot) {
|
|
436
|
-
this.setDisplayTypeDefault(displayType, slot, undefined);
|
|
437
|
-
}
|
|
438
|
-
else if (head) {
|
|
439
|
-
this.clearPreferenceOverride(head);
|
|
440
|
-
}
|
|
441
|
-
},
|
|
442
393
|
/**
|
|
443
394
|
* #action
|
|
444
395
|
* set the global scroll-to-zoom preference (see the `scrollZoom` getter)
|
|
@@ -1660,7 +1660,6 @@ export declare function MultipleViewsSessionMixin(pluginManager: PluginManager):
|
|
|
1660
1660
|
setPreferenceOverride(key: string, value: unknown): void;
|
|
1661
1661
|
clearPreferenceOverrides(): void;
|
|
1662
1662
|
clearPreferenceOverride(key: string): void;
|
|
1663
|
-
resetPreferenceChange(path: string[]): void;
|
|
1664
1663
|
setScrollZoom(flag: boolean): void;
|
|
1665
1664
|
setDisplayTypeDefault(displayType: string, slot: string, value: unknown): void;
|
|
1666
1665
|
setName(str: string): void;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { applyOrderWithin, localStorageGetBoolean, localStorageSetBoolean, reorderWithin, } from '@jbrowse/core/util';
|
|
1
|
+
import { applyOrderWithin, localStorageGetBoolean, localStorageSetBoolean, reorderWithin, scheduleDetachedDestroy, } from '@jbrowse/core/util';
|
|
2
2
|
import { addDisposer, applyPatch, cast, detach, getMembers, getParent, hasParent, isReferenceType, isStateTreeNode, types, } from '@jbrowse/mobx-state-tree';
|
|
3
3
|
import { autorun } from 'mobx';
|
|
4
|
-
import { scheduleDetachedDestroy } from '../scheduleDetachedDestroy.js';
|
|
5
4
|
import { BaseSessionModel, isBaseSession } from './BaseSession.js';
|
|
6
5
|
import { DrawerWidgetSessionMixin } from './DrawerWidgets.js';
|
|
7
6
|
// Whether `node` IS `view` or lives somewhere under it. A view can CONTAIN
|
|
@@ -1641,7 +1641,6 @@ export declare function PreferencesSessionMixin(pluginManager: PluginManager): i
|
|
|
1641
1641
|
setPreferenceOverride(key: string, value: unknown): void;
|
|
1642
1642
|
clearPreferenceOverrides(): void;
|
|
1643
1643
|
clearPreferenceOverride(key: string): void;
|
|
1644
|
-
resetPreferenceChange(path: string[]): void;
|
|
1645
1644
|
setScrollZoom(flag: boolean): void;
|
|
1646
1645
|
setDisplayTypeDefault(displayType: string, slot: string, value: unknown): void;
|
|
1647
1646
|
setName(str: string): void;
|
|
@@ -1670,7 +1670,6 @@ export declare function SessionTracksManagerSessionMixin(pluginManager: PluginMa
|
|
|
1670
1670
|
setPreferenceOverride(key: string, value: unknown): void;
|
|
1671
1671
|
clearPreferenceOverrides(): void;
|
|
1672
1672
|
clearPreferenceOverride(key: string): void;
|
|
1673
|
-
resetPreferenceChange(path: string[]): void;
|
|
1674
1673
|
setScrollZoom(flag: boolean): void;
|
|
1675
1674
|
setDisplayTypeDefault(displayType: string, slot: string, value: unknown): void;
|
|
1676
1675
|
setName(str: string): void;
|
|
@@ -1702,6 +1701,8 @@ export declare function SessionTracksManagerSessionMixin(pluginManager: PluginMa
|
|
|
1702
1701
|
} & {
|
|
1703
1702
|
getTrackById(id: string): AnyConfigurationModel | undefined;
|
|
1704
1703
|
getTracksById(): Record<string, AnyConfigurationModel>;
|
|
1704
|
+
} & {
|
|
1705
|
+
afterAttach(): void;
|
|
1705
1706
|
} & {
|
|
1706
1707
|
addSessionTrackConf(trackConf: AnyConfiguration): any;
|
|
1707
1708
|
publishTrackConf(trackConf: AnyConfiguration): any;
|
package/esm/Session/Tracks.d.ts
CHANGED
|
@@ -1638,7 +1638,6 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1638
1638
|
setPreferenceOverride(key: string, value: unknown): void;
|
|
1639
1639
|
clearPreferenceOverrides(): void;
|
|
1640
1640
|
clearPreferenceOverride(key: string): void;
|
|
1641
|
-
resetPreferenceChange(path: string[]): void;
|
|
1642
1641
|
setScrollZoom(flag: boolean): void;
|
|
1643
1642
|
setDisplayTypeDefault(displayType: string, slot: string, value: unknown): void;
|
|
1644
1643
|
setName(str: string): void;
|
|
@@ -1691,6 +1690,8 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1691
1690
|
* @deprecated
|
|
1692
1691
|
*/
|
|
1693
1692
|
getTracksById(): Record<string, AnyConfigurationModel>;
|
|
1693
|
+
} & {
|
|
1694
|
+
afterAttach(): void;
|
|
1694
1695
|
} & {
|
|
1695
1696
|
/**
|
|
1696
1697
|
* #action
|
|
@@ -1736,10 +1737,6 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1736
1737
|
* session, which is the destination every such caller wanted: a track a
|
|
1737
1738
|
* plugin stands up for one user is not a catalog entry. Nothing in tree
|
|
1738
1739
|
* may call it — `no-restricted-syntax` says so.
|
|
1739
|
-
*
|
|
1740
|
-
* Spelled out rather than delegating through `this`, for the reason
|
|
1741
|
-
* `SessionTracks.addToSession` is a plain closure: an action whose return
|
|
1742
|
-
* type is inferred from a sibling's makes the pair circular.
|
|
1743
1740
|
*/
|
|
1744
1741
|
addTrackConf(trackConf: AnyConfiguration): any;
|
|
1745
1742
|
/**
|
package/esm/Session/Tracks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { expandLooseTrackConfig } from '@jbrowse/core/util/tracks';
|
|
2
|
-
import { types } from '@jbrowse/mobx-state-tree';
|
|
3
|
-
import { computed } from 'mobx';
|
|
2
|
+
import { addDisposer, types } from '@jbrowse/mobx-state-tree';
|
|
3
|
+
import { autorun, computed } from 'mobx';
|
|
4
4
|
import { BaseSessionModel, isBaseSession } from './BaseSession.js';
|
|
5
5
|
import { isSessionWithConnections } from './Connections.js';
|
|
6
6
|
import { ReferenceManagementSessionMixin } from './ReferenceManagement.js';
|
|
@@ -24,16 +24,11 @@ export function TracksManagerSessionMixin(pluginManager) {
|
|
|
24
24
|
// One index trackId → config for all tracks, assembly sequences, and
|
|
25
25
|
// connection tracks. Frozen jbrowse.tracks entries stay plain objects
|
|
26
26
|
// here; hydration to MST nodes happens lazily in TrackConfigurationReference
|
|
27
|
-
// on first access.
|
|
28
|
-
// per
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
// walks every track, assembly and connection the session can resolve. A
|
|
33
|
-
// reader inside a reaction or an MST action was already fine — MobX
|
|
34
|
-
// caches within a batch, which is why the resolvers and `showTrackGeneric`
|
|
35
|
-
// never showed it. Ranking search hits is the caller that is neither, and
|
|
36
|
-
// it cost 33ms per search on a 2000-track config against 0.07ms held.
|
|
27
|
+
// on first access. Held hot by the autorun in afterAttach, so a reader
|
|
28
|
+
// outside any reaction (ranking search hits: 33ms per search unheld on a
|
|
29
|
+
// 2000-track config, 0.07ms held) gets the cache too. Not `keepAlive`: that
|
|
30
|
+
// subscription never ends, and it reaches jbrowse.tracks on the root, so
|
|
31
|
+
// it pinned every superseded session for the tab's life.
|
|
37
32
|
const tracksByIdRecord = computed(() => {
|
|
38
33
|
const temporaryAssemblies = 'temporaryAssemblies' in self
|
|
39
34
|
? self.temporaryAssemblies
|
|
@@ -59,7 +54,7 @@ export function TracksManagerSessionMixin(pluginManager) {
|
|
|
59
54
|
e.config,
|
|
60
55
|
]),
|
|
61
56
|
]);
|
|
62
|
-
}, {
|
|
57
|
+
}, { name: 'tracksByIdRecord' });
|
|
63
58
|
// Per-id computed cache backing getTrackById. Resolving one track's config
|
|
64
59
|
// subscribes only to that id's computed, so editing track A leaves track
|
|
65
60
|
// B's observers untouched: an unedited id's entry keeps its object identity
|
|
@@ -102,24 +97,15 @@ export function TracksManagerSessionMixin(pluginManager) {
|
|
|
102
97
|
};
|
|
103
98
|
})
|
|
104
99
|
.actions(self => ({
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* Defined here anyway so that every session has it: a feature standing a
|
|
114
|
-
* track up on the user's behalf can then call one action everywhere
|
|
115
|
-
* instead of asking which mixin it landed on.
|
|
116
|
-
* `SessionTracksManagerSessionMixin` overrides it with the real
|
|
117
|
-
* session-scoped store.
|
|
118
|
-
*/
|
|
119
|
-
addSessionTrackConf(trackConf) {
|
|
100
|
+
afterAttach() {
|
|
101
|
+
addDisposer(self, autorun(() => {
|
|
102
|
+
self.getTracksById();
|
|
103
|
+
}));
|
|
104
|
+
},
|
|
105
|
+
}))
|
|
106
|
+
.actions(self => {
|
|
107
|
+
function addToSession(trackConf) {
|
|
120
108
|
assertTrackConfOutlivesItsAssemblies(self, trackConf, 'jbrowse.tracks');
|
|
121
|
-
// the config's own adder appends without looking, so a re-add under a
|
|
122
|
-
// known id used to leave two entries with the first one winning
|
|
123
109
|
const expanded = expandLooseTrackConfig(trackConf, pluginManager);
|
|
124
110
|
const { trackId, type } = expanded;
|
|
125
111
|
const existing = self.getTrackById(trackId);
|
|
@@ -132,79 +118,93 @@ export function TracksManagerSessionMixin(pluginManager) {
|
|
|
132
118
|
return existing;
|
|
133
119
|
}
|
|
134
120
|
return self.jbrowse.addTrackConf(trackConf);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
/**
|
|
124
|
+
* #action
|
|
125
|
+
* Add a track config to *this session*.
|
|
126
|
+
*
|
|
127
|
+
* This mixin's session has no separate session-track store, so the
|
|
128
|
+
* destination is the jbrowse config — which in the products that compose
|
|
129
|
+
* it (desktop) is the single user's own file rather than something a
|
|
130
|
+
* server hands other visitors, so the two scopes are the same place.
|
|
131
|
+
* Defined here anyway so that every session has it: a feature standing a
|
|
132
|
+
* track up on the user's behalf can then call one action everywhere
|
|
133
|
+
* instead of asking which mixin it landed on.
|
|
134
|
+
* `SessionTracksManagerSessionMixin` overrides it with the real
|
|
135
|
+
* session-scoped store.
|
|
136
|
+
*/
|
|
137
|
+
addSessionTrackConf(trackConf) {
|
|
138
|
+
return addToSession(trackConf);
|
|
139
|
+
},
|
|
140
|
+
/**
|
|
141
|
+
* #action
|
|
142
|
+
* Add a track config wherever *this user's* catalog edits belong — the
|
|
143
|
+
* "Add track" workflows, where an admin adding a track means to add it
|
|
144
|
+
* for the whole site. `SessionTracksManagerSessionMixin` overrides it to
|
|
145
|
+
* send a non-admin's to the session instead; here there is only the one
|
|
146
|
+
* destination.
|
|
147
|
+
*
|
|
148
|
+
* Anything that is not an Add-track workflow wants
|
|
149
|
+
* `addSessionTrackConf`: a track a feature stands up on the user's behalf
|
|
150
|
+
* — a search result, a computed consensus, a reconstruction's labels — is
|
|
151
|
+
* not a catalog entry, and publishing one writes it into the config.json
|
|
152
|
+
* every visitor is served, once per click.
|
|
153
|
+
*/
|
|
154
|
+
publishTrackConf(trackConf) {
|
|
155
|
+
assertTrackConfOutlivesItsAssemblies(self, trackConf, 'jbrowse.tracks');
|
|
156
|
+
return self.jbrowse.addTrackConf(trackConf);
|
|
157
|
+
},
|
|
158
|
+
/**
|
|
159
|
+
* #action
|
|
160
|
+
* Deprecated alias of `addSessionTrackConf`. Call that, or
|
|
161
|
+
* `publishTrackConf`, which say which destination they mean.
|
|
162
|
+
*
|
|
163
|
+
* @deprecated
|
|
164
|
+
*
|
|
165
|
+
* Kept because a prebuilt plugin bundle reaches this by name at runtime
|
|
166
|
+
* and cannot be recompiled — `jbrowse-plugin-protein3d` calls it, and a
|
|
167
|
+
* member lookup that stops resolving throws nothing at all
|
|
168
|
+
* (`pluginFacingSessionApi.test.ts` is the guard). It now means the
|
|
169
|
+
* session, which is the destination every such caller wanted: a track a
|
|
170
|
+
* plugin stands up for one user is not a catalog entry. Nothing in tree
|
|
171
|
+
* may call it — `no-restricted-syntax` says so.
|
|
172
|
+
*/
|
|
173
|
+
addTrackConf(trackConf) {
|
|
174
|
+
return addToSession(trackConf);
|
|
175
|
+
},
|
|
176
|
+
/**
|
|
177
|
+
* #action
|
|
178
|
+
* Persist edited track config back to the in-memory jbrowse config. The
|
|
179
|
+
* session-tracks mixin overrides this so a non-admin's edits become a
|
|
180
|
+
* shareable session-track override instead.
|
|
181
|
+
*/
|
|
182
|
+
updateTrackConfiguration(trackConf) {
|
|
183
|
+
// an opened connection track lives in connectionTrackConfigs, not
|
|
184
|
+
// jbrowse.tracks; persist its edit there (jbrowse.updateTrackConf would
|
|
185
|
+
// no-op, since the track isn't in the config). Desktop uses this base
|
|
186
|
+
// mixin, so without this branch a connection-track edit is lost on
|
|
187
|
+
// reload.
|
|
188
|
+
if (isSessionWithConnections(self) &&
|
|
189
|
+
trackConf.trackId in self.connectionTrackConfigs) {
|
|
190
|
+
self.updateConnectionTrackConfig(trackConf);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
self.jbrowse.updateTrackConf(trackConf);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
/**
|
|
197
|
+
* #action
|
|
198
|
+
*/
|
|
199
|
+
deleteTrackConf(trackConf) {
|
|
200
|
+
const { trackId } = trackConf;
|
|
201
|
+
self.dereferenceTrack(trackId, self.getReferring(trackId));
|
|
202
|
+
if (self.adminMode) {
|
|
203
|
+
return self.jbrowse.deleteTrackConf(trackConf);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
208
|
}
|
|
209
209
|
/** Type guard for SessionWithTracks */
|
|
210
210
|
export function isSessionWithTracks(thing) {
|
package/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { AssertExtends, AssertNotAny } from './assertExtends.ts';
|
|
2
2
|
export { asRoot, asSession } from './siblingCast.ts';
|
|
3
|
-
export { scheduleDetachedDestroy } from '
|
|
3
|
+
export { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
4
4
|
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem, workspacesMenuItem, } from './RootModel/index.ts';
|
|
5
5
|
export type { BaseRootModel, BaseRootModelType, RootConfigurationSnapshot, RootModelWithInternetAccounts, RootModelWithInternetAccountsType, } from './RootModel/index.ts';
|
|
6
6
|
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem, bakePromotedDefaultsIntoSnapshot, bakeSessionCascades, getShareableSessionSnapshot, copyTrackSnapshot, finalizeSession, isBaseSession, isSession, isSessionWithConnections, isSessionWithDrawerWidgets, isSessionWithMultipleViews, isSessionWithReferenceManagement, isSessionWithThemes, isSessionWithTracks, pluginExtraTrackItems, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './Session/index.ts';
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { asRoot, asSession } from './siblingCast.js';
|
|
2
|
-
export { scheduleDetachedDestroy } from '
|
|
2
|
+
export { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
3
3
|
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem, workspacesMenuItem, } from './RootModel/index.js';
|
|
4
4
|
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem, bakePromotedDefaultsIntoSnapshot, bakeSessionCascades, getShareableSessionSnapshot, copyTrackSnapshot, finalizeSession, isBaseSession, isSession, isSessionWithConnections, isSessionWithDrawerWidgets, isSessionWithMultipleViews, isSessionWithReferenceManagement, isSessionWithThemes, isSessionWithTracks, pluginExtraTrackItems, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './Session/index.js';
|
|
5
5
|
export { AboutDialog, Drawer, DrawerControls, DrawerHeader, DrawerWidget, DrawerWidgetSelector, ModalWidget, ModalWidgetAppBar, PreferencesDialog, WidgetBody, WidgetHeading, drawerGridTemplateColumns, } from './ui/index.js';
|
|
@@ -12,8 +12,11 @@ const HELD_NODES_KEY = 'heldForMissingPlugins';
|
|
|
12
12
|
// widen the plugin ABI for nothing.
|
|
13
13
|
function buildableElements(pluginManager, group) {
|
|
14
14
|
return pluginManager.getElementTypesInGroup(group).filter(t => {
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const element = t;
|
|
16
|
+
if (element.isStateModelLoaded === false) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return isType(element.stateModel) && isModelType(element.stateModel);
|
|
17
20
|
});
|
|
18
21
|
}
|
|
19
22
|
// optional/stripDefault/late/snapshotProcessor all report the type they wrap,
|
|
@@ -9,6 +9,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
|
9
9
|
import { isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
10
10
|
import { observer } from 'mobx-react';
|
|
11
11
|
import AssemblyInfoPanel from './AssemblyInfoPanel.js';
|
|
12
|
+
import DescriptionPanel from './DescriptionPanel.js';
|
|
12
13
|
import FileInfoPanel from './FileInfoPanel.js';
|
|
13
14
|
import HeaderButtons from './HeaderButtons.js';
|
|
14
15
|
import RefNameInfoDialog from './RefNameInfoDialog.js';
|
|
@@ -49,7 +50,7 @@ const AboutDialogContents = observer(function AboutDialogContents({ config, sess
|
|
|
49
50
|
session,
|
|
50
51
|
pluginManager,
|
|
51
52
|
});
|
|
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
|
+
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(DescriptionPanel, { config: config, session: session }), _jsx(AssemblyInfoPanel, { config: config, session: session, hideUris: hideUris }), _jsx(PluggableComponents, { pluginManager: pluginManager,
|
|
53
54
|
/** #extensionPoint Core-extraAboutPanel | sync | Add extra panels to a track's About dialog */
|
|
54
55
|
name: "Core-extraAboutPanel", props: { session, config } }), hideUris ? null : _jsx(FileInfoPanel, { config: config, session: session }), showRefNames ? (_jsx(RefNameInfoDialog, { session: session, config: config, onClose: () => {
|
|
55
56
|
setShowRefNames(false);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import BaseCard from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail/BaseCard';
|
|
3
|
+
import { ErrorBanner, LoadingEllipses, SanitizedHTML } from '@jbrowse/core/ui';
|
|
4
|
+
import { openLocation } from '@jbrowse/core/util/io';
|
|
5
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
|
+
import { useFetch } from '@jbrowse/core/util/useFetch';
|
|
7
|
+
import { Link, Typography } from '@mui/material';
|
|
8
|
+
import { observer } from 'mobx-react';
|
|
9
|
+
import { getDescriptionHtmlUrl, rebaseDescriptionHtml, } from './descriptionHtml.js';
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
|
+
provenance: {
|
|
12
|
+
marginBottom: theme.spacing(1),
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
const DescriptionCard = observer(function DescriptionCard({ url, }) {
|
|
16
|
+
const { classes } = useStyles();
|
|
17
|
+
const { data: html, error, isLoading, } = useFetch(['trackDescriptionHtml', url], async (_name, url) => rebaseDescriptionHtml(await openLocation({ uri: url, locationType: 'UriLocation' }).readFile('utf8'), url));
|
|
18
|
+
return (_jsxs(BaseCard, { title: "Description", children: [_jsxs(Typography, { variant: "caption", color: "textSecondary", component: "div", className: classes.provenance, children: ["From the track hub, written for the UCSC Genome Browser \u2014 some display options it describes differ in JBrowse.", ' ', _jsx(Link, { href: url, target: "_blank", rel: "noopener noreferrer", children: "View original" })] }), error ? (_jsx(ErrorBanner, { error: error })) : isLoading || html === undefined ? (_jsx(LoadingEllipses, { message: "Loading description" })) : (_jsx(SanitizedHTML, { html: html }))] }));
|
|
19
|
+
});
|
|
20
|
+
const DescriptionPanel = observer(function DescriptionPanel({ config, }) {
|
|
21
|
+
const url = getDescriptionHtmlUrl(config);
|
|
22
|
+
return url ? _jsx(DescriptionCard, { url: url }) : null;
|
|
23
|
+
});
|
|
24
|
+
export default DescriptionPanel;
|
|
@@ -1,33 +1,20 @@
|
|
|
1
|
+
import type { DisplayDefaultsSession } from './displayDefaultChanges.ts';
|
|
1
2
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
export
|
|
3
|
-
getDisplayTypeDefaults: () => {
|
|
4
|
-
displayType: string;
|
|
5
|
-
slot: string;
|
|
6
|
-
value: unknown;
|
|
7
|
-
}[];
|
|
8
|
-
setDisplayTypeDefault: (displayType: string, slot: string, value: unknown) => void;
|
|
9
|
-
}
|
|
3
|
+
export type { DisplayDefaultsSession } from './displayDefaultChanges.ts';
|
|
10
4
|
/**
|
|
11
5
|
* The inventory of session-wide display-type defaults: every value the user has
|
|
12
6
|
* pinned from a track menu, what it overrides, and a button to clear one.
|
|
13
7
|
*
|
|
14
8
|
* The pin is easy to set and, until this, hard to find again. A pinned default
|
|
15
9
|
* shows on the track-selector badge of any **open** track it moves — but one
|
|
16
|
-
* affecting nothing currently open, one
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
10
|
+
* affecting nothing currently open, and one that no longer resolves at all (a
|
|
11
|
+
* stale value the cascade refuses, or a display type whose plugin is gone)
|
|
12
|
+
* appear nowhere. The only place that listed them was the "Reset preferences to
|
|
13
|
+
* defaults" confirmation, which is a destructive dialog to have to open in
|
|
14
|
+
* order to read something.
|
|
21
15
|
*
|
|
22
16
|
* The empty state is deliberate rather than rendering nothing: it is the one
|
|
23
17
|
* 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
18
|
*/
|
|
32
19
|
declare const DisplayDefaultsSection: ({ session, pluginManager, }: {
|
|
33
20
|
session: DisplayDefaultsSession;
|