@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,946 @@
|
|
|
1
|
+
import { makeAutoObservable } from 'mobx';
|
|
2
|
+
import type { TreeProvider, TreeSelectionInfo } from './TreeProvider';
|
|
3
|
+
import type { TreeNodeData, TreeLoadResult, TreeLoadOptions, TreeTableColumn, TreeTableSort, TreeTableExportOptions, TreeSelectionTheme } from '../types/TreeTypes';
|
|
4
|
+
import type { TreeContextMenuItem } from '../types/TreeTypes';
|
|
5
|
+
import { DEFAULT_SELECTION_THEME } from '../utils/SelectionTheme';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import {
|
|
8
|
+
FileText, ImageIcon as Image, Settings, BookOpen, TestTube, Package,
|
|
9
|
+
Palette, Globe, Zap, Music, Archive, GitBranch, Database, Key,
|
|
10
|
+
Code, Braces, Play, Component
|
|
11
|
+
} from 'lucide-react';
|
|
12
|
+
|
|
13
|
+
export class TestTreeProvider implements TreeProvider {
|
|
14
|
+
// Provider metadata (required)
|
|
15
|
+
readonly id = 'test-tree-provider';
|
|
16
|
+
readonly name = 'Test Tree Provider';
|
|
17
|
+
readonly version = '1.0.0';
|
|
18
|
+
|
|
19
|
+
// Configuration (required)
|
|
20
|
+
isMultiSelectEnabled = true;
|
|
21
|
+
readonly isDragDropEnabled = false;
|
|
22
|
+
readonly isVirtualizationEnabled = false;
|
|
23
|
+
readonly isTableViewEnabled = true;
|
|
24
|
+
useCheckboxSelection = false;
|
|
25
|
+
readonly allowPartialSelection = true;
|
|
26
|
+
readonly config = {};
|
|
27
|
+
|
|
28
|
+
// Observable selection theme
|
|
29
|
+
selectionTheme: TreeSelectionTheme = {
|
|
30
|
+
...DEFAULT_SELECTION_THEME,
|
|
31
|
+
colorScheme: 'primary',
|
|
32
|
+
intensity: 'prominent',
|
|
33
|
+
focusStyle: 'ring',
|
|
34
|
+
animated: true,
|
|
35
|
+
persistSelection: true
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Test provider specific settings
|
|
39
|
+
slowLoading = false;
|
|
40
|
+
simulateErrors = false;
|
|
41
|
+
maxDepth = 3;
|
|
42
|
+
nodesPerLevel = 5;
|
|
43
|
+
loadingDelay = 300;
|
|
44
|
+
|
|
45
|
+
// Callbacks (optional)
|
|
46
|
+
onSelectionChange?: (selectionInfo: TreeSelectionInfo) => void;
|
|
47
|
+
onNodeExpansion?: (node: TreeNodeData, isExpanded: boolean) => void;
|
|
48
|
+
onNodeFocus?: (node: TreeNodeData | null) => void;
|
|
49
|
+
|
|
50
|
+
constructor() {
|
|
51
|
+
makeAutoObservable(this, {
|
|
52
|
+
id: false,
|
|
53
|
+
name: false,
|
|
54
|
+
version: false,
|
|
55
|
+
isDragDropEnabled: false,
|
|
56
|
+
isVirtualizationEnabled: false,
|
|
57
|
+
isTableViewEnabled: false,
|
|
58
|
+
config: false,
|
|
59
|
+
// Make isMultiSelectEnabled and useCheckboxSelection observable
|
|
60
|
+
// isMultiSelectEnabled: true (default - observable)
|
|
61
|
+
// useCheckboxSelection: true (default - observable)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Update selection theme reactively
|
|
67
|
+
*/
|
|
68
|
+
updateSelectionTheme = (theme: Partial<TreeSelectionTheme>) => {
|
|
69
|
+
this.selectionTheme = { ...this.selectionTheme, ...theme };
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Update multi-select setting
|
|
74
|
+
*/
|
|
75
|
+
setMultiSelectEnabled = (enabled: boolean) => {
|
|
76
|
+
this.isMultiSelectEnabled = enabled;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Update checkbox selection setting
|
|
81
|
+
*/
|
|
82
|
+
setCheckboxSelection = (enabled: boolean) => {
|
|
83
|
+
this.useCheckboxSelection = enabled;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get selection theme configuration
|
|
88
|
+
*/
|
|
89
|
+
getSelectionTheme(): TreeSelectionTheme {
|
|
90
|
+
return this.selectionTheme;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Load tree nodes
|
|
95
|
+
*/
|
|
96
|
+
async loadNodes(options?: TreeLoadOptions): Promise<TreeLoadResult> {
|
|
97
|
+
await this.simulateDelay();
|
|
98
|
+
|
|
99
|
+
if (this.simulateErrors && Math.random() < 0.3) {
|
|
100
|
+
throw new Error('Simulated loading error - try again!');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const nodes = this.generateMockNodes('', 0);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
nodes,
|
|
107
|
+
hasMore: false,
|
|
108
|
+
totalCount: nodes.length
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Load child nodes for a given parent
|
|
114
|
+
*/
|
|
115
|
+
async loadChildren(node: TreeNodeData, options?: TreeLoadOptions): Promise<TreeLoadResult> {
|
|
116
|
+
await this.simulateDelay();
|
|
117
|
+
|
|
118
|
+
if (this.simulateErrors && Math.random() < 0.3) {
|
|
119
|
+
throw new Error('Simulated loading error - try again!');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Generate children for the given node
|
|
123
|
+
const pathParts = node.path.split('/').filter(Boolean);
|
|
124
|
+
const depth = pathParts.length;
|
|
125
|
+
|
|
126
|
+
// Only generate children if we haven't exceeded max depth
|
|
127
|
+
if (depth >= this.maxDepth) {
|
|
128
|
+
return {
|
|
129
|
+
nodes: [],
|
|
130
|
+
hasMore: false,
|
|
131
|
+
totalCount: 0
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const children = this.generateMockNodes(node.path, depth);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
nodes: children,
|
|
139
|
+
hasMore: false,
|
|
140
|
+
totalCount: children.length
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Refresh tree data
|
|
146
|
+
*/
|
|
147
|
+
async refresh(path?: string): Promise<TreeLoadResult> {
|
|
148
|
+
return path ? this.loadChildren({ path } as TreeNodeData) : this.loadNodes();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
canExpand(node: TreeNodeData): boolean {
|
|
152
|
+
return node.type === 'directory' && (node.hasChildren ?? true);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
canSelect(node: TreeNodeData): boolean {
|
|
156
|
+
return !node.disabled;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Context menu support
|
|
160
|
+
getNodeContextMenu(node: TreeNodeData): TreeContextMenuItem[] {
|
|
161
|
+
// Enhanced context menus based on node type and file extension
|
|
162
|
+
const baseItems: TreeContextMenuItem[] = [];
|
|
163
|
+
|
|
164
|
+
if (node.type === 'directory') {
|
|
165
|
+
// Folder-specific menus
|
|
166
|
+
if (node.name.includes('components')) {
|
|
167
|
+
// React Components folder
|
|
168
|
+
return [
|
|
169
|
+
{ id: 'open', label: 'Open Folder' },
|
|
170
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
171
|
+
{ id: 'new-component', label: 'New React Component' },
|
|
172
|
+
{ id: 'new-hook', label: 'New Custom Hook' },
|
|
173
|
+
{ id: 'new-story', label: 'New Storybook Story' },
|
|
174
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
175
|
+
{ id: 'run-tests', label: 'Run Component Tests' },
|
|
176
|
+
{ id: 'build-docs', label: 'Generate Docs' },
|
|
177
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
178
|
+
{ id: 'rename', label: 'Rename Folder' },
|
|
179
|
+
{ id: 'delete', label: 'Delete Folder' }
|
|
180
|
+
];
|
|
181
|
+
} else if (node.name.includes('config')) {
|
|
182
|
+
// Configuration folder
|
|
183
|
+
return [
|
|
184
|
+
{ id: 'open', label: 'Open Config Folder' },
|
|
185
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
186
|
+
{ id: 'new-env', label: 'New Environment File' },
|
|
187
|
+
{ id: 'new-config', label: 'New Config File' },
|
|
188
|
+
{ id: 'validate-config', label: 'Validate Configuration' },
|
|
189
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
190
|
+
{ id: 'backup-config', label: 'Backup Configuration' },
|
|
191
|
+
{ id: 'restore-config', label: 'Restore from Backup' },
|
|
192
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
193
|
+
{ id: 'rename', label: 'Rename Folder' },
|
|
194
|
+
{ id: 'delete', label: 'Delete Folder' }
|
|
195
|
+
];
|
|
196
|
+
} else {
|
|
197
|
+
// General folder menu
|
|
198
|
+
return [
|
|
199
|
+
{ id: 'open', label: 'Open Folder' },
|
|
200
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
201
|
+
{ id: 'new-file', label: 'New File' },
|
|
202
|
+
{ id: 'new-folder', label: 'New Folder' },
|
|
203
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
204
|
+
{ id: 'import-files', label: 'Import Files' },
|
|
205
|
+
{ id: 'export-folder', label: 'Export Folder' },
|
|
206
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
207
|
+
{ id: 'rename', label: 'Rename Folder' },
|
|
208
|
+
{ id: 'delete', label: 'Delete Folder' },
|
|
209
|
+
{ id: 'separator-4', label: '', type: 'separator' },
|
|
210
|
+
{ id: 'copy', label: 'Copy Folder' },
|
|
211
|
+
{ id: 'cut', label: 'Cut Folder' }
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// File-specific menus based on extension
|
|
217
|
+
const fileName = node.name;
|
|
218
|
+
const fileExt = fileName.split('.').pop()?.toLowerCase() || '';
|
|
219
|
+
|
|
220
|
+
switch (fileExt) {
|
|
221
|
+
case 'js':
|
|
222
|
+
case 'jsx':
|
|
223
|
+
// JavaScript/React files
|
|
224
|
+
return [
|
|
225
|
+
{ id: 'open', label: 'Open in Editor' },
|
|
226
|
+
{ id: 'open-preview', label: 'Open in Preview' },
|
|
227
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
228
|
+
{ id: 'run-file', label: 'Run JavaScript' },
|
|
229
|
+
{ id: 'debug-file', label: 'Debug in Browser' },
|
|
230
|
+
{ id: 'format-code', label: 'Format with Prettier' },
|
|
231
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
232
|
+
{ id: 'create-test', label: 'Create Test File' },
|
|
233
|
+
{ id: 'run-tests', label: 'Run Tests' },
|
|
234
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
235
|
+
{ id: 'rename', label: 'Rename File' },
|
|
236
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
237
|
+
{ id: 'delete', label: 'Delete File' }
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
case 'ts':
|
|
241
|
+
case 'tsx':
|
|
242
|
+
// TypeScript files
|
|
243
|
+
return [
|
|
244
|
+
{ id: 'open', label: 'Open in Editor' },
|
|
245
|
+
{ id: 'open-preview', label: 'Open in Preview' },
|
|
246
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
247
|
+
{ id: 'compile-ts', label: 'Compile TypeScript' },
|
|
248
|
+
{ id: 'type-check', label: 'Run Type Check' },
|
|
249
|
+
{ id: 'generate-types', label: 'Generate Type Definitions' },
|
|
250
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
251
|
+
{ id: 'create-test', label: 'Create Test File' },
|
|
252
|
+
{ id: 'run-tests', label: 'Run Tests' },
|
|
253
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
254
|
+
{ id: 'rename', label: 'Rename File' },
|
|
255
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
256
|
+
{ id: 'delete', label: 'Delete File' }
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
case 'css':
|
|
260
|
+
case 'scss':
|
|
261
|
+
case 'sass':
|
|
262
|
+
case 'less':
|
|
263
|
+
// Stylesheet files
|
|
264
|
+
return [
|
|
265
|
+
{ id: 'open', label: 'Open in Editor' },
|
|
266
|
+
{ id: 'open-preview', label: 'Live Preview' },
|
|
267
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
268
|
+
{ id: 'compile-css', label: 'Compile Stylesheet' },
|
|
269
|
+
{ id: 'optimize-css', label: 'Optimize CSS' },
|
|
270
|
+
{ id: 'validate-css', label: 'Validate CSS' },
|
|
271
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
272
|
+
{ id: 'extract-vars', label: 'Extract CSS Variables' },
|
|
273
|
+
{ id: 'generate-rtl', label: 'Generate RTL Version' },
|
|
274
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
275
|
+
{ id: 'rename', label: 'Rename File' },
|
|
276
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
277
|
+
{ id: 'delete', label: 'Delete File' }
|
|
278
|
+
];
|
|
279
|
+
|
|
280
|
+
case 'md':
|
|
281
|
+
case 'mdx':
|
|
282
|
+
// Markdown files
|
|
283
|
+
return [
|
|
284
|
+
{ id: 'open', label: 'Open in Editor' },
|
|
285
|
+
{ id: 'open-preview', label: 'Preview Markdown' },
|
|
286
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
287
|
+
{ id: 'export-html', label: 'Export to HTML' },
|
|
288
|
+
{ id: 'export-pdf', label: 'Export to PDF' },
|
|
289
|
+
{ id: 'check-links', label: 'Check Links' },
|
|
290
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
291
|
+
{ id: 'toc-generate', label: 'Generate Table of Contents' },
|
|
292
|
+
{ id: 'word-count', label: 'Word Count & Stats' },
|
|
293
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
294
|
+
{ id: 'rename', label: 'Rename File' },
|
|
295
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
296
|
+
{ id: 'delete', label: 'Delete File' }
|
|
297
|
+
];
|
|
298
|
+
|
|
299
|
+
case 'json':
|
|
300
|
+
// JSON configuration files
|
|
301
|
+
return [
|
|
302
|
+
{ id: 'open', label: 'Open in Editor' },
|
|
303
|
+
{ id: 'open-viewer', label: 'Open JSON Viewer' },
|
|
304
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
305
|
+
{ id: 'validate-json', label: 'Validate JSON' },
|
|
306
|
+
{ id: 'format-json', label: 'Format JSON' },
|
|
307
|
+
{ id: 'minify-json', label: 'Minify JSON' },
|
|
308
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
309
|
+
{ id: 'compare-json', label: 'Compare with...' },
|
|
310
|
+
{ id: 'schema-validate', label: 'Validate Against Schema' },
|
|
311
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
312
|
+
{ id: 'rename', label: 'Rename File' },
|
|
313
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
314
|
+
{ id: 'delete', label: 'Delete File' }
|
|
315
|
+
];
|
|
316
|
+
|
|
317
|
+
case 'jpg':
|
|
318
|
+
case 'jpeg':
|
|
319
|
+
case 'png':
|
|
320
|
+
case 'gif':
|
|
321
|
+
case 'svg':
|
|
322
|
+
case 'webp':
|
|
323
|
+
// Image files
|
|
324
|
+
return [
|
|
325
|
+
{ id: 'open', label: 'Open Image' },
|
|
326
|
+
{ id: 'open-editor', label: 'Edit in Image Editor' },
|
|
327
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
328
|
+
{ id: 'resize-image', label: 'Resize Image' },
|
|
329
|
+
{ id: 'compress-image', label: 'Compress Image' },
|
|
330
|
+
{ id: 'convert-format', label: 'Convert Format' },
|
|
331
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
332
|
+
{ id: 'image-info', label: 'Image Properties' },
|
|
333
|
+
{ id: 'copy-url', label: 'Copy Image URL' },
|
|
334
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
335
|
+
{ id: 'rename', label: 'Rename File' },
|
|
336
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
337
|
+
{ id: 'delete', label: 'Delete File' }
|
|
338
|
+
];
|
|
339
|
+
|
|
340
|
+
default:
|
|
341
|
+
// Generic file menu
|
|
342
|
+
return [
|
|
343
|
+
{ id: 'open', label: 'Open File' },
|
|
344
|
+
{ id: 'open-with', label: 'Open With...' },
|
|
345
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
346
|
+
{ id: 'properties', label: 'File Properties' },
|
|
347
|
+
{ id: 'permissions', label: 'Change Permissions' },
|
|
348
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
349
|
+
{ id: 'rename', label: 'Rename File' },
|
|
350
|
+
{ id: 'duplicate', label: 'Duplicate File' },
|
|
351
|
+
{ id: 'delete', label: 'Delete File' },
|
|
352
|
+
{ id: 'separator-3', label: '', type: 'separator' },
|
|
353
|
+
{ id: 'copy', label: 'Copy File' },
|
|
354
|
+
{ id: 'cut', label: 'Cut File' }
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
getMultiNodeContextMenu(nodes: TreeNodeData[]): TreeContextMenuItem[] {
|
|
360
|
+
// Enhanced multi-selection menus
|
|
361
|
+
const hasFiles = nodes.some(n => n.type === 'file');
|
|
362
|
+
const hasFolders = nodes.some(n => n.type === 'directory');
|
|
363
|
+
const allSameType = hasFiles && !hasFolders || hasFolders && !hasFiles;
|
|
364
|
+
|
|
365
|
+
if (allSameType && hasFiles) {
|
|
366
|
+
// All files selected
|
|
367
|
+
return [
|
|
368
|
+
{ id: 'open-all', label: `Open ${nodes.length} Files` },
|
|
369
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
370
|
+
{ id: 'compress-files', label: `Create Archive (${nodes.length} files)` },
|
|
371
|
+
{ id: 'copy-paths', label: 'Copy File Paths' },
|
|
372
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
373
|
+
{ id: 'copy-all', label: `Copy ${nodes.length} Files` },
|
|
374
|
+
{ id: 'cut-all', label: `Cut ${nodes.length} Files` },
|
|
375
|
+
{ id: 'delete-all', label: `Delete ${nodes.length} Files` }
|
|
376
|
+
];
|
|
377
|
+
} else if (allSameType && hasFolders) {
|
|
378
|
+
// All folders selected
|
|
379
|
+
return [
|
|
380
|
+
{ id: 'open-all', label: `Open ${nodes.length} Folders` },
|
|
381
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
382
|
+
{ id: 'merge-folders', label: 'Merge Folders' },
|
|
383
|
+
{ id: 'compare-folders', label: 'Compare Folders' },
|
|
384
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
385
|
+
{ id: 'copy-all', label: `Copy ${nodes.length} Folders` },
|
|
386
|
+
{ id: 'cut-all', label: `Cut ${nodes.length} Folders` },
|
|
387
|
+
{ id: 'delete-all', label: `Delete ${nodes.length} Folders` }
|
|
388
|
+
];
|
|
389
|
+
} else {
|
|
390
|
+
// Mixed selection (files and folders)
|
|
391
|
+
return [
|
|
392
|
+
{ id: 'open-all', label: `Open ${nodes.length} Items` },
|
|
393
|
+
{ id: 'separator-1', label: '', type: 'separator' },
|
|
394
|
+
{ id: 'compress-all', label: `Create Archive (${nodes.length} items)` },
|
|
395
|
+
{ id: 'copy-info', label: 'Copy Selection Info' },
|
|
396
|
+
{ id: 'separator-2', label: '', type: 'separator' },
|
|
397
|
+
{ id: 'copy-all', label: `Copy ${nodes.length} Items` },
|
|
398
|
+
{ id: 'cut-all', label: `Cut ${nodes.length} Items` },
|
|
399
|
+
{ id: 'delete-all', label: `Delete ${nodes.length} Items` }
|
|
400
|
+
];
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
onContextMenuAction(menuItemId: string, nodes: TreeNodeData[]): void {
|
|
405
|
+
const nodeNames = nodes.map(n => n.name).join(', ');
|
|
406
|
+
console.log(`🎯 Context menu action: ${menuItemId} on nodes: ${nodeNames}`);
|
|
407
|
+
|
|
408
|
+
// Enhanced action handling with more detailed logging
|
|
409
|
+
switch (menuItemId) {
|
|
410
|
+
// File operations
|
|
411
|
+
case 'open':
|
|
412
|
+
case 'open-all':
|
|
413
|
+
console.log(`📂 Opening: ${nodeNames}`);
|
|
414
|
+
alert(`Opening: ${nodeNames}`);
|
|
415
|
+
break;
|
|
416
|
+
case 'open-preview':
|
|
417
|
+
console.log(`👁️ Opening preview for: ${nodeNames}`);
|
|
418
|
+
alert(`Preview mode for: ${nodeNames}`);
|
|
419
|
+
break;
|
|
420
|
+
case 'open-editor':
|
|
421
|
+
console.log(`✏️ Opening in editor: ${nodeNames}`);
|
|
422
|
+
alert(`Editor opened for: ${nodeNames}`);
|
|
423
|
+
break;
|
|
424
|
+
|
|
425
|
+
// Development operations
|
|
426
|
+
case 'run-file':
|
|
427
|
+
case 'run-tests':
|
|
428
|
+
console.log(`▶️ Running: ${nodeNames}`);
|
|
429
|
+
alert(`Executing: ${nodeNames}`);
|
|
430
|
+
break;
|
|
431
|
+
case 'debug-file':
|
|
432
|
+
console.log(`🐛 Debugging: ${nodeNames}`);
|
|
433
|
+
alert(`Debug session started for: ${nodeNames}`);
|
|
434
|
+
break;
|
|
435
|
+
case 'compile-ts':
|
|
436
|
+
case 'compile-css':
|
|
437
|
+
console.log(`🔨 Compiling: ${nodeNames}`);
|
|
438
|
+
alert(`Compilation started for: ${nodeNames}`);
|
|
439
|
+
break;
|
|
440
|
+
case 'format-code':
|
|
441
|
+
case 'format-json':
|
|
442
|
+
console.log(`🎨 Formatting: ${nodeNames}`);
|
|
443
|
+
alert(`Code formatted: ${nodeNames}`);
|
|
444
|
+
break;
|
|
445
|
+
case 'type-check':
|
|
446
|
+
console.log(`🔍 Type checking: ${nodeNames}`);
|
|
447
|
+
alert(`Type check completed for: ${nodeNames}`);
|
|
448
|
+
break;
|
|
449
|
+
|
|
450
|
+
// Creation operations
|
|
451
|
+
case 'new-file':
|
|
452
|
+
case 'new-folder':
|
|
453
|
+
case 'new-component':
|
|
454
|
+
case 'new-hook':
|
|
455
|
+
case 'new-story':
|
|
456
|
+
console.log(`➕ Creating new ${menuItemId.replace('new-', '')} in: ${nodeNames}`);
|
|
457
|
+
alert(`Creating new ${menuItemId.replace('new-', '')} in: ${nodeNames}`);
|
|
458
|
+
break;
|
|
459
|
+
|
|
460
|
+
// Export/Import operations
|
|
461
|
+
case 'export-html':
|
|
462
|
+
case 'export-pdf':
|
|
463
|
+
console.log(`📤 Exporting ${menuItemId.replace('export-', '')}: ${nodeNames}`);
|
|
464
|
+
alert(`Exporting ${menuItemId.replace('export-', '').toUpperCase()}: ${nodeNames}`);
|
|
465
|
+
break;
|
|
466
|
+
case 'import-files':
|
|
467
|
+
console.log(`📥 Importing files to: ${nodeNames}`);
|
|
468
|
+
alert(`Import dialog opened for: ${nodeNames}`);
|
|
469
|
+
break;
|
|
470
|
+
|
|
471
|
+
// File management
|
|
472
|
+
case 'rename':
|
|
473
|
+
console.log(`✏️ Renaming: ${nodeNames}`);
|
|
474
|
+
alert(`Rename dialog for: ${nodeNames}`);
|
|
475
|
+
break;
|
|
476
|
+
case 'duplicate':
|
|
477
|
+
console.log(`📋 Duplicating: ${nodeNames}`);
|
|
478
|
+
alert(`Duplicated: ${nodeNames}`);
|
|
479
|
+
break;
|
|
480
|
+
case 'delete':
|
|
481
|
+
case 'delete-all':
|
|
482
|
+
console.log(`🗑️ Deleting: ${nodeNames}`);
|
|
483
|
+
alert(`Deleted: ${nodeNames}`);
|
|
484
|
+
break;
|
|
485
|
+
case 'copy':
|
|
486
|
+
case 'copy-all':
|
|
487
|
+
console.log(`📋 Copying: ${nodeNames}`);
|
|
488
|
+
alert(`Copied to clipboard: ${nodeNames}`);
|
|
489
|
+
break;
|
|
490
|
+
case 'cut':
|
|
491
|
+
case 'cut-all':
|
|
492
|
+
console.log(`✂️ Cutting: ${nodeNames}`);
|
|
493
|
+
alert(`Cut to clipboard: ${nodeNames}`);
|
|
494
|
+
break;
|
|
495
|
+
|
|
496
|
+
// Specialized operations
|
|
497
|
+
case 'validate-json':
|
|
498
|
+
case 'validate-css':
|
|
499
|
+
case 'validate-config':
|
|
500
|
+
console.log(`✅ Validating: ${nodeNames}`);
|
|
501
|
+
alert(`Validation passed for: ${nodeNames}`);
|
|
502
|
+
break;
|
|
503
|
+
case 'compress-image':
|
|
504
|
+
case 'compress-files':
|
|
505
|
+
case 'compress-all':
|
|
506
|
+
console.log(`🗜️ Compressing: ${nodeNames}`);
|
|
507
|
+
alert(`Compression completed for: ${nodeNames}`);
|
|
508
|
+
break;
|
|
509
|
+
case 'image-info':
|
|
510
|
+
case 'properties':
|
|
511
|
+
console.log(`ℹ️ Showing properties for: ${nodeNames}`);
|
|
512
|
+
alert(`Properties: ${nodeNames}\nSize: 1.2MB\nType: ${nodes[0]?.type || 'unknown'}\nModified: ${nodes[0]?.lastModified?.toLocaleDateString() || 'unknown'}`);
|
|
513
|
+
break;
|
|
514
|
+
|
|
515
|
+
default:
|
|
516
|
+
console.log(`❓ Unknown action: ${menuItemId}`);
|
|
517
|
+
alert(`Action executed: ${menuItemId} on ${nodeNames}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Table view configuration
|
|
522
|
+
getTableColumns(): TreeTableColumn[] {
|
|
523
|
+
return [
|
|
524
|
+
{
|
|
525
|
+
id: 'name',
|
|
526
|
+
label: 'Name',
|
|
527
|
+
dataKey: 'name',
|
|
528
|
+
width: '300px',
|
|
529
|
+
sortable: true,
|
|
530
|
+
filterable: true,
|
|
531
|
+
isTreeColumn: true,
|
|
532
|
+
align: 'left'
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
id: 'type',
|
|
536
|
+
label: 'Type',
|
|
537
|
+
dataKey: 'type',
|
|
538
|
+
width: '100px',
|
|
539
|
+
sortable: true,
|
|
540
|
+
filterable: true,
|
|
541
|
+
align: 'left',
|
|
542
|
+
formatValue: (value: string) => value === 'directory' ? 'Folder' : 'File'
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: 'size',
|
|
546
|
+
label: 'Size',
|
|
547
|
+
dataKey: 'size',
|
|
548
|
+
width: '100px',
|
|
549
|
+
sortable: true,
|
|
550
|
+
align: 'right',
|
|
551
|
+
formatValue: (value: number, node: TreeNodeData) => {
|
|
552
|
+
if (node.type === 'directory') return '-';
|
|
553
|
+
if (!value) return '-';
|
|
554
|
+
|
|
555
|
+
if (value < 1024) return `${value} B`;
|
|
556
|
+
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} KB`;
|
|
557
|
+
if (value < 1024 * 1024 * 1024) return `${(value / (1024 * 1024)).toFixed(1)} MB`;
|
|
558
|
+
return `${(value / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
id: 'lastModified',
|
|
563
|
+
label: 'Modified',
|
|
564
|
+
dataKey: 'lastModified',
|
|
565
|
+
width: '150px',
|
|
566
|
+
sortable: true,
|
|
567
|
+
align: 'left',
|
|
568
|
+
formatValue: (value: Date) => {
|
|
569
|
+
if (!value) return '-';
|
|
570
|
+
return value.toLocaleDateString();
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
id: 'path',
|
|
575
|
+
label: 'Path',
|
|
576
|
+
dataKey: 'path',
|
|
577
|
+
width: '200px',
|
|
578
|
+
sortable: true,
|
|
579
|
+
filterable: true,
|
|
580
|
+
align: 'left'
|
|
581
|
+
}
|
|
582
|
+
];
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
getDefaultTableSort(): TreeTableSort {
|
|
586
|
+
return {
|
|
587
|
+
columnId: 'name',
|
|
588
|
+
direction: 'asc'
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
onTableSort(sort: TreeTableSort | null): void {
|
|
593
|
+
console.log('Table sort changed:', sort);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
async onTableExport(options: TreeTableExportOptions): Promise<string | void> {
|
|
597
|
+
console.log('Table export requested:', options);
|
|
598
|
+
alert(`Export to ${options.format.toUpperCase()} format requested`);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
private async simulateDelay(): Promise<void> {
|
|
602
|
+
const delay = this.slowLoading ? 1000 : this.loadingDelay;
|
|
603
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
private generateMockNodes(parentPath: string, depth: number): TreeNodeData[] {
|
|
607
|
+
if (depth >= this.maxDepth) {
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const nodes: TreeNodeData[] = [];
|
|
612
|
+
|
|
613
|
+
// Enhanced file types with better variety for icon demo
|
|
614
|
+
const fileTypes = [
|
|
615
|
+
// Web Development
|
|
616
|
+
'js', 'jsx', 'ts', 'tsx', 'html', 'css', 'scss', 'sass', 'less',
|
|
617
|
+
// Documentation & Content
|
|
618
|
+
'md', 'mdx', 'txt', 'pdf',
|
|
619
|
+
// Data & Config
|
|
620
|
+
'json', 'yml', 'yaml', 'xml', 'env', 'config',
|
|
621
|
+
// Images
|
|
622
|
+
'jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'ico',
|
|
623
|
+
// Media
|
|
624
|
+
'mp4', 'mp3', 'wav', 'avi',
|
|
625
|
+
// Archives & Executables
|
|
626
|
+
'zip', 'tar', 'gz', 'exe', 'app', 'dmg',
|
|
627
|
+
// Development
|
|
628
|
+
'py', 'php', 'java', 'cpp', 'c', 'go', 'rs', 'rb'
|
|
629
|
+
];
|
|
630
|
+
|
|
631
|
+
// Enhanced folder names with special types for icon demo
|
|
632
|
+
const folderTypes = [
|
|
633
|
+
// Development Folders
|
|
634
|
+
{ name: 'components', type: 'react' },
|
|
635
|
+
{ name: 'hooks', type: 'react' },
|
|
636
|
+
{ name: 'pages', type: 'react' },
|
|
637
|
+
{ name: 'utils', type: 'code' },
|
|
638
|
+
{ name: 'lib', type: 'code' },
|
|
639
|
+
{ name: 'src', type: 'source' },
|
|
640
|
+
// Config & Build
|
|
641
|
+
{ name: 'config', type: 'config' },
|
|
642
|
+
{ name: 'build', type: 'build' },
|
|
643
|
+
{ name: 'dist', type: 'build' },
|
|
644
|
+
{ name: '.github', type: 'git' },
|
|
645
|
+
{ name: '.vscode', type: 'vscode' },
|
|
646
|
+
// Assets & Media
|
|
647
|
+
{ name: 'assets', type: 'assets' },
|
|
648
|
+
{ name: 'images', type: 'images' },
|
|
649
|
+
{ name: 'media', type: 'media' },
|
|
650
|
+
{ name: 'public', type: 'public' },
|
|
651
|
+
// Documentation & Tests
|
|
652
|
+
{ name: 'docs', type: 'docs' },
|
|
653
|
+
{ name: 'tests', type: 'test' },
|
|
654
|
+
{ name: '__tests__', type: 'test' },
|
|
655
|
+
// Node.js specific
|
|
656
|
+
{ name: 'node_modules', type: 'node_modules' }
|
|
657
|
+
];
|
|
658
|
+
|
|
659
|
+
for (let i = 0; i < this.nodesPerLevel; i++) {
|
|
660
|
+
const nodeId = `${parentPath || 'root'}-${depth}-${i}`.replace(/[^a-zA-Z0-9-_]/g, '-');
|
|
661
|
+
|
|
662
|
+
const shouldBeFolder = depth < this.maxDepth - 1 && (i < this.nodesPerLevel / 2 || Math.random() < 0.4);
|
|
663
|
+
|
|
664
|
+
if (shouldBeFolder) {
|
|
665
|
+
const folderType = folderTypes[i % folderTypes.length] || { name: `folder-${i}`, type: 'default' };
|
|
666
|
+
const folderPath = parentPath ? `${parentPath}/${folderType.name}` : `/${folderType.name}`;
|
|
667
|
+
|
|
668
|
+
nodes.push({
|
|
669
|
+
id: nodeId,
|
|
670
|
+
name: folderType.name,
|
|
671
|
+
path: folderPath,
|
|
672
|
+
type: 'directory',
|
|
673
|
+
hasChildren: depth < this.maxDepth - 1,
|
|
674
|
+
lastModified: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000),
|
|
675
|
+
// Add metadata for enhanced demo
|
|
676
|
+
metadata: {
|
|
677
|
+
folderType: folderType.type,
|
|
678
|
+
description: this.getFolderDescription(folderType.type)
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
} else {
|
|
682
|
+
const fileType = fileTypes[i % fileTypes.length] || 'txt';
|
|
683
|
+
const fileName = this.generateFileName(fileType, i);
|
|
684
|
+
const filePath = parentPath ? `${parentPath}/${fileName}` : `/${fileName}`;
|
|
685
|
+
|
|
686
|
+
nodes.push({
|
|
687
|
+
id: nodeId,
|
|
688
|
+
name: fileName,
|
|
689
|
+
path: filePath,
|
|
690
|
+
type: 'file',
|
|
691
|
+
hasChildren: false,
|
|
692
|
+
size: Math.floor(Math.random() * 1000000) + 1024,
|
|
693
|
+
lastModified: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000),
|
|
694
|
+
// Add metadata for enhanced demo
|
|
695
|
+
metadata: {
|
|
696
|
+
fileType: fileType,
|
|
697
|
+
category: this.getFileCategory(fileType),
|
|
698
|
+
description: this.getFileDescription(fileType)
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return nodes;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
private generateFileName(fileType: string, index: number): string {
|
|
708
|
+
const fileNames: Record<string, string[]> = {
|
|
709
|
+
'js': ['utils', 'helpers', 'config', 'index', 'main'],
|
|
710
|
+
'jsx': ['App', 'Component', 'Button', 'Modal', 'Form'],
|
|
711
|
+
'ts': ['types', 'interfaces', 'utils', 'service', 'api'],
|
|
712
|
+
'tsx': ['HomePage', 'UserCard', 'Navigation', 'Layout', 'Dashboard'],
|
|
713
|
+
'css': ['styles', 'main', 'theme', 'reset', 'variables'],
|
|
714
|
+
'scss': ['app', 'components', 'layout', 'mixins', 'variables'],
|
|
715
|
+
'md': ['README', 'CHANGELOG', 'CONTRIBUTING', 'DOCS', 'API'],
|
|
716
|
+
'json': ['package', 'tsconfig', 'config', 'settings', 'data'],
|
|
717
|
+
'yml': ['docker-compose', 'config', 'ci', 'deployment', 'settings'],
|
|
718
|
+
'py': ['main', 'utils', 'models', 'views', 'tests'],
|
|
719
|
+
'jpg': ['hero-image', 'profile', 'banner', 'thumbnail', 'cover'],
|
|
720
|
+
'png': ['logo', 'icon', 'screenshot', 'diagram', 'chart']
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
const names = fileNames[fileType] || ['file'];
|
|
724
|
+
const baseName = names[index % names.length];
|
|
725
|
+
|
|
726
|
+
return `${baseName}.${fileType}`;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
private getFolderDescription(folderType: string): string {
|
|
731
|
+
const descriptions: Record<string, string> = {
|
|
732
|
+
'react': 'React components and hooks',
|
|
733
|
+
'source': 'Source code files',
|
|
734
|
+
'code': 'Utility functions and libraries',
|
|
735
|
+
'config': 'Configuration files',
|
|
736
|
+
'build': 'Build output and artifacts',
|
|
737
|
+
'git': 'Git workflow configurations',
|
|
738
|
+
'vscode': 'VS Code editor settings',
|
|
739
|
+
'assets': 'Project assets and resources',
|
|
740
|
+
'images': 'Image files and graphics',
|
|
741
|
+
'media': 'Media files (video, audio)',
|
|
742
|
+
'public': 'Public static files',
|
|
743
|
+
'docs': 'Documentation files',
|
|
744
|
+
'test': 'Test files and specs',
|
|
745
|
+
'node_modules': 'Node.js dependencies',
|
|
746
|
+
'default': 'General folder'
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
return descriptions[folderType] || 'General folder';
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
private getFileCategory(fileType: string): string {
|
|
754
|
+
const categories: Record<string, string> = {
|
|
755
|
+
// Web Development
|
|
756
|
+
'js': 'JavaScript', 'jsx': 'React', 'ts': 'TypeScript', 'tsx': 'React TypeScript',
|
|
757
|
+
'css': 'Stylesheet', 'scss': 'Sass', 'sass': 'Sass', 'less': 'Less',
|
|
758
|
+
'html': 'Markup', 'xml': 'Markup', 'svg': 'Vector Graphics',
|
|
759
|
+
|
|
760
|
+
// Documentation
|
|
761
|
+
'md': 'Markdown', 'txt': 'Text', 'pdf': 'Document',
|
|
762
|
+
|
|
763
|
+
// Configuration
|
|
764
|
+
'json': 'Data', 'yml': 'Config', 'yaml': 'Config', 'env': 'Environment',
|
|
765
|
+
|
|
766
|
+
// Media
|
|
767
|
+
'jpg': 'Image', 'png': 'Image', 'gif': 'Image',
|
|
768
|
+
'mp3': 'Audio', 'mp4': 'Video',
|
|
769
|
+
|
|
770
|
+
// Programming
|
|
771
|
+
'py': 'Python', 'php': 'PHP', 'java': 'Java', 'cpp': 'C++', 'go': 'Go',
|
|
772
|
+
|
|
773
|
+
// Archives
|
|
774
|
+
'zip': 'Archive', 'tar': 'Archive',
|
|
775
|
+
|
|
776
|
+
// Default
|
|
777
|
+
'default': 'File'
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
return categories[fileType] || categories['default'] || 'File';
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
private getFileDescription(fileType: string): string {
|
|
784
|
+
const descriptions: Record<string, string> = {
|
|
785
|
+
'js': 'JavaScript source file',
|
|
786
|
+
'jsx': 'React component file',
|
|
787
|
+
'ts': 'TypeScript source file',
|
|
788
|
+
'tsx': 'React TypeScript component',
|
|
789
|
+
'css': 'Cascading Style Sheet',
|
|
790
|
+
'scss': 'Sass stylesheet',
|
|
791
|
+
'html': 'HTML markup file',
|
|
792
|
+
'md': 'Markdown documentation',
|
|
793
|
+
'json': 'JSON data file',
|
|
794
|
+
'py': 'Python script',
|
|
795
|
+
'jpg': 'JPEG image file',
|
|
796
|
+
'png': 'PNG image file',
|
|
797
|
+
'mp3': 'MP3 audio file',
|
|
798
|
+
'zip': 'Compressed archive'
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
return descriptions[fileType] || `${fileType.toUpperCase()} file`;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Get custom icon for a node based on file type and category
|
|
806
|
+
*/
|
|
807
|
+
getNodeIcon(node: TreeNodeData): string | React.ComponentType<any> {
|
|
808
|
+
// If it's a directory/folder, use special folder icons
|
|
809
|
+
if (node.type === 'directory') {
|
|
810
|
+
// Special folder icons based on name
|
|
811
|
+
if (node.name.includes('components')) {
|
|
812
|
+
return Component; // React component folder
|
|
813
|
+
}
|
|
814
|
+
if (node.name.includes('assets') || node.name.includes('images')) {
|
|
815
|
+
return Image;
|
|
816
|
+
}
|
|
817
|
+
if (node.name.includes('config') || node.name.includes('settings')) {
|
|
818
|
+
return Settings;
|
|
819
|
+
}
|
|
820
|
+
if (node.name.includes('docs') || node.name.includes('documentation')) {
|
|
821
|
+
return BookOpen;
|
|
822
|
+
}
|
|
823
|
+
if (node.name.includes('test') || node.name.includes('__tests__')) {
|
|
824
|
+
return TestTube;
|
|
825
|
+
}
|
|
826
|
+
if (node.name.includes('lib') || node.name.includes('library')) {
|
|
827
|
+
return Package;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Default folder icons (already handled by TreeNodeList)
|
|
831
|
+
return 'folder';
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// File icons based on extension
|
|
835
|
+
const extension = node.name.split('.').pop() || '';
|
|
836
|
+
|
|
837
|
+
switch (extension.toLowerCase()) {
|
|
838
|
+
// Web Development
|
|
839
|
+
case 'js':
|
|
840
|
+
case 'jsx':
|
|
841
|
+
return FileText; // JavaScript icon
|
|
842
|
+
|
|
843
|
+
case 'ts':
|
|
844
|
+
case 'tsx':
|
|
845
|
+
return Code; // TypeScript icon
|
|
846
|
+
|
|
847
|
+
case 'html':
|
|
848
|
+
case 'htm':
|
|
849
|
+
return Globe; // HTML icon
|
|
850
|
+
|
|
851
|
+
case 'css':
|
|
852
|
+
case 'scss':
|
|
853
|
+
case 'sass':
|
|
854
|
+
case 'less':
|
|
855
|
+
return Palette; // Stylesheet icon
|
|
856
|
+
|
|
857
|
+
// Documentation
|
|
858
|
+
case 'md':
|
|
859
|
+
case 'mdx':
|
|
860
|
+
return FileText; // Markdown icon
|
|
861
|
+
|
|
862
|
+
case 'txt':
|
|
863
|
+
return FileText;
|
|
864
|
+
|
|
865
|
+
case 'pdf':
|
|
866
|
+
return FileText;
|
|
867
|
+
|
|
868
|
+
// Data & Configuration
|
|
869
|
+
case 'json':
|
|
870
|
+
return Braces; // JSON icon
|
|
871
|
+
|
|
872
|
+
case 'yml':
|
|
873
|
+
case 'yaml':
|
|
874
|
+
return Settings; // YAML icon
|
|
875
|
+
|
|
876
|
+
case 'xml':
|
|
877
|
+
return Code; // XML icon
|
|
878
|
+
|
|
879
|
+
case 'env':
|
|
880
|
+
return Key; // Environment file icon
|
|
881
|
+
|
|
882
|
+
case 'config':
|
|
883
|
+
return Settings; // Config file icon
|
|
884
|
+
|
|
885
|
+
// Images
|
|
886
|
+
case 'jpg':
|
|
887
|
+
case 'jpeg':
|
|
888
|
+
case 'png':
|
|
889
|
+
case 'gif':
|
|
890
|
+
case 'webp':
|
|
891
|
+
case 'bmp':
|
|
892
|
+
case 'tiff':
|
|
893
|
+
case 'ico':
|
|
894
|
+
return Image; // Image icon
|
|
895
|
+
|
|
896
|
+
case 'svg':
|
|
897
|
+
return Zap; // SVG icon (special since it's vector)
|
|
898
|
+
|
|
899
|
+
// Media
|
|
900
|
+
case 'mp4':
|
|
901
|
+
case 'avi':
|
|
902
|
+
case 'mov':
|
|
903
|
+
case 'mkv':
|
|
904
|
+
return Play; // Video icon
|
|
905
|
+
|
|
906
|
+
case 'mp3':
|
|
907
|
+
case 'wav':
|
|
908
|
+
case 'flac':
|
|
909
|
+
case 'ogg':
|
|
910
|
+
return Music; // Audio icon
|
|
911
|
+
|
|
912
|
+
// Archives
|
|
913
|
+
case 'zip':
|
|
914
|
+
case 'tar':
|
|
915
|
+
case 'gz':
|
|
916
|
+
case '7z':
|
|
917
|
+
case 'rar':
|
|
918
|
+
return Archive; // Archive icon
|
|
919
|
+
|
|
920
|
+
// Executables
|
|
921
|
+
case 'exe':
|
|
922
|
+
case 'app':
|
|
923
|
+
case 'deb':
|
|
924
|
+
case 'dmg':
|
|
925
|
+
return Zap; // Executable icon
|
|
926
|
+
|
|
927
|
+
// Development Tools
|
|
928
|
+
case 'git':
|
|
929
|
+
case 'gitignore':
|
|
930
|
+
return GitBranch; // Git icon
|
|
931
|
+
|
|
932
|
+
case 'dockerfile':
|
|
933
|
+
return Package; // Docker icon
|
|
934
|
+
|
|
935
|
+
case 'sql':
|
|
936
|
+
return Database; // Database icon
|
|
937
|
+
|
|
938
|
+
case 'log':
|
|
939
|
+
return FileText; // Log file icon
|
|
940
|
+
|
|
941
|
+
// Default file icon (handled by TreeNodeList)
|
|
942
|
+
default:
|
|
943
|
+
return 'file'; // Use default File icon
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|