@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
@@ -24510,6 +24510,12 @@ class MenuService extends StartableObservableService {
24510
24510
  _markAsClosed() {
24511
24511
  this._$opened.next(false);
24512
24512
  }
24513
+ async close() {
24514
+ this._$opened.next(false);
24515
+ }
24516
+ async open() {
24517
+ this._$opened.next(true);
24518
+ }
24513
24519
  async ngOnStart() {
24514
24520
  console.info(`${this._logPrefix}Starting...`);
24515
24521
  // Restore sub items from settings
@@ -24906,7 +24912,7 @@ class MenuComponent {
24906
24912
  this._subscription.add(this.menuService.opened
24907
24913
  // Avoid duplicated events
24908
24914
  .pipe(distinctUntilChanged())
24909
- .subscribe((value) => (value ? this.open() : this.close())));
24915
+ .subscribe((value) => (value ? this.open({ emitEvent: false }) : this.close({ emitEvent: false }))));
24910
24916
  // TODO : Find a more reliable way to do this :
24911
24917
  // Must be donne after menuService subscription :
24912
24918
  // - In MenuService.ngOnStart accountChanges change will be emitted before the service is ready
@@ -24956,25 +24962,29 @@ class MenuComponent {
24956
24962
  await this.close();
24957
24963
  }
24958
24964
  }
24959
- async open() {
24965
+ async open(opts) {
24960
24966
  console.debug('[menu] Checking open event...');
24961
24967
  const opened = await this.menu.isOpen(this.menuId);
24962
24968
  if (!opened) {
24963
24969
  console.debug('[menu] Opening menu');
24964
24970
  await this.menu.open(this.menuId);
24965
24971
  // Propagate to service
24966
- this.menuService._markAsOpened();
24972
+ if (!opts || opts.emitEvent !== false) {
24973
+ this.menuService._markAsOpened();
24974
+ }
24967
24975
  }
24968
24976
  return true;
24969
24977
  }
24970
- async close() {
24978
+ async close(opts) {
24971
24979
  console.debug('[menu] Checking close event...');
24972
24980
  const opened = await this.menu.isOpen(this.menuId);
24973
24981
  if (opened) {
24974
24982
  console.debug('[menu] Closing menu');
24975
24983
  await this.menu.close(this.menuId);
24976
24984
  // Propagate to service
24977
- this.menuService._markAsClosed();
24985
+ if (!opts || opts.emitEvent !== false) {
24986
+ this.menuService._markAsClosed();
24987
+ }
24978
24988
  }
24979
24989
  return true;
24980
24990
  }
@@ -34897,6 +34907,7 @@ class AbstractUserEventService extends BaseGraphqlService {
34897
34907
  this.queries = options.queries;
34898
34908
  this.mutations = options.mutations || {};
34899
34909
  this.subscriptions = options.subscriptions || {};
34910
+ this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
34900
34911
  this._logPrefix = '[user-event-service] ';
34901
34912
  }
34902
34913
  get countSubject() {
@@ -35038,10 +35049,21 @@ class AbstractUserEventService extends BaseGraphqlService {
35038
35049
  return; // Rejected
35039
35050
  const withContent = !!entity.content;
35040
35051
  // Add user event locally
35041
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
35042
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
35043
- data: entity
35044
- });
35052
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35053
+ if (withContent) {
35054
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35055
+ query: this.queries.loadAllWithContent,
35056
+ data: entity
35057
+ });
35058
+ }
35059
+ this.insertIntoMutableCachedQueries(this.graphql.cache, {
35060
+ query: this.queries.loadAll,
35061
+ data: {
35062
+ ...entity,
35063
+ content: null
35064
+ }
35065
+ });
35066
+ }
35045
35067
  // Update count
35046
35068
  this._countSubject.next(this._countSubject.value + 1);
35047
35069
  // Add id
@@ -35155,16 +35177,14 @@ class AbstractUserEventService extends BaseGraphqlService {
35155
35177
  variables: {
35156
35178
  ids
35157
35179
  },
35158
- update: (proxy) => {
35159
- // Remove from caches
35160
- this.removeFromMutableCachedQueriesByIds(proxy, {
35161
- query: this.queries.loadAll,
35162
- ids
35163
- });
35164
- this.removeFromMutableCachedQueriesByIds(proxy, {
35165
- query: this.queries.loadAllWithContent,
35166
- ids
35167
- });
35180
+ update: (cache) => {
35181
+ // Remove from cache
35182
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35183
+ this.removeFromMutableCachedQueriesByIds(cache, {
35184
+ queries: this.getLoadQueries(),
35185
+ ids
35186
+ });
35187
+ }
35168
35188
  if (this._debug)
35169
35189
  console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
35170
35190
  }
@@ -35192,13 +35212,13 @@ class AbstractUserEventService extends BaseGraphqlService {
35192
35212
  console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
35193
35213
  this.copyIdAndUpdateDate(savedEntity, entity);
35194
35214
  // Add to cache
35195
- if (withContent) {
35196
- this.insertIntoMutableCachedQueries(proxy, {
35197
- query: this.queries.loadAllWithContent,
35198
- data: savedEntity
35199
- });
35200
- }
35201
- else {
35215
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35216
+ if (withContent) {
35217
+ this.insertIntoMutableCachedQueries(proxy, {
35218
+ query: this.queries.loadAllWithContent,
35219
+ data: savedEntity
35220
+ });
35221
+ }
35202
35222
  this.insertIntoMutableCachedQueries(proxy, {
35203
35223
  query: this.queries.loadAll,
35204
35224
  data: {
@@ -35349,6 +35369,9 @@ class AbstractUserEventService extends BaseGraphqlService {
35349
35369
  copyIdAndUpdateDate(source, target) {
35350
35370
  EntityUtils.copyIdAndUpdateDate(source, target);
35351
35371
  }
35372
+ getLoadQueries() {
35373
+ return [this.queries.loadAll, this.queries.loadAllWithContent].filter(isNotNil);
35374
+ }
35352
35375
  }
35353
35376
  AbstractUserEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AbstractUserEventService, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
35354
35377
  AbstractUserEventService.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: AbstractUserEventService, usesInheritance: true, ngImport: i0 });
@@ -35714,6 +35737,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35714
35737
  }]
35715
35738
  }] });
35716
35739
 
35740
+ var PersonFilter_1;
35741
+ // @dynamic
35742
+ let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
35743
+ constructor() {
35744
+ super(PersonFilter_1.TYPENAME);
35745
+ }
35746
+ static searchFilter(source) {
35747
+ return source && PersonFilter_1.fromObject(source).asFilterFn();
35748
+ }
35749
+ fromObject(source, opts) {
35750
+ super.fromObject(source, opts);
35751
+ this.email = source.email;
35752
+ this.pubkey = source.pubkey;
35753
+ this.searchText = source.searchText;
35754
+ this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
35755
+ this.userProfiles = source.userProfiles;
35756
+ this.excludedIds = source.excludedIds;
35757
+ this.searchAttribute = source.searchAttribute;
35758
+ this.searchAttributes = source.searchAttributes;
35759
+ }
35760
+ asObject(opts) {
35761
+ const target = super.asObject(opts);
35762
+ target.email = this.email;
35763
+ target.pubkey = this.pubkey;
35764
+ target.searchText = this.searchText;
35765
+ target.statusIds = this.statusIds;
35766
+ target.userProfiles = this.userProfiles;
35767
+ target.excludedIds = this.excludedIds;
35768
+ target.searchAttribute = this.searchAttribute;
35769
+ target.searchAttributes = this.searchAttributes;
35770
+ return target;
35771
+ }
35772
+ buildFilter() {
35773
+ const filterFns = super.buildFilter();
35774
+ // Filter by status
35775
+ if (isNotEmptyArray(this.statusIds)) {
35776
+ filterFns.push(e => this.statusIds.includes(e.statusId));
35777
+ }
35778
+ // Filter excluded ids
35779
+ if (isNotEmptyArray(this.excludedIds)) {
35780
+ filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
35781
+ }
35782
+ // Search text
35783
+ const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
35784
+ if (searchTextFilter)
35785
+ filterFns.push(searchTextFilter);
35786
+ return filterFns;
35787
+ }
35788
+ };
35789
+ PersonFilter = PersonFilter_1 = __decorate([
35790
+ EntityClass({ typename: 'PersonFilterVO' })
35791
+ ], PersonFilter);
35792
+
35717
35793
  const MessageTypes = {
35718
35794
  INBOX_MESSAGE: 'INBOX_MESSAGE',
35719
35795
  EMAIL: 'EMAIL',
@@ -35746,12 +35822,14 @@ let Message = class Message extends Entity {
35746
35822
  this.type = source.type;
35747
35823
  this.issuer = source.issuer && Person.fromObject(source.issuer);
35748
35824
  this.recipients = source.recipients && source.recipients.map(Person.fromObject);
35825
+ this.recipientFilter = source.recipientFilter && PersonFilter.fromObject(source.recipientFilter) || undefined;
35749
35826
  this.subject = source.subject;
35750
35827
  this.body = source.body;
35751
35828
  }
35752
35829
  asObject(opts) {
35753
35830
  const target = super.asObject(opts);
35754
35831
  target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));
35832
+ target.recipientFilter = this.recipientFilter && this.recipientFilter.asObject(opts) || undefined;
35755
35833
  return target;
35756
35834
  }
35757
35835
  };
@@ -35781,6 +35859,8 @@ class MessageForm extends AppForm {
35781
35859
  this.bodyMaxLength = 2000;
35782
35860
  this.bodyAutoHeight = true;
35783
35861
  this.canSelectType = false;
35862
+ this.canRecipientFilter = false;
35863
+ this.recipientFilterCount = 0;
35784
35864
  this.types = MessageTypeList;
35785
35865
  this.mobile = this.settings.mobile;
35786
35866
  }
@@ -35788,6 +35868,7 @@ class MessageForm extends AppForm {
35788
35868
  this.setForm(this.formBuilder.group({
35789
35869
  type: [MessageTypes.INBOX_MESSAGE, Validators.required],
35790
35870
  recipients: [null, Validators.required],
35871
+ recipientFilter: [null],
35791
35872
  subject: [
35792
35873
  null,
35793
35874
  this.subjectMaxLength
@@ -35796,6 +35877,11 @@ class MessageForm extends AppForm {
35796
35877
  ],
35797
35878
  body: [null, this.bodyMaxLength ? Validators.compose([Validators.maxLength(this.bodyMaxLength)]) : Validators.required],
35798
35879
  }));
35880
+ this.registerSubscription(this._form
35881
+ .get('type')
35882
+ .valueChanges.pipe(filter(isNotNil))
35883
+ .subscribe((type) => this.updateFormGroup(this._form, { type })));
35884
+ // Person combo
35799
35885
  const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name']);
35800
35886
  this.registerAutocompleteField('recipients', {
35801
35887
  showAllOnFocus: false,
@@ -35813,15 +35899,53 @@ class MessageForm extends AppForm {
35813
35899
  isSamePerson(o1, o2) {
35814
35900
  return EntityUtils.equals(o1, o2, 'id');
35815
35901
  }
35902
+ updateFormGroup(formGroup, opts) {
35903
+ console.debug('[message-form] Updating form group...', opts);
35904
+ // Recipient validator
35905
+ const recipientsRequired = toBoolean(opts?.recipientRequired, opts?.type !== MessageTypes.FEED);
35906
+ {
35907
+ const control = formGroup.get('recipients');
35908
+ if (recipientsRequired) {
35909
+ if (!control.hasValidator(Validators.required)) {
35910
+ control.addValidators(Validators.required);
35911
+ }
35912
+ control.enable();
35913
+ }
35914
+ else {
35915
+ if (control.hasValidator(Validators.required)) {
35916
+ control.removeValidators(Validators.required);
35917
+ }
35918
+ control.disable();
35919
+ }
35920
+ }
35921
+ // Recipient filter validator
35922
+ const recipientFilterRequired = this.canRecipientFilter && !recipientsRequired;
35923
+ {
35924
+ const control = formGroup.get('recipientFilter');
35925
+ if (recipientFilterRequired) {
35926
+ if (!control.hasValidator(Validators.required)) {
35927
+ control.addValidators(Validators.required);
35928
+ }
35929
+ control.enable();
35930
+ }
35931
+ else {
35932
+ if (control.hasValidator(Validators.required)) {
35933
+ control.removeValidators(Validators.required);
35934
+ }
35935
+ control.disable();
35936
+ }
35937
+ }
35938
+ formGroup.updateValueAndValidity();
35939
+ }
35816
35940
  markForCheck() {
35817
35941
  this.cd.markForCheck();
35818
35942
  }
35819
35943
  }
35820
35944
  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 });
35821
- 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 });
35945
+ 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 });
35822
35946
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, decorators: [{
35823
35947
  type: Component,
35824
- 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"] }]
35948
+ 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"] }]
35825
35949
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
35826
35950
  type: Input
35827
35951
  }], subjectMinLength: [{
@@ -35834,6 +35958,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35834
35958
  type: Input
35835
35959
  }], canSelectType: [{
35836
35960
  type: Input
35961
+ }], canRecipientFilter: [{
35962
+ type: Input
35963
+ }], recipientFilterCount: [{
35964
+ type: Input
35837
35965
  }] } });
35838
35966
 
35839
35967
  class MessageModal {
@@ -35904,16 +36032,20 @@ class MessageModal {
35904
36032
  }
35905
36033
  }
35906
36034
  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 });
35907
- 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 });
36035
+ 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 });
35908
36036
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, decorators: [{
35909
36037
  type: Component,
35910
- 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" }]
36038
+ 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" }]
35911
36039
  }], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: i2$1.ModalController }, { type: AccountService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
35912
36040
  type: Input
35913
36041
  }], data: [{
35914
36042
  type: Input
35915
36043
  }], canSelectType: [{
35916
36044
  type: Input
36045
+ }], canRecipientFilter: [{
36046
+ type: Input
36047
+ }], recipientFilterCount: [{
36048
+ type: Input
35917
36049
  }], form: [{
35918
36050
  type: ViewChild,
35919
36051
  args: ['form', { static: true }]
@@ -35922,28 +36054,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35922
36054
  class MessageModule {
35923
36055
  }
35924
36056
  MessageModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
35925
- MessageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, declarations: [MessageModal,
35926
- MessageForm], imports: [CommonModule,
35927
- CoreModule,
35928
- SharedModule], exports: [MessageModal] });
35929
- MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule,
35930
- CoreModule,
35931
- SharedModule] });
36057
+ 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] });
36058
+ MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule, CoreModule, SharedModule, MatChipsModule] });
35932
36059
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, decorators: [{
35933
36060
  type: NgModule,
35934
36061
  args: [{
35935
- imports: [
35936
- CommonModule,
35937
- CoreModule,
35938
- SharedModule
35939
- ],
35940
- declarations: [
35941
- MessageModal,
35942
- MessageForm
35943
- ],
35944
- exports: [
35945
- MessageModal
35946
- ]
36062
+ imports: [CommonModule, CoreModule, SharedModule, MatChipsModule],
36063
+ declarations: [MessageModal, MessageForm],
36064
+ exports: [MessageModal],
35947
36065
  }]
35948
36066
  }] });
35949
36067
 
@@ -36417,9 +36535,9 @@ class MessageService extends BaseGraphqlService {
36417
36535
  // On dismiss
36418
36536
  const { data } = await modal.onDidDismiss();
36419
36537
  if (!data || !(data instanceof Message))
36420
- return; // CANCELLED
36538
+ return true; // CANCELLED
36421
36539
  // Send message
36422
- await this.send(data, { showToast: options?.showToast });
36540
+ return await this.send(data, { showToast: options?.showToast });
36423
36541
  }
36424
36542
  /* -- protected methods -- */
36425
36543
  async showToast(opts) {
@@ -36442,59 +36560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36442
36560
  args: [ENVIRONMENT]
36443
36561
  }] }]; } });
36444
36562
 
36445
- var PersonFilter_1;
36446
- // @dynamic
36447
- let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
36448
- constructor() {
36449
- super(PersonFilter_1.TYPENAME);
36450
- }
36451
- static searchFilter(source) {
36452
- return source && PersonFilter_1.fromObject(source).asFilterFn();
36453
- }
36454
- fromObject(source, opts) {
36455
- super.fromObject(source, opts);
36456
- this.email = source.email;
36457
- this.pubkey = source.pubkey;
36458
- this.searchText = source.searchText;
36459
- this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
36460
- this.userProfiles = source.userProfiles;
36461
- this.excludedIds = source.excludedIds;
36462
- this.searchAttribute = source.searchAttribute;
36463
- this.searchAttributes = source.searchAttributes;
36464
- }
36465
- asObject(opts) {
36466
- const target = super.asObject(opts);
36467
- target.email = this.email;
36468
- target.pubkey = this.pubkey;
36469
- target.searchText = this.searchText;
36470
- target.statusIds = this.statusIds;
36471
- target.userProfiles = this.userProfiles;
36472
- target.excludedIds = this.excludedIds;
36473
- target.searchAttribute = this.searchAttribute;
36474
- target.searchAttributes = this.searchAttributes;
36475
- return target;
36476
- }
36477
- buildFilter() {
36478
- const filterFns = super.buildFilter();
36479
- // Filter by status
36480
- if (isNotEmptyArray(this.statusIds)) {
36481
- filterFns.push(e => this.statusIds.includes(e.statusId));
36482
- }
36483
- // Filter excluded ids
36484
- if (isNotEmptyArray(this.excludedIds)) {
36485
- filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
36486
- }
36487
- // Search text
36488
- const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
36489
- if (searchTextFilter)
36490
- filterFns.push(searchTextFilter);
36491
- return filterFns;
36492
- }
36493
- };
36494
- PersonFilter = PersonFilter_1 = __decorate([
36495
- EntityClass({ typename: 'PersonFilterVO' })
36496
- ], PersonFilter);
36497
-
36498
36563
  const PersonFragments = {
36499
36564
  person: gql `
36500
36565
  fragment PersonFragment on PersonVO {
@@ -36820,11 +36885,16 @@ class UsersPage extends AppTable {
36820
36885
  target.department = p.department?.asObject();
36821
36886
  return target;
36822
36887
  });
36888
+ const recipientFilter = PersonFilter.fromObject(this.filter);
36889
+ const canRecipientFilter = !recipientFilter.isEmpty() && (this.accountService.isAdmin() || this.accountService.isSupervisor());
36823
36890
  return this.messageService.openComposeModal({
36824
36891
  suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),
36825
- data: {
36892
+ canRecipientFilter,
36893
+ recipientFilterCount: this.totalRowCount,
36894
+ data: Message.fromObject({
36826
36895
  recipients,
36827
- },
36896
+ recipientFilter,
36897
+ }),
36828
36898
  });
36829
36899
  }
36830
36900
  /* -- protected methods -- */