Add date range picker and update backups and audit logs to use it
This commit is contained in:
parent
0a4dfef8cf
commit
b1bd8993a6
|
@ -0,0 +1,89 @@
|
|||
<script>
|
||||
import { DatePicker } from "@budibase/bbui"
|
||||
import dayjs from "dayjs"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { memo } from "@budibase/frontend-core"
|
||||
|
||||
export let value
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const valueStore = memo(value)
|
||||
|
||||
let date1
|
||||
let date2
|
||||
|
||||
$: valueStore.set(value)
|
||||
$: parseValue($valueStore)
|
||||
|
||||
const parseValue = value => {
|
||||
if (!Array.isArray(value) || !value[0] || !value[1]) {
|
||||
date1 = null
|
||||
date2 = null
|
||||
} else {
|
||||
date1 = value[0]
|
||||
date2 = value[1]
|
||||
}
|
||||
}
|
||||
|
||||
const onChangeDate1 = e => {
|
||||
date1 = e.detail ? dayjs(e.detail).startOf("day") : null
|
||||
if (date1 && (!date2 || date1.isAfter(date2))) {
|
||||
date2 = date1.endOf("day")
|
||||
} else if (!date1) {
|
||||
date2 = null
|
||||
}
|
||||
broadcastChange()
|
||||
}
|
||||
|
||||
const onChangeDate2 = e => {
|
||||
date2 = e.detail ? dayjs(e.detail).endOf("day") : null
|
||||
if (date2 && (!date1 || date2.isBefore(date1))) {
|
||||
date1 = date2.startOf("day")
|
||||
} else if (!date2) {
|
||||
date1 = null
|
||||
}
|
||||
broadcastChange()
|
||||
}
|
||||
|
||||
const broadcastChange = () => {
|
||||
dispatch("change", [date1, date2])
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="date-range-picker">
|
||||
<DatePicker
|
||||
value={date1}
|
||||
label="Date range"
|
||||
enableTime={false}
|
||||
on:change={onChangeDate1}
|
||||
/>
|
||||
<DatePicker value={date2} enableTime={false} on:change={onChangeDate2} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.date-range-picker {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
/* Overlap date pickers to remove double border, but put the focused one on top */
|
||||
.date-range-picker :global(.spectrum-InputGroup.is-focused) {
|
||||
z-index: 1;
|
||||
}
|
||||
.date-range-picker :global(> :last-child) {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
/* Remove border radius at the join */
|
||||
.date-range-picker :global(> :first-child .spectrum-InputGroup),
|
||||
.date-range-picker :global(> :first-child .spectrum-Picker) {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.date-range-picker :global(> :last-child .spectrum-InputGroup),
|
||||
.date-range-picker :global(> :last-child .spectrum-Textfield-input) {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,6 @@
|
|||
<script>
|
||||
import {
|
||||
Button,
|
||||
DatePicker,
|
||||
Divider,
|
||||
Layout,
|
||||
notifications,
|
||||
|
@ -25,14 +24,13 @@
|
|||
import BackupsDefault from "assets/backups-default.png"
|
||||
import { BackupTrigger, BackupType } from "constants/backend/backups"
|
||||
import { onMount } from "svelte"
|
||||
import dayjs from "dayjs"
|
||||
import DateRangePicker from "components/common/DateRangePicker.svelte"
|
||||
|
||||
let loading = true
|
||||
let backupData = null
|
||||
let pageInfo = createPaginationStore()
|
||||
let filterOpt = null
|
||||
let startDate = null
|
||||
let endDate = null
|
||||
let dateRange = []
|
||||
let filters = [
|
||||
{
|
||||
label: "Manual backup",
|
||||
|
@ -53,7 +51,7 @@
|
|||
]
|
||||
|
||||
$: page = $pageInfo.page
|
||||
$: fetchBackups(filterOpt, page, startDate, endDate)
|
||||
$: fetchBackups(filterOpt, page, dateRange)
|
||||
|
||||
let schema = {
|
||||
type: {
|
||||
|
@ -100,13 +98,13 @@
|
|||
})
|
||||
}
|
||||
|
||||
async function fetchBackups(filters, page, startDate, endDate) {
|
||||
async function fetchBackups(filters, page, dateRange) {
|
||||
const response = await backups.searchBackups({
|
||||
appId: $appStore.appId,
|
||||
...filters,
|
||||
page,
|
||||
startDate: startDate ? dayjs(startDate).startOf("day") : null,
|
||||
endDate: endDate ? dayjs(endDate).endOf("day") : null,
|
||||
startDate: dateRange[0],
|
||||
endDate: dateRange[1],
|
||||
})
|
||||
pageInfo.fetched(response.hasNextPage, response.nextPage)
|
||||
|
||||
|
@ -166,7 +164,7 @@
|
|||
}
|
||||
|
||||
onMount(async () => {
|
||||
await fetchBackups(filterOpt, page, startDate, endDate)
|
||||
await fetchBackups(filterOpt, page, dateRange)
|
||||
loading = false
|
||||
})
|
||||
</script>
|
||||
|
@ -208,7 +206,7 @@
|
|||
View plans
|
||||
</Button>
|
||||
</div>
|
||||
{:else if !backupData?.length && !loading && !filterOpt && !startDate}
|
||||
{:else if !backupData?.length && !loading && !filterOpt && !dateRange?.length}
|
||||
<div class="center">
|
||||
<Layout noPadding gap="S" justifyItems="center">
|
||||
<img height="130px" src={BackupsDefault} alt="BackupsDefault" />
|
||||
|
@ -237,21 +235,9 @@
|
|||
bind:value={filterOpt}
|
||||
/>
|
||||
</div>
|
||||
<DatePicker
|
||||
value={startDate}
|
||||
label="From"
|
||||
enableTime={false}
|
||||
on:change={e => {
|
||||
startDate = e.detail
|
||||
}}
|
||||
/>
|
||||
<DatePicker
|
||||
value={endDate}
|
||||
label="Until"
|
||||
enableTime={false}
|
||||
on:change={e => {
|
||||
endDate = e.detail
|
||||
}}
|
||||
<DateRangePicker
|
||||
value={dateRange}
|
||||
on:change={e => (dateRange = e.detail)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
import TimeRenderer from "./_components/TimeRenderer.svelte"
|
||||
import AppColumnRenderer from "./_components/AppColumnRenderer.svelte"
|
||||
import { cloneDeep } from "lodash"
|
||||
import DateRangePicker from "components/common/DateRangePicker.svelte"
|
||||
import dayjs from "dayjs"
|
||||
|
||||
const schema = {
|
||||
|
@ -70,15 +71,13 @@
|
|||
let sidePanelVisible = false
|
||||
let wideSidePanel = false
|
||||
let timer
|
||||
let endDate = dayjs()
|
||||
let startDate = endDate.subtract(30, "days")
|
||||
let dateRange = [dayjs().subtract(30, "days"), dayjs()]
|
||||
|
||||
$: fetchUsers(userPage, userSearchTerm)
|
||||
$: fetchLogs({
|
||||
logsPage,
|
||||
logSearchTerm,
|
||||
startDate,
|
||||
endDate,
|
||||
dateRange,
|
||||
selectedUsers,
|
||||
selectedApps,
|
||||
selectedEvents,
|
||||
|
@ -136,8 +135,7 @@
|
|||
const fetchLogs = async ({
|
||||
logsPage,
|
||||
logSearchTerm,
|
||||
startDate,
|
||||
endDate,
|
||||
dateRange,
|
||||
selectedUsers,
|
||||
selectedApps,
|
||||
selectedEvents,
|
||||
|
@ -155,8 +153,8 @@
|
|||
logsPageInfo.loading()
|
||||
await auditLogs.search({
|
||||
bookmark: logsPage,
|
||||
startDate: startDate ? dayjs(startDate).startOf("day") : null,
|
||||
endDate: endDate ? dayjs(endDate).endOf("day") : null,
|
||||
startDate: dateRange[0],
|
||||
endDate: dateRange[1],
|
||||
fullSearch: logSearchTerm,
|
||||
userIds: selectedUsers,
|
||||
appIds: selectedApps,
|
||||
|
@ -214,8 +212,8 @@
|
|||
const downloadLogs = async () => {
|
||||
try {
|
||||
window.location = auditLogs.getDownloadUrl({
|
||||
startDate,
|
||||
endDate,
|
||||
startDate: dateRange[0],
|
||||
endDate: dateRange[1],
|
||||
fullSearch: logSearchTerm,
|
||||
userIds: selectedUsers,
|
||||
appIds: selectedApps,
|
||||
|
@ -302,21 +300,9 @@
|
|||
</div>
|
||||
|
||||
<div class="date-picker">
|
||||
<DatePicker
|
||||
value={startDate}
|
||||
label="From"
|
||||
enableTime={false}
|
||||
on:change={e => {
|
||||
startDate = e.detail
|
||||
}}
|
||||
/>
|
||||
<DatePicker
|
||||
value={endDate}
|
||||
label="Until"
|
||||
enableTime={false}
|
||||
on:change={e => {
|
||||
endDate = e.detail
|
||||
}}
|
||||
<DateRangePicker
|
||||
value={dateRange}
|
||||
on:change={e => (dateRange = e.detail)}
|
||||
/>
|
||||
</div>
|
||||
<div class="freeSearch">
|
||||
|
@ -506,9 +492,9 @@
|
|||
min-width: 100px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--spacing-l);
|
||||
}
|
||||
.date-picker :global(> *) {
|
||||
.date-picker :global(.date-range-picker),
|
||||
.date-picker :global(.spectrum-Form-item) {
|
||||
flex: 1 1 auto;
|
||||
width: 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue