@cleavelandprice/ngx-lib 2.1.2 → 2.2.1

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 (157) hide show
  1. package/README.md +615 -615
  2. package/esm2020/cleavelandprice-ngx-lib.mjs +5 -0
  3. package/{esm2015/public_api.js → esm2020/public_api.mjs} +1 -1
  4. package/esm2020/src/authentication/authentication.module.mjs +112 -0
  5. package/esm2020/src/authentication/components/login/login.component.mjs +40 -0
  6. package/esm2020/src/authentication/components/login-form/login-form.component.mjs +45 -0
  7. package/esm2020/src/authentication/model/authentication-token.mjs +2 -0
  8. package/{esm2015/src/authentication/model/authentication.service.config.js → esm2020/src/authentication/model/authentication.service.config.mjs} +1 -1
  9. package/esm2020/src/authentication/services/authentication.service.mjs +136 -0
  10. package/esm2020/src/dialog/components/_dialog/dialog.component.mjs +83 -0
  11. package/esm2020/src/dialog/components/confirmation-dialog/confirmation-dialog.component.mjs +21 -0
  12. package/esm2020/src/dialog/components/input-dialog/input-dialog.component.mjs +21 -0
  13. package/esm2020/src/dialog/components/message-dialog/message-dialog.component.mjs +21 -0
  14. package/esm2020/src/dialog/dialog.module.mjs +74 -0
  15. package/{esm2015/src/dialog/model/confirmation-dialog-mode.enum.js → esm2020/src/dialog/model/confirmation-dialog-mode.enum.mjs} +1 -1
  16. package/esm2020/src/email/email.module.mjs +47 -0
  17. package/esm2020/src/email/model/email-dto.mjs +2 -0
  18. package/{esm2015/src/email/model/email-sender.js → esm2020/src/email/model/email-sender.mjs} +2 -1
  19. package/{esm2015/src/email/model/email.js → esm2020/src/email/model/email.mjs} +2 -1
  20. package/{esm2015/src/email/model/email.service.config.js → esm2020/src/email/model/email.service.config.mjs} +1 -1
  21. package/esm2020/src/email/services/email.service.mjs +31 -0
  22. package/esm2020/src/employee/employee.module.mjs +91 -0
  23. package/esm2020/src/employee/model/employee.mjs +2 -0
  24. package/{esm2015/src/employee/model/employee.service.config.js → esm2020/src/employee/model/employee.service.config.mjs} +1 -1
  25. package/esm2020/src/employee/pipes/departments.pipe.mjs +24 -0
  26. package/esm2020/src/employee/pipes/employee-by-dn.pipe.mjs +17 -0
  27. package/esm2020/src/employee/pipes/employee-photo-url.pipe.mjs +27 -0
  28. package/esm2020/src/employee/pipes/employees-with-property-value.pipe.mjs +17 -0
  29. package/esm2020/src/employee/pipes/filter-employees.pipe.mjs +22 -0
  30. package/esm2020/src/employee/pipes/is-member-of.pipe.mjs +17 -0
  31. package/esm2020/src/employee/pipes/sort-employees.pipe.mjs +44 -0
  32. package/esm2020/src/employee/services/employee.service.mjs +41 -0
  33. package/esm2020/src/file-upload/components/upload/upload.component.mjs +34 -0
  34. package/esm2020/src/file-upload/components/upload-dialog/upload-dialog.component.mjs +102 -0
  35. package/{esm2015/src/file-upload/model/database-file-info.js → esm2020/src/file-upload/model/database-file-info.mjs} +2 -1
  36. package/{esm2015/src/file-upload/model/file-upload-request.js → esm2020/src/file-upload/model/file-upload-request.mjs} +2 -1
  37. package/esm2020/src/file-upload/model/filesystem-file-info.mjs +2 -0
  38. package/esm2020/src/file-upload/model/upload.service.config.mjs +3 -0
  39. package/esm2020/src/file-upload/services/upload.service.mjs +93 -0
  40. package/esm2020/src/file-upload/upload.module.mjs +93 -0
  41. package/{esm2015/src/sharepoint/model/sharepoint-calendar-event.js → esm2020/src/sharepoint/model/sharepoint-calendar-event.mjs} +2 -1
  42. package/esm2020/src/sharepoint/model/sharepoint-customer-visit.mjs +2 -0
  43. package/{esm2015/src/sharepoint/model/sharepoint-employee-picture.js → esm2020/src/sharepoint/model/sharepoint-employee-picture.mjs} +2 -1
  44. package/esm2020/src/sharepoint/model/sharepoint-list-item.mjs +2 -0
  45. package/esm2020/src/sharepoint/model/sharepoint-list.mjs +2 -0
  46. package/esm2020/src/sharepoint/model/sharepoint-person.mjs +2 -0
  47. package/esm2020/src/sharepoint/model/sharepoint-picture.mjs +2 -0
  48. package/{esm2015/src/sharepoint/model/sharepoint.service.config.js → esm2020/src/sharepoint/model/sharepoint.service.config.mjs} +1 -1
  49. package/esm2020/src/sharepoint/pipes/sharepoint-photo-url.pipe.mjs +16 -0
  50. package/esm2020/src/sharepoint/pipes/sharepoint-url.pipe.mjs +16 -0
  51. package/esm2020/src/sharepoint/services/sharepoint.service.mjs +77 -0
  52. package/esm2020/src/sharepoint/sharepoint.module.mjs +69 -0
  53. package/esm2020/src/url/pipes/safe-url.pipe.mjs +21 -0
  54. package/esm2020/src/url/pipes/uri-scheme.pipe.mjs +103 -0
  55. package/esm2020/src/url/url.module.mjs +38 -0
  56. package/fesm2015/cleavelandprice-ngx-lib.mjs +1412 -0
  57. package/fesm2015/cleavelandprice-ngx-lib.mjs.map +1 -0
  58. package/fesm2020/cleavelandprice-ngx-lib.mjs +1384 -0
  59. package/fesm2020/cleavelandprice-ngx-lib.mjs.map +1 -0
  60. package/index.d.ts +5 -0
  61. package/package.json +22 -10
  62. package/src/authentication/authentication.module.d.ts +17 -0
  63. package/src/authentication/components/login/login.component.d.ts +6 -1
  64. package/src/authentication/components/login-form/login-form.component.d.ts +3 -0
  65. package/src/authentication/model/authentication-token.d.ts +1 -8
  66. package/src/authentication/services/authentication.service.d.ts +12 -2
  67. package/src/dialog/components/_dialog/dialog.component.d.ts +3 -0
  68. package/src/dialog/components/confirmation-dialog/confirmation-dialog.component.d.ts +3 -0
  69. package/src/dialog/components/input-dialog/input-dialog.component.d.ts +3 -0
  70. package/src/dialog/components/message-dialog/message-dialog.component.d.ts +3 -0
  71. package/src/dialog/dialog.module.d.ts +14 -0
  72. package/src/email/email.module.d.ts +5 -0
  73. package/src/email/services/email.service.d.ts +3 -0
  74. package/src/employee/employee.module.d.ts +12 -0
  75. package/src/employee/pipes/departments.pipe.d.ts +3 -0
  76. package/src/employee/pipes/employee-by-dn.pipe.d.ts +3 -0
  77. package/src/employee/pipes/employee-photo-url.pipe.d.ts +3 -0
  78. package/src/employee/pipes/employees-with-property-value.pipe.d.ts +3 -0
  79. package/src/employee/pipes/filter-employees.pipe.d.ts +3 -0
  80. package/src/employee/pipes/is-member-of.pipe.d.ts +3 -0
  81. package/src/employee/pipes/sort-employees.pipe.d.ts +3 -0
  82. package/src/employee/services/employee.service.d.ts +3 -0
  83. package/src/file-upload/components/upload/upload.component.d.ts +3 -0
  84. package/src/file-upload/components/upload-dialog/upload-dialog.component.d.ts +3 -0
  85. package/src/file-upload/services/upload.service.d.ts +3 -0
  86. package/src/file-upload/upload.module.d.ts +13 -0
  87. package/src/sharepoint/model/sharepoint-calendar-event.d.ts +3 -3
  88. package/src/sharepoint/model/sharepoint-customer-visit.d.ts +5 -5
  89. package/src/sharepoint/model/sharepoint-employee-picture.d.ts +2 -3
  90. package/src/sharepoint/model/sharepoint-list-item.d.ts +9 -9
  91. package/src/sharepoint/model/sharepoint-list.d.ts +8 -0
  92. package/src/sharepoint/model/sharepoint-person.d.ts +9 -0
  93. package/src/sharepoint/model/sharepoint-picture.d.ts +11 -8
  94. package/src/sharepoint/model/sharepoint.service.config.d.ts +2 -5
  95. package/src/sharepoint/pipes/sharepoint-photo-url.pipe.d.ts +3 -0
  96. package/src/sharepoint/pipes/sharepoint-url.pipe.d.ts +3 -0
  97. package/src/sharepoint/services/sharepoint.service.d.ts +11 -6
  98. package/src/sharepoint/sharepoint.module.d.ts +9 -4
  99. package/src/url/pipes/safe-url.pipe.d.ts +3 -0
  100. package/src/url/pipes/uri-scheme.pipe.d.ts +3 -0
  101. package/src/url/url.module.d.ts +7 -0
  102. package/bundles/cleavelandprice-ngx-lib.umd.js +0 -1360
  103. package/bundles/cleavelandprice-ngx-lib.umd.js.map +0 -1
  104. package/bundles/cleavelandprice-ngx-lib.umd.min.js +0 -2
  105. package/bundles/cleavelandprice-ngx-lib.umd.min.js.map +0 -1
  106. package/cleavelandprice-ngx-lib.d.ts +0 -5
  107. package/cleavelandprice-ngx-lib.metadata.json +0 -1
  108. package/esm2015/cleavelandprice-ngx-lib.js +0 -6
  109. package/esm2015/src/authentication/authentication.module.js +0 -84
  110. package/esm2015/src/authentication/components/login/login.component.js +0 -41
  111. package/esm2015/src/authentication/components/login-form/login-form.component.js +0 -41
  112. package/esm2015/src/authentication/model/authentication-token.js +0 -1
  113. package/esm2015/src/authentication/services/authentication.service.js +0 -129
  114. package/esm2015/src/dialog/components/_dialog/dialog.component.js +0 -75
  115. package/esm2015/src/dialog/components/confirmation-dialog/confirmation-dialog.component.js +0 -19
  116. package/esm2015/src/dialog/components/input-dialog/input-dialog.component.js +0 -19
  117. package/esm2015/src/dialog/components/message-dialog/message-dialog.component.js +0 -19
  118. package/esm2015/src/dialog/dialog.module.js +0 -54
  119. package/esm2015/src/email/email.module.js +0 -41
  120. package/esm2015/src/email/model/email-dto.js +0 -1
  121. package/esm2015/src/email/services/email.service.js +0 -30
  122. package/esm2015/src/employee/employee.module.js +0 -73
  123. package/esm2015/src/employee/model/employee.js +0 -1
  124. package/esm2015/src/employee/pipes/departments.pipe.js +0 -20
  125. package/esm2015/src/employee/pipes/employee-by-dn.pipe.js +0 -13
  126. package/esm2015/src/employee/pipes/employee-photo-url.pipe.js +0 -23
  127. package/esm2015/src/employee/pipes/employees-with-property-value.pipe.js +0 -13
  128. package/esm2015/src/employee/pipes/filter-employees.pipe.js +0 -18
  129. package/esm2015/src/employee/pipes/is-member-of.pipe.js +0 -13
  130. package/esm2015/src/employee/pipes/sort-employees.pipe.js +0 -40
  131. package/esm2015/src/employee/services/employee.service.js +0 -40
  132. package/esm2015/src/file-upload/components/upload/upload.component.js +0 -34
  133. package/esm2015/src/file-upload/components/upload-dialog/upload-dialog.component.js +0 -101
  134. package/esm2015/src/file-upload/model/filesystem-file-info.js +0 -1
  135. package/esm2015/src/file-upload/model/upload.service.config.js +0 -3
  136. package/esm2015/src/file-upload/services/upload.service.js +0 -91
  137. package/esm2015/src/file-upload/upload.module.js +0 -73
  138. package/esm2015/src/sharepoint/model/sharepoint-customer-visit.js +0 -1
  139. package/esm2015/src/sharepoint/model/sharepoint-list-item.js +0 -1
  140. package/esm2015/src/sharepoint/model/sharepoint-list-items-request.js +0 -1
  141. package/esm2015/src/sharepoint/model/sharepoint-picture.js +0 -1
  142. package/esm2015/src/sharepoint/model/sharepoint-uri-request.js +0 -1
  143. package/esm2015/src/sharepoint/model/sharepoint-user-request.js +0 -1
  144. package/esm2015/src/sharepoint/model/sharepoint-user.js +0 -1
  145. package/esm2015/src/sharepoint/pipes/sharepoint-photo-url.pipe.js +0 -12
  146. package/esm2015/src/sharepoint/pipes/sharepoint-url.pipe.js +0 -12
  147. package/esm2015/src/sharepoint/services/sharepoint.service.js +0 -71
  148. package/esm2015/src/sharepoint/sharepoint.module.js +0 -65
  149. package/esm2015/src/url/pipes/safe-url.pipe.js +0 -20
  150. package/esm2015/src/url/pipes/uri-scheme.pipe.js +0 -99
  151. package/esm2015/src/url/url.module.js +0 -31
  152. package/fesm2015/cleavelandprice-ngx-lib.js +0 -1247
  153. package/fesm2015/cleavelandprice-ngx-lib.js.map +0 -1
  154. package/src/sharepoint/model/sharepoint-list-items-request.d.ts +0 -10
  155. package/src/sharepoint/model/sharepoint-uri-request.d.ts +0 -5
  156. package/src/sharepoint/model/sharepoint-user-request.d.ts +0 -6
  157. package/src/sharepoint/model/sharepoint-user.d.ts +0 -8
@@ -1,1247 +0,0 @@
1
- import { EventEmitter, Component, Input, Output, Inject, NgModule, Injectable, Optional, SkipSelf, Pipe, ViewChild } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import { MatButtonModule } from '@angular/material/button';
5
- import { MatCheckboxModule } from '@angular/material/checkbox';
6
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
7
- import { MatInputModule } from '@angular/material/input';
8
- import { MatProgressBarModule } from '@angular/material/progress-bar';
9
- import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
10
- import { MatSelectModule } from '@angular/material/select';
11
- import { MatTooltipModule } from '@angular/material/tooltip';
12
- import { HttpClient, HttpRequest, HttpHeaders, HttpEventType, HttpResponse, HttpClientModule } from '@angular/common/http';
13
- import { JwtHelperService } from '@auth0/angular-jwt';
14
- import { of, Subject, forkJoin } from 'rxjs';
15
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
16
- import { MatListModule } from '@angular/material/list';
17
- import { DomSanitizer } from '@angular/platform-browser';
18
-
19
- var ConfirmationDialogMode;
20
- (function (ConfirmationDialogMode) {
21
- ConfirmationDialogMode[ConfirmationDialogMode["OkCancel"] = 0] = "OkCancel";
22
- ConfirmationDialogMode[ConfirmationDialogMode["YesNo"] = 1] = "YesNo";
23
- ConfirmationDialogMode[ConfirmationDialogMode["TrueFalse"] = 2] = "TrueFalse";
24
- ConfirmationDialogMode[ConfirmationDialogMode["Custom"] = 3] = "Custom";
25
- })(ConfirmationDialogMode || (ConfirmationDialogMode = {}));
26
-
27
- class DialogComponent {
28
- constructor() {
29
- this.closed = new EventEmitter();
30
- this.ConfirmationDialogMode = ConfirmationDialogMode;
31
- this.mode = ConfirmationDialogMode.OkCancel;
32
- this.customTrueFalseText = null;
33
- }
34
- ngOnInit() {
35
- if (this.data) {
36
- this.title = this.data.title || null;
37
- this.message = this.data.message || null;
38
- this.checkboxMessage = this.data.checkboxMessage || null;
39
- this.placeholder = this.data.placeholder || null;
40
- this.userInput = this.data.value || null;
41
- this.mode = this.data.mode || ConfirmationDialogMode.OkCancel;
42
- this.customTrueFalseText = this.data.customTrueFalseText;
43
- }
44
- }
45
- close() {
46
- let data;
47
- switch (this.dialogType) {
48
- case 'message':
49
- data = this.checkboxMessage ?
50
- {
51
- checkbox: this.checkboxValue || false
52
- } :
53
- null;
54
- break;
55
- case 'input':
56
- data = this.checkboxMessage ?
57
- {
58
- response: this.userInput,
59
- checkbox: this.checkboxValue || false
60
- } :
61
- this.userInput;
62
- break;
63
- case 'confirmation':
64
- data = this.checkboxMessage ?
65
- {
66
- response: true,
67
- checkbox: this.checkboxValue || false
68
- } :
69
- true;
70
- break;
71
- }
72
- this.closed.emit(data);
73
- }
74
- cancel() {
75
- let data;
76
- if (this.dialogType === 'confirmation') {
77
- data = this.checkboxMessage ?
78
- {
79
- response: false,
80
- checkbox: this.checkboxValue || false
81
- } :
82
- false;
83
- }
84
- this.closed.emit(data);
85
- }
86
- }
87
- DialogComponent.decorators = [
88
- { type: Component, args: [{
89
- selector: 'cp-dialog',
90
- template: "<h2 *ngIf=\"title\" mat-dialog-title [innerHTML]=\"title\"></h2>\n\n<mat-dialog-content>\n <div *ngIf=\"message\" [innerHTML]=\"message\"></div>\n\n <mat-form-field *ngIf=\"dialogType === 'input'\">\n <textarea matInput [placeholder]=\"placeholder\" [(ngModel)]=\"userInput\"></textarea>\n </mat-form-field>\n\n <div id=\"checkbox\" *ngIf=\"checkboxMessage\">\n <mat-checkbox [(ngModel)]=\"checkboxValue\">\n <span [innerHTML]=\"checkboxMessage\"></span>\n </mat-checkbox>\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions>\n <button mat-raised-button (click)=\"close()\" [disabled]=\"dialogType === 'input' && !userInput\">\n <span [ngSwitch]=\"mode\">\n <span *ngSwitchCase=\"ConfirmationDialogMode.YesNo\">Yes</span>\n <span *ngSwitchCase=\"ConfirmationDialogMode.TrueFalse\">True</span>\n <span *ngSwitchCase=\"ConfirmationDialogMode.Custom\">{{ customTrueFalseText[0] }}</span>\n <span *ngSwitchDefault>OK</span>\n </span>\n </button>\n <button *ngIf=\"dialogType !== 'message'\" mat-raised-button (click)=\"cancel()\">\n <span [ngSwitch]=\"mode\">\n <span *ngSwitchCase=\"ConfirmationDialogMode.YesNo\">No</span>\n <span *ngSwitchCase=\"ConfirmationDialogMode.TrueFalse\">False</span>\n <span *ngSwitchCase=\"ConfirmationDialogMode.Custom\">{{ customTrueFalseText[1] }}</span>\n <span *ngSwitchDefault>Cancel</span>\n </span>\n </button>\n</mat-dialog-actions>",
91
- styles: ["mat-form-field{margin-top:2em;width:100%}#checkbox{margin:2em 0}"]
92
- },] }
93
- ];
94
- DialogComponent.propDecorators = {
95
- dialogType: [{ type: Input }],
96
- data: [{ type: Input }],
97
- closed: [{ type: Output }]
98
- };
99
-
100
- class ConfirmationDialogComponent {
101
- constructor(dialogRef, data) {
102
- this.dialogRef = dialogRef;
103
- this.data = data;
104
- }
105
- }
106
- ConfirmationDialogComponent.decorators = [
107
- { type: Component, args: [{
108
- selector: 'cp-confirmation-dialog',
109
- template: "<cp-dialog\n [data]=\"data\"\n [dialogType]=\"'confirmation'\"\n (closed)=\"dialogRef.close($event)\">\n</cp-dialog>"
110
- },] }
111
- ];
112
- ConfirmationDialogComponent.ctorParameters = () => [
113
- { type: MatDialogRef },
114
- { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
115
- ];
116
-
117
- class InputDialogComponent {
118
- constructor(dialogRef, data) {
119
- this.dialogRef = dialogRef;
120
- this.data = data;
121
- }
122
- }
123
- InputDialogComponent.decorators = [
124
- { type: Component, args: [{
125
- selector: 'cp-input-dialog',
126
- template: "<cp-dialog\n [data]=\"data\"\n [dialogType]=\"'input'\"\n (closed)=\"dialogRef.close($event)\">\n</cp-dialog>"
127
- },] }
128
- ];
129
- InputDialogComponent.ctorParameters = () => [
130
- { type: MatDialogRef },
131
- { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
132
- ];
133
-
134
- class MessageDialogComponent {
135
- constructor(dialogRef, data) {
136
- this.dialogRef = dialogRef;
137
- this.data = data;
138
- }
139
- }
140
- MessageDialogComponent.decorators = [
141
- { type: Component, args: [{
142
- selector: 'cp-message-dialog',
143
- template: "<cp-dialog\n [data]=\"data\"\n [dialogType]=\"'message'\"\n (closed)=\"dialogRef.close($event)\">\n</cp-dialog>"
144
- },] }
145
- ];
146
- MessageDialogComponent.ctorParameters = () => [
147
- { type: MatDialogRef },
148
- { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
149
- ];
150
-
151
- //#region Imports
152
- //#endregion
153
- class DialogModule {
154
- }
155
- DialogModule.decorators = [
156
- { type: NgModule, args: [{
157
- imports: [
158
- CommonModule,
159
- FormsModule,
160
- MatButtonModule,
161
- MatCheckboxModule,
162
- MatInputModule,
163
- MatDialogModule
164
- ],
165
- declarations: [
166
- DialogComponent,
167
- ConfirmationDialogComponent,
168
- InputDialogComponent,
169
- MessageDialogComponent
170
- ],
171
- exports: [
172
- ConfirmationDialogComponent,
173
- InputDialogComponent,
174
- MessageDialogComponent
175
- ],
176
- entryComponents: [
177
- ConfirmationDialogComponent,
178
- InputDialogComponent,
179
- MessageDialogComponent
180
- ]
181
- },] }
182
- ];
183
-
184
- class AuthenticationServiceConfig {
185
- }
186
-
187
- class SharePointServiceConfig {
188
- }
189
-
190
- //#region Imports
191
- //#endregion
192
- class SharePointService {
193
- //#endregion
194
- constructor(config, http) {
195
- this.config = config;
196
- this.http = http;
197
- }
198
- //#region Utilities
199
- getListItems(request) {
200
- if (!request.username) {
201
- request.username = this.config.userName;
202
- }
203
- if (!request.password) {
204
- request.password = this.config.password;
205
- }
206
- return this.http.post(`${this.config.sharePointApiUrl}/listitems`, request);
207
- }
208
- /*getListItemsSimple(list: string, view: string, site?: string, limit?: string): Observable<SharePointListItem[]> {
209
- return this.http.get<SharePointListItem[]>(`${this.config.sharePointApiUrl}/${list}/${view}/${site}/${limit}`);
210
- }*/
211
- getPeople(request, storePeople) {
212
- // Do we already have people stored locally?
213
- if (this.users) {
214
- return of(this.users);
215
- }
216
- if (!request.username) {
217
- request.username = this.config.userName;
218
- }
219
- if (!request.password) {
220
- request.password = this.config.password;
221
- }
222
- // Should we store people locally for subsequent calls?
223
- if (storePeople) {
224
- this.http.post(`${this.config.sharePointApiUrl}/users`, request)
225
- .subscribe(users => this.users = users);
226
- }
227
- return this.http.post(`${this.config.sharePointApiUrl}/users`, request);
228
- }
229
- getPhotos(storePhotos) {
230
- // Do we already have photos stored locally?
231
- if (this.photos) {
232
- return of(this.photos);
233
- }
234
- const request = {
235
- list: this.config.employeePhotoList,
236
- site: `${this.config.sharePointServerUrl}/${this.config.employeePhotoSite}`,
237
- username: this.config.userName,
238
- password: this.config.password,
239
- additionalPropertiesToRetrieve: ['EncodedAbsUrl']
240
- };
241
- // Should we store photos locally for subsequent calls?
242
- if (storePhotos) {
243
- this.http.post(`${this.config.sharePointApiUrl}/listitems`, request)
244
- .subscribe(photos => this.photos = photos);
245
- }
246
- return this.http.post(`${this.config.sharePointApiUrl}/listitems`, request);
247
- }
248
- }
249
- SharePointService.decorators = [
250
- { type: Injectable }
251
- ];
252
- SharePointService.ctorParameters = () => [
253
- { type: SharePointServiceConfig, decorators: [{ type: Optional }] },
254
- { type: HttpClient }
255
- ];
256
-
257
- //#region Imports
258
- //#endregion
259
- /**
260
- * Authenticate Active Directory user
261
- */
262
- class AuthenticationService {
263
- //#endregion
264
- //#region Lifecycle
265
- /**
266
- * @ignore
267
- */
268
- constructor(config, http, sharePointService) {
269
- this.http = http;
270
- this.sharePointService = sharePointService;
271
- this.authenticatedChanged = new EventEmitter();
272
- this.authenticatingChanged = new EventEmitter();
273
- /**
274
- * Flag set to true while the service is attempting to authenticate the user
275
- */
276
- this.authenticating = false;
277
- /**
278
- * Flag set to true when the user is successfully authenticated
279
- */
280
- this.authenticated = false;
281
- this.authenticationApiUrl = config.authenticationApiUrl;
282
- this.checkForExistingToken();
283
- }
284
- //#endregion
285
- //#region Utilities
286
- /**
287
- * Authenticate the user and store the token in Local Storage
288
- *
289
- * @param username AD sAMAccountName
290
- * @param password
291
- * @param adminGroup AD group that determines if authenticated user is considered an administrator of the app
292
- */
293
- login(username, password, adminGroup) {
294
- const request = {
295
- username: username,
296
- password: password,
297
- adminGroup: adminGroup
298
- };
299
- this.authenticating = true;
300
- this.authenticatingChanged.emit(this.authenticating);
301
- this.http.request('POST', this.authenticationApiUrl, { responseType: 'text', body: request })
302
- // this.http.post<string>(this.authenticationApiUrl, request)
303
- .subscribe(token => this.validateUser(token), err => {
304
- this.authenticating = false;
305
- this.authenticatingChanged.emit(this.authenticating);
306
- });
307
- }
308
- /**
309
- * Logout the user and delete the token from Local Storage
310
- */
311
- logout() {
312
- if (localStorage.getItem('token')) {
313
- localStorage.removeItem('token');
314
- }
315
- this.authenticatedUser = null;
316
- this.authenticated = false;
317
- this.authenticatedChanged.emit(false);
318
- }
319
- /**
320
- * @ignore
321
- */
322
- validateUser(token) {
323
- if (!token) {
324
- return;
325
- }
326
- const jwtHelper = new JwtHelperService();
327
- const decoded = jwtHelper.decodeToken(token);
328
- if (jwtHelper.isTokenExpired(token)) {
329
- this.logout();
330
- return;
331
- }
332
- this.authenticatedUser = decoded;
333
- this.authenticatedUser.accountName = decoded.winaccountname;
334
- this.authenticatedUser.admin = decoded.role === 'Admin';
335
- localStorage.setItem('token', token);
336
- this.getPhoto();
337
- this.authenticated = true;
338
- this.authenticatedChanged.emit(this.authenticated);
339
- this.authenticating = false;
340
- this.authenticatingChanged.emit(this.authenticating);
341
- }
342
- /**
343
- * @ignore
344
- */
345
- getPhoto() {
346
- this.sharePointService.getPhotos()
347
- .subscribe(photos => {
348
- // The user may have been logged out by the time the photos came back
349
- if (!this.authenticatedUser || !this.authenticatedUser.employeeNumber) {
350
- return;
351
- }
352
- const photo = photos.find(pic => +pic.employeeNumber === +this.authenticatedUser.employeeNumber);
353
- if (photo) {
354
- this.authenticatedUser.photoUrl = photo.encodedAbsUrl;
355
- }
356
- });
357
- }
358
- /**
359
- * @ignore
360
- */
361
- checkForExistingToken() {
362
- if (localStorage.getItem('token')) {
363
- this.validateUser(localStorage.getItem('token'));
364
- }
365
- }
366
- }
367
- AuthenticationService.decorators = [
368
- { type: Injectable }
369
- ];
370
- AuthenticationService.ctorParameters = () => [
371
- { type: AuthenticationServiceConfig, decorators: [{ type: Optional }] },
372
- { type: HttpClient },
373
- { type: SharePointService }
374
- ];
375
- AuthenticationService.propDecorators = {
376
- authenticatedChanged: [{ type: Output }],
377
- authenticatingChanged: [{ type: Output }]
378
- };
379
-
380
- class LoginFormComponent {
381
- constructor(dialogRef, sharePointService, authenticationService, data) {
382
- this.dialogRef = dialogRef;
383
- this.sharePointService = sharePointService;
384
- this.authenticationService = authenticationService;
385
- this.data = data;
386
- this.adminGroup = data.adminGroup;
387
- }
388
- ngOnInit() {
389
- this.authenticationService.authenticatedChanged
390
- .subscribe((authenticated) => {
391
- if (authenticated) {
392
- this.dialogRef.close();
393
- }
394
- });
395
- }
396
- authenticate() {
397
- if (!this.sharePointService || !this.username || !this.password) {
398
- return;
399
- }
400
- this.authenticationService.login(this.username, this.password, this.adminGroup);
401
- }
402
- }
403
- LoginFormComponent.decorators = [
404
- { type: Component, args: [{
405
- selector: 'cp-login-form',
406
- template: "<h2 mat-dialog-title>\n <span *ngIf=\"!authenticationService.authenticating\">Login</span>\n <span *ngIf=\"authenticationService.authenticating\">Authenticating...</span>\n</h2>\n\n<mat-dialog-content [class.loginError]=\"loginError\">\n <div id=\"spinner\" *ngIf=\"authenticationService.authenticating\">\n <mat-progress-spinner color=\"primary\" mode=\"indeterminate\"></mat-progress-spinner>\n </div>\n\n <div *ngIf=\"!authenticationService.authenticating\">\n <div>\n <mat-form-field>\n <input matInput placeholder=\"Username\" [(ngModel)]=\"username\" name=\"username\" required (keyup.enter)=\"authenticate()\">\n </mat-form-field>\n </div>\n\n <div>\n <mat-form-field>\n <input matInput type=\"password\" placeholder=\"Password\" [(ngModel)]=\"password\" name=\"password\" required (keyup.enter)=\"authenticate()\">\n </mat-form-field>\n </div>\n </div>\n\n <div *ngIf=\"!authenticationService.authenticating && loginError\" class=\"alert alert-danger\">\n Bad username or password\n </div>\n</mat-dialog-content>\n\n<mat-dialog-actions *ngIf=\"!authenticationService.authenticating\">\n <button type=\"button\" mat-raised-button (click)=\"authenticate()\">OK</button>\n <button type=\"button\" mat-button (click)=\"dialogRef.close()\">Cancel</button>\n</mat-dialog-actions>",
407
- styles: ["#spinner{align-items:center;display:flex;height:100%;justify-content:center;width:100%}mat-dialog-content{height:150px}mat-dialog-content.loginError{height:200px}"]
408
- },] }
409
- ];
410
- LoginFormComponent.ctorParameters = () => [
411
- { type: MatDialogRef },
412
- { type: SharePointService },
413
- { type: AuthenticationService },
414
- { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
415
- ];
416
-
417
- class LoginComponent {
418
- constructor(dialog, authenticationService) {
419
- this.dialog = dialog;
420
- this.authenticationService = authenticationService;
421
- }
422
- login() {
423
- this.dialog.open(LoginFormComponent, {
424
- data: { adminGroup: this.adminGroup }
425
- });
426
- }
427
- confirmLogout() {
428
- const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
429
- data: { message: `Are you sure you want to logout?` }
430
- });
431
- dialogRef.afterClosed().subscribe(result => {
432
- if (result) {
433
- this.authenticationService.logout();
434
- }
435
- });
436
- }
437
- }
438
- LoginComponent.decorators = [
439
- { type: Component, args: [{
440
- selector: 'cp-login',
441
- template: "<div id=\"user-id\">\n <i id=\"unauthenticated-user-image\" *ngIf=\"!authenticationService.authenticated\"\n class=\"fa fa-user-circle\"\n [class.fa-spin]=\"authenticationService.authenticating\"\n aria-hidden=\"true\"\n matTooltip=\"Login\"\n (click)=\"login()\"></i>\n\n <img id=\"authenticated-user-image\"\n *ngIf=\"authenticationService.authenticated && authenticationService.authenticatedUser.photoUrl\"\n [src]=\"authenticationService.authenticatedUser.photoUrl\"\n matTooltip=\"Logout\"\n (click)=\"confirmLogout()\" />\n\n <i id=\"authenticated-user-image\"\n *ngIf=\"authenticationService.authenticated && !authenticationService.authenticatedUser.photoUrl\"\n class=\"fa fa-user-circle\"\n matTooltip=\"Logout\"\n (click)=\"confirmLogout()\"></i>\n\n <div id=\"user-name\" *ngIf=\"authenticationService.authenticated\">\n {{ authenticationService.authenticatedUser.displayName }}\n </div>\n</div>",
442
- styles: ["#user-id{display:flex;font-family:Verdana,Geneva,Tahoma,sans-serif;height:2em;padding:.3em}.fa{font-size:2em}img{border-radius:100%;height:2em;width:2em}#user-id>div{align-items:center;display:flex;font-size:1.15em;height:100%;margin-left:.75em}"]
443
- },] }
444
- ];
445
- LoginComponent.ctorParameters = () => [
446
- { type: MatDialog },
447
- { type: AuthenticationService }
448
- ];
449
- LoginComponent.propDecorators = {
450
- adminGroup: [{ type: Input }]
451
- };
452
-
453
- //#region Imports
454
- //#endregion
455
- /**
456
- * Provides a component and a service that allows you to perform Active/Directory authentication
457
- */
458
- class AuthenticationModule {
459
- constructor(parentModule) {
460
- if (parentModule) {
461
- throw new Error('AuthenticationModule is already loaded. Import it in the AppModule only');
462
- }
463
- }
464
- static forRoot(authenticationConfig) {
465
- return {
466
- ngModule: AuthenticationModule,
467
- providers: [
468
- AuthenticationService,
469
- { provide: AuthenticationServiceConfig, useValue: authenticationConfig }
470
- ]
471
- };
472
- }
473
- }
474
- AuthenticationModule.decorators = [
475
- { type: NgModule, args: [{
476
- imports: [
477
- CommonModule,
478
- FormsModule,
479
- MatButtonModule,
480
- MatCheckboxModule,
481
- MatDialogModule,
482
- MatInputModule,
483
- MatProgressBarModule,
484
- MatProgressSpinnerModule,
485
- MatTooltipModule,
486
- MatSelectModule,
487
- DialogModule
488
- ],
489
- declarations: [
490
- LoginComponent,
491
- LoginFormComponent
492
- ],
493
- exports: [
494
- LoginComponent,
495
- LoginFormComponent
496
- ],
497
- providers: [],
498
- entryComponents: [
499
- LoginFormComponent
500
- ]
501
- },] }
502
- ];
503
- AuthenticationModule.ctorParameters = () => [
504
- { type: AuthenticationModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
505
- ];
506
-
507
- class EmailServiceConfig {
508
- }
509
-
510
- //#region Imports
511
- //#endregion
512
- class EmailService {
513
- constructor(config, http) {
514
- this.http = http;
515
- this.emailServiceConfig = config;
516
- }
517
- send(email) {
518
- const dto = {
519
- server: this.emailServiceConfig.server,
520
- smtpPort: this.emailServiceConfig.smtpPort,
521
- sender: this.emailServiceConfig.sender,
522
- subject: email.subject,
523
- content: email.content,
524
- recipients: email.recipients
525
- };
526
- return this.http.post(this.emailServiceConfig.emailApiUrl, dto);
527
- }
528
- }
529
- EmailService.decorators = [
530
- { type: Injectable }
531
- ];
532
- EmailService.ctorParameters = () => [
533
- { type: EmailServiceConfig, decorators: [{ type: Optional }] },
534
- { type: HttpClient }
535
- ];
536
-
537
- //#region Imports
538
- //#endregion
539
- class EmailModule {
540
- constructor(parentModule) {
541
- if (parentModule) {
542
- throw new Error('EmailModule is already loaded. Import it in the AppModule only');
543
- }
544
- }
545
- static forRoot(emailConfig) {
546
- return {
547
- ngModule: EmailModule,
548
- providers: [
549
- EmailService,
550
- { provide: EmailServiceConfig, useValue: emailConfig }
551
- ]
552
- };
553
- }
554
- }
555
- EmailModule.decorators = [
556
- { type: NgModule, args: [{
557
- imports: [CommonModule],
558
- declarations: [],
559
- exports: []
560
- },] }
561
- ];
562
- EmailModule.ctorParameters = () => [
563
- { type: EmailModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
564
- ];
565
-
566
- class EmployeeServiceConfig {
567
- }
568
-
569
- //#region Imports
570
- //#endregion
571
- class EmployeeService {
572
- //#endregion
573
- //#region Lifecycle
574
- constructor(config, http) {
575
- this.http = http;
576
- this.employeeApiUrl = config.employeeApiUrl;
577
- }
578
- //#endregion
579
- //#region Utilities
580
- getEmployees(storeEmployees = false, includeDisabled = false) {
581
- // Do we already have employees stored locally?
582
- if (this.employees) {
583
- return of(this.employees);
584
- // return Observable.of(this.employees);
585
- }
586
- // Should we store employees locally for subsequent calls?
587
- if (storeEmployees) {
588
- this.http.get(`${this.employeeApiUrl}/false/${includeDisabled}`)
589
- .subscribe(emps => this.employees = emps);
590
- }
591
- return this.http.get(`${this.employeeApiUrl}/false/${includeDisabled}`);
592
- }
593
- getEmployee(sAMAccountName) {
594
- return this.http.get(`${this.employeeApiUrl}/name/${sAMAccountName}`);
595
- }
596
- }
597
- EmployeeService.decorators = [
598
- { type: Injectable }
599
- ];
600
- EmployeeService.ctorParameters = () => [
601
- { type: EmployeeServiceConfig, decorators: [{ type: Optional }] },
602
- { type: HttpClient }
603
- ];
604
-
605
- class DepartmentsPipe {
606
- transform(employees, args) {
607
- const departments = [];
608
- employees
609
- .filter(emp => emp.department)
610
- .forEach(emp => {
611
- if (departments.indexOf(emp.department) === -1) {
612
- departments.push(emp.department);
613
- }
614
- });
615
- return departments.sort();
616
- }
617
- }
618
- DepartmentsPipe.decorators = [
619
- { type: Pipe, args: [{
620
- name: 'departments'
621
- },] }
622
- ];
623
-
624
- class EmployeeByDnPipe {
625
- transform(employees, dn) {
626
- return employees
627
- .find(emp => emp.distinguishedName.toLowerCase() === dn.toLowerCase());
628
- }
629
- }
630
- EmployeeByDnPipe.decorators = [
631
- { type: Pipe, args: [{
632
- name: 'employeeByDn'
633
- },] }
634
- ];
635
-
636
- class EmployeePhotoUrlPipe {
637
- transform(employee, photos) {
638
- if (!photos) {
639
- return null;
640
- }
641
- // Try to match by employeeNumber, accountName, or title
642
- const photo = photos
643
- .find(pic => (pic.employeeNumber && employee.employeeNumber && +pic.employeeNumber === +employee.employeeNumber) ||
644
- (pic.accountName && pic.accountName.toLowerCase() === employee.sAMAccountName.toLowerCase()) ||
645
- (pic.title && pic.title.toLowerCase() === employee.displayName.toLowerCase()));
646
- if (!photo) {
647
- console.log(`No photo match for ${employee.displayName}`);
648
- }
649
- return photo ? photo.encodedAbsUrl : null;
650
- }
651
- }
652
- EmployeePhotoUrlPipe.decorators = [
653
- { type: Pipe, args: [{
654
- name: 'employeePhotoUrl'
655
- },] }
656
- ];
657
-
658
- class EmployeesWithPropertyValuePipe {
659
- transform(employees, propertyName, propertyValue) {
660
- return employees
661
- .filter(emp => emp[propertyName] && emp[propertyName] === propertyValue);
662
- }
663
- }
664
- EmployeesWithPropertyValuePipe.decorators = [
665
- { type: Pipe, args: [{
666
- name: 'employeesWithPropertyValue'
667
- },] }
668
- ];
669
-
670
- class FilterEmployeesPipe {
671
- transform(employees, filter) {
672
- return filter ?
673
- employees
674
- .filter(emp => emp.displayName.toLowerCase().indexOf(filter.toLowerCase()) !== -1 ||
675
- (emp.department && emp.department.toLowerCase().indexOf(filter.toLowerCase()) !== -1) ||
676
- (emp.title && emp.title.toLowerCase().indexOf(filter.toLowerCase()) !== -1) ||
677
- emp.sAMAccountName.toLowerCase().indexOf(filter.toLowerCase()) !== -1) :
678
- employees;
679
- }
680
- }
681
- FilterEmployeesPipe.decorators = [
682
- { type: Pipe, args: [{
683
- name: 'filterEmployees'
684
- },] }
685
- ];
686
-
687
- class IsMemberOfPipe {
688
- transform(employee, groupName) {
689
- return employee.memberOf &&
690
- (employee.memberOf.find(m => m.toLowerCase().indexOf(groupName.toLowerCase()) !== -1) !== undefined);
691
- }
692
- }
693
- IsMemberOfPipe.decorators = [
694
- { type: Pipe, args: [{
695
- name: 'isMemberOf'
696
- },] }
697
- ];
698
-
699
- class SortEmployeesPipe {
700
- transform(employees, sortBy, dataType, reverse) {
701
- return this.getSorted(employees, sortBy ? sortBy : 'displayName', dataType ? dataType : 'string', reverse ? reverse : false);
702
- }
703
- getSorted(employees, sortBy, dataType, reverse) {
704
- const sorted = employees
705
- .sort((a, b) => {
706
- let valA, valB;
707
- switch (dataType.toLowerCase()) {
708
- case 'string':
709
- valA = a[sortBy] ? a[sortBy].toString().toLowerCase() : null;
710
- valB = b[sortBy] ? b[sortBy].toString().toLowerCase() : null;
711
- break;
712
- case 'number':
713
- valA = a[sortBy] ? +a[sortBy] : null;
714
- valB = b[sortBy] ? +b[sortBy] : null;
715
- break;
716
- case 'date':
717
- valA = a[sortBy] ? a[sortBy] : null;
718
- valB = b[sortBy] ? b[sortBy] : null;
719
- break;
720
- }
721
- if (valA < valB) {
722
- return -1;
723
- }
724
- if (valA > valB) {
725
- return 1;
726
- }
727
- return 0;
728
- });
729
- return reverse ? sorted.reverse() : sorted;
730
- }
731
- }
732
- SortEmployeesPipe.decorators = [
733
- { type: Pipe, args: [{
734
- name: 'sortEmployees'
735
- },] }
736
- ];
737
-
738
- //#region Imports
739
- //#endregion
740
- class EmployeeModule {
741
- constructor(parentModule) {
742
- if (parentModule) {
743
- throw new Error('EmployeeModule is already loaded. Import it in the AppModule only');
744
- }
745
- }
746
- static forRoot(employeeConfig) {
747
- return {
748
- ngModule: EmployeeModule,
749
- providers: [
750
- EmployeeService,
751
- { provide: EmployeeServiceConfig, useValue: employeeConfig }
752
- ]
753
- };
754
- }
755
- }
756
- EmployeeModule.decorators = [
757
- { type: NgModule, args: [{
758
- imports: [CommonModule],
759
- declarations: [
760
- DepartmentsPipe,
761
- EmployeeByDnPipe,
762
- EmployeesWithPropertyValuePipe,
763
- FilterEmployeesPipe,
764
- IsMemberOfPipe,
765
- EmployeePhotoUrlPipe,
766
- SortEmployeesPipe
767
- ],
768
- exports: [
769
- DepartmentsPipe,
770
- EmployeeByDnPipe,
771
- EmployeesWithPropertyValuePipe,
772
- FilterEmployeesPipe,
773
- IsMemberOfPipe,
774
- EmployeePhotoUrlPipe,
775
- SortEmployeesPipe
776
- ]
777
- },] }
778
- ];
779
- EmployeeModule.ctorParameters = () => [
780
- { type: EmployeeModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
781
- ];
782
-
783
- class SharePointPhotoUrlPipe {
784
- transform(photo) {
785
- return photo.encodedAbsUrl;
786
- }
787
- }
788
- SharePointPhotoUrlPipe.decorators = [
789
- { type: Pipe, args: [{
790
- name: 'sharePointPhotoUrl'
791
- },] }
792
- ];
793
-
794
- class SharePointUrlPipe {
795
- transform(url) {
796
- return url !== null ? url.split(',')[0] : null;
797
- }
798
- }
799
- SharePointUrlPipe.decorators = [
800
- { type: Pipe, args: [{
801
- name: 'sharePointUrl'
802
- },] }
803
- ];
804
-
805
- //#region Imports
806
- //#endregion
807
- class SharePointModule {
808
- constructor(parentModule) {
809
- if (parentModule) {
810
- throw new Error('SharePointModule is already loaded. Import it in the AppModule only');
811
- }
812
- }
813
- static forRoot(sharePointConfig) {
814
- return {
815
- ngModule: SharePointModule,
816
- providers: [
817
- SharePointService,
818
- { provide: SharePointServiceConfig, useValue: sharePointConfig }
819
- ]
820
- };
821
- }
822
- }
823
- SharePointModule.decorators = [
824
- { type: NgModule, args: [{
825
- imports: [
826
- CommonModule
827
- ],
828
- declarations: [
829
- SharePointPhotoUrlPipe,
830
- SharePointUrlPipe
831
- ],
832
- exports: [
833
- SharePointPhotoUrlPipe,
834
- SharePointUrlPipe
835
- ]
836
- },] }
837
- ];
838
- SharePointModule.ctorParameters = () => [
839
- { type: SharePointModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
840
- ];
841
-
842
- class UploadServiceConfig {
843
- }
844
-
845
- // https://malcoded.com/posts/angular-file-upload-component-with-express
846
- class UploadService {
847
- constructor(http, config) {
848
- this.http = http;
849
- this.uploadApiUrl = config.uploadApiUrl;
850
- this.uploadPath = config.uploadPath || '';
851
- this.dbAppId = config.dbAppId || '';
852
- this.externalReferenceId = config.externalReferenceId || '';
853
- this.comment = config.comment || '';
854
- // UI configuration
855
- this.uploadButtonText = config.uploadButtonText;
856
- this.uploadDialogTitle = config.uploadDialogTitle;
857
- this.uploadDialogAddFilesButtonText = config.uploadDialogAddFilesButtonText;
858
- this.uploadDialogCancelButtonText = config.uploadDialogCancelButtonText;
859
- this.uploadDialogUploadButtonText = config.uploadDialogUploadButtonText;
860
- this.uploadDialogFinishButtonText = config.uploadDialogFinishButtonText;
861
- }
862
- upload(files) {
863
- // this will be the our resulting map
864
- const status = {};
865
- files.forEach(file => {
866
- // create a new multipart-form for every file
867
- const formData = new FormData();
868
- formData.append('file', file, file.name);
869
- // create a http-post request and pass the form
870
- // tell it to report the upload progress
871
- // A 'Destination' header is used to optionally configure the file upload destination (filesystem)
872
- // A 'DbAppId' header is used to configure the unique identifier of database uploads
873
- const req = new HttpRequest('POST', this.uploadApiUrl, formData, {
874
- reportProgress: true,
875
- responseType: 'blob',
876
- headers: new HttpHeaders()
877
- .set('Destination', this.uploadPath)
878
- .set('DbAppId', this.dbAppId)
879
- .set('ExternalReferenceId', this.externalReferenceId)
880
- .set('Comment', this.comment)
881
- /*headers: this.uploadPath ?
882
- new HttpHeaders({ 'Destination': this.uploadPath }) :
883
- this.dbAppId ?
884
- new HttpHeaders({ 'DbAppId': this.dbAppId }) :
885
- null*/
886
- });
887
- // create a new progress-subject for every file
888
- const progress = new Subject();
889
- // send the http-request and subscribe for progress-updates
890
- this.http.request(req).subscribe(event => {
891
- if (event.type === HttpEventType.UploadProgress) {
892
- // calculate the progress percentage
893
- const percentDone = Math.round(100 * event.loaded / event.total);
894
- // pass the percentage into the progress-stream
895
- progress.next(percentDone);
896
- }
897
- else if (event instanceof HttpResponse) {
898
- // Close the progress-stream if we get an answer form the API
899
- // The upload is complete
900
- progress.complete();
901
- }
902
- });
903
- // Save every progress-observable in a map of all observables
904
- status[file.name] = {
905
- progress: progress.asObservable()
906
- };
907
- });
908
- // return the map of progress.observables
909
- return status;
910
- }
911
- exists(fileName) {
912
- const query = this.uploadApiUrl.toLowerCase().indexOf('filesystem') === -1 ?
913
- { name: fileName, dbAppId: this.dbAppId } :
914
- { name: fileName, destination: this.uploadPath };
915
- return this.http.post(`${this.uploadApiUrl}/exists`, query);
916
- }
917
- download(request) {
918
- return this.http.post(`${this.uploadApiUrl}/stream`, request, { responseType: 'blob' });
919
- }
920
- getUploadInfo(request) {
921
- return this.http.post(`${this.uploadApiUrl}/info`, request);
922
- }
923
- }
924
- UploadService.decorators = [
925
- { type: Injectable }
926
- ];
927
- UploadService.ctorParameters = () => [
928
- { type: HttpClient },
929
- { type: UploadServiceConfig, decorators: [{ type: Optional }] }
930
- ];
931
-
932
- class UploadDialogComponent {
933
- constructor(dialogRef, uploadService) {
934
- this.dialogRef = dialogRef;
935
- this.uploadService = uploadService;
936
- this.files = new Set();
937
- this.canBeClosed = true;
938
- this.showCancelButton = true;
939
- this.uploading = false;
940
- this.uploadSuccessful = false;
941
- }
942
- ngOnInit() {
943
- this.uploadDialogTitle = this.uploadService.uploadDialogTitle ?
944
- this.uploadService.uploadDialogTitle :
945
- 'Upload Files';
946
- this.uploadDialogAddFilesButtonText = this.uploadService.uploadDialogAddFilesButtonText ?
947
- this.uploadService.uploadDialogAddFilesButtonText :
948
- 'Add Files';
949
- this.uploadDialogCancelButtonText = this.uploadService.uploadDialogCancelButtonText ?
950
- this.uploadService.uploadDialogCancelButtonText :
951
- 'Cancel';
952
- this.uploadDialogUploadButtonText = this.uploadService.uploadDialogUploadButtonText ?
953
- this.uploadService.uploadDialogUploadButtonText :
954
- 'Upload';
955
- this.uploadDialogFinishButtonText = this.uploadService.uploadDialogFinishButtonText ?
956
- this.uploadService.uploadDialogFinishButtonText :
957
- 'Finish';
958
- this.primaryButtonText = this.uploadDialogUploadButtonText;
959
- }
960
- addFiles() {
961
- this.file.nativeElement.click();
962
- }
963
- onFilesAdded() {
964
- const files = this.file.nativeElement.files;
965
- for (const key in files) {
966
- if (!isNaN(parseInt(key))) {
967
- // See if the file already exists
968
- this.uploadService.exists(files[key].name)
969
- .subscribe(exists => {
970
- if (exists) {
971
- this.existingFileConflict = files[key].name;
972
- }
973
- if (!exists) {
974
- this.files.add(files[key]);
975
- }
976
- });
977
- }
978
- }
979
- }
980
- closeDialog() {
981
- // if everything was uploaded already, just close the dialog
982
- if (this.uploadSuccessful) {
983
- return this.dialogRef.close();
984
- }
985
- // set the component state to "uploading"
986
- this.uploading = true;
987
- // start the upload and save the progress map
988
- this.progress = this.uploadService.upload(this.files);
989
- // convert the progress map into an array
990
- const allProgressObservables = [];
991
- for (let key in this.progress) {
992
- allProgressObservables.push(this.progress[key].progress);
993
- }
994
- // Adjust the state variables
995
- // The OK-button should have the text "Finish" now
996
- this.primaryButtonText = this.uploadDialogFinishButtonText;
997
- // The dialog should not be closed while uploading
998
- this.canBeClosed = false;
999
- this.dialogRef.disableClose = true;
1000
- // Hide the cancel-button
1001
- this.showCancelButton = false;
1002
- // When all progress-observables are completed...
1003
- forkJoin(allProgressObservables).subscribe(end => {
1004
- // ... the dialog can be closed again...
1005
- this.canBeClosed = true;
1006
- this.dialogRef.disableClose = false;
1007
- // ... the upload was successful...
1008
- this.uploadSuccessful = true;
1009
- // ... and the component is no longer uploading
1010
- this.uploading = false;
1011
- });
1012
- }
1013
- }
1014
- UploadDialogComponent.decorators = [
1015
- { type: Component, args: [{
1016
- selector: 'cp-upload-dialog',
1017
- template: "<input type=\"file\" #file style=\"display: none\" (change)=\"onFilesAdded()\" multiple />\n\n<div mat-dialog-title id=\"title\">\n <div>{{ uploadDialogTitle }}</div>\n <button [disabled]=\"uploading || uploadSuccessful\" mat-raised-button color=\"primary\" class=\"add-files-btn\" (click)=\"addFiles()\">\n {{ uploadDialogAddFilesButtonText }}\n </button>\n</div>\n\n<div id=\"conflict\" *ngIf=\"existingFileConflict\">\n {{ existingFileConflict }} already exists on the server and cannot be overwritten\n</div>\n\n<mat-dialog-content>\n <mat-list>\n <mat-list-item *ngFor=\"let file of files\">\n <h4 mat-line>{{file.name}}</h4>\n <mat-progress-bar *ngIf=\"progress\" mode=\"determinate\" [value]=\"progress[file.name].progress | async\"></mat-progress-bar>\n </mat-list-item>\n </mat-list>\n</mat-dialog-content>\n\n<mat-dialog-actions id=\"actions\">\n <button *ngIf=\"showCancelButton\" mat-button mat-dialog-close>{{ uploadDialogCancelButtonText }}</button>\n <button *ngIf=\"files.size > 0\" mat-raised-button color=\"primary\" [disabled]=\"!canBeClosed\" (click)=\"closeDialog()\">{{ primaryButtonText }}</button>\n</mat-dialog-actions>\n",
1018
- styles: ["#title{display:flex;justify-content:space-between}#actions{display:flex;justify-content:flex-end}#conflict{color:red;font-size:.8em;margin-top:.5em}"]
1019
- },] }
1020
- ];
1021
- UploadDialogComponent.ctorParameters = () => [
1022
- { type: MatDialogRef },
1023
- { type: UploadService }
1024
- ];
1025
- UploadDialogComponent.propDecorators = {
1026
- file: [{ type: ViewChild, args: ['file', { static: true },] }]
1027
- };
1028
-
1029
- class UploadComponent {
1030
- constructor(dialog, uploadService) {
1031
- this.dialog = dialog;
1032
- this.uploadService = uploadService;
1033
- this.dialogClosed = new EventEmitter();
1034
- }
1035
- ngOnInit() {
1036
- this.uploadButtonText = this.uploadService.uploadButtonText ?
1037
- this.uploadService.uploadButtonText :
1038
- 'Upload';
1039
- }
1040
- openUploadDialog() {
1041
- this.dialog.open(UploadDialogComponent, { width: '50%' })
1042
- .afterClosed().subscribe(() => this.dialogClosed.emit());
1043
- }
1044
- }
1045
- UploadComponent.decorators = [
1046
- { type: Component, args: [{
1047
- selector: 'cp-upload',
1048
- template: '<button mat-raised-button (click)="openUploadDialog()">{{ uploadButtonText }}</button>'
1049
- },] }
1050
- ];
1051
- UploadComponent.ctorParameters = () => [
1052
- { type: MatDialog },
1053
- { type: UploadService }
1054
- ];
1055
- UploadComponent.propDecorators = {
1056
- dialogClosed: [{ type: Output }]
1057
- };
1058
-
1059
- //#region Imports
1060
- //#endregion
1061
- class UploadModule {
1062
- constructor(parentModule) {
1063
- if (parentModule) {
1064
- throw new Error('UploadModule is already loaded. Import it in the AppModule only');
1065
- }
1066
- }
1067
- static forRoot(uploadConfig) {
1068
- return {
1069
- ngModule: UploadModule,
1070
- providers: [
1071
- UploadService,
1072
- { provide: UploadServiceConfig, useValue: uploadConfig }
1073
- ]
1074
- };
1075
- }
1076
- }
1077
- UploadModule.decorators = [
1078
- { type: NgModule, args: [{
1079
- imports: [
1080
- CommonModule,
1081
- BrowserAnimationsModule,
1082
- HttpClientModule,
1083
- MatButtonModule,
1084
- MatDialogModule,
1085
- MatListModule,
1086
- MatProgressBarModule
1087
- ],
1088
- declarations: [
1089
- UploadComponent,
1090
- UploadDialogComponent
1091
- ],
1092
- exports: [
1093
- UploadComponent,
1094
- UploadDialogComponent
1095
- ],
1096
- entryComponents: [
1097
- UploadDialogComponent
1098
- ]
1099
- },] }
1100
- ];
1101
- UploadModule.ctorParameters = () => [
1102
- { type: UploadModule, decorators: [{ type: Optional }, { type: SkipSelf }] }
1103
- ];
1104
-
1105
- // This pipe whitelists URLs so that they aren't prefixed with 'unsafe:' when they render in the DOM
1106
- class SafeUrlPipe {
1107
- constructor(domSanitizer) {
1108
- this.domSanitizer = domSanitizer;
1109
- }
1110
- transform(value) {
1111
- return this.domSanitizer.bypassSecurityTrustUrl(value);
1112
- }
1113
- }
1114
- SafeUrlPipe.decorators = [
1115
- { type: Pipe, args: [{
1116
- name: 'safeUrl'
1117
- },] }
1118
- ];
1119
- SafeUrlPipe.ctorParameters = () => [
1120
- { type: DomSanitizer }
1121
- ];
1122
-
1123
- class UriSchemePipe {
1124
- // https://docs.microsoft.com/en-us/office/client-developer/office-uri-schemes
1125
- transform(value) {
1126
- if (!localStorage.getItem('useUriScheme')) {
1127
- return value;
1128
- }
1129
- const urlSplit = value.split('.');
1130
- const extension = urlSplit[urlSplit.length - 1];
1131
- if (!extension) {
1132
- return value;
1133
- }
1134
- const command = this.command(extension);
1135
- const app = this.app(extension);
1136
- return `ms-${app}:${command}|u|${value}`;
1137
- }
1138
- app(extension) {
1139
- switch (extension.toLowerCase()) {
1140
- // documents
1141
- case 'doc':
1142
- case 'docx':
1143
- case 'docm':
1144
- case 'docb':
1145
- case 'dot':
1146
- case 'dotx':
1147
- case 'dotm': // templates
1148
- return 'word';
1149
- case 'xls':
1150
- case 'xlsx':
1151
- case 'xlm':
1152
- case 'xlsm':
1153
- case 'xlsb':
1154
- case 'xlw':
1155
- case 'xlt':
1156
- case 'xltx':
1157
- case 'xltm': // templates
1158
- return 'excel';
1159
- case 'ppt':
1160
- case 'pptx':
1161
- case 'pps':
1162
- case 'ppsx':
1163
- case 'pptm':
1164
- case 'ppsm':
1165
- case 'sldx':
1166
- case 'sldm':
1167
- case 'pot':
1168
- case 'potx':
1169
- case 'potm': // templates
1170
- return 'powerpoint';
1171
- case 'vsd':
1172
- case 'vsdx':
1173
- case 'vst':
1174
- case 'vstx': // templates
1175
- return 'visio';
1176
- case 'mdb':
1177
- case 'accdb':
1178
- case 'accde':
1179
- case 'accdr':
1180
- case 'accdt': // templates
1181
- return 'access';
1182
- case 'mpp':
1183
- case 'mppx':
1184
- case 'mpt': // templates
1185
- return 'project';
1186
- case 'pub':
1187
- return 'publisher';
1188
- case 'xsn':
1189
- return 'infopath';
1190
- }
1191
- }
1192
- command(extension) {
1193
- switch (extension.toLowerCase()) {
1194
- case 'dot':
1195
- case 'dotx':
1196
- case 'dotm':
1197
- case 'xlt':
1198
- case 'xltx':
1199
- case 'xltm':
1200
- case 'pot':
1201
- case 'potx':
1202
- case 'potm':
1203
- case 'vst':
1204
- case 'vstx':
1205
- case 'accdt':
1206
- case 'mpt':
1207
- return 'nft'; // new from template
1208
- default:
1209
- const openMode = 'v'; // for view, or 'e' or edit
1210
- return `of${openMode}`; // default: open file as view/edit
1211
- }
1212
- }
1213
- }
1214
- UriSchemePipe.decorators = [
1215
- { type: Pipe, args: [{
1216
- name: 'uriScheme',
1217
- pure: false
1218
- },] }
1219
- ];
1220
-
1221
- //#region Imports
1222
- //#endregion
1223
- class UrlModule {
1224
- }
1225
- UrlModule.decorators = [
1226
- { type: NgModule, args: [{
1227
- imports: [
1228
- CommonModule
1229
- ],
1230
- declarations: [
1231
- SafeUrlPipe,
1232
- UriSchemePipe
1233
- ],
1234
- exports: [
1235
- SafeUrlPipe,
1236
- UriSchemePipe
1237
- ],
1238
- entryComponents: []
1239
- },] }
1240
- ];
1241
-
1242
- /**
1243
- * Generated bundle index. Do not edit.
1244
- */
1245
-
1246
- export { AuthenticationModule, AuthenticationService, AuthenticationServiceConfig, ConfirmationDialogComponent, ConfirmationDialogMode, DepartmentsPipe, DialogModule, EmailModule, EmailService, EmailServiceConfig, EmployeeByDnPipe, EmployeeModule, EmployeePhotoUrlPipe, EmployeeService, EmployeeServiceConfig, EmployeesWithPropertyValuePipe, FilterEmployeesPipe, InputDialogComponent, IsMemberOfPipe, LoginComponent, LoginFormComponent, MessageDialogComponent, SafeUrlPipe, SharePointModule, SharePointPhotoUrlPipe, SharePointService, SharePointServiceConfig, SharePointUrlPipe, SortEmployeesPipe, UploadComponent, UploadDialogComponent, UploadModule, UploadService, UploadServiceConfig, UriSchemePipe, UrlModule, DialogComponent as ɵa };
1247
- //# sourceMappingURL=cleavelandprice-ngx-lib.js.map