From 6ca180bb05ebf6230fa20036b0fe248fef09830f Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Tue, 27 Jun 2023 14:30:55 +0800 Subject: [PATCH] Update empty state for no logs based on filters --- .../Organization/AuditLogs/AuditLogs.tsx | 401 +++++++++--------- 1 file changed, 199 insertions(+), 202 deletions(-) diff --git a/studio/components/interfaces/Organization/AuditLogs/AuditLogs.tsx b/studio/components/interfaces/Organization/AuditLogs/AuditLogs.tsx index 8b84b0d8965..61d80148bfd 100644 --- a/studio/components/interfaces/Organization/AuditLogs/AuditLogs.tsx +++ b/studio/components/interfaces/Organization/AuditLogs/AuditLogs.tsx @@ -23,8 +23,6 @@ import LogDetailsPanel from './LogDetailsPanel' // [Joshen considerations] // - Maybe fix the height of the table to the remaining height of the viewport, so that the search input is always visible // - We'll need pagination as well if the audit logs get too large, but that needs to be implemented on the API side first if possible -// - Need to update RQ's resource key, so that it can update with iso_timestamp_start/end changes, check Alaister OR LogsExplorer -// - Need to update to show retention policy (KM will update endpoint) // - I've hidden time input in the date picker for now cause the time support in the component is a bit iffy, need to investigate // - Maybe a rule to follow from here is just everytime we call dayjs, use UTC(), one TZ to rule them all @@ -89,221 +87,220 @@ const AuditLogs = () => { )} - {/* [Joshen] We'll need to also handle then, if the selected date range is out, rather than blocking all actions */} {isError && } {isSuccess && ( <> +
+

Filter by

+ setFilters({ ...filters, users: values })} + /> + setFilters({ ...filters, projects: values })} + /> + { + if (value.from !== null && value.to !== null) { + const current = dayjs().utc() + const from = dayjs(value.from) + .utc() + .hour(current.hour()) + .minute(current.minute()) + .second(current.second()) + .toISOString() + const to = dayjs(value.to) + .utc() + .hour(current.hour()) + .minute(current.minute()) + .second(current.second()) + .toISOString() + setDateRange({ from, to }) + } + }} + renderFooter={() => { + return ( + + Your organization has a log retention period of{' '} + + {retentionPeriod} day + {retentionPeriod > 1 ? 's' : ''} + + . You may only view logs from{' '} + {dayjs().subtract(retentionPeriod, 'days').format('DD MMM YYYY')} as the + earliest date. + + ) + }} + /> +
+ {logs.length === 0 ? (

Your organization does not have any audit logs available yet

+ ) : logs.length > 0 && sortedLogs.length === 0 ? ( +
+

No audit logs found based on the filters applied

+
) : ( - <> -
-

Filter by

- setFilters({ ...filters, users: values })} - /> - setFilters({ ...filters, projects: values })} - /> - { - if (value.from !== null && value.to !== null) { - const current = dayjs().utc() - const from = dayjs(value.from) - .utc() - .hour(current.hour()) - .minute(current.minute()) - .second(current.second()) - .toISOString() - const to = dayjs(value.to) - .utc() - .hour(current.hour()) - .minute(current.minute()) - .second(current.second()) - .toISOString() - setDateRange({ from, to }) - } - }} - renderFooter={() => { - return ( - - Your organization has a log retention period of{' '} - - {retentionPeriod} day - {retentionPeriod > 1 ? 's' : ''} - - . You may only view logs from{' '} - {dayjs().subtract(retentionPeriod, 'days').format('DD MMM YYYY')} as the - earliest date. - - ) - }} - /> -
+ + User + , + + Action + , + + Target + , + +
+

Date

-
- User - , - - Action - , - - Target - , - -
-

Date

- - - -
-
, - , - ]} - body={ - sortedLogs?.map((log) => { - const user = members.find((member) => member.gotrue_id === log.actor.id) - const role = roles.find((role) => user?.role_ids?.[0] === role.id) - const project = projects?.find( - (project) => project.ref === log.permission_group.project_ref - ) - const organization = organizations?.find( - (org) => org.slug === log.permission_group.org_slug - ) - - const hasStatusCode = log.action.metadata[0]?.status !== undefined - const userIcon = - user === undefined ? ( -
-

?

-
- ) : user?.invited_id || user?.username === user?.primary_email ? ( -
- -
- ) : ( - + + - - + + + + + + , + , + ]} + body={ + sortedLogs?.map((log) => { + const user = members.find((member) => member.gotrue_id === log.actor.id) + const role = roles.find((role) => user?.role_ids?.[0] === role.id) + const project = projects?.find( + (project) => project.ref === log.permission_group.project_ref + ) + const organization = organizations?.find( + (org) => org.slug === log.permission_group.org_slug + ) + + const hasStatusCode = log.action.metadata[0]?.status !== undefined + const userIcon = + user === undefined ? ( +
+

?

+
+ ) : user?.invited_id || user?.username === user?.primary_email ? ( +
+ +
+ ) : ( + ) - }) ?? [] - } - /> - + + return ( + setSelectedLog(log)} + className="cursor-pointer hover:!bg-scale-100 transition duration-100" + > + +
+ {userIcon} +
+

{user?.username ?? log.actor.id}

+ {role && ( +

{role?.name}

+ )} +
+
+
+ +
+ {hasStatusCode && ( +

+ {log.action.metadata[0].status} +

+ )} +

{log.action.name}

+
+
+ +

+ {project?.name + ? 'Project: ' + : organization?.name + ? 'Organization: ' + : null} + {project?.name ?? organization?.name ?? 'Entity no longer exists'} +

+

+ {log.permission_group.project_ref + ? 'Ref: ' + : log.permission_group.org_slug + ? 'Slug: ' + : null} + {log.permission_group.project_ref ?? log.permission_group.org_slug} +

+
+ {dayjs(log.timestamp).format('DD MMM YYYY, HH:mm:ss')} + + + +
+ ) + }) ?? [] + } + /> )} )}