Commit inicial - upload de todos os arquivos da pasta
This commit is contained in:
0
src/constants/.gitkeep
Normal file
0
src/constants/.gitkeep
Normal file
63
src/constants/__tests__/breadcrumbs.test.ts
Normal file
63
src/constants/__tests__/breadcrumbs.test.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { breadcrumbRoutes } from '../breadcrumbs';
|
||||
|
||||
const expectedRoutes = [
|
||||
'/',
|
||||
'/entregaveis',
|
||||
'/entregaveis/:id',
|
||||
'/ordens-servico',
|
||||
'/sprints',
|
||||
'/profissionais',
|
||||
'/usuarios',
|
||||
'/usuarios/novo',
|
||||
'/usuarios/:id/editar',
|
||||
'/clientes',
|
||||
'/configuracoes',
|
||||
];
|
||||
|
||||
describe('breadcrumbRoutes', () => {
|
||||
it('cobre todas as rotas do sistema', () => {
|
||||
const patterns = breadcrumbRoutes.map((r) => r.pattern);
|
||||
for (const route of expectedRoutes) {
|
||||
expect(patterns).toContain(route);
|
||||
}
|
||||
});
|
||||
|
||||
it('cada configuração tem pelo menos um item', () => {
|
||||
for (const route of breadcrumbRoutes) {
|
||||
expect(route.items.length).toBeGreaterThanOrEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
it('último item de cada configuração não tem "to"', () => {
|
||||
for (const route of breadcrumbRoutes) {
|
||||
const lastItem = route.items[route.items.length - 1];
|
||||
expect(lastItem.to).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('rotas com parâmetros usam padrão :param', () => {
|
||||
const dynamicRoutes = breadcrumbRoutes.filter((r) => r.pattern.includes(':'));
|
||||
expect(dynamicRoutes.length).toBeGreaterThan(0);
|
||||
for (const route of dynamicRoutes) {
|
||||
expect(route.pattern).toMatch(/:\w+/);
|
||||
}
|
||||
});
|
||||
|
||||
it('Dashboard é sempre a raiz dos breadcrumbs', () => {
|
||||
for (const route of breadcrumbRoutes) {
|
||||
expect(route.items[0].label).toBe('Dashboard');
|
||||
}
|
||||
});
|
||||
|
||||
it('página Dashboard não tem link no item', () => {
|
||||
const dashboardRoute = breadcrumbRoutes.find((r) => r.pattern === '/');
|
||||
expect(dashboardRoute?.items[0].to).toBeUndefined();
|
||||
});
|
||||
|
||||
it('não inclui rotas de autenticação', () => {
|
||||
const patterns = breadcrumbRoutes.map((r) => r.pattern);
|
||||
expect(patterns).not.toContain('/login');
|
||||
expect(patterns).not.toContain('/trocar-senha');
|
||||
});
|
||||
});
|
||||
143
src/constants/breadcrumbs.ts
Normal file
143
src/constants/breadcrumbs.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import type { BreadcrumbItem } from '../components/ui/Breadcrumbs';
|
||||
|
||||
export interface BreadcrumbRouteConfig {
|
||||
pattern: string;
|
||||
items: BreadcrumbItem[];
|
||||
}
|
||||
|
||||
const dashboard: BreadcrumbItem = { label: 'Dashboard', to: '/' };
|
||||
|
||||
export const breadcrumbRoutes: BreadcrumbRouteConfig[] = [
|
||||
{ pattern: '/', items: [{ label: 'Dashboard' }] },
|
||||
{ pattern: '/entregaveis', items: [dashboard, { label: 'Entregáveis' }] },
|
||||
{
|
||||
pattern: '/entregaveis/novo',
|
||||
items: [dashboard, { label: 'Entregáveis', to: '/entregaveis' }, { label: 'Novo Entregável' }],
|
||||
},
|
||||
{
|
||||
pattern: '/entregaveis/:id',
|
||||
items: [dashboard, { label: 'Entregáveis', to: '/entregaveis' }, { label: 'Entregável #:id' }],
|
||||
},
|
||||
{
|
||||
pattern: '/entregaveis/:id/editar',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Entregáveis', to: '/entregaveis' },
|
||||
{ label: 'Editar Entregável' },
|
||||
],
|
||||
},
|
||||
{ pattern: '/ordens-servico', items: [dashboard, { label: 'Ordens de Serviço' }] },
|
||||
{
|
||||
pattern: '/ordens-servico/nova',
|
||||
items: [dashboard, { label: 'Ordens de Serviço', to: '/ordens-servico' }, { label: 'Nova OS' }],
|
||||
},
|
||||
{
|
||||
pattern: '/ordens-servico/:id',
|
||||
items: [dashboard, { label: 'Ordens de Serviço', to: '/ordens-servico' }, { label: ':name' }],
|
||||
},
|
||||
{
|
||||
pattern: '/ordens-servico/:id/editar',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Ordens de Serviço', to: '/ordens-servico' },
|
||||
{ label: 'Editar OS' },
|
||||
],
|
||||
},
|
||||
{ pattern: '/sprints', items: [dashboard, { label: 'Sprints' }] },
|
||||
{
|
||||
pattern: '/sprints/novo',
|
||||
items: [dashboard, { label: 'Sprints', to: '/sprints' }, { label: 'Nova Sprint' }],
|
||||
},
|
||||
{
|
||||
pattern: '/sprints/:id',
|
||||
items: [dashboard, { label: 'Sprints', to: '/sprints' }, { label: ':name' }],
|
||||
},
|
||||
{
|
||||
pattern: '/sprints/:id/editar',
|
||||
items: [dashboard, { label: 'Sprints', to: '/sprints' }, { label: 'Editar :name' }],
|
||||
},
|
||||
{ pattern: '/profissionais', items: [dashboard, { label: 'Profissionais' }] },
|
||||
{
|
||||
pattern: '/profissionais/novo',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Profissionais', to: '/profissionais' },
|
||||
{ label: 'Novo Profissional' },
|
||||
],
|
||||
},
|
||||
{
|
||||
pattern: '/profissionais/:id/editar',
|
||||
items: [dashboard, { label: 'Profissionais', to: '/profissionais' }, { label: 'Editar :name' }],
|
||||
},
|
||||
{ pattern: '/usuarios', items: [dashboard, { label: 'Usuários' }] },
|
||||
{
|
||||
pattern: '/usuarios/novo',
|
||||
items: [dashboard, { label: 'Usuários', to: '/usuarios' }, { label: 'Novo Usuário' }],
|
||||
},
|
||||
{
|
||||
pattern: '/usuarios/:id/editar',
|
||||
items: [dashboard, { label: 'Usuários', to: '/usuarios' }, { label: 'Editar :name' }],
|
||||
},
|
||||
{ pattern: '/clientes', items: [dashboard, { label: 'Clientes' }] },
|
||||
{
|
||||
pattern: '/clientes/novo',
|
||||
items: [dashboard, { label: 'Clientes', to: '/clientes' }, { label: 'Novo Cliente' }],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id',
|
||||
items: [dashboard, { label: 'Clientes', to: '/clientes' }, { label: ':name' }],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id/editar',
|
||||
items: [dashboard, { label: 'Clientes', to: '/clientes' }, { label: 'Editar :name' }],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id/contratos/novo',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Clientes', to: '/clientes' },
|
||||
{ label: ':name' },
|
||||
{ label: 'Novo Contrato' },
|
||||
],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id/itens-contrato/novo',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Clientes', to: '/clientes' },
|
||||
{ label: ':name' },
|
||||
{ label: 'Novo Item de Contrato' },
|
||||
],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id/itens-contrato/:itemId/editar',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Clientes', to: '/clientes' },
|
||||
{ label: ':name' },
|
||||
{ label: 'Editar Item de Contrato' },
|
||||
],
|
||||
},
|
||||
{
|
||||
pattern: '/clientes/:id/projetos/novo',
|
||||
items: [
|
||||
dashboard,
|
||||
{ label: 'Clientes', to: '/clientes' },
|
||||
{ label: ':name' },
|
||||
{ label: 'Novo Projeto' },
|
||||
],
|
||||
},
|
||||
{
|
||||
pattern: '/contratos/:id/editar',
|
||||
items: [dashboard, { label: 'Clientes', to: '/clientes' }, { label: 'Editar Contrato' }],
|
||||
},
|
||||
{
|
||||
pattern: '/projetos/:id/editar',
|
||||
items: [dashboard, { label: 'Clientes', to: '/clientes' }, { label: 'Editar Projeto' }],
|
||||
},
|
||||
{ pattern: '/configuracoes', items: [dashboard, { label: 'Configurações' }] },
|
||||
{
|
||||
pattern: '/admin/integracoes/api-keys',
|
||||
items: [dashboard, { label: 'Integrações' }, { label: 'API Keys' }],
|
||||
},
|
||||
];
|
||||
28
src/constants/contract-item-type.ts
Normal file
28
src/constants/contract-item-type.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ContractItemType } from '../types/contract-item.types';
|
||||
|
||||
export const CONTRACT_ITEM_TYPE_LABELS: Record<ContractItemType, string> = {
|
||||
[ContractItemType.UST]: 'Unidade de Serviço Técnico (UST)',
|
||||
[ContractItemType.SAAS_LICENSE]: 'Licença SaaS',
|
||||
};
|
||||
|
||||
export interface ContractItemTypeBadgeConfig {
|
||||
label: string;
|
||||
color: 'gray' | 'blue';
|
||||
}
|
||||
|
||||
const badgeConfigMap: Record<ContractItemType, ContractItemTypeBadgeConfig> = {
|
||||
[ContractItemType.UST]: {
|
||||
label: CONTRACT_ITEM_TYPE_LABELS[ContractItemType.UST],
|
||||
color: 'gray',
|
||||
},
|
||||
[ContractItemType.SAAS_LICENSE]: {
|
||||
label: CONTRACT_ITEM_TYPE_LABELS[ContractItemType.SAAS_LICENSE],
|
||||
color: 'blue',
|
||||
},
|
||||
};
|
||||
|
||||
export function getContractItemTypeBadgeConfig(
|
||||
type: ContractItemType,
|
||||
): ContractItemTypeBadgeConfig {
|
||||
return badgeConfigMap[type];
|
||||
}
|
||||
45
src/constants/deliverable-status.ts
Normal file
45
src/constants/deliverable-status.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { DeliverableStatus } from '../types/deliverable.types';
|
||||
|
||||
type StatusVariant =
|
||||
| 'success'
|
||||
| 'danger'
|
||||
| 'warning'
|
||||
| 'info'
|
||||
| 'primary'
|
||||
| 'purple'
|
||||
| 'success-dark'
|
||||
| 'danger-dark'
|
||||
| 'neutral';
|
||||
|
||||
export interface StatusConfig {
|
||||
label: string;
|
||||
variant: StatusVariant;
|
||||
}
|
||||
|
||||
const statusConfigMap: Record<DeliverableStatus, StatusConfig> = {
|
||||
[DeliverableStatus.RASCUNHO]: { label: 'Rascunho', variant: 'neutral' },
|
||||
[DeliverableStatus.EMITIDA]: { label: 'Emitida', variant: 'info' },
|
||||
[DeliverableStatus.EM_EXECUCAO]: { label: 'Em Execução', variant: 'warning' },
|
||||
[DeliverableStatus.AGUARDANDO_VALIDACAO]: { label: 'Aguardando Validação', variant: 'warning' },
|
||||
[DeliverableStatus.EM_REVISAO]: { label: 'Em Revisão', variant: 'purple' },
|
||||
[DeliverableStatus.APROVADA]: { label: 'Aprovada', variant: 'success' },
|
||||
[DeliverableStatus.GLOSADA]: { label: 'Glosada', variant: 'danger' },
|
||||
[DeliverableStatus.ENCERRADA]: { label: 'Encerrada', variant: 'success-dark' },
|
||||
[DeliverableStatus.CANCELADA]: { label: 'Cancelada', variant: 'danger-dark' },
|
||||
[DeliverableStatus.AGUARDANDO_PAGAMENTO]: {
|
||||
label: 'Aguardando Pagamento',
|
||||
variant: 'warning',
|
||||
},
|
||||
[DeliverableStatus.PAGA]: { label: 'Paga', variant: 'success' },
|
||||
};
|
||||
|
||||
export function getStatusConfig(status: DeliverableStatus): StatusConfig {
|
||||
return statusConfigMap[status];
|
||||
}
|
||||
|
||||
export const DELIVERABLE_STATUS_OPTIONS = Object.entries(statusConfigMap).map(
|
||||
([value, config]) => ({
|
||||
value,
|
||||
label: config.label,
|
||||
}),
|
||||
);
|
||||
23
src/constants/deliverable-type.ts
Normal file
23
src/constants/deliverable-type.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export const DeliverableType = {
|
||||
DESCOBERTA: 'DESCOBERTA',
|
||||
DESIGN: 'DESIGN',
|
||||
ARQUITETURA: 'ARQUITETURA',
|
||||
CONSTRUCAO: 'CONSTRUCAO',
|
||||
MANUTENCAO: 'MANUTENCAO',
|
||||
LICENCA: 'LICENCA',
|
||||
} as const;
|
||||
|
||||
export type DeliverableType = (typeof DeliverableType)[keyof typeof DeliverableType];
|
||||
|
||||
export const DELIVERABLE_TYPE_LABELS: Record<DeliverableType, string> = {
|
||||
[DeliverableType.DESCOBERTA]: 'Descoberta',
|
||||
[DeliverableType.DESIGN]: 'Design',
|
||||
[DeliverableType.ARQUITETURA]: 'Arquitetura',
|
||||
[DeliverableType.CONSTRUCAO]: 'Construção',
|
||||
[DeliverableType.MANUTENCAO]: 'Manutenção',
|
||||
[DeliverableType.LICENCA]: 'Licença',
|
||||
};
|
||||
|
||||
export const DELIVERABLE_TYPE_OPTIONS = Object.entries(DELIVERABLE_TYPE_LABELS).map(
|
||||
([value, label]) => ({ value, label }),
|
||||
);
|
||||
70
src/constants/field-visibility.ts
Normal file
70
src/constants/field-visibility.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { UserRole } from '../types/auth.types';
|
||||
|
||||
export const FINANCIAL_FIELDS = new Set([
|
||||
'totalValue',
|
||||
'ustValue',
|
||||
'ustQuantity',
|
||||
'reservedUst',
|
||||
'calculatedValue',
|
||||
'timeboxDescoberta',
|
||||
'timeboxDesign',
|
||||
'timeboxArquitetura',
|
||||
'timeboxConstrucao',
|
||||
'timeboxManutencao',
|
||||
'numWeeks',
|
||||
]);
|
||||
|
||||
// Mirrors backend VISIBILITY_MAP (visibility-map.ts).
|
||||
// ADMIN is not listed — handled inline (always visible).
|
||||
// Default-deny: field absent from a client role's set = invisible.
|
||||
export const FIELD_VISIBILITY_MAP: Partial<Record<UserRole, Set<string>>> = {
|
||||
GESTOR_PROJETOS: new Set([
|
||||
'id', 'code', 'name', 'title', 'description', 'status', 'type',
|
||||
'isActive', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy',
|
||||
'startDate', 'endDate', 'expectedEndDate',
|
||||
'clientId', 'contractId', 'projectId', 'contractItemId', 'workOrderId', 'sprintId',
|
||||
'client', 'contract', 'project', 'contractItem', 'workOrder', 'sprint',
|
||||
'statusHistory', 'assignments', 'backlogItems', 'timelineEvents', 'notes',
|
||||
'sprintHistory', 'allocations', 'deliverables', 'projects',
|
||||
'contractItems', 'users', 'profiles', 'allocationTemplates',
|
||||
'email', 'role', 'clientSubRole', 'mustChangePassword',
|
||||
'workOrders', 'goal', 'sprintType', 'totalUst', 'itemType',
|
||||
'document', 'phone', 'contactName',
|
||||
'professional', 'professionals',
|
||||
'acceptanceCriteria', 'rejectionReason', 'sortOrder',
|
||||
'noteType', 'isRelevant',
|
||||
'profileId', 'quantity', 'allocationPercentage', 'profile',
|
||||
'token', 'scopes', 'lastFourChars', 'expiresAt', 'lastUsedAt', 'rateLimitPerMinute',
|
||||
]),
|
||||
|
||||
PO: new Set([
|
||||
'id', 'code', 'title', 'description', 'status', 'type',
|
||||
'isActive', 'createdAt', 'updatedAt',
|
||||
'startDate', 'expectedEndDate',
|
||||
'clientId', 'contractId', 'projectId',
|
||||
'client', 'contract', 'project',
|
||||
'backlogItems', 'timelineEvents',
|
||||
'acceptanceCriteria', 'rejectionReason', 'sortOrder',
|
||||
'name', 'email', 'role',
|
||||
]),
|
||||
|
||||
FISCAL_CONTRATO: new Set([
|
||||
'id', 'code', 'title', 'description', 'status', 'type',
|
||||
'isActive', 'createdAt', 'updatedAt',
|
||||
'startDate', 'expectedEndDate',
|
||||
'clientId', 'contractId', 'projectId',
|
||||
'client', 'contract', 'project',
|
||||
'statusHistory', 'timelineEvents',
|
||||
'name', 'email', 'role',
|
||||
]),
|
||||
|
||||
GESTOR_CONTRATO: new Set([
|
||||
'id', 'code', 'name', 'description', 'status',
|
||||
'isActive', 'createdAt', 'updatedAt',
|
||||
'startDate', 'endDate',
|
||||
'contractId', 'contractItemId',
|
||||
'contract', 'contractItem', 'projects', 'deliverables', 'statusHistory',
|
||||
'totalUst', 'itemType',
|
||||
'email', 'role',
|
||||
]),
|
||||
};
|
||||
29
src/constants/navigation.ts
Normal file
29
src/constants/navigation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
LayoutDashboard,
|
||||
FileText,
|
||||
Timer,
|
||||
Users,
|
||||
UserCog,
|
||||
Building2,
|
||||
Briefcase,
|
||||
KeyRound,
|
||||
} from 'lucide-react';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
|
||||
export interface NavItemConfig {
|
||||
icon: LucideIcon;
|
||||
label: string;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export const navigationItems: NavItemConfig[] = [
|
||||
{ icon: LayoutDashboard, label: 'Dashboard', to: '/' },
|
||||
{ icon: Briefcase, label: 'Ordens de Serviço', to: '/ordens-servico' },
|
||||
{ icon: FileText, label: 'Entregáveis', to: '/entregaveis' },
|
||||
{ icon: Building2, label: 'Clientes', to: '/clientes' },
|
||||
{ icon: Timer, label: 'Sprints', to: '/sprints' },
|
||||
{ icon: Users, label: 'Profissionais', to: '/profissionais' },
|
||||
{ icon: UserCog, label: 'Usuários', to: '/usuarios' },
|
||||
{ icon: KeyRound, label: 'API Keys', to: '/admin/integracoes/api-keys' },
|
||||
// { icon: Settings, label: 'Configurações', to: '/configuracoes' },
|
||||
];
|
||||
21
src/constants/permissions.ts
Normal file
21
src/constants/permissions.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { UserRole } from '../types/auth.types';
|
||||
|
||||
const OPERATOR_ROUTES = ['/', '/entregaveis', '/ordens-servico', '/sprints', '/profissionais', '/clientes'];
|
||||
|
||||
export const routePermissions: Record<UserRole, string[]> = {
|
||||
ADMIN: [
|
||||
'/',
|
||||
'/entregaveis',
|
||||
'/ordens-servico',
|
||||
'/sprints',
|
||||
'/profissionais',
|
||||
'/usuarios',
|
||||
'/clientes',
|
||||
'/configuracoes',
|
||||
'/admin/integracoes/api-keys',
|
||||
],
|
||||
GESTOR_PROJETOS: OPERATOR_ROUTES,
|
||||
PO: ['/', '/entregaveis', '/ordens-servico', '/clientes', '/sprints', '/po'],
|
||||
FISCAL_CONTRATO: ['/', '/entregaveis', '/ordens-servico', '/clientes', '/sprints', '/fiscal-contrato'],
|
||||
GESTOR_CONTRATO: ['/', '/ordens-servico', '/clientes', '/gestor-contrato'],
|
||||
};
|
||||
20
src/constants/professional-roles.ts
Normal file
20
src/constants/professional-roles.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export const PROFESSIONAL_ROLE_OPTIONS = [
|
||||
{ value: 'Gerente de Operação', label: 'Gerente de Operação' },
|
||||
{ value: 'Gerente de Projetos', label: 'Gerente de Projetos' },
|
||||
{ value: 'Product Owner', label: 'Product Owner' },
|
||||
{ value: 'Scrum Master', label: 'Scrum Master' },
|
||||
{ value: 'Tech Lead', label: 'Tech Lead' },
|
||||
{ value: 'Arquiteto de Software', label: 'Arquiteto de Software' },
|
||||
{ value: 'Desenvolvedor Frontend', label: 'Desenvolvedor Frontend' },
|
||||
{ value: 'Desenvolvedor Backend', label: 'Desenvolvedor Backend' },
|
||||
{ value: 'Desenvolvedor Fullstack', label: 'Desenvolvedor Fullstack' },
|
||||
{ value: 'Desenvolvedor Mobile', label: 'Desenvolvedor Mobile' },
|
||||
{ value: 'DevOps', label: 'DevOps' },
|
||||
{ value: 'QA / Analista de Testes', label: 'QA / Analista de Testes' },
|
||||
{ value: 'UX/UI Designer', label: 'UX/UI Designer' },
|
||||
{ value: 'Analista de Dados', label: 'Analista de Dados' },
|
||||
{ value: 'Analista de Sistemas', label: 'Analista de Sistemas' },
|
||||
{ value: 'Analista de Suporte', label: 'Analista de Suporte' },
|
||||
{ value: 'DBA', label: 'DBA' },
|
||||
{ value: 'Analista de Segurança', label: 'Analista de Segurança' },
|
||||
];
|
||||
39
src/constants/sprint.ts
Normal file
39
src/constants/sprint.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { SprintType, SprintStatus } from '../types/sprint.types';
|
||||
|
||||
export const SPRINT_TYPE_LABELS: Record<SprintType, string> = {
|
||||
DESCOBERTA: 'Descoberta',
|
||||
DESIGN: 'Design',
|
||||
ARQUITETURA: 'Arquitetura',
|
||||
CONSTRUCAO: 'Construção',
|
||||
};
|
||||
|
||||
export const SPRINT_TYPE_OPTIONS = Object.entries(SPRINT_TYPE_LABELS).map(([value, label]) => ({
|
||||
value,
|
||||
label,
|
||||
}));
|
||||
|
||||
export const SPRINT_STATUS_LABELS: Record<SprintStatus, string> = {
|
||||
RASCUNHO: 'Rascunho',
|
||||
EM_EXECUCAO: 'Em Execução',
|
||||
FINALIZADA: 'Finalizada',
|
||||
CANCELADA: 'Cancelada',
|
||||
};
|
||||
|
||||
export const SPRINT_STATUS_OPTIONS = Object.entries(SPRINT_STATUS_LABELS).map(([value, label]) => ({
|
||||
value,
|
||||
label,
|
||||
}));
|
||||
|
||||
export const SPRINT_STATUS_VARIANTS: Record<SprintStatus, string> = {
|
||||
RASCUNHO: 'info',
|
||||
EM_EXECUCAO: 'success',
|
||||
FINALIZADA: 'neutral',
|
||||
CANCELADA: 'danger',
|
||||
};
|
||||
|
||||
export const SPRINT_TYPE_VARIANTS: Record<SprintType, string> = {
|
||||
DESCOBERTA: 'purple',
|
||||
DESIGN: 'info',
|
||||
ARQUITETURA: 'warning',
|
||||
CONSTRUCAO: 'primary',
|
||||
};
|
||||
65
src/constants/work-order-status.ts
Normal file
65
src/constants/work-order-status.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Briefcase, FileEdit, Send, PlayCircle, CheckCircle2, XCircle } from 'lucide-react';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import { WorkOrderStatus } from '../types/work-order.types';
|
||||
|
||||
type StatusVariant =
|
||||
| 'success'
|
||||
| 'danger'
|
||||
| 'warning'
|
||||
| 'info'
|
||||
| 'primary'
|
||||
| 'purple'
|
||||
| 'success-dark'
|
||||
| 'danger-dark'
|
||||
| 'neutral';
|
||||
|
||||
export interface WorkOrderStatusConfig {
|
||||
label: string;
|
||||
variant: StatusVariant;
|
||||
color: string;
|
||||
icon: LucideIcon;
|
||||
}
|
||||
|
||||
const configMap: Record<WorkOrderStatus, WorkOrderStatusConfig> = {
|
||||
[WorkOrderStatus.RASCUNHO]: {
|
||||
label: 'Rascunho',
|
||||
variant: 'neutral',
|
||||
color: 'gray',
|
||||
icon: FileEdit,
|
||||
},
|
||||
[WorkOrderStatus.EMITIDA]: {
|
||||
label: 'Emitida',
|
||||
variant: 'info',
|
||||
color: 'blue',
|
||||
icon: Send,
|
||||
},
|
||||
[WorkOrderStatus.EM_EXECUCAO]: {
|
||||
label: 'Em execução',
|
||||
variant: 'success',
|
||||
color: 'green',
|
||||
icon: PlayCircle,
|
||||
},
|
||||
[WorkOrderStatus.TOTALMENTE_PAGA]: {
|
||||
label: 'Totalmente paga',
|
||||
variant: 'purple',
|
||||
color: 'purple',
|
||||
icon: CheckCircle2,
|
||||
},
|
||||
[WorkOrderStatus.CANCELADA]: {
|
||||
label: 'Cancelada',
|
||||
variant: 'danger-dark',
|
||||
color: 'red',
|
||||
icon: XCircle,
|
||||
},
|
||||
};
|
||||
|
||||
export function getWorkOrderStatusConfig(status: WorkOrderStatus): WorkOrderStatusConfig {
|
||||
return configMap[status];
|
||||
}
|
||||
|
||||
export const WORK_ORDER_STATUS_OPTIONS = Object.entries(configMap).map(([value, config]) => ({
|
||||
value,
|
||||
label: config.label,
|
||||
}));
|
||||
|
||||
export const WorkOrderIcon = Briefcase;
|
||||
Reference in New Issue
Block a user