Skip to content
Snippets Groups Projects
Commit ba84d775 authored by Grand Francois's avatar Grand Francois
Browse files

Merge branch '476-url-de-routeur-loadsession-pour-charger-un-exemple' into 'devel'

Resolve "URL de routeur "/loadsession" pour charger un exemple"

Closes #476

See merge request !159
parents f39a673b 67aad088
No related branches found
No related tags found
1 merge request!159Resolve "URL de routeur "/loadsession" pour charger un exemple"
Pipeline #139819 canceled
Showing with 308 additions and 5 deletions
......@@ -645,7 +645,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
});
}
public async loadSessionFile(f: File, info?: any) {
public async loadSessionFile(f: File|string, info?: any) {
// notes merge detection: was there already some notes ?
const existingNotes = Session.getInstance().documentation;
// load
......
......@@ -117,6 +117,9 @@ import {
JalhydModelValidationStepDirective
} from "./directives/jalhyd-model-validation.directive";
import { ImmediateErrorStateMatcher } from "./formulaire/immediate-error-state-matcher";
import { LoadSessionURLComponent } from "./components/load-session-url/load-session-url.component";
import { DialogShowMessageComponent } from "./components/dialog-show-message/dialog-show-message.component";
import { DialogConfirmLoadSessionURLComponent } from "./components/dialog-confirm-load-session-url/dialog-confirm-load-session-url.component";
const appRoutes: Routes = [
{ path: "list/search", component: CalculatorListComponent },
......@@ -125,6 +128,7 @@ const appRoutes: Routes = [
{ path: "setup", component: ApplicationSetupComponent },
{ path: "diagram", component: ModulesDiagramComponent },
{ path: "properties", component: SessionPropertiesComponent },
{ path: "loadsession/:path", component: LoadSessionURLComponent },
{ path: "**", redirectTo: "list", pathMatch: "full" }
];
......@@ -201,6 +205,8 @@ const appRoutes: Routes = [
DialogSaveSessionComponent,
DialogNewPbCloisonComponent,
DialogLoadPredefinedEspeceComponent,
DialogShowMessageComponent,
DialogConfirmLoadSessionURLComponent,
FieldSetComponent,
FieldsetContainerComponent,
FixedResultsComponent,
......@@ -217,6 +223,7 @@ const appRoutes: Routes = [
JalhydModelValidationStepDirective,
JetResultsComponent,
JetTrajectoryChartComponent,
LoadSessionURLComponent,
LogComponent,
LogDrawerComponent,
LogEntryComponent,
......@@ -247,7 +254,7 @@ const appRoutes: Routes = [
VarResultsComponent,
VerificateurResultsComponent
],
providers: [
providers: [ // services
ApplicationSetupService,
CustomBreakPointsProvider,
FormulaireService,
......
<h1 mat-dialog-title [innerHTML]="uitextTitle"></h1>
<div>
<mat-checkbox [(ngModel)]="emptyCurrentSession">
{{ uitextEmptyCurrentSession }}
</mat-checkbox>
<div mat-dialog-actions [attr.align]="'end'">
<button mat-raised-button color="primary" [mat-dialog-close]="false" cdkFocusInitial>
{{ uitextCancel }}
</button>
<button mat-raised-button type="submit" color="warn" (click)="loadSession()">
{{ uitextLoad }}
</button>
</div>
</div>
\ No newline at end of file
import { Component, Inject } from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
@Component({
selector: "dialog-confirm-load-session-url",
templateUrl: "dialog-confirm-load-session-url.component.html",
})
export class DialogConfirmLoadSessionURLComponent {
public emptyCurrentSession: boolean = false;
constructor(
public dialogRef: MatDialogRef<DialogConfirmLoadSessionURLComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {
}
public loadSession() {
this.dialogRef.close({
emptySession: this.emptyCurrentSession
});
}
public get uitextTitle() {
return "Please confirm loading";
}
public get uitextEmptyCurrentSession() {
return "Empty current session";
}
public get uitextCancel() {
return "Cancel";
}
public get uitextLoad() {
return "Load";
}
}
<h1 mat-dialog-title [innerHTML]="uitextTitle"></h1>
<div mat-dialog-content>
{{ uitextMessage }}
</div>
<div mat-dialog-actions [attr.align]="'end'">
<button mat-raised-button color="warn" [mat-dialog-close]="true">
{{ uitextClose }}
</button>
</div>
\ No newline at end of file
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
import { Inject, Component } from "@angular/core";
@Component({
selector: "dialog-show-message",
templateUrl: "dialog-show-message.component.html",
styleUrls: ["dialog-show-message.component.scss"]
})
export class DialogShowMessageComponent {
private title: string;
private message: string;
constructor(
public dialogRef: MatDialogRef<DialogShowMessageComponent>,
@Inject(MAT_DIALOG_DATA) data: any
) {
this.title = data.title;
this.message = data.message;
}
public get uitextTitle() {
return this.title;
}
public get uitextMessage() {
return this.message;
}
public get uitextClose() {
return "Close";
}
}
import { Location } from "@angular/common";
import { Component, forwardRef, Inject } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { ActivatedRoute } from "@angular/router";
import { AppComponent } from "app/app.component";
import { FormulaireService } from "app/services/formulaire.service";
import { HttpService } from "app/services/http.service";
import { DialogConfirmLoadSessionURLComponent } from "../dialog-confirm-load-session-url/dialog-confirm-load-session-url.component";
import { DialogShowMessageComponent } from "../dialog-show-message/dialog-show-message.component";
// load a session file by its URL (either local or remote)
@Component({
selector: "load-session-url",
template: ""
})
export class LoadSessionURLComponent {
constructor(
@Inject(forwardRef(() => AppComponent)) private appComponent: AppComponent,
private dialog: MatDialog,
private route: ActivatedRoute,
private httpService: HttpService,
private location: Location,
private formulaireService: FormulaireService
) {
}
ngOnInit() {
// check open calculators
if (this.formulaireService.formulaires.length > 0) {
this.confirmLoadSession().then(emptySession => {
if (emptySession === undefined) {
// cancel has been clicked, go to previous route
this.location.back();
}
else {
if (emptySession) {
this.appComponent.doEmptySession();
}
this.loadSession();
}
});
}
else {
this.loadSession();
}
}
private loadSession() {
// get "path" argument from URL
const path = this.route.snapshot.params.path;
if (path.startsWith("http")) {
// general URL path
// example URLs:
// http://localhost:4200/#/loadsession/https%3A%2F%2Fhydraulique.g-eau.fr%2Fcassiopee%2Fdevel%2Fapp%2Fexamples%2Fpab-complete-chain.json
// http://localhost/dist/#/loadsession/https%3A%2F%2Fhydraulique.g-eau.fr%2Fcassiopee%2Fdevel%2Fapp%2Fexamples%2Fpab-complete-chain.json
// turned by loadRemoteSession() to
// http://localhost/gofetch.php?url=https%3A%2F%2Fhydraulique.g-eau.fr%2Fcassiopee%2Fdevel%2Fapp%2F%2Fexamples%2Fpab-complete-chain.json
this.loadRemoteSession(path);
}
else {
// local path
// input URL example : http://localhost:4200/#/loadsession/app%2Fexamples%2Fpab-complete-chain.json
// extracted path : app/examples/pab-complete-chain.json
this.loadLocalSession(path);
}
}
private async loadRemoteSession(path: string) {
try {
const url = "assets/scripts/gofetch.php?url=" + encodeURIComponent(path);
this.httpService.httpGetRequestPromise(url).then(resp => {
const s = JSON.stringify(resp);
this.appComponent.loadSessionFile(s);
});
} catch (e) {
// display error dialog
await this.openErrorDialog(path);
// go to previous route
this.location.back();
}
}
/**
* load a locally stored session file
* @param path local path in the form eg. app/examples/pab-complete-chain.json
*/
private async loadLocalSession(path: string) {
try {
const d = await this.httpService.httpGetBlobRequestPromise(path);
const f: any = new Blob([d], { type: "application/json" });
this.appComponent.loadSessionFile(f);
} catch (e) {
// display error dialog
await this.openErrorDialog(path);
// go to previous route
this.location.back();
}
}
private async openErrorDialog(path: string) {
const dialogRef = this.dialog.open(
DialogShowMessageComponent,
{
data: {
title: "Error!",
message: "Session " + path + " does not exist."
},
disableClose: true
}
);
// wait for dialog to be closed
await dialogRef.afterClosed().toPromise();
}
private confirmLoadSession(): Promise<boolean> {
const dialogRef = this.dialog.open(
DialogConfirmLoadSessionURLComponent,
{
data: {
},
disableClose: true
}
);
return dialogRef.afterClosed().toPromise().then(result => {
return result.emptySession;
});
}
}
......@@ -628,13 +628,18 @@ export class FormulaireService extends Observable {
* @param f fichier session
* @param formInfos infos sur les modules de calcul @see DialogLoadSessionComponent.calculators
*/
public async loadSession(f: File, formInfos: any[] = []): Promise<{ hasErrors: boolean, loaded: string[] }> {
public async loadSession(i: Blob | string, formInfos: any[] = []): Promise<{ hasErrors: boolean, loaded: string[] }> {
try {
// disable "empty fields" flag temporarly
const emptyFields = ServiceFactory.applicationSetupService.enableEmptyFieldsOnFormInit;
ServiceFactory.applicationSetupService.enableEmptyFieldsOnFormInit = false;
const s = await this.readSingleFile(f);
let s;
if (i instanceof Blob) {
s = await this.readSingleFile(i as File);
} else {
s = i;
}
const uids: string[] = [];
formInfos.forEach((fi) => {
if (fi.selected) {
......@@ -827,7 +832,7 @@ export class FormulaireService extends Observable {
) {
const dependingNubs = Session.getInstance().getDependingNubs(f.currentNub.uid, symbol, forceResetAllDependencies, true);
for (const dn of dependingNubs) {
if (! visited.includes(dn.uid)) {
if (!visited.includes(dn.uid)) {
const form = this.getFormulaireFromNubId(dn.uid);
if (form) {
const hadResults = form.hasResults;
......
<?php
function do_log($msg) {
// echo($msg."\n");
}
do_log("start");
// http://localhost/gofetch.php?url=http%3A%2F%2Flocalhost%3A4200%2Fapp%2F%2Fexamples%2Fperr.json
// http://localhost/gofetch.php?url=https%3A%2F%2Fhydraulique.g-eau.fr%2Fcassiopee%2Fdevel%2Fapp%2F%2Fexamples%2Fperr.json
// fonction str_ends_with si PHP < 8
if ( ! function_exists( 'str_ends_with' ) ) {
function str_ends_with( $haystack, $needle ) {
if ( '' === $haystack && '' !== $needle ) {
return false;
}
$len = strlen( $needle );
return 0 === substr_compare( $haystack, $needle, -$len, $len );
}
}
do_log("get url");
$url = $_GET['url'];
do_log("url=" . $url);
$url=urldecode($url);
do_log("decode url=" . $url);
if( str_ends_with( strtolower( $url ), '.json' ) ) {
do_log("curl init");
// Initialise une session CURL.
$ch = curl_init();
do_log("setopt 1");
// Récupère le contenu de la page
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
do_log("setopt 2");
// Configure l'URL
curl_setopt($ch, CURLOPT_URL, $url);
// Désactive la vérification du certificat si l'URL utilise HTTPS
if (strpos($url,'https')===0) {
do_log("setopt 3");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}
do_log("curl exec");
// Exécute la requête
$result = curl_exec($ch);
// Affiche le résultat
echo $result;
}
?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment