@solcre-org/core-ui 2.15.27 → 2.15.28

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.
@@ -18,8 +18,8 @@ import { DomSanitizer } from '@angular/platform-browser';
18
18
  import * as i1$1 from '@angular/common/http';
19
19
  import { HttpClient, HttpHeaders } from '@angular/common/http';
20
20
  import dayjs from 'dayjs';
21
- import utc from 'dayjs/plugin/utc';
22
- import timezone from 'dayjs/plugin/timezone';
21
+ import * as utc from 'dayjs/plugin/utc';
22
+ import * as timezone from 'dayjs/plugin/timezone';
23
23
  import * as i1 from '@angular/cdk/overlay';
24
24
  import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
25
25
  import { TemplatePortal } from '@angular/cdk/portal';
@@ -2860,7 +2860,6 @@ const DEFAULT_COUNTRIES = [
2860
2860
  { "code": CountryCode.PL, "phone": "+48", "name": "Poland", "flag": "165-poland.svg" },
2861
2861
  { "code": CountryCode.CV, "phone": "+238", "name": "Cape Verde", "flag": "166-cape verde.svg" },
2862
2862
  { "code": CountryCode.TD, "phone": "+235", "name": "Chad", "flag": "167-chad.svg" },
2863
- { "code": CountryCode.BT, "phone": "+975", "name": "Bhutan", "flag": "168-bhutan.svg" },
2864
2863
  { "code": CountryCode.IO, "phone": "+246", "name": "British Indian Ocean Territory", "flag": "169-british indian ocean territory.svg" },
2865
2864
  { "code": CountryCode.KY, "phone": "+1", "name": "Cayman Islands", "flag": "170-cayman islands.svg" },
2866
2865
  { "code": CountryCode.CF, "phone": "+236", "name": "Central African Republic", "flag": "171-central african republic.svg" },
@@ -5608,6 +5607,18 @@ var PermissionsResources;
5608
5607
  PermissionsResources["MY_COMPANY_TELEWORK"] = "my_company_remote_work";
5609
5608
  PermissionsResources["FILE_TEMPLATES"] = "file_templates";
5610
5609
  PermissionsResources["CONFIGURATION"] = "configuration";
5610
+ PermissionsResources["COMPANIES_CHANGE_STATUS"] = "companies_change_status";
5611
+ PermissionsResources["EMPLOYEES_BULK_UPLOAD"] = "employees_bulk_upload";
5612
+ PermissionsResources["EMPLOYEES_EXPORT"] = "employees_export";
5613
+ PermissionsResources["RESERVATIONS_EXPORT"] = "reservations_export";
5614
+ PermissionsResources["SERVICES_EXPORT"] = "services_export";
5615
+ PermissionsResources["ACCESS_CARD_ASSIGN"] = "access_card_assign";
5616
+ PermissionsResources["ACCESS_CARD_REJECT_REQUEST"] = "access_card_reject_request";
5617
+ PermissionsResources["ACCESS_CARD_MARK_DELIVERED"] = "access_card_mark_delivered";
5618
+ PermissionsResources["ACCESS_CARD_REQUEST_REASSIGNMENT"] = "access_card_request_reassignment";
5619
+ PermissionsResources["ACCESS_CARD_MARK_RETURNED"] = "access_card_mark_returned";
5620
+ PermissionsResources["SERVICE_BUDGET_APPROVE"] = "service_budget_approve";
5621
+ PermissionsResources["SERVICE_BUDGET_REJECT"] = "service_budget_reject";
5611
5622
  })(PermissionsResources || (PermissionsResources = {}));
5612
5623
 
5613
5624
  class PermissionWrapperService {
@@ -5984,7 +5995,7 @@ class StepsService {
5984
5995
  return this._steps().findIndex(step => step.id === activeId);
5985
5996
  });
5986
5997
  initializeSteps(steps, activeStepId, instanceId) {
5987
- this._steps.set([...steps]);
5998
+ this._steps.set(steps.map(s => ({ ...s })));
5988
5999
  this._stepsInstanceId.set(instanceId || 'default');
5989
6000
  if (activeStepId) {
5990
6001
  this._activeStepId.set(activeStepId);
@@ -5999,11 +6010,11 @@ class StepsService {
5999
6010
  if (!step) {
6000
6011
  return null;
6001
6012
  }
6013
+ const previousStepId = this._activeStepId();
6014
+ this._activeStepId.set(stepId);
6002
6015
  if (step.disabled) {
6003
6016
  return null;
6004
6017
  }
6005
- const previousStepId = this._activeStepId();
6006
- this._activeStepId.set(stepId);
6007
6018
  return {
6008
6019
  step,
6009
6020
  index: this._steps().findIndex(s => s.id === stepId),
@@ -6935,44 +6946,42 @@ class GenericModalComponent {
6935
6946
  formGroup[fieldKey] = [initialValue, validators];
6936
6947
  });
6937
6948
  this.form.set(this.formBuilder.group(formGroup));
6938
- setTimeout(() => {
6939
- this.allFields().forEach(field => {
6940
- const fieldKey = field.key;
6941
- const payloadKey = (field.keyToPayload ?? field.key);
6942
- const modeConfig = field.modes?.[this.mode()];
6943
- const dynamicValueFn = (modeConfig?.dynamicValue ?? field.dynamicValue);
6944
- if (typeof dynamicValueFn === 'function') {
6945
- const dynamicVal = dynamicValueFn(newInstance);
6946
- if (dynamicVal !== undefined && dynamicVal !== null) {
6947
- newInstance[payloadKey] = dynamicVal;
6948
- const control = this.form().get(fieldKey);
6949
- if (control) {
6950
- control.setValue(dynamicVal, { emitEvent: true });
6951
- }
6949
+ this.allFields().forEach(field => {
6950
+ const fieldKey = field.key;
6951
+ const payloadKey = (field.keyToPayload ?? field.key);
6952
+ const modeConfig = field.modes?.[this.mode()];
6953
+ const dynamicValueFn = (modeConfig?.dynamicValue ?? field.dynamicValue);
6954
+ if (typeof dynamicValueFn === 'function') {
6955
+ const dynamicVal = dynamicValueFn(newInstance);
6956
+ if (dynamicVal !== undefined && dynamicVal !== null) {
6957
+ newInstance[payloadKey] = dynamicVal;
6958
+ const control = this.form().get(fieldKey);
6959
+ if (control) {
6960
+ control.setValue(dynamicVal, { emitEvent: true });
6952
6961
  }
6953
6962
  }
6954
- });
6955
- this.allFields().forEach(field => {
6956
- const fieldKey = field.key;
6957
- const control = this.form().get(fieldKey);
6958
- if (control && control.value !== undefined && control.value !== null) {
6959
- const payloadKey = (field.keyToPayload ?? field.key);
6960
- newInstance[payloadKey] = control.value;
6961
- }
6962
- });
6963
- Object.values(this.form().controls).forEach(control => {
6964
- control.markAsUntouched();
6965
- });
6966
- this.fieldErrors.set({});
6967
- this.internalErrors.set([]);
6968
- this.editedData.set(newInstance);
6969
- if (this.mode() !== ModalMode.VIEW) {
6970
- const originalCopy = Object.create(Object.getPrototypeOf(newInstance));
6971
- Object.assign(originalCopy, newInstance);
6972
- this.originalData.set(originalCopy);
6973
6963
  }
6974
- this.modalData.emit(newInstance);
6975
- }, 50);
6964
+ });
6965
+ this.allFields().forEach(field => {
6966
+ const fieldKey = field.key;
6967
+ const control = this.form().get(fieldKey);
6968
+ if (control && control.value !== undefined && control.value !== null) {
6969
+ const payloadKey = (field.keyToPayload ?? field.key);
6970
+ newInstance[payloadKey] = control.value;
6971
+ }
6972
+ });
6973
+ Object.values(this.form().controls).forEach(control => {
6974
+ control.markAsUntouched();
6975
+ });
6976
+ this.fieldErrors.set({});
6977
+ this.internalErrors.set([]);
6978
+ this.editedData.set(newInstance);
6979
+ if (this.mode() !== ModalMode.VIEW) {
6980
+ const originalCopy = Object.create(Object.getPrototypeOf(newInstance));
6981
+ Object.assign(originalCopy, newInstance);
6982
+ this.originalData.set(originalCopy);
6983
+ }
6984
+ this.modalData.emit(newInstance);
6976
6985
  }
6977
6986
  initializeActiveTabAndStep() {
6978
6987
  if (this.hasTabs()) {
@@ -7101,15 +7110,18 @@ class GenericModalComponent {
7101
7110
  const { _isSeparatedDocumentField, ...separatedKeys } = value;
7102
7111
  this.editedData.update(data => {
7103
7112
  if (data) {
7113
+ const newData = Object.create(Object.getPrototypeOf(data));
7114
+ Object.assign(newData, data);
7104
7115
  Object.keys(separatedKeys).forEach(key => {
7105
7116
  const value = separatedKeys[key];
7106
7117
  if (value !== null && value !== undefined) {
7107
- data[key] = value;
7118
+ newData[key] = value;
7108
7119
  }
7109
7120
  else {
7110
- delete data[key];
7121
+ delete newData[key];
7111
7122
  }
7112
7123
  });
7124
+ return newData;
7113
7125
  }
7114
7126
  return data;
7115
7127
  });
@@ -7126,22 +7138,15 @@ class GenericModalComponent {
7126
7138
  return;
7127
7139
  }
7128
7140
  const payloadKey = (field.keyToPayload ?? field.key);
7129
- if (field.type === FieldType.FILE) {
7130
- this.editedData.update(data => {
7131
- if (data) {
7132
- data[payloadKey] = value;
7133
- }
7134
- return data;
7135
- });
7136
- }
7137
- else {
7138
- this.editedData.update(data => {
7139
- if (data) {
7140
- data[payloadKey] = value;
7141
- }
7142
- return data;
7143
- });
7144
- }
7141
+ this.editedData.update(data => {
7142
+ if (data) {
7143
+ const newData = Object.create(Object.getPrototypeOf(data));
7144
+ Object.assign(newData, data);
7145
+ newData[payloadKey] = value;
7146
+ return newData;
7147
+ }
7148
+ return data;
7149
+ });
7145
7150
  const control = this.form().get(fieldKey);
7146
7151
  if (control) {
7147
7152
  control.setValue(value, { emitEvent: false });
@@ -7887,29 +7892,62 @@ class FileTemplateType {
7887
7892
  }
7888
7893
  }
7889
7894
 
7890
- // Safely extend dayjs with plugins (check if extend exists for Jest compatibility)
7891
- if (dayjs.extend) {
7892
- dayjs.extend(utc);
7893
- dayjs.extend(timezone);
7894
- }
7895
+ const utcPlugin = utc.default || utc;
7896
+ const tzPlugin = timezone.default || timezone;
7897
+ dayjs.extend(utcPlugin);
7898
+ dayjs.extend(tzPlugin);
7895
7899
  class DateUtility {
7900
+ static hasTz() {
7901
+ return typeof dayjs.tz === 'function';
7902
+ }
7903
+ static pad2(n) { return String(n).padStart(2, '0'); }
7904
+ static formatByPattern(d, pattern) {
7905
+ const dd = this.pad2(d.getUTCDate());
7906
+ const mm = this.pad2(d.getUTCMonth() + 1);
7907
+ const yyyy = d.getUTCFullYear();
7908
+ const HH = this.pad2(d.getUTCHours());
7909
+ const MM = this.pad2(d.getUTCMinutes());
7910
+ switch (pattern) {
7911
+ case 'DD/MM/YYYY HH:mm':
7912
+ return `${dd}/${mm}/${yyyy} ${HH}:${MM}`;
7913
+ case 'YYYY-MM-DD HH:mm':
7914
+ return `${yyyy}-${mm}-${dd} ${HH}:${MM}`;
7915
+ case 'YYYY-MM-DD':
7916
+ return `${yyyy}-${mm}-${dd}`;
7917
+ default:
7918
+ return d.toLocaleString();
7919
+ }
7920
+ }
7896
7921
  static fromUTCtoUruguay(date, outputFormat = 'DD/MM/YYYY HH:mm') {
7897
7922
  try {
7898
7923
  if (!date) {
7899
7924
  return '';
7900
7925
  }
7901
- let dayJsObj;
7902
- if (typeof date === 'string') {
7903
- dayJsObj = dayjs.utc(date);
7904
- }
7905
- else {
7906
- dayJsObj = dayjs.utc(date);
7926
+ const inputDate = new Date(date);
7927
+ if (isNaN(inputDate.getTime())) {
7928
+ console.error('Fecha inválida:', date);
7929
+ return '';
7907
7930
  }
7908
- return dayJsObj.tz('America/Montevideo').format(outputFormat);
7931
+ const offsetMs = 3 * 60 * 60 * 1000;
7932
+ const uyDate = new Date(inputDate.getTime() - offsetMs);
7933
+ return DateUtility.formatByPattern(uyDate, outputFormat);
7909
7934
  }
7910
7935
  catch (e) {
7911
7936
  console.error('Error al convertir fecha de UTC a Uruguay:', e);
7912
- return '';
7937
+ try {
7938
+ const d = typeof date === 'string' ? new Date(date) : date;
7939
+ if (!d || isNaN(d.getTime()))
7940
+ return '';
7941
+ const dd = String(d.getUTCDate()).padStart(2, '0');
7942
+ const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
7943
+ const yyyy = d.getUTCFullYear();
7944
+ const hh = String(d.getUTCHours()).padStart(2, '0');
7945
+ const min = String(d.getUTCMinutes()).padStart(2, '0');
7946
+ return `${dd}/${mm}/${yyyy} ${hh}:${min}`;
7947
+ }
7948
+ catch {
7949
+ return '';
7950
+ }
7913
7951
  }
7914
7952
  }
7915
7953
  static fromUTCtoUruguayWithInputFormat(date, inputFormat, outputFormat = 'DD/MM/YYYY HH:mm') {
@@ -7917,27 +7955,39 @@ class DateUtility {
7917
7955
  if (!date) {
7918
7956
  return '';
7919
7957
  }
7920
- let dayJsObj;
7958
+ let inputDate = null;
7921
7959
  if (typeof date === 'string') {
7922
- if (inputFormat) {
7923
- dayJsObj = dayjs(date, inputFormat).utc();
7924
- if (!dayJsObj.isValid()) {
7960
+ if (inputFormat === 'DD-MM-YYYY HH:mm') {
7961
+ const [dpart, tpart] = date.split(' ');
7962
+ if (!dpart || !tpart) {
7963
+ console.error('Error al parsear fecha con formato personalizado:', date, inputFormat);
7964
+ return '';
7965
+ }
7966
+ const [d, m, y] = dpart.split('-').map(Number);
7967
+ const [hh, mm] = tpart.split(':').map(Number);
7968
+ if (!y || !m || !d) {
7925
7969
  console.error('Error al parsear fecha con formato personalizado:', date, inputFormat);
7926
7970
  return '';
7927
7971
  }
7972
+ // Interpret as UTC time then shift to Uruguay
7973
+ inputDate = new Date(Date.UTC(y, m - 1, d, hh, mm, 0));
7928
7974
  }
7929
7975
  else {
7930
- dayJsObj = dayjs.utc(date);
7976
+ // Fallback: ISO-like strings
7977
+ const tmp = new Date(date);
7978
+ if (isNaN(tmp.getTime())) {
7979
+ console.error('Fecha inválida:', date);
7980
+ return '';
7981
+ }
7982
+ inputDate = tmp;
7931
7983
  }
7932
7984
  }
7933
7985
  else {
7934
- dayJsObj = dayjs.utc(date);
7935
- }
7936
- if (!dayJsObj.isValid()) {
7937
- console.error('Fecha inválida:', date);
7938
- return '';
7986
+ inputDate = new Date(date.getTime());
7939
7987
  }
7940
- return dayJsObj.tz('America/Montevideo').format(outputFormat);
7988
+ const offsetMs = 3 * 60 * 60 * 1000;
7989
+ const uyDate = new Date(inputDate.getTime() - offsetMs);
7990
+ return DateUtility.formatByPattern(uyDate, outputFormat);
7941
7991
  }
7942
7992
  catch (e) {
7943
7993
  console.error('Error al convertir fecha de UTC a Uruguay con formato de entrada:', e);
@@ -7949,23 +7999,33 @@ class DateUtility {
7949
7999
  if (!date) {
7950
8000
  return null;
7951
8001
  }
7952
- let dayJsObj;
7953
- if (typeof date === 'string') {
7954
- dayJsObj = dayjs.utc(date);
7955
- }
7956
- else {
7957
- dayJsObj = dayjs.utc(date);
8002
+ const inputDate = new Date(date);
8003
+ if (isNaN(inputDate.getTime())) {
8004
+ console.error('Fecha inválida:', date);
8005
+ return null;
7958
8006
  }
7959
- return dayJsObj.tz('America/Montevideo').toDate();
8007
+ const offsetMs = 3 * 60 * 60 * 1000;
8008
+ return new Date(inputDate.getTime() - offsetMs);
7960
8009
  }
7961
8010
  catch (e) {
7962
8011
  console.error('Error al convertir fecha de UTC a Uruguay:', e);
7963
- return null;
8012
+ try {
8013
+ const d = typeof date === 'string' ? new Date(date) : date;
8014
+ if (!d || isNaN(d.getTime()))
8015
+ return null;
8016
+ return d;
8017
+ }
8018
+ catch {
8019
+ return null;
8020
+ }
7964
8021
  }
7965
8022
  }
7966
8023
  static getCurrentUruguayTime(outputFormat = 'DD/MM/YYYY HH:mm') {
7967
8024
  try {
7968
- return dayjs().tz('America/Montevideo').format(outputFormat);
8025
+ const now = new Date();
8026
+ const offsetMs = 3 * 60 * 60 * 1000; // UTC-3
8027
+ const uy = new Date(now.getTime() - offsetMs);
8028
+ return DateUtility.formatByPattern(uy, outputFormat);
7969
8029
  }
7970
8030
  catch (e) {
7971
8031
  console.error('Error al obtener fecha actual de Uruguay:', e);
@@ -7977,14 +8037,29 @@ class DateUtility {
7977
8037
  if (!date) {
7978
8038
  return '';
7979
8039
  }
7980
- let dayJsObj;
8040
+ let inputDate = null;
7981
8041
  if (typeof date === 'string') {
7982
- dayJsObj = dayjs.tz(date, 'America/Montevideo');
8042
+ const parts = date.split('T');
8043
+ if (parts.length >= 2) {
8044
+ const [y, m, d] = parts[0].split('-').map(Number);
8045
+ const [hh, mm, ss] = parts[1].split(':').map(Number);
8046
+ inputDate = new Date(Date.UTC(y, m - 1, d, hh ?? 0, mm ?? 0, ss ?? 0));
8047
+ }
8048
+ else {
8049
+ const tmp = new Date(date);
8050
+ if (isNaN(tmp.getTime())) {
8051
+ console.error('Fecha inválida:', date);
8052
+ return '';
8053
+ }
8054
+ inputDate = tmp;
8055
+ }
7983
8056
  }
7984
8057
  else {
7985
- dayJsObj = dayjs.tz(date, 'America/Montevideo');
8058
+ inputDate = new Date(date.getTime());
7986
8059
  }
7987
- return dayJsObj.utc().format(outputFormat);
8060
+ const offsetMs = 3 * 60 * 60 * 1000;
8061
+ const utcDate = new Date(inputDate.getTime() + offsetMs);
8062
+ return DateUtility.formatByPattern(utcDate, outputFormat);
7988
8063
  }
7989
8064
  catch (e) {
7990
8065
  console.error('Error al convertir fecha de Uruguay a UTC:', e);
@@ -7996,15 +8071,21 @@ class DateUtility {
7996
8071
  if (!date1 || !date2) {
7997
8072
  return false;
7998
8073
  }
7999
- const uruguayDate1 = this.fromUTCtoUruguayDate(date1);
8000
- const uruguayDate2 = this.fromUTCtoUruguayDate(date2);
8001
- if (!uruguayDate1 || !uruguayDate2) {
8074
+ const d1 = new Date(date1);
8075
+ const d2 = new Date(date2);
8076
+ if (isNaN(d1.getTime()) || isNaN(d2.getTime())) {
8077
+ console.error('Fechas inválidas para comparación en Uruguay:', date1, date2);
8002
8078
  return false;
8003
8079
  }
8004
- return dayjs.tz(uruguayDate1, 'America/Montevideo').isSame(dayjs.tz(uruguayDate2, 'America/Montevideo'), 'day');
8080
+ const offsetMs = 3 * 60 * 60 * 1000;
8081
+ const d1Uy = new Date(d1.getTime() - offsetMs);
8082
+ const d2Uy = new Date(d2.getTime() - offsetMs);
8083
+ return (d1Uy.getUTCFullYear() === d2Uy.getUTCFullYear() &&
8084
+ d1Uy.getUTCMonth() === d2Uy.getUTCMonth() &&
8085
+ d1Uy.getUTCDate() === d2Uy.getUTCDate());
8005
8086
  }
8006
- catch (e) {
8007
- console.error('Error al comparar fechas en Uruguay:', e);
8087
+ catch (err) {
8088
+ console.error('Error al comparar fechas en Uruguay:', err);
8008
8089
  return false;
8009
8090
  }
8010
8091
  }
@@ -16007,12 +16088,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
16007
16088
  // Este archivo es generado automáticamente por scripts/update-version.js
16008
16089
  // No edites manualmente este archivo
16009
16090
  const VERSION = {
16010
- full: '2.15.27',
16091
+ full: '2.15.28',
16011
16092
  major: 2,
16012
16093
  minor: 15,
16013
- patch: 27,
16014
- timestamp: '2025-10-28T15:03:19.976Z',
16015
- buildDate: '28/10/2025'
16094
+ patch: 28,
16095
+ timestamp: '2025-11-04T16:16:41.680Z',
16096
+ buildDate: '4/11/2025'
16016
16097
  };
16017
16098
 
16018
16099
  class MainNavComponent {
@@ -16927,7 +17008,6 @@ class CustomClassService {
16927
17008
  this.rendererFactory = rendererFactory;
16928
17009
  this.dataStore = dataStore;
16929
17010
  this.renderer = this.rendererFactory.createRenderer(null, null);
16930
- // Initialize the store
16931
17011
  this.dataStore.hydrate(this.STORE_KEY, []);
16932
17012
  }
16933
17013
  ngOnDestroy() {
@@ -17024,9 +17104,7 @@ class CustomClassService {
17024
17104
  }
17025
17105
  const classes = Array.isArray(classNames) ? classNames : [classNames];
17026
17106
  elements.forEach(element => {
17027
- // Clear all existing classes
17028
17107
  element.className = '';
17029
- // Add new classes
17030
17108
  classes.forEach(className => {
17031
17109
  if (className && className.trim()) {
17032
17110
  this.renderer.addClass(element, className.trim());
@@ -17038,7 +17116,6 @@ class CustomClassService {
17038
17116
  }
17039
17117
  resolveElements(target, parent) {
17040
17118
  let searchContext = document;
17041
- // Resolve parent context if provided
17042
17119
  if (parent) {
17043
17120
  if (parent instanceof ElementRef) {
17044
17121
  searchContext = parent.nativeElement;
@@ -17056,41 +17133,32 @@ class CustomClassService {
17056
17133
  }
17057
17134
  }
17058
17135
  }
17059
- // ElementRef from ViewChild
17060
17136
  if (target instanceof ElementRef) {
17061
17137
  const element = target.nativeElement;
17062
- // If parent is specified, check if element is within parent
17063
17138
  if (parent && searchContext !== document) {
17064
17139
  return searchContext.contains(element) ? [element] : [];
17065
17140
  }
17066
17141
  return [element];
17067
17142
  }
17068
- // Direct HTMLElement
17069
17143
  if (target instanceof HTMLElement) {
17070
- // If parent is specified, check if element is within parent
17071
17144
  if (parent && searchContext !== document) {
17072
17145
  return searchContext.contains(target) ? [target] : [];
17073
17146
  }
17074
17147
  return [target];
17075
17148
  }
17076
- // NodeList or HTMLCollection
17077
17149
  if (target instanceof NodeList || target instanceof HTMLCollection) {
17078
17150
  const elements = Array.from(target);
17079
- // Filter by parent if specified
17080
17151
  if (parent && searchContext !== document) {
17081
17152
  return elements.filter(el => searchContext.contains(el));
17082
17153
  }
17083
17154
  return elements;
17084
17155
  }
17085
- // CSS Selector string
17086
17156
  if (typeof target === 'string') {
17087
17157
  const elements = searchContext.querySelectorAll(target);
17088
17158
  return Array.from(elements);
17089
17159
  }
17090
- // If it has a nativeElement property (custom wrapper)
17091
17160
  if (target && target.nativeElement instanceof HTMLElement) {
17092
17161
  const element = target.nativeElement;
17093
- // If parent is specified, check if element is within parent
17094
17162
  if (parent && searchContext !== document) {
17095
17163
  return searchContext.contains(element) ? [element] : [];
17096
17164
  }
@@ -18380,10 +18448,17 @@ class FilePreviewService {
18380
18448
  truncateFilename(filename, maxLength = 30) {
18381
18449
  if (filename.length <= maxLength)
18382
18450
  return filename;
18383
- const extension = filename.split('.').pop() || '';
18384
- const nameWithoutExtension = filename.substring(0, filename.lastIndexOf('.')) || filename;
18385
- const truncatedName = nameWithoutExtension.substring(0, maxLength - extension.length - 4) + '...';
18386
- return extension ? `${truncatedName}.${extension}` : truncatedName;
18451
+ const lastDotIndex = filename.lastIndexOf('.');
18452
+ const hasExtension = lastDotIndex > 0;
18453
+ if (hasExtension) {
18454
+ const extension = filename.substring(lastDotIndex + 1);
18455
+ const nameWithoutExtension = filename.substring(0, lastDotIndex);
18456
+ const truncatedName = nameWithoutExtension.substring(0, maxLength - extension.length - 4) + '...';
18457
+ return `${truncatedName}.${extension}`;
18458
+ }
18459
+ else {
18460
+ return filename.substring(0, maxLength - 3) + '...';
18461
+ }
18387
18462
  }
18388
18463
  isImage(contentType) {
18389
18464
  const result = getFilePreviewType(contentType) === FilePreviewType.IMAGE;
@@ -18394,13 +18469,6 @@ class FilePreviewService {
18394
18469
  return null;
18395
18470
  return null;
18396
18471
  }
18397
- /**
18398
- * Genera una vista previa real de la imagen desde S3
18399
- * @param file FilePreviewItem con los datos del archivo
18400
- * @param maxWidth Ancho máximo de la vista previa (default: 300px)
18401
- * @param maxHeight Alto máximo de la vista previa (default: 200px)
18402
- * @returns Observable<string> con la imagen en formato base64 o null si hay error
18403
- */
18404
18472
  generateImagePreview(file, maxWidth = 300, maxHeight = 200) {
18405
18473
  if (!this.isImage(file.contentType) || !file.s3Key) {
18406
18474
  return of(null);
@@ -18819,14 +18887,9 @@ class GenericChatComponent {
18819
18887
  if (!file) {
18820
18888
  return null;
18821
18889
  }
18822
- // Para archivos de imagen, intentar obtener URL en este orden de prioridad:
18823
- // 1. thumbnailUrl (URL optimizada para preview)
18824
- // 2. url (URL principal del archivo)
18825
- // 3. src (URL alternativa)
18826
18890
  if (this.isImageFilePreview(file)) {
18827
18891
  return file.thumbnailUrl || file.url || file.src || null;
18828
18892
  }
18829
- // Para archivos no imagen, usar URL principal
18830
18893
  return file.url || file.src || null;
18831
18894
  }
18832
18895
  getAttachmentPlaceholderUrl(file) {