@sumaris-net/ngx-components 2.6.15 → 2.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/esm2020/src/app/admin/users/users.mjs +9 -3
  2. package/esm2020/src/app/core/form/buttons/form-buttons-bar.component.mjs +1 -1
  3. package/esm2020/src/app/core/form/entity/editor.class.mjs +5 -2
  4. package/esm2020/src/app/core/menu/menu.component.mjs +10 -6
  5. package/esm2020/src/app/core/menu/menu.service.mjs +7 -1
  6. package/esm2020/src/app/social/message/message.form.mjs +56 -4
  7. package/esm2020/src/app/social/message/message.modal.mjs +7 -3
  8. package/esm2020/src/app/social/message/message.model.mjs +4 -1
  9. package/esm2020/src/app/social/message/message.module.mjs +7 -20
  10. package/esm2020/src/app/social/message/message.service.mjs +3 -3
  11. package/esm2020/src/app/social/user-event/user-event.service.mjs +35 -22
  12. package/fesm2015/sumaris-net.ngx-components.mjs +180 -107
  13. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  14. package/fesm2020/sumaris-net.ngx-components.mjs +179 -107
  15. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -1
  18. package/src/app/core/menu/menu.component.d.ts +6 -2
  19. package/src/app/core/menu/menu.service.d.ts +2 -0
  20. package/src/app/social/message/message.form.d.ts +8 -2
  21. package/src/app/social/message/message.modal.d.ts +5 -1
  22. package/src/app/social/message/message.model.d.ts +2 -0
  23. package/src/app/social/message/message.module.d.ts +2 -1
  24. package/src/app/social/user-event/user-event.service.d.ts +5 -0
  25. package/src/assets/i18n/en-US.json +1 -0
  26. package/src/assets/i18n/en.json +1 -0
  27. package/src/assets/i18n/fr.json +1 -0
  28. package/src/assets/manifest.json +1 -1
@@ -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
  }
@@ -30437,7 +30447,9 @@ class AppEditor {
30437
30447
  }
30438
30448
  ngOnInit() {
30439
30449
  if (this.formButtonsBar) {
30440
- this.registerSubscription(this.formButtonsBar.onBack.subscribe(event => this.goBack(event)));
30450
+ this.registerSubscription(this.formButtonsBar.onBack
30451
+ .pipe(throttleTime(200)) // Avoid to be called twice
30452
+ .subscribe(event => this.goBack(event)));
30441
30453
  }
30442
30454
  }
30443
30455
  ngAfterViewInit() {
@@ -34895,6 +34907,7 @@ class AbstractUserEventService extends BaseGraphqlService {
34895
34907
  this.queries = options.queries;
34896
34908
  this.mutations = options.mutations || {};
34897
34909
  this.subscriptions = options.subscriptions || {};
34910
+ this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
34898
34911
  this._logPrefix = '[user-event-service] ';
34899
34912
  }
34900
34913
  get countSubject() {
@@ -35036,10 +35049,21 @@ class AbstractUserEventService extends BaseGraphqlService {
35036
35049
  return; // Rejected
35037
35050
  const withContent = !!entity.content;
35038
35051
  // Add user event locally
35039
- this.insertIntoMutableCachedQueries(this.graphql.cache, {
35040
- query: withContent ? this.queries.loadAllWithContent : this.queries.loadAll,
35041
- data: entity
35042
- });
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
+ }
35043
35067
  // Update count
35044
35068
  this._countSubject.next(this._countSubject.value + 1);
35045
35069
  // Add id
@@ -35153,16 +35177,14 @@ class AbstractUserEventService extends BaseGraphqlService {
35153
35177
  variables: {
35154
35178
  ids
35155
35179
  },
35156
- update: (proxy) => {
35157
- // Remove from caches
35158
- this.removeFromMutableCachedQueriesByIds(proxy, {
35159
- query: this.queries.loadAll,
35160
- ids
35161
- });
35162
- this.removeFromMutableCachedQueriesByIds(proxy, {
35163
- query: this.queries.loadAllWithContent,
35164
- ids
35165
- });
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
+ }
35166
35188
  if (this._debug)
35167
35189
  console.debug(`${this._logPrefix}Events deleted in ${Date.now() - now}ms`);
35168
35190
  }
@@ -35190,13 +35212,13 @@ class AbstractUserEventService extends BaseGraphqlService {
35190
35212
  console.debug(`${this._logPrefix}User event saved in ${Date.now() - now}ms`, entity);
35191
35213
  this.copyIdAndUpdateDate(savedEntity, entity);
35192
35214
  // Add to cache
35193
- if (withContent) {
35194
- this.insertIntoMutableCachedQueries(proxy, {
35195
- query: this.queries.loadAllWithContent,
35196
- data: savedEntity
35197
- });
35198
- }
35199
- else {
35215
+ if (this.watchQueriesUpdatePolicy === 'update-cache') {
35216
+ if (withContent) {
35217
+ this.insertIntoMutableCachedQueries(proxy, {
35218
+ query: this.queries.loadAllWithContent,
35219
+ data: savedEntity
35220
+ });
35221
+ }
35200
35222
  this.insertIntoMutableCachedQueries(proxy, {
35201
35223
  query: this.queries.loadAll,
35202
35224
  data: {
@@ -35347,6 +35369,9 @@ class AbstractUserEventService extends BaseGraphqlService {
35347
35369
  copyIdAndUpdateDate(source, target) {
35348
35370
  EntityUtils.copyIdAndUpdateDate(source, target);
35349
35371
  }
35372
+ getLoadQueries() {
35373
+ return [this.queries.loadAll, this.queries.loadAllWithContent].filter(isNotNil);
35374
+ }
35350
35375
  }
35351
35376
  AbstractUserEventService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AbstractUserEventService, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
35352
35377
  AbstractUserEventService.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: AbstractUserEventService, usesInheritance: true, ngImport: i0 });
@@ -35712,6 +35737,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35712
35737
  }]
35713
35738
  }] });
35714
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
+
35715
35793
  const MessageTypes = {
35716
35794
  INBOX_MESSAGE: 'INBOX_MESSAGE',
35717
35795
  EMAIL: 'EMAIL',
@@ -35744,12 +35822,14 @@ let Message = class Message extends Entity {
35744
35822
  this.type = source.type;
35745
35823
  this.issuer = source.issuer && Person.fromObject(source.issuer);
35746
35824
  this.recipients = source.recipients && source.recipients.map(Person.fromObject);
35825
+ this.recipientFilter = source.recipientFilter && PersonFilter.fromObject(source.recipientFilter) || undefined;
35747
35826
  this.subject = source.subject;
35748
35827
  this.body = source.body;
35749
35828
  }
35750
35829
  asObject(opts) {
35751
35830
  const target = super.asObject(opts);
35752
35831
  target.recipients = this.recipients && this.recipients.map(p => p.asObject(opts));
35832
+ target.recipientFilter = this.recipientFilter && this.recipientFilter.asObject(opts) || undefined;
35753
35833
  return target;
35754
35834
  }
35755
35835
  };
@@ -35779,6 +35859,8 @@ class MessageForm extends AppForm {
35779
35859
  this.bodyMaxLength = 2000;
35780
35860
  this.bodyAutoHeight = true;
35781
35861
  this.canSelectType = false;
35862
+ this.canRecipientFilter = false;
35863
+ this.recipientFilterCount = 0;
35782
35864
  this.types = MessageTypeList;
35783
35865
  this.mobile = this.settings.mobile;
35784
35866
  }
@@ -35786,6 +35868,7 @@ class MessageForm extends AppForm {
35786
35868
  this.setForm(this.formBuilder.group({
35787
35869
  type: [MessageTypes.INBOX_MESSAGE, Validators.required],
35788
35870
  recipients: [null, Validators.required],
35871
+ recipientFilter: [null],
35789
35872
  subject: [
35790
35873
  null,
35791
35874
  this.subjectMaxLength
@@ -35794,6 +35877,11 @@ class MessageForm extends AppForm {
35794
35877
  ],
35795
35878
  body: [null, this.bodyMaxLength ? Validators.compose([Validators.maxLength(this.bodyMaxLength)]) : Validators.required],
35796
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
35797
35885
  const personAttributes = this.settings.getFieldDisplayAttributes('person', ['lastName', 'firstName', 'department.name']);
35798
35886
  this.registerAutocompleteField('recipients', {
35799
35887
  showAllOnFocus: false,
@@ -35811,15 +35899,53 @@ class MessageForm extends AppForm {
35811
35899
  isSamePerson(o1, o2) {
35812
35900
  return EntityUtils.equals(o1, o2, 'id');
35813
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
+ }
35814
35940
  markForCheck() {
35815
35941
  this.cd.markForCheck();
35816
35942
  }
35817
35943
  }
35818
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 });
35819
- 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 });
35820
35946
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageForm, decorators: [{
35821
35947
  type: Component,
35822
- 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"] }]
35823
35949
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1$2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
35824
35950
  type: Input
35825
35951
  }], subjectMinLength: [{
@@ -35832,6 +35958,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35832
35958
  type: Input
35833
35959
  }], canSelectType: [{
35834
35960
  type: Input
35961
+ }], canRecipientFilter: [{
35962
+ type: Input
35963
+ }], recipientFilterCount: [{
35964
+ type: Input
35835
35965
  }] } });
35836
35966
 
35837
35967
  class MessageModal {
@@ -35902,16 +36032,20 @@ class MessageModal {
35902
36032
  }
35903
36033
  }
35904
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 });
35905
- 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 });
35906
36036
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModal, decorators: [{
35907
36037
  type: Component,
35908
- 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" }]
35909
36039
  }], ctorParameters: function () { return [{ type: LocalSettingsService }, { type: i2$1.ModalController }, { type: AccountService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { suggestFn: [{
35910
36040
  type: Input
35911
36041
  }], data: [{
35912
36042
  type: Input
35913
36043
  }], canSelectType: [{
35914
36044
  type: Input
36045
+ }], canRecipientFilter: [{
36046
+ type: Input
36047
+ }], recipientFilterCount: [{
36048
+ type: Input
35915
36049
  }], form: [{
35916
36050
  type: ViewChild,
35917
36051
  args: ['form', { static: true }]
@@ -35920,28 +36054,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
35920
36054
  class MessageModule {
35921
36055
  }
35922
36056
  MessageModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
35923
- MessageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, declarations: [MessageModal,
35924
- MessageForm], imports: [CommonModule,
35925
- CoreModule,
35926
- SharedModule], exports: [MessageModal] });
35927
- MessageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, imports: [CommonModule,
35928
- CoreModule,
35929
- 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] });
35930
36059
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MessageModule, decorators: [{
35931
36060
  type: NgModule,
35932
36061
  args: [{
35933
- imports: [
35934
- CommonModule,
35935
- CoreModule,
35936
- SharedModule
35937
- ],
35938
- declarations: [
35939
- MessageModal,
35940
- MessageForm
35941
- ],
35942
- exports: [
35943
- MessageModal
35944
- ]
36062
+ imports: [CommonModule, CoreModule, SharedModule, MatChipsModule],
36063
+ declarations: [MessageModal, MessageForm],
36064
+ exports: [MessageModal],
35945
36065
  }]
35946
36066
  }] });
35947
36067
 
@@ -36415,9 +36535,9 @@ class MessageService extends BaseGraphqlService {
36415
36535
  // On dismiss
36416
36536
  const { data } = await modal.onDidDismiss();
36417
36537
  if (!data || !(data instanceof Message))
36418
- return; // CANCELLED
36538
+ return true; // CANCELLED
36419
36539
  // Send message
36420
- await this.send(data, { showToast: options?.showToast });
36540
+ return await this.send(data, { showToast: options?.showToast });
36421
36541
  }
36422
36542
  /* -- protected methods -- */
36423
36543
  async showToast(opts) {
@@ -36440,59 +36560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
36440
36560
  args: [ENVIRONMENT]
36441
36561
  }] }]; } });
36442
36562
 
36443
- var PersonFilter_1;
36444
- // @dynamic
36445
- let PersonFilter = PersonFilter_1 = class PersonFilter extends EntityFilter {
36446
- constructor() {
36447
- super(PersonFilter_1.TYPENAME);
36448
- }
36449
- static searchFilter(source) {
36450
- return source && PersonFilter_1.fromObject(source).asFilterFn();
36451
- }
36452
- fromObject(source, opts) {
36453
- super.fromObject(source, opts);
36454
- this.email = source.email;
36455
- this.pubkey = source.pubkey;
36456
- this.searchText = source.searchText;
36457
- this.statusIds = source.statusIds || (isNotNil(source.statusId) ? [source.statusId] : undefined);
36458
- this.userProfiles = source.userProfiles;
36459
- this.excludedIds = source.excludedIds;
36460
- this.searchAttribute = source.searchAttribute;
36461
- this.searchAttributes = source.searchAttributes;
36462
- }
36463
- asObject(opts) {
36464
- const target = super.asObject(opts);
36465
- target.email = this.email;
36466
- target.pubkey = this.pubkey;
36467
- target.searchText = this.searchText;
36468
- target.statusIds = this.statusIds;
36469
- target.userProfiles = this.userProfiles;
36470
- target.excludedIds = this.excludedIds;
36471
- target.searchAttribute = this.searchAttribute;
36472
- target.searchAttributes = this.searchAttributes;
36473
- return target;
36474
- }
36475
- buildFilter() {
36476
- const filterFns = super.buildFilter();
36477
- // Filter by status
36478
- if (isNotEmptyArray(this.statusIds)) {
36479
- filterFns.push(e => this.statusIds.includes(e.statusId));
36480
- }
36481
- // Filter excluded ids
36482
- if (isNotEmptyArray(this.excludedIds)) {
36483
- filterFns.push(e => isNil(e.id) || !this.excludedIds.includes(e.id));
36484
- }
36485
- // Search text
36486
- const searchTextFilter = EntityUtils.searchTextFilter(this.searchAttribute || this.searchAttributes || ['lastName', 'firstName', 'department.name'], this.searchText);
36487
- if (searchTextFilter)
36488
- filterFns.push(searchTextFilter);
36489
- return filterFns;
36490
- }
36491
- };
36492
- PersonFilter = PersonFilter_1 = __decorate([
36493
- EntityClass({ typename: 'PersonFilterVO' })
36494
- ], PersonFilter);
36495
-
36496
36563
  const PersonFragments = {
36497
36564
  person: gql `
36498
36565
  fragment PersonFragment on PersonVO {
@@ -36818,11 +36885,16 @@ class UsersPage extends AppTable {
36818
36885
  target.department = p.department?.asObject();
36819
36886
  return target;
36820
36887
  });
36888
+ const recipientFilter = PersonFilter.fromObject(this.filter);
36889
+ const canRecipientFilter = !recipientFilter.isEmpty() && (this.accountService.isAdmin() || this.accountService.isSupervisor());
36821
36890
  return this.messageService.openComposeModal({
36822
36891
  suggestFn: (value, filter, sortBy, sortDirection) => this.dataService.suggest(value, filter, sortBy, sortDirection),
36823
- data: {
36892
+ canRecipientFilter,
36893
+ recipientFilterCount: this.totalRowCount,
36894
+ data: Message.fromObject({
36824
36895
  recipients,
36825
- },
36896
+ recipientFilter,
36897
+ }),
36826
36898
  });
36827
36899
  }
36828
36900
  /* -- protected methods -- */