@@ -55,6 +55,7 @@ type Props<Params> = {
|
||||
onAttach: Mutation<Params>;
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
export function LinkedAuditsCard<Params>(props: Props<Params>) {
|
||||
@@ -97,16 +98,18 @@ export function LinkedAuditsCard<Params>(props: Props<Params>) {
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Audits")}</div>
|
||||
<LinkedAuditsDialog
|
||||
disabled={props.disabled}
|
||||
linkedAudits={props.audits}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link audit")}
|
||||
</Button>
|
||||
</LinkedAuditsDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedAuditsDialog
|
||||
disabled={props.disabled}
|
||||
linkedAudits={props.audits}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link audit")}
|
||||
</Button>
|
||||
</LinkedAuditsDialog>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
@@ -114,13 +117,13 @@ export function LinkedAuditsCard<Params>(props: Props<Params>) {
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{audits.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={3} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 2 : 3} className="text-center text-txt-secondary">
|
||||
{__("No audits linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
@@ -130,9 +133,10 @@ export function LinkedAuditsCard<Params>(props: Props<Params>) {
|
||||
key={audit.id}
|
||||
audit={audit}
|
||||
onClick={onDetach}
|
||||
readOnly={props.readOnly}
|
||||
/>
|
||||
))}
|
||||
{variant === "table" && (
|
||||
{variant === "table" && !props.readOnly && (
|
||||
<LinkedAuditsDialog
|
||||
disabled={props.disabled}
|
||||
linkedAudits={props.audits}
|
||||
@@ -163,6 +167,7 @@ export function LinkedAuditsCard<Params>(props: Props<Params>) {
|
||||
function AuditRow(props: {
|
||||
audit: LinkedAuditsCardFragment$key & { id: string };
|
||||
onClick: (auditId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const audit = useFragment(linkedAuditFragment, props.audit);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -187,15 +192,17 @@ function AuditRow(props: {
|
||||
{audit.state.replace(/_/g, " ")}
|
||||
</Badge>
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(audit.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(audit.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ type Props<Params> = {
|
||||
onAttach?: Mutation<Params>;
|
||||
// Allow sorting in the table
|
||||
refetch: ComponentProps<typeof SortableTable>["refetch"];
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,13 +97,13 @@ export function LinkedControlsCard<Params>(props: Props<Params>) {
|
||||
<Tr>
|
||||
<SortableTh field="SECTION_TITLE">{__("Reference")}</SortableTh>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{controls.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 2 : 3} className="text-center text-txt-secondary">
|
||||
{__("No controls linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
@@ -113,17 +114,20 @@ export function LinkedControlsCard<Params>(props: Props<Params>) {
|
||||
control={control}
|
||||
onClick={onDetach}
|
||||
onAttach={onAttach}
|
||||
readOnly={props.readOnly}
|
||||
/>
|
||||
))}
|
||||
<LinkedControlsDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedControls={controls}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={3}>{__("Link control")}</TrButton>
|
||||
</LinkedControlsDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedControlsDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedControls={controls}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={3}>{__("Link control")}</TrButton>
|
||||
</LinkedControlsDialog>
|
||||
)}
|
||||
</Tbody>
|
||||
</SortableTable>
|
||||
);
|
||||
@@ -133,6 +137,7 @@ function ControlRow(props: {
|
||||
control: LinkedControlsCardFragment$key & { id: string };
|
||||
onClick: (controlId: string) => void;
|
||||
onAttach?: (controlId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const control = useFragment(linkedControlFragment, props.control);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -149,15 +154,17 @@ function ControlRow(props: {
|
||||
</span>
|
||||
</Td>
|
||||
<Td>{control.name}</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(control.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(control.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ type Props<Params> = {
|
||||
// Mutation to detach a document (will receive {documentId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -109,17 +110,19 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Documents")}</div>
|
||||
<LinkedDocumentDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedDocuments={props.documents}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link document")}
|
||||
</Button>
|
||||
</LinkedDocumentDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedDocumentDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedDocuments={props.documents}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link document")}
|
||||
</Button>
|
||||
</LinkedDocumentDialog>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
@@ -128,13 +131,13 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("Type")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{documents.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 3 : 4} className="text-center text-txt-secondary">
|
||||
{__("No documents linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
@@ -144,9 +147,10 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
key={document.id}
|
||||
document={document}
|
||||
onClick={onDetach}
|
||||
readOnly={props.readOnly}
|
||||
/>
|
||||
))}
|
||||
{variant === "table" && (
|
||||
{variant === "table" && !props.readOnly && (
|
||||
<LinkedDocumentDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
@@ -178,6 +182,7 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
function DocumentRow(props: {
|
||||
document: LinkedDocumentsCardFragment$key & { id: string };
|
||||
onClick: (documentId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const document = useFragment(linkedDocumentFragment, props.document);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -203,15 +208,17 @@ function DocumentRow(props: {
|
||||
<Td>
|
||||
<DocumentVersionBadge state={document.versions.edges[0].node.status} />
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(document.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(document.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ type Props<Params> = {
|
||||
// Mutation to detach a measure (will receive {measureId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -102,17 +103,19 @@ export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Measures")}</div>
|
||||
<LinkedMeasureDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedMeasures={props.measures}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link measure")}
|
||||
</Button>
|
||||
</LinkedMeasureDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedMeasureDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedMeasures={props.measures}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link measure")}
|
||||
</Button>
|
||||
</LinkedMeasureDialog>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
@@ -120,21 +123,21 @@ export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{measures.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={3} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 2 : 3} className="text-center text-txt-secondary">
|
||||
{__("No measures linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{measures.map((measure) => (
|
||||
<MeasureRow key={measure.id} measure={measure} onClick={onDetach} />
|
||||
<MeasureRow key={measure.id} measure={measure} onClick={onDetach} readOnly={props.readOnly} />
|
||||
))}
|
||||
{variant === "table" && (
|
||||
{variant === "table" && !props.readOnly && (
|
||||
<LinkedMeasureDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
@@ -166,6 +169,7 @@ export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
function MeasureRow(props: {
|
||||
measure: LinkedMeasuresCardFragment$key & { id: string };
|
||||
onClick: (measureId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const measure = useFragment(linkedMeasureFragment, props.measure);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -177,15 +181,17 @@ function MeasureRow(props: {
|
||||
<Td>
|
||||
<MeasureBadge state={measure.state} />
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(measure.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(measure.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ type Props<Params> = {
|
||||
connectionId: string;
|
||||
disabled?: boolean;
|
||||
variant?: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
|
||||
params: Params;
|
||||
|
||||
@@ -102,17 +103,19 @@ export function LinkedObligationsCard<Params>(props: Props<Params>) {
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Obligations")}</div>
|
||||
<LinkedObligationDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedObligations={props.obligations}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link obligation")}
|
||||
</Button>
|
||||
</LinkedObligationDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedObligationDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedObligations={props.obligations}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link obligation")}
|
||||
</Button>
|
||||
</LinkedObligationDialog>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
@@ -122,21 +125,21 @@ export function LinkedObligationsCard<Params>(props: Props<Params>) {
|
||||
<Th>{__("Source")}</Th>
|
||||
<Th>{__("Status")}</Th>
|
||||
<Th>{__("Owner")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{obligations.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 4 : 5} className="text-center text-txt-secondary">
|
||||
{__("No obligations linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{obligations.map((obligation) => (
|
||||
<ObligationRow key={obligation.id} obligation={obligation} onClick={onDetach} />
|
||||
<ObligationRow key={obligation.id} obligation={obligation} onClick={onDetach} readOnly={props.readOnly} />
|
||||
))}
|
||||
{variant === "table" && (
|
||||
{variant === "table" && !props.readOnly && (
|
||||
<LinkedObligationDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
@@ -168,6 +171,7 @@ export function LinkedObligationsCard<Params>(props: Props<Params>) {
|
||||
function ObligationRow(props: {
|
||||
obligation: LinkedObligationsCardFragment$key & { id: string };
|
||||
onClick: (obligationId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const { __ } = useTranslate();
|
||||
const obligation = useFragment(linkedObligationFragment, props.obligation);
|
||||
@@ -199,15 +203,17 @@ function ObligationRow(props: {
|
||||
<Td>
|
||||
{obligation.owner?.fullName || __("Unassigned")}
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon={IconTrashCan}
|
||||
onClick={onDetach}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon={IconTrashCan}
|
||||
onClick={onDetach}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ const inviteMutation = graphql`
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
fullName: z.string(),
|
||||
role: z.enum(["OWNER", "ADMIN", "FULL", "VIEWER", "EMPLOYEE"]).default("VIEWER"),
|
||||
role: z.enum(["OWNER", "ADMIN", "FULL", "VIEWER", "AUDITOR", "EMPLOYEE"]).default("VIEWER"),
|
||||
createPeople: z.boolean().default(false),
|
||||
});
|
||||
|
||||
@@ -126,6 +126,7 @@ function InviteUserDialogContent({ children, connectionId, onRefetch }: Props) {
|
||||
{assignableRoles.includes("OWNER") && <Option value="OWNER">{__("Owner")}</Option>}
|
||||
{assignableRoles.includes("ADMIN") && <Option value="ADMIN">{__("Admin")}</Option>}
|
||||
{assignableRoles.includes("VIEWER") && <Option value="VIEWER">{__("Viewer")}</Option>}
|
||||
{assignableRoles.includes("AUDITOR") && <Option value="AUDITOR">{__("Auditor")}</Option>}
|
||||
{assignableRoles.includes("EMPLOYEE") && <Option value="EMPLOYEE">{__("Employee")}</Option>}
|
||||
</Select>
|
||||
<div className="mt-2 text-sm text-txt-tertiary">
|
||||
@@ -138,6 +139,9 @@ function InviteUserDialogContent({ children, connectionId, onRefetch }: Props) {
|
||||
{field.value === "VIEWER" && (
|
||||
<p>{__("Read-only access")}</p>
|
||||
)}
|
||||
{field.value === "AUDITOR" && (
|
||||
<p>{__("Read-only access without settings, tasks and meetings")}</p>
|
||||
)}
|
||||
{field.value === "EMPLOYEE" && (
|
||||
<p>{__("Access to employee page")}</p>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<4dda94f89f726842762d68c28d8180b6>>
|
||||
* @generated SignedSource<<31b0b8ac2c59ccf3addd4508d56bd166>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,7 +9,7 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type MembershipRole = "ADMIN" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
||||
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
||||
export type InviteUserInput = {
|
||||
createPeople: boolean;
|
||||
email: string;
|
||||
|
||||
@@ -48,6 +48,7 @@ type Props<Params> = {
|
||||
onAttach: Mutation<Params>;
|
||||
// Mutation to detach a risk (will receive {riskId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -88,29 +89,31 @@ export function LinkedRisksCard<Params>(props: Props<Params>) {
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("Inherent Risk")}</Th>
|
||||
<Th>{__("Residual Risk")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{props.risks.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
<Td colSpan={props.readOnly ? 3 : 4} className="text-center text-txt-secondary">
|
||||
{__("No risks linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{props.risks.map((risk) => (
|
||||
<RiskRow key={risk.id} risk={risk} onClick={onDetach} />
|
||||
<RiskRow key={risk.id} risk={risk} onClick={onDetach} readOnly={props.readOnly} />
|
||||
))}
|
||||
<LinkedRisksDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedRisks={props.risks}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={4}>{__("Link risk")}</TrButton>
|
||||
</LinkedRisksDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedRisksDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedRisks={props.risks}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={4}>{__("Link risk")}</TrButton>
|
||||
</LinkedRisksDialog>
|
||||
)}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</div>
|
||||
@@ -120,6 +123,7 @@ export function LinkedRisksCard<Params>(props: Props<Params>) {
|
||||
function RiskRow(props: {
|
||||
risk: LinkedRisksCardFragment$key & { id: string };
|
||||
onClick: (riskId: string) => void;
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const risk = useFragment(linkedRiskFragment, props.risk);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -134,15 +138,17 @@ function RiskRow(props: {
|
||||
<Td>
|
||||
<RiskBadge level={risk.residualRiskScore} />
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(risk.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(risk.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ type Props<Params> = {
|
||||
onAttach: Mutation<Params>;
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
export function LinkedSnapshotsCard<Params>(props: Props<Params>) {
|
||||
@@ -87,21 +88,26 @@ export function LinkedSnapshotsCard<Params>(props: Props<Params>) {
|
||||
|
||||
const Wrapper = variant === "card" ? Card : "div";
|
||||
|
||||
const colSpanTable = props.readOnly ? 4 : 5;
|
||||
const colSpanCard = props.readOnly ? 3 : 4;
|
||||
|
||||
return (
|
||||
<Wrapper padded className="space-y-[10px]">
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Snapshots")}</div>
|
||||
<LinkedSnapshotsDialog
|
||||
disabled={props.disabled}
|
||||
linkedSnapshots={props.snapshots}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link snapshot")}
|
||||
</Button>
|
||||
</LinkedSnapshotsDialog>
|
||||
{!props.readOnly && (
|
||||
<LinkedSnapshotsDialog
|
||||
disabled={props.disabled}
|
||||
linkedSnapshots={props.snapshots}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link snapshot")}
|
||||
</Button>
|
||||
</LinkedSnapshotsDialog>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
@@ -111,13 +117,13 @@ export function LinkedSnapshotsCard<Params>(props: Props<Params>) {
|
||||
<Th>{__("Type")}</Th>
|
||||
{variant === "table" && <Th>{__("Description")}</Th>}
|
||||
<Th>{__("Created")}</Th>
|
||||
<Th></Th>
|
||||
{!props.readOnly && <Th></Th>}
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{snapshots.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={variant === "table" ? 5 : 3} className="text-center text-txt-secondary">
|
||||
<Td colSpan={variant === "table" ? colSpanTable : colSpanCard} className="text-center text-txt-secondary">
|
||||
{__("No snapshots linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
@@ -128,16 +134,17 @@ export function LinkedSnapshotsCard<Params>(props: Props<Params>) {
|
||||
snapshot={snapshot}
|
||||
onClick={onDetach}
|
||||
variant={variant}
|
||||
readOnly={props.readOnly}
|
||||
/>
|
||||
))}
|
||||
{variant === "table" && (
|
||||
{variant === "table" && !props.readOnly && (
|
||||
<LinkedSnapshotsDialog
|
||||
disabled={props.disabled}
|
||||
linkedSnapshots={props.snapshots}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={variant === "table" ? 5 : 3} icon={IconPlusLarge}>
|
||||
<TrButton colspan={colSpanTable} icon={IconPlusLarge}>
|
||||
{__("Link snapshot")}
|
||||
</TrButton>
|
||||
</LinkedSnapshotsDialog>
|
||||
@@ -162,6 +169,7 @@ function SnapshotRow(props: {
|
||||
snapshot: LinkedSnapshotsCardFragment$key & { id: string };
|
||||
onClick: (snapshotId: string) => void;
|
||||
variant: "card" | "table";
|
||||
readOnly?: boolean;
|
||||
}) {
|
||||
const snapshot = useFragment(linkedSnapshotFragment, props.snapshot);
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -186,15 +194,17 @@ function SnapshotRow(props: {
|
||||
<Td className="text-txt-tertiary">
|
||||
{formatDate(snapshot.createdAt)}
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(snapshot.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
{!props.readOnly && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(snapshot.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user