Feat: Corrigindo merge

This commit is contained in:
Eduardo 2026-02-27 16:34:54 -03:00
parent 43efc1dc85
commit 4dcbfadd2c
23 changed files with 133 additions and 103 deletions

View File

@ -8,8 +8,8 @@ import { Mureg } from './pages/mureg/mureg';
import { Faturamento } from './pages/faturamento/faturamento';
import { authGuard } from './guards/auth.guard';
import { adminGuard } from './guards/admin.guard';
import { systemAdminGuard } from './guards/system-admin.guard';
import { sysadminOrGestorGuard } from './guards/sysadmin-or-gestor.guard';
import { sysadminOnlyGuard } from './guards/sysadmin-only.guard';
import { DadosUsuarios } from './pages/dados-usuarios/dados-usuarios';
import { VigenciaComponent } from './pages/vigencia/vigencia';
import { TrocaNumero } from './pages/troca-numero/troca-numero';
@ -29,20 +29,20 @@ export const routes: Routes = [
{ path: 'geral', component: Geral, canActivate: [authGuard], title: 'Geral' },
{ path: 'mureg', component: Mureg, canActivate: [authGuard], title: 'Mureg' },
{ path: 'faturamento', component: Faturamento, canActivate: [authGuard, adminGuard], title: 'Faturamento' },
{ path: 'faturamento', component: Faturamento, canActivate: [authGuard, sysadminOrGestorGuard], title: 'Faturamento' },
{ path: 'dadosusuarios', component: DadosUsuarios, canActivate: [authGuard], title: 'Dados dos Usuários' },
{ path: 'vigencia', component: VigenciaComponent, canActivate: [authGuard], title: 'Vigência' },
{ path: 'trocanumero', component: TrocaNumero, canActivate: [authGuard], title: 'Troca de Número' },
{ path: 'notificacoes', component: Notificacoes, canActivate: [authGuard], title: 'Notificações' },
{ path: 'chips-controle-recebidos', component: ChipsControleRecebidos, canActivate: [authGuard, adminGuard], title: 'Chips Controle Recebidos' },
{ path: 'chips-controle-recebidos', component: ChipsControleRecebidos, canActivate: [authGuard, sysadminOrGestorGuard], title: 'Chips Controle Recebidos' },
{ path: 'resumo', component: Resumo, canActivate: [authGuard], title: 'Resumo' },
{ path: 'parcelamentos', component: Parcelamentos, canActivate: [authGuard, adminGuard], title: 'Parcelamentos' },
{ path: 'historico', component: Historico, canActivate: [authGuard, adminGuard], title: 'Histórico' },
{ path: 'parcelamentos', component: Parcelamentos, canActivate: [authGuard, sysadminOrGestorGuard], title: 'Parcelamentos' },
{ path: 'historico', component: Historico, canActivate: [authGuard, sysadminOrGestorGuard], title: 'Histórico' },
{ path: 'perfil', component: Perfil, canActivate: [authGuard], title: 'Perfil' },
{
path: 'system/fornecer-usuario',
component: SystemProvisionUserPage,
canActivate: [authGuard, systemAdminGuard],
canActivate: [authGuard, sysadminOnlyGuard],
title: 'Fornecer Usuário',
},

View File

@ -185,13 +185,13 @@
<i class="bi bi-person-circle"></i> Perfil
</button>
<div class="divider"></div>
<button type="button" class="options-item" *ngIf="isAdmin" (click)="openCreateUserModal()">
<button type="button" class="options-item" *ngIf="isSysAdmin" (click)="openCreateUserModal()">
<i class="bi bi-person-plus"></i> Criar novo usuário
</button>
<button type="button" class="options-item" *ngIf="isAdmin" (click)="openManageUsersModal()">
<button type="button" class="options-item" *ngIf="isSysAdmin" (click)="openManageUsersModal()">
<i class="bi bi-people"></i> Editar usuário
</button>
<button type="button" class="options-item" *ngIf="isSystemAdmin" (click)="goToSystemProvisionUser()">
<button type="button" class="options-item" *ngIf="isSysAdmin" (click)="goToSystemProvisionUser()">
<i class="bi bi-shield-lock"></i> Fornecer usuário (cliente)
</button>
<div class="divider"></div>
@ -537,7 +537,7 @@
<a *ngIf="canViewAll" routerLink="/trocanumero" routerLinkActive="active" class="side-item" (click)="closeMenu()">
<i class="bi bi-arrow-left-right"></i> <span>Troca de número</span>
</a>
<a *ngIf="isSystemAdmin" routerLink="/system/fornecer-usuario" routerLinkActive="active" class="side-item" (click)="closeMenu()">
<a *ngIf="isSysAdmin" routerLink="/system/fornecer-usuario" routerLinkActive="active" class="side-item" (click)="closeMenu()">
<i class="bi bi-shield-lock-fill"></i> <span>Fornecer usuário</span>
</a>
</div>

View File

@ -31,9 +31,8 @@ export class Header implements AfterViewInit, OnDestroy {
manageUsersOpen = false;
isLoggedHeader = false;
isHome = false;
isAdmin = false;
isSysAdmin = false;
canViewAll = false;
isSystemAdmin = false;
notifications: NotificationDto[] = [];
notificationsLoading = false;
notificationsError = false;
@ -203,16 +202,14 @@ export class Header implements AfterViewInit, OnDestroy {
private syncPermissions() {
if (!isPlatformBrowser(this.platformId)) {
this.isAdmin = false;
this.isSysAdmin = false;
this.canViewAll = false;
this.isSystemAdmin = false;
return;
}
const isSysAdmin = this.authService.hasRole('sysadmin');
const isGestor = this.authService.hasRole('gestor');
this.isAdmin = isSysAdmin;
this.isSysAdmin = isSysAdmin;
this.canViewAll = isSysAdmin || isGestor;
this.isSystemAdmin = this.authService.hasRole('sysadmin');
}
toggleMenu() {
@ -238,13 +235,13 @@ export class Header implements AfterViewInit, OnDestroy {
}
goToSystemProvisionUser() {
if (!this.isSystemAdmin) return;
if (!this.isSysAdmin) return;
this.closeOptions();
this.router.navigate(['/system/fornecer-usuario']);
}
openCreateUserModal() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.createUserOpen = true;
this.closeOptions();
this.resetCreateUserState();
@ -256,7 +253,7 @@ export class Header implements AfterViewInit, OnDestroy {
}
openManageUsersModal() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.manageUsersOpen = true;
this.closeOptions();
this.resetManageUsersState();
@ -452,9 +449,8 @@ export class Header implements AfterViewInit, OnDestroy {
this.authService.logout();
this.optionsOpen = false;
this.notificationsOpen = false;
this.isAdmin = false;
this.isSysAdmin = false;
this.canViewAll = false;
this.isSystemAdmin = false;
this.router.navigate(['/']);
}
@ -616,7 +612,7 @@ export class Header implements AfterViewInit, OnDestroy {
this.createUserForm.markAllAsTouched();
return;
}
if (!this.isAdmin) {
if (!this.isSysAdmin) {
this.createUserForbidden = true;
return;
}

View File

@ -4,7 +4,7 @@ import { isPlatformBrowser } from '@angular/common';
import { AuthService } from '../services/auth.service';
export const systemAdminGuard: CanActivateFn = () => {
export const sysadminOnlyGuard: CanActivateFn = () => {
const router = inject(Router);
const platformId = inject(PLATFORM_ID);
const authService = inject(AuthService);
@ -18,8 +18,8 @@ export const systemAdminGuard: CanActivateFn = () => {
return router.parseUrl('/login');
}
const isSystemAdmin = authService.hasRole('sysadmin');
if (!isSystemAdmin) {
const isSysAdmin = authService.hasRole('sysadmin');
if (!isSysAdmin) {
return router.parseUrl('/dashboard');
}

View File

@ -3,7 +3,7 @@ import { CanActivateFn, Router } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
import { AuthService } from '../services/auth.service';
export const adminGuard: CanActivateFn = () => {
export const sysadminOrGestorGuard: CanActivateFn = () => {
const router = inject(Router);
const platformId = inject(PLATFORM_ID);
const authService = inject(AuthService);

View File

@ -36,14 +36,14 @@
<div class="header-actions d-flex gap-2 justify-content-end">
<button
*ngIf="isAdmin && activeTab === 'chips'"
*ngIf="isSysAdmin && activeTab === 'chips'"
class="btn btn-brand btn-sm"
(click)="openChipCreate()"
>
<i class="bi bi-plus-circle me-1"></i> Novo Chip
</button>
<button
*ngIf="isAdmin && activeTab === 'controle'"
*ngIf="isSysAdmin && activeTab === 'controle'"
class="btn btn-brand btn-sm"
(click)="openControleCreate()"
>
@ -197,10 +197,10 @@
<button class="btn-icon info" (click)="openChipDetail(r); $event.stopPropagation()" title="Detalhes">
<i class="bi bi-eye"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="openChipEdit(r); $event.stopPropagation()" title="Editar">
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openChipEdit(r); $event.stopPropagation()" title="Editar">
<i class="bi bi-pencil-square"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="openChipDelete(r); $event.stopPropagation()" title="Excluir">
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openChipDelete(r); $event.stopPropagation()" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</div>
@ -295,10 +295,10 @@
<button class="btn-icon info" (click)="openControleDetail(r); $event.stopPropagation()" title="Detalhes">
<i class="bi bi-eye"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="openControleEdit(r); $event.stopPropagation()" title="Editar">
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openControleEdit(r); $event.stopPropagation()" title="Editar">
<i class="bi bi-pencil-square"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="openControleDelete(r); $event.stopPropagation()" title="Excluir">
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openControleDelete(r); $event.stopPropagation()" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</div>
@ -339,10 +339,10 @@
<button class="btn-icon info" (click)="openControleDetail(r); $event.stopPropagation()" title="Detalhes">
<i class="bi bi-eye"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="openControleEdit(r); $event.stopPropagation()" title="Editar">
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openControleEdit(r); $event.stopPropagation()" title="Editar">
<i class="bi bi-pencil-square"></i>
</button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="openControleDelete(r); $event.stopPropagation()" title="Excluir">
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openControleDelete(r); $event.stopPropagation()" title="Excluir">
<i class="bi bi-trash"></i>
</button>
</div>

View File

@ -118,7 +118,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
controleDeleteOpen = false;
controleDeleteTarget: ControleRecebidoListDto | null = null;
isAdmin = false;
isSysAdmin = false;
constructor(
@Inject(PLATFORM_ID) private platformId: object,
@ -129,7 +129,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
ngOnInit(): void {
if (!isPlatformBrowser(this.platformId)) return;
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
this.fetchChips();
this.fetchControle();
}
@ -236,7 +236,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openChipCreate() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.chipCreateModel = {
id: '',
item: null,
@ -278,7 +278,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openChipEdit(row: ChipVirgemListDto) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.service.getChipVirgemById(row.id).subscribe({
next: (data) => {
this.chipEditingId = data.id;
@ -319,7 +319,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openChipDelete(row: ChipVirgemListDto) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.chipDeleteTarget = row;
this.chipDeleteOpen = true;
}
@ -498,7 +498,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openControleCreate() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.controleCreateModel = {
id: '',
ano: new Date().getFullYear(),
@ -603,7 +603,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openControleEdit(row: ControleRecebidoListDto) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.service.getControleRecebidoById(row.id).subscribe({
next: (data) => {
this.controleEditingId = data.id;
@ -659,7 +659,7 @@ export class ChipsControleRecebidos implements OnInit, OnDestroy {
}
openControleDelete(row: ControleRecebidoListDto) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.controleDeleteTarget = row;
this.controleDeleteOpen = true;
}

View File

@ -32,7 +32,7 @@
<button type="button" class="btn btn-brand btn-sm" (click)="refresh()" [disabled]="loading">
<i class="bi bi-arrow-clockwise me-1"></i> Atualizar
</button>
<button *ngIf="isAdmin" type="button" class="btn btn-brand btn-sm" (click)="openCreate()">
<button *ngIf="isSysAdmin" type="button" class="btn btn-brand btn-sm" (click)="openCreate()">
<i class="bi bi-plus-circle me-1"></i> Novo Usuário
</button>
</div>
@ -153,8 +153,8 @@
<td>
<div class="action-group justify-content-center">
<button class="btn-icon primary" (click)="openDetails(r)" title="Ver Detalhes"><i class="bi bi-eye"></i></button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="openEdit(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="openDelete(r)" title="Excluir"><i class="bi bi-trash"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openEdit(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openDelete(r)" title="Excluir"><i class="bi bi-trash"></i></button>
</div>
</td>
</tr>

View File

@ -103,7 +103,7 @@ export class DadosUsuarios implements OnInit {
createClientsLoading = false;
createLinesLoading = false;
isAdmin = false;
isSysAdmin = false;
toastOpen = false;
toastMessage = '';
toastType: 'success' | 'danger' = 'success';
@ -117,7 +117,7 @@ export class DadosUsuarios implements OnInit {
) {}
ngOnInit(): void {
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
this.fetch(1);
}
@ -283,7 +283,7 @@ export class DadosUsuarios implements OnInit {
closeDetails() { this.detailsOpen = false; }
openEdit(row: UserDataRow) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.service.getById(row.id).subscribe({
next: (fullData: UserDataRow) => {
this.editingId = fullData.id;
@ -366,7 +366,7 @@ export class DadosUsuarios implements OnInit {
// CREATE
// ==========================
openCreate() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.resetCreateModel();
this.createOpen = true;
this.preloadGeralClients();
@ -532,7 +532,7 @@ export class DadosUsuarios implements OnInit {
}
openDelete(row: UserDataRow) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.deleteTarget = row;
this.deleteOpen = true;
}

View File

@ -286,8 +286,8 @@
<div class="action-group justify-content-center">
<button class="btn-icon" (click)="onDetalhes(r)" title="Detalhes"><i class="bi bi-eye"></i></button>
<button class="btn-icon success" (click)="onComparativo(r)" title="Comparativo Vivo x Line"><i class="bi bi-columns-gap"></i></button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="onDelete(r)" title="Excluir"><i class="bi bi-trash"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="onDelete(r)" title="Excluir"><i class="bi bi-trash"></i></button>
</div>
</td>
</tr>

View File

@ -105,7 +105,7 @@ export class Faturamento implements AfterViewInit, OnDestroy {
deleteOpen = false;
deleteTarget: BillingItem | null = null;
isAdmin = false;
isSysAdmin = false;
private searchTimer: any = null;
private searchResolvedClients: string[] = [];
@ -164,7 +164,7 @@ export class Faturamento implements AfterViewInit, OnDestroy {
if (!isPlatformBrowser(this.platformId)) return;
this.initAnimations();
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
setTimeout(() => {
this.refreshData(true);
@ -714,7 +714,7 @@ export class Faturamento implements AfterViewInit, OnDestroy {
}
onEditar(r: BillingItem) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.editingId = r.id;
this.editModel = { ...r };
this.editOpen = true;
@ -729,7 +729,7 @@ export class Faturamento implements AfterViewInit, OnDestroy {
}
onDelete(r: BillingItem) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.deleteTarget = r;
this.deleteOpen = true;
this.cdr.detectChanges();

View File

@ -35,7 +35,7 @@
<button
type="button"
class="btn btn-glass btn-sm"
*ngIf="isAdmin"
*ngIf="isSysAdmin"
(click)="onImportExcel()"
[disabled]="loading">
<i class="bi bi-file-earmark-excel me-1"></i> Importar Dados Excel
@ -294,21 +294,49 @@
<div class="group-header" (click)="toggleGroup(group.cliente)">
<div class="group-info">
<h6 class="mb-0 fw-bold text-dark">{{ group.cliente }}</h6>
<div class="group-tags">
<span class="tag-pill">{{ group.totalLinhas }} linhas</span>
<span class="tag-pill active" *ngIf="group.ativos > 0">{{ group.ativos }} ativas</span>
<span class="tag-pill blocked" *ngIf="group.bloqueados > 0">{{ group.bloqueados }} bloqueadas</span>
<div class="group-tags">
<span class="tag-pill">{{ group.totalLinhas }} linhas</span>
<span class="tag-pill active" *ngIf="group.ativos > 0">{{ group.ativos }} ativas</span>
<span class="tag-pill blocked" *ngIf="group.bloqueados > 0">{{ group.bloqueados }} bloqueadas</span>
</div>
</div>
<div class="group-toggle-icon"><i class="bi bi-chevron-down"></i></div>
</div>
</div>
<div class="group-toggle-icon"><i class="bi bi-chevron-down"></i></div>
</div>
<div class="group-body" *ngIf="expandedGroup === group.cliente">
<div class="d-flex justify-content-between align-items-center px-4 py-2 border-bottom bg-white">
<small class="text-muted fw-bold">Gerenciar Grupo</small>
<button class="btn btn-sm btn-add-line-group" (click)="onAddLineToGroup(group.cliente)">
<i class="bi bi-plus-lg me-1"></i> Adicionar Linha
</button>
<div class="d-flex align-items-center gap-2 flex-wrap justify-content-end">
<ng-container *ngIf="hasGroupLineSelectionTools">
<button class="btn btn-sm btn-glass" type="button" (click)="toggleSelectAllReservaGroupLines()">
<i class="bi bi-check2-square me-1"></i>
{{ reservaSelectedCount > 0 && reservaSelectedCount === groupLines.length ? 'Limpar seleção' : 'Selecionar todas' }}
</button>
</ng-container>
<ng-container *ngIf="isReservaExpandedGroup">
<button
class="btn btn-sm btn-brand"
type="button"
(click)="openReservaTransferModal()"
[disabled]="reservaSelectedCount === 0"
>
<i class="bi bi-arrow-left-right me-1"></i> Atribuir Selecionadas ({{ reservaSelectedCount }})
</button>
</ng-container>
<ng-container *ngIf="canMoveSelectedLinesToReserva">
<button
class="btn btn-sm btn-send-reserva-group"
type="button"
(click)="openMoveToReservaModal()"
[disabled]="reservaSelectedCount === 0"
>
<i class="bi bi-box-arrow-left me-1"></i> Enviar p/ Reserva ({{ reservaSelectedCount }})
</button>
</ng-container>
<button class="btn btn-sm btn-add-line-group" *ngIf="!isClientRestricted" (click)="onAddLineToGroup(group.cliente)">
<i class="bi bi-plus-lg me-1"></i> Adicionar Linha
</button>
</div>
</div>
<!-- ✅ wrapper com classe extra para permitir MAIS ALTURA em notebook/TV via SCSS -->
@ -334,7 +362,7 @@
<th>LINHA</th>
<th>USUÁRIO</th>
<th>STATUS</th>
<th>VENCIMENTO</th>
<th *ngIf="!isClientRestricted">VENCIMENTO</th>
<th>AÇÕES</th>
</tr>
</thead>
@ -351,23 +379,29 @@
[attr.aria-label]="'Selecionar linha ' + (r.linha || r.item)"
/>
</td>
<td class="text-muted fw-bold">{{ r.item }}</td>
<td class="fw-black text-blue" [attr.title]="(r.chip || '') ? ('ICCID: ' + r.chip) : ''">
{{ r.linha }}
<div class="small text-muted fw-normal" *ngIf="r.chip">ICCID: {{ r.chip }}</div>
</td>
<td class="text-dark">{{ r.usuario || '-' }}</td>
<td>
<span class="status-pill" [ngClass]="statusClass(r.status)">{{ statusLabel(r.status) }}</span>
</td>
<td class="text-muted small fw-bold">{{ r.contrato }}</td>
<td class="text-muted small fw-bold" *ngIf="!isClientRestricted">{{ r.contrato }}</td>
<td>
<div class="action-group justify-content-center">
<button class="btn-icon" (click)="onDetalhes(r)" title="Detalhes"><i class="bi bi-eye"></i></button>
<ng-container *ngIf="!isClientRestricted">
<button class="btn-icon success" (click)="onFinanceiro(r)" title="Financeiro"><i class="bi bi-cash-coin"></i></button>
<button class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="onRemover(r, true)" title="Remover"><i class="bi bi-trash"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="onRemover(r, true)" title="Remover"><i class="bi bi-trash"></i></button>
</ng-container>
</div>
</td>
@ -479,14 +513,14 @@
<span class="status-pill" [ngClass]="statusClass(r.status)" [title]="r.status || ''">{{ statusLabel(r.status) }}</span>
</td>
<td class="text-center fw-bold text-muted small">{{ r.skil }}</td>
<td class="text-center fw-bold text-muted small">{{ r.contrato }}</td>
<td class="text-center fw-bold text-muted small" *ngIf="!isClientRestricted">{{ r.contrato }}</td>
<td class="text-center">
<div class="action-group justify-content-center">
<button class="btn-icon" (click)="onDetalhes(r)" title="Detalhes"><i class="bi bi-eye"></i></button>
<ng-container *ngIf="!isClientRestricted">
<button class="btn-icon success" (click)="onFinanceiro(r)" title="Financeiro"><i class="bi bi-cash-coin"></i></button>
<button class="btn-icon primary" (click)="onEditar(r)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="onRemover(r)" title="Remover"><i class="bi bi-trash"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="onRemover(r)" title="Remover"><i class="bi bi-trash"></i></button>
</ng-container>
</div>
</td>

View File

@ -274,7 +274,7 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy {
return `${apiBase}/templates`;
})();
loading = false;
isAdmin = false;
isSysAdmin = false;
isGestor = false;
isClientRestricted = false;
@ -691,9 +691,9 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy {
ngOnInit(): void {
if (!isPlatformBrowser(this.platformId)) return;
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
this.isGestor = this.authService.hasRole('gestor');
this.isClientRestricted = !(this.isAdmin || this.isGestor);
this.isClientRestricted = !(this.isSysAdmin || this.isGestor);
if (this.isClientRestricted) {
this.filterSkil = 'ALL';
@ -1760,7 +1760,7 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy {
}
async onImportExcel() {
if (!this.isAdmin) {
if (!this.isSysAdmin) {
await this.showToast('Você não tem permissão para importar planilha.');
return;
}
@ -1771,7 +1771,7 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy {
}
onExcelSelected(ev: Event) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
const file = (ev.target as HTMLInputElement).files?.[0];
if (!file) return;
@ -1961,7 +1961,7 @@ export class Geral implements OnInit, AfterViewInit, OnDestroy {
}
async onRemover(r: LineRow, fromGroup = false) {
if (!this.isAdmin) {
if (!this.isSysAdmin) {
await this.showToast('Apenas sysadmin pode remover linhas.');
return;
}

View File

@ -21,7 +21,7 @@
type="email"
id="email"
formControlName="username"
placeholder="admin@empresa.com"
placeholder="usuario@empresa.com"
[class.error]="hasError('username')"
>
<div class="error-msg" *ngIf="hasError('username')">E-mail obrigatório ou inválido.</div>

View File

@ -113,7 +113,7 @@
type="button"
title="Excluir"
aria-label="Excluir"
*ngIf="isAdmin"
*ngIf="isSysAdmin"
(click)="remove.emit(row)">
<i class="bi bi-trash"></i>
</button>

View File

@ -26,7 +26,7 @@ export class ParcelamentosTableComponent {
@Input() items: ParcelamentoViewItem[] = [];
@Input() loading = false;
@Input() errorMessage = '';
@Input() isAdmin = false;
@Input() isSysAdmin = false;
@Input() segment: ParcelamentoSegment = 'todos';
@Input() segmentCounts: Record<ParcelamentoSegment, number> = {

View File

@ -65,7 +65,7 @@
[total]="total"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
[isAdmin]="isAdmin"
[isSysAdmin]="isSysAdmin"
(segmentChange)="setSegment($event)"
(detail)="openDetails($event)"
(edit)="openEdit($event)"

View File

@ -87,7 +87,7 @@ export class Parcelamentos implements OnInit, OnDestroy {
kpiCards: ParcelamentoKpi[] = [];
activeChips: FilterChip[] = [];
isAdmin = false;
isSysAdmin = false;
detailOpen = false;
detailLoading = false;
@ -158,7 +158,7 @@ export class Parcelamentos implements OnInit, OnDestroy {
}
private syncPermissions(): void {
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
}
get totalPages(): number {
@ -440,7 +440,7 @@ export class Parcelamentos implements OnInit, OnDestroy {
}
openDelete(item: ParcelamentoViewItem): void {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.deleteTarget = item;
this.deleteError = '';
this.deleteOpen = true;

View File

@ -7,7 +7,7 @@
<div class="card-shell">
<header class="card-header">
<div class="title-badge">
<i class="bi bi-shield-lock-fill"></i> SYSTEM ADMIN
<i class="bi bi-shield-lock-fill"></i> SYSADMIN
</div>
<h1>Fornecer Usuário para Cliente</h1>
<p>Selecione um tenant-cliente e crie credenciais de acesso sem misturar tenants.</p>

View File

@ -11,10 +11,10 @@ import {
} from '@angular/forms';
import {
SystemAdminService,
SysadminService,
SystemTenantDto,
CreateSystemTenantUserResponse,
} from '../../services/system-admin.service';
} from '../../services/sysadmin.service';
type RoleOption = {
value: string;
@ -50,7 +50,7 @@ export class SystemProvisionUserPage implements OnInit {
constructor(
private fb: FormBuilder,
private systemAdminService: SystemAdminService
private sysadminService: SysadminService
) {
this.provisionForm = this.fb.group(
{
@ -75,7 +75,7 @@ export class SystemProvisionUserPage implements OnInit {
this.tenantsLoading = true;
this.tenantsError = '';
this.systemAdminService
this.sysadminService
.listTenants({ source: this.sourceType, active: true })
.subscribe({
next: (tenants) => {
@ -133,7 +133,7 @@ export class SystemProvisionUserPage implements OnInit {
this.submitting = true;
this.setFormDisabled(true);
this.systemAdminService
this.sysadminService
.createTenantUser(tenantId, {
name: nameRaw,
email,

View File

@ -24,7 +24,7 @@
<small class="subtitle">Controle de contratos e fidelização</small>
</div>
<div class="header-actions d-flex gap-2 justify-content-end">
<button *ngIf="isAdmin" class="btn btn-brand btn-sm" (click)="openCreate()">
<button *ngIf="isSysAdmin" class="btn btn-brand btn-sm" (click)="openCreate()">
<i class="bi bi-plus-circle me-1"></i> Nova Vigência
</button>
</div>
@ -157,8 +157,8 @@
Renovar +2 anos
</button>
<button class="btn-icon primary" (click)="openDetails(row)" title="Ver Detalhes"><i class="bi bi-eye"></i></button>
<button *ngIf="isAdmin" class="btn-icon primary" (click)="openEdit(row)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isAdmin" class="btn-icon danger" (click)="openDelete(row)" title="Excluir"><i class="bi bi-trash"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon primary" (click)="openEdit(row)" title="Editar"><i class="bi bi-pencil-square"></i></button>
<button *ngIf="isSysAdmin" class="btn-icon danger" (click)="openDelete(row)" title="Excluir"><i class="bi bi-trash"></i></button>
</div>
</td>
</tr>

View File

@ -100,7 +100,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
clientsFromGeral: string[] = [];
planOptions: string[] = [];
isAdmin = false;
isSysAdmin = false;
toastOpen = false;
toastMessage = '';
toastType: ToastType = 'success';
@ -117,7 +117,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
) {}
ngOnInit(): void {
this.isAdmin = this.authService.hasRole('sysadmin');
this.isSysAdmin = this.authService.hasRole('sysadmin');
this.loadClients();
this.loadPlanRules();
this.fetch(1);
@ -314,7 +314,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
closeDetails() { this.detailsOpen = false; }
openEdit(r: VigenciaRow) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.editingId = r.id;
this.editModel = { ...r };
this.editEfetivacao = this.toDateInput(r.dtEfetivacaoServico);
@ -365,7 +365,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
// CREATE
// ==========================
openCreate() {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.resetCreateModel();
this.createOpen = true;
this.preloadGeralClients();
@ -544,7 +544,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
}
openDelete(r: VigenciaRow) {
if (!this.isAdmin) return;
if (!this.isSysAdmin) return;
this.deleteTarget = r;
this.deleteOpen = true;
}
@ -613,7 +613,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
private openVigenciaLineById(lineId: string, openMode: string): void {
this.vigenciaService.getById(lineId).subscribe({
next: (row) => {
if (this.isAdmin && openMode !== 'details') {
if (this.isSysAdmin && openMode !== 'details') {
this.openEdit(row);
return;
}
@ -643,7 +643,7 @@ export class VigenciaComponent implements OnInit, OnDestroy {
return;
}
if (this.isAdmin && openMode !== 'details') {
if (this.isSysAdmin && openMode !== 'details') {
this.openEdit(match);
return;
}

View File

@ -29,7 +29,7 @@ export type CreateSystemTenantUserResponse = {
};
@Injectable({ providedIn: 'root' })
export class SystemAdminService {
export class SysadminService {
private readonly baseApi: string;
constructor(private http: HttpClient) {