@sumaris-net/ngx-components 2.6.15 → 2.6.17

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 (28) 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 +5 -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/social/message/message.form.mjs +56 -4
  7. package/esm2020/src/app/social/message/message.modal.mjs +7 -3
  8. package/esm2020/src/app/social/message/message.model.mjs +4 -1
  9. package/esm2020/src/app/social/message/message.module.mjs +7 -20
  10. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  11. package/esm2020/src/app/social/user-event/user-event.service.mjs +35 -22
  12. package/fesm2015/sumaris-net.ngx-components.mjs +180 -107
  13. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  14. package/fesm2020/sumaris-net.ngx-components.mjs +179 -107
  15. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -1
  18. package/src/app/core/menu/menu.component.d.ts +6 -2
  19. package/src/app/core/menu/menu.service.d.ts +2 -0
  20. package/src/app/social/message/message.form.d.ts +8 -2
  21. package/src/app/social/message/message.modal.d.ts +5 -1
  22. package/src/app/social/message/message.model.d.ts +2 -0
  23. package/src/app/social/message/message.module.d.ts +2 -1
  24. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  25. package/src/assets/i18n/en-US.json +1 -0
  26. package/src/assets/i18n/en.json +1 -0
  27. package/src/assets/i18n/fr.json +1 -0
  28. package/src/assets/manifest.json +1 -1
@@ -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
  });
@@ -31021,7 +31035,9 @@ class AppEditor {
31021
31035
  }
31022
31036
  ngOnInit() {
31023
31037
  if (this.formButtonsBar) {
31024
- this.registerSubscription(this.formButtonsBar.onBack.subscribe(event => this.goBack(event)));
31038
+ this.registerSubscription(this.formButtonsBar.onBack
31039
+ .pipe(throttleTime(200)) // Avoid to be called twice
31040
+ .subscribe(event => this.goBack(event)));
31025
31041
  }
31026
31042
  }
31027
31043
  ngAfterViewInit() {
@@ -35720,6 +35736,7 @@ class AbstractUserEventService extends BaseGraphqlService {
35720
35736
  this.queries = options.queries;
35721
35737
  this.mutations = options.mutations || {};
35722
35738
  this.subscriptions = options.subscriptions || {};
35739
+ this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
35723
35740
  this._logPrefix = '[user-event-service] ';
35724
35741
  }
35725
35742
  get countSubject() {
@@ -35864,10 +35881,18 @@ class AbstractUserEventService extends BaseGraphqlService {
35864
35881
  return; // Rejected
35865
35882
  const withContent = !!entity.content;
35866
35883
  // Add user event locally
35867
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
35868
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
35869
- data: entity
35870
- });
35884
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35885
+ if (withContent) {
35886
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35887
+ query: this.queries.loadAllWithContent,
35888
+ data: entity
35889
+ });
35890
+ }
35891
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35892
+ query: this.queries.loadAll,
35893
+ data: Object.assign(Object.assign({}, entity), { content: null })
35894
+ });
35895
+ }
35871
35896
  // Update count
35872
35897
  this._countSubject.next(this._countSubject.value + 1);
35873
35898
  // Add id
@@ -35990,16 +36015,14 @@ class AbstractUserEventService extends BaseGraphqlService {
35990
36015
  variables: {
35991
36016
  ids
35992
36017
  },
35993
- update: (proxy) => {
35994
- // Remove from caches
35995
- this.removeFromMutableCachedQueriesByIds(proxy, {
35996
- query: this.queries.loadAll,
35997
- ids
35998
- });
35999
- this.removeFromMutableCachedQueriesByIds(proxy, {
36000
- query: this.queries.loadAllWithContent,
36001
- ids
36002
- });
36018
+ update: (cache) => {
36019
+ // Remove from cache
36020
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
36021
+ this.removeFromMutableCachedQueriesByIds(cache, {
36022
+ queries: this.getLoadQueries(),
36023
+ ids
36024
+ });
36025
+ }
36003
36026
  if (this._debug)
36004
36027
  console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
36005
36028
  }
@@ -36029,13 +36052,13 @@ class AbstractUserEventService extends BaseGraphqlService {
36029
36052
  console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
36030
36053
  this.copyIdAndUpdateDate(savedEntity, entity);
36031
36054
  // Add to cache
36032
- if (withContent) {
36033
- this.insertIntoMutableCachedQueries(proxy, {
36034
- query: this.queries.loadAllWithContent,
36035
- data: savedEntity
36036
- });
36037
- }
36038
- else {
36055
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
36056
+ if (withContent) {
36057
+ this.insertIntoMutableCachedQueries(proxy, {
36058
+ query: this.queries.loadAllWithContent,
36059
+ data: savedEntity
36060
+ });
36061
+ }
36039
36062
  this.insertIntoMutableCachedQueries(proxy, {
36040
36063
  query: this.queries.loadAll,
36041
36064
  data: Object.assign(Object.assign({}, savedEntity), { content: null })
@@ -36196,6 +36219,9 @@ class AbstractUserEventService extends BaseGraphqlService {
36196
36219
  copyIdAndUpdateDate(source, target) {
36197
36220
  EntityUtils.copyIdAndUpdateDate(source, target);
36198
36221
  }
36222
+ getLoadQueries() {
36223
+ return [this.queries.loadAll, this.queries.loadAllWithContent].filter(isNotNil);
36224
+ }
36199
36225
  }
36200
36226
  AbstractUserEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AbstractUserEventService, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
36201
36227
  AbstractUserEventService.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: AbstractUserEventService, usesInheritance: true, ngImport: i0 });
@@ -36582,6 +36608,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36582
36608
  }]
36583
36609
  }] });
36584
36610
 
36611
+ var PersonFilter_1;
36612
+ // @dynamic
36613
+ let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
36614
+ constructor() {
36615
+ super(PersonFilter_1.TYPENAME);
36616
+ }
36617
+ static searchFilter(source) {
36618
+ return source && PersonFilter_1.fromObject(source).asFilterFn();
36619
+ }
36620
+ fromObject(source, opts) {
36621
+ super.fromObject(source, opts);
36622
+ this.email = source.email;
36623
+ this.pubkey = source.pubkey;
36624
+ this.searchText = source.searchText;
36625
+ this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
36626
+ this.userProfiles = source.userProfiles;
36627
+ this.excludedIds = source.excludedIds;
36628
+ this.searchAttribute = source.searchAttribute;
36629
+ this.searchAttributes = source.searchAttributes;
36630
+ }
36631
+ asObject(opts) {
36632
+ const target = super.asObject(opts);
36633
+ target.email = this.email;
36634
+ target.pubkey = this.pubkey;
36635
+ target.searchText = this.searchText;
36636
+ target.statusIds = this.statusIds;
36637
+ target.userProfiles = this.userProfiles;
36638
+ target.excludedIds = this.excludedIds;
36639
+ target.searchAttribute = this.searchAttribute;
36640
+ target.searchAttributes = this.searchAttributes;
36641
+ return target;
36642
+ }
36643
+ buildFilter() {
36644
+ const filterFns = super.buildFilter();
36645
+ // Filter by status
36646
+ if (isNotEmptyArray(this.statusIds)) {
36647
+ filterFns.push(e => this.statusIds.includes(e.statusId));
36648
+ }
36649
+ // Filter excluded ids
36650
+ if (isNotEmptyArray(this.excludedIds)) {
36651
+ filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
36652
+ }
36653
+ // Search text
36654
+ const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
36655
+ if (searchTextFilter)
36656
+ filterFns.push(searchTextFilter);
36657
+ return filterFns;
36658
+ }
36659
+ };
36660
+ PersonFilter = PersonFilter_1 = __decorate([
36661
+ EntityClass({ typename: 'PersonFilterVO' })
36662
+ ], PersonFilter);
36663
+
36585
36664
  const MessageTypes = {
36586
36665
  INBOX_MESSAGE: 'INBOX_MESSAGE',
36587
36666
  EMAIL: 'EMAIL',
@@ -36614,12 +36693,14 @@ let Message = class Message extends Entity {
36614
36693
  this.type = source.type;
36615
36694
  this.issuer = source.issuer && Person.fromObject(source.issuer);
36616
36695
  this.recipients = source.recipients && source.recipients.map(Person.fromObject);
36696
+ this.recipientFilter = source.recipientFilter && PersonFilter.fromObject(source.recipientFilter) || undefined;
36617
36697
  this.subject = source.subject;
36618
36698
  this.body = source.body;
36619
36699
  }
36620
36700
  asObject(opts) {
36621
36701
  const target = super.asObject(opts);
36622
36702
  target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));
36703
+ target.recipientFilter = this.recipientFilter && this.recipientFilter.asObject(opts) || undefined;
36623
36704
  return target;
36624
36705
  }
36625
36706
  };
@@ -36649,6 +36730,8 @@ class MessageForm extends AppForm {
36649
36730
  this.bodyMaxLength = 2000;
36650
36731
  this.bodyAutoHeight = true;
36651
36732
  this.canSelectType = false;
36733
+ this.canRecipientFilter = false;
36734
+ this.recipientFilterCount = 0;
36652
36735
  this.types = MessageTypeList;
36653
36736
  this.mobile = this.settings.mobile;
36654
36737
  }
@@ -36656,6 +36739,7 @@ class MessageForm extends AppForm {
36656
36739
  this.setForm(this.formBuilder.group({
36657
36740
  type: [MessageTypes.INBOX_MESSAGE, Validators.required],
36658
36741
  recipients: [null, Validators.required],
36742
+ recipientFilter: [null],
36659
36743
  subject: [
36660
36744
  null,
36661
36745
  this.subjectMaxLength
@@ -36664,6 +36748,11 @@ class MessageForm extends AppForm {
36664
36748
  ],
36665
36749
  body: [null, this.bodyMaxLength ? Validators.compose([Validators.maxLength(this.bodyMaxLength)]) : Validators.required],
36666
36750
  }));
36751
+ this.registerSubscription(this._form
36752
+ .get('type')
36753
+ .valueChanges.pipe(filter(isNotNil))
36754
+ .subscribe((type) => this.updateFormGroup(this._form, { type })));
36755
+ // Person combo
36667
36756
  const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name']);
36668
36757
  this.registerAutocompleteField('recipients', {
36669
36758
  showAllOnFocus: false,
@@ -36681,15 +36770,53 @@ class MessageForm extends AppForm {
36681
36770
  isSamePerson(o1, o2) {
36682
36771
  return EntityUtils.equals(o1, o2, 'id');
36683
36772
  }
36773
+ updateFormGroup(formGroup, opts) {
36774
+ console.debug('[message-form] Updating form group...', opts);
36775
+ // Recipient validator
36776
+ const recipientsRequired = toBoolean(opts === null || opts === void 0 ? void 0 : opts.recipientRequired, (opts === null || opts === void 0 ? void 0 : opts.type) !== MessageTypes.FEED);
36777
+ {
36778
+ const control = formGroup.get('recipients');
36779
+ if (recipientsRequired) {
36780
+ if (!control.hasValidator(Validators.required)) {
36781
+ control.addValidators(Validators.required);
36782
+ }
36783
+ control.enable();
36784
+ }
36785
+ else {
36786
+ if (control.hasValidator(Validators.required)) {
36787
+ control.removeValidators(Validators.required);
36788
+ }
36789
+ control.disable();
36790
+ }
36791
+ }
36792
+ // Recipient filter validator
36793
+ const recipientFilterRequired = this.canRecipientFilter && !recipientsRequired;
36794
+ {
36795
+ const control = formGroup.get('recipientFilter');
36796
+ if (recipientFilterRequired) {
36797
+ if (!control.hasValidator(Validators.required)) {
36798
+ control.addValidators(Validators.required);
36799
+ }
36800
+ control.enable();
36801
+ }
36802
+ else {
36803
+ if (control.hasValidator(Validators.required)) {
36804
+ control.removeValidators(Validators.required);
36805
+ }
36806
+ control.disable();
36807
+ }
36808
+ }
36809
+ formGroup.updateValueAndValidity();
36810
+ }
36684
36811
  markForCheck() {
36685
36812
  this.cd.markForCheck();
36686
36813
  }
36687
36814
  }
36688
36815
  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 });
36689
- 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 });
36816
+ 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 });
36690
36817
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, decorators: [{
36691
36818
  type: Component,
36692
- 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"] }]
36819
+ 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"] }]
36693
36820
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36694
36821
  type: Input
36695
36822
  }], subjectMinLength: [{
@@ -36702,6 +36829,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36702
36829
  type: Input
36703
36830
  }], canSelectType: [{
36704
36831
  type: Input
36832
+ }], canRecipientFilter: [{
36833
+ type: Input
36834
+ }], recipientFilterCount: [{
36835
+ type: Input
36705
36836
  }] } });
36706
36837
 
36707
36838
  class MessageModal {
@@ -36774,16 +36905,20 @@ class MessageModal {
36774
36905
  }
36775
36906
  }
36776
36907
  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 });
36777
- 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 });
36908
+ 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 });
36778
36909
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, decorators: [{
36779
36910
  type: Component,
36780
- 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" }]
36911
+ 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" }]
36781
36912
  }], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: i2$1.ModalController }, { type: AccountService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36782
36913
  type: Input
36783
36914
  }], data: [{
36784
36915
  type: Input
36785
36916
  }], canSelectType: [{
36786
36917
  type: Input
36918
+ }], canRecipientFilter: [{
36919
+ type: Input
36920
+ }], recipientFilterCount: [{
36921
+ type: Input
36787
36922
  }], form: [{
36788
36923
  type: ViewChild,
36789
36924
  args: ['form', { static: true }]
@@ -36792,28 +36927,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36792
36927
  class MessageModule {
36793
36928
  }
36794
36929
  MessageModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
36795
- MessageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, declarations: [MessageModal,
36796
- MessageForm], imports: [CommonModule,
36797
- CoreModule,
36798
- SharedModule], exports: [MessageModal] });
36799
- MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule,
36800
- CoreModule,
36801
- SharedModule] });
36930
+ 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] });
36931
+ MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule, CoreModule, SharedModule, MatChipsModule] });
36802
36932
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, decorators: [{
36803
36933
  type: NgModule,
36804
36934
  args: [{
36805
- imports: [
36806
- CommonModule,
36807
- CoreModule,
36808
- SharedModule
36809
- ],
36810
- declarations: [
36811
- MessageModal,
36812
- MessageForm
36813
- ],
36814
- exports: [
36815
- MessageModal
36816
- ]
36935
+ imports: [CommonModule, CoreModule, SharedModule, MatChipsModule],
36936
+ declarations: [MessageModal, MessageForm],
36937
+ exports: [MessageModal],
36817
36938
  }]
36818
36939
  }] });
36819
36940
 
@@ -37300,9 +37421,9 @@ class MessageService extends BaseGraphqlService {
37300
37421
  // On dismiss
37301
37422
  const { data } = yield modal.onDidDismiss();
37302
37423
  if (!data || !(data instanceof Message))
37303
- return; // CANCELLED
37424
+ return true; // CANCELLED
37304
37425
  // Send message
37305
- yield this.send(data, { showToast: options === null || options === void 0 ? void 0 : options.showToast });
37426
+ return yield this.send(data, { showToast: options === null || options === void 0 ? void 0 : options.showToast });
37306
37427
  });
37307
37428
  }
37308
37429
  /* -- protected methods -- */
@@ -37326,59 +37447,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
37326
37447
  }] }];
37327
37448
  } });
37328
37449
 
37329
- var PersonFilter_1;
37330
- // @dynamic
37331
- let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
37332
- constructor() {
37333
- super(PersonFilter_1.TYPENAME);
37334
- }
37335
- static searchFilter(source) {
37336
- return source && PersonFilter_1.fromObject(source).asFilterFn();
37337
- }
37338
- fromObject(source, opts) {
37339
- super.fromObject(source, opts);
37340
- this.email = source.email;
37341
- this.pubkey = source.pubkey;
37342
- this.searchText = source.searchText;
37343
- this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
37344
- this.userProfiles = source.userProfiles;
37345
- this.excludedIds = source.excludedIds;
37346
- this.searchAttribute = source.searchAttribute;
37347
- this.searchAttributes = source.searchAttributes;
37348
- }
37349
- asObject(opts) {
37350
- const target = super.asObject(opts);
37351
- target.email = this.email;
37352
- target.pubkey = this.pubkey;
37353
- target.searchText = this.searchText;
37354
- target.statusIds = this.statusIds;
37355
- target.userProfiles = this.userProfiles;
37356
- target.excludedIds = this.excludedIds;
37357
- target.searchAttribute = this.searchAttribute;
37358
- target.searchAttributes = this.searchAttributes;
37359
- return target;
37360
- }
37361
- buildFilter() {
37362
- const filterFns = super.buildFilter();
37363
- // Filter by status
37364
- if (isNotEmptyArray(this.statusIds)) {
37365
- filterFns.push(e => this.statusIds.includes(e.statusId));
37366
- }
37367
- // Filter excluded ids
37368
- if (isNotEmptyArray(this.excludedIds)) {
37369
- filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
37370
- }
37371
- // Search text
37372
- const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
37373
- if (searchTextFilter)
37374
- filterFns.push(searchTextFilter);
37375
- return filterFns;
37376
- }
37377
- };
37378
- PersonFilter = PersonFilter_1 = __decorate([
37379
- EntityClass({ typename: 'PersonFilterVO' })
37380
- ], PersonFilter);
37381
-
37382
37450
  const PersonFragments = {
37383
37451
  person: gql `
37384
37452
  fragment PersonFragment on PersonVO {
@@ -37715,11 +37783,16 @@ class UsersPage extends AppTable {
37715
37783
  target.department = (_a = p.department) === null || _a === void 0 ? void 0 : _a.asObject();
37716
37784
  return target;
37717
37785
  });
37786
+ const recipientFilter = PersonFilter.fromObject(this.filter);
37787
+ const canRecipientFilter = !recipientFilter.isEmpty() && (this.accountService.isAdmin() || this.accountService.isSupervisor());
37718
37788
  return this.messageService.openComposeModal({
37719
37789
  suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),
37720
- data: {
37790
+ canRecipientFilter,
37791
+ recipientFilterCount: this.totalRowCount,
37792
+ data: Message.fromObject({
37721
37793
  recipients,
37722
- },
37794
+ recipientFilter,
37795
+ }),
37723
37796
  });
37724
37797
  });
37725
37798
  }