添加了上传url的ui功能
This commit is contained in:
@@ -72,6 +72,7 @@ class ConfigPanel {
|
|||||||
this.moduleFolders = [];
|
this.moduleFolders = [];
|
||||||
this.currentModuleFolderFileTree = [];
|
this.currentModuleFolderFileTree = [];
|
||||||
this.projectPaths = new Map();
|
this.projectPaths = new Map();
|
||||||
|
this.pendingUploadFolderId = null;
|
||||||
// 仓库配置
|
// 仓库配置
|
||||||
this.repoConfigs = [];
|
this.repoConfigs = [];
|
||||||
// 状态管理
|
// 状态管理
|
||||||
@@ -197,6 +198,34 @@ class ConfigPanel {
|
|||||||
vscode.window.showErrorMessage(`在仓库配置中未找到名为 "${repoName}" 的仓库,请检查 dcsp-repos.json。`);
|
vscode.window.showErrorMessage(`在仓库配置中未找到名为 "${repoName}" 的仓库,请检查 dcsp-repos.json。`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 1️⃣ 新逻辑:Local 上传(pendingUploadFolderId 不为空)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
if (this.pendingUploadFolderId) {
|
||||||
|
const localFolderId = this.pendingUploadFolderId;
|
||||||
|
this.pendingUploadFolderId = null; // 必须清空,避免影响其他操作
|
||||||
|
console.log("🚀 Local 上传流程:repo =", repoName, "folderId =", localFolderId);
|
||||||
|
const folder = this.moduleFolders.find(f => f.id === localFolderId);
|
||||||
|
if (!folder) {
|
||||||
|
vscode.window.showErrorMessage("未找到要上传的本地模块文件夹");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 生成本地路径
|
||||||
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage("无法确定本地模块文件夹路径");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 自动从本地文件夹名生成分支名
|
||||||
|
const branchName = path.basename(fullPath);
|
||||||
|
console.log("🌿 自动生成分支名:", branchName);
|
||||||
|
// 正式执行上传
|
||||||
|
await this.uploadLocalModuleFolder(localFolderId, repo.url, branchName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 2️⃣ 旧逻辑:获取分支
|
||||||
|
// ---------------------------------------------------
|
||||||
this.currentRepoForBranches = repo;
|
this.currentRepoForBranches = repo;
|
||||||
await this.fetchBranchesForRepo(repo);
|
await this.fetchBranchesForRepo(repo);
|
||||||
}
|
}
|
||||||
@@ -264,8 +293,10 @@ class ConfigPanel {
|
|||||||
'deleteModuleFolder': (data) => this.deleteModuleFolder(data.folderId),
|
'deleteModuleFolder': (data) => this.deleteModuleFolder(data.folderId),
|
||||||
'importGitFile': (data) => this.importGitFile(data.filePath),
|
'importGitFile': (data) => this.importGitFile(data.filePath),
|
||||||
'openTheModuleFolder': (data) => this.openTheModuleFolder(data.moduleType, data.id),
|
'openTheModuleFolder': (data) => this.openTheModuleFolder(data.moduleType, data.id),
|
||||||
|
'renameModuleFolder': (data) => this.renameModuleFolder(data.folderId, data.newName),
|
||||||
// 上传功能
|
// 上传功能
|
||||||
'uploadGitModuleFolder': (data) => this.uploadGitModuleFolder(data.folderId, data.username, data.password),
|
'uploadGitModuleFolder': (data) => this.uploadGitModuleFolder(data.folderId, data.username, data.password),
|
||||||
|
'openRepoSelectForUpload': (data) => this.handleOpenRepoSelectForUpload(data.folderId),
|
||||||
'uploadLocalModuleFolder': (data) => this.uploadLocalModuleFolder(data.folderId, data.repoUrl, data.branchName)
|
'uploadLocalModuleFolder': (data) => this.uploadLocalModuleFolder(data.folderId, data.repoUrl, data.branchName)
|
||||||
};
|
};
|
||||||
const handler = messageHandlers[data.type];
|
const handler = messageHandlers[data.type];
|
||||||
@@ -476,6 +507,12 @@ class ConfigPanel {
|
|||||||
await this.saveCurrentProjectData();
|
await this.saveCurrentProjectData();
|
||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
|
async handleOpenRepoSelectForUpload(folderId) {
|
||||||
|
console.log("📌 Local 上传:收到 openRepoSelectForUpload,folderId =", folderId);
|
||||||
|
this.pendingUploadFolderId = folderId;
|
||||||
|
// 复用你现有的仓库选择弹窗
|
||||||
|
await this.openRepoSelect();
|
||||||
|
}
|
||||||
async deleteConfig(configId) {
|
async deleteConfig(configId) {
|
||||||
const config = this.configs.find(c => c.id === configId);
|
const config = this.configs.find(c => c.id === configId);
|
||||||
if (!config)
|
if (!config)
|
||||||
@@ -1629,6 +1666,31 @@ class ConfigPanel {
|
|||||||
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
vscode.window.showErrorMessage(`打开模块文件夹文件失败: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async renameModuleFolder(folderId, newName) {
|
||||||
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
|
if (!folder) {
|
||||||
|
vscode.window.showErrorMessage('未找到模块文件夹');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const oldName = folder.localPath.split('/').pop();
|
||||||
|
if (!oldName)
|
||||||
|
return;
|
||||||
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath)
|
||||||
|
return;
|
||||||
|
const newFullPath = path.join(path.dirname(fullPath), newName);
|
||||||
|
try {
|
||||||
|
await fs.promises.rename(fullPath, newFullPath);
|
||||||
|
// 更新 localPath
|
||||||
|
folder.localPath = folder.localPath.replace(/\/[^/]+$/, '/' + newName);
|
||||||
|
await this.saveCurrentProjectData();
|
||||||
|
vscode.window.showInformationMessage(`已重命名文件夹: ${oldName} → ${newName}`);
|
||||||
|
this.updateWebview();
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
vscode.window.showErrorMessage('重命名失败: ' + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
// =============================================
|
// =============================================
|
||||||
// Webview 更新方法
|
// Webview 更新方法
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -228,6 +228,12 @@ class BaseView {
|
|||||||
|
|
||||||
if (cancelBtn) {
|
if (cancelBtn) {
|
||||||
cancelBtn.addEventListener('click', function () {
|
cancelBtn.addEventListener('click', function () {
|
||||||
|
// 通知后端取消,清理可能的状态(例如待上传的本地文件夹)
|
||||||
|
if (typeof vscode !== 'undefined') {
|
||||||
|
vscode.postMessage({
|
||||||
|
type: 'repoSelectCanceled'
|
||||||
|
});
|
||||||
|
}
|
||||||
overlay.remove();
|
overlay.remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;IAIS,SAAS;QACf,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAiQN,CAAC;IACN,CAAC;CACJ;AA7QD,4BA6QC"}
|
{"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;IAIS,SAAS;QACf,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAuQN,CAAC;IACN,CAAC;CACJ;AAnRD,4BAmRC"}
|
||||||
@@ -38,12 +38,18 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
return `
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="editable">${icon} ${folder.name}</span>
|
<span class="editable clickable" onclick="renameModuleFolder('${folder.id}')">
|
||||||
|
${icon} ${folder.name}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="category-${folder.type}">${category}</td>
|
<td class="category-${folder.type}">${category}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', '${folder.type}')">${folder.localPath.split('/').pop()}</span>
|
<span class="clickable"
|
||||||
</td>
|
onclick="renameModuleFolder('${folder.id}', '${folder.localPath.split('/').pop()}')">
|
||||||
|
📄 ${folder.localPath.split('/').pop()}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-upload" onclick="uploadModuleFolder('${folder.id}', '${folder.type}')" style="margin-right: 5px;">上传</button>
|
<button class="btn-upload" onclick="uploadModuleFolder('${folder.id}', '${folder.type}')" style="margin-right: 5px;">上传</button>
|
||||||
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
||||||
@@ -293,7 +299,7 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
<div class="config-section">
|
<div class="config-section">
|
||||||
<h3 class="section-title">📚 模块云仓库</h3>
|
<h3 class="section-title">📚 模块云仓库</h3>
|
||||||
|
|
||||||
<!-- 仓库选择区域:不再手动输入 URL,通过弹窗获取仓库 -->
|
<!-- 仓库选择区域 -->
|
||||||
<div class="url-input-section">
|
<div class="url-input-section">
|
||||||
<h4>🔗 获取仓库</h4>
|
<h4>🔗 获取仓库</h4>
|
||||||
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
|
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
|
||||||
@@ -316,6 +322,25 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
let branchTreeData = [];
|
let branchTreeData = [];
|
||||||
let selectedConfigs = new Set();
|
let selectedConfigs = new Set();
|
||||||
|
|
||||||
|
function renameModuleFolder(folderId, oldName) {
|
||||||
|
showPromptDialog(
|
||||||
|
'重命名模块文件夹',
|
||||||
|
'请输入新的名称:',
|
||||||
|
oldName,
|
||||||
|
function(newName) {
|
||||||
|
if (newName && newName.trim() && newName !== oldName) {
|
||||||
|
vscode.postMessage({
|
||||||
|
type: 'renameModuleFolder',
|
||||||
|
folderId: folderId,
|
||||||
|
newName: newName.trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 配置管理功能
|
// 配置管理功能
|
||||||
function editConfigName(configId, currentName) {
|
function editConfigName(configId, currentName) {
|
||||||
showPromptDialog(
|
showPromptDialog(
|
||||||
@@ -428,90 +453,12 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else if (folderType === 'local') {
|
} else if (folderType === 'local') {
|
||||||
// Local 类型:弹出 URL 输入对话框
|
// Local 类型:不再手动输入 URL,改为复用“获取仓库”弹窗
|
||||||
showUploadDialog(folderId);
|
// 后端将根据选择的仓库 + 本地文件夹名 自动确定 repoUrl 和 分支名
|
||||||
}
|
vscode.postMessage({
|
||||||
}
|
type: 'openRepoSelectForUpload',
|
||||||
|
folderId: folderId
|
||||||
// 上传对话框函数(本地->Git)
|
});
|
||||||
function showUploadDialog(folderId) {
|
|
||||||
const overlay = document.createElement('div');
|
|
||||||
overlay.className = 'modal-overlay';
|
|
||||||
overlay.id = 'uploadModal';
|
|
||||||
|
|
||||||
overlay.innerHTML = \`
|
|
||||||
<div class="modal-dialog" style="width: 500px;">
|
|
||||||
<div class="modal-title">上传本地文件夹到 Git 仓库</div>
|
|
||||||
<div class="merge-dialog-content">
|
|
||||||
<div class="merge-input-section">
|
|
||||||
<label class="merge-input-label">Git 仓库 URL</label>
|
|
||||||
<input type="text" id="gitRepoUrlInput" class="merge-input-field"
|
|
||||||
placeholder="请输入 Git 仓库 URL,例如: https://github.com/username/repo.git">
|
|
||||||
<div class="merge-input-help">将把当前文件夹的内容上传到此仓库</div>
|
|
||||||
</div>
|
|
||||||
<div class="merge-input-section">
|
|
||||||
<label class="merge-input-label">分支名称</label>
|
|
||||||
<input type="text" id="branchNameInput" class="merge-input-field"
|
|
||||||
placeholder="请输入分支名称" value="">
|
|
||||||
<div class="merge-input-help">将以当前文件夹名称作为分支名创建新分支</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-buttons">
|
|
||||||
<button class="modal-btn modal-btn-secondary" onclick="closeUploadDialog()">取消</button>
|
|
||||||
<button class="modal-btn modal-btn-primary" onclick="confirmUpload('\${folderId}')">确定上传</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
\`;
|
|
||||||
|
|
||||||
document.body.appendChild(overlay);
|
|
||||||
|
|
||||||
// 自动聚焦到 URL 输入框
|
|
||||||
setTimeout(() => {
|
|
||||||
const urlInput = document.getElementById('gitRepoUrlInput');
|
|
||||||
if (urlInput) {
|
|
||||||
urlInput.focus();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirmUpload(folderId) {
|
|
||||||
const urlInput = document.getElementById('gitRepoUrlInput');
|
|
||||||
const branchInput = document.getElementById('branchNameInput');
|
|
||||||
|
|
||||||
const repoUrl = urlInput.value.trim();
|
|
||||||
const branchName = branchInput.value.trim();
|
|
||||||
|
|
||||||
if (!repoUrl) {
|
|
||||||
alert('请输入 Git 仓库 URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!repoUrl.startsWith('http')) {
|
|
||||||
alert('请输入有效的 Git 仓库 URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!branchName) {
|
|
||||||
alert('请输入分支名称');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('📤 确认上传本地文件夹:', { folderId, repoUrl, branchName });
|
|
||||||
|
|
||||||
vscode.postMessage({
|
|
||||||
type: 'uploadLocalModuleFolder',
|
|
||||||
folderId: folderId,
|
|
||||||
repoUrl: repoUrl,
|
|
||||||
branchName: branchName
|
|
||||||
});
|
|
||||||
|
|
||||||
closeUploadDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeUploadDialog() {
|
|
||||||
const modal = document.getElementById('uploadModal');
|
|
||||||
if (modal) {
|
|
||||||
modal.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,16 +466,14 @@ class ConfigView extends BaseView_1.BaseView {
|
|||||||
vscode.postMessage({ type: 'goBackToContainers' });
|
vscode.postMessage({ type: 'goBackToContainers' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔁 新逻辑:通过弹窗获取仓库(不再手动输入 URL)
|
// 🔁 通过弹窗获取仓库(用于克隆)
|
||||||
function openRepoSelect() {
|
function openRepoSelect() {
|
||||||
console.log('📦 请求仓库列表以选择 Git 仓库');
|
console.log('📦 请求仓库列表以选择 Git 仓库(用于克隆分支)');
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'openRepoSelect'
|
type: 'openRepoSelect'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不再在前端手动输入/校验 URL,分支拉取由 repo 选择 + 后端完成
|
|
||||||
|
|
||||||
function toggleBranch(branchName) {
|
function toggleBranch(branchName) {
|
||||||
const checkbox = document.getElementById('branch-' + branchName.replace(/[^a-zA-Z0-9-]/g, '-'));
|
const checkbox = document.getElementById('branch-' + branchName.replace(/[^a-zA-Z0-9-]/g, '-'));
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -10,6 +10,7 @@ import { ContainerView } from './views/ContainerView';
|
|||||||
import { ConfigView } from './views/ConfigView';
|
import { ConfigView } from './views/ConfigView';
|
||||||
import { ModuleFolder } from './types/CommonTypes';
|
import { ModuleFolder } from './types/CommonTypes';
|
||||||
|
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
// 数据模型接口
|
// 数据模型接口
|
||||||
// =============================================
|
// =============================================
|
||||||
@@ -92,6 +93,7 @@ export class ConfigPanel {
|
|||||||
private moduleFolders: ModuleFolder[] = [];
|
private moduleFolders: ModuleFolder[] = [];
|
||||||
private currentModuleFolderFileTree: GitFileTree[] = [];
|
private currentModuleFolderFileTree: GitFileTree[] = [];
|
||||||
private projectPaths: Map<string, string> = new Map();
|
private projectPaths: Map<string, string> = new Map();
|
||||||
|
private pendingUploadFolderId: string | null = null;
|
||||||
|
|
||||||
// 仓库配置
|
// 仓库配置
|
||||||
private repoConfigs: RepoConfigItem[] = [];
|
private repoConfigs: RepoConfigItem[] = [];
|
||||||
@@ -268,17 +270,54 @@ export class ConfigPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async handleRepoSelectedForBranches(repoName: string): Promise<void> {
|
private async handleRepoSelectedForBranches(repoName: string): Promise<void> {
|
||||||
await this.loadRepoConfigs();
|
await this.loadRepoConfigs();
|
||||||
const repo = this.repoConfigs.find(r => r.name === repoName);
|
const repo = this.repoConfigs.find(r => r.name === repoName);
|
||||||
if (!repo) {
|
|
||||||
vscode.window.showErrorMessage(`在仓库配置中未找到名为 "${repoName}" 的仓库,请检查 dcsp-repos.json。`);
|
if (!repo) {
|
||||||
|
vscode.window.showErrorMessage(`在仓库配置中未找到名为 "${repoName}" 的仓库,请检查 dcsp-repos.json。`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 1️⃣ 新逻辑:Local 上传(pendingUploadFolderId 不为空)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
if (this.pendingUploadFolderId) {
|
||||||
|
const localFolderId = this.pendingUploadFolderId;
|
||||||
|
this.pendingUploadFolderId = null; // 必须清空,避免影响其他操作
|
||||||
|
|
||||||
|
console.log("🚀 Local 上传流程:repo =", repoName, "folderId =", localFolderId);
|
||||||
|
|
||||||
|
const folder = this.moduleFolders.find(f => f.id === localFolderId);
|
||||||
|
if (!folder) {
|
||||||
|
vscode.window.showErrorMessage("未找到要上传的本地模块文件夹");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentRepoForBranches = repo;
|
// 生成本地路径
|
||||||
await this.fetchBranchesForRepo(repo);
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath) {
|
||||||
|
vscode.window.showErrorMessage("无法确定本地模块文件夹路径");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动从本地文件夹名生成分支名
|
||||||
|
const branchName = path.basename(fullPath);
|
||||||
|
console.log("🌿 自动生成分支名:", branchName);
|
||||||
|
|
||||||
|
// 正式执行上传
|
||||||
|
await this.uploadLocalModuleFolder(localFolderId, repo.url, branchName);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 2️⃣ 旧逻辑:获取分支
|
||||||
|
// ---------------------------------------------------
|
||||||
|
this.currentRepoForBranches = repo;
|
||||||
|
await this.fetchBranchesForRepo(repo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
// Webview 消息处理
|
// Webview 消息处理
|
||||||
// =============================================
|
// =============================================
|
||||||
@@ -353,9 +392,11 @@ export class ConfigPanel {
|
|||||||
'deleteModuleFolder': (data) => this.deleteModuleFolder(data.folderId),
|
'deleteModuleFolder': (data) => this.deleteModuleFolder(data.folderId),
|
||||||
'importGitFile': (data) => this.importGitFile(data.filePath),
|
'importGitFile': (data) => this.importGitFile(data.filePath),
|
||||||
'openTheModuleFolder': (data) => this.openTheModuleFolder(data.moduleType, data.id),
|
'openTheModuleFolder': (data) => this.openTheModuleFolder(data.moduleType, data.id),
|
||||||
|
'renameModuleFolder': (data) => this.renameModuleFolder(data.folderId, data.newName),
|
||||||
|
|
||||||
// 上传功能
|
// 上传功能
|
||||||
'uploadGitModuleFolder': (data) => this.uploadGitModuleFolder(data.folderId, data.username, data.password),
|
'uploadGitModuleFolder': (data) => this.uploadGitModuleFolder(data.folderId, data.username, data.password),
|
||||||
|
'openRepoSelectForUpload': (data) => this.handleOpenRepoSelectForUpload(data.folderId),
|
||||||
'uploadLocalModuleFolder': (data) => this.uploadLocalModuleFolder(data.folderId, data.repoUrl, data.branchName)
|
'uploadLocalModuleFolder': (data) => this.uploadLocalModuleFolder(data.folderId, data.repoUrl, data.branchName)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -607,6 +648,15 @@ export class ConfigPanel {
|
|||||||
this.updateWebview();
|
this.updateWebview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleOpenRepoSelectForUpload(folderId: string): Promise<void> {
|
||||||
|
console.log("📌 Local 上传:收到 openRepoSelectForUpload,folderId =", folderId);
|
||||||
|
this.pendingUploadFolderId = folderId;
|
||||||
|
|
||||||
|
// 复用你现有的仓库选择弹窗
|
||||||
|
await this.openRepoSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private async deleteConfig(configId: string): Promise<void> {
|
private async deleteConfig(configId: string): Promise<void> {
|
||||||
const config = this.configs.find(c => c.id === configId);
|
const config = this.configs.find(c => c.id === configId);
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
@@ -1979,6 +2029,39 @@ export class ConfigPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async renameModuleFolder(folderId: string, newName: string): Promise<void> {
|
||||||
|
const folder = this.moduleFolders.find(f => f.id === folderId);
|
||||||
|
if (!folder) {
|
||||||
|
vscode.window.showErrorMessage('未找到模块文件夹');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldName = folder.localPath.split('/').pop();
|
||||||
|
if (!oldName) return;
|
||||||
|
|
||||||
|
const fullPath = this.getModuleFolderFullPath(folder);
|
||||||
|
if (!fullPath) return;
|
||||||
|
|
||||||
|
const newFullPath = path.join(path.dirname(fullPath), newName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.promises.rename(fullPath, newFullPath);
|
||||||
|
|
||||||
|
// 更新 localPath
|
||||||
|
folder.localPath = folder.localPath.replace(/\/[^/]+$/, '/' + newName);
|
||||||
|
|
||||||
|
await this.saveCurrentProjectData();
|
||||||
|
|
||||||
|
vscode.window.showInformationMessage(`已重命名文件夹: ${oldName} → ${newName}`);
|
||||||
|
|
||||||
|
this.updateWebview();
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage('重命名失败: ' + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
// Webview 更新方法
|
// Webview 更新方法
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// src/panels/types/DataTypes.ts
|
|
||||||
// 此文件已过时,请使用 CommonTypes.ts 中的统一类型定义
|
|
||||||
export { ProjectData } from './CommonTypes';
|
|
||||||
@@ -232,6 +232,12 @@ export abstract class BaseView {
|
|||||||
|
|
||||||
if (cancelBtn) {
|
if (cancelBtn) {
|
||||||
cancelBtn.addEventListener('click', function () {
|
cancelBtn.addEventListener('click', function () {
|
||||||
|
// 通知后端取消,清理可能的状态(例如待上传的本地文件夹)
|
||||||
|
if (typeof vscode !== 'undefined') {
|
||||||
|
vscode.postMessage({
|
||||||
|
type: 'repoSelectCanceled'
|
||||||
|
});
|
||||||
|
}
|
||||||
overlay.remove();
|
overlay.remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,12 +83,18 @@ export class ConfigView extends BaseView {
|
|||||||
return `
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="editable">${icon} ${folder.name}</span>
|
<span class="editable clickable" onclick="renameModuleFolder('${folder.id}')">
|
||||||
|
${icon} ${folder.name}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="category-${folder.type}">${category}</td>
|
<td class="category-${folder.type}">${category}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="clickable" onclick="openTheModuleFolder('${folder.id}', '${folder.type}')">${folder.localPath.split('/').pop()}</span>
|
<span class="clickable"
|
||||||
</td>
|
onclick="renameModuleFolder('${folder.id}', '${folder.localPath.split('/').pop()}')">
|
||||||
|
📄 ${folder.localPath.split('/').pop()}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-upload" onclick="uploadModuleFolder('${folder.id}', '${folder.type}')" style="margin-right: 5px;">上传</button>
|
<button class="btn-upload" onclick="uploadModuleFolder('${folder.id}', '${folder.type}')" style="margin-right: 5px;">上传</button>
|
||||||
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
<button class="btn-delete" onclick="deleteModuleFolder('${folder.id}')">删除</button>
|
||||||
@@ -340,7 +346,7 @@ export class ConfigView extends BaseView {
|
|||||||
<div class="config-section">
|
<div class="config-section">
|
||||||
<h3 class="section-title">📚 模块云仓库</h3>
|
<h3 class="section-title">📚 模块云仓库</h3>
|
||||||
|
|
||||||
<!-- 仓库选择区域:不再手动输入 URL,通过弹窗获取仓库 -->
|
<!-- 仓库选择区域 -->
|
||||||
<div class="url-input-section">
|
<div class="url-input-section">
|
||||||
<h4>🔗 获取仓库</h4>
|
<h4>🔗 获取仓库</h4>
|
||||||
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
|
<div style="display: flex; gap: 10px; margin-top: 10px; align-items: center;">
|
||||||
@@ -363,6 +369,25 @@ export class ConfigView extends BaseView {
|
|||||||
let branchTreeData = [];
|
let branchTreeData = [];
|
||||||
let selectedConfigs = new Set();
|
let selectedConfigs = new Set();
|
||||||
|
|
||||||
|
function renameModuleFolder(folderId, oldName) {
|
||||||
|
showPromptDialog(
|
||||||
|
'重命名模块文件夹',
|
||||||
|
'请输入新的名称:',
|
||||||
|
oldName,
|
||||||
|
function(newName) {
|
||||||
|
if (newName && newName.trim() && newName !== oldName) {
|
||||||
|
vscode.postMessage({
|
||||||
|
type: 'renameModuleFolder',
|
||||||
|
folderId: folderId,
|
||||||
|
newName: newName.trim()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 配置管理功能
|
// 配置管理功能
|
||||||
function editConfigName(configId, currentName) {
|
function editConfigName(configId, currentName) {
|
||||||
showPromptDialog(
|
showPromptDialog(
|
||||||
@@ -475,90 +500,12 @@ export class ConfigView extends BaseView {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else if (folderType === 'local') {
|
} else if (folderType === 'local') {
|
||||||
// Local 类型:弹出 URL 输入对话框
|
// Local 类型:不再手动输入 URL,改为复用“获取仓库”弹窗
|
||||||
showUploadDialog(folderId);
|
// 后端将根据选择的仓库 + 本地文件夹名 自动确定 repoUrl 和 分支名
|
||||||
}
|
vscode.postMessage({
|
||||||
}
|
type: 'openRepoSelectForUpload',
|
||||||
|
folderId: folderId
|
||||||
// 上传对话框函数(本地->Git)
|
});
|
||||||
function showUploadDialog(folderId) {
|
|
||||||
const overlay = document.createElement('div');
|
|
||||||
overlay.className = 'modal-overlay';
|
|
||||||
overlay.id = 'uploadModal';
|
|
||||||
|
|
||||||
overlay.innerHTML = \`
|
|
||||||
<div class="modal-dialog" style="width: 500px;">
|
|
||||||
<div class="modal-title">上传本地文件夹到 Git 仓库</div>
|
|
||||||
<div class="merge-dialog-content">
|
|
||||||
<div class="merge-input-section">
|
|
||||||
<label class="merge-input-label">Git 仓库 URL</label>
|
|
||||||
<input type="text" id="gitRepoUrlInput" class="merge-input-field"
|
|
||||||
placeholder="请输入 Git 仓库 URL,例如: https://github.com/username/repo.git">
|
|
||||||
<div class="merge-input-help">将把当前文件夹的内容上传到此仓库</div>
|
|
||||||
</div>
|
|
||||||
<div class="merge-input-section">
|
|
||||||
<label class="merge-input-label">分支名称</label>
|
|
||||||
<input type="text" id="branchNameInput" class="merge-input-field"
|
|
||||||
placeholder="请输入分支名称" value="">
|
|
||||||
<div class="merge-input-help">将以当前文件夹名称作为分支名创建新分支</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-buttons">
|
|
||||||
<button class="modal-btn modal-btn-secondary" onclick="closeUploadDialog()">取消</button>
|
|
||||||
<button class="modal-btn modal-btn-primary" onclick="confirmUpload('\${folderId}')">确定上传</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
\`;
|
|
||||||
|
|
||||||
document.body.appendChild(overlay);
|
|
||||||
|
|
||||||
// 自动聚焦到 URL 输入框
|
|
||||||
setTimeout(() => {
|
|
||||||
const urlInput = document.getElementById('gitRepoUrlInput');
|
|
||||||
if (urlInput) {
|
|
||||||
urlInput.focus();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirmUpload(folderId) {
|
|
||||||
const urlInput = document.getElementById('gitRepoUrlInput');
|
|
||||||
const branchInput = document.getElementById('branchNameInput');
|
|
||||||
|
|
||||||
const repoUrl = urlInput.value.trim();
|
|
||||||
const branchName = branchInput.value.trim();
|
|
||||||
|
|
||||||
if (!repoUrl) {
|
|
||||||
alert('请输入 Git 仓库 URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!repoUrl.startsWith('http')) {
|
|
||||||
alert('请输入有效的 Git 仓库 URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!branchName) {
|
|
||||||
alert('请输入分支名称');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('📤 确认上传本地文件夹:', { folderId, repoUrl, branchName });
|
|
||||||
|
|
||||||
vscode.postMessage({
|
|
||||||
type: 'uploadLocalModuleFolder',
|
|
||||||
folderId: folderId,
|
|
||||||
repoUrl: repoUrl,
|
|
||||||
branchName: branchName
|
|
||||||
});
|
|
||||||
|
|
||||||
closeUploadDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeUploadDialog() {
|
|
||||||
const modal = document.getElementById('uploadModal');
|
|
||||||
if (modal) {
|
|
||||||
modal.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,16 +513,14 @@ export class ConfigView extends BaseView {
|
|||||||
vscode.postMessage({ type: 'goBackToContainers' });
|
vscode.postMessage({ type: 'goBackToContainers' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔁 新逻辑:通过弹窗获取仓库(不再手动输入 URL)
|
// 🔁 通过弹窗获取仓库(用于克隆)
|
||||||
function openRepoSelect() {
|
function openRepoSelect() {
|
||||||
console.log('📦 请求仓库列表以选择 Git 仓库');
|
console.log('📦 请求仓库列表以选择 Git 仓库(用于克隆分支)');
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
type: 'openRepoSelect'
|
type: 'openRepoSelect'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不再在前端手动输入/校验 URL,分支拉取由 repo 选择 + 后端完成
|
|
||||||
|
|
||||||
function toggleBranch(branchName) {
|
function toggleBranch(branchName) {
|
||||||
const checkbox = document.getElementById('branch-' + branchName.replace(/[^a-zA-Z0-9-]/g, '-'));
|
const checkbox = document.getElementById('branch-' + branchName.replace(/[^a-zA-Z0-9-]/g, '-'));
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
|
|||||||
Reference in New Issue
Block a user