Skip to content

Commit

Permalink
Support deleting a function from the FunctionEditComponent to the Sid…
Browse files Browse the repository at this point in the history
…ebarComponent
  • Loading branch information
ahmelsayed committed Jan 18, 2016
1 parent a98acef commit f73a169
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 19 deletions.
9 changes: 9 additions & 0 deletions AzureFunctions.Client/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class AppComponent implements OnInit{
public functionTemplates: FunctionTemplate[];
public selectedFunction: FunctionInfo;
public selectedFile: VfsObject;
public deleteSelectedFunction: boolean;
private initializing: boolean;

constructor(private _functionsService: FunctionsService) { }
Expand Down Expand Up @@ -55,4 +56,12 @@ export class AppComponent implements OnInit{
this.selectedFile = file;
}

onDeleteSelectedFunction(deleteSelectedFunction: boolean) {
this.deleteSelectedFunction = deleteSelectedFunction;
if (deleteSelectedFunction) {
this.selectedFile = null;
this.selectedFunction = null;
}
}

}
16 changes: 14 additions & 2 deletions AzureFunctions.Client/app/function-edit.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, OnInit} from 'angular2/core';
import {Component, OnInit, EventEmitter} from 'angular2/core';
import {FunctionsService} from './functions.service';
import {FunctionInfo} from './function-info';
import {VfsObject} from './vfs-object';
Expand All @@ -9,14 +9,18 @@ import {FunctionRunComponent} from './function-run.component';
selector: 'function-edit',
templateUrl: 'templates/function-edit.html',
inputs: ['selectedFunction', 'selectedFile'],
outputs: ['deleteSelectedFunction'],
directives: [AceEditorDirective, FunctionRunComponent]
})
export class FunctionEditComponent {
public selectedFunction: FunctionInfo;
public selectedFile: VfsObject;
public deleteSelectedFunction: EventEmitter<boolean>;
private updatedContent: string;

constructor(private _functionsService: FunctionsService) {}
constructor(private _functionsService: FunctionsService) {
this.deleteSelectedFunction = new EventEmitter<boolean>();
}

saveFile(file: VfsObject) {
if (file.isNew) {
Expand All @@ -37,4 +41,12 @@ export class FunctionEditComponent {
this.selectedFile.isDirty = true;
this.updatedContent = content;
}

deleteFunction(functionInfo: FunctionInfo) {
this._functionsService.deleteFunction(functionInfo)
.subscribe(r => {
this.deleteSelectedFunction.next(false);
this.deleteSelectedFunction.next(true);
});
}
}
1 change: 1 addition & 0 deletions AzureFunctions.Client/app/function-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export interface FunctionInfo {
expanded: boolean;
files: VfsObject[];
clientOnly: boolean;
isDeleted: boolean;
}
21 changes: 16 additions & 5 deletions AzureFunctions.Client/app/functions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ export class FunctionsService implements IFunctionsService {
script_root_path_href: null,
template_id: null,
test_data_href: null,
clientOnly: true
clientOnly: true,
isDeleted: false
};
}

Expand All @@ -115,14 +116,15 @@ export class FunctionsService implements IFunctionsService {
script_root_path_href: this.scmInfo.scm_url + '/api/vfs/site/wwwroot/app_data/jobs/functions/',
template_id: null,
test_data_href: null,
clientOnly: true
clientOnly: true,
isDeleted: false
};
}

getNewFileObject(functionInfo: FunctionInfo): VfsObject {
return {
name: '',
href: this.scmInfo.scm_url + '/api/vfs/site/wwwroot/app_data/functions/' + functionInfo.name + '/',
href: functionInfo.script_root_path_href,
isNew: true,
isDirty: true,
content: ''
Expand Down Expand Up @@ -152,7 +154,7 @@ export class FunctionsService implements IFunctionsService {
runFunction(functionInfo: FunctionInfo, content: string) {
var body: PassthroughInfo = {
httpMethod: 'POST',
url: this.scmInfo.scm_url + '/api/functions/' + functionInfo.name + '/run',
url: functionInfo.href + '/run',
requestBody: content,
mediaType: 'plain/text'
};
Expand All @@ -163,7 +165,7 @@ export class FunctionsService implements IFunctionsService {
getRunStatus(functionInfo: FunctionInfo, runId: string) {
var body: PassthroughInfo = {
httpMethod: 'GET',
url: this.scmInfo.scm_url + '/api/functions/' + functionInfo.name + '/status/' + runId
url: functionInfo.href + '/status/' + runId
};
return this._http.post('api/passthrough', JSON.stringify(body), { headers: this.getHeaders() })
.catch(e => Observable.of({
Expand All @@ -172,6 +174,15 @@ export class FunctionsService implements IFunctionsService {
.map<string>(r => r.text());
}

deleteFunction(functionInfo: FunctionInfo) {
var body: PassthroughInfo = {
httpMethod: 'DELETE',
url: functionInfo.href
};
return this._http.post('api/passthrough', JSON.stringify(body), { headers: this.getHeaders() })
.map<string>(r => r.statusText);
}

private getHeaders(contentType?: string): Headers {
contentType = contentType || 'application/json';
var headers = new Headers();
Expand Down
1 change: 1 addition & 0 deletions AzureFunctions.Client/app/ifunctions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export interface IFunctionsService {
getTestData(functionInfo: FunctionInfo): Observable<VfsObject>;
runFunction(functionInfo: FunctionInfo, content: string): Observable<RunResponse>;
getRunStatus(functionInfo: FunctionInfo, runId: string): Observable<string>;
deleteFunction(functionInfo: FunctionInfo): Observable<string>;
}
10 changes: 8 additions & 2 deletions AzureFunctions.Client/app/mock-functions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export class MockFunctionsService implements IFunctionsService {
script_root_path_href: null,
template_id: null,
test_data_href: null,
clientOnly: true
clientOnly: true,
isDeleted: false
};
}

Expand All @@ -86,7 +87,8 @@ export class MockFunctionsService implements IFunctionsService {
script_root_path_href: 'mocks/host.vfs.json',
template_id: null,
test_data_href: null,
clientOnly: true
clientOnly: true,
isDeleted: false
};
}

Expand Down Expand Up @@ -121,4 +123,8 @@ export class MockFunctionsService implements IFunctionsService {
id: "done"
});
}

deleteFunction(functionInfo: FunctionInfo) {
return Observable.of('Ok');
}
}
14 changes: 13 additions & 1 deletion AzureFunctions.Client/app/sidebar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {Subject} from 'rxjs/Subject';
@Component({
selector: 'sidebar',
templateUrl: 'templates/sidebar.html',
inputs: ['functionsInfo'],
inputs: ['functionsInfo', 'deleteSelectedFunction'],
outputs: ['functionSelected: selectedFunction', 'fileSelected: selectedFile']
})
export class SideBarComponent {
Expand Down Expand Up @@ -75,4 +75,16 @@ export class SideBarComponent {
event.stopPropagation();
event.preventDefault();
}

set deleteSelectedFunction(f: boolean) {
if (f)
for (var i = 0; this.functionsInfo.length; i++) {
if (this.functionsInfo[i] === this.selectedFunction) {
this.functionsInfo.splice(i, 1);
delete this.selectedFunction;
delete this.selectedFile;
break;
}
}
}
}
5 changes: 3 additions & 2 deletions AzureFunctions.Client/styles/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,10 @@ pre {
border: 0;
}

.file-list li a {
.file-list li span {
padding: 5px;
font-family: monospace;
display: block;
}

.file-list .selected {
Expand Down Expand Up @@ -249,7 +250,7 @@ pre {
background-image: none;
border: 1px solid transparent;
color: #fff;
background-color: #00bcf2;
background-color: #89c402;
}

.dirty {
Expand Down
8 changes: 6 additions & 2 deletions AzureFunctions.Client/templates/app.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<div class="container">
<top-bar></top-bar>
<div class="content">
<sidebar [functionsInfo]="functionsInfo" (selectedFunction)="onFunctionSelect($event)" (selectedFile)="onFileSelect($event)"></sidebar>
<sidebar
[functionsInfo]="functionsInfo"
[deleteSelectedFunction]="deleteSelectedFunction"
(selectedFunction)="onFunctionSelect($event)"
(selectedFile)="onFileSelect($event)"></sidebar>
<div class="work-space">
<div class="loader" *ngIf="initializing"></div>
<div *ngIf="selectedFunction">
<div *ngIf="selectedFunction.name !== 'New Function' || !selectedFunction.clientOnly">
<function-edit [selectedFunction]="selectedFunction" [selectedFile]="selectedFile"></function-edit>
<function-edit [selectedFunction]="selectedFunction" [selectedFile]="selectedFile" (deleteSelectedFunction)="onDeleteSelectedFunction($event)"></function-edit>
</div>
<div *ngIf="selectedFunction.clientOnly && selectedFunction.name === 'New Function'">
<new-function (functionAdded)="initFunctions()"></new-function>
Expand Down
4 changes: 3 additions & 1 deletion AzureFunctions.Client/templates/function-edit.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<function-run [functionInfo]="selectedFunction"></function-run>
<div class="gutter-container">
<h2 *ngIf="selectedFunction">{{selectedFunction.name}}</h2>
<h2 *ngIf="selectedFunction">{{selectedFunction.name}}
<i *ngIf="!selectedFunction.clientOnly" class="fa fa-trash clickable" (click)="deleteFunction(selectedFunction)"></i>
</h2>
<h3 class="file-name" *ngIf="selectedFile && !selectedFile.isNew">{{selectedFile.name}}</h3>
<input type="text" *ngIf="selectedFile && selectedFile.isNew" [(ngModel)]="selectedFile.name" class="new-function-name" placeholder="File Name"/>
<div class="file-tools"><button class="custom-button" *ngIf="selectedFile" [class.dirty]="selectedFile.isDirty" (click)="saveFile(selectedFile)">Save</button></div>
Expand Down
8 changes: 4 additions & 4 deletions AzureFunctions.Client/templates/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
(click)="clickStream.next(functionInfo)"
(click)="toggle(functionInfo)"
class="function-item">
<a class="function-item" [class.selected]="functionInfo === selectedFunction" href="#">{{functionInfo.name}}</a>
<span style="display: block; padding: 10px" class="function-item clickable" [class.selected]="functionInfo === selectedFunction" href="#">{{functionInfo.name}}</span>
<ul class="file-list" *ngIf="functionInfo.expanded">
<li *ngIf="!functionInfo.clientOnly">
<a href="#" (click)="onNewFileClick(functionInfo, $event)"><i class="fa fa-plus"></i> New File</a>
<span class="clickable" (click)="onNewFileClick(functionInfo, $event)"><i class="fa fa-plus"></i> New File</span>
</li>
<li *ngFor="#file of functionInfo.files">
<a class="function-file" href="#"
<span class="function-file clickable"
(click)="onFileClick(file, functionInfo, $event)"
[class.selected]="file === selectedFile">
<i class="fa fa-file-code-o"></i> {{file.name}}
</a>
</span>
</li>
</ul>
</li>
Expand Down

0 comments on commit f73a169

Please sign in to comment.