@gipisistemas/ngx-core 1.0.16 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,7 @@ import * as i3 from '@angular/material/input';
41
41
  import { MatInputModule } from '@angular/material/input';
42
42
  import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
43
43
  import * as i1$7 from '@angular/material/paginator';
44
- import { MatPaginatorModule, MatPaginatorIntl, MatPaginator } from '@angular/material/paginator';
44
+ import { MatPaginatorIntl, MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
45
45
  import { GlobalWorkerOptions, getDocument, OPS } from 'pdfjs-dist';
46
46
  import { EventBus, PDFLinkService, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';
47
47
  import { __decorate } from 'tslib';
@@ -4007,11 +4007,9 @@ class BaseService {
4007
4007
  const direction = 'direction' in value
4008
4008
  ? (value.direction ?? 'ASC')
4009
4009
  : 'ASC';
4010
- paramValue = `${value.field},${direction.toUpperCase()}`;
4011
- params.set(key, paramValue);
4010
+ params.set(key, `${value.field},${direction.toUpperCase()}`);
4012
4011
  }
4013
4012
  else if (Array.isArray(value)) {
4014
- paramValue = '';
4015
4013
  for (const item of value) {
4016
4014
  if (typeof item === 'object' && 'field' in item) {
4017
4015
  const direction = 'direction' in item
@@ -4020,15 +4018,22 @@ class BaseService {
4020
4018
  params.append('sort', `${item.field},${direction.toUpperCase()}`);
4021
4019
  }
4022
4020
  }
4021
+ continue;
4023
4022
  }
4024
4023
  }
4025
- else {
4026
- if (typeof value === 'object') {
4027
- paramValue = JSON.stringify(value);
4028
- }
4029
- else {
4030
- paramValue = String(value).trim();
4024
+ else if (Array.isArray(value)) {
4025
+ for (const item of value) {
4026
+ if (item !== null && item !== undefined) {
4027
+ params.append(key, String(item));
4028
+ }
4031
4029
  }
4030
+ continue;
4031
+ }
4032
+ else if (typeof value === 'object') {
4033
+ paramValue = JSON.stringify(value);
4034
+ }
4035
+ else {
4036
+ paramValue = String(value).trim();
4032
4037
  }
4033
4038
  if (key !== 'sort') {
4034
4039
  params.set(key, paramValue);
@@ -4864,12 +4869,12 @@ class FilterPersistenceService {
4864
4869
  this._injector = inject(EnvironmentInjector);
4865
4870
  this._baseAuthServiceToken = inject(BaseAuthServiceToken);
4866
4871
  this._localStorageToken = inject(LocalStorageToken);
4872
+ this._STORAGE_KEY = 'gipi.filters';
4867
4873
  }
4868
4874
  /** Inicializa os filtros a partir da URL ou localStorage */
4869
- initializeFilter(storageKey, defaultFilter, useUserSegregation = true) {
4875
+ initializeFilter(screenKey, defaultFilter) {
4870
4876
  return runInInjectionContext(this._injector, () => {
4871
4877
  const activatedRoute = inject(ActivatedRoute);
4872
- const normalizedStorageKey = this._normalizeStorageKey(storageKey, useUserSegregation);
4873
4878
  const rawQueryParams = activatedRoute.snapshot.queryParams;
4874
4879
  const hasAnyQueryParams = Object.keys(rawQueryParams).some((key) => {
4875
4880
  const value = rawQueryParams[key];
@@ -4888,7 +4893,7 @@ class FilterPersistenceService {
4888
4893
  return snapshotParams;
4889
4894
  }
4890
4895
  // FALLBACK do localStorage (somente se NÃO tiver nada na URL)
4891
- const saved = this._loadFromStorage(normalizedStorageKey);
4896
+ const saved = this._loadFromStorage(screenKey);
4892
4897
  if (saved) {
4893
4898
  this._updateUrl(this._serializeToQueryParams(saved));
4894
4899
  return saved;
@@ -4897,32 +4902,20 @@ class FilterPersistenceService {
4897
4902
  });
4898
4903
  }
4899
4904
  /** Atualiza URL e storage quando os filtros mudam */
4900
- updateFilter(storageKey, filters, useUserSegregation = true) {
4905
+ updateFilter(screenKey, filters) {
4901
4906
  const queryParams = this._serializeToQueryParams(filters);
4902
4907
  const cleanedParams = this._cleanQueryParams(queryParams);
4903
4908
  const mergedParams = this._mergeWithCurrentQueryParams(filters, cleanedParams);
4904
- const normalizedStorageKey = this._normalizeStorageKey(storageKey, useUserSegregation);
4905
4909
  // Atualiza URL
4906
4910
  this._updateUrl(mergedParams);
4907
4911
  // Salva no localStorage
4908
- this._saveToStorage(normalizedStorageKey, filters);
4912
+ this._saveToStorage(screenKey, filters);
4909
4913
  }
4910
4914
  /** Limpa filtros da URL e storage */
4911
- clearFilter(storageKey, defaultFilter, useUserSegregation = true) {
4912
- const normalizedStorageKey = this._normalizeStorageKey(storageKey, useUserSegregation);
4915
+ clearFilter(screenKey, defaultFilter) {
4913
4916
  const mergedParams = this._mergeWithCurrentQueryParams(defaultFilter, {});
4914
4917
  this._updateUrl(mergedParams);
4915
- this._saveToStorage(normalizedStorageKey, defaultFilter);
4916
- }
4917
- /** Normaliza a chave de storage incluindo o usuário quando necessário */
4918
- _normalizeStorageKey(storageKey, useUserSegregation = true) {
4919
- const prefix = 'gipi.filter';
4920
- let key = storageKey.startsWith(prefix) ? storageKey : `${prefix}${storageKey}`;
4921
- if (useUserSegregation) {
4922
- const userAndCompanyId = this._getCurrentUserAndCompanyId();
4923
- key = `${key}.user.${userAndCompanyId}`;
4924
- }
4925
- return key;
4918
+ this._saveToStorage(screenKey, defaultFilter);
4926
4919
  }
4927
4920
  /** Obtém o ID do usuário atual */
4928
4921
  _getCurrentUserAndCompanyId() {
@@ -5047,21 +5040,29 @@ class FilterPersistenceService {
5047
5040
  });
5048
5041
  return { ...defaultFilter, ...parsed };
5049
5042
  }
5050
- _hasQueryParams(filters, defaultFilter) {
5051
- return JSON.stringify(filters) !== JSON.stringify(defaultFilter);
5052
- }
5053
- _saveToStorage(storageKey, filters) {
5043
+ _saveToStorage(screenKey, filters) {
5054
5044
  try {
5055
- this._localStorageToken.setItem(storageKey, JSON.stringify(filters));
5045
+ const userCompany = this._getCurrentUserAndCompanyId();
5046
+ const storageRaw = this._localStorageToken.getItem(this._STORAGE_KEY);
5047
+ const storage = storageRaw ? JSON.parse(storageRaw) : {};
5048
+ if (!storage[userCompany]) {
5049
+ storage[userCompany] = {};
5050
+ }
5051
+ storage[userCompany][screenKey] = filters;
5052
+ this._localStorageToken.setItem(this._STORAGE_KEY, JSON.stringify(storage));
5056
5053
  }
5057
5054
  catch (error) {
5058
5055
  console.warn('Could not save filters to storage:', error);
5059
5056
  }
5060
5057
  }
5061
- _loadFromStorage(storageKey) {
5058
+ _loadFromStorage(screenKey) {
5062
5059
  try {
5063
- const saved = this._localStorageToken.getItem(storageKey);
5064
- return saved ? JSON.parse(saved) : null;
5060
+ const userCompany = this._getCurrentUserAndCompanyId();
5061
+ const storageRaw = this._localStorageToken.getItem(this._STORAGE_KEY);
5062
+ if (!storageRaw)
5063
+ return null;
5064
+ const storage = JSON.parse(storageRaw);
5065
+ return storage?.[userCompany]?.[screenKey] ?? null;
5065
5066
  }
5066
5067
  catch {
5067
5068
  return null;
@@ -5112,8 +5113,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5112
5113
  * const { filter, isInitializing, resetFilter } = useFilterPersistence({
5113
5114
  * defaultFilter: new MyFilter(),
5114
5115
  *
5115
- * // Recomendado iniciar com 'gipi.filter.'
5116
- * storageKey: 'gipi.filter.default',
5116
+ * // Recomendação: this.getPath();
5117
+ * screenKey: 'page/filter/default',
5117
5118
  *
5118
5119
  * // Opcional, padrão 100ms
5119
5120
  * debounceTime: 200,
@@ -5125,13 +5126,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5125
5126
  */
5126
5127
  function useFilterPersistence(config) {
5127
5128
  const filterPersistenceService = inject(FilterPersistenceService);
5128
- const { storageKey = 'gipi.filter.undefined', defaultFilter, debounceTime = 100, onFilterInit, useUserSegregation = true, } = config;
5129
+ const { screenKey = 'page/filter/undefined', defaultFilter, debounceTime = 100, onFilterInit, } = config;
5129
5130
  const isInitializing = signal(true, ...(ngDevMode ? [{ debugName: "isInitializing" }] : []));
5130
5131
  const filter = signal(defaultFilter, ...(ngDevMode ? [{ debugName: "filter" }] : []));
5131
5132
  // Inicialização
5132
5133
  const initializeFilter = () => {
5133
5134
  try {
5134
- const persistedFilter = filterPersistenceService.initializeFilter(storageKey, defaultFilter, useUserSegregation);
5135
+ const persistedFilter = filterPersistenceService.initializeFilter(screenKey, defaultFilter);
5135
5136
  filter.set(persistedFilter);
5136
5137
  if (onFilterInit) {
5137
5138
  onFilterInit(persistedFilter);
@@ -5139,7 +5140,7 @@ function useFilterPersistence(config) {
5139
5140
  }
5140
5141
  catch {
5141
5142
  filter.set(defaultFilter);
5142
- filterPersistenceService.clearFilter(storageKey, defaultFilter, useUserSegregation);
5143
+ filterPersistenceService.clearFilter(screenKey, defaultFilter);
5143
5144
  if (onFilterInit) {
5144
5145
  onFilterInit(defaultFilter);
5145
5146
  }
@@ -5152,7 +5153,7 @@ function useFilterPersistence(config) {
5152
5153
  const init = isInitializing();
5153
5154
  if (init)
5154
5155
  return;
5155
- const timeoutId = setTimeout(() => filterPersistenceService.updateFilter(storageKey, currentFilter, useUserSegregation), debounceTime);
5156
+ const timeoutId = setTimeout(() => filterPersistenceService.updateFilter(screenKey, currentFilter), debounceTime);
5156
5157
  return () => clearTimeout(timeoutId);
5157
5158
  });
5158
5159
  afterNextRender(() => initializeFilter());
@@ -5161,7 +5162,7 @@ function useFilterPersistence(config) {
5161
5162
  isInitializing: isInitializing.asReadonly(),
5162
5163
  reset: () => {
5163
5164
  filter.set(defaultFilter);
5164
- filterPersistenceService.clearFilter(storageKey, defaultFilter, useUserSegregation);
5165
+ filterPersistenceService.clearFilter(screenKey, defaultFilter);
5165
5166
  },
5166
5167
  set: (newFilter) => {
5167
5168
  filter.set(newFilter);
@@ -5178,7 +5179,6 @@ class BaseListComponent extends BaseComponent {
5178
5179
  this.service = service;
5179
5180
  this.filterPersistenceService = inject(FilterPersistenceService);
5180
5181
  this.pageAdjustService = inject(PageAdjustService);
5181
- this._SESSION_STORAGE_FILTER = `gipi.filter.${this.getFilterStorageKey()}`;
5182
5182
  this._isHydrating = signal(true, ...(ngDevMode ? [{ debugName: "_isHydrating" }] : []));
5183
5183
  this._persistTimer = null;
5184
5184
  this.filter = signal(this.newFilter(), ...(ngDevMode ? [{ debugName: "filter" }] : []));
@@ -5229,7 +5229,7 @@ class BaseListComponent extends BaseComponent {
5229
5229
  // Debounce manual para evitar muitas atualizações
5230
5230
  this._persistTimer = setTimeout(() => {
5231
5231
  const toPersist = this._filterToPersist(currentFilter);
5232
- this.filterPersistenceService.updateFilter(this._SESSION_STORAGE_FILTER, toPersist);
5232
+ this.filterPersistenceService.updateFilter(this.getFilterStorageKey(), toPersist);
5233
5233
  }, 150);
5234
5234
  });
5235
5235
  }
@@ -5260,6 +5260,12 @@ class BaseListComponent extends BaseComponent {
5260
5260
  return (!ArrayUtil.isEmpty(this.appliedFilters) &&
5261
5261
  this.appliedFilters().findIndex((e) => e.key === key) >= 0);
5262
5262
  }
5263
+ hasAnyAvailableAction(actions, canExecuteAction) {
5264
+ if (ArrayUtil.isEmpty(actions)) {
5265
+ return false;
5266
+ }
5267
+ return actions.some((action) => canExecuteAction(action));
5268
+ }
5263
5269
  /**
5264
5270
  * Método chamado quando o componente é inicializado.
5265
5271
  * - Chamado no OnInit
@@ -5275,7 +5281,7 @@ class BaseListComponent extends BaseComponent {
5275
5281
  this._isHydrating.set(true);
5276
5282
  this.page.set(this.newPage());
5277
5283
  const defaultFilter = this.newFilter();
5278
- const persistedFilter = this.filterPersistenceService.initializeFilter(this._SESSION_STORAGE_FILTER, defaultFilter);
5284
+ const persistedFilter = this.filterPersistenceService.initializeFilter(this.getFilterStorageKey(), defaultFilter);
5279
5285
  this.filter.set(persistedFilter);
5280
5286
  this.afterFilterInit();
5281
5287
  this.tableColumns.set(this.createTableColumns());
@@ -5630,7 +5636,7 @@ class BaseListComponent extends BaseComponent {
5630
5636
  }
5631
5637
  resetFilter() {
5632
5638
  // Limpa a persistência dos filtros
5633
- this.filterPersistenceService.clearFilter(this._SESSION_STORAGE_FILTER, this.newFilter());
5639
+ this.filterPersistenceService.clearFilter(this.getFilterStorageKey(), this.newFilter());
5634
5640
  this.page.set(this.newPage());
5635
5641
  this.filter.set(this.newFilter());
5636
5642
  this.appliedFilters.set([]);
@@ -5685,13 +5691,6 @@ class BaseReportComponent extends BaseComponent {
5685
5691
  get currentReportType() {
5686
5692
  return this._currentReportType();
5687
5693
  }
5688
- get _SESSION_STORAGE_FILTER() {
5689
- const current = this._currentReportType();
5690
- if (!current) {
5691
- return `gipi.filter.unknown`;
5692
- }
5693
- return `gipi.filter.${current.getFilterStorageKey()}`;
5694
- }
5695
5694
  // Computed para facilitar o acesso ao tipo atual
5696
5695
  get currentType() {
5697
5696
  return computed(() => this._currentReportType()?.type || '');
@@ -5708,6 +5707,13 @@ class BaseReportComponent extends BaseComponent {
5708
5707
  this.filterPersistenceService = inject(FilterPersistenceService);
5709
5708
  this._isInitializingScreen = signal(true, ...(ngDevMode ? [{ debugName: "_isInitializingScreen" }] : []));
5710
5709
  this._currentReportType = signal(null, ...(ngDevMode ? [{ debugName: "_currentReportType" }] : []));
5710
+ this._STORAGE_FILTER = computed(() => {
5711
+ const current = this._currentReportType();
5712
+ if (!current) {
5713
+ return `gipi/filter/unknown`;
5714
+ }
5715
+ return current.getFilterStorageKey();
5716
+ }, ...(ngDevMode ? [{ debugName: "_STORAGE_FILTER" }] : []));
5711
5717
  // Effect para persistência automática dos filtros
5712
5718
  effect(() => {
5713
5719
  const currentFilter = this._currentReportType().filter();
@@ -5717,7 +5723,7 @@ class BaseReportComponent extends BaseComponent {
5717
5723
  return;
5718
5724
  }
5719
5725
  // Debounce manual para evitar muitas atualizações
5720
- setTimeout(() => this.filterPersistenceService.updateFilter(this._SESSION_STORAGE_FILTER, currentFilter), 100);
5726
+ setTimeout(() => this.filterPersistenceService.updateFilter(this._STORAGE_FILTER(), currentFilter), 100);
5721
5727
  });
5722
5728
  // Effect para reagir à mudança de tipo de relatório
5723
5729
  effect(() => {
@@ -5737,7 +5743,7 @@ class BaseReportComponent extends BaseComponent {
5737
5743
  this.currentReportType = this.reportTypes[0];
5738
5744
  }
5739
5745
  const defaultFilter = this.currentReportType.newFilter();
5740
- const persistedFilter = this.filterPersistenceService.initializeFilter(this._SESSION_STORAGE_FILTER, defaultFilter);
5746
+ const persistedFilter = this.filterPersistenceService.initializeFilter(this._STORAGE_FILTER(), defaultFilter);
5741
5747
  this.currentReportType.filter.set(persistedFilter);
5742
5748
  // Hook para ações após a inicialização do filtro
5743
5749
  this.currentReportType.afterFilterInit();
@@ -5882,14 +5888,14 @@ class BaseReportComponent extends BaseComponent {
5882
5888
  _persistCurrentTypeState() {
5883
5889
  if (this.currentReportType) {
5884
5890
  const currentFilter = this.currentReportType.filter();
5885
- this.filterPersistenceService.updateFilter(`gipi.filter.${this.currentReportType.getFilterStorageKey()}`, currentFilter);
5891
+ this.filterPersistenceService.updateFilter(this.currentReportType.getFilterStorageKey(), currentFilter);
5886
5892
  }
5887
5893
  }
5888
5894
  /** Carrega o estado do novo tipo */
5889
5895
  _loadNewTypeState() {
5890
5896
  this._isInitializingScreen.set(true);
5891
5897
  const defaultFilter = this.currentReportType.newFilter();
5892
- const persistedFilter = this.filterPersistenceService.initializeFilter(this._SESSION_STORAGE_FILTER, defaultFilter);
5898
+ const persistedFilter = this.filterPersistenceService.initializeFilter(this._STORAGE_FILTER(), defaultFilter);
5893
5899
  this.currentReportType.filter.set(persistedFilter);
5894
5900
  this.currentReportType.afterFilterInit();
5895
5901
  // Força uma busca dos dados
@@ -10734,6 +10740,20 @@ class DatePickerCalendar {
10734
10740
  this.yearRangeStart.set(Math.floor(this.currentYear() / YEARS_DISPLAYED) * YEARS_DISPLAYED);
10735
10741
  }
10736
10742
  }
10743
+ navigatePrevious() {
10744
+ if (this.showMonthYearPicker() && this.monthYearPickerView() === 'year') {
10745
+ this.previousYearRange();
10746
+ return;
10747
+ }
10748
+ this.previousMonth();
10749
+ }
10750
+ navigateNext() {
10751
+ if (this.showMonthYearPicker() && this.monthYearPickerView() === 'year') {
10752
+ this.nextYearRange();
10753
+ return;
10754
+ }
10755
+ this.nextMonth();
10756
+ }
10737
10757
  previousMonth() {
10738
10758
  if (this.currentMonth() === 0) {
10739
10759
  this.currentMonth.set(11);
@@ -11843,24 +11863,26 @@ class DatePickerCalendar {
11843
11863
 
11844
11864
  <div class="g-navigation-buttons">
11845
11865
  <button
11846
- aria-label="Mês anterior"
11866
+ [attr.aria-label]="
11867
+ showMonthYearPicker() && monthYearPickerView() === 'year'
11868
+ ? 'Anos anteriores'
11869
+ : 'Mês anterior'
11870
+ "
11847
11871
  type="button"
11848
11872
  class="g-nav-button"
11849
- (click)="
11850
- monthYearPickerView() === 'year'
11851
- ? previousYearRange()
11852
- : previousMonth()
11853
- "
11873
+ (click)="navigatePrevious()"
11854
11874
  >
11855
11875
  <span class="material-symbols-rounded">chevron_left</span>
11856
11876
  </button>
11857
11877
  <button
11858
- aria-label="Próximo mês"
11878
+ [attr.aria-label]="
11879
+ showMonthYearPicker() && monthYearPickerView() === 'year'
11880
+ ? 'Próximos anos'
11881
+ : 'Próximo mês'
11882
+ "
11859
11883
  type="button"
11860
11884
  class="g-nav-button"
11861
- (click)="
11862
- monthYearPickerView() === 'year' ? nextYearRange() : nextMonth()
11863
- "
11885
+ (click)="navigateNext()"
11864
11886
  >
11865
11887
  <span class="material-symbols-rounded">chevron_right</span>
11866
11888
  </button>
@@ -12443,24 +12465,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
12443
12465
 
12444
12466
  <div class="g-navigation-buttons">
12445
12467
  <button
12446
- aria-label="Mês anterior"
12468
+ [attr.aria-label]="
12469
+ showMonthYearPicker() && monthYearPickerView() === 'year'
12470
+ ? 'Anos anteriores'
12471
+ : 'Mês anterior'
12472
+ "
12447
12473
  type="button"
12448
12474
  class="g-nav-button"
12449
- (click)="
12450
- monthYearPickerView() === 'year'
12451
- ? previousYearRange()
12452
- : previousMonth()
12453
- "
12475
+ (click)="navigatePrevious()"
12454
12476
  >
12455
12477
  <span class="material-symbols-rounded">chevron_left</span>
12456
12478
  </button>
12457
12479
  <button
12458
- aria-label="Próximo mês"
12480
+ [attr.aria-label]="
12481
+ showMonthYearPicker() && monthYearPickerView() === 'year'
12482
+ ? 'Próximos anos'
12483
+ : 'Próximo mês'
12484
+ "
12459
12485
  type="button"
12460
12486
  class="g-nav-button"
12461
- (click)="
12462
- monthYearPickerView() === 'year' ? nextYearRange() : nextMonth()
12463
- "
12487
+ (click)="navigateNext()"
12464
12488
  >
12465
12489
  <span class="material-symbols-rounded">chevron_right</span>
12466
12490
  </button>
@@ -17447,9 +17471,12 @@ class InputPhone extends BaseControlValueAccessor {
17447
17471
  this._uniqueId = inject(_IdGenerator).getId('gipi-input-phone-');
17448
17472
  this._controlId = inject(_IdGenerator).getId('gipi-input-phone-control-');
17449
17473
  this._inputElementRef = viewChild('inputElement', ...(ngDevMode ? [{ debugName: "_inputElementRef" }] : []));
17474
+ this._syncResetHandle = null;
17450
17475
  this.prefixRef = contentChild('prefix', ...(ngDevMode ? [{ debugName: "prefixRef" }] : []));
17451
17476
  this.suffixRef = contentChild('suffix', ...(ngDevMode ? [{ debugName: "suffixRef" }] : []));
17452
17477
  this.ngControl = viewChild(NgControl, ...(ngDevMode ? [{ debugName: "ngControl" }] : []));
17478
+ this._isSynchronizingViewValue = signal(false, ...(ngDevMode ? [{ debugName: "_isSynchronizingViewValue" }] : []));
17479
+ this.displayValue = signal('', ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
17453
17480
  this.isInputFocused = signal(false, ...(ngDevMode ? [{ debugName: "isInputFocused" }] : []));
17454
17481
  this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
17455
17482
  this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
@@ -17469,21 +17496,43 @@ class InputPhone extends BaseControlValueAccessor {
17469
17496
  this.phoneMask = signal('0*', ...(ngDevMode ? [{ debugName: "phoneMask" }] : []));
17470
17497
  }
17471
17498
  writeControlValue(value, setModelValue) {
17472
- const newValue = value || '';
17473
- this.value.set(newValue);
17474
- this._updatePhoneMask(newValue);
17475
- if (setModelValue) {
17476
- setModelValue(newValue);
17477
- }
17499
+ const newValue = this._normalizeModelValue(value || '');
17500
+ this._synchronizeViewValue(() => {
17501
+ if (setModelValue) {
17502
+ setModelValue(newValue);
17503
+ }
17504
+ else {
17505
+ this.value.set(newValue);
17506
+ }
17507
+ this._applyViewValue(newValue);
17508
+ });
17478
17509
  }
17479
17510
  onInputChange(value) {
17480
- if (this.$disabled()) {
17511
+ if (this.$disabled() || this._isSynchronizingViewValue()) {
17481
17512
  return;
17482
17513
  }
17483
- this._updatePhoneMask(value);
17484
- this.notifyValueChange(value);
17514
+ const modelValue = this._normalizeModelValue(value);
17515
+ this.displayValue.set(value || '');
17516
+ this._updatePhoneMask(modelValue);
17517
+ this.notifyValueChange(modelValue);
17485
17518
  this.markAsTouched();
17486
17519
  }
17520
+ _synchronizeViewValue(syncFn) {
17521
+ // O ngx-mask pode ecoar um ngModelChange apos writeValue/mudancas de mascara.
17522
+ this._isSynchronizingViewValue.set(true);
17523
+ if (this._syncResetHandle !== null) {
17524
+ clearTimeout(this._syncResetHandle);
17525
+ }
17526
+ try {
17527
+ syncFn();
17528
+ }
17529
+ finally {
17530
+ this._syncResetHandle = setTimeout(() => {
17531
+ this._isSynchronizingViewValue.set(false);
17532
+ this._syncResetHandle = null;
17533
+ });
17534
+ }
17535
+ }
17487
17536
  _updatePhoneMask(value) {
17488
17537
  if (this.foreign()) {
17489
17538
  this.phoneMask.set('0*');
@@ -17499,6 +17548,22 @@ class InputPhone extends BaseControlValueAccessor {
17499
17548
  this.phoneMask.set(mask);
17500
17549
  }
17501
17550
  }
17551
+ _applyViewValue(value) {
17552
+ this.displayValue.set(this._formatDisplayValue(value));
17553
+ this._updatePhoneMask(value);
17554
+ }
17555
+ _formatDisplayValue(value) {
17556
+ if (StringUtil.isEmpty(value) || this.foreign() || this.isInputFocused()) {
17557
+ return value;
17558
+ }
17559
+ return PhoneUtil.format(value);
17560
+ }
17561
+ _normalizeModelValue(value) {
17562
+ if (StringUtil.isEmpty(value) || this.foreign()) {
17563
+ return value || '';
17564
+ }
17565
+ return PhoneUtil.removeCharacters(value);
17566
+ }
17502
17567
  onInputKeydown(event) {
17503
17568
  if (this.readonly() || this.$disabled()) {
17504
17569
  return;
@@ -17512,7 +17577,7 @@ class InputPhone extends BaseControlValueAccessor {
17512
17577
  this.isInputFocused.set(true);
17513
17578
  // Para telefones nacionais, simplifica a máscara durante o foco
17514
17579
  if (!this.foreign()) {
17515
- this.phoneMask.set('0*');
17580
+ this._synchronizeViewValue(() => this._applyViewValue(this.value()));
17516
17581
  }
17517
17582
  this.onFocusEvent.emit(event);
17518
17583
  }
@@ -17523,15 +17588,7 @@ class InputPhone extends BaseControlValueAccessor {
17523
17588
  this.isInputFocused.set(false);
17524
17589
  // Para telefones nacionais, formata o número ao sair do campo
17525
17590
  if (!this.foreign()) {
17526
- const currentValue = this.value();
17527
- if (!StringUtil.isEmpty(currentValue)) {
17528
- const formattedValue = PhoneUtil.format(currentValue);
17529
- if (formattedValue !== currentValue) {
17530
- this.value.set(formattedValue);
17531
- this.notifyValueChange(formattedValue);
17532
- }
17533
- this._updatePhoneMask(formattedValue);
17534
- }
17591
+ this._synchronizeViewValue(() => this._applyViewValue(this.value()));
17535
17592
  }
17536
17593
  this.onBlurEvent.emit(event);
17537
17594
  this.markAsTouched();
@@ -17540,22 +17597,19 @@ class InputPhone extends BaseControlValueAccessor {
17540
17597
  if (this.$disabled() || !this._inputElementRef()?.nativeElement) {
17541
17598
  return;
17542
17599
  }
17543
- setTimeout(() => {
17544
- this._inputElementRef()?.nativeElement?.focus(options);
17545
- });
17600
+ setTimeout(() => this._inputElementRef()?.nativeElement?.focus(options));
17546
17601
  }
17547
17602
  select() {
17548
17603
  if (this.$disabled() || !this._inputElementRef()?.nativeElement) {
17549
17604
  return;
17550
17605
  }
17551
- setTimeout(() => {
17552
- this._inputElementRef()?.nativeElement?.select();
17553
- });
17606
+ setTimeout(() => this._inputElementRef()?.nativeElement?.select());
17554
17607
  }
17555
17608
  clear() {
17556
17609
  if (this.$disabled()) {
17557
17610
  return;
17558
17611
  }
17612
+ this.displayValue.set('');
17559
17613
  this.phoneMask.set('0*');
17560
17614
  this.notifyValueChange('');
17561
17615
  }
@@ -17594,7 +17648,7 @@ class InputPhone extends BaseControlValueAccessor {
17594
17648
  [disabled]="$disabled()"
17595
17649
  [readonly]="readonly()"
17596
17650
  [required]="required()"
17597
- [ngModel]="value()"
17651
+ [ngModel]="displayValue()"
17598
17652
  (ngModelChange)="onInputChange($event)"
17599
17653
  (keydown)="onInputKeydown($event)"
17600
17654
  (focus)="onInputFocus($event)"
@@ -17652,7 +17706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
17652
17706
  [disabled]="$disabled()"
17653
17707
  [readonly]="readonly()"
17654
17708
  [required]="required()"
17655
- [ngModel]="value()"
17709
+ [ngModel]="displayValue()"
17656
17710
  (ngModelChange)="onInputChange($event)"
17657
17711
  (keydown)="onInputKeydown($event)"
17658
17712
  (focus)="onInputFocus($event)"
@@ -17772,63 +17826,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
17772
17826
  }]
17773
17827
  }] });
17774
17828
 
17829
+ const portugueseRangeLabel = (page, pageSize, length) => {
17830
+ if (length === 0 || pageSize === 0) {
17831
+ return `0 de ${length}`;
17832
+ }
17833
+ length = Math.max(length, 0);
17834
+ const startIndex = page * pageSize;
17835
+ // Se o índice inicial exceder o comprimento da lista, não tente fixar o índice final no final.
17836
+ const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
17837
+ return `${startIndex + 1} - ${endIndex} de ${length}`;
17838
+ };
17839
+ const PAGINATOR_INTL_PT_BR = () => {
17840
+ const paginatorIntl = new MatPaginatorIntl();
17841
+ paginatorIntl.itemsPerPageLabel = 'Itens por página';
17842
+ paginatorIntl.nextPageLabel = 'Próxima página';
17843
+ paginatorIntl.previousPageLabel = 'Página anterior';
17844
+ paginatorIntl.getRangeLabel = portugueseRangeLabel;
17845
+ paginatorIntl.firstPageLabel = 'Primeira página';
17846
+ paginatorIntl.lastPageLabel = 'Última página';
17847
+ return paginatorIntl;
17848
+ };
17849
+ // eslint-disable-next-line @typescript-eslint/naming-convention
17850
+ const PaginatorIntlToken = new InjectionToken('PAGINATOR_INTL_TOKEN', {
17851
+ factory: () => PAGINATOR_INTL_PT_BR(),
17852
+ });
17853
+ function providePaginatorIntl(config) {
17854
+ return {
17855
+ provide: PaginatorIntlToken,
17856
+ useValue: config ?? PAGINATOR_INTL_PT_BR(),
17857
+ };
17858
+ }
17859
+
17775
17860
  class Paginator {
17776
17861
  constructor() {
17777
17862
  this._uniqueId = inject(_IdGenerator).getId('gipi-paginator-');
17778
- this.currentPage = signal(0, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
17779
- this.currentPageSize = signal(0, ...(ngDevMode ? [{ debugName: "currentPageSize" }] : []));
17780
17863
  this.id = input(this._uniqueId, ...(ngDevMode ? [{ debugName: "id" }] : []));
17781
17864
  this.name = input(this._uniqueId, ...(ngDevMode ? [{ debugName: "name" }] : []));
17782
17865
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
17783
17866
  this.hidePageSize = input(false, ...(ngDevMode ? [{ debugName: "hidePageSize", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
17784
17867
  this.length = input(0, ...(ngDevMode ? [{ debugName: "length", transform: numberAttribute }] : [{ transform: numberAttribute }]));
17785
- this.pageNumber = input(0, ...(ngDevMode ? [{ debugName: "pageNumber", transform: numberAttribute }] : [{ transform: numberAttribute }]));
17786
- this.pageSize = input(0, ...(ngDevMode ? [{ debugName: "pageSize", transform: numberAttribute }] : [{ transform: numberAttribute }]));
17787
17868
  this.pageSizeOptions = input([10, 20, 30], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : []));
17869
+ this.pageNumber = model(0, ...(ngDevMode ? [{ debugName: "pageNumber" }] : []));
17870
+ this.pageSize = model(0, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
17788
17871
  this.onPage = output();
17789
- this.currentPage.set(this.pageNumber());
17790
- this.currentPageSize.set(this.pageSize());
17791
17872
  }
17792
17873
  onHandlePage(pageEvent) {
17793
17874
  if (!pageEvent) {
17794
17875
  return;
17795
17876
  }
17796
- this.currentPage.set(pageEvent.pageIndex);
17797
- this.currentPageSize.set(pageEvent.pageSize);
17877
+ this.pageNumber.set(pageEvent.pageIndex);
17878
+ this.pageSize.set(pageEvent.pageSize);
17798
17879
  this.onPage.emit(pageEvent);
17799
17880
  }
17800
17881
  setPage(pageIndex) {
17801
- this.currentPage.set(pageIndex);
17882
+ this.pageNumber.set(pageIndex);
17802
17883
  }
17803
17884
  setPageSize(pageSize) {
17804
- this.currentPageSize.set(pageSize);
17885
+ this.pageSize.set(pageSize);
17805
17886
  }
17806
17887
  nextPage() {
17807
- this.currentPage.update((page) => page + 1);
17888
+ this.pageNumber.update((page) => page + 1);
17808
17889
  }
17809
17890
  previousPage() {
17810
- this.currentPage.update((page) => Math.max(0, page - 1));
17891
+ this.pageNumber.update((page) => Math.max(0, page - 1));
17811
17892
  }
17812
17893
  firstPage() {
17813
- this.currentPage.set(0);
17894
+ this.pageNumber.set(0);
17814
17895
  }
17815
17896
  lastPage() {
17816
- const totalPages = Math.ceil(this.length() / this.currentPageSize());
17817
- this.currentPage.set(Math.max(0, totalPages - 1));
17897
+ const totalPages = Math.ceil(this.length() / this.pageSize());
17898
+ this.pageNumber.set(Math.max(0, totalPages - 1));
17818
17899
  }
17819
17900
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Paginator, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
17820
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: Paginator, isStandalone: true, selector: "gipi-paginator", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, pageNumber: { classPropertyName: "pageNumber", publicName: "pageNumber", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onPage: "onPage" }, host: { properties: { "attr.id": "id()", "attr.name": "name()" }, classAttribute: "g-paginator" }, exportAs: ["gPaginator"], ngImport: i0, template: `
17901
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: Paginator, isStandalone: true, selector: "gipi-paginator", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageNumber: { classPropertyName: "pageNumber", publicName: "pageNumber", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageNumber: "pageNumberChange", pageSize: "pageSizeChange", onPage: "onPage" }, host: { properties: { "attr.id": "id()", "attr.name": "name()" }, classAttribute: "g-paginator" }, providers: [
17902
+ {
17903
+ provide: MatPaginatorIntl,
17904
+ useFactory: () => inject(PaginatorIntlToken),
17905
+ },
17906
+ ], exportAs: ["gPaginator"], ngImport: i0, template: `
17821
17907
  <mat-paginator
17822
17908
  class="g-paginator-control"
17823
17909
  [disabled]="disabled()"
17824
17910
  [hidePageSize]="hidePageSize()"
17825
17911
  [length]="length()"
17826
- [pageIndex]="currentPage()"
17827
- [pageSize]="currentPageSize()"
17912
+ [pageIndex]="pageNumber()"
17913
+ [pageSize]="pageSize()"
17828
17914
  [pageSizeOptions]="pageSizeOptions()"
17829
17915
  [selectConfig]="{}"
17830
17916
  [showFirstLastButtons]="true"
17831
- (page)="onHandlePage($event)" />
17917
+ (page)="onHandlePage($event)"
17918
+ />
17832
17919
  `, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i1$7.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
17833
17920
  }
17834
17921
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Paginator, decorators: [{
@@ -17839,18 +17926,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
17839
17926
  [disabled]="disabled()"
17840
17927
  [hidePageSize]="hidePageSize()"
17841
17928
  [length]="length()"
17842
- [pageIndex]="currentPage()"
17843
- [pageSize]="currentPageSize()"
17929
+ [pageIndex]="pageNumber()"
17930
+ [pageSize]="pageSize()"
17844
17931
  [pageSizeOptions]="pageSizeOptions()"
17845
17932
  [selectConfig]="{}"
17846
17933
  [showFirstLastButtons]="true"
17847
- (page)="onHandlePage($event)" />
17934
+ (page)="onHandlePage($event)"
17935
+ />
17848
17936
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
17849
17937
  '[attr.id]': 'id()',
17850
17938
  '[attr.name]': 'name()',
17851
17939
  class: 'g-paginator',
17852
- }, imports: [MatPaginatorModule] }]
17853
- }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], pageNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageNumber", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], onPage: [{ type: i0.Output, args: ["onPage"] }] } });
17940
+ }, providers: [
17941
+ {
17942
+ provide: MatPaginatorIntl,
17943
+ useFactory: () => inject(PaginatorIntlToken),
17944
+ },
17945
+ ], imports: [MatPaginatorModule] }]
17946
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageNumber", required: false }] }, { type: i0.Output, args: ["pageNumberChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], onPage: [{ type: i0.Output, args: ["onPage"] }] } });
17854
17947
  class PaginatorModule {
17855
17948
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PaginatorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
17856
17949
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: PaginatorModule, imports: [Paginator], exports: [Paginator] }); }
@@ -20788,37 +20881,6 @@ function Debounce(options = 300) {
20788
20881
  };
20789
20882
  }
20790
20883
 
20791
- const portugueseRangeLabel = (page, pageSize, length) => {
20792
- if (length === 0 || pageSize === 0) {
20793
- return `0 de ${length}`;
20794
- }
20795
- length = Math.max(length, 0);
20796
- const startIndex = page * pageSize;
20797
- // Se o índice inicial exceder o comprimento da lista, não tente fixar o índice final no final.
20798
- const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
20799
- return `${startIndex + 1} - ${endIndex} de ${length}`;
20800
- };
20801
- const PAGINATOR_INTL_PT_BR = () => {
20802
- const paginatorIntl = new MatPaginatorIntl();
20803
- paginatorIntl.itemsPerPageLabel = 'Itens por página';
20804
- paginatorIntl.nextPageLabel = 'Próxima página';
20805
- paginatorIntl.previousPageLabel = 'Página anterior';
20806
- paginatorIntl.getRangeLabel = portugueseRangeLabel;
20807
- paginatorIntl.firstPageLabel = 'Primeira página';
20808
- paginatorIntl.lastPageLabel = 'Última página';
20809
- return paginatorIntl;
20810
- };
20811
- // eslint-disable-next-line @typescript-eslint/naming-convention
20812
- const PaginatorIntlToken = new InjectionToken('PAGINATOR_INTL_TOKEN', {
20813
- factory: () => PAGINATOR_INTL_PT_BR(),
20814
- });
20815
- function providePaginatorIntl(config) {
20816
- return {
20817
- provide: PaginatorIntlToken,
20818
- useValue: config ?? PAGINATOR_INTL_PT_BR(),
20819
- };
20820
- }
20821
-
20822
20884
  class TextEllipsisDirective {
20823
20885
  constructor() {
20824
20886
  this._elementRef = inject(ElementRef);