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

Merge branch 'merge-conflicts' into 'develop'

Conflicts resolved

See merge request !53
parents 14d37123 03f74a76
Pipeline #1510 passed with stages
in 10 minutes and 26 seconds
......@@ -6,6 +6,7 @@ export interface Dataset {
display: number;
count: number;
vo: boolean;
selectable_row: boolean;
project_name: string;
id_dataset_family: number;
}
......@@ -14,7 +14,7 @@
<div *ngIf="isSelected(attribute.id)">
<button class="btn btn-block text-left py-1 m-0 rounded-0"
(click)="toggleSelection(attribute.id)">
<i class="fas fa-fw fa-check-square anis-color"></i> {{ attribute.form_label }}
<i class="fas fa-fw fa-check-square theme-color"></i> {{ attribute.form_label }}
</button>
</div>
<div *ngIf="!isSelected(attribute.id)">
......
.data-selected {
cursor: pointer;
}
.data-selected button:focus {
box-shadow: none;
}
\ No newline at end of file
......@@ -13,24 +13,31 @@
<span class="sr-only">Loading...</span>
</div>
<div *ngIf="searchMeta">
<div class="mb-2">
<button [disabled]="noSelectedData()" class="btn btn-sm btn-outline-primary">Action</button>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th></th>
<th *ngIf="getDataset().selectable_row"></th>
<th *ngFor="let attribute of searchMeta.attributes_selected" scope="col">
{{ attribute.label }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let datum of searchData">
<td>
<button class="btn btn-block text-left py-0 m-0"
(click)="toggleSelection(datum.id)">
<div *ngIf="isSelected(datum.id); then selected else unselected"></div>
<td *ngIf="getDataset().selectable_row" class="data-selected" (click)="toggleSelection(datum)">
<button class="btn btn-block text-left p-0 m-0">
<div *ngIf="!isSelected(datum)">
<i class="far fa-square fa-lg text-secondary"></i>
</div>
<div *ngIf="isSelected(datum)">
<i class="fas fa-check-square fa-lg theme-color"></i>
</div>
</button>
</td>
<td *ngFor="let attribute of searchMeta.attributes_selected">
<td *ngFor="let attribute of searchMeta.attributes_selected" class="align-middle">
<div *ngIf="datum[attribute.label]" [ngSwitch]="getAttributeRenderer(attribute.name)">
<div *ngSwitchCase="'img'">
<app-img [src]="getAttributeUriAction(attribute.name, datum[attribute.label])">
......@@ -85,16 +92,4 @@
</div>
</div>
</accordion-group>
</accordion>
<ng-template #selected>
<span class="fa-stack fa-1x">
<i class="far fa-square fa-stack-1x text-secondary"></i>
<i class="fas fa-check fa-stack-1x theme-color"></i>
</span>
</ng-template>
<ng-template #unselected>
<span class="fa-stack fa-1x">
<i class="far fa-square fa-stack-1x text-secondary"></i>
</span>
</ng-template>
\ No newline at end of file
</accordion>
\ No newline at end of file
import { Component, Input, ChangeDetectionStrategy, Output, EventEmitter } from '@angular/core';
import { SearchMeta, SearchQueryParams } from '../../store/model';
import { Attribute } from 'src/app/metamodel/model';
import { Attribute, Dataset } from 'src/app/metamodel/model';
@Component({
selector: 'app-datatable',
......@@ -11,20 +11,26 @@ import { Attribute } from 'src/app/metamodel/model';
})
export class DatatableComponent {
@Input() datasetName: string;
@Input() datasetList: Dataset[];
@Input() queryParams: SearchQueryParams;
@Input() datasetAttributeList: Attribute[];
@Input() searchMeta: SearchMeta;
@Input() searchData: any[];
@Input() selectedData: any[];
@Output() initSearchMeta: EventEmitter<{}> = new EventEmitter();
@Output() getSearchData: EventEmitter<number> = new EventEmitter();
public selection: number[] = [];
@Output() addSelectedData: EventEmitter<any> = new EventEmitter();
@Output() deleteSelectedData: EventEmitter<any> = new EventEmitter();
initDatatable() {
this.initSearchMeta.emit();
this.getSearchData.emit(1);
}
getDataset() {
return this.datasetList.find(dataset => dataset.name === this.datasetName);
}
getAttributeId(attributeName: string): number {
const attribute = this.datasetAttributeList.find(a => a.name === attributeName);
return attribute.id;
......@@ -44,19 +50,27 @@ export class DatatableComponent {
}
}
toggleSelection(attributeId: number): void {
const index = this.selection.indexOf(attributeId);
toggleSelection(datum: any): void {
const attribute = this.datasetAttributeList.find(a => a.search_flag === 'ID');
const index = this.selectedData.indexOf(datum[attribute.name]);
if (index > -1) {
this.selection.splice(index, 1);
this.deleteSelectedData.emit(datum[attribute.name]);
} else {
this.selection.push(attributeId);
this.addSelectedData.emit(datum[attribute.name]);
}
}
isSelected(attributeId: number): boolean {
if (this.selection.indexOf(attributeId) > -1) {
isSelected(datum: any): boolean {
const attribute = this.datasetAttributeList.find(a => a.search_flag === 'ID');
if (this.selectedData.indexOf(datum[attribute.name]) > -1) {
return true;
}
return false;
}
noSelectedData() {
return this.selectedData.length < 1;
}
}
......@@ -13,12 +13,16 @@
</app-url-display>
<app-datatable
[datasetName]="datasetName | async"
[datasetList]="datasetList | async"
[queryParams]="queryParams | async"
[datasetAttributeList]="datasetAttributeList | async"
[searchMeta]="searchMeta | async"
[searchData]="searchData | async"
[selectedData]="selectedData | async"
(initSearchMeta)="getSearchMeta()"
(getSearchData)="getSearchData($event)">
(getSearchData)="getSearchData($event)"
(addSelectedData)="addSearchData($event)"
(deleteSelectedData)="deleteSearchData($event)">
</app-datatable>
</div>
<div class="col-12 col-md-4 pt-2">
......
......@@ -38,6 +38,7 @@ export class ResultComponent implements OnInit {
public outputList: Observable<number[]>;
public searchMeta: Observable<SearchMeta>;
public searchData: Observable<any[]>;
public selectedData: Observable<any[]>;
public queryParams: Observable<SearchQueryParams>;
constructor(private store: Store<StoreState>) {
......@@ -53,6 +54,7 @@ export class ResultComponent implements OnInit {
this.outputList = this.store.select(searchSelector.getOutputList);
this.searchMeta = this.store.select(searchSelector.getSearchMeta);
this.searchData = this.store.select(searchSelector.getSearchData);
this.selectedData = this.store.select(searchSelector.getSelectedData);
this.queryParams = this.store.select(searchSelector.getQueryParams);
}
......@@ -72,4 +74,12 @@ export class ResultComponent implements OnInit {
getSearchData(page: number): void {
this.store.dispatch(new searchActions.RetrieveDataAction(page));
}
addSearchData(data: any) {
this.store.dispatch(new searchActions.AddSelectedDataAction(data));
}
deleteSearchData(data: any) {
this.store.dispatch(new searchActions.DeleteSelectedDataAction(data));
}
}
......@@ -19,6 +19,8 @@ export const RETRIEVE_META_FAIL = '[Search] Retrieve Meta Fail';
export const RETRIEVE_DATA = '[Search] Retrieve Data';
export const RETRIEVE_DATA_SUCCESS = '[Search] Retrieve Data Success';
export const RETRIEVE_DATA_FAIL = '[Search] Retrieve Data Fail';
export const ADD_SELECTED_DATA = '[Search] Add Selected Data';
export const DELETE_SELECTED_DATA = '[Search] Delete Selected Data';
export class InitSearchByUrl implements Action {
type = INIT_SEARCH_BY_URL;
......@@ -122,6 +124,18 @@ export class RetrieveDataFailAction implements Action {
constructor(public payload: {} = null) { }
}
export class AddSelectedDataAction implements Action {
type = ADD_SELECTED_DATA;
constructor(public payload: any) { }
}
export class DeleteSelectedDataAction implements Action {
type = DELETE_SELECTED_DATA;
constructor(public payload: any) { }
}
export type Actions
= InitSearchByUrl
| ChangeStepAction
......@@ -139,4 +153,6 @@ export type Actions
| RetrieveMetaFailAction
| RetrieveDataAction
| RetrieveDataSuccessAction
| RetrieveDataFailAction;
| RetrieveDataFailAction
| AddSelectedDataAction
| DeleteSelectedDataAction;
......@@ -65,6 +65,7 @@ export class SearchEffects {
let defaultOutputList = loadAttributeSearchMetaSuccessAction.payload
.filter(attribute => attribute.selected && attribute.id_output_category)
.sort((a, b) => a.output_display - b.output_display)
.map(attribute => attribute.id);
if (state.router.state.queryParams.a) {
......
......@@ -15,6 +15,7 @@ export interface State {
searchMetaIsLoaded: boolean;
searchMeta: SearchMeta;
searchData: any[];
selectedData: any[];
}
const initialState: State = {
......@@ -29,7 +30,8 @@ const initialState: State = {
searchMetaIsLoading: false,
searchMetaIsLoaded: false,
searchMeta: null,
searchData: null
searchData: null,
selectedData: []
};
export function reducer(state: State = initialState, action: actions.Actions): State {
......@@ -139,6 +141,22 @@ export function reducer(state: State = initialState, action: actions.Actions): S
searchData
};
case actions.ADD_SELECTED_DATA:
const addData = action.payload as any;
return {
...state,
selectedData: [...state.selectedData, addData]
}
case actions.DELETE_SELECTED_DATA:
const deleteData = action.payload as any;
return {
...state,
selectedData: [...state.selectedData.filter(d => d !== deleteData)]
}
default:
return state;
}
......@@ -156,3 +174,4 @@ export const getSearchMetaIsLoading = (state: State) => state.searchMetaIsLoadin
export const getSearchMetaIsLoaded = (state: State) => state.searchMetaIsLoaded;
export const getSearchMeta = (state: State) => state.searchMeta;
export const getSearchData = (state: State) => state.searchData;
export const getSelectedData = (state: State) => state.selectedData;
......@@ -65,6 +65,11 @@ export const getSearchData = createSelector(
search.getSearchData
);
export const getSelectedData = createSelector(
getSearchState,
search.getSelectedData
);
export const getQueryParams = createSelector(
getCriteriaList,
getOutputList,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment