@provoly/dashboard 0.12.2 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/esm2022/admin/store/admin.service.mjs +2 -2
  2. package/esm2022/import/components/import.component.mjs +25 -9
  3. package/esm2022/import/i18n/en.translations.mjs +4 -2
  4. package/esm2022/import/i18n/fr.translations.mjs +4 -2
  5. package/esm2022/import/store/import.actions.mjs +1 -1
  6. package/esm2022/import/store/import.effects.mjs +5 -3
  7. package/esm2022/import/store/import.reducer.mjs +1 -1
  8. package/esm2022/import/store/import.selectors.mjs +3 -1
  9. package/esm2022/import/store/import.service.mjs +12 -5
  10. package/esm2022/lib/core/components/upload/upload.component.mjs +2 -2
  11. package/esm2022/lib/dashboard/store/dashboard.effects.mjs +2 -1
  12. package/esm2022/lib/dashboard/store/dashboard.reducers.mjs +9 -5
  13. package/esm2022/toolbox/components/save-view/save-view.component.mjs +3 -3
  14. package/fesm2022/provoly-dashboard-admin.mjs +1 -1
  15. package/fesm2022/provoly-dashboard-admin.mjs.map +1 -1
  16. package/fesm2022/provoly-dashboard-import.mjs +47 -16
  17. package/fesm2022/provoly-dashboard-import.mjs.map +1 -1
  18. package/fesm2022/provoly-dashboard-toolbox.mjs +2 -2
  19. package/fesm2022/provoly-dashboard-toolbox.mjs.map +1 -1
  20. package/fesm2022/provoly-dashboard.mjs +10 -5
  21. package/fesm2022/provoly-dashboard.mjs.map +1 -1
  22. package/import/components/import.component.d.ts +11 -5
  23. package/import/i18n/en.translations.d.ts +3 -1
  24. package/import/i18n/fr.translations.d.ts +2 -0
  25. package/import/store/import.actions.d.ts +4 -2
  26. package/import/store/import.effects.d.ts +1 -1
  27. package/import/store/import.reducer.d.ts +1 -1
  28. package/import/store/import.selectors.d.ts +2 -1
  29. package/import/store/import.service.d.ts +1 -1
  30. package/package.json +25 -25
@@ -47,7 +47,9 @@ const importReducer = createReducer(initialImportState, on(ImportActions.upload,
47
47
  const feature = createFeatureSelector(importFeatureKey);
48
48
  const numberOfLines = createSelector(feature, (state) => state?.numberOfLines);
49
49
  const errors = createSelector(feature, (state) => state?.errors);
50
+ const upload = createSelector(feature, (state) => state.loading);
50
51
  const ImportSelectors = {
52
+ upload,
51
53
  numberOfLines,
52
54
  errors
53
55
  };
@@ -62,21 +64,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
62
64
  }] });
63
65
 
64
66
  class PryImportComponent {
65
- constructor(store, translateService) {
67
+ constructor(store) {
66
68
  this.store = store;
67
- this.translateService = translateService;
69
+ this.selectedFileType = 'csv';
68
70
  this.fileTypes = [
69
71
  {
70
72
  label: 'Csv',
71
73
  value: 'csv'
74
+ },
75
+ {
76
+ label: 'Shapefile',
77
+ value: 'zip'
72
78
  }
73
79
  ];
80
+ this.fileExtension = {
81
+ csv: '.csv',
82
+ zip: '.zip'
83
+ };
74
84
  store.dispatch(DataSourceActions.dataset.loadDataset());
75
85
  this.datasets$ = store
76
86
  .select(DataSourceSelectors.datasets)
77
87
  .pipe(map((datasets) => datasets
78
88
  .filter((dataset) => dataset.type === PryDatasetType.CLOSED)
79
89
  .sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1))));
90
+ this.uploadShapefile$ = store.select(ImportSelectors.upload);
80
91
  this.numberOfLine$ = store.select(ImportSelectors.numberOfLines);
81
92
  this.errors$ = store.select(ImportSelectors.errors);
82
93
  this.errorCount$ = this.errors$.pipe(map((errors) => {
@@ -97,8 +108,8 @@ class PryImportComponent {
97
108
  this.file = $event;
98
109
  }
99
110
  submit() {
100
- if (this.file && this.datasetSelected) {
101
- this.store.dispatch(ImportActions.upload({ file: this.file, dataset: this.datasetSelected }));
111
+ if (this.file && this.datasetSelected && this.selectedFileType) {
112
+ this.store.dispatch(ImportActions.upload({ file: this.file, dataset: this.datasetSelected, fileType: this.selectedFileType }));
102
113
  this.file = undefined;
103
114
  }
104
115
  }
@@ -114,13 +125,20 @@ class PryImportComponent {
114
125
  }
115
126
  return `${size} bytes`;
116
127
  }
117
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryImportComponent, deps: [{ token: i2.Store }, { token: i2$1.PryI18nService }], target: i0.ɵɵFactoryTarget.Component }); }
118
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: PryImportComponent, selector: "pry-import", ngImport: i0, template: "<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"true\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">{{ '@pry.import.uploadTitle' | i18n }}</label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n accept=\".csv\"\n mode=\"csv\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue: sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n: { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n: lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: i2$1.PryUploadComponent, selector: "pry-upload", inputs: ["mode", "accept", "labelTranslate"], outputs: ["uploaded", "uploadedFile"] }, { kind: "component", type: i2$1.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PryImportCssComponent, selector: "pry-import-css" }, { kind: "pipe", type: i2$1.I18nPipe, name: "i18n" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); }
128
+ onFileTypeChange(fileType) {
129
+ this.selectedFileType = fileType;
130
+ }
131
+ getDatasetName(selectedId, datasets) {
132
+ const selectedDataset = datasets.find((dataset) => dataset.id === selectedId);
133
+ return selectedDataset ? selectedDataset.name : undefined;
134
+ }
135
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryImportComponent, deps: [{ token: i2.Store }], target: i0.ɵɵFactoryTarget.Component }); }
136
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: PryImportComponent, selector: "pry-import", ngImport: i0, template: "<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"false\"\n (ngModelChange)=\"onFileTypeChange($event)\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">\n {{ ('@pry.import.uploadTitle' | i18n) + selectedFileType }}\n </label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n [accept]=\"fileExtension[selectedFileType]\"\n mode=\"files\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"(uploadShapefile$ | async) && (datasets$ | async) as datasets\">\n <div class=\"o-import__result\">\n <h1>\n {{ '@pry.import.consultDataset' | i18n : { parameter: getDatasetName(datasetSelected, datasets) } }}\n </h1>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue : sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n : { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n : lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: i2$1.PryUploadComponent, selector: "pry-upload", inputs: ["mode", "accept", "labelTranslate"], outputs: ["uploaded", "uploadedFile"] }, { kind: "component", type: i2$1.PrySelectComponent, selector: "pry-select", inputs: ["labelTranslate", "baseTranslate", "translationFn", "translationFnArgs", "clearable", "multiple", "multipleClearRight", "placeholder", "isForm", "required", "name", "readonly", "items", "itemsAsOption", "bindData", "bindValue", "bindLabel", "bindIcon", "iconSize", "templateLabel", "templateOption", "autocomplete"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.PryIconComponent, selector: "pry-icon", inputs: ["color", "iconSvg", "animation", "iconImage", "alt", "width", "height", "classes"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: PryImportCssComponent, selector: "pry-import-css" }, { kind: "pipe", type: i2$1.I18nPipe, name: "i18n" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); }
119
137
  }
120
138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryImportComponent, decorators: [{
121
139
  type: Component,
122
- args: [{ selector: 'pry-import', template: "<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"true\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">{{ '@pry.import.uploadTitle' | i18n }}</label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n accept=\".csv\"\n mode=\"csv\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue: sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n: { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n: lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
123
- }], ctorParameters: function () { return [{ type: i2.Store }, { type: i2$1.PryI18nService }]; } });
140
+ args: [{ selector: 'pry-import', template: "<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"false\"\n (ngModelChange)=\"onFileTypeChange($event)\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">\n {{ ('@pry.import.uploadTitle' | i18n) + selectedFileType }}\n </label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n [accept]=\"fileExtension[selectedFileType]\"\n mode=\"files\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"(uploadShapefile$ | async) && (datasets$ | async) as datasets\">\n <div class=\"o-import__result\">\n <h1>\n {{ '@pry.import.consultDataset' | i18n : { parameter: getDatasetName(datasetSelected, datasets) } }}\n </h1>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue : sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n : { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n : lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
141
+ }], ctorParameters: function () { return [{ type: i2.Store }]; } });
124
142
 
125
143
  const enTranslations = {
126
144
  '@pry': {
@@ -130,9 +148,11 @@ const enTranslations = {
130
148
  import: 'Import',
131
149
  errorTitle: 'Import failed',
132
150
  successTitle: 'Import successful',
133
- uploadTitle: 'Choose a .csv file',
151
+ uploadTitleShapefile: 'Choose a .zip file',
152
+ uploadTitleCsv: 'Choose a .csv file',
134
153
  selectFile: 'Select file',
135
154
  importedLines: 'imported lines',
155
+ consultDataset: 'The import is in progress, see the {{ parameter }} dataset page to check its condition',
136
156
  errors: 'errors',
137
157
  error: 'Error on import: {{msg}}',
138
158
  line: 'Line {{line}}: ',
@@ -158,9 +178,11 @@ const frTranslations = {
158
178
  import: 'Importer',
159
179
  errorTitle: "L'import a échoué",
160
180
  successTitle: 'Import de données réussi',
161
- uploadTitle: 'Choisir un fichier .csv',
181
+ uploadTitle: 'Choisir un fichier .',
162
182
  selectFile: 'Sélectionner un fichier',
163
183
  importedLines: 'lignes importée(s)',
184
+ consultDataset: "L'import est en cours, consultez la page du jeu de données {{parameter}} pour vérifier son état",
185
+ shapefileState: ' pour vérifier son état',
164
186
  error: "Erreur lors de l'import: {{msg}}",
165
187
  errors: 'erreur(s)',
166
188
  line: 'Ligne {{line}}: ',
@@ -209,11 +231,18 @@ class ImportService {
209
231
  this.httpClient = httpClient;
210
232
  this.store = store;
211
233
  }
212
- upload(file, datasetId) {
234
+ upload(file, datasetId, fileType) {
213
235
  const formData = new FormData();
214
- formData.append('file', new Blob([file], { type: 'text/csv' }), file.name);
215
- return this.store.select(ConfigSelectors.dataUrl).pipe(mergeMap((url) => this.httpClient.post(`${url}/imports/csv/dataset/id/${datasetId}`, formData, {
216
- headers: new HttpHeaders({ 'File-Content-Type': 'text/csv' })
236
+ let mimeType = '';
237
+ if (fileType === 'csv') {
238
+ mimeType = 'text/csv';
239
+ }
240
+ else if (fileType === 'zip') {
241
+ mimeType = 'application/shp';
242
+ }
243
+ formData.append('file', new Blob([file], { type: mimeType }), file.name);
244
+ return this.store.select(ConfigSelectors.dataUrl).pipe(mergeMap((url) => this.httpClient.post(`${url}/imports/dataset/id/${datasetId}`, formData, {
245
+ headers: new HttpHeaders({ 'File-Content-Type': mimeType })
217
246
  })));
218
247
  }
219
248
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: ImportService, deps: [{ token: i1$1.HttpClient }, { token: i2.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -232,8 +261,10 @@ class ImportEffects {
232
261
  this.service = service;
233
262
  this.snackbar = snackbar;
234
263
  this.translateService = translateService;
235
- this.upload$ = createEffect(() => this.actions$.pipe(ofType(ImportActions.upload), mergeMap$1((action) => this.service.upload(action.file, action.dataset).pipe(map$1((data) => ImportActions.uploadSuccess({ numberOfLines: data.numberOfLines })), catchError((error) => {
236
- if (error.status === 400) {
264
+ this.upload$ = createEffect(() => this.actions$.pipe(ofType(ImportActions.upload), mergeMap$1((action) => this.service.upload(action.file, action.dataset, action.fileType).pipe(map$1((data) => {
265
+ return ImportActions.uploadSuccess({ numberOfLines: data.numberOfLines });
266
+ }), catchError((error) => {
267
+ if (error.status === 400 || error.status === 500) {
237
268
  return [ImportActions.uploadFailure({ errors: error.error.itemErrors })];
238
269
  }
239
270
  this.snackbar.open({
@@ -1 +1 @@
1
- {"version":3,"file":"provoly-dashboard-import.mjs","sources":["../../../../projects/provoly/dashboard/import/store/import.actions.ts","../../../../projects/provoly/dashboard/import/store/import.reducer.ts","../../../../projects/provoly/dashboard/import/store/import.selectors.ts","../../../../projects/provoly/dashboard/import/style/css.component.ts","../../../../projects/provoly/dashboard/import/components/import.component.ts","../../../../projects/provoly/dashboard/import/components/import.component.html","../../../../projects/provoly/dashboard/import/i18n/en.translations.ts","../../../../projects/provoly/dashboard/import/i18n/fr.translations.ts","../../../../projects/provoly/dashboard/import/import-routing.module.ts","../../../../projects/provoly/dashboard/import/store/import.service.ts","../../../../projects/provoly/dashboard/import/store/import.effects.ts","../../../../projects/provoly/dashboard/import/import.module.ts","../../../../projects/provoly/dashboard/import/provoly-dashboard-import.ts"],"sourcesContent":["import { createAction, props } from '@ngrx/store';\n\nexport interface ImportError {\n code: string;\n params?: {\n name?: string;\n type?: string;\n elasticError?: string;\n };\n}\n\nexport interface ImportResponse {\n numberOfLines: number;\n itemErrors: { [p: string]: ImportError[] } | null;\n}\n\nexport const ImportActions = {\n upload: createAction('[Import] import data', props<{ file: File; dataset: string }>()),\n uploadSuccess: createAction('[Import] import data successful', props<{ numberOfLines: number }>()),\n uploadFailure: createAction('[Import] import data failure', props<{ errors: any }>())\n};\n","import { createReducer, on } from '@ngrx/store';\nimport { ImportActions, ImportError } from './import.actions';\n\nexport const importFeatureKey = '@pry/import';\n\nexport interface ImportState {\n loading: boolean;\n errors: { [p: string]: ImportError[] } | null;\n numberOfLines: number;\n}\n\nexport const initialImportState: ImportState = {\n loading: false,\n errors: null,\n numberOfLines: 0\n};\n\nexport const importReducer = createReducer(\n initialImportState,\n on(ImportActions.upload, (state, action) => ({\n ...state,\n loading: true,\n numberOfLines: 0,\n errors: null\n })),\n on(ImportActions.uploadSuccess, (state, action) => ({\n ...state,\n loading: false,\n numberOfLines: action.numberOfLines\n })),\n on(ImportActions.uploadFailure, (state, action) => ({\n ...state,\n loading: false,\n errors: action.errors\n }))\n);\n","import { createFeatureSelector, createSelector } from '@ngrx/store';\nimport * as fromPipeline from './import.reducer';\n\nconst feature = createFeatureSelector<fromPipeline.ImportState>(fromPipeline.importFeatureKey);\n\nconst numberOfLines = createSelector(feature, (state) => state?.numberOfLines);\nconst errors = createSelector(feature, (state) => state?.errors);\n\nexport const ImportSelectors = {\n numberOfLines,\n errors\n};\n","import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'pry-import-css',\n template: '',\n styleUrls: ['./_o-import.scss'],\n encapsulation: ViewEncapsulation.None\n})\nexport class PryImportCssComponent {}\n","import { Component } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { Dataset, DataSourceActions, DataSourceSelectors, PryDatasetType, PryI18nService } from '@provoly/dashboard';\nimport { map, Observable } from 'rxjs';\nimport { ImportActions, ImportError } from '../store/import.actions';\nimport { ImportSelectors } from '../store/import.selectors';\n\n@Component({\n selector: 'pry-import',\n templateUrl: './import.component.html'\n})\nexport class PryImportComponent {\n datasets$: Observable<Dataset[]>;\n file?: File;\n datasetSelected?: string;\n numberOfLine$: Observable<number>;\n errors$: Observable<{ [p: string | number]: ImportError[] } | null>;\n errorCount$: Observable<number | null>;\n fileTypes: { label: string; value: string }[] = [\n {\n label: 'Csv',\n value: 'csv'\n }\n ];\n\n constructor(\n private store: Store,\n private translateService: PryI18nService\n ) {\n store.dispatch(DataSourceActions.dataset.loadDataset());\n\n this.datasets$ = store\n .select(DataSourceSelectors.datasets)\n .pipe(\n map((datasets) =>\n datasets\n .filter((dataset) => dataset.type === PryDatasetType.CLOSED)\n .sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1))\n )\n );\n this.numberOfLine$ = store.select(ImportSelectors.numberOfLines);\n this.errors$ = store.select(ImportSelectors.errors);\n this.errorCount$ = this.errors$.pipe(\n map((errors) => {\n if (errors) {\n return Object.values(errors).flat().length;\n }\n return null;\n })\n );\n }\n\n sortObjectEntries(obj: any) {\n let arraySorted: any = [];\n Object.keys(obj)\n .sort((a: any, b: any) => a - b)\n .forEach((el) => (arraySorted[el] = obj[el]));\n return arraySorted;\n }\n\n uploadedChange($event: File) {\n this.file = $event;\n }\n\n submit() {\n if (this.file && this.datasetSelected) {\n this.store.dispatch(ImportActions.upload({ file: this.file, dataset: this.datasetSelected }));\n this.file = undefined;\n }\n }\n\n isSubmitDisabled() {\n return this.file === undefined || this.datasetSelected === undefined;\n }\n\n getFileSize(size: number) {\n if (size >= 1000 && size < 1000000) {\n return `${(size / 1000).toFixed(1)} KB`;\n } else if (size >= 1000000) {\n return `${(size / 1000000).toFixed(1)} MB`;\n }\n return `${size} bytes`;\n }\n}\n","<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"true\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">{{ '@pry.import.uploadTitle' | i18n }}</label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n accept=\".csv\"\n mode=\"csv\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue: sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n: { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n: lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n","export const enTranslations = {\n '@pry': {\n import: {\n title: 'Import data',\n datasetImport: 'Import in :',\n import: 'Import',\n errorTitle: 'Import failed',\n successTitle: 'Import successful',\n uploadTitle: 'Choose a .csv file',\n selectFile: 'Select file',\n importedLines: 'imported lines',\n errors: 'errors',\n error: 'Error on import: {{msg}}',\n line: 'Line {{line}}: ',\n withoutLine: 'Global errors: ',\n dataset: 'Dataset',\n fileType: 'Select file type',\n code: {\n UNRECOGNIZED: 'Provided file contains a column \"{{name}}\", which is not present in the chosen dataset',\n FILE_MANDATORY: 'No file was provided',\n NB_ATTRIBUTES:\n 'The number of columns in the file does not match the number of attributes in the chosen dataset',\n CAST: 'Value {{name}} could not be casted to type \"{{type}}\"',\n ELASTIC_SEARCH: 'Elastic Search error: {{elasticError}}'\n }\n }\n }\n};\n","export const frTranslations = {\n '@pry': {\n import: {\n title: 'Import de données',\n datasetImport: 'Importer dans un jeu de données:',\n import: 'Importer',\n errorTitle: \"L'import a échoué\",\n successTitle: 'Import de données réussi',\n uploadTitle: 'Choisir un fichier .csv',\n selectFile: 'Sélectionner un fichier',\n importedLines: 'lignes importée(s)',\n error: \"Erreur lors de l'import: {{msg}}\",\n errors: 'erreur(s)',\n line: 'Ligne {{line}}: ',\n withoutLine: 'Erreurs globales: ',\n dataset: 'Jeu de données',\n fileType: 'Sélectionner un type de fichier',\n code: {\n UNRECOGNIZED:\n \"Le fichier fourni contient une colonne «\\u00A0{{name}}\\u00A0», qui n'est pas présente dans le jeu de données choisi\",\n FILE_MANDATORY: 'Aucun fichier fourni',\n NB_ATTRIBUTES:\n \"Le nombre des colonnes dans le fichier fourni ne correspond pas au nombre d'attributs dans le jeu de données choisi\",\n CAST: \"La valeur «\\u00A0{{name}}\\u00A0», n'a pas pu être convertie en type «\\u00A0{{type}}\\u00A0»,\",\n ELASTIC_SEARCH: 'Elastic Search stack trace error: {{elasticError}}'\n }\n }\n }\n};\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { PRY_ACCESS_GUARD } from '@provoly/dashboard';\nimport { PryImportComponent } from './components/import.component';\n\nconst routes: Routes = [\n {\n path: '',\n component: PryImportComponent,\n data: {\n access: {\n module: 'dashboard',\n page: 'import'\n }\n },\n canActivate: [PRY_ACCESS_GUARD]\n }\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule]\n})\nexport class PryImportRoutingModule {}\n","import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { ConfigSelectors } from '@provoly/dashboard';\nimport { mergeMap } from 'rxjs';\nimport { ImportResponse } from './import.actions';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ImportService {\n constructor(\n private httpClient: HttpClient,\n private store: Store<any>\n ) {}\n\n upload(file: File, datasetId: string) {\n const formData = new FormData();\n formData.append('file', new Blob([file], { type: 'text/csv' }), file.name);\n\n return this.store.select(ConfigSelectors.dataUrl).pipe(\n mergeMap((url) =>\n this.httpClient.post<ImportResponse>(`${url}/imports/csv/dataset/id/${datasetId}`, formData, {\n headers: new HttpHeaders({ 'File-Content-Type': 'text/csv' })\n })\n )\n );\n }\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Actions, createEffect, ofType } from '@ngrx/effects';\nimport { PryI18nService, PrySnackbarService } from '@provoly/dashboard';\nimport { catchError, map, mergeMap } from 'rxjs/operators';\nimport { ImportActions } from './import.actions';\nimport { ImportService } from './import.service';\n\n@Injectable()\nexport class ImportEffects {\n upload$ = createEffect(() =>\n this.actions$.pipe(\n ofType(ImportActions.upload),\n mergeMap((action) =>\n this.service.upload(action.file, action.dataset).pipe(\n map((data) => ImportActions.uploadSuccess({ numberOfLines: data.numberOfLines })),\n catchError((error: HttpErrorResponse) => {\n if (error.status === 400) {\n return [ImportActions.uploadFailure({ errors: error.error.itemErrors })];\n }\n this.snackbar.open({\n type: 'error',\n message: this.translateService.instant('@pry.import.error', { msg: error.error.message })\n });\n throw error;\n })\n )\n )\n )\n );\n\n constructor(\n private actions$: Actions,\n private service: ImportService,\n private snackbar: PrySnackbarService,\n private translateService: PryI18nService\n ) {}\n}\n","import { CommonModule, DatePipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { EffectsModule } from '@ngrx/effects';\nimport { StoreModule } from '@ngrx/store';\nimport { PryCoreModule, PryI18nModule, PryI18nService, PryIconModule, PrySelectModule } from '@provoly/dashboard';\nimport { PryImportComponent } from './components/import.component';\nimport { enTranslations } from './i18n/en.translations';\nimport { frTranslations } from './i18n/fr.translations';\nimport { PryImportRoutingModule } from './import-routing.module';\nimport { ImportEffects } from './store/import.effects';\nimport { importFeatureKey, importReducer } from './store/import.reducer';\nimport { PryImportCssComponent } from './style/css.component';\n\n@NgModule({\n providers: [DatePipe],\n declarations: [PryImportComponent, PryImportCssComponent],\n imports: [\n PryCoreModule,\n PrySelectModule,\n PryI18nModule,\n CommonModule,\n PryIconModule,\n FormsModule,\n PryImportRoutingModule,\n StoreModule.forFeature(importFeatureKey, importReducer),\n EffectsModule.forFeature([ImportEffects])\n ],\n exports: [PryImportComponent]\n})\nexport class PryImportModule {\n constructor(private pryTranslateService: PryI18nService) {\n this.pryTranslateService.addLangObject('fr', 'import', frTranslations);\n this.pryTranslateService.addLangObject('en', 'import', enTranslations);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["fromPipeline.importFeatureKey","i1","i2","i5.PryImportCssComponent","mergeMap","map","i2.ImportService","i3"],"mappings":"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"}
1
+ {"version":3,"file":"provoly-dashboard-import.mjs","sources":["../../../../projects/provoly/dashboard/import/store/import.actions.ts","../../../../projects/provoly/dashboard/import/store/import.reducer.ts","../../../../projects/provoly/dashboard/import/store/import.selectors.ts","../../../../projects/provoly/dashboard/import/style/css.component.ts","../../../../projects/provoly/dashboard/import/components/import.component.ts","../../../../projects/provoly/dashboard/import/components/import.component.html","../../../../projects/provoly/dashboard/import/i18n/en.translations.ts","../../../../projects/provoly/dashboard/import/i18n/fr.translations.ts","../../../../projects/provoly/dashboard/import/import-routing.module.ts","../../../../projects/provoly/dashboard/import/store/import.service.ts","../../../../projects/provoly/dashboard/import/store/import.effects.ts","../../../../projects/provoly/dashboard/import/import.module.ts","../../../../projects/provoly/dashboard/import/provoly-dashboard-import.ts"],"sourcesContent":["import { createAction, props } from '@ngrx/store';\n\nexport interface ImportError {\n code: string;\n params?: {\n name?: string;\n type?: string;\n elasticError?: string;\n };\n}\n\nexport interface ImportResponse {\n numberOfLines: number;\n itemErrors: { [p: string]: ImportError[] } | null;\n}\n\nexport const ImportActions = {\n upload: createAction('[Import] import data', props<{ file: File; dataset: string; fileType: string }>()),\n uploadSuccess: createAction('[Import] import data successful', props<{ numberOfLines?: number }>()),\n uploadFailure: createAction('[Import] import data failure', props<{ errors: any }>())\n};\n","import { createReducer, on } from '@ngrx/store';\nimport { ImportActions, ImportError } from './import.actions';\n\nexport const importFeatureKey = '@pry/import';\n\nexport interface ImportState {\n loading: boolean;\n errors: { [p: string]: ImportError[] } | null;\n numberOfLines: number | undefined;\n}\n\nexport const initialImportState: ImportState = {\n loading: false,\n errors: null,\n numberOfLines: 0\n};\n\nexport const importReducer = createReducer(\n initialImportState,\n on(ImportActions.upload, (state, action) => ({\n ...state,\n loading: true,\n numberOfLines: 0,\n errors: null\n })),\n on(ImportActions.uploadSuccess, (state, action) => ({\n ...state,\n loading: false,\n numberOfLines: action.numberOfLines\n })),\n on(ImportActions.uploadFailure, (state, action) => ({\n ...state,\n loading: false,\n errors: action.errors\n }))\n);\n","import { createFeatureSelector, createSelector } from '@ngrx/store';\nimport * as fromPipeline from './import.reducer';\n\nconst feature = createFeatureSelector<fromPipeline.ImportState>(fromPipeline.importFeatureKey);\n\nconst numberOfLines = createSelector(feature, (state) => state?.numberOfLines);\nconst errors = createSelector(feature, (state) => state?.errors);\nconst upload = createSelector(feature, (state) => state.loading);\n\nexport const ImportSelectors = {\n upload,\n numberOfLines,\n errors\n};\n","import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'pry-import-css',\n template: '',\n styleUrls: ['./_o-import.scss'],\n encapsulation: ViewEncapsulation.None\n})\nexport class PryImportCssComponent {}\n","import { Component } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { Dataset, DataSourceActions, DataSourceSelectors, PryDatasetType, PryI18nService } from '@provoly/dashboard';\nimport { map, Observable } from 'rxjs';\nimport { ImportActions, ImportError } from '../store/import.actions';\nimport { ImportSelectors } from '../store/import.selectors';\n\ntype FileExtension = 'csv' | 'zip';\n\n@Component({\n selector: 'pry-import',\n templateUrl: './import.component.html'\n})\nexport class PryImportComponent {\n datasets$: Observable<Dataset[]>;\n file?: File;\n datasetSelected?: string;\n selectedFileType: FileExtension = 'csv';\n uploadShapefile$: Observable<boolean>;\n numberOfLine$: Observable<number | undefined>;\n errors$: Observable<{ [p: string | number]: ImportError[] } | null>;\n errorCount$: Observable<number | null>;\n fileTypes: { label: string; value: FileExtension }[] = [\n {\n label: 'Csv',\n value: 'csv'\n },\n {\n label: 'Shapefile',\n value: 'zip'\n }\n ];\n\n fileExtension: Record<FileExtension, string> = {\n csv: '.csv',\n zip: '.zip'\n };\n constructor(private store: Store) {\n store.dispatch(DataSourceActions.dataset.loadDataset());\n\n this.datasets$ = store\n .select(DataSourceSelectors.datasets)\n .pipe(\n map((datasets) =>\n datasets\n .filter((dataset) => dataset.type === PryDatasetType.CLOSED)\n .sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1))\n )\n );\n this.uploadShapefile$ = store.select(ImportSelectors.upload);\n this.numberOfLine$ = store.select(ImportSelectors.numberOfLines);\n this.errors$ = store.select(ImportSelectors.errors);\n this.errorCount$ = this.errors$.pipe(\n map((errors) => {\n if (errors) {\n return Object.values(errors).flat().length;\n }\n return null;\n })\n );\n }\n\n sortObjectEntries(obj: any) {\n let arraySorted: any = [];\n Object.keys(obj)\n .sort((a: any, b: any) => a - b)\n .forEach((el) => (arraySorted[el] = obj[el]));\n return arraySorted;\n }\n\n uploadedChange($event: File) {\n this.file = $event;\n }\n\n submit() {\n if (this.file && this.datasetSelected && this.selectedFileType) {\n this.store.dispatch(\n ImportActions.upload({ file: this.file, dataset: this.datasetSelected, fileType: this.selectedFileType })\n );\n this.file = undefined;\n }\n }\n\n isSubmitDisabled() {\n return this.file === undefined || this.datasetSelected === undefined;\n }\n\n getFileSize(size: number) {\n if (size >= 1000 && size < 1000000) {\n return `${(size / 1000).toFixed(1)} KB`;\n } else if (size >= 1000000) {\n return `${(size / 1000000).toFixed(1)} MB`;\n }\n return `${size} bytes`;\n }\n\n onFileTypeChange(fileType: FileExtension) {\n this.selectedFileType = fileType;\n }\n\n getDatasetName(selectedId: string | undefined, datasets: Dataset[]): string | undefined {\n const selectedDataset = datasets.find((dataset) => dataset.id === selectedId);\n return selectedDataset ? selectedDataset.name : undefined;\n }\n}\n","<pry-import-css></pry-import-css>\n<div class=\"o-import\">\n <h1 class=\"a-h1\">{{ '@pry.import.title' | i18n }}</h1>\n <div class=\"o-import__container\">\n <div class=\"o-import__container__input\">\n <div class=\"m-form-label-field\">\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.fileType' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"fileType\"\n [items]=\"fileTypes\"\n [itemsAsOption]=\"true\"\n [ngModel]=\"fileTypes[0].value\"\n [disabled]=\"false\"\n (ngModelChange)=\"onFileTypeChange($event)\"\n bindValue=\"value\"\n bindLabel=\"label\"\n ></pry-select>\n </div>\n <label class=\"a-h3\" for=\"upload_input\">\n {{ ('@pry.import.uploadTitle' | i18n) + selectedFileType }}\n </label>\n <div class=\"o-file-input\">\n <div *ngIf=\"file\" class=\"o-import__container__input__file\">\n <pry-icon iconSvg=\"download\"></pry-icon>\n <h3>{{ file.name }}</h3>\n <span>{{ getFileSize(file.size) }}</span>\n </div>\n <pry-upload\n id=\"upload_input\"\n [accept]=\"fileExtension[selectedFileType]\"\n mode=\"files\"\n (uploadedFile)=\"uploadedChange($event)\"\n labelTranslate=\"@pry.import.selectFile\"\n ></pry-upload>\n </div>\n </div>\n <div class=\"m-form-label-field\">\n <label class=\"a-h3\" for=\"datasets\">{{ '@pry.import.datasetImport' | i18n }}</label>\n <pry-select\n class=\"a-pry-select\"\n id=\"datasets\"\n [items]=\"datasets$ | async\"\n [itemsAsOption]=\"true\"\n [(ngModel)]=\"datasetSelected\"\n [placeholder]=\"'@pry.import.dataset' | i18n\"\n bindValue=\"id\"\n bindLabel=\"name\"\n ></pry-select>\n </div>\n <div class=\"o-import__container__input__actions\">\n <button class=\"a-btn a-btn--primary\" (click)=\"submit()\" [disabled]=\"isSubmitDisabled()\">\n {{ '@pry.import.import' | i18n }}\n </button>\n </div>\n </div>\n <ng-container *ngIf=\"numberOfLine$ | async as lineImported; else errors\">\n <div *ngIf=\"lineImported > 0; else errors\" class=\"o-import__result\">\n <h2>{{ '@pry.import.successTitle' | i18n }}</h2>\n <div>\n <h3>{{ lineImported }} {{ '@pry.import.importedLines' | i18n }}</h3>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"(uploadShapefile$ | async) && (datasets$ | async) as datasets\">\n <div class=\"o-import__result\">\n <h1>\n {{ '@pry.import.consultDataset' | i18n : { parameter: getDatasetName(datasetSelected, datasets) } }}\n </h1>\n </div>\n </ng-container>\n </div>\n</div>\n<ng-template #errors>\n <div class=\"o-import__result\" *ngIf=\"errors$ | async as errors\">\n <h2 class=\"a-h2\">{{ '@pry.import.errorTitle' | i18n }}</h2>\n <div>\n <h3>{{ errorCount$ | async }} {{ '@pry.import.errors' | i18n }}</h3>\n <div *ngFor=\"let error of errors | keyvalue : sortObjectEntries\" class=\"o-import__result__error\">\n <p *ngIf=\"error.key === '0'; else withLine\">\n {{ '@pry.import.withoutLine' | i18n }}\n </p>\n <ng-template #withLine>\n {{ '@pry.import.line' | i18n : { line: error.key } }}\n </ng-template>\n <ul *ngIf=\"error.value\">\n <li *ngFor=\"let lineError of error.value\">\n {{ '@pry.import.code.' + lineError.code | i18n : lineError.params }}\n </li>\n </ul>\n </div>\n </div>\n </div>\n</ng-template>\n","export const enTranslations = {\n '@pry': {\n import: {\n title: 'Import data',\n datasetImport: 'Import in :',\n import: 'Import',\n errorTitle: 'Import failed',\n successTitle: 'Import successful',\n uploadTitleShapefile: 'Choose a .zip file',\n uploadTitleCsv: 'Choose a .csv file',\n selectFile: 'Select file',\n importedLines: 'imported lines',\n consultDataset: 'The import is in progress, see the {{ parameter }} dataset page to check its condition',\n errors: 'errors',\n error: 'Error on import: {{msg}}',\n line: 'Line {{line}}: ',\n withoutLine: 'Global errors: ',\n dataset: 'Dataset',\n fileType: 'Select file type',\n code: {\n UNRECOGNIZED: 'Provided file contains a column \"{{name}}\", which is not present in the chosen dataset',\n FILE_MANDATORY: 'No file was provided',\n NB_ATTRIBUTES:\n 'The number of columns in the file does not match the number of attributes in the chosen dataset',\n CAST: 'Value {{name}} could not be casted to type \"{{type}}\"',\n ELASTIC_SEARCH: 'Elastic Search error: {{elasticError}}'\n }\n }\n }\n};\n","export const frTranslations = {\n '@pry': {\n import: {\n title: 'Import de données',\n datasetImport: 'Importer dans un jeu de données:',\n import: 'Importer',\n errorTitle: \"L'import a échoué\",\n successTitle: 'Import de données réussi',\n uploadTitle: 'Choisir un fichier .',\n selectFile: 'Sélectionner un fichier',\n importedLines: 'lignes importée(s)',\n consultDataset: \"L'import est en cours, consultez la page du jeu de données {{parameter}} pour vérifier son état\",\n shapefileState: ' pour vérifier son état',\n error: \"Erreur lors de l'import: {{msg}}\",\n errors: 'erreur(s)',\n line: 'Ligne {{line}}: ',\n withoutLine: 'Erreurs globales: ',\n dataset: 'Jeu de données',\n fileType: 'Sélectionner un type de fichier',\n code: {\n UNRECOGNIZED:\n \"Le fichier fourni contient une colonne «\\u00A0{{name}}\\u00A0», qui n'est pas présente dans le jeu de données choisi\",\n FILE_MANDATORY: 'Aucun fichier fourni',\n NB_ATTRIBUTES:\n \"Le nombre des colonnes dans le fichier fourni ne correspond pas au nombre d'attributs dans le jeu de données choisi\",\n CAST: \"La valeur «\\u00A0{{name}}\\u00A0», n'a pas pu être convertie en type «\\u00A0{{type}}\\u00A0»,\",\n ELASTIC_SEARCH: 'Elastic Search stack trace error: {{elasticError}}'\n }\n }\n }\n};\n","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { PRY_ACCESS_GUARD } from '@provoly/dashboard';\nimport { PryImportComponent } from './components/import.component';\n\nconst routes: Routes = [\n {\n path: '',\n component: PryImportComponent,\n data: {\n access: {\n module: 'dashboard',\n page: 'import'\n }\n },\n canActivate: [PRY_ACCESS_GUARD]\n }\n];\n\n@NgModule({\n imports: [RouterModule.forChild(routes)],\n exports: [RouterModule]\n})\nexport class PryImportRoutingModule {}\n","import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Store } from '@ngrx/store';\nimport { ConfigSelectors } from '@provoly/dashboard';\nimport { mergeMap } from 'rxjs';\nimport { ImportResponse } from './import.actions';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ImportService {\n constructor(private httpClient: HttpClient, private store: Store<any>) {}\n\n upload(file: File, datasetId: string, fileType: string) {\n const formData = new FormData();\n let mimeType = '';\n\n if (fileType === 'csv') {\n mimeType = 'text/csv';\n } else if (fileType === 'zip') {\n mimeType = 'application/shp';\n }\n formData.append('file', new Blob([file], { type: mimeType }), file.name);\n\n return this.store.select(ConfigSelectors.dataUrl).pipe(\n mergeMap((url) =>\n this.httpClient.post<ImportResponse>(`${url}/imports/dataset/id/${datasetId}`, formData, {\n headers: new HttpHeaders({ 'File-Content-Type': mimeType })\n })\n )\n );\n }\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Actions, createEffect, ofType } from '@ngrx/effects';\nimport { PryI18nService, PrySnackbarService } from '@provoly/dashboard';\nimport { catchError, map, mergeMap } from 'rxjs/operators';\nimport { ImportActions } from './import.actions';\nimport { ImportService } from './import.service';\n\n@Injectable()\nexport class ImportEffects {\n upload$ = createEffect(() =>\n this.actions$.pipe(\n ofType(ImportActions.upload),\n mergeMap((action) =>\n this.service.upload(action.file, action.dataset, action.fileType).pipe(\n map((data) => {\n return ImportActions.uploadSuccess({ numberOfLines: data.numberOfLines });\n }),\n catchError((error: HttpErrorResponse) => {\n if (error.status === 400 || error.status === 500) {\n return [ImportActions.uploadFailure({ errors: error.error.itemErrors })];\n }\n this.snackbar.open({\n type: 'error',\n message: this.translateService.instant('@pry.import.error', { msg: error.error.message })\n });\n throw error;\n })\n )\n )\n )\n );\n\n constructor(\n private actions$: Actions,\n private service: ImportService,\n private snackbar: PrySnackbarService,\n private translateService: PryI18nService\n ) {}\n}\n","import { CommonModule, DatePipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { EffectsModule } from '@ngrx/effects';\nimport { StoreModule } from '@ngrx/store';\nimport { PryCoreModule, PryI18nModule, PryI18nService, PryIconModule, PrySelectModule } from '@provoly/dashboard';\nimport { PryImportComponent } from './components/import.component';\nimport { enTranslations } from './i18n/en.translations';\nimport { frTranslations } from './i18n/fr.translations';\nimport { PryImportRoutingModule } from './import-routing.module';\nimport { ImportEffects } from './store/import.effects';\nimport { importFeatureKey, importReducer } from './store/import.reducer';\nimport { PryImportCssComponent } from './style/css.component';\n\n@NgModule({\n providers: [DatePipe],\n declarations: [PryImportComponent, PryImportCssComponent],\n imports: [\n PryCoreModule,\n PrySelectModule,\n PryI18nModule,\n CommonModule,\n PryIconModule,\n FormsModule,\n PryImportRoutingModule,\n StoreModule.forFeature(importFeatureKey, importReducer),\n EffectsModule.forFeature([ImportEffects])\n ],\n exports: [PryImportComponent]\n})\nexport class PryImportModule {\n constructor(private pryTranslateService: PryI18nService) {\n this.pryTranslateService.addLangObject('fr', 'import', frTranslations);\n this.pryTranslateService.addLangObject('en', 'import', enTranslations);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["fromPipeline.importFeatureKey","i1","i2","i5.PryImportCssComponent","mergeMap","map","i2.ImportService","i3"],"mappings":"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"}
@@ -498,14 +498,14 @@ class SaveViewComponent extends ToolboxActionComponent {
498
498
  this.overlayRefDirectSaveType.backdropClick().subscribe((_) => this.toggleDirectSaveType());
499
499
  this.overlayRefDirectSaveType.attach(new TemplatePortal(this.templateDirectSaveType, this.viewContainerRef));
500
500
  setTimeout(() => {
501
- this.firstFocusdirective.nativeElement.focus();
501
+ this.firstFocusdirective?.nativeElement.focus();
502
502
  }, 10);
503
503
  }
504
504
  else {
505
505
  this.overlayRefDirectSaveType?.dispose();
506
506
  this.overlayRefDirectSaveType = undefined;
507
507
  this.store.dispatch(ConfigActions.closeOverlay({ id: this.constructor.name }));
508
- this.directiveSave.nativeElement.focus();
508
+ this.directiveSave?.nativeElement.focus();
509
509
  }
510
510
  }
511
511
  get mustOpenModal() {