diff --git a/src/app/components/custom-select/custom-select.html b/src/app/components/custom-select/custom-select.html index 6b77859..6fd6bb0 100644 --- a/src/app/components/custom-select/custom-select.html +++ b/src/app/components/custom-select/custom-select.html @@ -7,7 +7,7 @@ [attr.aria-disabled]="disabled" > {{ displayLabel }} - +
diff --git a/src/app/components/custom-select/custom-select.scss b/src/app/components/custom-select/custom-select.scss index 117324d..4ffab52 100644 --- a/src/app/components/custom-select/custom-select.scss +++ b/src/app/components/custom-select/custom-select.scss @@ -75,7 +75,8 @@ white-space: nowrap; } -.app-select-trigger .app-select-chevron { + +.app-select-trigger i { position: absolute; right: 8px; top: 50%; diff --git a/src/app/pages/geral/geral.html b/src/app/pages/geral/geral.html index 796667f..0317570 100644 --- a/src/app/pages/geral/geral.html +++ b/src/app/pages/geral/geral.html @@ -98,19 +98,27 @@ -
- - -
+ + + + +
@@ -339,37 +347,35 @@ -
-
- - Selecionadas: {{ batchStatusSelectionCount }} - - - -
+
+ + Itens por pág: + -
- - Itens por pág: - - -
- -
+
+
+ +
+ + Selecionadas: {{ batchStatusSelectionCount }} + + + +
diff --git a/src/app/pages/geral/geral.scss b/src/app/pages/geral/geral.scss index 6519cc5..2056380 100644 --- a/src/app/pages/geral/geral.scss +++ b/src/app/pages/geral/geral.scss @@ -143,88 +143,13 @@ .filters-row-top { justify-content: center; - z-index: 60; } .filters-row-bottom { justify-content: center; - z-index: 40; -} -.filter-tabs { display: flex; gap: 4px; padding: 4px; background: rgba(255, 255, 255, 0.6); border: 1px solid rgba(17, 18, 20, 0.08); border-radius: 12px; backdrop-filter: blur(8px); flex-wrap: wrap; justify-content: center; } -.filter-tab { border: none; background: transparent; padding: 8px 16px; border-radius: 8px; font-size: 0.85rem; font-weight: 700; color: var(--muted); transition: all 0.2s ease; display: flex; align-items: center; gap: 6px; flex: 0 0 auto; white-space: nowrap; line-height: 1.1; &:hover { color: var(--text); background: rgba(255, 255, 255, 0.5); } &.active { background: #fff; color: var(--brand); box-shadow: 0 2px 8px rgba(227, 61, 207, 0.15); } &:disabled { opacity: 0.5; cursor: not-allowed; } } -.filter-blocked-select-box { width: 196px; flex: 0 0 auto; position: relative; z-index: 80; } -.blocked-status-select-icon { - position: absolute; - left: 11px; - top: 50%; - transform: translateY(-50%); - z-index: 2; - pointer-events: none; - color: rgba(17, 18, 20, 0.68); - font-size: 0.82rem; -} -.blocked-status-native-select { - width: 100%; - height: 36px; - border-radius: 12px; - border: 1px solid rgba(17, 18, 20, 0.15); - background: rgba(255, 255, 255, 0.7); - color: #0f172a; - font-size: 0.78rem; - font-weight: 800; - padding: 0 30px 0 30px; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); - appearance: none; - -webkit-appearance: none; - transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; - - &:hover { - background: #fff; - border-color: rgba(17, 18, 20, 0.7); - box-shadow: 0 4px 12px rgba(3, 15, 170, 0.1); - } - - &:focus { - outline: none; - border-color: #e33dcf; - box-shadow: 0 0 0 3px rgba(227, 61, 207, 0.15); - } - - &:disabled { - background-color: #f1f5f9; - color: #94a3b8; - cursor: not-allowed; - } -} - -@media (max-width: 1366px) { - .filter-tabs { - gap: 3px; - padding: 3px; - } - - .filter-tab { - padding: 7px 12px; - font-size: 0.78rem; - gap: 5px; - } - - .filter-blocked-select-box { - width: 184px; - } -} - -@media (max-width: 1200px) { - .filter-tab { - padding: 6px 10px; - font-size: 0.74rem; - gap: 4px; - } - - .filter-blocked-select-box { - width: 176px; - } } +.filter-tabs { display: flex; gap: 4px; padding: 4px; background: rgba(255, 255, 255, 0.6); border: 1px solid rgba(17, 18, 20, 0.08); border-radius: 12px; backdrop-filter: blur(8px); } +.filter-tab { border: none; background: transparent; padding: 8px 16px; border-radius: 8px; font-size: 0.85rem; font-weight: 700; color: var(--muted); transition: all 0.2s ease; display: flex; align-items: center; gap: 6px; &:hover { color: var(--text); background: rgba(255, 255, 255, 0.5); } &.active { background: #fff; color: var(--brand); box-shadow: 0 2px 8px rgba(227, 61, 207, 0.15); } &:disabled { opacity: 0.5; cursor: not-allowed; } } .client-filter-wrap { position: relative; z-index: 40; } .btn-client-filter { display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 12px; border: 1px solid rgba(17, 18, 20, 0.08); background: rgba(255, 255, 255, 0.6); color: var(--muted); font-weight: 700; font-size: 0.85rem; backdrop-filter: blur(8px); transition: all 0.2s; min-height: 38px; height: auto; flex-wrap: wrap; &:hover { background: #fff; border-color: var(--blue); color: var(--blue); } &.active, &.has-selection { background: #fff; border-color: var(--brand); } } @@ -410,32 +335,17 @@ /* Controls */ .controls { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; } -.controls-right { - margin-left: auto; - display: flex; - align-items: center; - justify-content: flex-end; - gap: 12px; - flex-wrap: wrap; - - @media (max-width: 900px) { - width: 100%; - justify-content: space-between; - } - - @media (max-width: 500px) { - gap: 8px; - } -} .search-group { max-width: 270px; border-radius: 12px; overflow: hidden; display: flex; align-items: stretch; background: #fff; border: 1px solid rgba(17, 18, 20, 0.15); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04); transition: all 0.2s ease; &:focus-within { border-color: var(--brand); box-shadow: 0 4px 12px rgba(227, 61, 207, 0.15); transform: translateY(-1px); } .input-group-text { background: transparent; border: none; color: var(--muted); padding-left: 14px; padding-right: 8px; display: flex; align-items: center; i { font-size: 1rem; } } .form-control { border: none; background: transparent; padding: 10px 0; font-size: 0.9rem; color: var(--text); box-shadow: none; &::placeholder { color: rgba(17, 18, 20, 0.4); font-weight: 500; } &:focus { outline: none; } } .btn-clear { background: transparent; border: none; color: var(--muted); padding: 0 12px; display: flex; align-items: center; cursor: pointer; transition: color 0.2s; &:hover { color: #dc3545; } i { font-size: 1rem; } } } -.page-size { @media (max-width: 500px) { width: 100%; justify-content: space-between; } } +.page-size { margin-left: auto; @media (max-width: 500px) { margin-left: 0; width: 100%; justify-content: space-between; } } .batch-status-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; + margin-left: auto; @media (max-width: 900px) { + margin-left: 0; width: 100%; } } diff --git a/src/app/pages/geral/geral.spec.ts b/src/app/pages/geral/geral.spec.ts index 8cc0768..4f94d6b 100644 --- a/src/app/pages/geral/geral.spec.ts +++ b/src/app/pages/geral/geral.spec.ts @@ -144,23 +144,6 @@ describe('Geral', () => { expect(filtered[0].status).toBe('ATIVO'); }); - it('should filter only pre-activation blocked lines when PRE_ATIVACAO is selected', () => { - component.filterStatus = 'BLOCKED'; - component.blockedStatusMode = 'PRE_ATIVACAO'; - component.filterOperadora = 'ALL'; - component.filterContaEmpresa = ''; - component.additionalMode = 'ALL'; - component.selectedAdditionalServices = []; - - const filtered = (component as any).applyAdditionalFiltersClientSide([ - { id: '1', item: 1, conta: '1', linha: '11911111111', cliente: 'A', usuario: 'U', vencConta: null, status: 'BLOQUEIO DE PRE ATIVACAO' }, - { id: '2', item: 2, conta: '2', linha: '11922222222', cliente: 'B', usuario: 'U', vencConta: null, status: 'BLOQUEIO 120 DIAS' }, - ]); - - expect(filtered.length).toBe(1); - expect(filtered[0].status).toBe('BLOQUEIO DE PRE ATIVACAO'); - }); - it('should classify active line as ACTIVE during smart search resolution', () => { const target = (component as any).buildSmartSearchTarget({ id: '1', @@ -177,33 +160,6 @@ describe('Geral', () => { expect(target?.statusFilter).toBe('ACTIVE'); }); - it('should classify pre-activation line as blocked during smart search resolution', () => { - const target = (component as any).buildSmartSearchTarget({ - id: '1', - item: 1, - conta: '1', - linha: '11911111111', - cliente: 'CLIENTE A', - usuario: 'USUARIO A', - vencConta: null, - status: 'BLOQUEIO DE PRE ATIVACAO', - skil: 'PESSOA JURIDICA', - }, true); - - expect(target?.statusFilter).toBe('BLOCKED'); - expect(target?.blockedStatusMode).toBe('PRE_ATIVACAO'); - }); - - it('should toggle blocked select filter off when selecting the same blocked option again', () => { - component.setBlockedStatusFilter('BLOQUEIO_120'); - expect(component.filterStatus).toBe('BLOCKED'); - expect(component.blockedStatusMode).toBe('BLOQUEIO_120'); - - component.setBlockedStatusFilter('BLOQUEIO_120'); - expect(component.filterStatus).toBe('ALL'); - expect(component.blockedStatusMode).toBe('ALL'); - }); - it('should request assigned reserve lines in ALL filter only', () => { component.filterSkil = 'ALL'; let params = (component as any).applyBaseFilters(new HttpParams()); diff --git a/src/app/pages/geral/geral.ts b/src/app/pages/geral/geral.ts index 3ccfba5..06efc75 100644 --- a/src/app/pages/geral/geral.ts +++ b/src/app/pages/geral/geral.ts @@ -68,7 +68,7 @@ type CreateEntryMode = 'SINGLE' | 'BATCH'; type AdditionalMode = 'ALL' | 'WITH' | 'WITHOUT'; type OperadoraFilterMode = 'ALL' | 'VIVO' | 'CLARO' | 'TIM'; type AdditionalServiceKey = 'gvd' | 'skeelo' | 'news' | 'travel' | 'sync' | 'dispositivo'; -type BlockedStatusMode = 'ALL' | 'PERDA_ROUBO' | 'BLOQUEIO_120' | 'PRE_ATIVACAO'; +type BlockedStatusMode = 'ALL' | 'PERDA_ROUBO' | 'BLOQUEIO_120'; type SkilFilterMode = 'ALL' | 'PF' | 'PJ' | 'RESERVA' | 'ESTOQUE'; interface LineRow { @@ -418,12 +418,6 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { selectedAdditionalServices: AdditionalServiceKey[] = []; filterOperadora: OperadoraFilterMode = 'ALL'; filterContaEmpresa = ''; - readonly blockedStatusFilterOptions: Array<{ label: string; value: BlockedStatusMode }> = [ - { label: 'Bloqueadas', value: 'ALL' }, - { label: 'Bloqueio Perda/Roubo', value: 'PERDA_ROUBO' }, - { label: 'Bloqueio por 120 dias', value: 'BLOQUEIO_120' }, - { label: 'Bloqueio de Pré Ativação', value: 'PRE_ATIVACAO' }, - ]; readonly additionalServiceOptions: Array<{ key: AdditionalServiceKey; label: string }> = [ { key: 'gvd', label: 'Gestão Voz e Dados' }, { key: 'skeelo', label: 'Skeelo' }, @@ -539,7 +533,7 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { kpiAtivas = 0; kpiBloqueadas = 0; - readonly statusOptions = ['ATIVO', 'BLOQUEIO PERDA/ROUBO', 'BLOQUEIO 120 DIAS', 'BLOQUEIO DE PRÉ ATIVAÇÃO']; + readonly statusOptions = ['ATIVO', 'BLOQUEIO PERDA/ROUBO', 'BLOQUEIO 120 DIAS']; readonly skilOptions = ['PESSOA FÍSICA', 'PESSOA JURÍDICA', 'RESERVA']; planOptions = [ @@ -1220,13 +1214,6 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { ) { return 'BLOQUEIO_120'; } - if ( - token === 'PREATIVACAO' || - token === 'PREATIV' || - token === 'BLOQUEIOPREATIVACAO' - ) { - return 'PRE_ATIVACAO'; - } return null; } @@ -1858,18 +1845,13 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { this.refreshData(); } - setBlockedStatusFilter(mode: BlockedStatusMode) { - const normalizedMode = mode ?? 'ALL'; - const sameSelection = this.filterStatus === 'BLOCKED' && this.blockedStatusMode === normalizedMode; - - if (sameSelection) { + toggleBlockedFilter() { + if (this.filterStatus === 'BLOCKED') { this.filterStatus = 'ALL'; this.blockedStatusMode = 'ALL'; } else { this.filterStatus = 'BLOCKED'; - this.blockedStatusMode = normalizedMode; } - this.expandedGroup = null; this.groupLines = []; this.searchResolvedClient = null; @@ -1884,10 +1866,24 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { this.refreshData(); } - onBlockedStatusSelectChange(event: Event) { - const target = event.target; - const value = target instanceof HTMLSelectElement ? target.value : 'ALL'; - this.setBlockedStatusFilter(value as BlockedStatusMode); + setBlockedStatusMode(mode: Exclude) { + if (this.filterStatus !== 'BLOCKED') { + this.filterStatus = 'BLOCKED'; + } + + this.blockedStatusMode = this.blockedStatusMode === mode ? 'ALL' : mode; + this.expandedGroup = null; + this.groupLines = []; + this.searchResolvedClient = null; + this.selectedClients = []; + this.clientSearchTerm = ''; + this.page = 1; + + if (!this.isClientRestricted) { + this.loadClients(); + } + + this.refreshData(); } setAdditionalMode(mode: AdditionalMode) { @@ -1978,7 +1974,6 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { next = next.set('statusMode', 'blocked'); if (this.blockedStatusMode === 'PERDA_ROUBO') next = next.set('statusSubtype', 'perda_roubo'); else if (this.blockedStatusMode === 'BLOQUEIO_120') next = next.set('statusSubtype', '120_dias'); - else if (this.blockedStatusMode === 'PRE_ATIVACAO') next = next.set('statusSubtype', 'pre_ativacao'); } if (this.additionalMode === 'WITH') next = next.set('additionalMode', 'with'); @@ -2025,17 +2020,15 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { normalized.includes('BLOQUE') || normalized.includes('PERDA') || normalized.includes('ROUBO') || - normalized.includes('FURTO') || - normalized.includes('PREATIV'); + normalized.includes('FURTO'); if (!hasBlockedToken) return null; if (normalized.includes('120')) return 'BLOQUEIO_120'; - if (normalized.includes('PREATIV')) return 'PRE_ATIVACAO'; if (normalized.includes('PERDA') || normalized.includes('ROUBO') || normalized.includes('FURTO')) { return 'PERDA_ROUBO'; } - return 'PRE_ATIVACAO'; + return 'PERDA_ROUBO'; } private isBlockedStatus(status: unknown): boolean { @@ -2946,7 +2939,6 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy { } else if (this.filterStatus === 'BLOCKED') { if (this.blockedStatusMode === 'PERDA_ROUBO') parts.push('bloq-perda-roubo'); else if (this.blockedStatusMode === 'BLOQUEIO_120') parts.push('bloq-120'); - else if (this.blockedStatusMode === 'PRE_ATIVACAO') parts.push('bloq-pre-ativacao'); else parts.push('bloqueadas'); }