@anymux/ui-kit 0.1.0
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/dist/ExplorerLayout-CSIJd7N4.js +105 -0
- package/dist/ExplorerLayout-CSIJd7N4.js.map +1 -0
- package/dist/FileBrowserContext-B6jixa2j.js +11 -0
- package/dist/FileBrowserContext-B6jixa2j.js.map +1 -0
- package/dist/calendar-DSlrbHoj.js +761 -0
- package/dist/calendar-DSlrbHoj.js.map +1 -0
- package/dist/calendar.d.ts +3 -0
- package/dist/calendar.js +3 -0
- package/dist/contacts-DQXTZzHc.js +539 -0
- package/dist/contacts-DQXTZzHc.js.map +1 -0
- package/dist/contacts.d.ts +3 -0
- package/dist/contacts.js +3 -0
- package/dist/file-browser-m5atC3kF.js +6755 -0
- package/dist/file-browser-m5atC3kF.js.map +1 -0
- package/dist/file-browser.d.ts +11 -0
- package/dist/file-browser.js +9 -0
- package/dist/git-B55e6LL-.js +561 -0
- package/dist/git-B55e6LL-.js.map +1 -0
- package/dist/git.d.ts +2 -0
- package/dist/git.js +3 -0
- package/dist/iconMap-V4B8P-Uh.js +206 -0
- package/dist/iconMap-V4B8P-Uh.js.map +1 -0
- package/dist/icons-CIsIOZXR.js +0 -0
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -0
- package/dist/index-BNmNIWBL.d.ts +71 -0
- package/dist/index-BNmNIWBL.d.ts.map +1 -0
- package/dist/index-Bryv_GCG.d.ts +1481 -0
- package/dist/index-Bryv_GCG.d.ts.map +1 -0
- package/dist/index-CuQIjSXs.d.ts +134 -0
- package/dist/index-CuQIjSXs.d.ts.map +1 -0
- package/dist/index-DSu19mq0.d.ts +153 -0
- package/dist/index-DSu19mq0.d.ts.map +1 -0
- package/dist/index-DmsyeHFr.d.ts +149 -0
- package/dist/index-DmsyeHFr.d.ts.map +1 -0
- package/dist/index-DxnJ8FYM.d.ts +17 -0
- package/dist/index-DxnJ8FYM.d.ts.map +1 -0
- package/dist/index-DzfY1Tok.d.ts +32 -0
- package/dist/index-DzfY1Tok.d.ts.map +1 -0
- package/dist/index-Ml_SgiKa.d.ts +1847 -0
- package/dist/index-Ml_SgiKa.d.ts.map +1 -0
- package/dist/index-kHr9udZD.d.ts +1025 -0
- package/dist/index-kHr9udZD.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -0
- package/dist/layout-Ca_4r8ka.js +89 -0
- package/dist/layout-Ca_4r8ka.js.map +1 -0
- package/dist/layout.d.ts +2 -0
- package/dist/layout.js +5 -0
- package/dist/list-CxfT6hix.js +6831 -0
- package/dist/list-CxfT6hix.js.map +1 -0
- package/dist/list.d.ts +2 -0
- package/dist/list.js +5 -0
- package/dist/media-DZ292aKK.js +557 -0
- package/dist/media-DZ292aKK.js.map +1 -0
- package/dist/media.d.ts +3 -0
- package/dist/media.js +3 -0
- package/dist/tree-Dd9Z0Aso.js +3351 -0
- package/dist/tree-Dd9Z0Aso.js.map +1 -0
- package/dist/tree.d.ts +2 -0
- package/dist/tree.js +6 -0
- package/dist/types-common-CB3kRek8.d.ts +26 -0
- package/dist/types-common-CB3kRek8.d.ts.map +1 -0
- package/dist/utils-B4fdKKsy.js +3 -0
- package/package.json +109 -0
- package/src/calendar/AgendaView.tsx +37 -0
- package/src/calendar/CalendarBrowser.tsx +90 -0
- package/src/calendar/CalendarModel.ts +142 -0
- package/src/calendar/CalendarSidebar.tsx +81 -0
- package/src/calendar/DayView.tsx +76 -0
- package/src/calendar/EventCard.tsx +51 -0
- package/src/calendar/MockCalendarProvider.ts +98 -0
- package/src/calendar/MonthView.tsx +77 -0
- package/src/calendar/WeekView.tsx +129 -0
- package/src/calendar/index.ts +18 -0
- package/src/calendar/types.ts +25 -0
- package/src/contacts/ContactAvatar.tsx +35 -0
- package/src/contacts/ContactBrowser.tsx +56 -0
- package/src/contacts/ContactCard.tsx +37 -0
- package/src/contacts/ContactDetail.tsx +63 -0
- package/src/contacts/ContactGroupSidebar.tsx +40 -0
- package/src/contacts/ContactList.tsx +32 -0
- package/src/contacts/ContactListModel.ts +120 -0
- package/src/contacts/MockContactProvider.ts +77 -0
- package/src/contacts/index.ts +17 -0
- package/src/contacts/types.ts +26 -0
- package/src/demos/CalendarBrowserDemo.tsx +15 -0
- package/src/demos/ContactBrowserDemo.tsx +15 -0
- package/src/demos/MediaBrowserDemo.tsx +15 -0
- package/src/file-browser/adapters/DocumentViewerAdapter.ts +371 -0
- package/src/file-browser/adapters/FileSystemBridge.ts +168 -0
- package/src/file-browser/adapters/GitBrowserAdapter.ts +546 -0
- package/src/file-browser/adapters/README.md +504 -0
- package/src/file-browser/adapters/index.ts +27 -0
- package/src/file-browser/adapters/types.ts +70 -0
- package/src/file-browser/architecture.md +645 -0
- package/src/file-browser/components/CreateItemDialog.tsx +71 -0
- package/src/file-browser/components/DeleteConfirmDialog.tsx +58 -0
- package/src/file-browser/components/FileBrowser.tsx +473 -0
- package/src/file-browser/components/FileBrowserContent.tsx +209 -0
- package/src/file-browser/components/FileBrowserHeader.tsx +151 -0
- package/src/file-browser/components/FileBrowserToolbar.tsx +145 -0
- package/src/file-browser/components/LeftPanel/LeftPanel.tsx +103 -0
- package/src/file-browser/components/LeftPanel/LeftPanelTabs.tsx +70 -0
- package/src/file-browser/components/LeftPanel/TreeNavigationView.tsx +256 -0
- package/src/file-browser/components/PreviewPane.tsx +146 -0
- package/src/file-browser/components/RightPanel/FilePreview.tsx +219 -0
- package/src/file-browser/components/RightPanel/RightPanel.tsx +186 -0
- package/src/file-browser/components/RightPanel/RightPanelToolbar.tsx +113 -0
- package/src/file-browser/components/UploadProgress.tsx +123 -0
- package/src/file-browser/components/ViewerHost.tsx +208 -0
- package/src/file-browser/components/mobile/MobileNavigation.tsx +227 -0
- package/src/file-browser/components/navigation/NavigationButtons.tsx +171 -0
- package/src/file-browser/components/shared/ErrorBoundary.tsx +116 -0
- package/src/file-browser/components/shared/FileBrowserItem.tsx +195 -0
- package/src/file-browser/components/shared/FileIcon.tsx +169 -0
- package/src/file-browser/components/toolbar/ViewModeToggle.tsx +200 -0
- package/src/file-browser/components/views/ListView/ListView.tsx +484 -0
- package/src/file-browser/components/views/ThumbnailView/ThumbnailView.tsx +323 -0
- package/src/file-browser/components/views/TreeView/TreeNode.tsx +186 -0
- package/src/file-browser/components/views/TreeView/TreeNodeList.tsx +191 -0
- package/src/file-browser/components/views/TreeView/TreeView.tsx +200 -0
- package/src/file-browser/components/views/TreemapView/TreemapView.tsx +339 -0
- package/src/file-browser/context/FileBrowserContext.tsx +13 -0
- package/src/file-browser/examples/BasicUsage.tsx +20 -0
- package/src/file-browser/index.ts +98 -0
- package/src/file-browser/models/FileBrowserModel.ts +623 -0
- package/src/file-browser/models/LeftPanelManagerModel.ts +105 -0
- package/src/file-browser/models/NavigationManagerModel.ts +312 -0
- package/src/file-browser/models/ResponsiveLayoutManagerModel.ts +437 -0
- package/src/file-browser/models/RightPanelManagerModel.ts +190 -0
- package/src/file-browser/models/SelectionManagerModel.ts +252 -0
- package/src/file-browser/models/ToolbarManagerModel.ts +144 -0
- package/src/file-browser/models/UploadModel.ts +147 -0
- package/src/file-browser/models/ViewModeManagerModel.ts +185 -0
- package/src/file-browser/models/ViewerHostModel.ts +44 -0
- package/src/file-browser/models/ui/ListViewUIModel.ts +265 -0
- package/src/file-browser/models/ui/PreviewUIModel.ts +297 -0
- package/src/file-browser/models/ui/ThumbnailViewUIModel.ts +254 -0
- package/src/file-browser/models/ui/TreeViewUIModel.ts +128 -0
- package/src/file-browser/models/ui/TreemapViewUIModel.ts +350 -0
- package/src/file-browser/providers/FileSystemListProvider.ts +552 -0
- package/src/file-browser/providers/FileSystemProvider.ts +401 -0
- package/src/file-browser/providers/FileSystemTreeProvider.ts +231 -0
- package/src/file-browser/providers/GitProvider.ts +337 -0
- package/src/file-browser/providers/GitRepositoryProvider.ts +376 -0
- package/src/file-browser/providers/IFileBrowserProvider.ts +56 -0
- package/src/file-browser/providers/MemoryProvider.ts +303 -0
- package/src/file-browser/providers/index.ts +4 -0
- package/src/file-browser/registry/ViewerRegistry.ts +551 -0
- package/src/file-browser/registry/types.ts +144 -0
- package/src/file-browser/scripts/performanceBenchmark.ts +553 -0
- package/src/file-browser/services/ThumbnailCacheService.ts +128 -0
- package/src/file-browser/tasks.md +537 -0
- package/src/file-browser/types/FileBrowserTypes.ts +126 -0
- package/src/file-browser/types/ProviderTypes.ts +155 -0
- package/src/file-browser/types/UITypes.ts +235 -0
- package/src/file-browser/types/ViewModeTypes.ts +150 -0
- package/src/file-browser/utils/gestures.ts +327 -0
- package/src/file-browser/utils/performance.ts +563 -0
- package/src/file-browser/viewers/ImageViewer.tsx +163 -0
- package/src/file-browser/viewers/ImageViewerModel.ts +79 -0
- package/src/file-browser/viewers/TextViewer.tsx +95 -0
- package/src/file-browser/viewers/UnsupportedFileViewer.tsx +57 -0
- package/src/file-browser/viewers/index.ts +61 -0
- package/src/git/BranchList.tsx +128 -0
- package/src/git/CommitGraph.tsx +239 -0
- package/src/git/CommitList.tsx +258 -0
- package/src/git/DiffViewer.tsx +219 -0
- package/src/git/index.ts +4 -0
- package/src/icons/iconMap.ts +146 -0
- package/src/icons/index.ts +9 -0
- package/src/index.ts +13 -0
- package/src/layout/README.md +307 -0
- package/src/layout/components/ExplorerLayout/ExplorerLayout.tsx +178 -0
- package/src/layout/examples/SimpleExample.tsx +60 -0
- package/src/layout/index.ts +6 -0
- package/src/lib/utils.ts +1 -0
- package/src/list/README.md +303 -0
- package/src/list/architecture.md +807 -0
- package/src/list/components/CalculatedGridView.tsx +252 -0
- package/src/list/components/DragPreview.tsx +102 -0
- package/src/list/components/ListContextMenu.tsx +274 -0
- package/src/list/components/ListItem.tsx +761 -0
- package/src/list/components/ListItems.tsx +919 -0
- package/src/list/components/MasonryView.tsx +241 -0
- package/src/list/components/SearchFilter.tsx +44 -0
- package/src/list/components/TreemapView.tsx +709 -0
- package/src/list/components/ViewSizeControls.tsx +205 -0
- package/src/list/components/ViewTypeSelector.tsx +312 -0
- package/src/list/components/VirtualizedDetailsView.tsx +231 -0
- package/src/list/components/VirtualizedGrid.tsx +164 -0
- package/src/list/components/VirtualizedList.tsx +154 -0
- package/src/list/components/VirtualizedMasonryView.tsx +344 -0
- package/src/list/components/shared/EmptyState.tsx +103 -0
- package/src/list/components/shared/ErrorBoundary.tsx +123 -0
- package/src/list/components/shared/ErrorDisplay.tsx +100 -0
- package/src/list/components/shared/ListLoader.tsx +146 -0
- package/src/list/components/shared/LoadingIndicator.tsx +80 -0
- package/src/list/index.ts +92 -0
- package/src/list/models/ListItemsModel.ts +1301 -0
- package/src/list/models/TreemapModel.ts +204 -0
- package/src/list/providers/ListItemsProvider.ts +313 -0
- package/src/list/providers/TestListProvider.ts +604 -0
- package/src/list/tasks.md +937 -0
- package/src/list/types/ListTypes.ts +178 -0
- package/src/list/utils/BenchmarkLogger.ts +243 -0
- package/src/list/utils/DragDropManager.ts +320 -0
- package/src/list/utils/GridLayoutCalculator.ts +290 -0
- package/src/list/utils/ListAccessibility.ts +367 -0
- package/src/list/utils/ListKeyboard.ts +414 -0
- package/src/list/utils/MasonryLayoutCalculator.ts +302 -0
- package/src/list/utils/MasonryLayoutEngine.ts +401 -0
- package/src/list/utils/__tests__/MasonryLayoutEngine.test.ts +157 -0
- package/src/list/utils/__tests__/VirtualizedMasonryView.test.tsx +251 -0
- package/src/media/AlbumSidebar.tsx +48 -0
- package/src/media/MediaBrowser.tsx +92 -0
- package/src/media/MediaBrowserModel.ts +138 -0
- package/src/media/MediaGrid.tsx +50 -0
- package/src/media/MediaList.tsx +49 -0
- package/src/media/MediaPreview.tsx +63 -0
- package/src/media/MediaTimeline.tsx +38 -0
- package/src/media/MockMediaProvider.ts +70 -0
- package/src/media/index.ts +18 -0
- package/src/media/types.ts +21 -0
- package/src/styles/variables.css +60 -0
- package/src/tree/DEVELOPMENT_SUMMARY.md +170 -0
- package/src/tree/__tests__/TreeModel.test.ts +16 -0
- package/src/tree/architecture.md +530 -0
- package/src/tree/components/Tree.tsx +283 -0
- package/src/tree/components/TreeCheckbox.tsx +147 -0
- package/src/tree/components/TreeContextMenu.tsx +139 -0
- package/src/tree/components/TreeNodeList.tsx +329 -0
- package/src/tree/components/TreeTable.tsx +382 -0
- package/src/tree/index.ts +58 -0
- package/src/tree/models/TreeModel.ts +839 -0
- package/src/tree/providers/SimpleTreeProvider.ts +463 -0
- package/src/tree/providers/TestTreeProvider.ts +946 -0
- package/src/tree/providers/TreeProvider.ts +308 -0
- package/src/tree/tasks.md +2046 -0
- package/src/tree/types/TreeTypes.ts +279 -0
- package/src/tree/utils/SelectionTheme.ts +150 -0
- package/src/tree/utils/logger.ts +203 -0
- package/src/types-common.ts +21 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { makeAutoObservable, observable } from 'mobx';
|
|
2
|
+
import type { TreeViewUIModel } from './ui/TreeViewUIModel';
|
|
3
|
+
|
|
4
|
+
export interface LeftPanelMode {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
component: React.ComponentType<any>;
|
|
9
|
+
isAvailable?: () => boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class LeftPanelManagerModel {
|
|
13
|
+
// Available left panel modes (provided by provider)
|
|
14
|
+
availableModes = observable.map<string, LeftPanelMode>();
|
|
15
|
+
currentMode = 'tree'; // default: tree navigation
|
|
16
|
+
|
|
17
|
+
// Tree view state (default mode)
|
|
18
|
+
treeViewUI: TreeViewUIModel;
|
|
19
|
+
|
|
20
|
+
// Other panel modes added by providers
|
|
21
|
+
customModes = observable.map<string, any>();
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
private owner: { logger?: any },
|
|
25
|
+
treeViewUI: TreeViewUIModel
|
|
26
|
+
) {
|
|
27
|
+
this.treeViewUI = treeViewUI;
|
|
28
|
+
|
|
29
|
+
// Add default tree mode
|
|
30
|
+
this.availableModes.set('tree', {
|
|
31
|
+
id: 'tree',
|
|
32
|
+
name: 'Tree',
|
|
33
|
+
icon: 'folder-tree',
|
|
34
|
+
component: {} as any, // Will be set by consumer
|
|
35
|
+
isAvailable: () => true
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
makeAutoObservable(this);
|
|
39
|
+
this.owner.logger?.info('LeftPanelManagerModel initialized');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Actions
|
|
43
|
+
setCurrentMode = (modeId: string) => {
|
|
44
|
+
if (this.availableModes.has(modeId)) {
|
|
45
|
+
this.currentMode = modeId;
|
|
46
|
+
this.owner.logger?.info(`Left panel mode changed to: ${modeId}`);
|
|
47
|
+
} else {
|
|
48
|
+
this.owner.logger?.warn(`Unknown left panel mode: ${modeId}`);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
addMode = (mode: LeftPanelMode) => {
|
|
53
|
+
this.availableModes.set(mode.id, mode);
|
|
54
|
+
this.owner.logger?.info(`Added left panel mode: ${mode.id}`);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
removeMode = (modeId: string) => {
|
|
58
|
+
if (modeId === 'tree') {
|
|
59
|
+
this.owner.logger?.warn('Cannot remove default tree mode');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.availableModes.delete(modeId);
|
|
64
|
+
this.customModes.delete(modeId);
|
|
65
|
+
|
|
66
|
+
// Switch to tree if current mode was removed
|
|
67
|
+
if (this.currentMode === modeId) {
|
|
68
|
+
this.currentMode = 'tree';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.owner.logger?.info(`Removed left panel mode: ${modeId}`);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
addCustomModeState = (modeId: string, state: any) => {
|
|
75
|
+
this.customModes.set(modeId, state);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Computed
|
|
79
|
+
get availableModesList() {
|
|
80
|
+
return Array.from(this.availableModes.values()).filter(mode =>
|
|
81
|
+
mode.isAvailable ? mode.isAvailable() : true
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get fileBrowserModel() {
|
|
86
|
+
return this.owner as any; // Cast to access FileBrowserModel properties
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get currentModeData() {
|
|
90
|
+
return this.availableModes.get(this.currentMode);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get hasMultipleModes() {
|
|
94
|
+
return this.availableModesList.length > 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get currentUIModel() {
|
|
98
|
+
switch (this.currentMode) {
|
|
99
|
+
case 'tree':
|
|
100
|
+
return this.treeViewUI;
|
|
101
|
+
default:
|
|
102
|
+
return this.customModes.get(this.currentMode) || null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { makeAutoObservable, reaction } from 'mobx';
|
|
2
|
+
|
|
3
|
+
interface NavigationOwner {
|
|
4
|
+
logger?: { info: (message: string) => void } | null;
|
|
5
|
+
leftPanel?: any; // LeftPanelManagerModel
|
|
6
|
+
rightPanel?: any; // RightPanelManagerModel
|
|
7
|
+
selectionManager?: any; // SelectionManagerModel
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class NavigationManagerModel {
|
|
11
|
+
// Observable state
|
|
12
|
+
history: string[] = [];
|
|
13
|
+
historyIndex = -1;
|
|
14
|
+
|
|
15
|
+
// Coordination state
|
|
16
|
+
isUpdatingFromPanels = false; // Prevent infinite loops
|
|
17
|
+
|
|
18
|
+
private owner: NavigationOwner;
|
|
19
|
+
private disposers: (() => void)[] = [];
|
|
20
|
+
|
|
21
|
+
constructor(owner: NavigationOwner) {
|
|
22
|
+
makeAutoObservable(this);
|
|
23
|
+
|
|
24
|
+
this.owner = owner;
|
|
25
|
+
|
|
26
|
+
// Set up coordination reactions
|
|
27
|
+
this.setupCoordinationReactions();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Computed values
|
|
31
|
+
get canGoBack() {
|
|
32
|
+
return this.historyIndex > 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get canGoForward() {
|
|
36
|
+
return this.historyIndex < this.history.length - 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get currentPath() {
|
|
40
|
+
return this.historyIndex >= 0 ? (this.history[this.historyIndex] ?? '/') : '/';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get previousPath(): string | null {
|
|
44
|
+
if (!this.canGoBack) return null;
|
|
45
|
+
return this.history[this.historyIndex - 1] ?? null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get nextPath(): string | null {
|
|
49
|
+
if (!this.canGoForward) return null;
|
|
50
|
+
return this.history[this.historyIndex + 1] ?? null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Actions
|
|
54
|
+
addToHistory = (path: string) => {
|
|
55
|
+
const normalizedPath = this.normalizePath(path);
|
|
56
|
+
this.owner.logger?.info(`addToHistory: ${normalizedPath}`);
|
|
57
|
+
|
|
58
|
+
// Don't add if it's the same as current path
|
|
59
|
+
if (normalizedPath === this.currentPath) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Remove any forward history when adding new path
|
|
64
|
+
if (this.canGoForward) {
|
|
65
|
+
this.history = this.history.slice(0, this.historyIndex + 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add new path
|
|
69
|
+
this.history.push(normalizedPath);
|
|
70
|
+
this.historyIndex = this.history.length - 1;
|
|
71
|
+
|
|
72
|
+
// Limit history size to prevent memory issues
|
|
73
|
+
const maxHistorySize = 100;
|
|
74
|
+
if (this.history.length > maxHistorySize) {
|
|
75
|
+
this.history = this.history.slice(-maxHistorySize);
|
|
76
|
+
this.historyIndex = this.history.length - 1;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
goBack = (): string | null => {
|
|
81
|
+
if (!this.canGoBack) {
|
|
82
|
+
this.owner.logger?.info('goBack: cannot go back');
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.historyIndex--;
|
|
87
|
+
const path = this.currentPath;
|
|
88
|
+
this.owner.logger?.info(`goBack: navigating to ${path}`);
|
|
89
|
+
return path;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
goForward = (): string | null => {
|
|
93
|
+
if (!this.canGoForward) {
|
|
94
|
+
this.owner.logger?.info('goForward: cannot go forward');
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.historyIndex++;
|
|
99
|
+
const path = this.currentPath;
|
|
100
|
+
this.owner.logger?.info(`goForward: navigating to ${path}`);
|
|
101
|
+
return path;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
goToParent = (currentPath: string): string | null => {
|
|
105
|
+
const normalizedPath = this.normalizePath(currentPath);
|
|
106
|
+
const parentPath = this.getParentPath(normalizedPath);
|
|
107
|
+
|
|
108
|
+
if (parentPath && parentPath !== normalizedPath) {
|
|
109
|
+
this.owner.logger?.info(`goToParent: ${normalizedPath} -> ${parentPath}`);
|
|
110
|
+
return parentPath;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.owner.logger?.info(`goToParent: already at root for ${normalizedPath}`);
|
|
114
|
+
return null;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
clearHistory = () => {
|
|
118
|
+
this.owner.logger?.info('clearHistory');
|
|
119
|
+
this.history = [];
|
|
120
|
+
this.historyIndex = -1;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
setCurrentPath = (path: string) => {
|
|
124
|
+
this.addToHistory(path);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
navigateTo = (path: string) => {
|
|
128
|
+
this.addToHistory(path);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Path utilities
|
|
132
|
+
normalizePath = (path: string): string => {
|
|
133
|
+
if (!path || path === '') return '/';
|
|
134
|
+
|
|
135
|
+
// Ensure path starts with /
|
|
136
|
+
let normalized = path.startsWith('/') ? path : '/' + path;
|
|
137
|
+
|
|
138
|
+
// Remove trailing slash unless it's root
|
|
139
|
+
if (normalized.length > 1 && normalized.endsWith('/')) {
|
|
140
|
+
normalized = normalized.slice(0, -1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Resolve .. and . segments
|
|
144
|
+
const segments = normalized.split('/').filter(segment => segment !== '');
|
|
145
|
+
const resolvedSegments: string[] = [];
|
|
146
|
+
|
|
147
|
+
for (const segment of segments) {
|
|
148
|
+
if (segment === '..') {
|
|
149
|
+
if (resolvedSegments.length > 0) {
|
|
150
|
+
resolvedSegments.pop();
|
|
151
|
+
}
|
|
152
|
+
} else if (segment !== '.') {
|
|
153
|
+
resolvedSegments.push(segment);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return resolvedSegments.length === 0 ? '/' : '/' + resolvedSegments.join('/');
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
getParentPath = (path: string): string | null => {
|
|
161
|
+
const normalized = this.normalizePath(path);
|
|
162
|
+
|
|
163
|
+
if (normalized === '/') {
|
|
164
|
+
return null; // Root has no parent
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const lastSlashIndex = normalized.lastIndexOf('/');
|
|
168
|
+
if (lastSlashIndex === 0) {
|
|
169
|
+
return '/'; // Parent is root
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return normalized.substring(0, lastSlashIndex);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
getPathSegments = (path: string): string[] => {
|
|
176
|
+
const normalized = this.normalizePath(path);
|
|
177
|
+
if (normalized === '/') return [];
|
|
178
|
+
|
|
179
|
+
return normalized.split('/').filter(segment => segment !== '');
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
joinPaths = (...paths: string[]): string => {
|
|
183
|
+
const joined = paths.join('/');
|
|
184
|
+
return this.normalizePath(joined);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// Coordination methods
|
|
188
|
+
private setupCoordinationReactions = () => {
|
|
189
|
+
// React to navigation changes for panel coordination
|
|
190
|
+
const navigationReaction = reaction(
|
|
191
|
+
() => this.currentPath,
|
|
192
|
+
(currentPath) => {
|
|
193
|
+
if (this.isUpdatingFromPanels || !currentPath) return;
|
|
194
|
+
|
|
195
|
+
this.owner.logger?.info(`Navigation reaction: path changed to ${currentPath}`);
|
|
196
|
+
|
|
197
|
+
// Update panels based on navigation
|
|
198
|
+
this.coordinateNavigation(currentPath);
|
|
199
|
+
},
|
|
200
|
+
{ name: 'NavigationCoordination' }
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
this.disposers.push(navigationReaction);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
private coordinateNavigation = (path: string) => {
|
|
207
|
+
if (this.isUpdatingFromPanels) return;
|
|
208
|
+
|
|
209
|
+
this.isUpdatingFromPanels = true;
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
// Update right panel to show the new path content
|
|
213
|
+
if (this.owner.rightPanel) {
|
|
214
|
+
// If navigating to a directory, clear selection and show folder content
|
|
215
|
+
this.owner.rightPanel.setSelectedItem(null);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Update selection manager to reflect navigation
|
|
219
|
+
if (this.owner.selectionManager) {
|
|
220
|
+
// Find the item for this path and set it as focused
|
|
221
|
+
// This will be implemented when we have access to the items
|
|
222
|
+
this.owner.logger?.info(`Navigation coordination: ${path}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
} finally {
|
|
226
|
+
this.isUpdatingFromPanels = false;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Panel-specific navigation methods
|
|
231
|
+
navigateFromTreePanel = (path: string) => {
|
|
232
|
+
this.isUpdatingFromPanels = true;
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
this.navigateTo(path);
|
|
236
|
+
|
|
237
|
+
// Update right panel to show folder content
|
|
238
|
+
if (this.owner.rightPanel) {
|
|
239
|
+
this.owner.rightPanel.setSelectedItem(null);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.owner.logger?.info(`Tree panel navigation: ${path}`);
|
|
243
|
+
|
|
244
|
+
} finally {
|
|
245
|
+
this.isUpdatingFromPanels = false;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
navigateFromRightPanel = (path: string) => {
|
|
250
|
+
this.isUpdatingFromPanels = true;
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
this.navigateTo(path);
|
|
254
|
+
|
|
255
|
+
// TODO: Update tree panel expansion when TreeNavigationView supports it
|
|
256
|
+
this.owner.logger?.info(`Right panel navigation: ${path}`);
|
|
257
|
+
|
|
258
|
+
} finally {
|
|
259
|
+
this.isUpdatingFromPanels = false;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Breadcrumb navigation
|
|
264
|
+
navigateFromBreadcrumb = (path: string) => {
|
|
265
|
+
this.isUpdatingFromPanels = true;
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
this.navigateTo(path);
|
|
269
|
+
|
|
270
|
+
// Update both panels
|
|
271
|
+
if (this.owner.rightPanel) {
|
|
272
|
+
this.owner.rightPanel.setSelectedItem(null);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
this.owner.logger?.info(`Breadcrumb navigation: ${path}`);
|
|
276
|
+
|
|
277
|
+
} finally {
|
|
278
|
+
this.isUpdatingFromPanels = false;
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// Enhanced navigation with coordination
|
|
283
|
+
navigateToWithCoordination = (path: string, source: 'tree' | 'right' | 'breadcrumb' | 'history' = 'history') => {
|
|
284
|
+
switch (source) {
|
|
285
|
+
case 'tree':
|
|
286
|
+
this.navigateFromTreePanel(path);
|
|
287
|
+
break;
|
|
288
|
+
case 'right':
|
|
289
|
+
this.navigateFromRightPanel(path);
|
|
290
|
+
break;
|
|
291
|
+
case 'breadcrumb':
|
|
292
|
+
this.navigateFromBreadcrumb(path);
|
|
293
|
+
break;
|
|
294
|
+
default:
|
|
295
|
+
this.navigateTo(path);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// Set selection manager reference after both managers are created
|
|
301
|
+
setSelectionManager = (selectionManager: any) => {
|
|
302
|
+
(this.owner as any).selectionManager = selectionManager;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// Cleanup
|
|
306
|
+
dispose = () => {
|
|
307
|
+
this.disposers.forEach(disposer => disposer());
|
|
308
|
+
this.disposers = [];
|
|
309
|
+
this.clearHistory();
|
|
310
|
+
this.owner.logger?.info('NavigationManagerModel disposed');
|
|
311
|
+
};
|
|
312
|
+
}
|