Permitir consulta pública dos ecrãs reais com dados privados protegidos
tests / ci (push) Canceled after 0s
tests / ci (push) Canceled after 0s
This commit is contained in:
@@ -56,7 +56,11 @@ export function AppSidebar() {
|
||||
...(canReadPurchases
|
||||
? [
|
||||
{ title: 'Fornecedores', href: '/fornecedores', icon: Users },
|
||||
{ title: 'Avaliação de fornecedores', href: '/fornecedores/avaliacoes', icon: Users },
|
||||
{
|
||||
title: 'Avaliação de fornecedores',
|
||||
href: '/fornecedores/avaliacoes',
|
||||
icon: Users,
|
||||
},
|
||||
{ title: 'Cotações', href: '/cotacoes', icon: Scale },
|
||||
{
|
||||
title: 'Ordens de compra',
|
||||
@@ -157,7 +161,14 @@ export function AppSidebar() {
|
||||
icon: FileCheck2,
|
||||
},
|
||||
...(payablesAvailable === true
|
||||
? [{title: 'Obrigações a fornecedores', href: '/obrigacoes-fornecedores', icon: FileCheck2, fullPage: true}]
|
||||
? [
|
||||
{
|
||||
title: 'Obrigações a fornecedores',
|
||||
href: '/obrigacoes-fornecedores',
|
||||
icon: FileCheck2,
|
||||
fullPage: true,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
title: 'Pagamentos externos',
|
||||
|
||||
@@ -34,6 +34,9 @@ import { roleLabels } from '@/types/procurement';
|
||||
export function SgcWorkspaceShell({ children }: { children: ReactNode }) {
|
||||
const page = usePage();
|
||||
const user = page.props.auth?.user;
|
||||
const publicNavigation = page.props.publicNavigation as
|
||||
| { paths: string[] }
|
||||
| undefined;
|
||||
const [mobileOpen, setMobileOpen] = useState(false);
|
||||
const [search, setSearch] = useState('');
|
||||
const [expanded, setExpanded] = useState<Record<string, boolean>>({});
|
||||
@@ -44,6 +47,7 @@ export function SgcWorkspaceShell({ children }: { children: ReactNode }) {
|
||||
const groups = procurementNavigation(
|
||||
access?.active ? access.permissions : (user?.purchasing_role ?? ''),
|
||||
page.props.payablesAvailable === true,
|
||||
publicNavigation?.paths,
|
||||
);
|
||||
const activeId = activeProcurementEntry(groups, page.url);
|
||||
const activeGroup = groups.find((group) =>
|
||||
@@ -274,6 +278,13 @@ export function SgcWorkspaceShell({ children }: { children: ReactNode }) {
|
||||
);
|
||||
return (
|
||||
<div className="min-h-screen bg-slate-50 text-foreground dark:bg-background print:block">
|
||||
{publicNavigation && (
|
||||
<p className="border-b bg-background p-3 text-center text-sm">
|
||||
Consulta pública de desenvolvimento · Sem organização
|
||||
seleccionada e sem registos privados. Alterações exigem
|
||||
autenticação.
|
||||
</p>
|
||||
)}
|
||||
<a
|
||||
href="#sgc-main"
|
||||
className="sr-only z-50 rounded bg-white p-3 text-black focus:not-sr-only focus:fixed focus:top-2 focus:left-2"
|
||||
|
||||
@@ -31,6 +31,7 @@ const inventory = [...readers, 'warehouse'];
|
||||
export function procurementNavigation(
|
||||
role: string | string[],
|
||||
payables: boolean,
|
||||
publicPaths?: string[],
|
||||
): ProcurementGroup[] {
|
||||
const groups: ProcurementGroup[] = [
|
||||
{
|
||||
@@ -341,17 +342,20 @@ export function procurementNavigation(
|
||||
return compact
|
||||
.map((group) => ({
|
||||
...group,
|
||||
entries: group.entries.filter(
|
||||
(entry) =>
|
||||
(entry.id !== 'new_request' ||
|
||||
!Array.isArray(role) ||
|
||||
role.includes('requester')) &&
|
||||
(!entry.roles ||
|
||||
entry.roles.some((permission) =>
|
||||
(Array.isArray(role) ? role : [role]).includes(
|
||||
permission,
|
||||
),
|
||||
)),
|
||||
entries: group.entries.filter((entry) =>
|
||||
publicPaths
|
||||
? publicPaths.includes(
|
||||
new URL(entry.path, 'http://local').pathname,
|
||||
)
|
||||
: (entry.id !== 'new_request' ||
|
||||
!Array.isArray(role) ||
|
||||
role.includes('requester')) &&
|
||||
(!entry.roles ||
|
||||
entry.roles.some((permission) =>
|
||||
(Array.isArray(role) ? role : [role]).includes(
|
||||
permission,
|
||||
),
|
||||
)),
|
||||
),
|
||||
}))
|
||||
.filter((group) => group.entries.length);
|
||||
|
||||
@@ -222,7 +222,7 @@ export default function Budgets({
|
||||
Dotação acumulada: {money(b.approved_total_minor)}
|
||||
</p>
|
||||
<p className="my-3">{b.reason}</p>
|
||||
{!b.approved_by && b.created_by !== auth.user.id && (
|
||||
{!b.approved_by && b.created_by !== auth.user?.id && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
router.post(`/orcamentos/${b.id}/aprovar`)
|
||||
@@ -270,7 +270,7 @@ export default function Budgets({
|
||||
</p>
|
||||
)}
|
||||
{r.status === 'pending' &&
|
||||
r.created_by !== auth.user.id && (
|
||||
r.created_by !== auth.user?.id && (
|
||||
<ReinforcementReview id={r.id} />
|
||||
)}
|
||||
</article>
|
||||
|
||||
@@ -444,7 +444,12 @@ export default function SubmissionForms({
|
||||
return (
|
||||
<>
|
||||
<Head title="Formulários de candidaturas" />
|
||||
<Link className="m-5 inline-block underline" href="/administracao/candidaturas/portal">Configurar área externa do candidato</Link>
|
||||
<Link
|
||||
className="m-5 inline-block underline"
|
||||
href="/administracao/candidaturas/portal"
|
||||
>
|
||||
Configurar área externa do candidato
|
||||
</Link>
|
||||
<div className="mx-auto max-w-5xl space-y-6 p-5 lg:p-8">
|
||||
<PageTitle
|
||||
title="Inscrições e candidaturas electrónicas"
|
||||
|
||||
@@ -31,6 +31,7 @@ export default function Dashboard({
|
||||
approvals,
|
||||
}: Props) {
|
||||
const canRequest = usePage().props.canRequest === true;
|
||||
const publicNavigation = !!usePage().props.publicNavigation;
|
||||
const cards = [
|
||||
{
|
||||
label: 'Requisições',
|
||||
@@ -66,6 +67,7 @@ export default function Dashboard({
|
||||
title="Visão geral das compras"
|
||||
description="Acompanhe os pedidos, as aprovações e a actividade da sua empresa."
|
||||
action={
|
||||
!publicNavigation &&
|
||||
(!company || canRequest) && (
|
||||
<Button
|
||||
asChild
|
||||
@@ -87,7 +89,7 @@ export default function Dashboard({
|
||||
)
|
||||
}
|
||||
/>
|
||||
{!company ? (
|
||||
{!company && !publicNavigation ? (
|
||||
<Panel
|
||||
title="Vamos configurar a sua empresa"
|
||||
description="Crie a organização e o primeiro departamento. Depois pode adicionar a equipa e começar a registar pedidos."
|
||||
@@ -120,7 +122,7 @@ export default function Dashboard({
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{company.rules_provisional && (
|
||||
{company?.rules_provisional && (
|
||||
<div className="rounded-xl border border-amber-200 bg-amber-50 px-5 py-4 text-sm text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100">
|
||||
<strong>
|
||||
Ambiente de desenvolvimento · regras
|
||||
|
||||
@@ -283,11 +283,11 @@ export default function Investment({
|
||||
{canManage &&
|
||||
p.status === 'pending' &&
|
||||
p.id === policies[0]?.id &&
|
||||
p.created_by !== auth.user.id &&
|
||||
p.created_by !== auth.user?.id &&
|
||||
!reviews.some(
|
||||
(r) =>
|
||||
r.investment_policy_id === p.id &&
|
||||
r.reviewed_by === auth.user.id,
|
||||
r.reviewed_by === auth.user?.id,
|
||||
) && <Decision id={p.id} />}
|
||||
</Panel>
|
||||
))}
|
||||
|
||||
@@ -71,7 +71,14 @@ export default function Invoices({
|
||||
return (
|
||||
<>
|
||||
<Head title="Facturas" />
|
||||
{payablesAvailable && <a className="m-6 inline-block underline" href="/obrigacoes-fornecedores">Obrigações a fornecedores — ensaio sintético</a>}
|
||||
{payablesAvailable && (
|
||||
<a
|
||||
className="m-6 inline-block underline"
|
||||
href="/obrigacoes-fornecedores"
|
||||
>
|
||||
Obrigações a fornecedores — ensaio sintético
|
||||
</a>
|
||||
)}
|
||||
<div className="mx-auto grid w-full max-w-6xl gap-6 p-6">
|
||||
<PageTitle
|
||||
eyebrow="SGC · Finanças"
|
||||
@@ -287,8 +294,12 @@ export default function Invoices({
|
||||
</p>
|
||||
{payablesAvailable && (
|
||||
<p className="my-3">
|
||||
<a className="underline" href={`/obrigacoes-fornecedores?invoice=${invoice.id}`}>
|
||||
Consultar ou preparar obrigação desta factura
|
||||
<a
|
||||
className="underline"
|
||||
href={`/obrigacoes-fornecedores?invoice=${invoice.id}`}
|
||||
>
|
||||
Consultar ou preparar obrigação desta
|
||||
factura
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
@@ -303,7 +314,7 @@ export default function Invoices({
|
||||
</ul>
|
||||
{canManage &&
|
||||
invoice.status === 'pending' &&
|
||||
invoice.created_by !== auth.user.id && (
|
||||
invoice.created_by !== auth.user?.id && (
|
||||
<Button
|
||||
disabled={validating !== null}
|
||||
onClick={() => {
|
||||
|
||||
@@ -300,7 +300,7 @@ export default function Payments({
|
||||
)}
|
||||
{canManage &&
|
||||
p.status === 'pending' &&
|
||||
p.created_by !== auth.user.id && (
|
||||
p.created_by !== auth.user?.id && (
|
||||
<Review id={p.id} />
|
||||
)}
|
||||
</Panel>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user