flexdesk 0.4.2 → 0.4.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/README.md +12 -0
- package/dist/charts.js +2 -2
- package/dist/{chunk-XKDTIT4Q.js → chunk-4RGQSRMC.js} +2 -2
- package/dist/{chunk-QIU5S2RU.js → chunk-P4AALM3A.js} +2 -2
- package/dist/{chunk-QIU5S2RU.js.map → chunk-P4AALM3A.js.map} +2 -2
- package/dist/tiles.js +2 -2
- package/dist/widgets.js +1 -1
- package/dist/wm.js +206 -165
- package/dist/wm.js.map +3 -3
- package/package.json +1 -1
- package/src/tiling/tile_breadcrumb.js +9 -8
- package/src/tiling/wm.js +222 -175
- package/src/ui/components/data_table.js +5 -1
- /package/dist/{chunk-XKDTIT4Q.js.map → chunk-4RGQSRMC.js.map} +0 -0
package/dist/tiles.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
} from "./chunk-O5OHMWBB.js";
|
|
4
4
|
import {
|
|
5
5
|
openRawTracesWindow
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-4RGQSRMC.js";
|
|
7
|
+
import "./chunk-P4AALM3A.js";
|
|
8
8
|
import "./chunk-LH5TSOZW.js";
|
|
9
9
|
import "./chunk-FL5KFNQH.js";
|
|
10
10
|
import {
|
package/dist/widgets.js
CHANGED
package/dist/wm.js
CHANGED
|
@@ -2335,7 +2335,9 @@ function mountTileBreadcrumb(kind, props, ctx) {
|
|
|
2335
2335
|
console.error("[breadcrumb] no WM available \u2014 click ignored", k);
|
|
2336
2336
|
return;
|
|
2337
2337
|
}
|
|
2338
|
-
if (typeof wm.
|
|
2338
|
+
if (typeof wm.navigateUp === "function") {
|
|
2339
|
+
wm.navigateUp(k, p, { ctx });
|
|
2340
|
+
} else if (typeof wm.navigate === "function") {
|
|
2339
2341
|
wm.navigate(k, p, { ctx, dest: "origin" });
|
|
2340
2342
|
} else if (typeof wm.openInPrimary === "function") {
|
|
2341
2343
|
wm.openInPrimary(k, p);
|
|
@@ -4158,56 +4160,42 @@ var WindowManager = class _WindowManager {
|
|
|
4158
4160
|
* methods (openFromContext / openInLeaf / navigateActiveTab) —
|
|
4159
4161
|
* they all record history by default. */
|
|
4160
4162
|
navigateBack() {
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
const
|
|
4166
|
-
|
|
4167
|
-
const
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
this._notifyChange("navigate-back");
|
|
4198
|
-
return;
|
|
4199
|
-
}
|
|
4200
|
-
if (this.backToOpenList && this._backToOpenList(id)) return;
|
|
4201
|
-
const leaf = tree.get(id);
|
|
4202
|
-
if (!leaf?.content) return;
|
|
4203
|
-
const { kind, props } = leaf.content;
|
|
4204
|
-
const up = this.taxonomy.parentOf(kind, props);
|
|
4205
|
-
if (up) {
|
|
4206
|
-
this.navigateActiveTab(id, up.kind, up.props);
|
|
4207
|
-
return;
|
|
4208
|
-
}
|
|
4209
|
-
const parent = this.taxonomy.parentKindFor(kind);
|
|
4210
|
-
if (parent) this.navigateActiveTab(id, parent);
|
|
4163
|
+
const scope = this._backScope();
|
|
4164
|
+
if (!scope) return;
|
|
4165
|
+
if (scope.leafId && this._popTabHistory(scope.leafId)) return;
|
|
4166
|
+
if (this._returnToOpenList(scope)) return;
|
|
4167
|
+
const active = this._scopeActiveTab(scope);
|
|
4168
|
+
if (!active) return;
|
|
4169
|
+
const up = this.taxonomy.parentOf(active.kind, active.props || {});
|
|
4170
|
+
const parentKind = up ? up.kind : this.taxonomy.parentKindFor(active.kind);
|
|
4171
|
+
if (parentKind) this._navigateInScope(scope, parentKind, up ? up.props || {} : {});
|
|
4172
|
+
}
|
|
4173
|
+
/**
|
|
4174
|
+
* C35. CLIMB TO A LEVEL: what a breadcrumb crumb means.
|
|
4175
|
+
*
|
|
4176
|
+
* `navigate` goes to exactly the target. A crumb says something different:
|
|
4177
|
+
* "take me up to this level of where I am". From a record, the level it
|
|
4178
|
+
* names is usually a list of the record's own section, and when such a list
|
|
4179
|
+
* is already open that is the SAME request Backspace makes, so it goes
|
|
4180
|
+
* through the same rule, `_returnToOpenList`, and closes the record onto the
|
|
4181
|
+
* open list instead of turning the record into a second copy of it.
|
|
4182
|
+
*
|
|
4183
|
+
* Every crumb calls this, so no crumb needs to know whether it is the
|
|
4184
|
+
* immediate parent. A crumb that names an entity (an epic above a story), a
|
|
4185
|
+
* record with no list of its section open, or content that is not a record
|
|
4186
|
+
* navigates in place, exactly as `navigate(…, { dest: 'origin' })` would.
|
|
4187
|
+
*
|
|
4188
|
+
* @param {string} kind
|
|
4189
|
+
* @param {object} [props]
|
|
4190
|
+
* @param {{ctx?: object}} [opts] the crumb's tile or window context
|
|
4191
|
+
*/
|
|
4192
|
+
navigateUp(kind, props = {}, { ctx = null } = {}) {
|
|
4193
|
+
const scope = this._scopeFromCtx(ctx);
|
|
4194
|
+
if (!scope) return this.navigate(kind, props, { ctx, dest: "origin" });
|
|
4195
|
+
const active = this._scopeActiveTab(scope);
|
|
4196
|
+
const aimsAtOwnList = !_isEntityTab({ props }) && _isEntityTab(active) && this.taxonomy.topNavFor(kind) === this.taxonomy.topNavFor(active.kind);
|
|
4197
|
+
if (aimsAtOwnList && this._returnToOpenList(scope)) return;
|
|
4198
|
+
this._navigateInScope(scope, kind, props);
|
|
4211
4199
|
}
|
|
4212
4200
|
/** True when `navigateBack` would do something user-visible — i.e.
|
|
4213
4201
|
* the active tab has per-tab history, OR the current kind has a
|
|
@@ -4239,135 +4227,178 @@ var WindowManager = class _WindowManager {
|
|
|
4239
4227
|
this.renderer?.rebaselineLeaf?.(leafId, expected);
|
|
4240
4228
|
this._persist();
|
|
4241
4229
|
}
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
*
|
|
4250
|
-
*
|
|
4251
|
-
* the
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
* test `swapToPage` uses for "the caller asked for a specific entity" — look
|
|
4258
|
-
* for an open tab of the SAME section that is NOT one. That is the list or
|
|
4259
|
-
* landing page the record belongs to. Close the record and activate it.
|
|
4260
|
-
*
|
|
4261
|
-
* NEAREST TO THE LEFT FIRST. New tabs are appended at the end, so the tab a
|
|
4262
|
-
* record was opened from sits to its left; when several lists of the section
|
|
4263
|
-
* are open, the nearest one on that side is the one it most plausibly came
|
|
4264
|
-
* from. The right side is searched only after the left has nothing.
|
|
4265
|
-
*
|
|
4266
|
-
* DECLINES, and leaves step (3) to walk up in place, whenever there is no
|
|
4267
|
-
* such tab: a record that is the tile's only tab, or one whose section has no
|
|
4268
|
-
* list open. That keeps the one guarantee the whole rule exists for — Back
|
|
4269
|
-
* never leaves two copies of a list — without ever closing a record into a
|
|
4270
|
-
* tile that has nothing of its own to show.
|
|
4271
|
-
*
|
|
4272
|
-
* Matching is by SECTION (`topNavFor`) and not by kind, because the list a
|
|
4273
|
-
* record was opened from is often not the record's taxonomy parent: a root
|
|
4274
|
-
* landing page that renders the section, or a list that a flattened taxonomy
|
|
4275
|
-
* files beside the record rather than above it.
|
|
4276
|
-
*
|
|
4277
|
-
* @returns {boolean} whether it closed a tab
|
|
4278
|
-
*/
|
|
4279
|
-
_backToOpenList(leafId) {
|
|
4230
|
+
// ── Back and up: one scope model, one rule ─────────────────────
|
|
4231
|
+
//
|
|
4232
|
+
// A SCOPE is where a navigation happens: `{ leafId }` for a tile or
|
|
4233
|
+
// `{ windowId }` for a floating window. Backspace and `navigateUp` both
|
|
4234
|
+
// resolve one, and everything below works on a scope, so tiles and windows
|
|
4235
|
+
// cannot drift into two versions of the same behaviour.
|
|
4236
|
+
/** The scope Backspace acts on. C34: a floating window the user last
|
|
4237
|
+
* clicked in, because the tree's focus never moves to a window; else the
|
|
4238
|
+
* focused content tile; else the primary tile. Panels are never a scope:
|
|
4239
|
+
* Backspace from the nav panel walks the content area. */
|
|
4240
|
+
_backScope() {
|
|
4241
|
+
if (this._backWindowId && this._windowToLeaf.has(this._backWindowId)) {
|
|
4242
|
+
return { windowId: this._backWindowId };
|
|
4243
|
+
}
|
|
4244
|
+
this._backWindowId = null;
|
|
4280
4245
|
const tree = this._tree();
|
|
4281
|
-
const
|
|
4282
|
-
|
|
4283
|
-
const
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
if (
|
|
4290
|
-
const
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4246
|
+
const focusedId = tree.focusedLeafId;
|
|
4247
|
+
const focusedKind = focusedId ? tree.get(focusedId)?.content?.kind || "" : "";
|
|
4248
|
+
const id = focusedId && focusedKind && !focusedKind.startsWith("panel:") && focusedKind !== "window-placeholder" ? focusedId : tree.primaryLeafId();
|
|
4249
|
+
return id ? { leafId: id } : null;
|
|
4250
|
+
}
|
|
4251
|
+
/** The scope a content context names: its window, or its tile. Null for a
|
|
4252
|
+
* panel or a context the WM does not know. */
|
|
4253
|
+
_scopeFromCtx(ctx) {
|
|
4254
|
+
if (ctx?.windowId && this._windowToLeaf.has(ctx.windowId)) return { windowId: ctx.windowId };
|
|
4255
|
+
const leaf = ctx?.leafId ? this._tree().get(ctx.leafId) : null;
|
|
4256
|
+
const k = leaf?.content?.kind || "";
|
|
4257
|
+
if (leaf && leaf.kind === "leaf" && k && !k.startsWith("panel:")) return { leafId: leaf.id };
|
|
4258
|
+
return null;
|
|
4259
|
+
}
|
|
4260
|
+
/** A scope's tab list and active index. A window promoted with no strip, or
|
|
4261
|
+
* a tile with no tab array, reads as a single tab. */
|
|
4262
|
+
_scopeTabs(scope) {
|
|
4263
|
+
if (scope?.windowId) {
|
|
4264
|
+
const rec = this._windowToLeaf.get(scope.windowId);
|
|
4265
|
+
if (!rec) return null;
|
|
4266
|
+
const tabs2 = Array.isArray(rec.tabs) && rec.tabs.length ? rec.tabs : [rec.original].filter(Boolean);
|
|
4267
|
+
return { tabs: tabs2, activeIdx: Math.max(0, Math.min(tabs2.length - 1, rec.activeTabIdx || 0)) };
|
|
4268
|
+
}
|
|
4269
|
+
const leaf = scope?.leafId ? this._tree().get(scope.leafId) : null;
|
|
4270
|
+
if (!leaf || leaf.kind !== "leaf") return null;
|
|
4271
|
+
const tabs = Array.isArray(leaf.tabs) && leaf.tabs.length ? leaf.tabs : [leaf.content].filter(Boolean);
|
|
4272
|
+
return { tabs, activeIdx: Math.max(0, Math.min(tabs.length - 1, leaf.activeTabIdx || 0)) };
|
|
4273
|
+
}
|
|
4274
|
+
_scopeActiveTab(scope) {
|
|
4275
|
+
const src = this._scopeTabs(scope);
|
|
4276
|
+
return src ? src.tabs[src.activeIdx] || null : null;
|
|
4277
|
+
}
|
|
4278
|
+
/** Replace what a scope shows, in place: the tile's active tab (recording
|
|
4279
|
+
* history) or the window's content. */
|
|
4280
|
+
_navigateInScope(scope, kind, props = {}) {
|
|
4281
|
+
if (scope.windowId) return this.openInWindow(scope.windowId, kind, props);
|
|
4282
|
+
return this.navigateActiveTab(scope.leafId, kind, props);
|
|
4283
|
+
}
|
|
4284
|
+
/** Pop the active tab's history, if it has any. */
|
|
4285
|
+
_popTabHistory(id) {
|
|
4286
|
+
const tree = this._tree();
|
|
4287
|
+
const prior = tree.popActiveTabHistory?.(id);
|
|
4288
|
+
if (!prior || !prior.kind) return false;
|
|
4289
|
+
const curKind = tree.get(id)?.content?.kind;
|
|
4290
|
+
const curTopNav = curKind ? this.taxonomy.topNavFor(curKind) : null;
|
|
4291
|
+
const title = prior.title || _tabTitle(prior.kind, prior.props);
|
|
4292
|
+
if (prior.topNav && curTopNav && prior.topNav !== curTopNav) {
|
|
4293
|
+
tree.swapToPage?.(
|
|
4294
|
+
id,
|
|
4295
|
+
{ kind: prior.kind, props: prior.props || {}, title },
|
|
4296
|
+
curTopNav,
|
|
4297
|
+
prior.topNav,
|
|
4298
|
+
{ recordHistory: false }
|
|
4299
|
+
);
|
|
4300
|
+
} else {
|
|
4301
|
+
tree.replaceActiveTabContent(
|
|
4302
|
+
id,
|
|
4303
|
+
{ kind: prior.kind, props: prior.props || {} },
|
|
4304
|
+
title,
|
|
4305
|
+
{ recordHistory: false }
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
tree.focus(id);
|
|
4298
4309
|
this.renderer.render();
|
|
4299
4310
|
this._persist();
|
|
4300
|
-
this._notifyChange("navigate-back
|
|
4311
|
+
this._notifyChange("navigate-back");
|
|
4301
4312
|
return true;
|
|
4302
4313
|
}
|
|
4303
4314
|
/**
|
|
4304
|
-
* C34.
|
|
4305
|
-
*
|
|
4306
|
-
*
|
|
4307
|
-
*
|
|
4308
|
-
*
|
|
4309
|
-
*
|
|
4310
|
-
*
|
|
4311
|
-
*
|
|
4312
|
-
*
|
|
4313
|
-
*
|
|
4314
|
-
*
|
|
4315
|
+
* C32 / C34 / C35. BACK FROM A RECORD RETURNS TO THE LIST; IT DOES NOT MAKE ONE.
|
|
4316
|
+
*
|
|
4317
|
+
* The gesture this is for: a list, a record opened from it into a new tab,
|
|
4318
|
+
* then Backspace or the list's crumb in that record. Rewriting the record
|
|
4319
|
+
* into its parent would leave the list open twice. The user's model is a
|
|
4320
|
+
* browser's: the list is still open, so going back closes the record and
|
|
4321
|
+
* shows the list again. This function is the ONLY place that rule lives.
|
|
4322
|
+
*
|
|
4323
|
+
* Applies when `backToOpenList` is on and the scope's active tab is a RECORD
|
|
4324
|
+
* (its props carry an `id`). The list is an open tab that is not a record
|
|
4325
|
+
* and belongs to the same SECTION (`topNavFor`), matched by section and not
|
|
4326
|
+
* by kind because a record's list is often not its taxonomy parent: a root
|
|
4327
|
+
* landing that renders the section, or a list filed beside the record.
|
|
4328
|
+
*
|
|
4329
|
+
* Where it looks, in order:
|
|
4330
|
+
* - the scope's own tabs, nearest to the LEFT first (new tabs are appended,
|
|
4331
|
+
* so the tab a record came from sits to its left), then to the right;
|
|
4332
|
+
* - for a WINDOW only, then any tile of the window's desktop, primary tile
|
|
4333
|
+
* first, activating a list tab there. Closing a window's last tab closes
|
|
4334
|
+
* the window, which discards it; a plain close never docks back.
|
|
4335
|
+
*
|
|
4336
|
+
* Declines, leaving the caller to navigate in place, when there is no such
|
|
4337
|
+
* list, so Back never closes a record into a tile with nothing to show.
|
|
4338
|
+
*
|
|
4339
|
+
* @returns {boolean} whether it closed the record
|
|
4315
4340
|
*/
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
const
|
|
4319
|
-
if (!
|
|
4320
|
-
|
|
4321
|
-
return false;
|
|
4322
|
-
}
|
|
4323
|
-
const tabs = Array.isArray(rec.tabs) && rec.tabs.length ? rec.tabs : [rec.original].filter(Boolean);
|
|
4324
|
-
const activeIdx = Math.max(0, Math.min(tabs.length - 1, rec.activeTabIdx || 0));
|
|
4341
|
+
_returnToOpenList(scope) {
|
|
4342
|
+
if (!this.backToOpenList) return false;
|
|
4343
|
+
const src = this._scopeTabs(scope);
|
|
4344
|
+
if (!src) return false;
|
|
4345
|
+
const { tabs, activeIdx } = src;
|
|
4325
4346
|
const active = tabs[activeIdx];
|
|
4326
|
-
if (!active) return
|
|
4327
|
-
const section = this.
|
|
4347
|
+
if (!_isEntityTab(active)) return false;
|
|
4348
|
+
const section = this.taxonomy.topNavFor(active.kind);
|
|
4349
|
+
if (!section) return false;
|
|
4328
4350
|
const isList = (t) => !!t && !_isEntityTab(t) && this.taxonomy.topNavFor(t.kind) === section;
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
this.
|
|
4335
|
-
this.showWindowTab(winId, own > activeIdx ? own - 1 : own);
|
|
4351
|
+
const own = _nearestIndex(tabs, activeIdx, isList);
|
|
4352
|
+
if (own >= 0 && tabs.length > 1) {
|
|
4353
|
+
const landing = own > activeIdx ? own - 1 : own;
|
|
4354
|
+
if (scope.windowId) {
|
|
4355
|
+
this._windowTabAction(scope.windowId, "close", { idx: activeIdx });
|
|
4356
|
+
this.showWindowTab(scope.windowId, landing);
|
|
4336
4357
|
return true;
|
|
4337
4358
|
}
|
|
4338
|
-
const
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4359
|
+
const tree2 = this._tree();
|
|
4360
|
+
tree2.removeLeafTab(scope.leafId, activeIdx);
|
|
4361
|
+
tree2.setActiveLeafTab(scope.leafId, landing);
|
|
4362
|
+
tree2.focus(scope.leafId);
|
|
4363
|
+
this.renderer.render();
|
|
4364
|
+
this._persist();
|
|
4365
|
+
this._notifyChange("navigate-back-close");
|
|
4366
|
+
return true;
|
|
4367
|
+
}
|
|
4368
|
+
if (!scope.windowId) return false;
|
|
4369
|
+
const rec = this._windowToLeaf.get(scope.windowId);
|
|
4370
|
+
const tree = (this.desktops.desktops[rec.desktopIdx] || this.desktops.active()).tree;
|
|
4371
|
+
const primaryId = tree.primaryLeafId();
|
|
4372
|
+
const leaves = tree.leaves?.() || [];
|
|
4373
|
+
const ordered = [...leaves.filter((l) => l.id === primaryId), ...leaves.filter((l) => l.id !== primaryId)];
|
|
4374
|
+
for (const leaf of ordered) {
|
|
4375
|
+
const ltabs = Array.isArray(leaf.tabs) ? leaf.tabs : [];
|
|
4376
|
+
const cur = Math.max(0, Math.min(ltabs.length - 1, leaf.activeTabIdx || 0));
|
|
4377
|
+
const hit = isList(ltabs[cur]) ? cur : ltabs.findIndex(isList);
|
|
4378
|
+
if (hit < 0) continue;
|
|
4379
|
+
if (this._backWindowId === scope.windowId) this._backWindowId = null;
|
|
4380
|
+
if (Array.isArray(rec.tabs) && rec.tabs.length > 1) {
|
|
4381
|
+
this._windowTabAction(scope.windowId, "close", { idx: activeIdx });
|
|
4382
|
+
} else {
|
|
4383
|
+
try {
|
|
4384
|
+
rec.window.close({ force: true });
|
|
4385
|
+
} catch {
|
|
4360
4386
|
}
|
|
4361
|
-
this._persist();
|
|
4362
|
-
this._notifyChange("navigate-back-close");
|
|
4363
|
-
return true;
|
|
4364
4387
|
}
|
|
4388
|
+
if (this.desktops.active().tree === tree) {
|
|
4389
|
+
tree.setActiveLeafTab(leaf.id, hit);
|
|
4390
|
+
tree.focus(leaf.id);
|
|
4391
|
+
this.renderer.render();
|
|
4392
|
+
}
|
|
4393
|
+
this._persist();
|
|
4394
|
+
this._notifyChange("navigate-back-close");
|
|
4395
|
+
return true;
|
|
4365
4396
|
}
|
|
4366
|
-
|
|
4367
|
-
const parentKind = up ? up.kind : this.taxonomy.parentKindFor(active.kind);
|
|
4368
|
-
if (parentKind) this.openInWindow(winId, parentKind, up ? up.props || {} : {});
|
|
4369
|
-
return true;
|
|
4397
|
+
return false;
|
|
4370
4398
|
}
|
|
4399
|
+
/** Navigate inside the current tab — preserves every other tab in
|
|
4400
|
+
* the leaf. Used by Backspace + breadcrumb segments + anything
|
|
4401
|
+
* else that should walk WITHIN the tile rather than reset it. */
|
|
4371
4402
|
navigateActiveTab(leafId, kind, props = {}) {
|
|
4372
4403
|
const tree = this._tree();
|
|
4373
4404
|
const leaf = tree.get(leafId);
|
|
@@ -4494,6 +4525,11 @@ var WindowManager = class _WindowManager {
|
|
|
4494
4525
|
currentTopNav,
|
|
4495
4526
|
targetTopNav
|
|
4496
4527
|
);
|
|
4528
|
+
const _leaf = tree.get(leafId);
|
|
4529
|
+
const _active = _leaf?.tabs?.[_leaf.activeTabIdx];
|
|
4530
|
+
if (_active && _active.kind === kind && Object.keys(props || {}).length > 0 && JSON.stringify(_active.props || {}) !== JSON.stringify(props || {})) {
|
|
4531
|
+
tree.replaceActiveTabContent(leafId, { kind, props }, title, { recordHistory: false });
|
|
4532
|
+
}
|
|
4497
4533
|
tree.focus(leafId);
|
|
4498
4534
|
if (spawned) this._canonicalize(tree, this.desktops.active());
|
|
4499
4535
|
this.renderer.render();
|
|
@@ -6986,6 +7022,11 @@ function _swapSiblings(tree, aId, bId) {
|
|
|
6986
7022
|
parent.sizes[j] = size;
|
|
6987
7023
|
return true;
|
|
6988
7024
|
}
|
|
7025
|
+
function _nearestIndex(tabs, from, test) {
|
|
7026
|
+
for (let i = from - 1; i >= 0; i--) if (test(tabs[i])) return i;
|
|
7027
|
+
for (let i = from + 1; i < tabs.length; i++) if (test(tabs[i])) return i;
|
|
7028
|
+
return -1;
|
|
7029
|
+
}
|
|
6989
7030
|
function _isEntityTab(tab) {
|
|
6990
7031
|
return !!tab && tab.props != null && tab.props.id != null && tab.props.id !== "";
|
|
6991
7032
|
}
|