Files
compras/resources/js/components/organization-activation-preview.tsx
T
2026-11-02 20:27:11 +02:00

191 lines
8.6 KiB
TypeScript

import { Link } from '@inertiajs/react';
import { Panel } from '@/components/procurement';
type Person = {
id: number;
name: string;
current_permissions: string[];
configured_permissions: string[];
added: string[];
removed: string[];
current_can_request: boolean;
configured_can_request: boolean;
configured_maintenance_only: boolean;
permanent_admin: boolean;
current_contexts: string[] | null;
configured_contexts: string[] | null;
loses_access: boolean;
};
export type ActivationPreview = {
ready: boolean;
active?: boolean;
version?: number;
checked_at?: string;
users: Person[];
permanent_administrators?: number;
provisional_rules?: boolean;
can_activate?: boolean;
losing_access?: number;
context_labels?: Record<string, string>;
};
export function OrganizationActivationPreview({
preview,
permissions,
tasks,
}: {
preview: ActivationPreview;
permissions: Record<string, string>;
tasks: Record<string, { key: string; label: string }[]>;
}) {
if (!preview.ready) return null;
const labels = (keys: string[], source = permissions) =>
keys.map((key) => source[key] ?? key).join('; ') || 'Nenhuma';
return (
<Panel
title={
preview.active
? 'Acessos e tarefas da configuração activa'
: 'Conferir o efeito da activação'
}
description="Esta consulta reutiliza os perfis e as atribuições guardados. Não altera acessos, não cria contas e não decide processos."
>
<div className="space-y-4 text-sm">
<p>
{preview.users.length} utilizador(es) ·{' '}
{preview.permanent_administrators} administrador(es)
permanente(s)
{preview.active
? ''
: ` · ${preview.losing_access} utilizador(es) ficaria(m) sem competência de acesso`}
</p>
{!preview.active && (
<p className="rounded border p-3">
{preview.can_activate
? 'As condições existentes de dois administradores permanentes e regras confirmadas estão preenchidas. Confira o efeito em cada pessoa antes de activar.'
: 'A activação exige dois administradores permanentes atribuídos e regras de aprovação confirmadas.'}
{preview.provisional_rules &&
' As regras actuais continuam provisórias.'}
</p>
)}
<p>
As tarefas descritas dependem também do processo,
departamento, contexto, independência e competências
específicas. Uma competência financeira não substitui os
acessos próprios às obrigações financeiras.
</p>
<Link
href="/administracao/parametrizacao"
preserveScroll
className="inline-block font-semibold underline"
>
Actualizar diagnóstico e configuração
</Link>
{preview.users.map((person) => (
<details key={person.id} className="rounded border p-3">
<summary className="cursor-pointer font-semibold">
{person.name}
{person.loses_access && !preview.active
? ' · Ficaria sem acesso'
: ''}
{person.permanent_admin
? ' · Administração permanente'
: ''}
</summary>
<div className="mt-3 space-y-3">
<p>
<strong>Competências actuais:</strong>{' '}
{labels(person.current_permissions)}
</p>
<p>
<strong>
Competências dos perfis guardados:
</strong>{' '}
{labels(person.configured_permissions)}
</p>
{!preview.active && (
<>
<p>
<strong>Acrescentadas:</strong>{' '}
{labels(person.added)}
</p>
<p>
<strong>Retiradas:</strong>{' '}
{labels(person.removed)}
</p>
</>
)}
<p>
<strong>
Preparação de requisição de compra:
</strong>{' '}
actualmente{' '}
{person.current_can_request ? 'sim' : 'não'};
pelos perfis guardados{' '}
{person.configured_can_request ? 'sim' : 'não'}.
</p>
{person.configured_contexts === null ? (
<p>
A selecção de contextos ainda não está
activa nesta empresa.
</p>
) : (
<>
<p>
<strong>Contextos actuais:</strong>{' '}
{labels(
person.current_contexts ?? [],
preview.context_labels,
)}
</p>
<p>
<strong>
Contextos pelos perfis guardados:
</strong>{' '}
{labels(
person.configured_contexts,
preview.context_labels,
)}
</p>
</>
)}
{person.configured_maintenance_only ? (
<p>
Manutenção temporária: diagnóstico e
consulta, sem operações de negócio.
</p>
) : (
<div>
<strong>
Tarefas associadas às competências
guardadas:
</strong>
<ul className="mt-2 list-disc space-y-1 pl-5">
{person.configured_permissions
.flatMap(
(permission) =>
tasks[permission] ?? [],
)
.map((task) => (
<li key={task.key}>
{task.label}
</li>
))}
{person.configured_permissions
.length === 0 && (
<li>
Sem tarefas atribuídas pelos
perfis.
</li>
)}
</ul>
</div>
)}
</div>
</details>
))}
</div>
</Panel>
);
}