Compare commits

..

No commits in common. "f70f98fed061a1fa7540d1c23b514c6aeb439d24" and "1def80ba422e9bd0d24a10115448bb73c70bc9c4" have entirely different histories.

16 changed files with 234 additions and 169 deletions

View file

@ -1,24 +1,21 @@
import { useState } from 'react';
import { DateFilter } from '@/components/input/DateFilter'; import { DateFilter } from '@/components/input/DateFilter';
import { Button, Row } from '@umami/react-zen'; import { Button, Row } from '@umami/react-zen';
import { useMessages } from '@/components/hooks'; import { useDateRange, useMessages } from '@/components/hooks';
import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE_VALUE } from '@/lib/constants'; import { DEFAULT_DATE_RANGE_VALUE } from '@/lib/constants';
import { setItem, getItem } from '@/lib/storage';
export function DateRangeSetting() { export function DateRangeSetting() {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const [date, setDate] = useState(getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE_VALUE); const { dateRange, saveDateRange } = useDateRange();
const { value } = dateRange;
const handleChange = (value: string) => { const handleChange = (value: string) => {
setItem(DATE_RANGE_CONFIG, value); saveDateRange(value);
setDate(value);
}; };
const handleReset = () => saveDateRange(DEFAULT_DATE_RANGE_VALUE);
const handleReset = () => setItem(DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE_VALUE);
return ( return (
<Row gap="3"> <Row gap="3">
<DateFilter value={date} onChange={handleChange} placement="bottom start" /> <DateFilter value={value} onChange={handleChange} placement="bottom start" />
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button> <Button onPress={handleReset}>{formatMessage(labels.reset)}</Button>
</Row> </Row>
); );

View file

@ -15,7 +15,7 @@ export function WebsiteChart({
const { startDate, endDate, unit, value } = dateRange; const { startDate, endDate, unit, value } = dateRange;
const { data, isLoading, isFetching, error } = useWebsitePageviewsQuery({ const { data, isLoading, isFetching, error } = useWebsitePageviewsQuery({
websiteId, websiteId,
compare: compareMode ? dateCompare?.['value'] : undefined, compare: compareMode ? dateCompare : undefined,
}); });
const { pageviews, sessions, compare } = (data || {}) as any; const { pageviews, sessions, compare } = (data || {}) as any;

View file

@ -9,7 +9,6 @@ export * from './context/useWebsite';
// Query hooks // Query hooks
export * from './queries/useActiveUsersQuery'; export * from './queries/useActiveUsersQuery';
export * from './queries/useDateRangeQuery';
export * from './queries/useDeleteQuery'; export * from './queries/useDeleteQuery';
export * from './queries/useEventDataEventsQuery'; export * from './queries/useEventDataEventsQuery';
export * from './queries/useEventDataPropertiesQuery'; export * from './queries/useEventDataPropertiesQuery';
@ -77,7 +76,6 @@ export * from './useModified';
export * from './useNavigation'; export * from './useNavigation';
export * from './usePagedQuery'; export * from './usePagedQuery';
export * from './usePageParameters'; export * from './usePageParameters';
export * from './useQueryStringDate';
export * from './useRegionNames'; export * from './useRegionNames';
export * from './useSlug'; export * from './useSlug';
export * from './useSticky'; export * from './useSticky';

View file

@ -1,12 +0,0 @@
import { useApi } from '../useApi';
import { ReactQueryOptions } from '@/lib/types';
export function useDateRangeQuery(websiteId: string, options?: ReactQueryOptions) {
const { get, useQuery } = useApi();
return useQuery<any>({
queryKey: ['date-range', websiteId],
queryFn: () => get(`/websites/${websiteId}/daterange`),
enabled: !!websiteId,
...options,
});
}

View file

@ -1,35 +1,65 @@
import { getMinimumUnit, parseDateRange } from '@/lib/date'; import { useMemo } from 'react';
import { useLocale } from '@/components/hooks/useLocale'; import { getMinimumUnit, parseDateRange, getOffsetDateRange } from '@/lib/date';
import { useApi } from '@/components/hooks//useApi'; import { setItem } from '@/lib/storage';
import { useQueryStringDate } from '@/components/hooks/useQueryStringDate'; import { DATE_RANGE_CONFIG, DEFAULT_DATE_COMPARE, DEFAULT_DATE_RANGE_VALUE } from '@/lib/constants';
import { useGlobalState } from '@/components/hooks/useGlobalState'; import { setWebsiteDateCompare, setWebsiteDateRange, useWebsites } from '@/store/websites';
import { setDateRangeValue, useApp } from '@/store/app';
import { useLocale } from './useLocale';
import { useApi } from './useApi';
import { useNavigation } from './useNavigation';
export function useDateRange(websiteId: string) { export interface UseDateRangeOptions {
ignoreOffset?: boolean;
}
export function useDateRange(websiteId?: string, options: UseDateRangeOptions = {}) {
const { get } = useApi(); const { get } = useApi();
const { locale } = useLocale(); const { locale } = useLocale();
const { dateRange: defaultDateRange, dateCompare } = useQueryStringDate(); const {
query: { date, offset = 0 },
} = useNavigation();
const websiteConfig = useWebsites(state => state[websiteId]?.dateRange);
const globalConfig = useApp(state => state.dateRangeValue);
const dateValue = websiteConfig?.value || date || globalConfig || DEFAULT_DATE_RANGE_VALUE;
const [dateRange, setDateRange] = useGlobalState(`date-range:${websiteId}`, defaultDateRange); const dateRange = useMemo(() => {
const dateRangeObject = parseDateRange(dateValue, locale);
const setDateRangeValue = async (value: string) => { return !options.ignoreOffset && offset
if (value === 'all') { ? getOffsetDateRange(dateRangeObject, +offset)
const result = await get(`/websites/${websiteId}/daterange`); : dateRangeObject;
const { mindate, maxdate } = result; }, [date, offset, dateValue, options]);
const startDate = new Date(mindate); const dateCompare = useWebsites(state => state[websiteId]?.dateCompare || DEFAULT_DATE_COMPARE);
const endDate = new Date(maxdate);
const unit = getMinimumUnit(startDate, endDate);
setDateRange({ const saveDateRange = async (value: string) => {
startDate, if (websiteId) {
endDate, if (value === 'all') {
unit, const result: any = await get(`/websites/${websiteId}/daterange`);
value, const { mindate, maxdate } = result;
});
const startDate = new Date(mindate);
const endDate = new Date(maxdate);
const unit = getMinimumUnit(startDate, endDate);
setWebsiteDateRange(websiteId, {
startDate,
endDate,
unit,
value,
});
} else {
setWebsiteDateRange(websiteId, parseDateRange(value, locale));
}
} else { } else {
setDateRange(parseDateRange(value, locale)); setItem(DATE_RANGE_CONFIG, value);
setDateRangeValue(value);
} }
}; };
return { dateRange, dateCompare, setDateRange, setDateRangeValue }; const saveDateCompare = (value: string) => {
setWebsiteDateCompare(websiteId, value);
};
return { dateRange, saveDateRange, dateCompare, saveDateCompare };
} }

View file

@ -1,24 +0,0 @@
import { useNavigation } from '@/components/hooks/useNavigation';
import { useMemo } from 'react';
import { getCompareDate, getOffsetDateRange, parseDateRange } from '@/lib/date';
import { useLocale } from '@/components/hooks/useLocale';
import { DEFAULT_DATE_RANGE_VALUE } from '@/lib/constants';
export function useQueryStringDate(options: { ignoreOffset?: boolean } = {}) {
const {
query: { date = DEFAULT_DATE_RANGE_VALUE, offset = 0, compare = 'prev' },
} = useNavigation();
const { locale } = useLocale();
const dateRange = useMemo(() => {
const dateRangeObject = parseDateRange(date, locale);
return !options.ignoreOffset && offset
? getOffsetDateRange(dateRangeObject, +offset)
: dateRangeObject;
}, [date, offset, options]);
const dateCompare = getCompareDate(compare, dateRange.startDate, dateRange.endDate);
return { date, offset, dateRange, dateCompare };
}

View file

@ -3,8 +3,6 @@ import { isAfter } from 'date-fns';
import { ChevronRight } from '@/components/icons'; import { ChevronRight } from '@/components/icons';
import { useDateRange, useMessages, useNavigation } from '@/components/hooks'; import { useDateRange, useMessages, useNavigation } from '@/components/hooks';
import { DateFilter } from './DateFilter'; import { DateFilter } from './DateFilter';
import { getOffsetDateRange } from '@/lib/date';
import { useCallback } from 'react';
export interface WebsiteDateFilterProps { export interface WebsiteDateFilterProps {
websiteId: string; websiteId: string;
@ -20,7 +18,7 @@ export function WebsiteDateFilter({
showButtons = true, showButtons = true,
allowCompare, allowCompare,
}: WebsiteDateFilterProps) { }: WebsiteDateFilterProps) {
const { dateRange, setDateRange, setDateRangeValue } = useDateRange(websiteId); const { dateRange, saveDateRange } = useDateRange(websiteId);
const { value, endDate } = dateRange; const { value, endDate } = dateRange;
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { const {
@ -29,25 +27,18 @@ export function WebsiteDateFilter({
query: { compare = 'prev', offset = 0 }, query: { compare = 'prev', offset = 0 },
} = useNavigation(); } = useNavigation();
const isAllTime = value === 'all'; const isAllTime = value === 'all';
const isCustomRange = value.startsWith('range'); const isCustomRange = value.startsWith('range');
const disableForward = value === 'all' || isAfter(endDate, new Date()); const disableForward = value === 'all' || isAfter(endDate, new Date());
const handleChange = (date: string) => { const handleChange = (date: string) => {
setDateRangeValue(date); saveDateRange(date);
router.push(updateParams({ date, offset: undefined })); router.push(updateParams({ date, offset: undefined }));
}; };
const handleIncrement = useCallback( const handleIncrement = (increment: number) => {
(increment: number) => { router.push(updateParams({ offset: +offset + increment }));
const offsetDate = getOffsetDateRange(dateRange, +offset + increment); };
setDateRange(offsetDate);
router.push(updateParams({ offset: +offset + increment }));
},
[offset],
);
const handleSelect = (compare: any) => { const handleSelect = (compare: any) => {
router.push(updateParams({ compare })); router.push(updateParams({ compare }));

View file

@ -187,7 +187,9 @@ async function rawQuery(sql: string, data: Record<string, any>, name?: string):
return `$${params.length}${type ?? ''}`; return `$${params.length}${type ?? ''}`;
}); });
return client.$queryRawUnsafe(query, ...params); return process.env.DATABASE_REPLICA_URL
? await client.$replica().$queryRawUnsafe(query, ...params)
: await client.$queryRawUnsafe(query, ...params);
} }
async function pagedQuery<T>(model: string, criteria: T, filters?: QueryFilters) { async function pagedQuery<T>(model: string, criteria: T, filters?: QueryFilters) {
@ -281,7 +283,6 @@ function getClient() {
url: process.env.DATABASE_URL, url: process.env.DATABASE_URL,
prismaClient: PrismaClient, prismaClient: PrismaClient,
logQuery: !!process.env.LOG_QUERY, logQuery: !!process.env.LOG_QUERY,
replicaUrl: process.env.DATABASE_REPLICA_URL,
}); });
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
@ -291,7 +292,7 @@ function getClient() {
return prisma.client; return prisma.client;
} }
const client: PrismaClient = globalThis[PRISMA] || getClient(); const client = globalThis[PRISMA] || getClient();
export default { export default {
client, client,

View file

@ -1,12 +1,12 @@
import { Prisma } from '@/generated/prisma/client'; import { Prisma, Link } from '@/generated/prisma/client';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
export async function findLink(criteria: Prisma.LinkFindUniqueArgs) { export async function findLink(criteria: Prisma.LinkFindUniqueArgs): Promise<Link> {
return prisma.client.link.findUnique(criteria); return prisma.client.link.findUnique(criteria);
} }
export async function getLink(linkId: string) { export async function getLink(linkId: string): Promise<Link> {
return findLink({ return findLink({
where: { where: {
id: linkId, id: linkId,
@ -14,7 +14,10 @@ export async function getLink(linkId: string) {
}); });
} }
export async function getLinks(criteria: Prisma.LinkFindManyArgs, filters: QueryFilters = {}) { export async function getLinks(
criteria: Prisma.LinkFindManyArgs,
filters: QueryFilters = {},
): Promise<PageResult<Link[]>> {
const { search } = filters; const { search } = filters;
const { getSearchParameters, pagedQuery } = prisma; const { getSearchParameters, pagedQuery } = prisma;
@ -30,7 +33,10 @@ export async function getLinks(criteria: Prisma.LinkFindManyArgs, filters: Query
return pagedQuery('link', { ...criteria, where }, filters); return pagedQuery('link', { ...criteria, where }, filters);
} }
export async function getUserLinks(userId: string, filters?: QueryFilters) { export async function getUserLinks(
userId: string,
filters?: QueryFilters,
): Promise<PageResult<Link[]>> {
return getLinks( return getLinks(
{ {
where: { where: {
@ -42,7 +48,10 @@ export async function getUserLinks(userId: string, filters?: QueryFilters) {
); );
} }
export async function getTeamLinks(teamId: string, filters?: QueryFilters) { export async function getTeamLinks(
teamId: string,
filters?: QueryFilters,
): Promise<PageResult<Link[]>> {
return getLinks( return getLinks(
{ {
where: { where: {
@ -53,14 +62,14 @@ export async function getTeamLinks(teamId: string, filters?: QueryFilters) {
); );
} }
export async function createLink(data: Prisma.LinkUncheckedCreateInput) { export async function createLink(data: Prisma.LinkUncheckedCreateInput): Promise<Link> {
return prisma.client.link.create({ data }); return prisma.client.link.create({ data });
} }
export async function updateLink(linkId: string, data: any) { export async function updateLink(linkId: string, data: any): Promise<Link> {
return prisma.client.link.update({ where: { id: linkId }, data }); return prisma.client.link.update({ where: { id: linkId }, data });
} }
export async function deleteLink(linkId: string) { export async function deleteLink(linkId: string): Promise<Link> {
return prisma.client.link.delete({ where: { id: linkId } }); return prisma.client.link.delete({ where: { id: linkId } });
} }

View file

@ -1,12 +1,12 @@
import { Prisma } from '@/generated/prisma/client'; import { Prisma, Pixel } from '@/generated/prisma/client';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
export async function findPixel(criteria: Prisma.PixelFindUniqueArgs) { export async function findPixel(criteria: Prisma.PixelFindUniqueArgs): Promise<Pixel> {
return prisma.client.pixel.findUnique(criteria); return prisma.client.pixel.findUnique(criteria);
} }
export async function getPixel(pixelId: string) { export async function getPixel(pixelId: string): Promise<Pixel> {
return findPixel({ return findPixel({
where: { where: {
id: pixelId, id: pixelId,
@ -14,7 +14,10 @@ export async function getPixel(pixelId: string) {
}); });
} }
export async function getPixels(criteria: Prisma.PixelFindManyArgs, filters: QueryFilters = {}) { export async function getPixels(
criteria: Prisma.PixelFindManyArgs,
filters: QueryFilters = {},
): Promise<PageResult<Pixel[]>> {
const { search } = filters; const { search } = filters;
const where: Prisma.PixelWhereInput = { const where: Prisma.PixelWhereInput = {
@ -25,7 +28,10 @@ export async function getPixels(criteria: Prisma.PixelFindManyArgs, filters: Que
return prisma.pagedQuery('pixel', { ...criteria, where }, filters); return prisma.pagedQuery('pixel', { ...criteria, where }, filters);
} }
export async function getUserPixels(userId: string, filters?: QueryFilters) { export async function getUserPixels(
userId: string,
filters?: QueryFilters,
): Promise<PageResult<Pixel[]>> {
return getPixels( return getPixels(
{ {
where: { where: {
@ -36,7 +42,10 @@ export async function getUserPixels(userId: string, filters?: QueryFilters) {
); );
} }
export async function getTeamPixels(teamId: string, filters?: QueryFilters) { export async function getTeamPixels(
teamId: string,
filters?: QueryFilters,
): Promise<PageResult<Pixel[]>> {
return getPixels( return getPixels(
{ {
where: { where: {
@ -47,14 +56,14 @@ export async function getTeamPixels(teamId: string, filters?: QueryFilters) {
); );
} }
export async function createPixel(data: Prisma.PixelUncheckedCreateInput) { export async function createPixel(data: Prisma.PixelUncheckedCreateInput): Promise<Pixel> {
return prisma.client.pixel.create({ data }); return prisma.client.pixel.create({ data });
} }
export async function updatePixel(pixelId: string, data: any) { export async function updatePixel(pixelId: string, data: any): Promise<Pixel> {
return prisma.client.pixel.update({ where: { id: pixelId }, data }); return prisma.client.pixel.update({ where: { id: pixelId }, data });
} }
export async function deletePixel(pixelId: string) { export async function deletePixel(pixelId: string): Promise<Pixel> {
return prisma.client.pixel.delete({ where: { id: pixelId } }); return prisma.client.pixel.delete({ where: { id: pixelId } });
} }

View file

@ -1,13 +1,13 @@
import { Prisma } from '@/generated/prisma/client'; import { Prisma, Report } from '@/generated/prisma/client';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
import ReportFindManyArgs = Prisma.ReportFindManyArgs; import ReportFindManyArgs = Prisma.ReportFindManyArgs;
async function findReport(criteria: Prisma.ReportFindUniqueArgs) { async function findReport(criteria: Prisma.ReportFindUniqueArgs): Promise<Report> {
return prisma.client.report.findUnique(criteria); return prisma.client.report.findUnique(criteria);
} }
export async function getReport(reportId: string) { export async function getReport(reportId: string): Promise<Report> {
return findReport({ return findReport({
where: { where: {
id: reportId, id: reportId,
@ -15,7 +15,10 @@ export async function getReport(reportId: string) {
}); });
} }
export async function getReports(criteria: ReportFindManyArgs, filters: QueryFilters = {}) { export async function getReports(
criteria: ReportFindManyArgs,
filters: QueryFilters = {},
): Promise<PageResult<Report[]>> {
const { search } = filters; const { search } = filters;
const where: Prisma.ReportWhereInput = { const where: Prisma.ReportWhereInput = {
@ -45,7 +48,10 @@ export async function getReports(criteria: ReportFindManyArgs, filters: QueryFil
return prisma.pagedQuery('report', { ...criteria, where }, filters); return prisma.pagedQuery('report', { ...criteria, where }, filters);
} }
export async function getUserReports(userId: string, filters?: QueryFilters) { export async function getUserReports(
userId: string,
filters?: QueryFilters,
): Promise<PageResult<Report[]>> {
return getReports( return getReports(
{ {
where: { where: {
@ -64,7 +70,10 @@ export async function getUserReports(userId: string, filters?: QueryFilters) {
); );
} }
export async function getWebsiteReports(websiteId: string, filters: QueryFilters = {}) { export async function getWebsiteReports(
websiteId: string,
filters: QueryFilters = {},
): Promise<PageResult<Report[]>> {
return getReports( return getReports(
{ {
where: { where: {
@ -75,14 +84,14 @@ export async function getWebsiteReports(websiteId: string, filters: QueryFilters
); );
} }
export async function createReport(data: Prisma.ReportUncheckedCreateInput) { export async function createReport(data: Prisma.ReportUncheckedCreateInput): Promise<Report> {
return prisma.client.report.create({ data }); return prisma.client.report.create({ data });
} }
export async function updateReport(reportId: string, data: any) { export async function updateReport(reportId: string, data: any): Promise<Report> {
return prisma.client.report.update({ where: { id: reportId }, data }); return prisma.client.report.update({ where: { id: reportId }, data });
} }
export async function deleteReport(reportId: string) { export async function deleteReport(reportId: string): Promise<Report> {
return prisma.client.report.delete({ where: { id: reportId } }); return prisma.client.report.delete({ where: { id: reportId } });
} }

View file

@ -1,12 +1,12 @@
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { Prisma } from '@/generated/prisma/client'; import { Prisma, Segment } from '@/generated/prisma/client';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
async function findSegment(criteria: Prisma.SegmentFindUniqueArgs) { async function findSegment(criteria: Prisma.SegmentFindUniqueArgs): Promise<Segment> {
return prisma.client.segment.findUnique(criteria); return prisma.client.Segment.findUnique(criteria);
} }
export async function getSegment(segmentId: string) { export async function getSegment(segmentId: string): Promise<Segment> {
return findSegment({ return findSegment({
where: { where: {
id: segmentId, id: segmentId,
@ -14,7 +14,10 @@ export async function getSegment(segmentId: string) {
}); });
} }
export async function getSegments(criteria: Prisma.SegmentFindManyArgs, filters: QueryFilters) { export async function getSegments(
criteria: Prisma.SegmentFindManyArgs,
filters: QueryFilters,
): Promise<PageResult<Segment[]>> {
const { search } = filters; const { search } = filters;
const { getSearchParameters, pagedQuery } = prisma; const { getSearchParameters, pagedQuery } = prisma;
@ -30,13 +33,17 @@ export async function getSegments(criteria: Prisma.SegmentFindManyArgs, filters:
return pagedQuery('segment', { ...criteria, where }, filters); return pagedQuery('segment', { ...criteria, where }, filters);
} }
export async function getWebsiteSegment(websiteId: string, segmentId: string) { export async function getWebsiteSegment(websiteId: string, segmentId: string): Promise<Segment> {
return prisma.client.segment.findFirst({ return prisma.client.Segment.findFirst({
where: { id: segmentId, websiteId }, where: { id: segmentId, websiteId },
}); });
} }
export async function getWebsiteSegments(websiteId: string, type: string, filters?: QueryFilters) { export async function getWebsiteSegments(
websiteId: string,
type: string,
filters?: QueryFilters,
): Promise<PageResult<Segment[]>> {
return getSegments( return getSegments(
{ {
where: { where: {
@ -48,14 +55,17 @@ export async function getWebsiteSegments(websiteId: string, type: string, filter
); );
} }
export async function createSegment(data: Prisma.SegmentUncheckedCreateInput) { export async function createSegment(data: Prisma.SegmentUncheckedCreateInput): Promise<Segment> {
return prisma.client.segment.create({ data }); return prisma.client.Segment.create({ data });
} }
export async function updateSegment(SegmentId: string, data: Prisma.SegmentUpdateInput) { export async function updateSegment(
return prisma.client.segment.update({ where: { id: SegmentId }, data }); SegmentId: string,
data: Prisma.SegmentUpdateInput,
): Promise<Segment> {
return prisma.client.Segment.update({ where: { id: SegmentId }, data });
} }
export async function deleteSegment(SegmentId: string) { export async function deleteSegment(SegmentId: string): Promise<Segment> {
return prisma.client.segment.delete({ where: { id: SegmentId } }); return prisma.client.Segment.delete({ where: { id: SegmentId } });
} }

View file

@ -9,10 +9,7 @@ export async function findTeam(criteria: Prisma.TeamFindUniqueArgs): Promise<Tea
return prisma.client.team.findUnique(criteria); return prisma.client.team.findUnique(criteria);
} }
export async function getTeam( export async function getTeam(teamId: string, options: { includeMembers?: boolean } = {}) {
teamId: string,
options: { includeMembers?: boolean } = {},
): Promise<Team> {
const { includeMembers } = options; const { includeMembers } = options;
return findTeam({ return findTeam({
@ -132,9 +129,11 @@ export async function updateTeam(teamId: string, data: Prisma.TeamUpdateInput):
}); });
} }
export async function deleteTeam(teamId: string) { export async function deleteTeam(
teamId: string,
): Promise<Promise<[Prisma.BatchPayload, Prisma.BatchPayload, Team]>> {
const { client, transaction } = prisma; const { client, transaction } = prisma;
const cloudMode = !!process.env.CLOUD_MODE; const cloudMode = !!process.env.CLOUD_URL;
if (cloudMode) { if (cloudMode) {
return transaction([ return transaction([

View file

@ -1,14 +1,14 @@
import { uuid } from '@/lib/crypto'; import { uuid } from '@/lib/crypto';
import { Prisma } from '@/generated/prisma/client'; import { Prisma, TeamUser } from '@/generated/prisma/client';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
import TeamUserFindManyArgs = Prisma.TeamUserFindManyArgs; import TeamUserFindManyArgs = Prisma.TeamUserFindManyArgs;
export async function findTeamUser(criteria: Prisma.TeamUserFindUniqueArgs) { export async function findTeamUser(criteria: Prisma.TeamUserFindUniqueArgs): Promise<TeamUser> {
return prisma.client.teamUser.findUnique(criteria); return prisma.client.teamUser.findUnique(criteria);
} }
export async function getTeamUser(teamId: string, userId: string) { export async function getTeamUser(teamId: string, userId: string): Promise<TeamUser> {
return prisma.client.teamUser.findFirst({ return prisma.client.teamUser.findFirst({
where: { where: {
teamId, teamId,
@ -17,7 +17,10 @@ export async function getTeamUser(teamId: string, userId: string) {
}); });
} }
export async function getTeamUsers(criteria: TeamUserFindManyArgs, filters?: QueryFilters) { export async function getTeamUsers(
criteria: TeamUserFindManyArgs,
filters?: QueryFilters,
): Promise<PageResult<TeamUser[]>> {
const { search } = filters; const { search } = filters;
const where: Prisma.TeamUserWhereInput = { const where: Prisma.TeamUserWhereInput = {
@ -35,7 +38,11 @@ export async function getTeamUsers(criteria: TeamUserFindManyArgs, filters?: Que
); );
} }
export async function createTeamUser(userId: string, teamId: string, role: string) { export async function createTeamUser(
userId: string,
teamId: string,
role: string,
): Promise<TeamUser> {
return prisma.client.teamUser.create({ return prisma.client.teamUser.create({
data: { data: {
id: uuid(), id: uuid(),
@ -46,7 +53,10 @@ export async function createTeamUser(userId: string, teamId: string, role: strin
}); });
} }
export async function updateTeamUser(teamUserId: string, data: Prisma.TeamUserUpdateInput) { export async function updateTeamUser(
teamUserId: string,
data: Prisma.TeamUserUpdateInput,
): Promise<TeamUser> {
return prisma.client.teamUser.update({ return prisma.client.teamUser.update({
where: { where: {
id: teamUserId, id: teamUserId,
@ -55,7 +65,7 @@ export async function updateTeamUser(teamUserId: string, data: Prisma.TeamUserUp
}); });
} }
export async function deleteTeamUser(teamId: string, userId: string) { export async function deleteTeamUser(teamId: string, userId: string): Promise<Prisma.BatchPayload> {
return prisma.client.teamUser.deleteMany({ return prisma.client.teamUser.deleteMany({
where: { where: {
teamId, teamId,

View file

@ -1,7 +1,7 @@
import { Prisma } from '@/generated/prisma/client'; import { Prisma, User } from '@/generated/prisma/client';
import { ROLES } from '@/lib/constants'; import { ROLES } from '@/lib/constants';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { Role, QueryFilters } from '@/lib/types'; import { PageResult, Role, QueryFilters } from '@/lib/types';
import { getRandomChars } from '@/lib/generate'; import { getRandomChars } from '@/lib/generate';
import UserFindManyArgs = Prisma.UserFindManyArgs; import UserFindManyArgs = Prisma.UserFindManyArgs;
@ -10,7 +10,10 @@ export interface GetUserOptions {
showDeleted?: boolean; showDeleted?: boolean;
} }
async function findUser(criteria: Prisma.UserFindUniqueArgs, options: GetUserOptions = {}) { async function findUser(
criteria: Prisma.UserFindUniqueArgs,
options: GetUserOptions = {},
): Promise<User> {
const { includePassword = false, showDeleted = false } = options; const { includePassword = false, showDeleted = false } = options;
return prisma.client.user.findUnique({ return prisma.client.user.findUnique({
@ -44,7 +47,10 @@ export async function getUserByUsername(username: string, options: GetUserOption
return findUser({ where: { username } }, options); return findUser({ where: { username } }, options);
} }
export async function getUsers(criteria: UserFindManyArgs, filters: QueryFilters = {}) { export async function getUsers(
criteria: UserFindManyArgs,
filters: QueryFilters = {},
): Promise<PageResult<User[]>> {
const { search } = filters; const { search } = filters;
const where: Prisma.UserWhereInput = { const where: Prisma.UserWhereInput = {
@ -72,7 +78,11 @@ export async function createUser(data: {
username: string; username: string;
password: string; password: string;
role: Role; role: Role;
}) { }): Promise<{
id: string;
username: string;
role: string;
}> {
return prisma.client.user.create({ return prisma.client.user.create({
data, data,
select: { select: {
@ -83,7 +93,7 @@ export async function createUser(data: {
}); });
} }
export async function updateUser(userId: string, data: Prisma.UserUpdateInput) { export async function updateUser(userId: string, data: Prisma.UserUpdateInput): Promise<User> {
return prisma.client.user.update({ return prisma.client.user.update({
where: { where: {
id: userId, id: userId,
@ -98,9 +108,21 @@ export async function updateUser(userId: string, data: Prisma.UserUpdateInput) {
}); });
} }
export async function deleteUser(userId: string) { export async function deleteUser(
userId: string,
): Promise<
[
Prisma.BatchPayload,
Prisma.BatchPayload,
Prisma.BatchPayload,
Prisma.BatchPayload,
Prisma.BatchPayload,
Prisma.BatchPayload,
User,
]
> {
const { client, transaction } = prisma; const { client, transaction } = prisma;
const cloudMode = !!process.env.CLOUD_MODE; const cloudMode = !!process.env.CLOUD_URL;
const websites = await client.website.findMany({ const websites = await client.website.findMany({
where: { userId }, where: { userId },

View file

@ -1,10 +1,10 @@
import { Prisma } from '@/generated/prisma/client'; import { Prisma, Website } from '@/generated/prisma/client';
import redis from '@/lib/redis'; import redis from '@/lib/redis';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { QueryFilters } from '@/lib/types'; import { PageResult, QueryFilters } from '@/lib/types';
import { ROLES } from '@/lib/constants'; import { ROLES } from '@/lib/constants';
export async function findWebsite(criteria: Prisma.WebsiteFindUniqueArgs) { export async function findWebsite(criteria: Prisma.WebsiteFindUniqueArgs): Promise<Website> {
return prisma.client.website.findUnique(criteria); return prisma.client.website.findUnique(criteria);
} }
@ -25,7 +25,10 @@ export async function getSharedWebsite(shareId: string) {
}); });
} }
export async function getWebsites(criteria: Prisma.WebsiteFindManyArgs, filters: QueryFilters) { export async function getWebsites(
criteria: Prisma.WebsiteFindManyArgs,
filters: QueryFilters,
): Promise<PageResult<Website[]>> {
const { search } = filters; const { search } = filters;
const { getSearchParameters, pagedQuery } = prisma; const { getSearchParameters, pagedQuery } = prisma;
@ -43,7 +46,10 @@ export async function getWebsites(criteria: Prisma.WebsiteFindManyArgs, filters:
return pagedQuery('website', { ...criteria, where }, filters); return pagedQuery('website', { ...criteria, where }, filters);
} }
export async function getAllUserWebsitesIncludingTeamOwner(userId: string, filters?: QueryFilters) { export async function getAllUserWebsitesIncludingTeamOwner(
userId: string,
filters?: QueryFilters,
): Promise<PageResult<Website[]>> {
return getWebsites( return getWebsites(
{ {
where: { where: {
@ -70,7 +76,10 @@ export async function getAllUserWebsitesIncludingTeamOwner(userId: string, filte
); );
} }
export async function getUserWebsites(userId: string, filters?: QueryFilters) { export async function getUserWebsites(
userId: string,
filters?: QueryFilters,
): Promise<PageResult<Website[]>> {
return getWebsites( return getWebsites(
{ {
where: { where: {
@ -92,7 +101,10 @@ export async function getUserWebsites(userId: string, filters?: QueryFilters) {
); );
} }
export async function getTeamWebsites(teamId: string, filters?: QueryFilters) { export async function getTeamWebsites(
teamId: string,
filters?: QueryFilters,
): Promise<PageResult<Website[]>> {
return getWebsites( return getWebsites(
{ {
where: { where: {
@ -113,7 +125,7 @@ export async function getTeamWebsites(teamId: string, filters?: QueryFilters) {
export async function createWebsite( export async function createWebsite(
data: Prisma.WebsiteCreateInput | Prisma.WebsiteUncheckedCreateInput, data: Prisma.WebsiteCreateInput | Prisma.WebsiteUncheckedCreateInput,
) { ): Promise<Website> {
return prisma.client.website.create({ return prisma.client.website.create({
data, data,
}); });
@ -122,7 +134,7 @@ export async function createWebsite(
export async function updateWebsite( export async function updateWebsite(
websiteId: string, websiteId: string,
data: Prisma.WebsiteUpdateInput | Prisma.WebsiteUncheckedUpdateInput, data: Prisma.WebsiteUpdateInput | Prisma.WebsiteUncheckedUpdateInput,
) { ): Promise<Website> {
return prisma.client.website.update({ return prisma.client.website.update({
where: { where: {
id: websiteId, id: websiteId,
@ -131,9 +143,11 @@ export async function updateWebsite(
}); });
} }
export async function resetWebsite(websiteId: string) { export async function resetWebsite(
websiteId: string,
): Promise<[Prisma.BatchPayload, Prisma.BatchPayload, Website]> {
const { client, transaction } = prisma; const { client, transaction } = prisma;
const cloudMode = !!process.env.CLOUD_MODE; const cloudMode = !!process.env.CLOUD_URL;
return transaction([ return transaction([
client.eventData.deleteMany({ client.eventData.deleteMany({
@ -163,9 +177,11 @@ export async function resetWebsite(websiteId: string) {
}); });
} }
export async function deleteWebsite(websiteId: string) { export async function deleteWebsite(
websiteId: string,
): Promise<[Prisma.BatchPayload, Prisma.BatchPayload, Website]> {
const { client, transaction } = prisma; const { client, transaction } = prisma;
const cloudMode = !!process.env.CLOUD_MODE; const cloudMode = !!process.env.CLOUD_URL;
return transaction([ return transaction([
client.eventData.deleteMany({ client.eventData.deleteMany({