mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 15:39:41 +02:00
fix(tabs): report an edit dropped behind an in-flight save, respect the group cap (#525 landing)
- createEditCoordinator's finally block rebases the edits queued during a write; one that the write's 409 made inapplicable was dropped with no toast. It is now reported once, like the main loop and adoptExternal do (found by the PR bot's re-review; regression test fails without it). - At the 32-group server cap the row and group menus no longer offer a new group, which could only fail with an untranslated 'group limit reached'. MAX_GROUPS is exported from tab-layout-browser.js. - CLAUDE.md names the pagehide keepalive as the one deliberate exception to 'never PUT the layout outside the coordinator'. - The Dashboard wiki page describes tab groups in the vertical rail row. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6694,7 +6694,8 @@ class CodemanApp {
|
||||
actions.push({ label: `Move to "${group.name}"`, run: () => this.moveTabRef(ref, group.id) });
|
||||
}
|
||||
if (location.groupId !== null) actions.push({ label: 'Move to Ungrouped', run: () => this.moveTabRef(ref, null) });
|
||||
actions.push({ label: 'Move to new group', run: () => this.createTabGroup({ ref }) });
|
||||
// At the server's group cap a new group can only fail, so it is not offered.
|
||||
if (this._canCreateTabGroup()) actions.push({ label: 'Move to new group', run: () => this.createTabGroup({ ref }) });
|
||||
return actions;
|
||||
}
|
||||
|
||||
@@ -6728,13 +6729,18 @@ class CodemanApp {
|
||||
item?.focus();
|
||||
}
|
||||
|
||||
_canCreateTabGroup() {
|
||||
const max = window.CodemanTabLayout?.MAX_GROUPS;
|
||||
return !max || (this.tabLayout?.groups?.length || 0) < max;
|
||||
}
|
||||
|
||||
openTabGroupMenu(event, groupId) {
|
||||
const groups = this.tabLayout?.groups || [];
|
||||
const index = groups.findIndex((group) => group.id === groupId);
|
||||
if (index < 0) return false;
|
||||
return this._openTabLayoutMenu(event, `group:${groupId}`, 'Group actions', [
|
||||
{ label: 'Rename group', run: () => this.startTabGroupRename(groupId) },
|
||||
{ label: 'New group', run: () => this.createTabGroup({ index: index + 1 }) },
|
||||
...(this._canCreateTabGroup() ? [{ label: 'New group', run: () => this.createTabGroup({ index: index + 1 }) }] : []),
|
||||
...(index > 0 ? [{ label: 'Move group up', run: () => this.moveTabGroup(groupId, -1) }] : []),
|
||||
...(index < groups.length - 1 ? [{ label: 'Move group down', run: () => this.moveTabGroup(groupId, 1) }] : []),
|
||||
{ label: 'Delete group', className: 'danger', run: () => this.deleteTabGroup(groupId) },
|
||||
|
||||
@@ -658,6 +658,11 @@
|
||||
writing = false;
|
||||
if (!disposed) {
|
||||
const rebased = replayOperations(authoritative, pending);
|
||||
// Edits made while the write was in flight are rebased here, so one the
|
||||
// conflict made inapplicable is dropped here too, and says so (once).
|
||||
if (rebased.dropped && !failed && !reportedDrop) {
|
||||
report('Tab groups changed elsewhere; part of your edit no longer applies.');
|
||||
}
|
||||
pending = rebased.kept;
|
||||
optimistic = rebased.layout;
|
||||
publish({ authoritative: true });
|
||||
@@ -740,5 +745,6 @@
|
||||
createLoadCoordinator,
|
||||
loadCollapsedGroupIds,
|
||||
saveCollapsedGroupIds,
|
||||
MAX_GROUPS,
|
||||
};
|
||||
})(typeof window !== 'undefined' ? window : globalThis);
|
||||
|
||||
Reference in New Issue
Block a user