0
0

1、将每个代码仓库进行了隔离。2、优化了每个页面的ui对齐。3、增加了飞行器页面的所属项目显示。4、切换页面时对项目进行扫描,实时更新项目的结构,避免复制导致ui不显示的bug

This commit is contained in:
xubing
2026-03-04 10:19:04 +08:00
parent 942dab0f96
commit 79f7a3a860
38 changed files with 255 additions and 400 deletions

View File

@@ -24,7 +24,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigPanel = void 0;
// src/panels/ConfigPanel.ts
const vscode = __importStar(require("vscode"));
const path = __importStar(require("path"));
const ProjectView_1 = require("./views/ProjectView");
@@ -97,15 +96,12 @@ class ConfigPanel {
async openRepoSelectForScope(scope) {
this.currentCloneScope = scope;
await this.loadRepoConfigs();
if (this.repoConfigs.length === 0) {
vscode.window.showWarningMessage('尚未配置任何仓库,请先点击右上角 "仓库配置" 按钮编辑 dcsp-repos.json。');
return;
}
const repos = this.getRepoConfigsForScope(scope);
if (this.isWebviewDisposed)
return;
this.panel.webview.postMessage({
type: 'showRepoSelect',
repos: this.repoConfigs.map(r => ({ name: r.name }))
repos: repos.map(r => ({ name: r.name }))
});
}
async openRepoSelect() {
@@ -113,30 +109,24 @@ class ConfigPanel {
}
async openUploadRepoSelect(folderId, folderType) {
await this.loadRepoConfigs();
if (this.repoConfigs.length === 0) {
vscode.window.showWarningMessage('尚未配置任何仓库,请先点击右上角 "仓库配置" 按钮编辑 dcsp-repos.json。');
return;
}
if (this.isWebviewDisposed)
return;
const repos = this.getRepoConfigsForScope('config');
this.panel.webview.postMessage({
type: 'showUploadRepoSelect',
repos: this.repoConfigs.map(r => ({ name: r.name })),
repos: repos.map(r => ({ name: r.name })),
folderId,
folderType
});
}
async openUploadRepoSelectForScope(scope, id) {
await this.loadRepoConfigs();
if (this.repoConfigs.length === 0) {
vscode.window.showWarningMessage('尚未配置任何仓库,请先点击右上角 "仓库配置" 按钮编辑 dcsp-repos.json。');
return;
}
const repos = this.getRepoConfigsForScope(scope);
if (this.isWebviewDisposed)
return;
this.panel.webview.postMessage({
type: 'showUploadRepoSelect',
repos: this.repoConfigs.map(r => ({ name: r.name })),
repos: repos.map(r => ({ name: r.name })),
folderId: id,
folderType: scope
});
@@ -298,7 +288,7 @@ class ConfigPanel {
}
}
async handleOpenProject(data) {
// [新增] 在进入视图前,主动扫描磁盘同步数据
// 在进入视图前,主动扫描磁盘同步数据
const changed = await this.projectService.refreshProjectContent(data.projectId);
if (changed) {
await this.saveCurrentProjectData(); // 如果有变动,立即保存
@@ -308,7 +298,7 @@ class ConfigPanel {
this.updateWebview();
}
async handleOpenAircraftConfig(data) {
// [新增] 进入飞行器详情前,主动同步容器列表
// 进入飞行器详情前,主动同步容器列表
const changed = await this.projectService.refreshAircraftContent(data.aircraftId);
if (changed) {
await this.saveCurrentProjectData();
@@ -319,7 +309,7 @@ class ConfigPanel {
this.updateWebview();
}
async handleOpenContainerConfig(data) {
// [新增] 进入容器详情前,主动同步配置和模块
// 进入容器详情前,主动同步配置和模块
const changed = await this.projectService.refreshContainerContent(data.containerId);
if (changed) {
await this.saveCurrentProjectData();
@@ -517,7 +507,7 @@ class ConfigPanel {
return;
}
const containerId = await this.projectService.createContainer(name, this.currentAircraftId);
vscode.window.showInformationMessage(`新建容器: ${name} (包含2个默认配置文件)`);
vscode.window.showInformationMessage(`新建容器: ${name}`);
await this.saveCurrentProjectData();
this.updateWebview();
}
@@ -1500,7 +1490,7 @@ class ConfigPanel {
if (projectId) {
this.currentProjectId = projectId;
this.currentView = 'aircrafts';
// [新增] 项目加载成功后,启动文件监听
// 项目加载成功后,启动文件监听
this.setupFileWatcher(projectPath, projectId);
vscode.window.showInformationMessage(`项目数据已从 ${projectPath} 加载`);
this.updateWebview();
@@ -1514,15 +1504,14 @@ class ConfigPanel {
}
}
setupFileWatcher(projectPath, projectId) {
// 1. 如果已有监听器,先销毁
// 如果已有监听器,先销毁
if (this.fileWatcher) {
this.fileWatcher.dispose();
}
// 2. 创建新的监听器:监听项目目录下的所有变化
// Pattern: /path/to/project/**/*
// 创建新的监听器:监听项目目录下的所有变化
const pattern = new vscode.RelativePattern(projectPath, '**/*');
this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern, false, true, false); // 忽略 onChange只监听 Create/Delete
// 3. 定义处理逻辑(使用防抖,避免连续创建文件导致多次刷新)
// 定义处理逻辑(使用防抖,避免连续创建文件导致多次刷新)
const handleCreate = async (uri) => {
if (this.isWebviewDisposed)
return;
@@ -1535,7 +1524,6 @@ class ConfigPanel {
let dataChanged = false;
// 层级 1: 飞行器 (Folder)
if (parts.length === 1) {
// 检查是文件还是文件夹
const stat = await vscode.workspace.fs.stat(uri);
if ((stat.type & vscode.FileType.Directory) === vscode.FileType.Directory) {
await this.projectService.importAircraftFromExistingFolder(projectId, parts[0]);
@@ -1588,7 +1576,7 @@ class ConfigPanel {
this.updateWebview();
}
};
// 4. 绑定事件 (防抖建议设为 500ms 左右)
// 绑定事件 (防抖建议设为 500ms 左右)
const debouncedCreate = debounce(handleCreate, 500);
const debouncedDelete = debounce(handleDelete, 500);
this.fileWatcher.onDidCreate(uri => debouncedCreate(uri));
@@ -1608,6 +1596,9 @@ class ConfigPanel {
}
catch (error) { }
}
getRepoConfigsForScope(scope) {
return (this.repoConfigs || []).filter(r => Array.isArray(r.scopes) && r.scopes.includes(scope));
}
getWebviewContent() {
switch (this.currentView) {
case 'projects':
@@ -1615,12 +1606,18 @@ class ConfigPanel {
projects: this.projectService.getProjects(),
projectPaths: this.projectService.getProjectPaths()
});
case 'aircrafts':
const projectAircrafts = this.projectService.getAircraftsByProject(this.currentProjectId);
case 'aircrafts': {
const project = this.projectService.getProjects()
.find(p => p.id === this.currentProjectId);
const projectAircrafts = this.projectService
.getAircraftsByProject(this.currentProjectId)
.filter(a => a.name !== '.git');
return this.aircraftView.render({
project: project,
aircrafts: projectAircrafts
});
case 'containers':
}
case 'containers': {
const project = this.projectService.getProjects().find(p => p.id === this.currentProjectId);
const currentAircraft = this.projectService.getAircraftsByProject(this.currentProjectId)
.find(a => a.id === this.currentAircraftId);
@@ -1632,7 +1629,8 @@ class ConfigPanel {
aircraft: currentAircraft,
containers: projectContainers
});
case 'configs':
}
case 'configs': {
const currentContainer = this.projectService.getContainersByAircraft(this.currentAircraftId)
.find(c => c.id === this.currentContainerId);
const currentModuleFolder = this.projectService.getModuleFolder(this.currentModuleFolderId);
@@ -1646,6 +1644,7 @@ class ConfigPanel {
moduleFolderFileTree: this.currentModuleFolderFileTree,
moduleFolderLoading: false
});
}
default:
return this.projectView.render({
projects: this.projectService.getProjects(),

File diff suppressed because one or more lines are too long

View File

@@ -27,7 +27,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitService = void 0;
// src/panels/services/GitService.ts
const fs = __importStar(require("fs"));
const isomorphic_git_1 = __importDefault(require("isomorphic-git"));
const node_1 = __importDefault(require("isomorphic-git/http/node"));
@@ -94,8 +93,7 @@ class GitService {
}
if (dirExists) {
const dirContents = await fs.promises.readdir(localPath);
// 修正后的逻辑:过滤掉所有以 "." 开头的隐藏文件/目录。
// 只有当存在非 "." 开头的文件或目录时,才阻止克隆。
// 过滤掉所有以 "." 开头的隐藏文件/目录。
const nonBenignFiles = dirContents.filter(item => !item.startsWith('.'));
if (nonBenignFiles.length > 0) {
throw new Error('目标目录不为空,请清空目录或选择其他路径');
@@ -195,7 +193,6 @@ class GitService {
if (username || token) {
const u = encodeURIComponent(username || '');
const t = encodeURIComponent(token || '');
// 注意: 仅在 URL 是 http/https 时添加 auth
if (repoUrl.startsWith('http')) {
finalUrl = repoUrl.replace('://', `://${u}:${t}@`);
}
@@ -226,7 +223,7 @@ class GitService {
await execAsync(`git push -u origin "${branchName}" --force`, { cwd: localPath });
}
/**
* 使用Git命令提交并推送 (用于原有的 Git 模块更新)
* 使用Git命令提交并推送
*/
static async commitAndPush(localPath) {
await execAsync('git add .', { cwd: localPath });
@@ -263,15 +260,13 @@ class GitService {
await execAsync(commands.join(' && '), { cwd: localPath });
}
/**
* 提交并推送到指定分支和远程 (用于 Project/Aircraft/Container 上传)
* 提交并推送到指定分支和远程
*/
static async commitAndPushToBranch(localPath, branchName, repoUrl, // 这里的 repoUrl 是为了构造带 auth 的 finalUrl
username, token) {
static async commitAndPushToBranch(localPath, branchName, repoUrl, username, token) {
let finalUrl = repoUrl || 'origin';
if (repoUrl && (username || token)) {
const u = encodeURIComponent(username || '');
const t = encodeURIComponent(token || '');
// 注意: 仅在 URL 是 http/https 时添加 auth
if (repoUrl.startsWith('http')) {
finalUrl = repoUrl.replace('://', `://${u}:${t}@`);
}
@@ -313,13 +308,10 @@ class GitService {
const files = await fs.promises.readdir(dir);
const tree = [];
for (const file of files) {
// 1. 不要解析 .git
if (file === '.git')
continue;
// 2. 不要解析项目数据文件
if (file === 'dcsp-data.json')
continue;
// 3. 其它所有隐藏文件/目录统统忽略
if (file.startsWith('.'))
continue;
const filePath = path.join(dir, file);

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectService = void 0;
// src/panels/services/ProjectService.ts
const vscode = __importStar(require("vscode"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
@@ -53,17 +52,17 @@ class ProjectService {
*/
sanitizeFileName(name) {
let fileName = name.trim();
// 1. 替换所有空格为下划线
// 替换所有空格为下划线
fileName = fileName.replace(/\s+/g, '_');
// 2. 移除特殊字符
// 移除特殊字符
fileName = fileName.replace(/[^\u4e00-\u9fa5a-zA-Z0-9_\-\.]/g, '');
// 3. 确保不为空
// 确保不为空
if (fileName.length === 0) {
return 'config_file';
}
return fileName;
}
// =============== 查重工具方法 (新增) ===============
// =============== 查重工具方法 ===============
/** 检查项目名是否重复 */
isProjectNameExists(name) {
return this.projects.some(p => p.name === name);
@@ -218,7 +217,6 @@ class ProjectService {
};
this.containers.push(newContainer);
await this.createContainerDirectory(newContainer);
await this.createDefaultConfigs(newContainer);
return newId;
}
updateContainerName(containerId, newName) {
@@ -537,20 +535,6 @@ class ProjectService {
console.error(`确保容器目录存在失败: ${error}`);
}
}
async createDefaultConfigs(container) {
this.configs.push({
id: this.generateUniqueId('cfg', this.configs),
name: '配置1',
fileName: 'dockerfile',
containerId: container.id
});
this.configs.push({
id: this.generateUniqueId('cfg', this.configs),
name: '配置2',
fileName: 'docker-compose.yml',
containerId: container.id
});
}
// =============== 数据持久化 ===============
async saveCurrentProjectData(projectId) {
try {
@@ -688,12 +672,11 @@ class ProjectService {
return true;
}
/**
* [新方法] 仅在内存中注册模块文件夹(用于监测到磁盘文件夹创建时)
* 仅在内存中注册模块文件夹(用于监测到磁盘文件夹创建时)
*/
registerModuleFolderFromDisk(folderName, containerId, aircraftId, projectId, aircraftName, containerName, fullPath) {
const relativePath = `/${projectId}/${aircraftName}/${containerName}/${folderName}`;
// 查重:只要同一个容器下,有任何一个模块指向了相同的文件夹名,就视为已存在
// 这样即使旧数据的 localPath 路径字符串是过时的,也不会重复添加
// 只要同一个容器下,有任何一个模块指向了相同的文件夹名,就视为已存在
const existing = this.moduleFolders.find(f => {
if (f.containerId !== containerId)
return false;
@@ -703,7 +686,7 @@ class ProjectService {
});
if (existing)
return false;
// 智能检测:如果文件夹下有 .git则标记为 git 类型
// 如果文件夹下有 .git则标记为 git 类型
let type = 'local';
if (fullPath) {
const gitDir = path.join(fullPath, '.git');
@@ -723,11 +706,9 @@ class ProjectService {
return true;
}
/**
* [新方法] 处理磁盘删除事件:根据路径移除对应的 Config 或 ModuleFolder
* 处理磁盘删除事件:根据路径移除对应的 Config 或 ModuleFolder
*/
removeEntityByPath(filePath, projectId) {
// 这里的 filePath 是绝对路径,需要反解出是哪个 Config 或 Folder
// 这是一个比较繁琐的过程,简化逻辑如下:
let changed = false;
const projectPath = this.projectPaths.get(projectId);
if (!projectPath || !filePath.startsWith(projectPath))
@@ -760,7 +741,7 @@ class ProjectService {
if (!projectPath || !fs.existsSync(projectPath))
return false;
let changed = false;
// 1. 扫描磁盘,添加缺失的飞行器
// 扫描磁盘,添加缺失的飞行器
try {
const entries = await fs.promises.readdir(projectPath, { withFileTypes: true });
for (const entry of entries) {
@@ -780,7 +761,7 @@ class ProjectService {
catch (e) {
console.error('扫描项目目录失败:', e);
}
// 2. 检查内存,移除磁盘不存在的飞行器 (清理无效数据)
// 检查内存,移除磁盘不存在的飞行器 (清理无效数据)
const currentAircrafts = this.getAircraftsByProject(projectId);
for (const aircraft of currentAircrafts) {
const aircraftPath = path.join(projectPath, aircraft.name);
@@ -799,7 +780,7 @@ class ProjectService {
if (!dirPath || !fs.existsSync(dirPath))
return false;
let changed = false;
// 1. 扫描磁盘,添加缺失的容器
// 扫描磁盘,添加缺失的容器
try {
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
for (const entry of entries) {
@@ -817,7 +798,7 @@ class ProjectService {
catch (e) {
console.error('扫描飞行器目录失败:', e);
}
// 2. 检查内存,移除磁盘不存在的容器
// 检查内存,移除磁盘不存在的容器
const currentContainers = this.getContainersByAircraft(aircraftId);
for (const container of currentContainers) {
const containerPath = path.join(dirPath, container.name);
@@ -842,7 +823,7 @@ class ProjectService {
if (!aircraft)
return false;
let changed = false;
// 1. 扫描磁盘,添加缺失的配置和模块
// 扫描磁盘,添加缺失的配置和模块
try {
const entries = await fs.promises.readdir(dirPath, { withFileTypes: true });
for (const entry of entries) {
@@ -865,7 +846,7 @@ class ProjectService {
catch (e) {
console.error('扫描容器目录失败:', e);
}
// 2. 检查内存,移除磁盘不存在的 配置
// 检查内存,移除磁盘不存在的 配置
const currentConfigs = this.getConfigsByContainer(containerId);
for (const config of currentConfigs) {
const configPath = path.join(dirPath, config.fileName);
@@ -874,12 +855,9 @@ class ProjectService {
changed = true;
}
}
// 3. 检查内存,移除磁盘不存在的 模块文件夹
// 检查内存,移除磁盘不存在的 模块文件夹
const currentModules = this.getModuleFoldersByContainer(containerId);
for (const folder of currentModules) {
// 注意Git 类型的模块文件夹,其 localPath 也是指向这个目录的
// 这里我们简单拼接路径来检查
// folder.localPath 格式: /projectId/aircraft/container/folderName
const folderName = folder.localPath.split('/').pop();
if (folderName) {
const folderPath = path.join(dirPath, folderName);
@@ -892,7 +870,7 @@ class ProjectService {
return changed;
}
/**
* [新增] 递归清理目录下所有的嵌套 .git 文件夹
* 递归清理目录下所有的嵌套 .git 文件夹
* 作用:保留 rootDir 下的 .git但删除所有子目录中的 .git
* 解决父级上传时因包含子级仓库导致的冲突
*/
@@ -902,17 +880,17 @@ class ProjectService {
try {
const entries = await fs.promises.readdir(rootDir, { withFileTypes: true });
for (const entry of entries) {
// 1. 如果遍历到的是当前目录下的 .git直接跳过(这是我们要保留的主仓库)
// 如果遍历到的是当前目录下的 .git直接跳过
if (entry.name === '.git')
continue;
// 2. 只处理目录
// 只处理目录
if (entry.isDirectory()) {
const subDir = path.join(rootDir, entry.name);
const nestedGit = path.join(subDir, '.git');
// 检查子目录下是否有 .git
if (fs.existsSync(nestedGit)) {
console.log(`🧹 发现嵌套 Git 仓库,正在移除以支持父级上传: ${nestedGit}`);
// 使用您之前实现的强力删除方法(带权限处理)
// 使用强力删除方法(带权限处理)
await this.deleteDirectoryFromDisk(nestedGit);
}
// 继续递归,防止有多层嵌套
@@ -922,7 +900,6 @@ class ProjectService {
}
catch (error) {
console.error(`清理嵌套 Git 失败: ${error}`);
// 不抛出错误,尽力而为,以免打断上传流程
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StorageService = void 0;
// src/panels/services/StorageService.ts
const vscode = __importStar(require("vscode"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));

View File

@@ -1 +1 @@
{"version":3,"file":"StorageService.js","sourceRoot":"","sources":["../../../src/panels/services/StorageService.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"StorageService.js","sourceRoot":"","sources":["../../../src/panels/services/StorageService.ts"],"names":[],"mappings":"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"}

View File

@@ -1,5 +1,6 @@
"use strict";
// src/panels/types/CommonTypes.ts
// 统一的核心类型定义
// =============================================
// 基础实体接口
// =============================================
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=CommonTypes.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"CommonTypes.js","sourceRoot":"","sources":["../../../src/panels/types/CommonTypes.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,YAAY"}
{"version":3,"file":"CommonTypes.js","sourceRoot":"","sources":["../../../src/panels/types/CommonTypes.ts"],"names":[],"mappings":";AACA,gDAAgD;AAChD,SAAS;AACT,gDAAgD"}

View File

@@ -24,7 +24,7 @@ class AircraftView extends BaseView_1.BaseView {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>飞行器配置</title>
<title>飞行器管理</title>
${this.getStyles()}
${this.getRepoSelectScript()}
<style>
@@ -153,16 +153,20 @@ class AircraftView extends BaseView_1.BaseView {
</head>
<body>
<div class="header">
<h2>🚀飞行器配置</h2>
<h2>🚀 飞行器管理 -
<span style="color: var(--vscode-textLink-foreground);">
${data?.project?.name || '未知项目'}
</span>
</h2>
<button class="back-btn" onclick="goBackToProjects()">← 返回项目</button>
</div>
<table class="table">
<thead>
<tr>
<th width="40%">飞行器</th>
<th width="40%">配置</th>
<th width="20%">操作</th>
<th width="43%" style="padding-left: 40px;">飞行器</th>
<th width="43%">配置</th>
<th width="14%" style="padding-left: 45px;">操作</th>
</tr>
</thead>
<tbody>
@@ -176,13 +180,13 @@ class AircraftView extends BaseView_1.BaseView {
</table>
<div class="config-section">
<h3 class="section-title">🛫 飞行器云仓库</h3>
<h3 class="section-title">📚 飞行器云仓库</h3>
<div class="url-input-section">
<h4>🔗 获取飞行器仓库</h4>
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
<button class="btn-new" onclick="openRepoSelectForAircraft()">获取仓库</button>
<span style="font-size: 12px; color: var(--vscode-descriptionForeground);">
从仓库配置中选择 Git 仓库,选择分支后可将飞行器代码克隆到当前项目下(以分支名作为飞行器名称)
从仓库配置中选择 Git 仓库,随后可以选择分支并克隆到本地
</span>
</div>
<div id="branchSelectionContainer"></div>
@@ -238,18 +242,12 @@ class AircraftView extends BaseView_1.BaseView {
);
}
// 新增上传功能
// 上传功能
function uploadAircraft(aircraftId, aircraftName) {
showConfirmDialog(
'上传飞行器仓库',
'确定将此飞行器目录(包括所有子文件夹和文件)上传到一个新的 Git 仓库分支吗?',
function() {
vscode.postMessage({
type: 'openRepoSelectForAircraftUpload',
aircraftId: aircraftId
});
}
);
vscode.postMessage({
type: 'openRepoSelectForAircraftUpload',
aircraftId: aircraftId
});
}
// 飞行器名称编辑功能

View File

@@ -1 +1 @@
{"version":3,"file":"AircraftView.js","sourceRoot":"","sources":["../../../src/panels/views/AircraftView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,YAAa,SAAQ,mBAAQ;IACtC,MAAM,CAAC,IAAwC;QAC3C,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC;QAExC,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;;;oEAGY,QAAQ,CAAC,EAAE,QAAQ,QAAQ,CAAC,IAAI;;;2EAGzB,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC,SAAS;;;0EAGrC,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC,IAAI;0EAC/B,QAAQ,CAAC,EAAE;;;SAG5E,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4IlB,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqRnB,CAAC;IACL,CAAC;CACJ;AA7bD,oCA6bC"}
{"version":3,"file":"AircraftView.js","sourceRoot":"","sources":["../../../src/panels/views/AircraftView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,YAAa,SAAQ,mBAAQ;IACtC,MAAM,CAAC,IAAuD;QAC1D,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC;QAExC,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;;;oEAGY,QAAQ,CAAC,EAAE,QAAQ,QAAQ,CAAC,IAAI;;;2EAGzB,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC,SAAS;;;0EAGrC,QAAQ,CAAC,EAAE,OAAO,QAAQ,CAAC,IAAI;0EAC/B,QAAQ,CAAC,EAAE;;;SAG5E,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiIlB,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,MAAM;;;;;;;;;;;;;;;cAe7B,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+QnB,CAAC;IACL,CAAC;CACJ;AA3bD,oCA2bC"}

View File

@@ -278,7 +278,7 @@ class BaseView {
}
window.__dcspRepoDialogInitialized = true;
// 仅用于“获取仓库 -> 拉取分支”的弹窗
// 仅用于“获取仓库 -> 拉取分支”的弹窗
function showRepoSelectDialog(repos) {
// 移除已有弹窗
var existing = document.getElementById('repoSelectModal');
@@ -362,7 +362,7 @@ class BaseView {
}
}
// 专门用于“上传代码”的仓库+分支弹窗
// 专门用于“上传代码”的仓库+分支弹窗
function showUploadRepoSelectDialog(repos, folderId, folderType) {
var existing = document.getElementById('uploadRepoSelectModal');
if (existing) {
@@ -471,11 +471,10 @@ class BaseView {
var message = event.data;
if (!message || !message.type) return;
if (message.type === 'showRepoSelect') {
// 旧逻辑:仅用于获取分支
// 仅用于获取分支
showRepoSelectDialog(message.repos || []);
} else if (message.type === 'showUploadRepoSelect') {
// 新逻辑:上传代码用(仓库 + 分支)
// 这里的 folderId/folderType 现在可能是 Project/Aircraft/Container 的 ID/Type
// 上传代码用(仓库 + 分支)
showUploadRepoSelectDialog(message.repos || [], message.folderId, message.folderType);
}
});

View File

@@ -1 +1 @@
{"version":3,"file":"BaseView.js","sourceRoot":"","sources":["../../../src/panels/views/BaseView.ts"],"names":[],"mappings":";;;AAEA,MAAsB,QAAQ;IAG1B,YAAY,YAAwB;QAChC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAID;;OAEG;IACO,uBAAuB;QAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA8PN,CAAC;IACN,CAAC;IAED;;OAEG;IACO,mBAAmB;QACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoNN,CAAC;IACN,CAAC;IAED;;OAEG;IACO,SAAS;QACf,OAAO,IAAI,CAAC,uBAAuB,EAAE,CAAC;IAC1C,CAAC;CACJ;AA/eD,4BA+eC"}
{"version":3,"file":"BaseView.js","sourceRoot":"","sources":["../../../src/panels/views/BaseView.ts"],"names":[],"mappings":";;;AAEA,MAAsB,QAAQ;IAG1B,YAAY,YAAwB;QAChC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAID;;OAEG;IACO,uBAAuB;QAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA8PN,CAAC;IACN,CAAC;IAED;;OAEG;IACO,mBAAmB;QACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAmNN,CAAC;IACN,CAAC;IAED;;OAEG;IACO,SAAS;QACf,OAAO,IAAI,CAAC,uBAAuB,EAAE,CAAC;IAC1C,CAAC;CACJ;AA9eD,4BA8eC"}

View File

@@ -261,25 +261,23 @@ class ConfigView extends BaseView_1.BaseView {
</head>
<body>
<div class="header">
<h2>⚙️ 模块管理 - <span style="color: var(--vscode-textLink-foreground);">${container?.name || '未知容器'}</span></h2>
<h2>📁 模块管理 - <span style="color: var(--vscode-textLink-foreground);">${container?.name || '未知容器'}</span></h2>
<button class="back-btn" onclick="goBackToContainers()">← 返回容器管理</button>
</div>
<div class="config-section">
<h3 class="section-title">📋 配置文件管理</h3>
<div class="config-section">
<div class="action-buttons">
<button class="btn-new" onclick="createNewConfig()">+ 新建配置</button>
<button class="btn-merge" id="mergeButton" onclick="mergeSelectedConfigs()" disabled>合并选中配置</button>
<button class="btn-new" onclick="createNewConfig()">+ 新建文件</button>
<button class="btn-merge" id="mergeButton" onclick="mergeSelectedConfigs()" disabled>合并选中文件</button>
</div>
<table class="table">
<thead>
<tr>
<th width="25%">模</th>
<th width="15%">类别</th>
<th width="35%" style="padding-left: 50px;">模</th>
<th width="16%">类别</th>
<th width="35%">文件/文件夹</th>
<th width="25%">操作</th>
<th width="14%" style="padding-left: 45px;">操作</th>
</tr>
</thead>
<tbody>
@@ -313,7 +311,7 @@ class ConfigView extends BaseView_1.BaseView {
let branchTreeData = [];
let selectedConfigs = new Set();
// [新增] 配置文件重命名弹窗
// 配置文件重命名弹窗
function showConfigRenameDialog(configId, currentName, currentFileName) {
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';
@@ -413,13 +411,12 @@ class ConfigView extends BaseView_1.BaseView {
}
}
// [修改] editConfigName使用新的双输入弹窗
function editConfigName(configId, currentName, currentFileName) {
// currentFileName 现在已从模板传入
showConfigRenameDialog(configId, currentName, currentFileName);
}
// [新增] 模块文件夹重命名双输入弹窗
// 模块文件夹重命名双输入弹窗
function showModuleFolderRenameDialog(folderId, currentName, currentFolderName) {
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';
@@ -430,16 +427,15 @@ class ConfigView extends BaseView_1.BaseView {
<div class="modal-title">重命名模块文件夹</div>
<div class="merge-dialog-content">
<div class="merge-input-section">
<label class="merge-input-label">显示名称</label>
<label class="merge-input-label">模型名称</label>
<input type="text" id="moduleDisplayNameInput" class="merge-input-field"
placeholder="在配置栏显示的名称" value="\${currentName}">
<div class="merge-input-help">在左侧配置栏显示的名称</div>
</div>
<div class="merge-input-section">
<label class="merge-input-label">磁盘文件夹名称 (将同步修改磁盘目录)</label>
<label class="merge-input-label">文件/文件夹名称</label>
<input type="text" id="moduleFolderNameInput" class="merge-input-field"
placeholder="磁盘上的实际文件夹名" value="\${currentFolderName}">
<div class="merge-input-help">请使用英文、数字、中文、-、_不要使用空格和/</div>
<div class="merge-input-help">禁止使用空格和"/"</div>
</div>
<div id="moduleFolderNameValidationMessage" style="color: var(--vscode-inputValidation-errorForeground); font-size: 12px; margin-top: 5px;"></div>
</div>
@@ -519,10 +515,9 @@ class ConfigView extends BaseView_1.BaseView {
}
}
// [修改] renameModuleFolder获取磁盘文件夹名并使用双输入弹窗
// 获取磁盘文件夹名并使用双输入弹窗
function renameModuleFolder(folderId, currentName) {
// 通过 data-folder-id 找到模块文件夹的行
// 修复:避免在 JS 字符串中使用内嵌模板字符串,改用拼接以解决编译问题
const editableSpan = document.querySelector('.module-folder-name[data-folder-id="' + folderId + '"]');
if (!editableSpan) return;
@@ -534,9 +529,6 @@ class ConfigView extends BaseView_1.BaseView {
showModuleFolderRenameDialog(folderId, currentName, currentFolderName);
}
// 模块管理功能
// 原始的 editConfigName 已被修改为接受三个参数
// 在 VSCode 中打开配置文件
function openConfigFileInVSCode(configId) {
vscode.postMessage({

File diff suppressed because one or more lines are too long

View File

@@ -141,16 +141,16 @@ class ContainerView extends BaseView_1.BaseView {
</head>
<body>
<div class="header">
<h2>📋 容器管理 - <span style="color: var(--vscode-textLink-foreground);">${aircraft?.name || '未知飞行器'}</span></h2>
<h2>📦 容器管理 - <span style="color: var(--vscode-textLink-foreground);">${aircraft?.name || '未知飞行器'}</span></h2>
<button class="back-btn" onclick="goBackToAircrafts()">← 返回飞行器管理</button>
</div>
<table class="table">
<thead>
<tr>
<th width="40%">容器</th>
<th width="40%">打开</th>
<th width="20%">操作</th>
<th width="43%" style="padding-left: 50px;">容器</th>
<th width="43%">打开</th>
<th width="14%" style="padding-left: 45px;">操作</th>
</tr>
</thead>
<tbody>
@@ -164,13 +164,13 @@ class ContainerView extends BaseView_1.BaseView {
</table>
<div class="config-section">
<h3 class="section-title">📦 容器云仓库</h3>
<h3 class="section-title">📚 容器云仓库</h3>
<div class="url-input-section">
<h4>🔗 获取容器仓库</h4>
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
<button class="btn-new" onclick="openRepoSelectForContainer()">获取仓库</button>
<span style="font-size: 12px; color: var(--vscode-descriptionForeground);">
从仓库配置中选择 Git 仓库,选择分支后可将容器代码克隆到当前飞行器下(以分支名作为容器名称)
从仓库配置中选择 Git 仓库,选择分支后可将完整容器克隆到本地
</span>
</div>
<div id="branchSelectionContainer"></div>
@@ -240,18 +240,11 @@ class ContainerView extends BaseView_1.BaseView {
);
}
// 新增上传功能
function uploadContainer(containerId, containerName) {
showConfirmDialog(
'上传容器仓库',
'确定将此容器目录(包括所有子文件夹和文件)上传到一个新的 Git 仓库分支吗?',
function() {
vscode.postMessage({
type: 'openRepoSelectForContainerUpload',
containerId: containerId
});
}
);
vscode.postMessage({
type: 'openRepoSelectForContainerUpload',
containerId: containerId
});
}
// ======== Git 仓库 & 分支树 - ContainerView 作用域 ========

View File

@@ -1 +1 @@
{"version":3,"file":"ContainerView.js","sourceRoot":"","sources":["../../../src/panels/views/ContainerView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,aAAc,SAAQ,mBAAQ;IACvC,MAAM,CAAC,IAAyB;QAC5B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;QAE1C,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAA4B,EAAE,EAAE,CAAC;;;yEAGP,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC,IAAI,UAAU,SAAS,CAAC,IAAI;;;4EAGtD,SAAS,CAAC,EAAE;;;2EAGb,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC,IAAI;2EACjC,SAAS,CAAC,EAAE;;;SAG9E,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAiHgD,QAAQ,EAAE,IAAI,IAAI,OAAO;;;;;;;;;;;;;cAa3F,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAmQpB,CAAC;IACL,CAAC;CACJ;AA/ZD,sCA+ZC"}
{"version":3,"file":"ContainerView.js","sourceRoot":"","sources":["../../../src/panels/views/ContainerView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,aAAc,SAAQ,mBAAQ;IACvC,MAAM,CAAC,IAAyB;QAC5B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;QAE1C,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAA4B,EAAE,EAAE,CAAC;;;yEAGP,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC,IAAI,UAAU,SAAS,CAAC,IAAI;;;4EAGtD,SAAS,CAAC,EAAE;;;2EAGb,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC,IAAI;2EACjC,SAAS,CAAC,EAAE;;;SAG9E,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAiHgD,QAAQ,EAAE,IAAI,IAAI,OAAO;;;;;;;;;;;;;cAa3F,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4PpB,CAAC;IACL,CAAC;CACJ;AAxZD,sCAwZC"}

View File

@@ -191,9 +191,9 @@ class ProjectView extends BaseView_1.BaseView {
<table class="table">
<thead>
<tr>
<th width="40%">项目</th>
<th width="40%">配置</th>
<th width="20%">操作</th>
<th width="43%" style="padding-left: 50px;">项目</th>
<th width="43%">配置</th>
<th width="14%" style="padding-left: 45px;">操作</th>
</tr>
</thead>
<tbody>
@@ -220,7 +220,7 @@ class ProjectView extends BaseView_1.BaseView {
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
<button class="btn-new" onclick="openRepoSelectForProject()">获取仓库</button>
<span style="font-size: 12px; color: var(--vscode-descriptionForeground);">
从仓库配置中选择 Git 仓库,选择分支后可将完整项目克隆到本地
从仓库配置中选择 Git 仓库,随后可以选择分支并克隆到本地
</span>
</div>
<div id="branchSelectionContainer"></div>
@@ -240,7 +240,8 @@ class ProjectView extends BaseView_1.BaseView {
if (isConfigured) {
vscode.postMessage({
type: 'openProject',
projectId: projectId
projectId: projectId,
projectName: projectName
});
} else {
vscode.postMessage({
@@ -289,18 +290,12 @@ class ProjectView extends BaseView_1.BaseView {
);
}
// 新增上传功能
// 上传功能
function uploadProject(projectId, projectName) {
showConfirmDialog(
'上传项目仓库',
'确定将此项目目录(包括所有子文件夹和文件)上传到一个新的 Git 仓库分支吗?',
function() {
vscode.postMessage({
type: 'openRepoSelectForProjectUpload',
projectId: projectId
});
}
);
vscode.postMessage({
type: 'openRepoSelectForProjectUpload',
projectId: projectId
});
}
// 项目名称编辑功能

View File

@@ -1 +1 @@
{"version":3,"file":"ProjectView.js","sourceRoot":"","sources":["../../../src/panels/views/ProjectView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,WAAY,SAAQ,mBAAQ;IACrC,MAAM,CAAC,IAA0E;QAC7E,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,IAAI,GAAG,EAAE,CAAC;QAErD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAwB,EAAE,EAAE;YAC3D,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YAEhD,OAAO;;;kEAG+C,OAAO,CAAC,EAAE,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI;;0BAEjF,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;;;;yEAItB,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,IAAI,MAAM,YAAY;0BAC9F,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;sBAI9B,YAAY,CAAC,CAAC,CAAC,sDAAsD,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,IAAI,4CAA4C,CAAC,CAAC,CAAC,EAAE;yEAChG,OAAO,CAAC,EAAE;;;SAG1E,CAAA;QAAA,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEb,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgKlB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAySlB,CAAC;IACL,CAAC;CACJ;AAhfD,kCAgfC"}
{"version":3,"file":"ProjectView.js","sourceRoot":"","sources":["../../../src/panels/views/ProjectView.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAGtC,MAAa,WAAY,SAAQ,mBAAQ;IACrC,MAAM,CAAC,IAA0E;QAC7E,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,IAAI,GAAG,EAAE,CAAC;QAErD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAwB,EAAE,EAAE;YAC3D,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;YAEhD,OAAO;;;kEAG+C,OAAO,CAAC,EAAE,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI;;0BAEjF,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;;;;yEAItB,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,IAAI,MAAM,YAAY;0BAC9F,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;sBAI9B,YAAY,CAAC,CAAC,CAAC,sDAAsD,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,IAAI,4CAA4C,CAAC,CAAC,CAAC,EAAE;yEAChG,OAAO,CAAC,EAAE;;;SAG1E,CAAA;QAAA,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEb,OAAO;;;;;;MAMT,IAAI,CAAC,SAAS,EAAE;MAChB,IAAI,CAAC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgKlB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAoSlB,CAAC;IACL,CAAC;CACJ;AA3eD,kCA2eC"}