diff --git a/.gitignore b/.gitignore index f9db6fa19727f326db8c70b4dad8791827b60999..371089b341039668cbe0bcb651773ce321703d53 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # See http://help.github.com/ignore-files/ for more about ignoring files. +# config +/src/app/config.json + # compiled output /dist /tmp diff --git a/src/app/app.component.html b/src/app/app.component.html index 8a1b870615f7333a902854337b434d895d530801..2df5abc73ff0aaf5faf27a31081c0f93bb6aa693 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -103,13 +103,7 @@ </mat-sidenav> <mat-sidenav-content class="sidenav-content" fxFlexFill> - <div class="container-fluid"> - <div class="row"> - <div class="col-12"> - <router-outlet (activate)="onRouterOutletActivated($event)"></router-outlet> - </div> - </div> - </div> + <router-outlet (activate)="onRouterOutletActivated($event)"></router-outlet> </mat-sidenav-content> </mat-sidenav-container> diff --git a/src/app/components/calculator-list/calculator-list.component.css b/src/app/components/calculator-list/calculator-list.component.css deleted file mode 100644 index 107f363974953c98e69a1bfc896224fb9b87e84a..0000000000000000000000000000000000000000 --- a/src/app/components/calculator-list/calculator-list.component.css +++ /dev/null @@ -1,16 +0,0 @@ -.full-page { - width: 100%; - height: 100%; - min-height: 100%; - background: red; - display: block; -} - -.full-height { - min-height: 100%; - height: 100%; -} - -button:focus { - outline: 0; -} diff --git a/src/app/components/calculator-list/calculator-list.component.html b/src/app/components/calculator-list/calculator-list.component.html index 7f8497ad9e951393574bbfd5ca62125eb75b7bef..e8b083588ce1145dfe2ffc0e37f736a02a5908ac 100644 --- a/src/app/components/calculator-list/calculator-list.component.html +++ b/src/app/components/calculator-list/calculator-list.component.html @@ -1,10 +1,26 @@ -<div class="container-fluid"> - <div class="row"> - <div class="offset-1 col-10 mx-auto"> - <ul *ngFor="let l of items" class="list-group"> - <!-- on utilise [innerHTML] pour que les codes HTML comme soient interprétés correctement --> - <button class="list-group-item" (click)="create(l.type)" [innerHTML]="l.label"></button> - </ul> - </div> - </div> -</div> \ No newline at end of file +<div class="container" fxLayout="row wrap" fxLayoutAlign="space-evenly stretch"> + + <mat-card *ngFor="let theme of items" class="compute-nodes-theme"> + + <mat-card-header> + <!-- <img mat-card-avatar src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-12/256/water-wave.png"> --> + <mat-card-title>{{ theme.title }}</mat-card-title> + <mat-card-subtitle>{{ theme.description }}</mat-card-subtitle> + </mat-card-header> + + <!-- <img mat-card-image src="http://maurice.rolland.pagesperso-orange.fr/barduser01.jpg"> --> + + <!-- <mat-card-content> + <p>{{ theme.description }}</p> + </mat-card-content> --> + + <mat-card-actions> + <div class="container" fxLayout="column" fxLayoutAlign="left" fxLayoutGap="10px"> + <button mat-raised-button color="accent" *ngFor="let calc of theme.calculators" class="theme-calculator" + (click)="create(calc.type)" [innerHTML]="calc.label"></button> + </div> + </mat-card-actions> + + </mat-card> + +</div> diff --git a/src/app/components/calculator-list/calculator-list.component.scss b/src/app/components/calculator-list/calculator-list.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..0d8f2afd2ead503f78ebf9c0af85287f0c166dc2 --- /dev/null +++ b/src/app/components/calculator-list/calculator-list.component.scss @@ -0,0 +1,13 @@ +mat-card.compute-nodes-theme { + width: 300px; + margin: 1em; + + button.theme-calculator { + margin-left: 0; + margin-right: 0; + } + + .mat-card-actions:last-child { + margin-bottom: 0; // instead of -8px + } +} diff --git a/src/app/components/calculator-list/calculator-list.component.ts b/src/app/components/calculator-list/calculator-list.component.ts index 910568f99c394980c70bc56bcafc3ebfb981664c..2af92fe5f19110d66eb6e3334be391d0722e34cf 100644 --- a/src/app/components/calculator-list/calculator-list.component.ts +++ b/src/app/components/calculator-list/calculator-list.component.ts @@ -5,40 +5,74 @@ import { CalculatorType, EnumEx } from "jalhyd"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; import { ServiceFactory } from "../../services/service-factory"; -import { InternationalisationService } from "../../services/internationalisation/internationalisation.service"; +import { I18nService } from "../../services/internationalisation/internationalisation.service"; import { FormulaireParallelStructure } from "../../formulaire/definition/concrete/form-parallel-structures"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; -class ListElement { - private _label: string; - - constructor(private _type: CalculatorType) { - this._label = ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(_type); - } - - public get label() { return this._label; } - public get type() { return this._type; } -} @Component({ selector: "list", templateUrl: "./calculator-list.component.html", - styleUrls: ["./calculator-list.component.css"] + styleUrls: ["./calculator-list.component.scss"] }) export class CalculatorListComponent implements OnInit { - private _items: ListElement[]; + private _items: any[]; constructor(private router: Router) { - ServiceFactory.instance.internationalisationService.addObserver(this); + ServiceFactory.instance.i18nService.addObserver(this); + ServiceFactory.instance.applicationSetupService.addObserver(this); } - private updateLocale() { + /** triggered on init */ + private loadCalculatorsThemes() { this._items = []; - for (const t of EnumEx.getValues(CalculatorType)) { - if (t !== CalculatorType.Structure) { - this._items.push(new ListElement(t)); + const unusedCalculators = EnumEx.getValues(CalculatorType); + const themes = ServiceFactory.instance.applicationSetupService.themes; + if (themes) { + // group by themes + for (const theme of themes) { + // get theme details from config + const themeTitleKey = "INFO_THEME_" + theme.name + "_TITRE"; + const themeDescriptionKey = "INFO_THEME_" + theme.name + "_DESCRIPTION"; + const item = { + title: ServiceFactory.instance.i18nService.localizeText(themeTitleKey), + description: ServiceFactory.instance.i18nService.localizeText(themeDescriptionKey), + calculators: [] + }; + // get calculators for this theme + for (const calcType of theme.calculators) { + item.calculators.push({ + type: calcType, + label: ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(calcType) + }); + // mark as used + const index = unusedCalculators.indexOf(calcType); + if (index > -1) { + unusedCalculators.splice(index, 1); + } + } + this._items.push(item); } } + // extra card for unused calculators + if (unusedCalculators.length > 0) { + const unusedTheme = { + title: "Pas utilisées", + description: "Tout ce qu'est pas dans les autres thèmes", + calculators: [] + }; + for (const t of unusedCalculators) { + if (t !== CalculatorType.Structure) { + unusedTheme.calculators.push({ + type: t, + label: ServiceFactory.instance.formulaireService.getLocalisedTitleFromCalculatorType(t) + }); + } + } + if (unusedTheme.calculators.length > 0) { + this._items.push(unusedTheme); + } // else the only remaining calculator was "Structure", the one we don't want + } } private create(t: CalculatorType) { @@ -66,14 +100,12 @@ export class CalculatorListComponent implements OnInit { // interface Observer update(sender: any, data: any): void { - if (sender instanceof InternationalisationService) { - this.updateLocale(); + if (sender instanceof I18nService) { + this.loadCalculatorsThemes(); } } - // OnInit - ngOnInit() { - this.updateLocale(); + this.loadCalculatorsThemes(); } } diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 1fad871b858d0514cc51d4b4e5ab500cf4d30cfb..90a9ecefab9af83f5d3e3e8df60c4ff43174ebe3 100644 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -125,6 +125,16 @@ "INFO_SETUP_PRECISION_AFFICHAGE": "Display accuracy", "INFO_SETUP_PRECISION_CALCUL": "Computation accuracy", "INFO_SETUP_TITLE": "Application setup", + "INFO_THEME_PASSE_A_BASSIN_TITRE": "Basin pass", + "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "A great pass with a great basin", + "INFO_THEME_PASSE_NATURELLE_TITRE": "Natural pass", + "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "A great and very natural pass", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_TITRE": "Hydraulics on free surface", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_DESCRIPTION": "Hydraulics on free surface is great!", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_TITRE": "Hydraulics on charge", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_DESCRIPTION": "Hydraulics on charge is great!", + "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Parallel structures", + "INFO_THEME_LOIS_D_OUVRAGES_DESCRIPTION": "Parallel structures are great!", "WARNING_REMOUS_ARRET_CRITIQUE": "Calculation stopped: critical elevation reached at abscissa %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p must not be greater than 2.5. h/p is forced to 2.5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "Threshold height should be greater than 0.1 m. Beta coefficient is forced to 0" diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index 0772944e520fd37849da255b7e8dddac74f829f9..3190c9fa762b9c6ddbbe224ecefd8d8419ebcf93 100644 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -140,6 +140,16 @@ "INFO_SETUP_PRECISION_AFFICHAGE": "Précision d'affichage", "INFO_SETUP_PRECISION_CALCUL": "Précision de calcul", "INFO_SETUP_TITLE": "Paramètres de l'application", + "INFO_THEME_PASSE_A_BASSIN_TITRE": "Passe à bassin", + "INFO_THEME_PASSE_A_BASSIN_DESCRIPTION": "Une super passe avec un super bassin", + "INFO_THEME_PASSE_NATURELLE_TITRE": "Passe naturelle", + "INFO_THEME_PASSE_NATURELLE_DESCRIPTION": "Une super passe super naturelle", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_TITRE": "Hydraulique à surface libre", + "INFO_THEME_HYDRAULIQUE_A_SURFACE_LIBRE_DESCRIPTION": "L'hydraulique à surface libre c'est super !", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_TITRE": "Hydraulique en charge", + "INFO_THEME_HYDRAULIQUE_EN_CHARGE_DESCRIPTION": "L'hydraulique en charge c'est super !", + "INFO_THEME_LOIS_D_OUVRAGES_TITRE": "Lois d'ouvrages", + "INFO_THEME_LOIS_D_OUVRAGES_DESCRIPTION": "Les lois d'ouvrages c'est super !", "WARNING_REMOUS_ARRET_CRITIQUE": "Arrêt du calcul : hauteur critique atteinte à l'abscisse %x%", "WARNING_STRUCTUREKIVI_HP_TROP_ELEVE": "h/p ne doit pas être supérieur à 2,5. h/p est forcé à 2,5", "WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE": "La pelle du seuil doit mesurer au moins 0,1 m. Le coefficient béta est forcé à 0"