Audit changes
This commit is contained in:
parent
fb382e55e9
commit
3e47e2e900
@ -3,12 +3,17 @@
|
|||||||
|
|
||||||
export let type: 'button' | 'submit' = 'button';
|
export let type: 'button' | 'submit' = 'button';
|
||||||
export let variant: 'default' | 'primary' | 'link' = 'default';
|
export let variant: 'default' | 'primary' | 'link' = 'default';
|
||||||
|
export let formaction: string | undefined = undefined;
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
const dispath = createEventDispatcher();
|
const dispath = createEventDispatcher();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button {type} class="btn btn-{variant}" on:click={(e) => dispath('click', e)} {disabled}
|
<button
|
||||||
><slot /></button
|
{type}
|
||||||
|
{formaction}
|
||||||
|
class="btn btn-{variant}"
|
||||||
|
on:click={(e) => dispath('click', e)}
|
||||||
|
{disabled}><slot /></button
|
||||||
>
|
>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -45,6 +45,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(select[multiple]) {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.form-control > :global(label) {
|
.form-control > :global(label) {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"current": "Current",
|
"current": "Current",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"filter": "Filter",
|
"filter": "Filter",
|
||||||
|
"clear": "Clear",
|
||||||
"theme": {
|
"theme": {
|
||||||
"light": "Light mode",
|
"light": "Light mode",
|
||||||
"dark": "Dark mode"
|
"dark": "Dark mode"
|
||||||
|
@ -98,7 +98,7 @@ export class Audit {
|
|||||||
|
|
||||||
private static getAuditWhere(search: AuditSearchClause) {
|
private static getAuditWhere(search: AuditSearchClause) {
|
||||||
const selectList: SQL<unknown>[] = [];
|
const selectList: SQL<unknown>[] = [];
|
||||||
if (search.actions) {
|
if (search.actions?.length) {
|
||||||
const actions = Array.isArray(search.actions)
|
const actions = Array.isArray(search.actions)
|
||||||
? search.actions
|
? search.actions
|
||||||
: (search.actions as string).split(',');
|
: (search.actions as string).split(',');
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export class Changesets {
|
export class Changesets {
|
||||||
static take<TRes>(
|
static take<TRes>(
|
||||||
fields: (keyof TRes)[],
|
fields: (keyof TRes)[],
|
||||||
body: FormData,
|
body: FormData | URLSearchParams,
|
||||||
challenge?: Partial<TRes>
|
challenge?: Partial<TRes>
|
||||||
): Partial<TRes> {
|
): Partial<TRes> {
|
||||||
return fields.reduce<Partial<TRes>>((accum, field) => {
|
return fields.reduce<Partial<TRes>>((accum, field) => {
|
||||||
|
@ -1,51 +1,43 @@
|
|||||||
import { AdminUtils } from '$lib/server/admin-utils';
|
import { AdminUtils } from '$lib/server/admin-utils';
|
||||||
import { Audit } from '$lib/server/audit/audit.js';
|
import { Audit } from '$lib/server/audit/audit.js';
|
||||||
import { AuditAction } from '$lib/server/audit/types.js';
|
import { AuditAction } from '$lib/server/audit/types.js';
|
||||||
|
import { Changesets } from '$lib/server/changesets.js';
|
||||||
|
|
||||||
const PAGE_SIZE = 50;
|
const PAGE_SIZE = 50;
|
||||||
|
|
||||||
|
interface AuditSearchParams {
|
||||||
|
page: string;
|
||||||
|
pageSize: string;
|
||||||
|
actions: string;
|
||||||
|
user: string;
|
||||||
|
content: string;
|
||||||
|
ip: string;
|
||||||
|
flagged: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const load = async ({ url, parent }) => {
|
export const load = async ({ url, parent }) => {
|
||||||
const { user: userInfo } = await parent();
|
const { user: userInfo } = await parent();
|
||||||
AdminUtils.checkPrivileges(userInfo, ['admin:audit']);
|
AdminUtils.checkPrivileges(userInfo, ['admin:audit']);
|
||||||
|
|
||||||
let limit = PAGE_SIZE;
|
const actions = url.searchParams.getAll('actions') as AuditAction[];
|
||||||
let page = 1;
|
const { page, pageSize, user, content, ip, flagged } = Changesets.take<AuditSearchParams>(
|
||||||
let actions: AuditAction[] | undefined = undefined;
|
['page', 'pageSize', 'user', 'content', 'ip', 'flagged'],
|
||||||
let user: string | undefined = undefined;
|
url.searchParams
|
||||||
let content: string | undefined = undefined;
|
);
|
||||||
let ip: string | undefined = undefined;
|
|
||||||
let flagged: boolean | undefined = undefined;
|
|
||||||
if (url.searchParams.has('page')) {
|
|
||||||
page = Number(url.searchParams.get('page')) || 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.searchParams.has('pageSize')) {
|
const limit = Number(pageSize) || PAGE_SIZE;
|
||||||
limit = Number(url.searchParams.get('pageSize')) || PAGE_SIZE;
|
const offset = ((Number(page) || 1) - 1) * limit;
|
||||||
}
|
|
||||||
|
|
||||||
if (url.searchParams.has('actions')) {
|
const data = await Audit.searchAudit({
|
||||||
actions = url.searchParams.getAll('actions') as AuditAction[];
|
limit,
|
||||||
}
|
offset,
|
||||||
|
actions,
|
||||||
|
user,
|
||||||
|
content,
|
||||||
|
ip,
|
||||||
|
flagged: !!flagged
|
||||||
|
});
|
||||||
|
|
||||||
if (url.searchParams.has('user')) {
|
|
||||||
user = url.searchParams.get('user') as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.searchParams.has('content')) {
|
|
||||||
content = url.searchParams.get('content') as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.searchParams.has('ip')) {
|
|
||||||
ip = url.searchParams.get('ip') as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.searchParams.has('flagged')) {
|
|
||||||
flagged = !!url.searchParams.get('flagged');
|
|
||||||
}
|
|
||||||
|
|
||||||
const offset = (page - 1) * limit;
|
|
||||||
|
|
||||||
const data = await Audit.searchAudit({ limit, offset, actions, user, content, ip, flagged });
|
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
actions: Object.values(AuditAction)
|
actions: Object.values(AuditAction)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Paginator from '$lib/components/Paginator.svelte';
|
|
||||||
import { t } from '$lib/i18n';
|
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
import { t } from '$lib/i18n';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import Paginator from '$lib/components/Paginator.svelte';
|
||||||
import FormControl from '$lib/components/form/FormControl.svelte';
|
import FormControl from '$lib/components/form/FormControl.svelte';
|
||||||
import ColumnView from '$lib/components/container/ColumnView.svelte';
|
import ColumnView from '$lib/components/container/ColumnView.svelte';
|
||||||
import { page } from '$app/stores';
|
|
||||||
import SplitView from '$lib/components/container/SplitView.svelte';
|
import SplitView from '$lib/components/container/SplitView.svelte';
|
||||||
import Button from '$lib/components/Button.svelte';
|
import Button from '$lib/components/Button.svelte';
|
||||||
import AdminAuditCard from '../../../lib/components/admin/AdminAuditCard.svelte';
|
import AdminAuditCard from '$lib/components/admin/AdminAuditCard.svelte';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
</script>
|
</script>
|
||||||
@ -36,26 +36,36 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl>
|
|
||||||
<label for="content">{$t('admin.audit.comment')}</label>
|
<ColumnView>
|
||||||
<input name="content" id="content" value={$page.url.searchParams.get('content')} />
|
<FormControl>
|
||||||
</FormControl>
|
<label for="content">{$t('admin.audit.comment')}</label>
|
||||||
|
<input name="content" id="content" value={$page.url.searchParams.get('content')} />
|
||||||
|
</FormControl>
|
||||||
|
<FormControl>
|
||||||
|
<label for="ip">{$t('admin.audit.ip')}</label>
|
||||||
|
<input name="ip" id="ip" value={$page.url.searchParams.get('ip')} />
|
||||||
|
</FormControl>
|
||||||
|
</ColumnView>
|
||||||
</SplitView>
|
</SplitView>
|
||||||
|
|
||||||
<SplitView>
|
<SplitView>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<label for="flagged">{$t('admin.audit.flagged')}</label>
|
<label for="user">{$t('admin.audit.user')}</label>
|
||||||
<input
|
<input name="user" id="user" value={$page.url.searchParams.get('user')} />
|
||||||
name="flagged"
|
|
||||||
id="flagged"
|
|
||||||
type="checkbox"
|
|
||||||
checked={!!$page.url.searchParams.get('flagged')}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl>
|
|
||||||
<label for="ip">{$t('admin.audit.ip')}</label>
|
|
||||||
<input name="ip" id="ip" value={$page.url.searchParams.get('ip')} />
|
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</SplitView>
|
</SplitView>
|
||||||
|
|
||||||
|
<FormControl>
|
||||||
|
<label for="flagged">{$t('admin.audit.flagged')}</label>
|
||||||
|
<input
|
||||||
|
name="flagged"
|
||||||
|
id="flagged"
|
||||||
|
type="checkbox"
|
||||||
|
checked={!!$page.url.searchParams.get('flagged')}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Button type="submit">{$t('common.filter')}</Button>
|
<Button type="submit">{$t('common.filter')}</Button>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user