mirror of
https://github.com/supabase/supabase.git
synced 2026-10-19 08:09:11 +03:00
Add date picker, but yet to hook up
This commit is contained in:
1 parent
1eeebaca00
commit
391622db9e
2 files changed
+103
-51
No files matched your search
@@ -15,9 +15,10 @@ import { useOrganizationDetailQuery } from 'data/organizations/organization-deta
|
||||
import { useOrganizationRolesQuery } from 'data/organizations/organization-roles-query'
|
||||
import { useOrganizationsQuery } from 'data/organizations/organizations-query'
|
||||
import { useProjectsQuery } from 'data/projects/projects-query'
|
||||
import { Button, IconArrowDown, IconArrowUp, IconBarChart, IconUser } from 'ui'
|
||||
import { Alert, Button, IconArrowDown, IconArrowUp, IconBarChart, IconUser } from 'ui'
|
||||
import FilterPopover from './FilterPopover'
|
||||
import LogDetailsPanel from './LogDetailsPanel'
|
||||
import { DatePicker } from 'components/ui/DatePicker'
|
||||
|
||||
// [Joshen considerations]
|
||||
// - Maybe fix the height of the table to the remaining height of the viewport, so that the search input is always visible
|
||||
@@ -25,12 +26,16 @@ import LogDetailsPanel from './LogDetailsPanel'
|
||||
|
||||
const AuditLogs = () => {
|
||||
const { slug } = useParams()
|
||||
const currentTime = dayjs().set('millisecond', 0)
|
||||
const currentTime = dayjs().utc().set('millisecond', 0)
|
||||
const [dateSortDesc, setDateSortDesc] = useState(true)
|
||||
const [dateRange, setDateRange] = useState({
|
||||
from: currentTime.subtract(1, 'day').toISOString(),
|
||||
to: currentTime.toISOString(),
|
||||
})
|
||||
const [selectedLog, setSelectedLog] = useState<OrganizationAuditLog>()
|
||||
const [filters, setFilters] = useState<{ users: string[]; projects: string[] }>({
|
||||
users: [], // gotrue_id
|
||||
projects: [], // project_ref
|
||||
users: [], // gotrue_id[]
|
||||
projects: [], // project_ref[]
|
||||
})
|
||||
|
||||
const { data: projects } = useProjectsQuery()
|
||||
@@ -44,8 +49,8 @@ const AuditLogs = () => {
|
||||
isError,
|
||||
} = useOrganizationAuditLogsQuery({
|
||||
slug,
|
||||
iso_timestamp_start: currentTime.subtract(1, 'day').toISOString(),
|
||||
iso_timestamp_end: currentTime.toISOString(),
|
||||
iso_timestamp_start: dateRange.from,
|
||||
iso_timestamp_end: dateRange.to,
|
||||
})
|
||||
|
||||
const members = detailData?.members ?? []
|
||||
@@ -82,6 +87,7 @@ const AuditLogs = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* [Joshen] We'll need to also handle then, if the selected date range is out, rather than blocking all actions */}
|
||||
{isError && <AlertError subject="Failed to retrieve audit logs" />}
|
||||
|
||||
{isSuccess && (
|
||||
@@ -112,6 +118,43 @@ const AuditLogs = () => {
|
||||
activeOptions={filters.projects}
|
||||
onSaveFilters={(values) => setFilters({ ...filters, projects: values })}
|
||||
/>
|
||||
<DatePicker
|
||||
hideTime
|
||||
hideClear
|
||||
triggerButtonType="dashed"
|
||||
triggerButtonTitle=""
|
||||
from={dateRange.from}
|
||||
to={dateRange.to}
|
||||
onChange={(value) => {
|
||||
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={({ to, from }) => {
|
||||
// If selected range is outside of retention policy
|
||||
if (true) {
|
||||
return (
|
||||
<Alert title="" variant="warning" className="mx-3 pl-2 pr-2 pt-1 pb-2">
|
||||
Selected range is outside of included retention policy, as such no data
|
||||
will be returned.
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
|
||||
@@ -17,11 +17,13 @@ import { DatePickerToFrom } from 'components/interfaces/Settings/Logs'
|
||||
|
||||
export interface DatePickerProps {
|
||||
onChange?: (args: DatePickerToFrom) => void
|
||||
to?: string
|
||||
from?: string
|
||||
to?: string // ISO string
|
||||
from?: string // ISO string
|
||||
triggerButtonType?: ButtonProps['type']
|
||||
triggerButtonClassName?: string
|
||||
triggerButtonTitle?: string
|
||||
hideTime?: boolean
|
||||
hideClear?: boolean
|
||||
renderFooter?: (args: DatePickerToFrom) => React.ReactNode | void
|
||||
}
|
||||
|
||||
@@ -38,6 +40,8 @@ function _DatePicker({
|
||||
triggerButtonType = 'default',
|
||||
triggerButtonClassName = '',
|
||||
triggerButtonTitle,
|
||||
hideTime = false,
|
||||
hideClear = false,
|
||||
renderFooter = () => null,
|
||||
}: DatePickerProps) {
|
||||
const [open, setOpen] = useState<boolean>(false)
|
||||
@@ -64,6 +68,7 @@ function _DatePicker({
|
||||
setAppliedEndDate(end)
|
||||
setEndDate(end)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [to, from])
|
||||
|
||||
function handleDatePickerChange(dates: [from: Date | null, to: Date | null]) {
|
||||
@@ -81,15 +86,15 @@ function _DatePicker({
|
||||
const payload = {
|
||||
from: dayjs
|
||||
.utc(startDate)
|
||||
.second(startTime.ss)
|
||||
.minute(startTime.mm)
|
||||
.hour(startTime.HH)
|
||||
.second(Number(startTime.ss))
|
||||
.minute(Number(startTime.mm))
|
||||
.hour(Number(startTime.HH))
|
||||
.toISOString(),
|
||||
to: dayjs
|
||||
.utc(endDate || startDate)
|
||||
.second(endTime.ss)
|
||||
.minute(endTime.mm)
|
||||
.hour(endTime.HH)
|
||||
.second(Number(endTime.ss))
|
||||
.minute(Number(endTime.mm))
|
||||
.hour(Number(endTime.HH))
|
||||
.toISOString(),
|
||||
}
|
||||
if (onChange) onChange(payload)
|
||||
@@ -114,47 +119,49 @@ function _DatePicker({
|
||||
align="center"
|
||||
side="bottom"
|
||||
header={
|
||||
<>
|
||||
<div className="flex items-stretch justify-between py-2">
|
||||
<div className="flex grow flex-col gap-1">
|
||||
<TimeSplitInput
|
||||
type="start"
|
||||
startTime={startTime}
|
||||
endTime={endTime}
|
||||
time={startTime}
|
||||
setTime={setStartTime}
|
||||
setStartTime={setStartTime}
|
||||
setEndTime={setEndTime}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
hideTime ? null : (
|
||||
<>
|
||||
<div className="flex items-stretch justify-between py-2">
|
||||
<div className="flex grow flex-col gap-1">
|
||||
<TimeSplitInput
|
||||
type="start"
|
||||
startTime={startTime}
|
||||
endTime={endTime}
|
||||
time={startTime}
|
||||
setTime={setStartTime}
|
||||
setStartTime={setStartTime}
|
||||
setEndTime={setEndTime}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
flex
|
||||
w-12
|
||||
items-center
|
||||
justify-center
|
||||
text-scale-900
|
||||
`}
|
||||
>
|
||||
<IconArrowRight strokeWidth={1.5} size={14} />
|
||||
>
|
||||
<IconArrowRight strokeWidth={1.5} size={14} />
|
||||
</div>
|
||||
<div className="flex grow flex-col gap-1">
|
||||
<TimeSplitInput
|
||||
type="end"
|
||||
startTime={startTime}
|
||||
endTime={endTime}
|
||||
time={endTime}
|
||||
setTime={setEndTime}
|
||||
setStartTime={setStartTime}
|
||||
setEndTime={setEndTime}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex grow flex-col gap-1">
|
||||
<TimeSplitInput
|
||||
type="end"
|
||||
startTime={startTime}
|
||||
endTime={endTime}
|
||||
time={endTime}
|
||||
setTime={setEndTime}
|
||||
setStartTime={setStartTime}
|
||||
setEndTime={setEndTime}
|
||||
startDate={startDate}
|
||||
endDate={endDate}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
)
|
||||
}
|
||||
overlay={
|
||||
<>
|
||||
@@ -213,9 +220,11 @@ function _DatePicker({
|
||||
})}
|
||||
<Popover.Separator />
|
||||
<div className="flex items-center justify-end gap-2 py-2 px-3 pb-4">
|
||||
<Button type="default" onClick={() => handleClear()}>
|
||||
Clear
|
||||
</Button>
|
||||
{!hideClear && (
|
||||
<Button type="default" onClick={() => handleClear()}>
|
||||
Clear
|
||||
</Button>
|
||||
)}
|
||||
<Button onClick={() => handleSubmit()}>Apply</Button>
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in new issue
Block a user