tickera-angular-components 0.0.1-dev.186 → 0.0.1-dev.188

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.
@@ -4923,6 +4923,76 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4923
4923
  args: [{ providedIn: 'root' }]
4924
4924
  }], ctorParameters: () => [{ type: ApiService }] });
4925
4925
 
4926
+ /**
4927
+ * Servicio genérico de "cambios pendientes" para tablas con edición rápida
4928
+ * + guardado masivo (QTN-49, primer consumidor: Bonos de Regalo en
4929
+ * tickera-backoffice-frontend).
4930
+ *
4931
+ * IMPORTANTE: proveerlo a nivel de componente/página
4932
+ * (`providers: [PendingChangesService]` en el `@Component` que lo usa),
4933
+ * NUNCA en `providedIn: 'root'` — si no, dos tablas con edición rápida
4934
+ * abiertas al mismo tiempo (dos pestañas, o dos listados en la misma
4935
+ * sesión) compartirían el mismo estado de cambios pendientes. Mismo
4936
+ * criterio que ya sigue este repo con GiftBondService, provisto a nivel de
4937
+ * GiftBondDetailsComponent en vez de en 'root'.
4938
+ */
4939
+ class PendingChangesService {
4940
+ changesSignal = signal(new Map(), ...(ngDevMode ? [{ debugName: "changesSignal" }] : []));
4941
+ originalValues = new Map();
4942
+ changes = this.changesSignal.asReadonly();
4943
+ changeCount = computed(() => this.changesSignal().size, ...(ngDevMode ? [{ debugName: "changeCount" }] : []));
4944
+ hasChanges = computed(() => this.changesSignal().size > 0, ...(ngDevMode ? [{ debugName: "hasChanges" }] : []));
4945
+ /**
4946
+ * Registra (o actualiza) el cambio pendiente de `id`. `originalValue` es
4947
+ * el valor que tenía la fila antes de cualquier edición en esta sesión de
4948
+ * la tabla — solo se guarda la primera vez que se llama para ese id, así
4949
+ * que no importa pasarlo en cada llamada subsiguiente.
4950
+ *
4951
+ * Si `newValue` termina siendo igual al valor original, el id se
4952
+ * elimina automáticamente de los cambios pendientes (evita que quede
4953
+ * marcado como "modificado" un valor que el usuario cambió y luego
4954
+ * revirtió a mano).
4955
+ */
4956
+ setChange(id, originalValue, newValue) {
4957
+ if (!this.originalValues.has(id)) {
4958
+ this.originalValues.set(id, originalValue);
4959
+ }
4960
+ const next = new Map(this.changesSignal());
4961
+ if (newValue === this.originalValues.get(id)) {
4962
+ next.delete(id);
4963
+ this.originalValues.delete(id);
4964
+ }
4965
+ else {
4966
+ next.set(id, newValue);
4967
+ }
4968
+ this.changesSignal.set(next);
4969
+ }
4970
+ getPendingValue(id) {
4971
+ return this.changesSignal().get(id);
4972
+ }
4973
+ /** Descarta el cambio pendiente de una fila puntual (botón "Deshacer" por fila, si aplica). */
4974
+ discard(id) {
4975
+ const next = new Map(this.changesSignal());
4976
+ next.delete(id);
4977
+ this.changesSignal.set(next);
4978
+ this.originalValues.delete(id);
4979
+ }
4980
+ /** Descarta todos los cambios pendientes sin guardar nada (botón "Deshacer" de la barra flotante). */
4981
+ discardAll() {
4982
+ this.changesSignal.set(new Map());
4983
+ this.originalValues.clear();
4984
+ }
4985
+ /** Llamar después de que el guardado en lote fue exitoso, para limpiar el estado. */
4986
+ clearAfterSave() {
4987
+ this.discardAll();
4988
+ }
4989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PendingChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4990
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PendingChangesService });
4991
+ }
4992
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PendingChangesService, decorators: [{
4993
+ type: Injectable
4994
+ }] });
4995
+
4926
4996
  const authInterceptor = (req, next) => {
4927
4997
  const platformId = inject(PLATFORM_ID);
4928
4998
  const config = inject(TICKERA_COMPONENTS_CONFIG);
@@ -5508,14 +5578,25 @@ class DynamicTableComponent {
5508
5578
  this.pageSizeChange.emit(newSize); // El padre recibe el nuevo tamaño y refetch desde la página 1
5509
5579
  }
5510
5580
  }
5581
+ rowInjectors = new Map();
5582
+ ngOnChanges(changes) {
5583
+ if (changes['data']) {
5584
+ this.rowInjectors.clear();
5585
+ }
5586
+ }
5511
5587
  createInjector(row) {
5512
- return Injector.create({
5513
- providers: [{ provide: 'ROW_DATA', useValue: row }],
5514
- parent: this.injector,
5515
- });
5588
+ let rowInjector = this.rowInjectors.get(row);
5589
+ if (!rowInjector) {
5590
+ rowInjector = Injector.create({
5591
+ providers: [{ provide: 'ROW_DATA', useValue: row }],
5592
+ parent: this.injector,
5593
+ });
5594
+ this.rowInjectors.set(row, rowInjector);
5595
+ }
5596
+ return rowInjector;
5516
5597
  }
5517
5598
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DynamicTableComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
5518
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DynamicTableComponent, isStandalone: true, selector: "dynamic-table", inputs: { title: "title", data: "data", headers: "headers", searcherPlaceholder: "searcherPlaceholder", columnComponents: "columnComponents", isLoading: "isLoading", totalItems: "totalItems", itemsPerPage: "itemsPerPage", currentPage: "currentPage", searchValue: "searchValue", showPagination: "showPagination", showSearch: "showSearch", showTitle: "showTitle" }, outputs: { pageChange: "pageChange", searchChange: "searchChange", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<div class=\"dynamic-table\">\n @if (showTitle || showSearch) {\n <div class=\"dynamic-table-toolbar\">\n @if (showTitle) {\n <h2 class=\"dynamic-table-title\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n [placeholder]=\"searcherPlaceholder\"\n (input)=\"onSearch($event)\"\n type=\"search\"\n class=\"dynamic-table-search form-input\"\n />\n }\n </div>\n }\n\n <div class=\"dynamic-table-scroll\">\n <table class=\"dynamic-table-table\">\n <thead class=\"dynamic-table-head\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"dynamic-table-head-cell\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"dynamic-table-body\">\n @if (isLoading) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell\">\n <div class=\"dynamic-table-skeleton\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell dynamic-table-cell--nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n <span class=\"dynamic-table-cell--text\" [title]=\"row[header.key]\">\n {{ row[header.key] || '---' }}\n </span>\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td [attr.colspan]=\"headers.length\" class=\"dynamic-table-empty\">\n @if (searchValue.length > 0) {\n No se encontraron sedes que coincidan con <q>{{ searchValue }}</q>\n <br />\n Revisa la ortograf\u00EDa o limpia la b\u00FAsqueda\n } @else {\n No se encontraron a\u00FAn registros almacenados en base de datos.\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div class=\"dynamic-table-pagination\">\n <div class=\"dynamic-table-pagination-size\">\n <label for=\"page-size-select\" class=\"dynamic-table-pagination-size-label\">\n Items por p\u00E1gina\n </label>\n <select\n id=\"page-size-select\"\n class=\"dynamic-table-pagination-size-select\"\n [value]=\"itemsPerPage\"\n (change)=\"changePageSize($event)\"\n >\n @for (option of pageSizeOptions; track option) {\n <option [value]=\"option\" [selected]=\"option === itemsPerPage\">{{ option }}</option>\n }\n </select>\n </div>\n\n <div class=\"dynamic-table-pagination-info\">\n Mostrando p\u00E1gina\n <span class=\"dynamic-table-pagination-strong\">{{ currentPage }}</span> de\n <span class=\"dynamic-table-pagination-strong\">{{ totalPages }}</span>\n <span class=\"dynamic-table-pagination-total\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"dynamic-table-pagination-actions\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"totalPages <= 1 || currentPage === 1\"\n class=\"dynamic-table-pagination-button\"\n >\n Anterior\n </button>\n\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"totalPages <= 1 || currentPage >= totalPages\"\n class=\"dynamic-table-pagination-button\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".dynamic-table{background-color:#fff;border-radius:.5rem;overflow:hidden;border:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table{background-color:#1f2937;border-color:#374151}}.dynamic-table-toolbar{padding:1rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:flex-start}@media(prefers-color-scheme:dark){.dynamic-table-toolbar{border-color:#374151}}.dynamic-table-title{font-size:1.125rem;font-weight:600;margin:0}@media(prefers-color-scheme:dark){.dynamic-table-title{color:#fff}}.dynamic-table-search{margin-left:auto;max-width:24rem}.dynamic-table-scroll{overflow-x:auto}.dynamic-table-table{width:100%;text-align:left;border-collapse:collapse}.dynamic-table-head{background-color:#f3f4f6;color:#4b5563;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-head{background-color:#374151;color:#d1d5db}}.dynamic-table-head-cell{text-overflow:ellipsis;max-width:200px;padding:.75rem;border-bottom:1px solid #d1d5db;white-space:nowrap}@media(prefers-color-scheme:dark){.dynamic-table-head-cell{border-color:#4b5563}}.dynamic-table-body{color:#374151;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-body{color:#e5e7eb}}.dynamic-table-row{border-bottom:1px solid #e5e7eb;transition:background-color .15s ease-in-out}.dynamic-table-row:last-child{border-bottom:none}.dynamic-table-row:nth-child(2n){background-color:#f3f4f6}.dynamic-table-row:hover{background-color:#e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table-row{border-color:#374151}.dynamic-table-row:nth-child(2n){background-color:#37415180}.dynamic-table-row:hover{background-color:#374151}}.dynamic-table-cell{padding:.75rem}.dynamic-table-cell--nowrap{white-space:nowrap}.dynamic-table-cell--text{display:inline-block;overflow:hidden;text-overflow:ellipsis;max-width:280px}.dynamic-table-skeleton{height:1.25rem;width:100%;background-color:#e5e7eb;border-radius:.375rem;animation:dynamic-table-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.dynamic-table-skeleton{background-color:#4b5563}}.dynamic-table-empty{padding:1.5rem;text-align:center;color:#9ca3af;font-style:italic}@media(prefers-color-scheme:dark){.dynamic-table-empty{color:#6b7280}}.dynamic-table-pagination{padding:1rem;display:flex;align-items:center;justify-content:space-between;background-color:#f9fafb;border-top:1px solid #d1d5db}@media(prefers-color-scheme:dark){.dynamic-table-pagination{background-color:#1f293780;border-color:#374151}}.dynamic-table-pagination-info{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-info{color:#9ca3af}}.dynamic-table-pagination-strong{font-weight:600;color:#1f2937}@media(prefers-color-scheme:dark){.dynamic-table-pagination-strong{color:#fff}}.dynamic-table-pagination-total{margin-left:.25rem}.dynamic-table-pagination-actions{display:flex;gap:.5rem}.dynamic-table-pagination-size{display:flex;align-items:center;gap:.5rem}.dynamic-table-pagination-size-label{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-size-label{color:#9ca3af}}.dynamic-table-pagination-size-select{padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;color:#1f2937;cursor:pointer;transition:all .15s ease-in-out}.dynamic-table-pagination-size-select:hover{background-color:#f3f4f6}.dynamic-table-pagination-size-select:focus{outline:2px solid #4f46e5;outline-offset:-2px}@media(prefers-color-scheme:dark){.dynamic-table-pagination-size-select{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-size-select:hover{background-color:#4b5563}.dynamic-table-pagination-size-select:focus{outline-color:#6366f1}}.dynamic-table-pagination-button{display:flex;align-items:center;padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;transition:all .15s ease-in-out}.dynamic-table-pagination-button:hover{background-color:#f3f4f6}.dynamic-table-pagination-button:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.dynamic-table-pagination-button{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-button:hover{background-color:#4b5563}}@keyframes dynamic-table-pulse{0%,to{opacity:1}50%{opacity:.5}}\n", ".form-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-input-label{color:#d1d5db}}.form-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;outline:0;padding:.375rem .75rem;width:100%}.form-input::placeholder{color:#9ca3af}.form-input:focus{border-color:#1f2937}.form-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-input.error{background-color:#374151;outline-color:#ef4444}}.form-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-input.disabled{background-color:#374151;color:#d1d5db}}@media screen and (min-width:768px){.form-input{font-size:.875rem}}.form-input-required{color:#ef4444}.form-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
5599
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DynamicTableComponent, isStandalone: true, selector: "dynamic-table", inputs: { title: "title", data: "data", headers: "headers", searcherPlaceholder: "searcherPlaceholder", columnComponents: "columnComponents", isLoading: "isLoading", totalItems: "totalItems", itemsPerPage: "itemsPerPage", currentPage: "currentPage", searchValue: "searchValue", showPagination: "showPagination", showSearch: "showSearch", showTitle: "showTitle" }, outputs: { pageChange: "pageChange", searchChange: "searchChange", pageSizeChange: "pageSizeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"dynamic-table\">\n @if (showTitle || showSearch) {\n <div class=\"dynamic-table-toolbar\">\n @if (showTitle) {\n <h2 class=\"dynamic-table-title\">{{ title }}</h2>\n }\n\n @if (showSearch) {\n <input\n [placeholder]=\"searcherPlaceholder\"\n (input)=\"onSearch($event)\"\n type=\"search\"\n class=\"dynamic-table-search form-input\"\n />\n }\n </div>\n }\n\n <div class=\"dynamic-table-scroll\">\n <table class=\"dynamic-table-table\">\n <thead class=\"dynamic-table-head\">\n <tr>\n @for (header of headers; track header.key) {\n <th class=\"dynamic-table-head-cell\">\n {{ header.label }}\n </th>\n }\n </tr>\n </thead>\n\n <tbody class=\"dynamic-table-body\">\n @if (isLoading) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell\">\n <div class=\"dynamic-table-skeleton\"></div>\n </td>\n }\n </tr>\n }\n\n @for (row of data; track row) {\n <tr class=\"dynamic-table-row\">\n @for (header of headers; track header.key) {\n <td class=\"dynamic-table-cell dynamic-table-cell--nowrap\">\n @if (columnComponents[header.key]) {\n <ng-container\n *ngComponentOutlet=\"columnComponents[header.key]; injector: createInjector(row)\"\n ></ng-container>\n } @else {\n <span class=\"dynamic-table-cell--text\" [title]=\"row[header.key]\">\n {{ row[header.key] || '---' }}\n </span>\n }\n </td>\n }\n </tr>\n }\n\n @if ((!data || data.length < 1) && !isLoading) {\n <tr>\n <td [attr.colspan]=\"headers.length\" class=\"dynamic-table-empty\">\n @if (searchValue.length > 0) {\n No se encontraron sedes que coincidan con <q>{{ searchValue }}</q>\n <br />\n Revisa la ortograf\u00EDa o limpia la b\u00FAsqueda\n } @else {\n No se encontraron a\u00FAn registros almacenados en base de datos.\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n @if (showPagination) {\n <div class=\"dynamic-table-pagination\">\n <div class=\"dynamic-table-pagination-size\">\n <label for=\"page-size-select\" class=\"dynamic-table-pagination-size-label\">\n Items por p\u00E1gina\n </label>\n <select\n id=\"page-size-select\"\n class=\"dynamic-table-pagination-size-select\"\n [value]=\"itemsPerPage\"\n (change)=\"changePageSize($event)\"\n >\n @for (option of pageSizeOptions; track option) {\n <option [value]=\"option\" [selected]=\"option === itemsPerPage\">{{ option }}</option>\n }\n </select>\n </div>\n\n <div class=\"dynamic-table-pagination-info\">\n Mostrando p\u00E1gina\n <span class=\"dynamic-table-pagination-strong\">{{ currentPage }}</span> de\n <span class=\"dynamic-table-pagination-strong\">{{ totalPages }}</span>\n <span class=\"dynamic-table-pagination-total\">({{ totalItems }} registros totales)</span>\n </div>\n\n <div class=\"dynamic-table-pagination-actions\">\n <button\n (click)=\"changePage(-1)\"\n [disabled]=\"totalPages <= 1 || currentPage === 1\"\n class=\"dynamic-table-pagination-button\"\n >\n Anterior\n </button>\n\n <button\n (click)=\"changePage(1)\"\n [disabled]=\"totalPages <= 1 || currentPage >= totalPages\"\n class=\"dynamic-table-pagination-button\"\n >\n Siguiente\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".dynamic-table{background-color:#fff;border-radius:.5rem;overflow:hidden;border:1px solid #e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table{background-color:#1f2937;border-color:#374151}}.dynamic-table-toolbar{padding:1rem;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;justify-content:flex-start}@media(prefers-color-scheme:dark){.dynamic-table-toolbar{border-color:#374151}}.dynamic-table-title{font-size:1.125rem;font-weight:600;margin:0}@media(prefers-color-scheme:dark){.dynamic-table-title{color:#fff}}.dynamic-table-search{margin-left:auto;max-width:24rem}.dynamic-table-scroll{overflow-x:auto}.dynamic-table-table{width:100%;text-align:left;border-collapse:collapse}.dynamic-table-head{background-color:#f3f4f6;color:#4b5563;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-head{background-color:#374151;color:#d1d5db}}.dynamic-table-head-cell{text-overflow:ellipsis;max-width:200px;padding:.75rem;border-bottom:1px solid #d1d5db;white-space:nowrap}@media(prefers-color-scheme:dark){.dynamic-table-head-cell{border-color:#4b5563}}.dynamic-table-body{color:#374151;font-size:.75rem}@media(prefers-color-scheme:dark){.dynamic-table-body{color:#e5e7eb}}.dynamic-table-row{border-bottom:1px solid #e5e7eb;transition:background-color .15s ease-in-out}.dynamic-table-row:last-child{border-bottom:none}.dynamic-table-row:nth-child(2n){background-color:#f3f4f6}.dynamic-table-row:hover{background-color:#e5e7eb}@media(prefers-color-scheme:dark){.dynamic-table-row{border-color:#374151}.dynamic-table-row:nth-child(2n){background-color:#37415180}.dynamic-table-row:hover{background-color:#374151}}.dynamic-table-cell{padding:.75rem}.dynamic-table-cell--nowrap{white-space:nowrap}.dynamic-table-cell--text{display:inline-block;overflow:hidden;text-overflow:ellipsis;max-width:280px}.dynamic-table-skeleton{height:1.25rem;width:100%;background-color:#e5e7eb;border-radius:.375rem;animation:dynamic-table-pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media(prefers-color-scheme:dark){.dynamic-table-skeleton{background-color:#4b5563}}.dynamic-table-empty{padding:1.5rem;text-align:center;color:#9ca3af;font-style:italic}@media(prefers-color-scheme:dark){.dynamic-table-empty{color:#6b7280}}.dynamic-table-pagination{padding:1rem;display:flex;align-items:center;justify-content:space-between;background-color:#f9fafb;border-top:1px solid #d1d5db}@media(prefers-color-scheme:dark){.dynamic-table-pagination{background-color:#1f293780;border-color:#374151}}.dynamic-table-pagination-info{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-info{color:#9ca3af}}.dynamic-table-pagination-strong{font-weight:600;color:#1f2937}@media(prefers-color-scheme:dark){.dynamic-table-pagination-strong{color:#fff}}.dynamic-table-pagination-total{margin-left:.25rem}.dynamic-table-pagination-actions{display:flex;gap:.5rem}.dynamic-table-pagination-size{display:flex;align-items:center;gap:.5rem}.dynamic-table-pagination-size-label{font-size:.875rem;color:#6b7280}@media(prefers-color-scheme:dark){.dynamic-table-pagination-size-label{color:#9ca3af}}.dynamic-table-pagination-size-select{padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;color:#1f2937;cursor:pointer;transition:all .15s ease-in-out}.dynamic-table-pagination-size-select:hover{background-color:#f3f4f6}.dynamic-table-pagination-size-select:focus{outline:2px solid #4f46e5;outline-offset:-2px}@media(prefers-color-scheme:dark){.dynamic-table-pagination-size-select{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-size-select:hover{background-color:#4b5563}.dynamic-table-pagination-size-select:focus{outline-color:#6366f1}}.dynamic-table-pagination-button{display:flex;align-items:center;padding:.5rem 1rem;border:1px solid #d1d5db;border-radius:.5rem;background-color:#fff;font-size:.875rem;font-weight:500;transition:all .15s ease-in-out}.dynamic-table-pagination-button:hover{background-color:#f3f4f6}.dynamic-table-pagination-button:disabled{opacity:.4;cursor:not-allowed}@media(prefers-color-scheme:dark){.dynamic-table-pagination-button{background-color:#374151;border-color:#4b5563;color:#fff}.dynamic-table-pagination-button:hover{background-color:#4b5563}}@keyframes dynamic-table-pulse{0%,to{opacity:1}50%{opacity:.5}}\n", ".form-input-label{color:#374151;display:block;font-size:.875rem;font-weight:600;margin-bottom:.25rem}@media(prefers-color-scheme:dark){.form-input-label{color:#d1d5db}}.form-input{background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;color:#111827;display:block;outline:0;padding:.375rem .75rem;width:100%}.form-input::placeholder{color:#9ca3af}.form-input:focus{border-color:#1f2937}.form-input.error{outline-color:#ef4444}@media(prefers-color-scheme:dark){.form-input.error{background-color:#374151;outline-color:#ef4444}}.form-input.disabled{background-color:#e5e7eb;color:#6b7280;cursor:not-allowed}@media(prefers-color-scheme:dark){.form-input.disabled{background-color:#374151;color:#d1d5db}}@media screen and (min-width:768px){.form-input{font-size:.875rem}}.form-input-required{color:#ef4444}.form-input-error-message{color:#ef4444;font-size:.75rem;margin-top:.25rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
5519
5600
  }
5520
5601
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DynamicTableComponent, decorators: [{
5521
5602
  type: Component,
@@ -5605,6 +5686,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
5605
5686
  type: Input
5606
5687
  }] } });
5607
5688
 
5689
+ /**
5690
+ * Select genérico para editar un campo (típicamente "estado") directamente
5691
+ * en una celda de tabla, sin guardar de inmediato (QTN-49).
5692
+ *
5693
+ * Este componente es deliberadamente "tonto": no sabe a qué recurso
5694
+ * pertenece la fila ni cómo guardarla — solo muestra `options`, refleja
5695
+ * `value`, y emite `valueChange` cuando el usuario elige otra opción.
5696
+ * El componente que lo envuelve (p. ej. gift-bond-table-status en
5697
+ * tickera-backoffice-frontend) es quien conoce el id de la fila y decide
5698
+ * si guarda de inmediato o acumula el cambio en un
5699
+ * PendingChangesService + bulk-save-bar para guardado masivo.
5700
+ */
5701
+ class QuickStatusEditComponent {
5702
+ options = [];
5703
+ value;
5704
+ /** Resalta visualmente la celda como "modificada, sin guardar". */
5705
+ dirty = false;
5706
+ disabled = false;
5707
+ valueChange = new EventEmitter();
5708
+ onChange(newValue) {
5709
+ this.value = newValue;
5710
+ this.valueChange.emit(newValue);
5711
+ }
5712
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: QuickStatusEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5713
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: QuickStatusEditComponent, isStandalone: true, selector: "quick-status-edit", inputs: { options: "options", value: "value", dirty: "dirty", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<select\n class=\"quick-status-edit-select\"\n [class.quick-status-edit-select--dirty]=\"dirty\"\n [ngModel]=\"value\"\n [disabled]=\"disabled\"\n (ngModelChange)=\"onChange($event)\"\n>\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">{{ option.label }}</option>\n }\n</select>\n", styles: [".quick-status-edit-select{border:1px solid #d1d5db;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;background-color:#fff;cursor:pointer}.quick-status-edit-select--dirty{border-color:#f59e0b;background-color:#fffbeb}.quick-status-edit-select:disabled{cursor:not-allowed;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5714
+ }
5715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: QuickStatusEditComponent, decorators: [{
5716
+ type: Component,
5717
+ args: [{ selector: 'quick-status-edit', standalone: true, imports: [CommonModule, FormsModule], template: "<select\n class=\"quick-status-edit-select\"\n [class.quick-status-edit-select--dirty]=\"dirty\"\n [ngModel]=\"value\"\n [disabled]=\"disabled\"\n (ngModelChange)=\"onChange($event)\"\n>\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">{{ option.label }}</option>\n }\n</select>\n", styles: [".quick-status-edit-select{border:1px solid #d1d5db;border-radius:.375rem;padding:.25rem .5rem;font-size:.75rem;background-color:#fff;cursor:pointer}.quick-status-edit-select--dirty{border-color:#f59e0b;background-color:#fffbeb}.quick-status-edit-select:disabled{cursor:not-allowed;opacity:.6}\n"] }]
5718
+ }], propDecorators: { options: [{
5719
+ type: Input,
5720
+ args: [{ required: true }]
5721
+ }], value: [{
5722
+ type: Input
5723
+ }], dirty: [{
5724
+ type: Input
5725
+ }], disabled: [{
5726
+ type: Input
5727
+ }], valueChange: [{
5728
+ type: Output
5729
+ }] } });
5730
+
5731
+ /**
5732
+ * Barra flotante "Guardar cambios" para guardado masivo (QTN-49).
5733
+ *
5734
+ * No conoce el recurso concreto ni cómo persistir los cambios — el
5735
+ * componente que la usa le pasa `[count]` (típicamente
5736
+ * `pendingChangesService.changeCount()`) y escucha `(save)`/`(discard)`
5737
+ * para llamar al endpoint bulk correspondiente.
5738
+ */
5739
+ class BulkSaveBarComponent {
5740
+ count = 0;
5741
+ loading = false;
5742
+ saveLabel = 'Guardar cambios';
5743
+ discardLabel = 'Deshacer';
5744
+ save = new EventEmitter();
5745
+ discard = new EventEmitter();
5746
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BulkSaveBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5747
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: BulkSaveBarComponent, isStandalone: true, selector: "bulk-save-bar", inputs: { count: "count", loading: "loading", saveLabel: "saveLabel", discardLabel: "discardLabel" }, outputs: { save: "save", discard: "discard" }, ngImport: i0, template: "@if (count > 0) {\n <div class=\"bulk-save-bar\">\n <span class=\"bulk-save-bar__badge\">{{ count }}</span>\n <span class=\"bulk-save-bar__label\">\n {{ count === 1 ? '1 cambio sin guardar' : count + ' cambios sin guardar' }}\n </span>\n <button\n type=\"button\"\n class=\"bulk-save-bar__discard\"\n [disabled]=\"loading\"\n (click)=\"discard.emit()\"\n >\n {{ discardLabel }}\n </button>\n <button\n type=\"button\"\n class=\"bulk-save-bar__save\"\n [disabled]=\"loading\"\n (click)=\"save.emit()\"\n >\n {{ loading ? 'Guardando...' : saveLabel }}\n </button>\n </div>\n}\n", styles: [".bulk-save-bar{position:fixed;bottom:1.5rem;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.75rem;background-color:#111827;color:#fff;border-radius:9999px;padding:.5rem .75rem .5rem 1rem;box-shadow:0 10px 25px #00000040;z-index:40}.bulk-save-bar__badge{background-color:#f59e0b;color:#111827;font-weight:700;font-size:.75rem;border-radius:9999px;min-width:1.25rem;height:1.25rem;display:inline-flex;align-items:center;justify-content:center;padding:0 .375rem}.bulk-save-bar__label{font-size:.8125rem;white-space:nowrap}.bulk-save-bar__discard,.bulk-save-bar__save{border:none;border-radius:9999px;padding:.375rem .875rem;font-size:.75rem;font-weight:600;cursor:pointer}.bulk-save-bar__discard:disabled,.bulk-save-bar__save:disabled{cursor:not-allowed;opacity:.6}.bulk-save-bar__discard{background-color:transparent;color:#d1d5db}.bulk-save-bar__discard:hover:not(:disabled){color:#fff}.bulk-save-bar__save{background-color:#fff;color:#111827}.bulk-save-bar__save:hover:not(:disabled){background-color:#f3f4f6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
5748
+ }
5749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BulkSaveBarComponent, decorators: [{
5750
+ type: Component,
5751
+ args: [{ selector: 'bulk-save-bar', standalone: true, imports: [CommonModule], template: "@if (count > 0) {\n <div class=\"bulk-save-bar\">\n <span class=\"bulk-save-bar__badge\">{{ count }}</span>\n <span class=\"bulk-save-bar__label\">\n {{ count === 1 ? '1 cambio sin guardar' : count + ' cambios sin guardar' }}\n </span>\n <button\n type=\"button\"\n class=\"bulk-save-bar__discard\"\n [disabled]=\"loading\"\n (click)=\"discard.emit()\"\n >\n {{ discardLabel }}\n </button>\n <button\n type=\"button\"\n class=\"bulk-save-bar__save\"\n [disabled]=\"loading\"\n (click)=\"save.emit()\"\n >\n {{ loading ? 'Guardando...' : saveLabel }}\n </button>\n </div>\n}\n", styles: [".bulk-save-bar{position:fixed;bottom:1.5rem;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.75rem;background-color:#111827;color:#fff;border-radius:9999px;padding:.5rem .75rem .5rem 1rem;box-shadow:0 10px 25px #00000040;z-index:40}.bulk-save-bar__badge{background-color:#f59e0b;color:#111827;font-weight:700;font-size:.75rem;border-radius:9999px;min-width:1.25rem;height:1.25rem;display:inline-flex;align-items:center;justify-content:center;padding:0 .375rem}.bulk-save-bar__label{font-size:.8125rem;white-space:nowrap}.bulk-save-bar__discard,.bulk-save-bar__save{border:none;border-radius:9999px;padding:.375rem .875rem;font-size:.75rem;font-weight:600;cursor:pointer}.bulk-save-bar__discard:disabled,.bulk-save-bar__save:disabled{cursor:not-allowed;opacity:.6}.bulk-save-bar__discard{background-color:transparent;color:#d1d5db}.bulk-save-bar__discard:hover:not(:disabled){color:#fff}.bulk-save-bar__save{background-color:#fff;color:#111827}.bulk-save-bar__save:hover:not(:disabled){background-color:#f3f4f6}\n"] }]
5752
+ }], propDecorators: { count: [{
5753
+ type: Input
5754
+ }], loading: [{
5755
+ type: Input
5756
+ }], saveLabel: [{
5757
+ type: Input
5758
+ }], discardLabel: [{
5759
+ type: Input
5760
+ }], save: [{
5761
+ type: Output
5762
+ }], discard: [{
5763
+ type: Output
5764
+ }] } });
5765
+
5608
5766
  class ShowTypeBadgeComponent {
5609
5767
  show;
5610
5768
  size = 'xs';
@@ -10955,5 +11113,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
10955
11113
  * Generated bundle index. Do not edit.
10956
11114
  */
10957
11115
 
10958
- export { ADMIN_API_ROUTES, ADMISSION_API_ROUTES, ALERT_ICONS, AdminSelectComponent, AdminService, AdmissionQueueService, ApiService, AppAlertComponent, AppBadgeComponent, AppBreadcumbComponent, AppButtonComponent, AppLinkButtonComponent, AppModalComponent, AsyncSelectComponent, AuditInformationComponent, BASE_BUTTON_CLASSES, BASE_INPUT_CLASSES, BUTTON_SIZES_CLASSES, BUTTON_VARIANT_CLASSES, BaseModalService, BrowserZoomLockService, CITY_API_ENDPOINTS, COUNTRY_API_ENDPOINTS, CUSTOMERS_API_ROUTES, ChangePasswordFormComponent, ChangePasswordFormService, CitiesService, CitySelectComponent, ColorPickerComponent, ConfirmationOrderModalComponent, ConfirmationOrderModalService, CorporateBondStatus, CountrySelectComponent, CountryService, CouponApplicability, CouponDiscountType, CouponStatus, CreatorType, CustomerSelectComponent, CustomerService, DEFAULT_STAGE_CONFIG, DOCUMENT_TYPES_OPTIONS, DateInputComponent, DateService, DaySelectorGridComponent, DeleteConfirmationComponent, DeleteConfirmationService, DynamicTableComponent, ERROR_INPUT_CLASSES, EndDateGreaterThanStartValidator, FORM_ERROR_MESSAGES, FeedbackModalComponent, FeedbackModalService, FileType, FileUploadComponent, FileUploadPreviewComponent, FormEditorComponent, FormInputComponent, FormSelectComponent, FormTextareaComponent, GiftBondPurchaseStatus, GiftBondStatus, IdentityDocumentInputComponent, KONVA_SHAPE_MAPPINGS, LanguageSwitcherComponent, MembershipStatus, MinTodayValidator, MustMatchValidator, NumberInputComponent, ORDER_DISCOUNT_COLORS, ORDER_ITEM_TYPES_COLORS, ORDER_STATUS_COLORS, OrderBillingInfoComponent, OrderDiscountAppliedComponent, OrderInformationComponent, OrderItemType, OrderItemTypeBadgeComponent, OrderItemsComponent, OrderStatus, OrderStatusBadgeComponent, OrderTransactionDetailsModalComponent, OrderTransactionDetailsModalService, OrderTransactionsComponent, PAYMENT_METHODS_OPTIONS, PERFORMANCES_API_ROUTES, PERFORMANCE_STATUS_COLORS, PERFORMANCE_TICKET_STATUS_COLORS, PHONE_COUNTRIES, PRICE_ZONES_API_ROUTES, PRODUCTS_API_ROUTES, PRODUCT_CATEGORIES_API_ROUTES, PRODUCT_TAGS_API_ROUTES, PRODUCT_TYPES_API_ROUTES, PaymentMethod, PerformanceBookingDataService, PerformanceCardComponent, PerformanceCardListComponent, PerformanceMultiSelectComponent, PerformanceSelectComponent, PerformanceService, PerformanceStatus, PerformanceStatusBadgeComponent, PerformanceStepperComponent, PerformanceTicketMapComponent, PerformanceTicketStatus, PerformanceTicketStatusBadgeComponent, PerformancesListEventsService, PhoneInputComponent, PriceZoneEventService, PriceZoneFormModalService, PriceZoneSelectComponent, PriceZoneService, ProductCategoryService, ProductMultiSelectComponent, ProductSelectComponent, ProductService, ProductTagService, ProductTypeService, PurchaseLimitService, RoomMapElementOrientation, RoomMapElementType, SHOWS_API_ROUTES, SHOW_TYPE_COLORS, STATE_API_ENDPOINTS, SeatAvailabilitySseService, SeatSelectionEmptySummaryComponent, SeatSelectionSummaryComponent, SeatSelectionSummaryItemComponent, SelectedDiscountCardType, ShowCardComponent, ShowCardSkeletonComponent, ShowMultiSelectComponent, ShowSelectComponent, ShowService, ShowType, ShowTypeBadgeComponent, ShowsFilterComponent, StateSelectComponent, StatesService, TICKERA_COMPONENTS_CONFIG, TICKET_ELEMENT_TYPES, TICKET_MAP_GRID_SIZE, TICKET_MAP_LAST_TICKETS_LIMIT, TICKET_MAP_TITLE_HEIGHT, TICKET_STATUS_COLORS, TICKET_STATUS_FILLS, TICKET_STATUS_LABELS, TIcketMapProductSelectionComponent, TRANSACTION_STATUS_COLORS, TextExpandableComponent, TickeraTranslocoLoader, TicketMapFloorSelectorComponent, TicketMapPriceZonesComponent, TicketMapProductSelectionItemComponent, TicketMapTotalsComponent, TicketMapWidgetComponent, TicketMapWidgetHeaderComponent, TicketMapWrapperComponent, TicketMapZoomControlsComponent, TicketMapZoomService, TicketQrComponent, TicketQrModalComponent, TicketQrModalService, TicketQrService, TicketSelectionDetailsService, TicketSelectionDiscountService, TicketSelectionService, TicketSelectionTotalsService, ToastService, ToggleSwitchComponent, TransactionStatus, VENUES_API_ROUTES, VIP_CARDS_API_ROUTES, VipBalanceCardComponent, VipCardService, VipCardStatus, VipCardStatusBadgeComponent, VipRechargeModalComponent, VipTransactionType, VipTransactionsTableComponent, ZonePriceItemComponent, ZonePriceListComponent, authInterceptor, drawChairIcon$1 as drawChairIcon, drawHappyFace, drawRoundedRect, drawWheelchairIcon, emailValidator, findElementAtPosition, findTicketAtPosition, formatCitiesResponseToSelect, generateExitScene, generateHallwayScene, generateProductionAreaScene, generateSeatBlockScene, generateSeatBlockTicketScene, generateStageScene, generateStairScene, generateTableScene, generateTableTicketScene, generateUnavailableSpaceScene, generateZoneScene, getBrowserLanguage, getCustomerFullname, getItemTypeIcon, getOrderDiscount, getStoredLanguage, numberToLetter$1 as numberToLetter, parseJsonToFormDataAdvanced, phoneCountryFlag, processElementsToRenderData, provideTickeraComponents, resolveLanguage, setStoredLanguage, ticketCanOpenQr, tintColor, transformImageToFile, transformUrlParams };
11116
+ export { ADMIN_API_ROUTES, ADMISSION_API_ROUTES, ALERT_ICONS, AdminSelectComponent, AdminService, AdmissionQueueService, ApiService, AppAlertComponent, AppBadgeComponent, AppBreadcumbComponent, AppButtonComponent, AppLinkButtonComponent, AppModalComponent, AsyncSelectComponent, AuditInformationComponent, BASE_BUTTON_CLASSES, BASE_INPUT_CLASSES, BUTTON_SIZES_CLASSES, BUTTON_VARIANT_CLASSES, BaseModalService, BrowserZoomLockService, BulkSaveBarComponent, CITY_API_ENDPOINTS, COUNTRY_API_ENDPOINTS, CUSTOMERS_API_ROUTES, ChangePasswordFormComponent, ChangePasswordFormService, CitiesService, CitySelectComponent, ColorPickerComponent, ConfirmationOrderModalComponent, ConfirmationOrderModalService, CorporateBondStatus, CountrySelectComponent, CountryService, CouponApplicability, CouponDiscountType, CouponStatus, CreatorType, CustomerSelectComponent, CustomerService, DEFAULT_STAGE_CONFIG, DOCUMENT_TYPES_OPTIONS, DateInputComponent, DateService, DaySelectorGridComponent, DeleteConfirmationComponent, DeleteConfirmationService, DynamicTableComponent, ERROR_INPUT_CLASSES, EndDateGreaterThanStartValidator, FORM_ERROR_MESSAGES, FeedbackModalComponent, FeedbackModalService, FileType, FileUploadComponent, FileUploadPreviewComponent, FormEditorComponent, FormInputComponent, FormSelectComponent, FormTextareaComponent, GiftBondPurchaseStatus, GiftBondStatus, IdentityDocumentInputComponent, KONVA_SHAPE_MAPPINGS, LanguageSwitcherComponent, MembershipStatus, MinTodayValidator, MustMatchValidator, NumberInputComponent, ORDER_DISCOUNT_COLORS, ORDER_ITEM_TYPES_COLORS, ORDER_STATUS_COLORS, OrderBillingInfoComponent, OrderDiscountAppliedComponent, OrderInformationComponent, OrderItemType, OrderItemTypeBadgeComponent, OrderItemsComponent, OrderStatus, OrderStatusBadgeComponent, OrderTransactionDetailsModalComponent, OrderTransactionDetailsModalService, OrderTransactionsComponent, PAYMENT_METHODS_OPTIONS, PERFORMANCES_API_ROUTES, PERFORMANCE_STATUS_COLORS, PERFORMANCE_TICKET_STATUS_COLORS, PHONE_COUNTRIES, PRICE_ZONES_API_ROUTES, PRODUCTS_API_ROUTES, PRODUCT_CATEGORIES_API_ROUTES, PRODUCT_TAGS_API_ROUTES, PRODUCT_TYPES_API_ROUTES, PaymentMethod, PendingChangesService, PerformanceBookingDataService, PerformanceCardComponent, PerformanceCardListComponent, PerformanceMultiSelectComponent, PerformanceSelectComponent, PerformanceService, PerformanceStatus, PerformanceStatusBadgeComponent, PerformanceStepperComponent, PerformanceTicketMapComponent, PerformanceTicketStatus, PerformanceTicketStatusBadgeComponent, PerformancesListEventsService, PhoneInputComponent, PriceZoneEventService, PriceZoneFormModalService, PriceZoneSelectComponent, PriceZoneService, ProductCategoryService, ProductMultiSelectComponent, ProductSelectComponent, ProductService, ProductTagService, ProductTypeService, PurchaseLimitService, QuickStatusEditComponent, RoomMapElementOrientation, RoomMapElementType, SHOWS_API_ROUTES, SHOW_TYPE_COLORS, STATE_API_ENDPOINTS, SeatAvailabilitySseService, SeatSelectionEmptySummaryComponent, SeatSelectionSummaryComponent, SeatSelectionSummaryItemComponent, SelectedDiscountCardType, ShowCardComponent, ShowCardSkeletonComponent, ShowMultiSelectComponent, ShowSelectComponent, ShowService, ShowType, ShowTypeBadgeComponent, ShowsFilterComponent, StateSelectComponent, StatesService, TICKERA_COMPONENTS_CONFIG, TICKET_ELEMENT_TYPES, TICKET_MAP_GRID_SIZE, TICKET_MAP_LAST_TICKETS_LIMIT, TICKET_MAP_TITLE_HEIGHT, TICKET_STATUS_COLORS, TICKET_STATUS_FILLS, TICKET_STATUS_LABELS, TIcketMapProductSelectionComponent, TRANSACTION_STATUS_COLORS, TextExpandableComponent, TickeraTranslocoLoader, TicketMapFloorSelectorComponent, TicketMapPriceZonesComponent, TicketMapProductSelectionItemComponent, TicketMapTotalsComponent, TicketMapWidgetComponent, TicketMapWidgetHeaderComponent, TicketMapWrapperComponent, TicketMapZoomControlsComponent, TicketMapZoomService, TicketQrComponent, TicketQrModalComponent, TicketQrModalService, TicketQrService, TicketSelectionDetailsService, TicketSelectionDiscountService, TicketSelectionService, TicketSelectionTotalsService, ToastService, ToggleSwitchComponent, TransactionStatus, VENUES_API_ROUTES, VIP_CARDS_API_ROUTES, VipBalanceCardComponent, VipCardService, VipCardStatus, VipCardStatusBadgeComponent, VipRechargeModalComponent, VipTransactionType, VipTransactionsTableComponent, ZonePriceItemComponent, ZonePriceListComponent, authInterceptor, drawChairIcon$1 as drawChairIcon, drawHappyFace, drawRoundedRect, drawWheelchairIcon, emailValidator, findElementAtPosition, findTicketAtPosition, formatCitiesResponseToSelect, generateExitScene, generateHallwayScene, generateProductionAreaScene, generateSeatBlockScene, generateSeatBlockTicketScene, generateStageScene, generateStairScene, generateTableScene, generateTableTicketScene, generateUnavailableSpaceScene, generateZoneScene, getBrowserLanguage, getCustomerFullname, getItemTypeIcon, getOrderDiscount, getStoredLanguage, numberToLetter$1 as numberToLetter, parseJsonToFormDataAdvanced, phoneCountryFlag, processElementsToRenderData, provideTickeraComponents, resolveLanguage, setStoredLanguage, ticketCanOpenQr, tintColor, transformImageToFile, transformUrlParams };
10959
11117
  //# sourceMappingURL=tickera-angular-components.mjs.map