mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
@@ -46,6 +46,10 @@
|
||||
"title": "%refresh-workspace-command%",
|
||||
"category": "",
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "projects.removeProject",
|
||||
"title": "%remove-project-command%"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -69,6 +73,17 @@
|
||||
{
|
||||
"command": "dataworkspace.refresh",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "projects.removeProject",
|
||||
"when": "false"
|
||||
}
|
||||
],
|
||||
"view/item/context": [
|
||||
{
|
||||
"command": "projects.removeProject",
|
||||
"when": "view == dataworkspace.views.main && viewItem == databaseProject.itemType.project",
|
||||
"group": "9_dbProjectsLast@9"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
"data-workspace-view-container-name": "Projects",
|
||||
"main-view-name": "Projects",
|
||||
"add-project-command": "Add Project",
|
||||
"refresh-workspace-command": "Refresh"
|
||||
"refresh-workspace-command": "Refresh",
|
||||
"remove-project-command":"Remove Project"
|
||||
}
|
||||
|
||||
@@ -58,6 +58,17 @@ export interface IWorkspaceService {
|
||||
* @param projectFiles the list of project files to be added, the project file should be absolute path.
|
||||
*/
|
||||
addProjectsToWorkspace(projectFiles: vscode.Uri[]): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove the project from workspace
|
||||
* @param projectFile The project file to be removed
|
||||
*/
|
||||
removeProject(projectFile: vscode.Uri): Promise<void>;
|
||||
|
||||
/**
|
||||
* Event fires when projects in workspace changes
|
||||
*/
|
||||
readonly onDidWorkspaceProjectsChange: vscode.Event<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,11 @@ import { UnknownProjectsErrorMessage } from './constants';
|
||||
* Tree data provider for the workspace main view
|
||||
*/
|
||||
export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<WorkspaceTreeItem>{
|
||||
constructor(private _workspaceService: IWorkspaceService) { }
|
||||
constructor(private _workspaceService: IWorkspaceService) {
|
||||
this._workspaceService.onDidWorkspaceProjectsChange(() => {
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
private _onDidChangeTreeData: vscode.EventEmitter<void | WorkspaceTreeItem | null | undefined> | undefined = new vscode.EventEmitter<WorkspaceTreeItem | undefined | void>();
|
||||
readonly onDidChangeTreeData?: vscode.Event<void | WorkspaceTreeItem | null | undefined> | undefined = this._onDidChangeTreeData?.event;
|
||||
|
||||
@@ -31,6 +31,12 @@ declare module 'dataworkspace' {
|
||||
*/
|
||||
getProjectTreeDataProvider(projectFile: vscode.Uri): Promise<vscode.TreeDataProvider<any>>;
|
||||
|
||||
/**
|
||||
* Notify the project provider extension that the specified project file has been removed from the data workspace
|
||||
* @param projectFile The Uri of the project file
|
||||
*/
|
||||
RemoveProject(projectFile: vscode.Uri): Promise<void>;
|
||||
|
||||
/**
|
||||
* Gets the supported project types
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ import { WorkspaceTreeDataProvider } from './common/workspaceTreeDataProvider';
|
||||
import { WorkspaceService } from './services/workspaceService';
|
||||
import { DataWorkspaceExtension } from './dataWorkspaceExtension';
|
||||
import { SelectProjectFileActionName } from './common/constants';
|
||||
import { WorkspaceTreeItem } from './common/interfaces';
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<dataworkspace.IExtension> {
|
||||
const workspaceService = new WorkspaceService();
|
||||
@@ -36,7 +37,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<datawo
|
||||
return;
|
||||
}
|
||||
await workspaceService.addProjectsToWorkspace(fileUris);
|
||||
workspaceTreeDataProvider.refresh();
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -44,6 +44,10 @@ export async function activate(context: vscode.ExtensionContext): Promise<datawo
|
||||
workspaceTreeDataProvider.refresh();
|
||||
}));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('projects.removeProject', async (treeItem: WorkspaceTreeItem) => {
|
||||
await workspaceService.removeProject(vscode.Uri.file(treeItem.element.project.projectFilePath));
|
||||
}));
|
||||
|
||||
return new DataWorkspaceExtension();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ const WorkspaceConfigurationName = 'dataworkspace';
|
||||
const ProjectsConfigurationName = 'projects';
|
||||
|
||||
export class WorkspaceService implements IWorkspaceService {
|
||||
private _onDidWorkspaceProjectsChange: vscode.EventEmitter<void> = new vscode.EventEmitter<void>();
|
||||
readonly onDidWorkspaceProjectsChange: vscode.Event<void> = this._onDidWorkspaceProjectsChange?.event;
|
||||
|
||||
async addProjectsToWorkspace(projectFiles: vscode.Uri[]): Promise<void> {
|
||||
if (vscode.workspace.workspaceFile) {
|
||||
const currentProjects: vscode.Uri[] = await this.getProjectsInWorkspace();
|
||||
@@ -37,6 +40,7 @@ export class WorkspaceService implements IWorkspaceService {
|
||||
if (newProjectFileAdded) {
|
||||
// Save the new set of projects to the workspace configuration.
|
||||
await this.setWorkspaceConfigurationValue(ProjectsConfigurationName, currentProjects.map(project => this.toRelativePath(project)));
|
||||
this._onDidWorkspaceProjectsChange.fire();
|
||||
}
|
||||
|
||||
if (newWorkspaceFolders.length > 0) {
|
||||
@@ -68,6 +72,18 @@ export class WorkspaceService implements IWorkspaceService {
|
||||
return ProjectProviderRegistry.getProviderByProjectType(projectType);
|
||||
}
|
||||
|
||||
async removeProject(projectFile: vscode.Uri): Promise<void> {
|
||||
if (vscode.workspace.workspaceFile) {
|
||||
const currentProjects: vscode.Uri[] = await this.getProjectsInWorkspace();
|
||||
const projectIdx = currentProjects.findIndex((p: vscode.Uri) => p.fsPath === projectFile.fsPath);
|
||||
if (projectIdx !== -1) {
|
||||
currentProjects.splice(projectIdx, 1);
|
||||
await this.setWorkspaceConfigurationValue(ProjectsConfigurationName, currentProjects.map(project => this.toRelativePath(project)));
|
||||
this._onDidWorkspaceProjectsChange.fire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the project provider extension for the specified project is loaded
|
||||
* @param projectType The file extension of the project, if not specified, all project provider extensions will be loaded.
|
||||
|
||||
@@ -23,6 +23,9 @@ export function createProjectProvider(projectTypes: IProjectType[]): IProjectPro
|
||||
const treeDataProvider = new MockTreeDataProvider();
|
||||
const projectProvider: IProjectProvider = {
|
||||
supportedProjectTypes: projectTypes,
|
||||
RemoveProject: (projectFile: vscode.Uri): Promise<void> => {
|
||||
return Promise.resolve();
|
||||
},
|
||||
getProjectTreeDataProvider: (projectFile: vscode.Uri): Promise<vscode.TreeDataProvider<any>> => {
|
||||
return Promise.resolve(treeDataProvider);
|
||||
}
|
||||
|
||||
@@ -186,6 +186,10 @@ suite('WorkspaceService Tests', function (): void {
|
||||
stubWorkspaceFile(DefaultWorkspaceFilePath);
|
||||
const updateConfigurationStub = sinon.stub();
|
||||
const getConfigurationStub = sinon.stub().returns([processPath('folder1/proj2.sqlproj')]);
|
||||
const onWorkspaceProjectsChangedStub = sinon.stub();
|
||||
const onWorkspaceProjectsChangedDisposable = service.onDidWorkspaceProjectsChange(() => {
|
||||
onWorkspaceProjectsChangedStub();
|
||||
});
|
||||
stubGetConfigurationValue(getConfigurationStub, updateConfigurationStub);
|
||||
const asRelativeStub = sinon.stub(vscode.workspace, 'asRelativePath');
|
||||
sinon.stub(vscode.workspace, 'workspaceFolders').value(['.']);
|
||||
@@ -207,5 +211,28 @@ suite('WorkspaceService Tests', function (): void {
|
||||
should.strictEqual(updateWorkspaceFoldersStub.calledWith(1, null, sinon.match((arg) => {
|
||||
return arg.uri.path === '/test/other';
|
||||
})), true, 'updateWorkspaceFolder parameters does not match expectation');
|
||||
should.strictEqual(onWorkspaceProjectsChangedStub.calledOnce, true, 'the onDidWorkspaceProjectsChange event should have been fired');
|
||||
onWorkspaceProjectsChangedDisposable.dispose();
|
||||
});
|
||||
|
||||
test('test removeProject', async () => {
|
||||
const processPath = (original: string): string => {
|
||||
return original.replace(/\//g, path.sep);
|
||||
};
|
||||
stubWorkspaceFile(DefaultWorkspaceFilePath);
|
||||
const updateConfigurationStub = sinon.stub();
|
||||
const getConfigurationStub = sinon.stub().returns([processPath('folder1/proj2.sqlproj'), processPath('folder2/proj3.sqlproj')]);
|
||||
const onWorkspaceProjectsChangedStub = sinon.stub();
|
||||
const onWorkspaceProjectsChangedDisposable = service.onDidWorkspaceProjectsChange(() => {
|
||||
onWorkspaceProjectsChangedStub();
|
||||
});
|
||||
stubGetConfigurationValue(getConfigurationStub, updateConfigurationStub);
|
||||
await service.removeProject(vscode.Uri.file('/test/folder/folder1/proj2.sqlproj'));
|
||||
should.strictEqual(updateConfigurationStub.calledWith('projects', sinon.match.array.deepEquals([
|
||||
processPath('folder2/proj3.sqlproj')
|
||||
]), vscode.ConfigurationTarget.Workspace), true, 'updateConfiguration parameters does not match expectation for remove project');
|
||||
should.strictEqual(onWorkspaceProjectsChangedStub.calledOnce, true, 'the onDidWorkspaceProjectsChange event should have been fired');
|
||||
onWorkspaceProjectsChangedDisposable.dispose();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -71,6 +71,9 @@ suite('workspaceTreeDataProvider Tests', function (): void {
|
||||
icon: '',
|
||||
displayName: 'sql project'
|
||||
}],
|
||||
RemoveProject: (projectFile: vscode.Uri): Promise<void> => {
|
||||
return Promise.resolve();
|
||||
},
|
||||
getProjectTreeDataProvider: (projectFile: vscode.Uri): Promise<vscode.TreeDataProvider<any>> => {
|
||||
return Promise.resolve(treeDataProvider);
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.close",
|
||||
"when": "view =~ /^(sqlDatabaseProjectsView|dataworkspace.views.main)$/ && viewItem == databaseProject.itemType.project",
|
||||
"when": "view == sqlDatabaseProjectsView && viewItem == databaseProject.itemType.project",
|
||||
"group": "9_dbProjectsLast@9"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -24,6 +24,16 @@ export class SqlDatabaseProjectProvider implements dataworkspace.IProjectProvide
|
||||
return provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method when a project has been removed from the workspace view
|
||||
* @param projectFile The Uri of the project file
|
||||
*/
|
||||
RemoveProject(projectFile: vscode.Uri): Promise<void> {
|
||||
// No resource release needed
|
||||
console.log(`project file unloaded: ${projectFile.fsPath}`);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supported project types
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user