Skip to content

Commit a483e6f

Browse files
Ticket #12 : Publish a function
1 parent 94c9b5f commit a483e6f

File tree

11 files changed

+145
-8
lines changed

11 files changed

+145
-8
lines changed

src/FaasNet.Website/Program.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace FaasNet.Website
2+
{
3+
public class Program
4+
{
5+
public static void Main(string[] args)
6+
{
7+
}
8+
}
9+
}

src/FaasNet.Website/src/app/functions/functions.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ArrayRenderingComponent } from "./function-rendering/array/array-render
55
import { FunctionRenderingComponent } from "./function-rendering/function-rendering.component";
66
import { StringRenderingComponent } from "./function-rendering/string/string-rendering.component";
77
import { FunctionsRoutes } from "./functions.routes";
8+
import { AddFunctionComponent } from "./list/add-function.component";
89
import { ListFunctionsComponent } from "./list/list.component";
910
import { InfoFunctionComponent } from "./view/info/info.component";
1011
import { InvokeFunctionComponent } from "./view/invoke/invoke.component";
@@ -23,7 +24,8 @@ import { ViewFunctionComponent } from "./view/view.component";
2324
ArrayRenderingComponent,
2425
StringRenderingComponent,
2526
InvokeFunctionComponent,
26-
InfoFunctionComponent
27+
InfoFunctionComponent,
28+
AddFunctionComponent
2729
]
2830
})
2931

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<h1 mat-dialog-title>{{ 'functions.add' | translate }}</h1>
2+
<form [formGroup]="addFunctionFormGroup" (ngSubmit)="save()">
3+
<div mat-dialog-content>
4+
<!-- Name -->
5+
<mat-form-field appearance="outline" class="full-width">
6+
<mat-label>{{ 'functions.name' | translate }}</mat-label>
7+
<input matInput formControlName="name" />
8+
<mat-error *ngIf="addFunctionFormGroup.get('name')?.hasError('required')">
9+
{{ 'functions.nameRequired' | translate }}
10+
</mat-error>
11+
</mat-form-field>
12+
<!-- Image -->
13+
<mat-form-field appearance="outline" class="full-width">
14+
<mat-label>{{ 'functions.image' | translate }}</mat-label>
15+
<input matInput formControlName="image" />
16+
<mat-error *ngIf="addFunctionFormGroup.get('image')?.hasError('required')">
17+
{{ 'functions.imageRequired' | translate }}
18+
</mat-error>
19+
</mat-form-field>
20+
</div>
21+
<div mat-dialog-actions>
22+
<button mat-button color="primary">{{ 'shared.create' | translate }}</button>
23+
<button mat-button color="warn" mat-dialog-close>{{ 'shared.close' | translate }}</button>
24+
</div>
25+
</form>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Component } from '@angular/core';
2+
import { FormControl, FormGroup, Validators } from '@angular/forms';
3+
import { MatDialogRef } from '@angular/material/dialog';
4+
import { TranslateService } from '@ngx-translate/core';
5+
6+
@Component({
7+
selector: 'addfunction',
8+
templateUrl: './add-function.component.html'
9+
})
10+
export class AddFunctionComponent{
11+
addFunctionFormGroup: FormGroup = new FormGroup({
12+
name: new FormControl('', [Validators.required]),
13+
image: new FormControl('', [Validators.required])
14+
});
15+
16+
constructor(
17+
private translateService: TranslateService,
18+
private dialogRef: MatDialogRef<AddFunctionComponent>) {
19+
}
20+
21+
save() {
22+
if (!this.addFunctionFormGroup.valid) {
23+
return;
24+
}
25+
26+
this.dialogRef.close(this.addFunctionFormGroup.value);
27+
}
28+
}

src/FaasNet.Website/src/app/functions/list/list.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
</ul>
66
</div>
77
</div>
8+
<div class="mb-10">
9+
<button mat-raised-button color="primary" (click)="addFunction()">{{ 'functions.add' | translate }}</button>
10+
</div>
811
<div class="mat-elevation-z8 overflow-hidden">
912
<mat-table class="full-width" [dataSource]="functions" matSortActive="createDateTime" matSortDirection="desc" matSort>
1013
<!-- Name -->

src/FaasNet.Website/src/app/functions/list/list.component.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { Component, OnInit, ViewChild } from '@angular/core';
2+
import { MatDialog } from '@angular/material/dialog';
23
import { MatPaginator } from '@angular/material/paginator';
4+
import { MatSnackBar } from '@angular/material/snack-bar';
35
import { MatSort } from '@angular/material/sort';
4-
import { select, Store } from '@ngrx/store';
6+
import { ScannedActionsSubject, select, Store } from '@ngrx/store';
7+
import { TranslateService } from '@ngx-translate/core';
58
import * as fromReducers from '@stores/appstate';
69
import { SearchResult } from '@stores/common/search.model';
7-
import { startSearch } from '@stores/functions/actions/function.actions';
10+
import { startAdd, startSearch } from '@stores/functions/actions/function.actions';
811
import { FunctionResult } from '@stores/functions/models/function.model';
912
import { merge } from 'rxjs';
13+
import { filter } from 'rxjs/operators';
14+
import { AddFunctionComponent } from './add-function.component';
1015

1116
@Component({
1217
selector: 'list-functions',
@@ -20,9 +25,28 @@ export class ListFunctionsComponent implements OnInit {
2025
length: number | undefined;
2126

2227
constructor(
23-
private store: Store<fromReducers.AppState>) { }
28+
private store: Store<fromReducers.AppState>,
29+
private dialog: MatDialog,
30+
private actions$: ScannedActionsSubject,
31+
private translateService: TranslateService,
32+
private snackBar: MatSnackBar) { }
2433

2534
ngOnInit(): void {
35+
this.actions$.pipe(
36+
filter((action: any) => action.type === '[Functions] COMPLETE_ADD_FUNCTION'))
37+
.subscribe((e) => {
38+
this.snackBar.open(this.translateService.instant('functions.messages.functionAdded'), this.translateService.instant('undo'), {
39+
duration: 2000
40+
});
41+
this.refresh();
42+
});
43+
this.actions$.pipe(
44+
filter((action: any) => action.type === '[Functions] ERROR_ADD_FUNCTION'))
45+
.subscribe(() => {
46+
this.snackBar.open(this.translateService.instant('functions.messages.errorAddFunction'), this.translateService.instant('undo'), {
47+
duration: 2000
48+
});
49+
});
2650
this.store.pipe(select(fromReducers.selectFunctionsResult)).subscribe((state: SearchResult<FunctionResult> | null) => {
2751
if (!state || !state.content) {
2852
return;
@@ -42,6 +66,20 @@ export class ListFunctionsComponent implements OnInit {
4266
this.refresh();
4367
}
4468

69+
addFunction() {
70+
const dialogRef = this.dialog.open(AddFunctionComponent, {
71+
width: '800px'
72+
});
73+
dialogRef.afterClosed().subscribe((opt: any) => {
74+
if (!opt) {
75+
return;
76+
}
77+
78+
const addFunction = startAdd({ name: opt.name, image: opt.image });
79+
this.store.dispatch(addFunction);
80+
});
81+
}
82+
4583
private refresh() {
4684
if (!this.paginator || !this.sort) {
4785
return;

src/FaasNet.Website/src/assets/i18n/en.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"list": "Functions",
44
"name": "Function",
55
"image": "Docker Image",
6+
"add": "Add a function",
67
"createDateTime": "Create Datetime",
78
"updateDateTime": "Update Datetime",
89
"launch": "Launch",
@@ -15,16 +16,22 @@
1516
"deleteTitle": "Delete this function",
1617
"delete": "Delete",
1718
"info": "Information",
19+
"nameRequired": "The name is required",
20+
"imageRequired": "The image is required",
1821
"messages": {
1922
"errorInvokeFunction": "An error occured while trying to invoke the function",
2023
"functionRemoved": "The function has been removed",
21-
"errorRemoveFunction": "An error occured while trying to remove the function"
24+
"errorRemoveFunction": "An error occured while trying to remove the function",
25+
"functionAdded": "The function has been added",
26+
"errorAddFunction": "An error occured while trying to add the function"
2227
}
2328
},
2429
"shared": {
2530
"add": "Add",
2631
"remove": "Remove",
2732
"save": "Save",
28-
"parameter": "Parameter N°{{index}}"
33+
"parameter": "Parameter N°{{index}}",
34+
"create": "Create",
35+
"close": "Close"
2936
}
3037
}

src/FaasNet.Website/src/stores/functions/actions/function.actions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ export const errorGet = createAction('[Functions] ERROR_GET_FUNCTION');
1717
export const startDelete = createAction('[Functions] START_DELETE_FUNCTION', props<{ name: string }>());
1818
export const completeDelete = createAction('[Functions] COMPLETE_DELETE_FUNCTION');
1919
export const errorDelete = createAction('[Functions] ERROR_DELETE_FUNCTION');
20+
export const startAdd = createAction('[Functions] START_ADD_FUNCTION', props<{ name: string, image: string }>());
21+
export const completeAdd = createAction('[Functions] COMPLETE_ADD_FUNCTION', props<{ name: string, image: string }>());
22+
export const errorAdd = createAction('[Functions] ERROR_ADD_FUNCTION');

src/FaasNet.Website/src/stores/functions/effects/function.effects.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { Actions, Effect, ofType } from '@ngrx/effects';
33
import { of } from 'rxjs';
44
import { catchError, map, mergeMap } from 'rxjs/operators';
55
import {
6+
completeAdd,
67
completeDelete,
78
completeGet,
89
completeGetConfiguration,
910
completeInvoke,
10-
completeSearch, errorDelete, errorGet, errorGetConfiguration, errorInvoke, errorSearch, startDelete, startGet, startGetConfiguration, startInvoke, startSearch
11+
completeSearch, errorAdd, errorDelete, errorGet, errorGetConfiguration, errorInvoke, errorSearch, startAdd, startDelete, startGet, startGetConfiguration, startInvoke, startSearch
1112
} from '../actions/function.actions';
1213
import { FunctionService } from '../services/function.service';
1314

@@ -86,5 +87,19 @@ export class FunctionEffects {
8687
);
8788
}
8889
)
90+
);
91+
92+
@Effect()
93+
addFunction$ = this.actions$
94+
.pipe(
95+
ofType(startAdd),
96+
mergeMap((evt: { name: string, image: string }) => {
97+
return this.applicationService.add(evt.name, evt.image)
98+
.pipe(
99+
map(content => completeAdd({ name: evt.name, image: evt.image })),
100+
catchError(() => of(errorAdd()))
101+
);
102+
}
103+
)
89104
);
90105
}

src/FaasNet.Website/src/stores/functions/reducers/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const functionReducer = createReducer(
4444
...state,
4545
Function: { ...content }
4646
};
47-
}),
47+
})
4848
);
4949

5050
export function getSearchFunctionsReducer(state: SearchFunctionsState | undefined, action: Action) {

0 commit comments

Comments
 (0)