@sumaris-net/ngx-components 2.6.16 → 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 (27) 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/menu/menu.component.mjs +10 -6
  4. package/esm2020/src/app/core/menu/menu.service.mjs +7 -1
  5. package/esm2020/src/app/social/message/message.form.mjs +56 -4
  6. package/esm2020/src/app/social/message/message.modal.mjs +7 -3
  7. package/esm2020/src/app/social/message/message.model.mjs +4 -1
  8. package/esm2020/src/app/social/message/message.module.mjs +7 -20
  9. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  10. package/esm2020/src/app/social/user-event/user-event.service.mjs +35 -22
  11. package/fesm2015/sumaris-net.ngx-components.mjs +177 -106
  12. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  13. package/fesm2020/sumaris-net.ngx-components.mjs +176 -106
  14. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  15. package/package.json +1 -1
  16. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -1
  17. package/src/app/core/menu/menu.component.d.ts +6 -2
  18. package/src/app/core/menu/menu.service.d.ts +2 -0
  19. package/src/app/social/message/message.form.d.ts +8 -2
  20. package/src/app/social/message/message.modal.d.ts +5 -1
  21. package/src/app/social/message/message.model.d.ts +2 -0
  22. package/src/app/social/message/message.module.d.ts +2 -1
  23. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  24. package/src/assets/i18n/en-US.json +1 -0
  25. package/src/assets/i18n/en.json +1 -0
  26. package/src/assets/i18n/fr.json +1 -0
  27. 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
  });
@@ -35722,6 +35736,7 @@ class AbstractUserEventService extends BaseGraphqlService {
35722
35736
  this.queries = options.queries;
35723
35737
  this.mutations = options.mutations || {};
35724
35738
  this.subscriptions = options.subscriptions || {};
35739
+ this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
35725
35740
  this._logPrefix = '[user-event-service] ';
35726
35741
  }
35727
35742
  get countSubject() {
@@ -35866,10 +35881,18 @@ class AbstractUserEventService extends BaseGraphqlService {
35866
35881
  return; // Rejected
35867
35882
  const withContent = !!entity.content;
35868
35883
  // Add user event locally
35869
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
35870
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
35871
- data: entity
35872
- });
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
+ }
35873
35896
  // Update count
35874
35897
  this._countSubject.next(this._countSubject.value + 1);
35875
35898
  // Add id
@@ -35992,16 +36015,14 @@ class AbstractUserEventService extends BaseGraphqlService {
35992
36015
  variables: {
35993
36016
  ids
35994
36017
  },
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
- });
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
+ }
36005
36026
  if (this._debug)
36006
36027
  console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
36007
36028
  }
@@ -36031,13 +36052,13 @@ class AbstractUserEventService extends BaseGraphqlService {
36031
36052
  console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
36032
36053
  this.copyIdAndUpdateDate(savedEntity, entity);
36033
36054
  // Add to cache
36034
- if (withContent) {
36035
- this.insertIntoMutableCachedQueries(proxy, {
36036
- query: this.queries.loadAllWithContent,
36037
- data: savedEntity
36038
- });
36039
- }
36040
- else {
36055
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
36056
+ if (withContent) {
36057
+ this.insertIntoMutableCachedQueries(proxy, {
36058
+ query: this.queries.loadAllWithContent,
36059
+ data: savedEntity
36060
+ });
36061
+ }
36041
36062
  this.insertIntoMutableCachedQueries(proxy, {
36042
36063
  query: this.queries.loadAll,
36043
36064
  data: Object.assign(Object.assign({}, savedEntity), { content: null })
@@ -36198,6 +36219,9 @@ class AbstractUserEventService extends BaseGraphqlService {
36198
36219
  copyIdAndUpdateDate(source, target) {
36199
36220
  EntityUtils.copyIdAndUpdateDate(source, target);
36200
36221
  }
36222
+ getLoadQueries() {
36223
+ return [this.queries.loadAll, this.queries.loadAllWithContent].filter(isNotNil);
36224
+ }
36201
36225
  }
36202
36226
  AbstractUserEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AbstractUserEventService, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
36203
36227
  AbstractUserEventService.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: AbstractUserEventService, usesInheritance: true, ngImport: i0 });
@@ -36584,6 +36608,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36584
36608
  }]
36585
36609
  }] });
36586
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
+
36587
36664
  const MessageTypes = {
36588
36665
  INBOX_MESSAGE: 'INBOX_MESSAGE',
36589
36666
  EMAIL: 'EMAIL',
@@ -36616,12 +36693,14 @@ let Message = class Message extends Entity {
36616
36693
  this.type = source.type;
36617
36694
  this.issuer = source.issuer && Person.fromObject(source.issuer);
36618
36695
  this.recipients = source.recipients && source.recipients.map(Person.fromObject);
36696
+ this.recipientFilter = source.recipientFilter && PersonFilter.fromObject(source.recipientFilter) || undefined;
36619
36697
  this.subject = source.subject;
36620
36698
  this.body = source.body;
36621
36699
  }
36622
36700
  asObject(opts) {
36623
36701
  const target = super.asObject(opts);
36624
36702
  target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));
36703
+ target.recipientFilter = this.recipientFilter && this.recipientFilter.asObject(opts) || undefined;
36625
36704
  return target;
36626
36705
  }
36627
36706
  };
@@ -36651,6 +36730,8 @@ class MessageForm extends AppForm {
36651
36730
  this.bodyMaxLength = 2000;
36652
36731
  this.bodyAutoHeight = true;
36653
36732
  this.canSelectType = false;
36733
+ this.canRecipientFilter = false;
36734
+ this.recipientFilterCount = 0;
36654
36735
  this.types = MessageTypeList;
36655
36736
  this.mobile = this.settings.mobile;
36656
36737
  }
@@ -36658,6 +36739,7 @@ class MessageForm extends AppForm {
36658
36739
  this.setForm(this.formBuilder.group({
36659
36740
  type: [MessageTypes.INBOX_MESSAGE, Validators.required],
36660
36741
  recipients: [null, Validators.required],
36742
+ recipientFilter: [null],
36661
36743
  subject: [
36662
36744
  null,
36663
36745
  this.subjectMaxLength
@@ -36666,6 +36748,11 @@ class MessageForm extends AppForm {
36666
36748
  ],
36667
36749
  body: [null, this.bodyMaxLength ? Validators.compose([Validators.maxLength(this.bodyMaxLength)]) : Validators.required],
36668
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
36669
36756
  const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name']);
36670
36757
  this.registerAutocompleteField('recipients', {
36671
36758
  showAllOnFocus: false,
@@ -36683,15 +36770,53 @@ class MessageForm extends AppForm {
36683
36770
  isSamePerson(o1, o2) {
36684
36771
  return EntityUtils.equals(o1, o2, 'id');
36685
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
+ }
36686
36811
  markForCheck() {
36687
36812
  this.cd.markForCheck();
36688
36813
  }
36689
36814
  }
36690
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 });
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 });
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 });
36692
36817
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, decorators: [{
36693
36818
  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"] }]
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"] }]
36695
36820
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36696
36821
  type: Input
36697
36822
  }], subjectMinLength: [{
@@ -36704,6 +36829,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36704
36829
  type: Input
36705
36830
  }], canSelectType: [{
36706
36831
  type: Input
36832
+ }], canRecipientFilter: [{
36833
+ type: Input
36834
+ }], recipientFilterCount: [{
36835
+ type: Input
36707
36836
  }] } });
36708
36837
 
36709
36838
  class MessageModal {
@@ -36776,16 +36905,20 @@ class MessageModal {
36776
36905
  }
36777
36906
  }
36778
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 });
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 });
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 });
36780
36909
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, decorators: [{
36781
36910
  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" }]
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" }]
36783
36912
  }], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: i2$1.ModalController }, { type: AccountService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
36784
36913
  type: Input
36785
36914
  }], data: [{
36786
36915
  type: Input
36787
36916
  }], canSelectType: [{
36788
36917
  type: Input
36918
+ }], canRecipientFilter: [{
36919
+ type: Input
36920
+ }], recipientFilterCount: [{
36921
+ type: Input
36789
36922
  }], form: [{
36790
36923
  type: ViewChild,
36791
36924
  args: ['form', { static: true }]
@@ -36794,28 +36927,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36794
36927
  class MessageModule {
36795
36928
  }
36796
36929
  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] });
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] });
36804
36932
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, decorators: [{
36805
36933
  type: NgModule,
36806
36934
  args: [{
36807
- imports: [
36808
- CommonModule,
36809
- CoreModule,
36810
- SharedModule
36811
- ],
36812
- declarations: [
36813
- MessageModal,
36814
- MessageForm
36815
- ],
36816
- exports: [
36817
- MessageModal
36818
- ]
36935
+ imports: [CommonModule, CoreModule, SharedModule, MatChipsModule],
36936
+ declarations: [MessageModal, MessageForm],
36937
+ exports: [MessageModal],
36819
36938
  }]
36820
36939
  }] });
36821
36940
 
@@ -37302,9 +37421,9 @@ class MessageService extends BaseGraphqlService {
37302
37421
  // On dismiss
37303
37422
  const { data } = yield modal.onDidDismiss();
37304
37423
  if (!data || !(data instanceof Message))
37305
- return; // CANCELLED
37424
+ return true; // CANCELLED
37306
37425
  // Send message
37307
- 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 });
37308
37427
  });
37309
37428
  }
37310
37429
  /* -- protected methods -- */
@@ -37328,59 +37447,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
37328
37447
  }] }];
37329
37448
  } });
37330
37449
 
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
37450
  const PersonFragments = {
37385
37451
  person: gql `
37386
37452
  fragment PersonFragment on PersonVO {
@@ -37717,11 +37783,16 @@ class UsersPage extends AppTable {
37717
37783
  target.department = (_a = p.department) === null || _a === void 0 ? void 0 : _a.asObject();
37718
37784
  return target;
37719
37785
  });
37786
+ const recipientFilter = PersonFilter.fromObject(this.filter);
37787
+ const canRecipientFilter = !recipientFilter.isEmpty() && (this.accountService.isAdmin() || this.accountService.isSupervisor());
37720
37788
  return this.messageService.openComposeModal({
37721
37789
  suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),
37722
- data: {
37790
+ canRecipientFilter,
37791
+ recipientFilterCount: this.totalRowCount,
37792
+ data: Message.fromObject({
37723
37793
  recipients,
37724
- },
37794
+ recipientFilter,
37795
+ }),
37725
37796
  });
37726
37797
  });
37727
37798
  }