@sumaris-net/ngx-components 2.6.16 → 2.6.18

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/esm2020/src/app/admin/users/users.mjs +9 -3
  2. package/esm2020/src/app/core/form/buttons/form-buttons-bar.component.mjs +1 -1
  3. package/esm2020/src/app/core/form/entity/editor.class.mjs +3 -2
  4. package/esm2020/src/app/core/menu/menu.component.mjs +10 -6
  5. package/esm2020/src/app/core/menu/menu.service.mjs +7 -1
  6. package/esm2020/src/app/shared/services/memory-entity-service.class.mjs +3 -3
  7. package/esm2020/src/app/social/message/message.form.mjs +56 -4
  8. package/esm2020/src/app/social/message/message.modal.mjs +7 -3
  9. package/esm2020/src/app/social/message/message.model.mjs +4 -1
  10. package/esm2020/src/app/social/message/message.module.mjs +7 -20
  11. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  12. package/esm2020/src/app/social/user-event/user-event.service.mjs +35 -22
  13. package/fesm2015/sumaris-net.ngx-components.mjs +181 -109
  14. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  15. package/fesm2020/sumaris-net.ngx-components.mjs +180 -109
  16. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  17. package/package.json +1 -1
  18. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -1
  19. package/src/app/core/menu/menu.component.d.ts +6 -2
  20. package/src/app/core/menu/menu.service.d.ts +2 -0
  21. package/src/app/shared/services/memory-entity-service.class.d.ts +3 -1
  22. package/src/app/social/message/message.form.d.ts +8 -2
  23. package/src/app/social/message/message.modal.d.ts +5 -1
  24. package/src/app/social/message/message.model.d.ts +2 -0
  25. package/src/app/social/message/message.module.d.ts +2 -1
  26. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  27. package/src/assets/i18n/en-US.json +1 -0
  28. package/src/assets/i18n/en.json +1 -0
  29. package/src/assets/i18n/fr.json +1 -0
  30. package/src/assets/manifest.json +1 -1
@@ -23491,7 +23491,7 @@ class InMemoryEntitiesService extends StartableObservableService {
23491
23491
  const res = { data, total };
23492
23492
  const nextOffset = size > 0 ? (offset || 0) + size : total;
23493
23493
  if (nextOffset < total) {
23494
- res.fetchMore = () => this.loadAll(nextOffset, size, sortBy, sortDirection, filter, opts)
23494
+ res.fetchMore = () => this.loadAll(nextOffset, size, sortBy, sortDirection, filter, Object.assign(Object.assign({}, opts), { updateHiddenData: false }))
23495
23495
  .then(res => {
23496
23496
  var _a, _b;
23497
23497
  // Update hidden data (remove new fetched item)
@@ -23505,7 +23505,7 @@ class InMemoryEntitiesService extends StartableObservableService {
23505
23505
  }
23506
23506
  finally {
23507
23507
  // Remember hidden data
23508
- if (offset === 0) {
23508
+ if ((opts === null || opts === void 0 ? void 0 : opts.updateHiddenData) !== false) {
23509
23509
  this._hiddenData = !excludedDataByPagination ? excludedDataByFilter : excludedDataByFilter.concat(...excludedDataByPagination);
23510
23510
  }
23511
23511
  }
@@ -24906,6 +24906,16 @@ class MenuService extends StartableObservableService {
24906
24906
  _markAsClosed() {
24907
24907
  this._$opened.next(false);
24908
24908
  }
24909
+ close() {
24910
+ return __awaiter(this, void 0, void 0, function* () {
24911
+ this._$opened.next(false);
24912
+ });
24913
+ }
24914
+ open() {
24915
+ return __awaiter(this, void 0, void 0, function* () {
24916
+ this._$opened.next(true);
24917
+ });
24918
+ }
24909
24919
  ngOnStart() {
24910
24920
  return __awaiter(this, void 0, void 0, function* () {
24911
24921
  console.info(`${this._logPrefix}Starting...`);
@@ -25306,7 +25316,7 @@ class MenuComponent {
25306
25316
  this._subscription.add(this.menuService.opened
25307
25317
  // Avoid duplicated events
25308
25318
  .pipe(distinctUntilChanged())
25309
- .subscribe((value) => (value ? this.open() : this.close())));
25319
+ .subscribe((value) => (value ? this.open({ emitEvent: false }) : this.close({ emitEvent: false }))));
25310
25320
  // TODO : Find a more reliable way to do this :
25311
25321
  // Must be donne after menuService subscription :
25312
25322
  // - In MenuService.ngOnStart accountChanges change will be emitted before the service is ready
@@ -25363,7 +25373,7 @@ class MenuComponent {
25363
25373
  }
25364
25374
  });
25365
25375
  }
25366
- open() {
25376
+ open(opts) {
25367
25377
  return __awaiter(this, void 0, void 0, function* () {
25368
25378
  console.debug('[menu] Checking open event...');
25369
25379
  const opened = yield this.menu.isOpen(this.menuId);
@@ -25371,12 +25381,14 @@ class MenuComponent {
25371
25381
  console.debug('[menu] Opening menu');
25372
25382
  yield this.menu.open(this.menuId);
25373
25383
  // Propagate to service
25374
- this.menuService._markAsOpened();
25384
+ if (!opts || opts.emitEvent !== false) {
25385
+ this.menuService._markAsOpened();
25386
+ }
25375
25387
  }
25376
25388
  return true;
25377
25389
  });
25378
25390
  }
25379
- close() {
25391
+ close(opts) {
25380
25392
  return __awaiter(this, void 0, void 0, function* () {
25381
25393
  console.debug('[menu] Checking close event...');
25382
25394
  const opened = yield this.menu.isOpen(this.menuId);
@@ -25384,7 +25396,9 @@ class MenuComponent {
25384
25396
  console.debug('[menu] Closing menu');
25385
25397
  yield this.menu.close(this.menuId);
25386
25398
  // Propagate to service
25387
- this.menuService._markAsClosed();
25399
+ if (!opts || opts.emitEvent !== false) {
25400
+ this.menuService._markAsClosed();
25401
+ }
25388
25402
  }
25389
25403
  return true;
25390
25404
  });
@@ -31399,7 +31413,8 @@ class AppEditor {
31399
31413
  }
31400
31414
  }
31401
31415
  setError(value, opts) {
31402
- if (this.errorSubject.value !== value) {
31416
+ // Compare using '!=' to detect null and undefined as same value
31417
+ if (this.errorSubject.value != value) {
31403
31418
  this.errorSubject.next(value);
31404
31419
  if (!opts || opts.emitEvent !== false)
31405
31420
  this.markForCheck();
@@ -35722,6 +35737,7 @@ class AbstractUserEventService extends BaseGraphqlService {
35722
35737
  this.queries = options.queries;
35723
35738
  this.mutations = options.mutations || {};
35724
35739
  this.subscriptions = options.subscriptions || {};
35740
+ this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
35725
35741
  this._logPrefix = '[user-event-service] ';
35726
35742
  }
35727
35743
  get countSubject() {
@@ -35866,10 +35882,18 @@ class AbstractUserEventService extends BaseGraphqlService {
35866
35882
  return; // Rejected
35867
35883
  const withContent = !!entity.content;
35868
35884
  // Add user event locally
35869
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
35870
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
35871
- data: entity
35872
- });
35885
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35886
+ if (withContent) {
35887
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35888
+ query: this.queries.loadAllWithContent,
35889
+ data: entity
35890
+ });
35891
+ }
35892
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35893
+ query: this.queries.loadAll,
35894
+ data: Object.assign(Object.assign({}, entity), { content: null })
35895
+ });
35896
+ }
35873
35897
  // Update count
35874
35898
  this._countSubject.next(this._countSubject.value + 1);
35875
35899
  // Add id
@@ -35992,16 +36016,14 @@ class AbstractUserEventService extends BaseGraphqlService {
35992
36016
  variables: {
35993
36017
  ids
35994
36018
  },
35995
- update: (proxy) => {
35996
- // Remove from caches
35997
- this.removeFromMutableCachedQueriesByIds(proxy, {
35998
- query: this.queries.loadAll,
35999
- ids
36000
- });
36001
- this.removeFromMutableCachedQueriesByIds(proxy, {
36002
- query: this.queries.loadAllWithContent,
36003
- ids
36004
- });
36019
+ update: (cache) => {
36020
+ // Remove from cache
36021
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
36022
+ this.removeFromMutableCachedQueriesByIds(cache, {
36023
+ queries: this.getLoadQueries(),
36024
+ ids
36025
+ });
36026
+ }
36005
36027
  if (this._debug)
36006
36028
  console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
36007
36029
  }
@@ -36031,13 +36053,13 @@ class AbstractUserEventService extends BaseGraphqlService {
36031
36053
  console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
36032
36054
  this.copyIdAndUpdateDate(savedEntity, entity);
36033
36055
  // Add to cache
36034
- if (withContent) {
36035
- this.insertIntoMutableCachedQueries(proxy, {
36036
- query: this.queries.loadAllWithContent,
36037
- data: savedEntity
36038
- });
36039
- }
36040
- else {
36056
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
36057
+ if (withContent) {
36058
+ this.insertIntoMutableCachedQueries(proxy, {
36059
+ query: this.queries.loadAllWithContent,
36060
+ data: savedEntity
36061
+ });
36062
+ }
36041
36063
  this.insertIntoMutableCachedQueries(proxy, {
36042
36064
  query: this.queries.loadAll,
36043
36065
  data: Object.assign(Object.assign({}, savedEntity), { content: null })
@@ -36198,6 +36220,9 @@ class AbstractUserEventService extends BaseGraphqlService {
36198
36220
  copyIdAndUpdateDate(source, target) {
36199
36221
  EntityUtils.copyIdAndUpdateDate(source, target);
36200
36222
  }
36223
+ getLoadQueries() {
36224
+ return [this.queries.loadAll, this.queries.loadAllWithContent].filter(isNotNil);
36225
+ }
36201
36226
  }
36202
36227
  AbstractUserEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AbstractUserEventService, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
36203
36228
  AbstractUserEventService.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: AbstractUserEventService, usesInheritance: true, ngImport: i0 });
@@ -36584,6 +36609,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36584
36609
  }]
36585
36610
  }] });
36586
36611
 
36612
+ var PersonFilter_1;
36613
+ // @dynamic
36614
+ let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
36615
+ constructor() {
36616
+ super(PersonFilter_1.TYPENAME);
36617
+ }
36618
+ static searchFilter(source) {
36619
+ return source && PersonFilter_1.fromObject(source).asFilterFn();
36620
+ }
36621
+ fromObject(source, opts) {
36622
+ super.fromObject(source, opts);
36623
+ this.email = source.email;
36624
+ this.pubkey = source.pubkey;
36625
+ this.searchText = source.searchText;
36626
+ this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
36627
+ this.userProfiles = source.userProfiles;
36628
+ this.excludedIds = source.excludedIds;
36629
+ this.searchAttribute = source.searchAttribute;
36630
+ this.searchAttributes = source.searchAttributes;
36631
+ }
36632
+ asObject(opts) {
36633
+ const target = super.asObject(opts);
36634
+ target.email = this.email;
36635
+ target.pubkey = this.pubkey;
36636
+ target.searchText = this.searchText;
36637
+ target.statusIds = this.statusIds;
36638
+ target.userProfiles = this.userProfiles;
36639
+ target.excludedIds = this.excludedIds;
36640
+ target.searchAttribute = this.searchAttribute;
36641
+ target.searchAttributes = this.searchAttributes;
36642
+ return target;
36643
+ }
36644
+ buildFilter() {
36645
+ const filterFns = super.buildFilter();
36646
+ // Filter by status
36647
+ if (isNotEmptyArray(this.statusIds)) {
36648
+ filterFns.push(e => this.statusIds.includes(e.statusId));
36649
+ }
36650
+ // Filter excluded ids
36651
+ if (isNotEmptyArray(this.excludedIds)) {
36652
+ filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
36653
+ }
36654
+ // Search text
36655
+ const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
36656
+ if (searchTextFilter)
36657
+ filterFns.push(searchTextFilter);
36658
+ return filterFns;
36659
+ }
36660
+ };
36661
+ PersonFilter = PersonFilter_1 = __decorate([
36662
+ EntityClass({ typename: 'PersonFilterVO' })
36663
+ ], PersonFilter);
36664
+
36587
36665
  const MessageTypes = {
36588
36666
  INBOX_MESSAGE: 'INBOX_MESSAGE',
36589
36667
  EMAIL: 'EMAIL',
@@ -36616,12 +36694,14 @@ let Message = class Message extends Entity {
36616
36694
  this.type = source.type;
36617
36695
  this.issuer = source.issuer && Person.fromObject(source.issuer);
36618
36696
  this.recipients = source.recipients && source.recipients.map(Person.fromObject);
36697
+ this.recipientFilter = source.recipientFilter && PersonFilter.fromObject(source.recipientFilter) || undefined;
36619
36698
  this.subject = source.subject;
36620
36699
  this.body = source.body;
36621
36700
  }
36622
36701
  asObject(opts) {
36623
36702
  const target = super.asObject(opts);
36624
36703
  target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));
36704
+ target.recipientFilter = this.recipientFilter && this.recipientFilter.asObject(opts) || undefined;
36625
36705
  return target;
36626
36706
  }
36627
36707
  };
@@ -36651,6 +36731,8 @@ class MessageForm extends AppForm {
36651
36731
  this.bodyMaxLength = 2000;
36652
36732
  this.bodyAutoHeight = true;
36653
36733
  this.canSelectType = false;
36734
+ this.canRecipientFilter = false;
36735
+ this.recipientFilterCount = 0;
36654
36736
  this.types = MessageTypeList;
36655
36737
  this.mobile = this.settings.mobile;
36656
36738
  }
@@ -36658,6 +36740,7 @@ class MessageForm extends AppForm {
36658
36740
  this.setForm(this.formBuilder.group({
36659
36741
  type: [MessageTypes.INBOX_MESSAGE, Validators.required],
36660
36742
  recipients: [null, Validators.required],
36743
+ recipientFilter: [null],
36661
36744
  subject: [
36662
36745
  null,
36663
36746
  this.subjectMaxLength
@@ -36666,6 +36749,11 @@ class MessageForm extends AppForm {
36666
36749
  ],
36667
36750
  body: [null, this.bodyMaxLength ? Validators.compose([Validators.maxLength(this.bodyMaxLength)]) : Validators.required],
36668
36751
  }));
36752
+ this.registerSubscription(this._form
36753
+ .get('type')
36754
+ .valueChanges.pipe(filter(isNotNil))
36755
+ .subscribe((type) => this.updateFormGroup(this._form, { type })));
36756
+ // Person combo
36669
36757
  const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name']);
36670
36758
  this.registerAutocompleteField('recipients', {
36671
36759
  showAllOnFocus: false,
@@ -36683,15 +36771,53 @@ class MessageForm extends AppForm {
36683
36771
  isSamePerson(o1, o2) {
36684
36772
  return EntityUtils.equals(o1, o2, 'id');
36685
36773
  }
36774
+ updateFormGroup(formGroup, opts) {
36775
+ console.debug('[message-form] Updating form group...', opts);
36776
+ // Recipient validator
36777
+ const recipientsRequired = toBoolean(opts === null || opts === void 0 ? void 0 : opts.recipientRequired, (opts === null || opts === void 0 ? void 0 : opts.type) !== MessageTypes.FEED);
36778
+ {
36779
+ const control = formGroup.get('recipients');
36780
+ if (recipientsRequired) {
36781
+ if (!control.hasValidator(Validators.required)) {
36782
+ control.addValidators(Validators.required);
36783
+ }
36784
+ control.enable();
36785
+ }
36786
+ else {
36787
+ if (control.hasValidator(Validators.required)) {
36788
+ control.removeValidators(Validators.required);
36789
+ }
36790
+ control.disable();
36791
+ }
36792
+ }
36793
+ // Recipient filter validator
36794
+ const recipientFilterRequired = this.canRecipientFilter && !recipientsRequired;
36795
+ {
36796
+ const control = formGroup.get('recipientFilter');
36797
+ if (recipientFilterRequired) {
36798
+ if (!control.hasValidator(Validators.required)) {
36799
+ control.addValidators(Validators.required);
36800
+ }
36801
+ control.enable();
36802
+ }
36803
+ else {
36804
+ if (control.hasValidator(Validators.required)) {
36805
+ control.removeValidators(Validators.required);
36806
+ }
36807
+ control.disable();
36808
+ }
36809
+ }
36810
+ formGroup.updateValueAndValidity();
36811
+ }
36686
36812
  markForCheck() {
36687
36813
  this.cd.markForCheck();
36688
36814
  }
36689
36815
  }
36690
36816
  MessageForm.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, deps: [{ token: i0.Injector }, { token: i1$2.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
36691
- MessageForm.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MessageForm, selector: "app-message-form", inputs: { suggestFn: "suggestFn", subjectMinLength: "subjectMinLength", subjectMaxLength: "subjectMaxLength", bodyMaxLength: "bodyMaxLength", bodyAutoHeight: "bodyAutoHeight", canSelectType: "canSelectType" }, usesInheritance: true, ngImport: i0, template: "\n\n<form [formGroup]=\"form\" class=\"form-container\">\n\n <!-- type -->\n <mat-form-field *ngIf=\"canSelectType\">\n <mat-select formControlName=\"type\" [placeholder]=\"'SOCIAL.MESSAGE.TYPE'|translate\">\n <mat-option *ngFor=\"let item of types\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <!-- Recipients -->\n <mat-chips-field *ngIf=\"(form.controls.type.valueChanges|async) !== 'FEED'\"\n formControlName=\"recipients\"\n chipColor=\"accent\"\n [placeholder]=\"'SOCIAL.MESSAGE.RECIPIENTS'|translate\"\n [config]=\"autocompleteFields.recipients\"\n [equals]=\"isSamePerson\">\n </mat-chips-field>\n\n <!-- Subject -->\n <mat-form-field>\n <input matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.SUBJECT'|translate\"\n formControlName=\"subject\"\n autocomplete=\"off\"\n required>\n <mat-error *ngIf=\"form.controls.subject.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('minlength')\">\n {{ 'ERROR.FIELD_MIN_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-hint *ngIf=\"subjectMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.subject.value?.length || 0, max: subjectMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n <!-- Body -->\n <mat-form-field floatLabel=\"never\">\n <textarea matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.BODY_HELP'|translate\"\n formControlName=\"body\"\n [class.fixed-height]=\"!bodyAutoHeight\"\n [cdkTextareaAutosize]=\"bodyAutoHeight\"\n (keydown.control.enter)=\"doSubmit($event)\"\n >\n </textarea>\n <mat-error *ngIf=\"form.controls.body.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH' | translate: form.controls.body.errors.maxlength }}\n </mat-error>\n <mat-hint *ngIf=\"bodyMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.body.value?.length || 0, max: bodyMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n</form>\n", styles: ["textarea.fixed-height{height:11.5em}textarea{min-height:11.5em}\n"], dependencies: [{ 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.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: MatChipsField, selector: "mat-chips-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "appearance", "placeholder", "suggestFn", "required", "mobile", "readonly", "clearable", "debounceTime", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "class", "panelWidth", "matAutocompletePosition", "itemSize", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "chipColor", "debug", "filter", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
36817
+ MessageForm.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MessageForm, selector: "app-message-form", inputs: { suggestFn: "suggestFn", subjectMinLength: "subjectMinLength", subjectMaxLength: "subjectMaxLength", bodyMaxLength: "bodyMaxLength", bodyAutoHeight: "bodyAutoHeight", canSelectType: "canSelectType", canRecipientFilter: "canRecipientFilter", recipientFilterCount: "recipientFilterCount" }, usesInheritance: true, ngImport: i0, template: "\n\n<form [formGroup]=\"form\" class=\"form-container\">\n\n <!-- type -->\n <mat-form-field *ngIf=\"canSelectType\">\n <mat-select formControlName=\"type\" [placeholder]=\"'SOCIAL.MESSAGE.TYPE'|translate\">\n <ng-container *ngFor=\"let item of types\">\n <mat-option [value]=\"item.id\" *ngIf=\"item.id !== 'FEED' || canRecipientFilter\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n\n <!-- Recipients -->\n <mat-chips-field *ngIf=\"(form.controls.type.valueChanges|async) !== 'FEED'; else recipientFilter\"\n formControlName=\"recipients\"\n chipColor=\"accent\"\n [placeholder]=\"'SOCIAL.MESSAGE.RECIPIENTS'|translate\"\n [config]=\"autocompleteFields.recipients\"\n [equals]=\"isSamePerson\">\n </mat-chips-field>\n <ng-template #recipientFilter>\n <mat-form-field>\n <mat-chip-list>\n <mat-chip>{{'SOCIAL.MESSAGE.RECIPIENT_FILTER_COUNT'|translate: {count: recipientFilterCount} }}</mat-chip>\n </mat-chip-list>\n <input matInput hidden type=\"number\">\n </mat-form-field>\n </ng-template>\n\n <!-- Subject -->\n <mat-form-field>\n <input matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.SUBJECT'|translate\"\n formControlName=\"subject\"\n autocomplete=\"off\"\n required>\n <mat-error *ngIf=\"form.controls.subject.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('minlength')\">\n {{ 'ERROR.FIELD_MIN_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-hint *ngIf=\"subjectMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.subject.value?.length || 0, max: subjectMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n <!-- Body -->\n <mat-form-field floatLabel=\"never\">\n <textarea matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.BODY_HELP'|translate\"\n formControlName=\"body\"\n [class.fixed-height]=\"!bodyAutoHeight\"\n [cdkTextareaAutosize]=\"bodyAutoHeight\"\n (keydown.control.enter)=\"doSubmit($event)\"\n >\n </textarea>\n <mat-error *ngIf=\"form.controls.body.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH' | translate: form.controls.body.errors.maxlength }}\n </mat-error>\n <mat-hint *ngIf=\"bodyMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.body.value?.length || 0, max: bodyMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n</form>\n", styles: ["textarea.fixed-height{height:11.5em}textarea{min-height:11.5em}\n"], dependencies: [{ 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.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6$1.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: MatChipsField, selector: "mat-chips-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "appearance", "placeholder", "suggestFn", "required", "mobile", "readonly", "clearable", "debounceTime", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "class", "panelWidth", "matAutocompletePosition", "itemSize", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "chipColor", "debug", "filter", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "component", type: i11$1.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i11$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
36692
36818
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, decorators: [{
36693
36819
  type: Component,
36694
- args: [{ selector: 'app-message-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n\n<form [formGroup]=\"form\" class=\"form-container\">\n\n <!-- type -->\n <mat-form-field *ngIf=\"canSelectType\">\n <mat-select formControlName=\"type\" [placeholder]=\"'SOCIAL.MESSAGE.TYPE'|translate\">\n <mat-option *ngFor=\"let item of types\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <!-- Recipients -->\n <mat-chips-field *ngIf=\"(form.controls.type.valueChanges|async) !== 'FEED'\"\n formControlName=\"recipients\"\n chipColor=\"accent\"\n [placeholder]=\"'SOCIAL.MESSAGE.RECIPIENTS'|translate\"\n [config]=\"autocompleteFields.recipients\"\n [equals]=\"isSamePerson\">\n </mat-chips-field>\n\n <!-- Subject -->\n <mat-form-field>\n <input matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.SUBJECT'|translate\"\n formControlName=\"subject\"\n autocomplete=\"off\"\n required>\n <mat-error *ngIf=\"form.controls.subject.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('minlength')\">\n {{ 'ERROR.FIELD_MIN_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-hint *ngIf=\"subjectMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.subject.value?.length || 0, max: subjectMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n <!-- Body -->\n <mat-form-field floatLabel=\"never\">\n <textarea matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.BODY_HELP'|translate\"\n formControlName=\"body\"\n [class.fixed-height]=\"!bodyAutoHeight\"\n [cdkTextareaAutosize]=\"bodyAutoHeight\"\n (keydown.control.enter)=\"doSubmit($event)\"\n >\n </textarea>\n <mat-error *ngIf=\"form.controls.body.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH' | translate: form.controls.body.errors.maxlength }}\n </mat-error>\n <mat-hint *ngIf=\"bodyMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.body.value?.length || 0, max: bodyMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n</form>\n", styles: ["textarea.fixed-height{height:11.5em}textarea{min-height:11.5em}\n"] }]
36820
+ args: [{ selector: 'app-message-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n\n<form [formGroup]=\"form\" class=\"form-container\">\n\n <!-- type -->\n <mat-form-field *ngIf=\"canSelectType\">\n <mat-select formControlName=\"type\" [placeholder]=\"'SOCIAL.MESSAGE.TYPE'|translate\">\n <ng-container *ngFor=\"let item of types\">\n <mat-option [value]=\"item.id\" *ngIf=\"item.id !== 'FEED' || canRecipientFilter\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label |translate }}\n </mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n\n <!-- Recipients -->\n <mat-chips-field *ngIf=\"(form.controls.type.valueChanges|async) !== 'FEED'; else recipientFilter\"\n formControlName=\"recipients\"\n chipColor=\"accent\"\n [placeholder]=\"'SOCIAL.MESSAGE.RECIPIENTS'|translate\"\n [config]=\"autocompleteFields.recipients\"\n [equals]=\"isSamePerson\">\n </mat-chips-field>\n <ng-template #recipientFilter>\n <mat-form-field>\n <mat-chip-list>\n <mat-chip>{{'SOCIAL.MESSAGE.RECIPIENT_FILTER_COUNT'|translate: {count: recipientFilterCount} }}</mat-chip>\n </mat-chip-list>\n <input matInput hidden type=\"number\">\n </mat-form-field>\n </ng-template>\n\n <!-- Subject -->\n <mat-form-field>\n <input matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.SUBJECT'|translate\"\n formControlName=\"subject\"\n autocomplete=\"off\"\n required>\n <mat-error *ngIf=\"form.controls.subject.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('minlength')\">\n {{ 'ERROR.FIELD_MIN_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-error *ngIf=\"form.controls.subject.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH_COMPACT'|translate }}\n </mat-error>\n <mat-hint *ngIf=\"subjectMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.subject.value?.length || 0, max: subjectMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n <!-- Body -->\n <mat-form-field floatLabel=\"never\">\n <textarea matInput type=\"text\"\n [placeholder]=\"'SOCIAL.MESSAGE.BODY_HELP'|translate\"\n formControlName=\"body\"\n [class.fixed-height]=\"!bodyAutoHeight\"\n [cdkTextareaAutosize]=\"bodyAutoHeight\"\n (keydown.control.enter)=\"doSubmit($event)\"\n >\n </textarea>\n <mat-error *ngIf=\"form.controls.body.hasError('maxlength')\">\n {{ 'ERROR.FIELD_MAX_LENGTH' | translate: form.controls.body.errors.maxlength }}\n </mat-error>\n <mat-hint *ngIf=\"bodyMaxLength\" align=\"end\">\n {{ 'INFO.TEXT_PROGRESS' | translate: { current: form.controls.body.value?.length || 0, max: bodyMaxLength } }}\n </mat-hint>\n </mat-form-field>\n\n</form>\n", styles: ["textarea.fixed-height{height:11.5em}textarea{min-height:11.5em}\n"] }]
36695
36821
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36696
36822
  type: Input
36697
36823
  }], subjectMinLength: [{
@@ -36704,6 +36830,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36704
36830
  type: Input
36705
36831
  }], canSelectType: [{
36706
36832
  type: Input
36833
+ }], canRecipientFilter: [{
36834
+ type: Input
36835
+ }], recipientFilterCount: [{
36836
+ type: Input
36707
36837
  }] } });
36708
36838
 
36709
36839
  class MessageModal {
@@ -36776,16 +36906,20 @@ class MessageModal {
36776
36906
  }
36777
36907
  }
36778
36908
  MessageModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, deps: [{ token: LocalSettingsService }, { token: i2$1.ModalController }, { token: AccountService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
36779
- MessageModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MessageModal, selector: "app-message-modal", inputs: { suggestFn: "suggestFn", data: "data", canSelectType: "canSelectType" }, viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, static: true }], ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"secondary\">\n <ion-buttons slot=\"start\">\n <ion-button class=\"back-button\" (click)=\"cancel($event)\" visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title>\n {{'SOCIAL.MESSAGE.NEW.TITLE' | translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n\n <ion-button class=\"back-button\" (click)=\"doSubmit($event)\"\n [disabled]=\"!form.valid\"\n visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"checkmark\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n\n<ion-content class=\"ion-padding\" >\n\n <ion-item *ngIf=\"form.error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"form.error|translate\"></ion-label>\n </ion-item>\n\n <app-message-form #form (onSubmit)=\"doSubmit($event)\"\n (onCancel)=\"cancel($event)\"\n [canSelectType]=\"canSelectType\"\n [suggestFn]=\"suggestFn\">\n </app-message-form>\n\n</ion-content>\n\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"cancel($event)\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button [fill]=\"form.invalid ? 'clear' : 'solid'\"\n [disabled]=\"form.loading || form.invalid\"\n (keyup.enter)=\"doSubmit($event)\"\n (click)=\"doSubmit($event)\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_SEND</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n\n\n </ion-toolbar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2$1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: MessageForm, selector: "app-message-form", inputs: ["suggestFn", "subjectMinLength", "subjectMaxLength", "bodyMaxLength", "bodyAutoHeight", "canSelectType"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
36909
+ MessageModal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MessageModal, selector: "app-message-modal", inputs: { suggestFn: "suggestFn", data: "data", canSelectType: "canSelectType", canRecipientFilter: "canRecipientFilter", recipientFilterCount: "recipientFilterCount" }, viewQueries: [{ propertyName: "form", first: true, predicate: ["form"], descendants: true, static: true }], ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"secondary\">\n <ion-buttons slot=\"start\">\n <ion-button class=\"back-button\" (click)=\"cancel($event)\" visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title>\n {{'SOCIAL.MESSAGE.NEW.TITLE' | translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n\n <ion-button class=\"back-button\" (click)=\"doSubmit($event)\"\n [disabled]=\"!form.valid\"\n visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"checkmark\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n\n<ion-content class=\"ion-padding\" >\n\n <ion-item *ngIf=\"form.error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"form.error|translate\"></ion-label>\n </ion-item>\n\n <app-message-form #form (onSubmit)=\"doSubmit($event)\"\n (onCancel)=\"cancel($event)\"\n [canSelectType]=\"canSelectType\"\n [canRecipientFilter]=\"canRecipientFilter\"\n [recipientFilterCount]=\"recipientFilterCount\"\n [suggestFn]=\"suggestFn\">\n </app-message-form>\n\n</ion-content>\n\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"cancel($event)\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button [fill]=\"form.invalid ? 'clear' : 'solid'\"\n [disabled]=\"form.loading || form.invalid\"\n (keyup.enter)=\"doSubmit($event)\"\n (click)=\"doSubmit($event)\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_SEND</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n\n\n </ion-toolbar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2$1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: MessageForm, selector: "app-message-form", inputs: ["suggestFn", "subjectMinLength", "subjectMaxLength", "bodyMaxLength", "bodyAutoHeight", "canSelectType", "canRecipientFilter", "recipientFilterCount"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
36780
36910
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, decorators: [{
36781
36911
  type: Component,
36782
- args: [{ selector: 'app-message-modal', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar color=\"secondary\">\n <ion-buttons slot=\"start\">\n <ion-button class=\"back-button\" (click)=\"cancel($event)\" visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title>\n {{'SOCIAL.MESSAGE.NEW.TITLE' | translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n\n <ion-button class=\"back-button\" (click)=\"doSubmit($event)\"\n [disabled]=\"!form.valid\"\n visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"checkmark\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n\n<ion-content class=\"ion-padding\" >\n\n <ion-item *ngIf=\"form.error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"form.error|translate\"></ion-label>\n </ion-item>\n\n <app-message-form #form (onSubmit)=\"doSubmit($event)\"\n (onCancel)=\"cancel($event)\"\n [canSelectType]=\"canSelectType\"\n [suggestFn]=\"suggestFn\">\n </app-message-form>\n\n</ion-content>\n\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"cancel($event)\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button [fill]=\"form.invalid ? 'clear' : 'solid'\"\n [disabled]=\"form.loading || form.invalid\"\n (keyup.enter)=\"doSubmit($event)\"\n (click)=\"doSubmit($event)\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_SEND</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n\n\n </ion-toolbar>\n</ion-footer>\n" }]
36912
+ args: [{ selector: 'app-message-modal', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar color=\"secondary\">\n <ion-buttons slot=\"start\">\n <ion-button class=\"back-button\" (click)=\"cancel($event)\" visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"arrow-back\"></ion-icon>\n </ion-button>\n </ion-buttons>\n\n <ion-title>\n {{'SOCIAL.MESSAGE.NEW.TITLE' | translate}}\n </ion-title>\n\n <ion-buttons slot=\"end\">\n\n <ion-button class=\"back-button\" (click)=\"doSubmit($event)\"\n [disabled]=\"!form.valid\"\n visible-xs visible-sm visible-mobile>\n <ion-icon slot=\"icon-only\" name=\"checkmark\"></ion-icon>\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n\n<ion-content class=\"ion-padding\" >\n\n <ion-item *ngIf=\"form.error\" visible-xs visible-sm visible-mobile lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"form.error|translate\"></ion-label>\n </ion-item>\n\n <app-message-form #form (onSubmit)=\"doSubmit($event)\"\n (onCancel)=\"cancel($event)\"\n [canSelectType]=\"canSelectType\"\n [canRecipientFilter]=\"canRecipientFilter\"\n [recipientFilterCount]=\"recipientFilterCount\"\n [suggestFn]=\"suggestFn\">\n </app-message-form>\n\n</ion-content>\n\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"cancel($event)\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button [fill]=\"form.invalid ? 'clear' : 'solid'\"\n [disabled]=\"form.loading || form.invalid\"\n (keyup.enter)=\"doSubmit($event)\"\n (click)=\"doSubmit($event)\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_SEND</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n\n\n </ion-toolbar>\n</ion-footer>\n" }]
36783
36913
  }], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: i2$1.ModalController }, { type: AccountService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36784
36914
  type: Input
36785
36915
  }], data: [{
36786
36916
  type: Input
36787
36917
  }], canSelectType: [{
36788
36918
  type: Input
36919
+ }], canRecipientFilter: [{
36920
+ type: Input
36921
+ }], recipientFilterCount: [{
36922
+ type: Input
36789
36923
  }], form: [{
36790
36924
  type: ViewChild,
36791
36925
  args: ['form', { static: true }]
@@ -36794,28 +36928,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36794
36928
  class MessageModule {
36795
36929
  }
36796
36930
  MessageModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
36797
- MessageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, declarations: [MessageModal,
36798
- MessageForm], imports: [CommonModule,
36799
- CoreModule,
36800
- SharedModule], exports: [MessageModal] });
36801
- MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule,
36802
- CoreModule,
36803
- SharedModule] });
36931
+ MessageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, declarations: [MessageModal, MessageForm], imports: [CommonModule, CoreModule, SharedModule, MatChipsModule], exports: [MessageModal] });
36932
+ MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule, CoreModule, SharedModule, MatChipsModule] });
36804
36933
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, decorators: [{
36805
36934
  type: NgModule,
36806
36935
  args: [{
36807
- imports: [
36808
- CommonModule,
36809
- CoreModule,
36810
- SharedModule
36811
- ],
36812
- declarations: [
36813
- MessageModal,
36814
- MessageForm
36815
- ],
36816
- exports: [
36817
- MessageModal
36818
- ]
36936
+ imports: [CommonModule, CoreModule, SharedModule, MatChipsModule],
36937
+ declarations: [MessageModal, MessageForm],
36938
+ exports: [MessageModal],
36819
36939
  }]
36820
36940
  }] });
36821
36941
 
@@ -37302,9 +37422,9 @@ class MessageService extends BaseGraphqlService {
37302
37422
  // On dismiss
37303
37423
  const { data } = yield modal.onDidDismiss();
37304
37424
  if (!data || !(data instanceof Message))
37305
- return; // CANCELLED
37425
+ return true; // CANCELLED
37306
37426
  // Send message
37307
- yield this.send(data, { showToast: options === null || options === void 0 ? void 0 : options.showToast });
37427
+ return yield this.send(data, { showToast: options === null || options === void 0 ? void 0 : options.showToast });
37308
37428
  });
37309
37429
  }
37310
37430
  /* -- protected methods -- */
@@ -37328,59 +37448,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
37328
37448
  }] }];
37329
37449
  } });
37330
37450
 
37331
- var PersonFilter_1;
37332
- // @dynamic
37333
- let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
37334
- constructor() {
37335
- super(PersonFilter_1.TYPENAME);
37336
- }
37337
- static searchFilter(source) {
37338
- return source && PersonFilter_1.fromObject(source).asFilterFn();
37339
- }
37340
- fromObject(source, opts) {
37341
- super.fromObject(source, opts);
37342
- this.email = source.email;
37343
- this.pubkey = source.pubkey;
37344
- this.searchText = source.searchText;
37345
- this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
37346
- this.userProfiles = source.userProfiles;
37347
- this.excludedIds = source.excludedIds;
37348
- this.searchAttribute = source.searchAttribute;
37349
- this.searchAttributes = source.searchAttributes;
37350
- }
37351
- asObject(opts) {
37352
- const target = super.asObject(opts);
37353
- target.email = this.email;
37354
- target.pubkey = this.pubkey;
37355
- target.searchText = this.searchText;
37356
- target.statusIds = this.statusIds;
37357
- target.userProfiles = this.userProfiles;
37358
- target.excludedIds = this.excludedIds;
37359
- target.searchAttribute = this.searchAttribute;
37360
- target.searchAttributes = this.searchAttributes;
37361
- return target;
37362
- }
37363
- buildFilter() {
37364
- const filterFns = super.buildFilter();
37365
- // Filter by status
37366
- if (isNotEmptyArray(this.statusIds)) {
37367
- filterFns.push(e => this.statusIds.includes(e.statusId));
37368
- }
37369
- // Filter excluded ids
37370
- if (isNotEmptyArray(this.excludedIds)) {
37371
- filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
37372
- }
37373
- // Search text
37374
- const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
37375
- if (searchTextFilter)
37376
- filterFns.push(searchTextFilter);
37377
- return filterFns;
37378
- }
37379
- };
37380
- PersonFilter = PersonFilter_1 = __decorate([
37381
- EntityClass({ typename: 'PersonFilterVO' })
37382
- ], PersonFilter);
37383
-
37384
37451
  const PersonFragments = {
37385
37452
  person: gql `
37386
37453
  fragment PersonFragment on PersonVO {
@@ -37717,11 +37784,16 @@ class UsersPage extends AppTable {
37717
37784
  target.department = (_a = p.department) === null || _a === void 0 ? void 0 : _a.asObject();
37718
37785
  return target;
37719
37786
  });
37787
+ const recipientFilter = PersonFilter.fromObject(this.filter);
37788
+ const canRecipientFilter = !recipientFilter.isEmpty() && (this.accountService.isAdmin() || this.accountService.isSupervisor());
37720
37789
  return this.messageService.openComposeModal({
37721
37790
  suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),
37722
- data: {
37791
+ canRecipientFilter,
37792
+ recipientFilterCount: this.totalRowCount,
37793
+ data: Message.fromObject({
37723
37794
  recipients,
37724
- },
37795
+ recipientFilter,
37796
+ }),
37725
37797
  });
37726
37798
  });
37727
37799
  }