wip event list
This commit is contained in:
@@ -173,7 +173,6 @@ export function EventListItem({
|
||||
{profile && (
|
||||
<KeyValueSubtle
|
||||
name="Profile"
|
||||
// icon={<ProfileAvatar size="xs" {...(profile ?? {})} />}
|
||||
value={getProfileName(profile)}
|
||||
href={`/${params.organizationId}/${params.projectId}/profiles/${profile.id}`}
|
||||
/>
|
||||
@@ -191,28 +190,36 @@ export function EventListItem({
|
||||
}
|
||||
image={<EventIcon name={name} />}
|
||||
>
|
||||
{propertiesList.length > 0 && (
|
||||
<div className="p-4 flex flex-col gap-4">
|
||||
<div className="font-medium">Your properties</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-2">
|
||||
{propertiesList.map((item) => (
|
||||
<KeyValue key={item.name} name={item.name} value={item.value} />
|
||||
))}
|
||||
<div className="p-2">
|
||||
<div className="bg-gradient-to-tr from-slate-100 to-white rounded-md">
|
||||
{propertiesList.length > 0 && (
|
||||
<div className="p-4 flex flex-col gap-4">
|
||||
<div className="font-medium">Your properties</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-2">
|
||||
{propertiesList.map((item) => (
|
||||
<KeyValue
|
||||
key={item.name}
|
||||
name={item.name}
|
||||
value={item.value}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-4 flex flex-col gap-4">
|
||||
<div className="font-medium">Properties</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-2">
|
||||
{keyValueList.map((item) => (
|
||||
<KeyValue
|
||||
onClick={() => item.onClick?.()}
|
||||
key={item.name}
|
||||
name={item.name}
|
||||
value={item.value}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-4 flex flex-col gap-4">
|
||||
<div className="font-medium">Properties</div>
|
||||
<div className="flex flex-wrap gap-x-4 gap-y-2">
|
||||
{keyValueList.map((item) => (
|
||||
<KeyValue
|
||||
onClick={item.onClick}
|
||||
key={item.name}
|
||||
name={item.name}
|
||||
value={item.value}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</ExpandableListItem>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import { FullPageEmptyState } from '@/components/FullPageEmptyState';
|
||||
import { Pagination } from '@/components/Pagination';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useCursor } from '@/hooks/useCursor';
|
||||
import { GanttChartIcon } from 'lucide-react';
|
||||
import { last } from 'ramda';
|
||||
|
||||
import { IServiceCreateEventPayload } from '@mixan/db';
|
||||
|
||||
import { EventListItem } from './event-list-item';
|
||||
|
||||
interface EventListProps {
|
||||
data: IServiceCreateEventPayload[];
|
||||
}
|
||||
export function EventList({ data }: EventListProps) {
|
||||
const { cursor, setCursor } = useCursor();
|
||||
return (
|
||||
<>
|
||||
<div className="p-4">
|
||||
{data.length === 0 ? (
|
||||
<FullPageEmptyState title="No events here" icon={GanttChartIcon}>
|
||||
{/* {filterEvents.length ? (
|
||||
<p>Could not find any events with your filter</p>
|
||||
) : (
|
||||
<p>We have not recieved any events yet</p>
|
||||
)} */}
|
||||
<p>We have not recieved any events yet</p>
|
||||
</FullPageEmptyState>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex flex-col gap-4">
|
||||
{data.map((item) => (
|
||||
<EventListItem
|
||||
key={item.createdAt.toString() + item.name + item.profileId}
|
||||
{...item}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setCursor(last(data)?.createdAt ?? null)}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import { useMemo, useState } from 'react';
|
||||
import { api } from '@/app/_trpc/client';
|
||||
import { StickyBelowHeader } from '@/app/(app)/[organizationId]/[projectId]/layout-sticky-below-header';
|
||||
import { FullPageEmptyState } from '@/components/FullPageEmptyState';
|
||||
import { Pagination, usePagination } from '@/components/Pagination';
|
||||
import { ComboboxAdvanced } from '@/components/ui/combobox-advanced';
|
||||
import { GanttChartIcon } from 'lucide-react';
|
||||
import { parseAsArrayOf, parseAsString, useQueryState } from 'nuqs';
|
||||
|
||||
import { EventListItem } from './event-list-item';
|
||||
|
||||
interface ListEventsProps {
|
||||
projectId: string;
|
||||
}
|
||||
export function ListEvents({ projectId }: ListEventsProps) {
|
||||
const pagination = usePagination();
|
||||
const [eventFilters, setEventFilters] = useQueryState(
|
||||
'events',
|
||||
parseAsArrayOf(parseAsString).withDefault([])
|
||||
);
|
||||
const eventsQuery = api.event.list.useQuery({
|
||||
events: eventFilters,
|
||||
projectId: projectId,
|
||||
...pagination,
|
||||
});
|
||||
const events = useMemo(() => eventsQuery.data ?? [], [eventsQuery]);
|
||||
|
||||
const filterEventsQuery = api.chart.events.useQuery({
|
||||
projectId: projectId,
|
||||
});
|
||||
|
||||
const filterEvents = (filterEventsQuery.data ?? []).map((item) => ({
|
||||
value: item.name,
|
||||
label: item.name,
|
||||
}));
|
||||
|
||||
return (
|
||||
<>
|
||||
<StickyBelowHeader className="p-4 flex justify-between">
|
||||
<div>
|
||||
<ComboboxAdvanced
|
||||
items={filterEvents}
|
||||
value={eventFilters}
|
||||
onChange={setEventFilters}
|
||||
placeholder="Filter by event"
|
||||
/>
|
||||
</div>
|
||||
</StickyBelowHeader>
|
||||
<div className="p-4">
|
||||
{events.length === 0 ? (
|
||||
<FullPageEmptyState title="No events here" icon={GanttChartIcon}>
|
||||
{eventFilters.length ? (
|
||||
<p>Could not find any events with your filter</p>
|
||||
) : (
|
||||
<p>We have not recieved any events yet</p>
|
||||
)}
|
||||
</FullPageEmptyState>
|
||||
) : (
|
||||
<>
|
||||
<div className="flex flex-col gap-4">
|
||||
{events.map((item) => (
|
||||
<EventListItem key={item.createdAt.toString()} {...item} />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<Pagination {...pagination} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,22 +1,39 @@
|
||||
import { Suspense } from 'react';
|
||||
import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout';
|
||||
import { OverviewFiltersDrawer } from '@/components/overview/filters/overview-filters-drawer';
|
||||
import { getExists } from '@/server/pageExists';
|
||||
|
||||
import { ListEvents } from './list-events';
|
||||
import { getEventList, getEvents } from '@mixan/db';
|
||||
|
||||
import { StickyBelowHeader } from '../layout-sticky-below-header';
|
||||
import { EventList } from './event-list';
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
projectId: string;
|
||||
organizationId: string;
|
||||
};
|
||||
searchParams: {
|
||||
cursor?: string;
|
||||
};
|
||||
}
|
||||
export default async function Page({
|
||||
params: { projectId, organizationId },
|
||||
searchParams: { cursor },
|
||||
}: PageProps) {
|
||||
await getExists(organizationId, projectId);
|
||||
const events = await getEventList({
|
||||
cursor,
|
||||
projectId,
|
||||
take: 50,
|
||||
});
|
||||
|
||||
return (
|
||||
<PageLayout title="Events" organizationSlug={organizationId}>
|
||||
<ListEvents projectId={projectId} />
|
||||
<StickyBelowHeader className="p-4 flex justify-between">
|
||||
<OverviewFiltersDrawer projectId={projectId} />
|
||||
</StickyBelowHeader>
|
||||
<EventList data={events} />
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user