add feedback blank filter option
This commit is contained in:
@@ -38,11 +38,14 @@ export const feedback = {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
feedbacks: defineAction({
|
feedbacks: defineAction({
|
||||||
handler: async (_, context) => {
|
input: z.object({
|
||||||
|
includeBlanks: z.boolean()
|
||||||
|
}),
|
||||||
|
handler: async (input, context) => {
|
||||||
Session.actionSessionFromCookies(context.cookies, Permissions.Feedback);
|
Session.actionSessionFromCookies(context.cookies, Permissions.Feedback);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
feedbacks: await db.getFeedbacks({})
|
feedbacks: await db.getFeedbacks({ includeBlanks: input.includeBlanks })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import BottomBar from './BottomBar.svelte';
|
import BottomBar from './BottomBar.svelte';
|
||||||
import { feedbacks, fetchFeedbacks, type Feedback } from '@app/admin/feedback/feedback.ts';
|
import { feedbacks, type Feedback } from '@app/admin/feedback/feedback.ts';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import DataTable from '@components/admin/table/DataTable.svelte';
|
import DataTable from '@components/admin/table/DataTable.svelte';
|
||||||
|
|
||||||
// consts
|
// consts
|
||||||
@@ -15,11 +14,6 @@
|
|||||||
|
|
||||||
// states
|
// states
|
||||||
let activeFeedback = $state<Feedback | null>(null);
|
let activeFeedback = $state<Feedback | null>(null);
|
||||||
|
|
||||||
// lifecycle
|
|
||||||
onMount(() => {
|
|
||||||
fetchFeedbacks();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet date(value: string)}
|
{#snippet date(value: string)}
|
||||||
|
|||||||
19
src/app/admin/feedback/SidebarActions.svelte
Normal file
19
src/app/admin/feedback/SidebarActions.svelte
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Checkbox from '@components/input/Checkbox.svelte';
|
||||||
|
import { fetchFeedbacks } from './feedback';
|
||||||
|
|
||||||
|
// states
|
||||||
|
let showBlank = $state(false);
|
||||||
|
|
||||||
|
// lifecycle
|
||||||
|
$effect(() => {
|
||||||
|
fetchFeedbacks(showBlank);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<fieldset class="fieldset border border-base-content/50 rounded-box p-2">
|
||||||
|
<legend class="fieldset-legend">Filter</legend>
|
||||||
|
<Checkbox bind:checked={showBlank} label="Unausgefüllte zeigen" />
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
@@ -10,8 +10,8 @@ export type Feedback = Feedbacks[0];
|
|||||||
export const feedbacks = writable<Feedbacks>([]);
|
export const feedbacks = writable<Feedbacks>([]);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
export async function fetchFeedbacks(reporter?: string | null, reported?: string | null) {
|
export async function fetchFeedbacks(includeBlanks: boolean) {
|
||||||
const { data, error } = await actions.feedback.feedbacks({ reporter: reporter, reported: reported });
|
const { data, error } = await actions.feedback.feedbacks({ includeBlanks: includeBlanks });
|
||||||
if (error) {
|
if (error) {
|
||||||
actionErrorPopup(error);
|
actionErrorPopup(error);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
import { int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
|
||||||
import { user } from './user.ts';
|
import { user } from './user.ts';
|
||||||
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
import type { MySql2Database } from 'drizzle-orm/mysql2';
|
||||||
import { desc, eq, inArray } from 'drizzle-orm';
|
import { desc, eq, inArray, isNotNull } from 'drizzle-orm';
|
||||||
import { generateRandomString } from '@util/random.ts';
|
import { generateRandomString } from '@util/random.ts';
|
||||||
|
|
||||||
type Database = MySql2Database<{ feedback: typeof feedback }>;
|
type Database = MySql2Database<{ feedback: typeof feedback }>;
|
||||||
@@ -32,7 +32,9 @@ export type SubmitFeedbackReq = {
|
|||||||
content: string;
|
content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GetFeedbacksReq = {};
|
export type GetFeedbacksReq = {
|
||||||
|
includeBlanks?: boolean | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type GetFeedbackByUrlHash = {
|
export type GetFeedbackByUrlHash = {
|
||||||
urlHash: string;
|
urlHash: string;
|
||||||
@@ -76,7 +78,7 @@ export async function submitFeedback(db: Database, values: SubmitFeedbackReq) {
|
|||||||
.where(eq(feedback.urlHash, values.urlHash));
|
.where(eq(feedback.urlHash, values.urlHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getFeedbacks(db: Database, _values: GetFeedbacksReq) {
|
export async function getFeedbacks(db: Database, values: GetFeedbacksReq) {
|
||||||
return db
|
return db
|
||||||
.select({
|
.select({
|
||||||
id: feedback.id,
|
id: feedback.id,
|
||||||
@@ -89,6 +91,7 @@ export async function getFeedbacks(db: Database, _values: GetFeedbacksReq) {
|
|||||||
})
|
})
|
||||||
.from(feedback)
|
.from(feedback)
|
||||||
.leftJoin(user, eq(feedback.userId, user.id))
|
.leftJoin(user, eq(feedback.userId, user.id))
|
||||||
|
.where(!values.includeBlanks ? isNotNull(feedback.lastChanged) : undefined)
|
||||||
.orderBy(desc(feedback.id));
|
.orderBy(desc(feedback.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export async function getReports(db: Database, values: GetReportsReq) {
|
|||||||
and(
|
and(
|
||||||
values.reporter != null ? eq(reporter.username, values.reporter) : undefined,
|
values.reporter != null ? eq(reporter.username, values.reporter) : undefined,
|
||||||
values.reported != null ? eq(reported.username, values.reported) : undefined,
|
values.reported != null ? eq(reported.username, values.reported) : undefined,
|
||||||
values.includeDrafts == false ? isNotNull(report.createdAt) : undefined
|
!values.includeDrafts ? isNotNull(report.createdAt) : undefined
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.orderBy(desc(report.id));
|
.orderBy(desc(report.id));
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import AdminLayout from '@layouts/admin/AdminLayout.astro';
|
|||||||
import { Session } from '@util/session.ts';
|
import { Session } from '@util/session.ts';
|
||||||
import { Permissions } from '@util/permissions.ts';
|
import { Permissions } from '@util/permissions.ts';
|
||||||
import { BASE_PATH } from 'astro:env/server';
|
import { BASE_PATH } from 'astro:env/server';
|
||||||
|
import SidebarActions from '@app/admin/feedback/SidebarActions.svelte';
|
||||||
|
|
||||||
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Feedback);
|
const session = Session.sessionFromCookies(Astro.cookies, Permissions.Feedback);
|
||||||
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
if (!session) return Astro.redirect(`${BASE_PATH}/admin`);
|
||||||
---
|
---
|
||||||
|
|
||||||
<AdminLayout title="Feedback">
|
<AdminLayout title="Feedback">
|
||||||
|
<SidebarActions slot="actions" client:load />
|
||||||
<Feedback client:load />
|
<Feedback client:load />
|
||||||
</AdminLayout>
|
</AdminLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user