@@ -30,11 +30,11 @@ export function ControlledField<TFieldValues extends FieldValues = FieldValues>(
|
||||
);
|
||||
}
|
||||
|
||||
export function ControlledSelect({
|
||||
export function ControlledSelect<TFieldValues extends FieldValues = FieldValues>({
|
||||
control,
|
||||
name,
|
||||
...props
|
||||
}: Props<typeof Select>) {
|
||||
}: Props<typeof Select, TFieldValues>) {
|
||||
return (
|
||||
<Controller
|
||||
control={control}
|
||||
|
||||
@@ -30,7 +30,7 @@ export function PublicTrustCenterLayout({ organizationName, organizationLogo, ch
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
} catch (error) {
|
||||
} catch {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: __("Logout failed"),
|
||||
|
||||
@@ -336,7 +336,7 @@ export default function APIKeysPage() {
|
||||
const data: { key: string } = await response.json();
|
||||
setCurrentKey(data.key);
|
||||
keyDialogRef.current?.open();
|
||||
} catch (error) {
|
||||
} catch {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: __("Failed to load API key"),
|
||||
@@ -355,7 +355,7 @@ export default function APIKeysPage() {
|
||||
description: __("API key copied to clipboard"),
|
||||
variant: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
} catch {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: __("Failed to copy to clipboard"),
|
||||
|
||||
@@ -19,6 +19,7 @@ type Document = {
|
||||
document_version_id: string;
|
||||
title: string;
|
||||
signed?: boolean;
|
||||
organization_name: string;
|
||||
};
|
||||
|
||||
type DocumentSigningResponse = {
|
||||
@@ -86,7 +87,7 @@ export default function DocumentSigningRequestsPage() {
|
||||
// Extract organization name from the first document
|
||||
const organizationName =
|
||||
documents.length > 0
|
||||
? (documents[0] as any).organization_name || "Organization"
|
||||
? documents[0].organization_name || "Organization"
|
||||
: "Organization";
|
||||
|
||||
setSigningData({
|
||||
|
||||
@@ -47,10 +47,10 @@ export default function LoginPage() {
|
||||
}
|
||||
|
||||
window.location.href = "/";
|
||||
} catch (e: any) {
|
||||
} catch (e: unknown) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: e.message as string,
|
||||
description: e instanceof Error ? e.message : __("Failed to login"),
|
||||
variant: "error",
|
||||
});
|
||||
} finally {
|
||||
@@ -90,10 +90,10 @@ export default function LoginPage() {
|
||||
} else {
|
||||
throw new Error(__("SSO not available for this email domain"));
|
||||
}
|
||||
} catch (e: any) {
|
||||
} catch (e: unknown) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: e.message as string,
|
||||
description: e instanceof Error ? e.message : __("Failed to login"),
|
||||
variant: "error",
|
||||
});
|
||||
} finally {
|
||||
|
||||
@@ -47,7 +47,16 @@ export default function NewOrganizationPage() {
|
||||
const handleSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
const name = formData.get("name")?.toString()!;
|
||||
const name = formData.get("name")?.toString();
|
||||
if (!name) {
|
||||
toast({
|
||||
title: __("Error"),
|
||||
description: __("Name is required"),
|
||||
variant: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsFetching(true);
|
||||
|
||||
createOrganization({
|
||||
|
||||
@@ -63,8 +63,8 @@ export default function AssetDetailsPage(props: Props) {
|
||||
);
|
||||
const deleteAsset = useDeleteAsset(assetEntry, connectionId);
|
||||
|
||||
const vendors = assetEntry.vendors?.edges.map((edge: any) => edge.node) ?? [];
|
||||
const vendorIds = vendors.map((vendor: any) => vendor.id);
|
||||
const vendors = assetEntry.vendors?.edges.map((edge) => edge.node) ?? [];
|
||||
const vendorIds = vendors.map((vendor) => vendor.id);
|
||||
|
||||
const { control, formState, handleSubmit, register, reset } = useFormWithSchema(updateAssetSchema, {
|
||||
defaultValues: {
|
||||
|
||||
@@ -54,9 +54,6 @@ export default function AuditDetailsPage(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const organizationId = useOrganizationId();
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
if (!auditEntry || !auditEntry.id || !auditEntry.framework) {
|
||||
return <div>{__("Audit not found")}</div>;
|
||||
}
|
||||
|
||||
const deleteAudit = useDeleteAudit(
|
||||
{ id: auditEntry.id!, framework: { name: auditEntry.framework!.name } },
|
||||
@@ -78,6 +75,10 @@ export default function AuditDetailsPage(props: Props) {
|
||||
const confirm = useConfirm();
|
||||
const { toast } = useToast();
|
||||
|
||||
if (!auditEntry || !auditEntry.id || !auditEntry.framework) {
|
||||
return <div>{__("Audit not found")}</div>;
|
||||
}
|
||||
|
||||
const onSubmit = handleSubmit(async (formData) => {
|
||||
if (!auditEntry.id) return;
|
||||
|
||||
|
||||
@@ -61,9 +61,6 @@ export default function ContinualImprovementDetailsPage(props: Props) {
|
||||
const { snapshotId } = useParams<{ snapshotId?: string }>();
|
||||
const isSnapshotMode = Boolean(snapshotId);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
if (!improvement) {
|
||||
return <div>{__("Continual improvement entry not found")}</div>;
|
||||
}
|
||||
|
||||
validateSnapshotConsistency(improvement, snapshotId);
|
||||
|
||||
@@ -94,6 +91,10 @@ export default function ContinualImprovementDetailsPage(props: Props) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!improvement) {
|
||||
return <div>{__("Continual improvement entry not found")}</div>;
|
||||
}
|
||||
|
||||
const onSubmit = handleSubmit(async (formData) => {
|
||||
try {
|
||||
await updateImprovement({
|
||||
|
||||
@@ -281,7 +281,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
|
||||
variant="card"
|
||||
measures={control.measures?.edges.map((edge) => edge.node) ?? []}
|
||||
params={{ controlId: control.id }}
|
||||
connectionId={control.measures?.__id!}
|
||||
connectionId={control.measures?.__id ?? ""}
|
||||
onAttach={withErrorHandling(attachMeasure, __("Failed to link measure"))}
|
||||
onDetach={withErrorHandling(detachMeasure, __("Failed to unlink measure"))}
|
||||
disabled={isAttachingMeasure || isDetachingMeasure}
|
||||
@@ -292,7 +292,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
|
||||
variant="card"
|
||||
documents={control.documents?.edges.map((edge) => edge.node) ?? []}
|
||||
params={{ controlId: control.id }}
|
||||
connectionId={control.documents?.__id!}
|
||||
connectionId={control.documents?.__id ?? ""}
|
||||
onAttach={withErrorHandling(attachDocument, __("Failed to link document"))}
|
||||
onDetach={withErrorHandling(detachDocument, __("Failed to unlink document"))}
|
||||
disabled={isAttachingDocument || isDetachingDocument}
|
||||
@@ -303,7 +303,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
|
||||
variant="card"
|
||||
audits={control.audits?.edges.map((edge) => edge.node) ?? []}
|
||||
params={{ controlId: control.id }}
|
||||
connectionId={control.audits?.__id!}
|
||||
connectionId={control.audits?.__id ?? ""}
|
||||
onAttach={withErrorHandling(attachAudit, __("Failed to link audit"))}
|
||||
onDetach={withErrorHandling(detachAudit, __("Failed to unlink audit"))}
|
||||
disabled={isAttachingAudit || isDetachingAudit}
|
||||
@@ -314,7 +314,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
|
||||
variant="card"
|
||||
snapshots={control.snapshots?.edges.map((edge) => edge.node) ?? []}
|
||||
params={{ controlId: control.id }}
|
||||
connectionId={control.snapshots?.__id!}
|
||||
connectionId={control.snapshots?.__id ?? ""}
|
||||
onAttach={withErrorHandling(attachSnapshot, __("Failed to link snapshot"))}
|
||||
onDetach={withErrorHandling(detachSnapshot, __("Failed to unlink snapshot"))}
|
||||
disabled={isAttachingSnapshot || isDetachingSnapshot}
|
||||
|
||||
@@ -83,15 +83,10 @@ export function FrameworkControlDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const frameworkControl = useFragment(controlFragment, props.control);
|
||||
const dialogRef = useDialogRef();
|
||||
const [mutate, isMutating] = props.control
|
||||
? useMutationWithToasts(updateMutation, {
|
||||
successMessage: __("Control updated successfully."),
|
||||
errorMessage: __("Failed to update control"),
|
||||
})
|
||||
: useMutationWithToasts(createMutation, {
|
||||
successMessage: __("Control created successfully."),
|
||||
errorMessage: __("Failed to create control"),
|
||||
});
|
||||
const [mutate, isMutating] = useMutationWithToasts(props.control ? updateMutation : createMutation, {
|
||||
successMessage: __(`Control ${props.control ? "updated" : "created"} successfully.`),
|
||||
errorMessage: __(`Failed to ${props.control ? "update" : "create"} control`),
|
||||
});
|
||||
|
||||
const defaultValues = useMemo(() => ({
|
||||
name: frameworkControl?.name ?? "",
|
||||
|
||||
@@ -65,7 +65,8 @@ const schema = z.object({
|
||||
*/
|
||||
export function FrameworkFormDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const dialogRef = props.ref ?? useDialogRef();
|
||||
const ref = useDialogRef();
|
||||
const dialogRef = props.ref ?? ref;
|
||||
const { register, handleSubmit, reset } = useFormWithSchema(schema, {
|
||||
defaultValues: {
|
||||
name: props.framework?.name ?? "",
|
||||
|
||||
@@ -66,15 +66,16 @@ type Props = {
|
||||
|
||||
export default function MeasureFormDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const ref = useDialogRef();
|
||||
const dialogRef = props.ref ?? ref;
|
||||
const measure = useFragment(measureFragment, props.measure);
|
||||
const dialogRef = props.ref ?? useDialogRef();
|
||||
const organizationId = useOrganizationId();
|
||||
const [mutate] = props.measure
|
||||
? useUpdateMeasure()
|
||||
: useMutationWithToasts(measureCreateMutation, {
|
||||
successMessage: __("Measure created successfully."),
|
||||
errorMessage: __("Failed to create measure"),
|
||||
});
|
||||
const [updateMeasure] = useUpdateMeasure();
|
||||
const [createMeasure] = useMutationWithToasts(measureCreateMutation, {
|
||||
successMessage: __("Measure created successfully."),
|
||||
errorMessage: __("Failed to create measure"),
|
||||
});
|
||||
const mutate = props.measure ? updateMeasure : createMeasure;
|
||||
|
||||
const { control, handleSubmit, register, formState, reset } =
|
||||
useFormWithSchema(measureSchema, {
|
||||
|
||||
@@ -56,10 +56,6 @@ export default function MeetingDetailPage(props: Props) {
|
||||
const navigate = useNavigate();
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
if (!meeting) {
|
||||
return <div>{__("Meeting not found")}</div>;
|
||||
}
|
||||
|
||||
const [deleteMeeting, isDeleting] = useDeleteMeetingMutation();
|
||||
const confirm = useConfirm();
|
||||
const updateMinutesDialogRef = useRef<UpdateMeetingMinutesDialogRef>(null);
|
||||
@@ -117,12 +113,16 @@ export default function MeetingDetailPage(props: Props) {
|
||||
setCanDelete(false);
|
||||
}
|
||||
}
|
||||
}, [organizationId]);
|
||||
|
||||
const hasAnyAction = canUpdate || canDelete;
|
||||
}, [organizationId, isAuthorized]);
|
||||
|
||||
usePageTitle(meeting.name);
|
||||
|
||||
if (!meeting) {
|
||||
return <div>{__("Meeting not found")}</div>;
|
||||
}
|
||||
|
||||
const hasAnyAction = canUpdate || canDelete;
|
||||
|
||||
const handleDelete = () => {
|
||||
confirm(
|
||||
() =>
|
||||
|
||||
@@ -64,10 +64,6 @@ export default function ObligationDetailsPage(props: Props) {
|
||||
const isSnapshotMode = Boolean(snapshotId);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
if (!obligation) {
|
||||
return <div>{__("Obligation not found")}</div>;
|
||||
}
|
||||
|
||||
validateSnapshotConsistency(obligation, snapshotId);
|
||||
|
||||
const updateObligation = useUpdateObligation();
|
||||
@@ -79,7 +75,7 @@ export default function ObligationDetailsPage(props: Props) {
|
||||
);
|
||||
|
||||
const deleteObligation = useDeleteObligation(
|
||||
{ id: obligation?.id! },
|
||||
{ id: obligation?.id ?? "" },
|
||||
connectionId
|
||||
);
|
||||
|
||||
@@ -104,6 +100,10 @@ export default function ObligationDetailsPage(props: Props) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!obligation) {
|
||||
return <div>{__("Obligation not found")}</div>;
|
||||
}
|
||||
|
||||
const onSubmit = handleSubmit(async (formData) => {
|
||||
try {
|
||||
await updateObligation({
|
||||
|
||||
@@ -77,10 +77,6 @@ export default function ProcessingActivityDetailsPage(props: Props) {
|
||||
const isSnapshotMode = Boolean(snapshotId);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
if (!activity) {
|
||||
return <div>{__("Processing activity not found")}</div>;
|
||||
}
|
||||
|
||||
validateSnapshotConsistency(activity, snapshotId);
|
||||
|
||||
const updateActivity = useUpdateProcessingActivity();
|
||||
@@ -120,6 +116,10 @@ export default function ProcessingActivityDetailsPage(props: Props) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!activity) {
|
||||
return <div>{__("Processing activity not found")}</div>;
|
||||
}
|
||||
|
||||
const onSubmit = handleSubmit(async (formData) => {
|
||||
try {
|
||||
await updateActivity({
|
||||
|
||||
@@ -102,7 +102,7 @@ export default function SAMLSettingsTab() {
|
||||
const configs = organization.samlConfigurations;
|
||||
|
||||
const dialogRef = useDialogRef();
|
||||
const [editingConfig, setEditingConfig] = useState<typeof configs[0] | null>(null);
|
||||
const [editingConfig, setEditingConfig] = useState<Partial<typeof configs[0]> & {id: string} | null>(null);
|
||||
const [currentStep, setCurrentStep] = useState<SetupStep>("initiate");
|
||||
const [dnsRecord, setDnsRecord] = useState<string>("");
|
||||
|
||||
@@ -222,7 +222,7 @@ export default function SAMLSettingsTab() {
|
||||
},
|
||||
onCompleted: (response) => {
|
||||
setDnsRecord(response.initiateDomainVerification.dnsRecord);
|
||||
setEditingConfig(response.initiateDomainVerification.samlConfiguration as any);
|
||||
setEditingConfig(response.initiateDomainVerification.samlConfiguration);
|
||||
setCurrentStep("verify");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -45,10 +45,6 @@ export default function VendorDetailPage(props: Props) {
|
||||
const isSnapshotMode = Boolean(snapshotId);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
|
||||
if (!vendor) {
|
||||
return <div>{__("Vendor not found")}</div>;
|
||||
}
|
||||
|
||||
validateSnapshotConsistency(vendor, snapshotId);
|
||||
const deleteVendor = useDeleteVendor(
|
||||
vendor,
|
||||
@@ -60,6 +56,10 @@ export default function VendorDetailPage(props: Props) {
|
||||
vendor as VendorComplianceTabFragment$key
|
||||
).complianceReports.edges.length;
|
||||
|
||||
if (!vendor) {
|
||||
return <div>{__("Vendor not found")}</div>;
|
||||
}
|
||||
|
||||
const vendorsUrl = isSnapshotMode && snapshotId
|
||||
? `/organizations/${organizationId}/snapshots/${snapshotId}/vendors`
|
||||
: `/organizations/${organizationId}/vendors`;
|
||||
|
||||
@@ -68,7 +68,7 @@ function Certifications(props: CertificationsProps) {
|
||||
([key, value]) =>
|
||||
[key, value.filter((c) => props.value.includes(c))] as const
|
||||
)
|
||||
.filter(([_, certifications]) => certifications.length > 0);
|
||||
.filter(([, certifications]) => certifications.length > 0);
|
||||
categories.push([
|
||||
"custom",
|
||||
props.value.filter((c) => !categorizedCertifications.includes(c)),
|
||||
|
||||
Reference in New Issue
Block a user