From b928331d2297da5c831ebcee8f0e34f68c9175aa Mon Sep 17 00:00:00 2001 From: iandebruin98 Date: Wed, 6 Nov 2024 13:21:01 +0100 Subject: [PATCH 1/2] feat: Create fields in the admin to set the sorting --- .../[project]/widgets/comments/[id]/index.tsx | 20 +++ .../widgets/comments/[id]/sorting.tsx | 154 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/sorting.tsx diff --git a/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/index.tsx b/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/index.tsx index e1453575a..1ccd15fc3 100644 --- a/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/index.tsx +++ b/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/index.tsx @@ -20,6 +20,7 @@ import { } from '@/lib/server-side-props-definition'; import WidgetPublish from '@/components/widget-publish'; import { BaseProps, ProjectSettingProps } from '@openstad-headless/types'; +import ArgumentsSorting from "@/pages/projects/[project]/widgets/comments/[id]/sorting"; export const getServerSideProps = withApiUrl; // Use these props in the widget tabs @@ -63,6 +64,7 @@ export default function WidgetArguments({ apiUrl }: WithApiUrlProps) { Algemeen Titel Formulier + Sorteren Publiceren @@ -120,6 +122,24 @@ export default function WidgetArguments({ apiUrl }: WithApiUrlProps) { /> ) : null} + + {previewConfig ? ( + + updateConfig({ ...widget.config, ...config }) + } + onFieldChanged={(key, value) => { + if (previewConfig) { + updatePreview({ + ...previewConfig, + [key]: value, + }); + } + }} + /> + ) : null} + diff --git a/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/sorting.tsx b/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/sorting.tsx new file mode 100644 index 000000000..a1dab5998 --- /dev/null +++ b/apps/admin-server/src/pages/projects/[project]/widgets/comments/[id]/sorting.tsx @@ -0,0 +1,154 @@ +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; +import { Separator } from '@/components/ui/separator'; +import { Heading } from '@/components/ui/typography'; +import { EditFieldProps } from '@/lib/form-widget-helpers/EditFieldProps'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; +import * as z from 'zod'; +import {ArgumentWidgetTabProps} from "@/pages/projects/[project]/widgets/comments/[id]/index"; + +// Defines the types allowed to go to the frontend +const SortingTypes = [ + { + value: "createdAt_desc", + label: "Nieuwste eerst" + }, + { + value: "createdAt_asc", + label: "Oudste eerst" + }, +]; + +const formSchema = z.object({ + defaultSorting: z.string().optional(), + sorting: z + .array(z.object({ value: z.string(), label: z.string() })) + .optional(), +}); + +export default function ArgumentsSorting( + props: ArgumentWidgetTabProps & + EditFieldProps +) { + type FormData = z.infer; + + async function onSubmit(values: FormData) { + props.updateConfig({ ...props, ...values }); + } + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + defaultSorting: props?.defaultSorting || 'createdAt_asc', + sorting: props?.sorting || [], + }, + }); + + return ( +
+
+ Sorteren + + + + ( + + Standaard manier van sorteren + + + + )} + /> + ( + +
+ Selecteer uw gewenste sorteeropties +
+
+ {SortingTypes.map((item) => ( + { + return ( + + + el.value === item.value)} + onCheckedChange={(checked: boolean) => { + const newValue = checked + ? [...(field.value || []), { value: item.value, label: item.label }] + : (field.value || []).filter((val) => val.value !== item.value); + + field.onChange(newValue); + props.onFieldChanged(field.name, newValue); + }} + /> + + + {item.label} + + + ); + }} + /> + ))} +
+
+ )} + /> + + + +
+ ); +} From ba27973bd275b8684c481f4a8fbd1671e7241ce9 Mon Sep 17 00:00:00 2001 From: iandebruin98 Date: Wed, 6 Nov 2024 13:24:32 +0100 Subject: [PATCH 2/2] feat: Sort the comments based on settings or the filter value --- packages/comments/src/comments.tsx | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/comments/src/comments.tsx b/packages/comments/src/comments.tsx index 1c3721d83..fd7e17ec9 100644 --- a/packages/comments/src/comments.tsx +++ b/packages/comments/src/comments.tsx @@ -14,6 +14,7 @@ import '@utrecht/design-tokens/dist/root.css'; import { Button, Paragraph, Heading3, Heading } from '@utrecht/component-library-react'; import { CommentFormProps } from './types/comment-form-props'; import toast, {Toaster} from "react-hot-toast"; +import {Filters} from "@openstad-headless/ui/src/stem-begroot-and-resource-overview/filter"; // This type holds all properties needed for this component to work export type CommentsWidgetProps = BaseProps & @@ -39,6 +40,8 @@ export type CommentsWidgetProps = BaseProps & customTitle?: string; onlyIncludeTags?: string; loginText?: string; + defaultSorting?: string; + sorting?: Array<{ value: string; label: string }>; setRefreshComments?: React.Dispatch; } & Partial>; @@ -109,6 +112,10 @@ function CommentsInner({ resourceId: resourceId, }); + const [sort, setSort] = useState( + props.defaultSorting || "createdAt_asc" + ); + const [canComment, setCanComment] = useState(args.canComment) const [disableSubmit, setDisableSubmit] = useState(false); @@ -226,8 +233,39 @@ function CommentsInner({ {Array.isArray(comments) && comments.length === 0 ? ( {emptyListText} - ) : null} - {(comments || []).map((comment: any, index: number) => { + ) : ((props.sorting || []).length > 0 && datastore) ? ( + <> + { + if (['createdAt_desc', 'createdAt_asc'].includes(f.sort)) { + setSort(f.sort); + } + }} + applyText={'Toepassen'} + resources={undefined} + displaySearch={false} + displayTagFilters={false} + searchPlaceholder={''} + resetText={'Reset'} + /> + + + + ) : null + } + {(comments || []) + ?.sort((a: any, b: any) => { + const dateA = new Date(a.createdAt).getTime(); + const dateB = new Date(b.createdAt).getTime(); + return sort === 'createdAt_desc' ? dateB - dateA : dateA - dateB; + }) + ?.map((comment: any, index: number) => { + let attributes = { ...args, comment, submitComment, setRefreshComments: refreshComments }; return ; })}