ichec-angular-core 1.0.1 → 1.0.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.
@@ -11,6 +11,7 @@ import { ActivatedRoute, UrlSerializer, createUrlTreeFromSnapshot, RouterModule,
11
11
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, MatDialog } from '@angular/material/dialog';
12
12
  import * as i2 from '@angular/material/button';
13
13
  import { MatButtonModule } from '@angular/material/button';
14
+ import { MatSnackBar } from '@angular/material/snack-bar';
14
15
  import * as i1 from '@angular/material/table';
15
16
  import { MatTable, MatTableModule } from '@angular/material/table';
16
17
  import * as i2$1 from '@angular/material/form-field';
@@ -349,6 +350,9 @@ class RestService {
349
350
  }
350
351
  }
351
352
 
353
+ function _toTitleCase(str) {
354
+ return str.replace(/\w\S*/g, text => text.charAt(0).toUpperCase() + text.substring(1).toLowerCase());
355
+ }
352
356
  class ItemService extends RestService {
353
357
  typenamePlural = "";
354
358
  typename = "";
@@ -367,6 +371,9 @@ class ItemService extends RestService {
367
371
  typePlural() {
368
372
  return this.typenamePlural ? this.typenamePlural : this.typename + "s";
369
373
  }
374
+ get typeTitleCase() {
375
+ return _toTitleCase(this.typename.replaceAll("_", ""));
376
+ }
370
377
  }
371
378
 
372
379
  class ResolvedPermission {
@@ -956,17 +963,36 @@ class DetailView {
956
963
  }
957
964
  }
958
965
 
966
+ class FeedbackService extends ItemWithUserService {
967
+ _url = Feedback.plural;
968
+ typename = Feedback.typename;
969
+ sendError(e) {
970
+ this.postItem({ comments: JSON.stringify(e) }).subscribe();
971
+ }
972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
973
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, providedIn: 'root' });
974
+ }
975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, decorators: [{
976
+ type: Injectable,
977
+ args: [{
978
+ providedIn: 'root',
979
+ }]
980
+ }] });
981
+
959
982
  class EditView {
960
983
  createMode = signal(false, ...(ngDevMode ? [{ debugName: "createMode" }] : []));
961
984
  heading = computed(() => { const prefix = this.createMode() ? "New " : "Edit "; return prefix + this.getTitle(); }, ...(ngDevMode ? [{ debugName: "heading" }] : []));
962
985
  submitting = signal(false, ...(ngDevMode ? [{ debugName: "submitting" }] : []));
986
+ errorType = signal("", ...(ngDevMode ? [{ debugName: "errorType" }] : []));
963
987
  item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
964
988
  fileKeys = [];
965
989
  _route = inject(ActivatedRoute);
966
990
  _location = inject(Location);
967
991
  _userService = inject(UserService);
992
+ feedbackService = inject(FeedbackService);
968
993
  form;
969
994
  itemService;
995
+ snackBar = inject(MatSnackBar);
970
996
  uploadedFiles = [];
971
997
  constructor(itemService, form) {
972
998
  this.itemService = itemService;
@@ -1026,13 +1052,45 @@ class EditView {
1026
1052
  }
1027
1053
  postItem() {
1028
1054
  this.submitting.set(true);
1029
- this.itemService.postItem(this.createItem()).subscribe(item => this.saveFiles(item));
1055
+ this.errorType.set("");
1056
+ this.itemService.postItem(this.createItem()).subscribe({
1057
+ next: (item) => this.saveFiles(item),
1058
+ error: (e) => this.onPostError(e)
1059
+ });
1060
+ }
1061
+ onPostError(e) {
1062
+ this.submitting.set(false);
1063
+ this.errorType.set("submit");
1064
+ this.feedbackService.sendError(e);
1065
+ console.log(e);
1066
+ this.onPostErrorSnackBar(e);
1067
+ }
1068
+ onPostErrorSnackBar(_e) {
1069
+ this.snackBar.open("Submission failed - request support in the top right menu", "Dismiss", { verticalPosition: "top",
1070
+ duration: 5000
1071
+ });
1030
1072
  }
1031
1073
  putItem(item) {
1032
1074
  this.submitting.set(true);
1033
- this.itemService.putItem(this.updateItem(item)).subscribe(item => this.saveFiles(item));
1075
+ this.itemService.putItem(this.updateItem(item)).subscribe({
1076
+ next: (item) => this.saveFiles(item),
1077
+ error: (e) => this.onPutError(e)
1078
+ });
1079
+ }
1080
+ onPutError(e) {
1081
+ this.submitting.set(false);
1082
+ this.errorType.set("submit");
1083
+ this.feedbackService.sendError(e);
1084
+ console.log(e);
1085
+ this.onPutErrorSnackBar(e);
1086
+ }
1087
+ onPutErrorSnackBar(_e) {
1088
+ this.snackBar.open("Submission failed - request support in the top right menu", "Dismiss", { verticalPosition: "top",
1089
+ duration: 5000
1090
+ });
1034
1091
  }
1035
1092
  saveFiles(item) {
1093
+ this.item.set(item);
1036
1094
  const next_file = this.getNextFileForUpload();
1037
1095
  if (next_file) {
1038
1096
  this.saveFile(item, next_file);
@@ -1042,11 +1100,14 @@ class EditView {
1042
1100
  }
1043
1101
  }
1044
1102
  saveFile(item, record) {
1045
- this.uploadedFiles.push(record.name);
1046
1103
  if (record.file) {
1047
- this.itemService.putFile(item.id, record.name, record.file).subscribe(item => this.saveFiles(item));
1104
+ this.itemService.putFile(item.id, record.name, record.file).subscribe({
1105
+ next: (item) => { this.uploadedFiles.push(record.name); this.saveFiles(item); },
1106
+ error: (e) => this.onPutFileError(e)
1107
+ });
1048
1108
  }
1049
1109
  else {
1110
+ this.uploadedFiles.push(record.name);
1050
1111
  this.saveFiles(item);
1051
1112
  }
1052
1113
  }
@@ -1058,6 +1119,21 @@ class EditView {
1058
1119
  }
1059
1120
  return null;
1060
1121
  }
1122
+ onPutFileError(e) {
1123
+ // Since the item is already created on the backend
1124
+ // switch to 'edit mode' for a file resubmit attempt
1125
+ this.createMode.set(false);
1126
+ this.submitting.set(false);
1127
+ this.errorType.set("submit");
1128
+ this.feedbackService.sendError(e);
1129
+ console.log(e);
1130
+ this.onPutFileErrorSnackbar(e);
1131
+ }
1132
+ onPutFileErrorSnackbar(_e) {
1133
+ this.snackBar.open("File upload failed - please re-attach and try submitting again", "Dismiss", { verticalPosition: "top",
1134
+ duration: 5000
1135
+ });
1136
+ }
1061
1137
  isCreateRoute() {
1062
1138
  const urls = this._route.snapshot.url;
1063
1139
  if (!urls) {
@@ -1085,8 +1161,15 @@ class EditView {
1085
1161
  }
1086
1162
  onItemUpdated(item) {
1087
1163
  this.submitting.set(false);
1164
+ this.errorType.set("");
1088
1165
  this.uploadedFiles = [];
1089
1166
  this.item.set(item);
1167
+ this.postItemUpdated();
1168
+ }
1169
+ postItemUpdated() {
1170
+ this.snackBar.open(this.itemService.typeTitleCase + " updated ok", "Dismiss", { verticalPosition: "top",
1171
+ duration: 5000
1172
+ });
1090
1173
  this.goBack();
1091
1174
  }
1092
1175
  onOptions(options) {
@@ -2534,19 +2617,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
2534
2617
  MatDividerModule], template: "<mat-sidenav-container class=\"leftnav-container\">\n @if(leftNavService.wide()){\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" [opened]=\"user()!== null\" style=\"width:200px; padding-top:0px\">\n <mat-nav-list>\n @for (grouping of leftNavService.activeGroupings(); track grouping; let idx=$index; let count=$count) { \n <ul>\n @if(grouping.name)\n {\n <div style=\"display:flex; width: 100%; align-items: center; text-align: center;margin-top: 5px; margin-bottom: 5px;\">\n <span style=\"width:100%\">{{grouping.name}}</span>\n </div>\n }\n @for (option of grouping.options; track option) {\n <li>\n <a mat-list-item \n [routerLink]=\"option.route\" \n routerLinkActive #rla=\"routerLinkActive\" \n [activated]=\"rla.isActive\">\n <div style=\"display:flex; vertical-align:middle;\">\n <mat-icon style=\"margin-right: 5px;\">{{option.icon}}</mat-icon><span>{{ option.name }}</span>\n </div>\n </a>\n </li>\n }\n @if(idx < count-1)\n {\n <mat-divider></mat-divider>\n }\n </ul>\n }\n </mat-nav-list>\n </mat-sidenav>\n }\n @else{\n <mat-sidenav mode=\"side\" class=\"leftnav-side\" [opened]=\"user()!== null\" style=\"width: 70px;\">\n <mat-nav-list>\n @for (grouping of leftNavService.activeGroupings(); track grouping; let idx=$index; let count=$count) { \n <ul>\n @if(grouping.name)\n {\n <div style=\"display:flex; width: 100%; flex-direction: row; align-items: center; text-align: center;margin-top: 5px; margin-bottom: 5px;\">\n <span style=\"width:100%\">{{grouping.name}}</span>\n </div>\n }\n @for (option of grouping.options; track option) {\n <li>\n <a mat-list-item \n [routerLink]=\"option.route\" \n routerLinkActive #rla=\"routerLinkActive\" \n [activated]=\"rla.isActive\" matTooltip=\"{{option.name}}\">\n <div style=\"display:flex; vertical-align:middle;\">\n <mat-icon>{{option.icon}}</mat-icon>\n </div>\n </a>\n </li>\n }\n @if(idx < count-1)\n {\n <mat-divider></mat-divider>\n }\n </ul>\n }\n </mat-nav-list>\n </mat-sidenav>\n }\n\n <mat-sidenav-content class=\"leftnav-content\" [style.background-image]=\"backgroundStyle\"> \n <router-outlet />\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{display:flex;flex-direction:column}.leftnav-container{flex-grow:1;display:flex}.leftnav-content{display:flex;flex-grow:1;height:90vh;background-blend-mode:lighten;background-color:#ffffffa6;background-size:cover}.leftnav-side{padding:5px}ul,li{margin:0;padding:0;list-style-type:none;padding-inline-start:0;list-style:none}\n"] }]
2535
2618
  }], ctorParameters: () => [], propDecorators: { background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }], sideNavContent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSidenavContent), { isSignal: true }] }] } });
2536
2619
 
2537
- class FeedbackService extends ItemWithUserService {
2538
- _url = Feedback.plural;
2539
- typename = Feedback.typename;
2540
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
2541
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, providedIn: 'root' });
2542
- }
2543
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FeedbackService, decorators: [{
2544
- type: Injectable,
2545
- args: [{
2546
- providedIn: 'root',
2547
- }]
2548
- }] });
2549
-
2550
2620
  class FeedbackForm {
2551
2621
  fb = inject(FormBuilder);
2552
2622
  form;