Commit 98f17f6b authored by François Agneray's avatar François Agneray
Browse files

WIP manage attributes by dataset

parent 90ea14bf
...@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #55: Add image renderer configuration - #55: Add image renderer configuration
### Changed ### Changed
- #57: GUI improvments
- #52: Update dependencies (Angular v11, ngrx v11, ...) - #52: Update dependencies (Angular v11, ngrx v11, ...)
- #56: Cone-search configuration improvement - #56: Cone-search configuration improvement
......
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Label</th>
<th>Save</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let attribute of attributeList">
<td>{{ attribute.id }}</td>
<td>{{ attribute.name }}</td>
<td>{{ attribute.label }}</td>
<td>
<button (click)="deleteAttribute.emit(attribute)" class="btn btn-outline-danger">
<i class="fas fa-trash-alt"></i> Delete attribute
</button>
</td>
</tr>
<tr *ngFor="let column of getColumnAvailable(); let index = index">
<td>{{ getMaxId() + index + 1 }}</td>
<td>{{ column.name }}</td>
<td>{{ column.name }}</td>
<td>
<button (click)="add(getMaxId() + index + 1, column)" class="btn btn-outline-primary">
<i class="fas fa-save"></i> Add attribute
</button>
</td>
</tr>
</tbody>
</table>
</div>
\ No newline at end of file
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core';
import { Attribute, Column } from '../../store/model';
@Component({
selector: 'app-form-manage-attribute',
templateUrl: 'form-manage-attribute.component.html',
styleUrls: [ 'form-manage-attribute.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FormManageAttributeComponent {
@Input() attributeList: Attribute[];
@Input() columnList: Column[];
@Output() addAttribute: EventEmitter<Attribute> = new EventEmitter();
@Output() deleteAttribute: EventEmitter<Attribute> = new EventEmitter();
getColumnAvailable(): Column[] {
return this.columnList.filter(c => !this.attributeList.map(a => a.name).includes(c.name));
}
getMaxId(): number {
return Math.max(...this.attributeList.map(a => a.id));
}
add(id: number, column: Column): void {
this.addAttribute.emit({
id,
name: column.name,
label: column.name,
form_label: column.name,
type: column.type,
criteria_display: id * 10,
output_display: id * 10,
display_detail: id * 10,
order_display: id * 10
})
}
}
import { FormManageAttributeComponent } from './form-manage-attribute.component';
import { FormAttributeListComponent } from './form-attribute-list.component'; import { FormAttributeListComponent } from './form-attribute-list.component';
import { TableDesignComponent } from './design/table-design.component'; import { TableDesignComponent } from './design/table-design.component';
import { TrDesignComponent } from './design/tr-design.component'; import { TrDesignComponent } from './design/tr-design.component';
...@@ -24,6 +25,7 @@ import { OutputCategoryListComponent } from './families/output-category-list.co ...@@ -24,6 +25,7 @@ import { OutputCategoryListComponent } from './families/output-category-list.co
import { FormOutputCategoryComponent } from './families/form-output-category.component'; import { FormOutputCategoryComponent } from './families/form-output-category.component';
export const attributeDummiesComponents = [ export const attributeDummiesComponents = [
FormManageAttributeComponent,
FormAttributeListComponent, FormAttributeListComponent,
TableDesignComponent, TableDesignComponent,
TrDesignComponent, TrDesignComponent,
......
<div class="container-fluid">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a routerLink="/instance-list">Instances</a></li>
<li class="breadcrumb-item"><a routerLink="/configure-instance/{{ instanceSelected | async }}">Configure
instance {{ instanceSelected | async }}</a></li>
<li class="breadcrumb-item active" aria-current="page">Manage attributes
{{ datasetSelected | async }}</li>
</ol>
</nav>
<div *ngIf="(attributeListIsLoading | async) || (columnListIsLoading | async)" class="row justify-content-center mt-5">
<span class="fas fa-circle-notch fa-spin fa-3x"></span>
<span class="sr-only">Loading...</span>
</div>
<div *ngIf="(attributeListIsLoaded | async) && (columnListIsLoaded | async)">
<app-form-manage-attribute
[attributeList]="attributeList | async"
[columnList]="columnList | async"
(addAttribute)="addAttribute($event)"
(deleteAttribute)="deleteAttribute($event)">
</app-form-manage-attribute>
</div>
</div>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { Attribute, Column} from '../../store/model';
import * as projectActions from '../../store/action/project.action';
import * as datasetActions from '../../store/action/dataset.action';
import * as attributeActions from '../../store/action/attribute.action';
import * as databaseActions from '../../store/action/database.action';
import * as attributeSelector from '../../store/selector/attribute.selector';
import * as datasetSelector from '../../store/selector/dataset.selector';
import * as instanceSelector from '../../store/selector/instance.selector';
import * as databaseSelector from '../../store/selector/database.selector';
import * as metamodelReducer from '../../store/reducer';
@Component({
selector: 'app-manage-attribute',
templateUrl: 'manage-attribute.component.html',
styleUrls: [ 'manage-attribute.component.css' ]
})
export class ManageAttributeComponent implements OnInit {
public instanceSelected: Observable<string>;
public datasetSelected: Observable<string>;
public attributeList: Observable<Attribute[]>;
public attributeListIsLoading: Observable<boolean>;
public attributeListIsLoaded: Observable<boolean>;
public columnList: Observable<Column[]>;
public columnListIsLoading: Observable<boolean>;
public columnListIsLoaded: Observable<boolean>;
constructor(private store: Store<metamodelReducer.State>) {
this.instanceSelected = store.select(instanceSelector.getInstanceSelected);
this.datasetSelected = store.select(datasetSelector.getDatasetSelected);
this.attributeList = store.select(attributeSelector.getAttributeList);
this.attributeListIsLoading = store.select(attributeSelector.getAttributeListIsLoading);
this.attributeListIsLoaded = store.select(attributeSelector.getAttributeListIsLoaded);
this.columnList = store.select(databaseSelector.getColumnList);
this.columnListIsLoading = store.select(databaseSelector.getColumnListIsLoading);
this.columnListIsLoaded = store.select(databaseSelector.getColumnListIsLoaded);
}
ngOnInit() {
this.store.dispatch(new projectActions.LoadProjectListAction());
this.store.dispatch(new datasetActions.LoadDatasetListAction());
this.store.dispatch(new attributeActions.LoadAttributeListAction());
this.store.dispatch(new databaseActions.LoadColumnListAction());
}
addAttribute(attribute: Attribute): void {
this.store.dispatch(new attributeActions.AddNewAttributeAction(attribute));
}
deleteAttribute(attribute: Attribute): void {
this.store.dispatch(new attributeActions.DeleteAttributeAction(attribute));
}
}
...@@ -13,6 +13,7 @@ import { NewInstanceComponent } from './containers/instance/new-instance.compone ...@@ -13,6 +13,7 @@ import { NewInstanceComponent } from './containers/instance/new-instance.compone
import { EditInstanceComponent } from './containers/instance/edit-instance.component'; import { EditInstanceComponent } from './containers/instance/edit-instance.component';
import { ConfigureInstanceComponent } from './containers/instance/configure-instance.component'; import { ConfigureInstanceComponent } from './containers/instance/configure-instance.component';
import { NewDatasetComponent } from './containers/dataset/new-dataset.component'; import { NewDatasetComponent } from './containers/dataset/new-dataset.component';
import { ManageAttributeComponent } from './containers/attribute/manage-attribute.component';
import { EditDatasetComponent } from './containers/dataset/edit-dataset.component'; import { EditDatasetComponent } from './containers/dataset/edit-dataset.component';
import { AttributeComponent } from './containers/attribute/attribute.component'; import { AttributeComponent } from './containers/attribute/attribute.component';
import { GroupComponent } from './containers/group/group.component'; import { GroupComponent } from './containers/group/group.component';
...@@ -30,6 +31,7 @@ const routes: Routes = [ ...@@ -30,6 +31,7 @@ const routes: Routes = [
{ path: 'configure-instance/:iname/new-group', component: NewGroupComponent }, { path: 'configure-instance/:iname/new-group', component: NewGroupComponent },
{ path: 'configure-instance/:iname/edit-group/:id', component: EditGroupComponent }, { path: 'configure-instance/:iname/edit-group/:id', component: EditGroupComponent },
{ path: 'configure-instance/:iname/new-dataset', component: NewDatasetComponent }, { path: 'configure-instance/:iname/new-dataset', component: NewDatasetComponent },
{ path: 'configure-instance/:iname/manage-attribute/:dname', component: ManageAttributeComponent },
{ path: 'configure-instance/:iname/edit-dataset/:dname', component: EditDatasetComponent }, { path: 'configure-instance/:iname/edit-dataset/:dname', component: EditDatasetComponent },
{ path: 'configure-instance/:iname/configure-dataset/:dname', component: AttributeComponent }, { path: 'configure-instance/:iname/configure-dataset/:dname', component: AttributeComponent },
{ {
...@@ -75,6 +77,7 @@ export const routedComponents = [ ...@@ -75,6 +77,7 @@ export const routedComponents = [
EditDatabaseComponent, EditDatabaseComponent,
ConfigureInstanceComponent, ConfigureInstanceComponent,
NewDatasetComponent, NewDatasetComponent,
ManageAttributeComponent,
EditDatasetComponent, EditDatasetComponent,
AttributeComponent, AttributeComponent,
GroupComponent, GroupComponent,
......
...@@ -5,9 +5,15 @@ import { Attribute } from '../model'; ...@@ -5,9 +5,15 @@ import { Attribute } from '../model';
export const LOAD_ATTRIBUTE_LIST = '[Attribute] Load Attribute List'; export const LOAD_ATTRIBUTE_LIST = '[Attribute] Load Attribute List';
export const LOAD_ATTRIBUTE_LIST_SUCCESS = '[Attribute] Load Attribute List Sucess'; export const LOAD_ATTRIBUTE_LIST_SUCCESS = '[Attribute] Load Attribute List Sucess';
export const LOAD_ATTRIBUTE_LIST_FAIL = '[Attribute] Load Attribute List Fail'; export const LOAD_ATTRIBUTE_LIST_FAIL = '[Attribute] Load Attribute List Fail';
export const ADD_NEW_ATTRIBUTE = '[Attribute] Add New Attribute';
export const ADD_NEW_ATTRIBUTE_SUCCESS = '[Attribute] Add New Attribute Success';
export const ADD_NEW_ATTRIBUTE_FAIL = '[Attribute] Add New Attribute Fail';
export const EDIT_ATTRIBUTE = '[Attribute] Edit Attribute'; export const EDIT_ATTRIBUTE = '[Attribute] Edit Attribute';
export const EDIT_ATTRIBUTE_SUCCESS = '[Attribute] Edit Attribute Success'; export const EDIT_ATTRIBUTE_SUCCESS = '[Attribute] Edit Attribute Success';
export const EDIT_ATTRIBUTE_FAIL = '[Attribute] Edit Attribute Fail'; export const EDIT_ATTRIBUTE_FAIL = '[Attribute] Edit Attribute Fail';
export const DELETE_ATTRIBUTE = '[Attribute] Delete Attribute';
export const DELETE_ATTRIBUTE_SUCCESS = '[Attribute] Delete Attribute Success';
export const DELETE_ATTRIBUTE_FAIL = '[Attribute] Delete Attribute Fail';
export const GENERATE_OPTION_LIST = '[Attribute] Generate Option List'; export const GENERATE_OPTION_LIST = '[Attribute] Generate Option List';
export const GENERATE_OPTION_LIST_SUCCESS = '[Attribute] Generate Option List Success'; export const GENERATE_OPTION_LIST_SUCCESS = '[Attribute] Generate Option List Success';
export const GENERATE_OPTION_LIST_FAIL = '[Attribute] Generate Option List Fail'; export const GENERATE_OPTION_LIST_FAIL = '[Attribute] Generate Option List Fail';
...@@ -30,6 +36,24 @@ export class LoadAttributeListFailAction implements Action { ...@@ -30,6 +36,24 @@ export class LoadAttributeListFailAction implements Action {
constructor(public payload: {} = null) { } constructor(public payload: {} = null) { }
} }
export class AddNewAttributeAction implements Action {
type = ADD_NEW_ATTRIBUTE;
constructor(public payload: Attribute) { }
}
export class AddNewAttributeSuccessAction implements Action {
type = ADD_NEW_ATTRIBUTE_SUCCESS;
constructor(public payload: Attribute) { }
}
export class AddNewAttributeFailAction implements Action {
type = ADD_NEW_ATTRIBUTE_FAIL;
constructor(public payload: {} = null) { }
}
export class EditAttributeAction implements Action { export class EditAttributeAction implements Action {
type = EDIT_ATTRIBUTE; type = EDIT_ATTRIBUTE;
...@@ -48,6 +72,24 @@ export class EditAttributeFailAction implements Action { ...@@ -48,6 +72,24 @@ export class EditAttributeFailAction implements Action {
constructor(public payload: {} = null) { } constructor(public payload: {} = null) { }
} }
export class DeleteAttributeAction implements Action {
type = DELETE_ATTRIBUTE;
constructor(public payload: Attribute) { }
}
export class DeleteAttributeSuccessAction implements Action {
type = DELETE_ATTRIBUTE_SUCCESS;
constructor(public payload: Attribute) { }
}
export class DeleteAttributeFailAction implements Action {
type = DELETE_ATTRIBUTE_FAIL;
constructor(public payload: {} = null) { }
}
export class GenerateOptionListAction implements Action { export class GenerateOptionListAction implements Action {
type = GENERATE_OPTION_LIST; type = GENERATE_OPTION_LIST;
...@@ -70,9 +112,15 @@ export type Actions ...@@ -70,9 +112,15 @@ export type Actions
= LoadAttributeListAction = LoadAttributeListAction
| LoadAttributeListSuccessAction | LoadAttributeListSuccessAction
| LoadAttributeListFailAction | LoadAttributeListFailAction
| AddNewAttributeAction
| AddNewAttributeSuccessAction
| AddNewAttributeFailAction
| EditAttributeAction | EditAttributeAction
| EditAttributeSuccessAction | EditAttributeSuccessAction
| EditAttributeFailAction | EditAttributeFailAction
| DeleteAttributeAction
| DeleteAttributeSuccessAction
| DeleteAttributeFailAction
| GenerateOptionListAction | GenerateOptionListAction
| GenerateOptionListSuccessAction | GenerateOptionListSuccessAction
| GenerateOptionListFailAction; | GenerateOptionListFailAction;
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { Database } from '../model'; import { Database, Column } from '../model';
export const LOAD_DATABASE_LIST = '[Database] Load Database List'; export const LOAD_DATABASE_LIST = '[Database] Load Database List';
export const LOAD_DATABASE_LIST_WIP = '[Database] Load Database List WIP'; export const LOAD_DATABASE_LIST_WIP = '[Database] Load Database List WIP';
export const LOAD_DATABASE_LIST_SUCCESS = '[Database] Load Database List Success'; export const LOAD_DATABASE_LIST_SUCCESS = '[Database] Load Database List Success';
export const LOAD_DATABASE_LIST_FAIL = '[Database] Load Database List Fail'; export const LOAD_DATABASE_LIST_FAIL = '[Database] Load Database List Fail';
export const LOAD_TABLE_LIST = 'Load Table List'; export const LOAD_TABLE_LIST = '[Database] Load Table List';
export const LOAD_TABLE_LIST_SUCCESS = 'Load Table List Success'; export const LOAD_TABLE_LIST_SUCCESS = '[Database] Load Table List Success';
export const LOAD_TABLE_LIST_FAIL = 'Load Table List Fail'; export const LOAD_TABLE_LIST_FAIL = '[Database] Load Table List Fail';
export const LOAD_COLUMN_LIST = '[Database] Load Column List';
export const LOAD_COLUMN_LIST_SUCCESS = '[Database] Load Column List Success';
export const LOAD_COLUMN_LIST_FAIL = '[Database] Load Column List Fail';
export const ADD_NEW_DATABASE = '[Database] Add New Database'; export const ADD_NEW_DATABASE = '[Database] Add New Database';
export const ADD_NEW_DATABASE_SUCCESS = '[Database] Add New Database Success'; export const ADD_NEW_DATABASE_SUCCESS = '[Database] Add New Database Success';
export const ADD_NEW_DATABASE_FAIL = '[Database] Add New Database Fail'; export const ADD_NEW_DATABASE_FAIL = '[Database] Add New Database Fail';
...@@ -61,6 +64,24 @@ export class LoadTableListFailAction implements Action { ...@@ -61,6 +64,24 @@ export class LoadTableListFailAction implements Action {
constructor(public payload: {} = null) { } constructor(public payload: {} = null) { }
} }
export class LoadColumnListAction implements Action {
type = LOAD_COLUMN_LIST;
constructor(public payload: {} = null) { }
}
export class LoadColumnListSuccessAction implements Action {
type = LOAD_COLUMN_LIST_SUCCESS;
constructor(public payload: Column[]) { }
}
export class LoadColumnListFailAction implements Action {
type = LOAD_COLUMN_LIST_FAIL;
constructor(public payload: {} = null) { }
}
export class AddNewDatabaseAction implements Action { export class AddNewDatabaseAction implements Action {
type = ADD_NEW_DATABASE; type = ADD_NEW_DATABASE;
...@@ -123,6 +144,9 @@ export type Actions ...@@ -123,6 +144,9 @@ export type Actions
| LoadTableListAction | LoadTableListAction
| LoadTableListSuccessAction | LoadTableListSuccessAction
| LoadTableListFailAction | LoadTableListFailAction
| LoadColumnListAction
| LoadColumnListSuccessAction
| LoadColumnListFailAction
| AddNewDatabaseAction | AddNewDatabaseAction
| AddNewDatabaseSuccessAction | AddNewDatabaseSuccessAction
| AddNewDatabaseFailAction | AddNewDatabaseFailAction
......
...@@ -61,6 +61,34 @@ export class AttributeEffects { ...@@ -61,6 +61,34 @@ export class AttributeEffects {
map(_ => this.toastr.error('Loading Failed!', 'Generate option list failed')) map(_ => this.toastr.error('Loading Failed!', 'Generate option list failed'))
); );
@Effect()
addNewAttributeAction$ = this.actions$.pipe(
ofType(attributeActions.ADD_NEW_ATTRIBUTE),
withLatestFrom(this.store$),
switchMap(([action, state]) => {
const datasetName = state.router.state.params.dname;
const addNewAttributeAction = action as attributeActions.AddNewAttributeAction;
return this.attributeService.addAttribute(datasetName, addNewAttributeAction.payload).pipe(
map((attribute: Attribute) => new attributeActions.AddNewAttributeSuccessAction(attribute)),
catchError(() => of(new attributeActions.AddNewAttributeFailAction()))
)
})
);
@Effect({dispatch: false})
addNewAttributeSuccessAction$ = this.actions$.pipe(
ofType(attributeActions.ADD_NEW_ATTRIBUTE_SUCCESS),
map(action => {
this.toastr.success('Add attribute success!', 'The new attribute has been created!');
})
);
@Effect({dispatch: false})
addNewAttributeFailedAction$ = this.actions$.pipe(
ofType(attributeActions.ADD_NEW_ATTRIBUTE_FAIL),
map(_ => this.toastr.error('Add attribute failed!', 'The new attribute could not be created into the database'))
);
@Effect() @Effect()
editAttributeAction$ = this.actions$.pipe( editAttributeAction$ = this.actions$.pipe(
ofType(attributeActions.EDIT_ATTRIBUTE), ofType(attributeActions.EDIT_ATTRIBUTE),
...@@ -88,4 +116,32 @@ export class AttributeEffects { ...@@ -88,4 +116,32 @@ export class AttributeEffects {
ofType(attributeActions.EDIT_ATTRIBUTE_FAIL), ofType(attributeActions.EDIT_ATTRIBUTE_FAIL),
map(_ => this.toastr.error('Edit attribute failed!', 'The existing entities could not be edited into the database')) map(_ => this.toastr.error('Edit attribute failed!', 'The existing entities could not be edited into the database'))
); );
@Effect()
deleteAttributeAction$ = this.actions$.pipe(
ofType(attributeActions.DELETE_ATTRIBUTE),
withLatestFrom(this.store$),
switchMap(([action, state]) => {
const datasetName = state.router.state.params.dname;
const deleteAttributeAction = action as attributeActions.DeleteAttributeAction;
return this.attributeService.deleteAttribute(datasetName, deleteAttributeAction.payload).pipe(
map(_ => new attributeActions.DeleteAttributeSuccessAction(deleteAttributeAction.payload)),
catchError(() => of(new attributeActions.DeleteAttributeFailAction()))
)
})
);
@Effect({dispatch: false})
deleteDatabaseSuccessAction$ = this.actions$.pipe(
ofType(attributeActions.DELETE_ATTRIBUTE_SUCCESS),
map(_ => {
this.toastr.success('Delete attribute success!', 'The attribute has been deleted!');
})
);
@Effect({dispatch: false})
deleteAttributeFailedAction$ = this.actions$.pipe(
ofType(attributeActions.DELETE_ATTRIBUTE_FAIL),
map(_ => this.toastr.error('Delete attribute failed!', 'The attribute could not be deleted into the database'))
);
} }
...@@ -8,7 +8,8 @@ import { of } from 'rxjs'; ...@@ -8,7 +8,8 @@ import { of } from 'rxjs';
import { withLatestFrom, switchMap, map, catchError, tap } from 'rxjs/operators'; import { withLatestFrom, switchMap, map, catchError, tap } from 'rxjs/operators';
import * as fromMetamodel from '../reducer'; import * as fromMetamodel from '../reducer';
import { Database } from '../model'; import * as fromRouter from '../../../shared/utils';
import { Database, Column } from '../model';
import * as databaseActions from '../action/database.action'; import * as databaseActions from '../action/database.action';
import { DatabaseService } from '../service/database.service'; import { DatabaseService } from '../service/database.service';
...@@ -16,7 +17,7 @@ import { DatabaseService } from '../service/database.service'; ...@@ -16,7 +17,7 @@ import { DatabaseService } from '../service/database.service';
export class DatabaseEffects { export class DatabaseEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private store$: Store<{metamodel: fromMetamodel.State}>, private store$: Store<{router: fromRouter.RouterReducerState, metamodel: fromMetamodel.State}>,
private databaseService: DatabaseService, private databaseService: DatabaseService,
private router: Router, private router: Router,
private toastr: ToastrService private toastr: ToastrService
...@@ -70,6 +71,25 @@ export class DatabaseEffects { ...@@ -70,6 +71,25 @@ export class DatabaseEffects {
map(_ => this.toastr.error('Loading Failed!', 'Table list loading failed')) map(_ => this.toastr.error('Loading Failed!', 'Table list loading failed'))
); );
@Effect()
loadColumnListAction$ = this.actions$.pipe(
ofType(databaseActions.LOAD_COLUMN_LIST),
withLatestFrom(this.store$),
switchMap(([action, state]) => {
const datasetName = state.router.state.params.dname;
return this.databaseService.retrieveColumns(datasetName).pipe(
map((columnList: Column[]) => new databaseActions.LoadColumnListSuccessAction(columnList)),
catchError(() => of(new databaseActions.LoadColumnListFailAction()))
)
})
);
@Effect()
loadColumnListFailAction$ = this.actions$.pipe(
ofType(databaseActions.LOAD_COLUMN_LIST_FAIL),
map(_ => this.toastr.error('Loading Failed!', 'Column list loading failed'))
);
@Effect() @Effect()
addNewDatabaseAction$ = this.actions$.pipe( addNewDatabaseAction$ = this.actions$.pipe(
ofType(databaseActions.ADD_NEW_DATABASE), ofType(databaseActions.ADD_NEW_DATABASE),
......
...@@ -62,8 +62,9 @@ export class DatasetEffects { ...@@ -62,8 +62,9 @@ export class DatasetEffects {
ofType(datasetActions.ADD_NEW_DATASET_SUCCESS), ofType(datasetActions.ADD_NEW_DATASET_SUCCESS),
withLatestFrom(this.store$), withLatestFrom(this.store$),
map(([action, state]) => { map(([action, state]) => {
const addNewDatasetSuccessAction = action as datasetActions.AddNewDatasetSuccessAction;
const instanceName = state.router.state.params.iname; const instanceName = state.router.state.params.iname;
this.router.navigate(['/configure-instance/' + instanceName]); this.router.navigate(['/configure-instance/' + instanceName + '/manage-attribute/' + addNewDatasetSuccessAction.payload.name]);
this.toastr.success('Add dataset success!', 'The new dataset has been created!'); this.toastr.success('Add dataset success!', 'The new dataset has been created!');
}) })
); );
......
...@@ -4,35 +4,34 @@ import { RendererConfig } from './renderer/renderer-config.model'; ...@@ -4,35 +4,34 @@ import { RendererConfig } from './renderer/renderer-config.model';
export interface Attribute { export interface Attribute {
id: number; id: number;
name: string; name: string;
table_name: string;
label: string; label: string;
form_label: string; form_label: string;