Skip to content

Commit

Permalink
Merge pull request #679 from openstad/feat/sort-reactions-option
Browse files Browse the repository at this point in the history
Feat/sort reactions option
  • Loading branch information
rudivanhierden authored Nov 6, 2024
2 parents 775186f + ba27973 commit 35dbc35
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -63,6 +64,7 @@ export default function WidgetArguments({ apiUrl }: WithApiUrlProps) {
<TabsTrigger value="general">Algemeen</TabsTrigger>
<TabsTrigger value="list">Titel</TabsTrigger>
<TabsTrigger value="form">Formulier</TabsTrigger>
<TabsTrigger value="sorting">Sorteren</TabsTrigger>
<TabsTrigger value="publish">Publiceren</TabsTrigger>
</TabsList>
<TabsContent value="general" className="p-0">
Expand Down Expand Up @@ -120,6 +122,24 @@ export default function WidgetArguments({ apiUrl }: WithApiUrlProps) {
/>
) : null}
</TabsContent>
<TabsContent value="sorting" className="p-0">
{previewConfig ? (
<ArgumentsSorting
{...previewConfig}
updateConfig={(config) =>
updateConfig({ ...widget.config, ...config })
}
onFieldChanged={(key, value) => {
if (previewConfig) {
updatePreview({
...previewConfig,
[key]: value,
});
}
}}
/>
) : null}
</TabsContent>
<TabsContent value="publish" className="p-0">
<WidgetPublish apiUrl={apiUrl} />
</TabsContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ArgumentWidgetTabProps>
) {
type FormData = z.infer<typeof formSchema>;

async function onSubmit(values: FormData) {
props.updateConfig({ ...props, ...values });
}

const form = useForm<FormData>({
resolver: zodResolver<any>(formSchema),
defaultValues: {
defaultSorting: props?.defaultSorting || 'createdAt_asc',
sorting: props?.sorting || [],
},
});

return (
<div className="p-6 bg-white rounded-md">
<Form {...form}>
<Heading size="xl">Sorteren</Heading>
<Separator className="my-4" />
<form
onSubmit={form.handleSubmit(onSubmit)}
className="lg:w-1/2 grid grid-cols-1 lg:grid-cols-2 gap-4">

<FormField
control={form.control}
name="defaultSorting"
render={({ field }) => (
<FormItem>
<FormLabel>Standaard manier van sorteren</FormLabel>
<Select
onValueChange={(value) => {
field.onChange(value);
props.onFieldChanged(field.name, value);
}}
value={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Nieuwste eerst" />
</SelectTrigger>
</FormControl>
<SelectContent>
{SortingTypes.map((sort) => (
<SelectItem
key={`sort-type-${sort.value}`}
value={sort.value}>
{sort.label}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="sorting"
render={() => (
<FormItem className="col-span-full">
<div>
<FormLabel>Selecteer uw gewenste sorteeropties</FormLabel>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-4 gap-y-2">
{SortingTypes.map((item) => (
<FormField
key={item.value}
control={form.control}
name="sorting"
render={({ field }) => {
return (
<FormItem
key={item.value}
className="flex flex-row items-start space-x-3 space-y-0">
<FormControl>
<Checkbox
checked={field.value?.some((el) => 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);
}}
/>
</FormControl>
<FormLabel className="font-normal">
{item.label}
</FormLabel>
</FormItem>
);
}}
/>
))}
</div>
</FormItem>
)}
/>
<Button className="w-fit col-span-full" type="submit">
Opslaan
</Button>
</form>
</Form>
</div>
);
}
42 changes: 40 additions & 2 deletions packages/comments/src/comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 &
Expand All @@ -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<any>;
} & Partial<Pick<CommentFormProps, 'formIntro' | 'placeholder'>>;

Expand Down Expand Up @@ -109,6 +112,10 @@ function CommentsInner({
resourceId: resourceId,
});

const [sort, setSort] = useState<string | undefined>(
props.defaultSorting || "createdAt_asc"
);

const [canComment, setCanComment] = useState(args.canComment)
const [disableSubmit, setDisableSubmit] = useState(false);

Expand Down Expand Up @@ -226,8 +233,39 @@ function CommentsInner({

{Array.isArray(comments) && comments.length === 0 ? (
<Paragraph>{emptyListText}</Paragraph>
) : null}
{(comments || []).map((comment: any, index: number) => {
) : ((props.sorting || []).length > 0 && datastore) ? (
<>
<Filters
className="osc-flex-columned"
dataStore={datastore}
sorting={props.sorting || []}
displaySorting={true}
defaultSorting={props.defaultSorting || 'createdAt_asc'}
onUpdateFilter={(f) => {
if (['createdAt_desc', 'createdAt_asc'].includes(f.sort)) {
setSort(f.sort);
}
}}
applyText={'Toepassen'}
resources={undefined}
displaySearch={false}
displayTagFilters={false}
searchPlaceholder={''}
resetText={'Reset'}
/>

<Spacer size={1} />
</>
) : 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 <Comment {...attributes} disableSubmit={disableSubmit} index={index} key={index} selected={selectedComment === index} />;
})}
Expand Down

0 comments on commit 35dbc35

Please sign in to comment.