rename organizationId -> organizationSlug

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-04-08 21:49:00 +02:00
parent 097ea18320
commit 19b0e509e0
37 changed files with 109 additions and 128 deletions

View File

@@ -42,7 +42,7 @@ export function ListReports({ reports }: ListReportsProps) {
icon={PlusIcon} icon={PlusIcon}
onClick={() => { onClick={() => {
router.push( router.push(
`/${params.organizationId}/${ `/${params.organizationSlug}/${
params.projectId params.projectId
}/reports?${new URLSearchParams({ }/reports?${new URLSearchParams({
dashboardId: params.dashboardId, dashboardId: params.dashboardId,
@@ -60,7 +60,7 @@ export function ListReports({ reports }: ListReportsProps) {
return ( return (
<div className="card" key={report.id}> <div className="card" key={report.id}>
<Link <Link
href={`/${params.organizationId}/${params.projectId}/reports/${report.id}`} href={`/${params.organizationSlug}/${params.projectId}/reports/${report.id}`}
className="flex items-center justify-between border-b border-border p-4 leading-none [&_svg]:hover:opacity-100" className="flex items-center justify-between border-b border-border p-4 leading-none [&_svg]:hover:opacity-100"
shallow shallow
> >

View File

@@ -14,7 +14,7 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { organizationId, projectId, dashboardId }, params: { organizationId: organizationSlug, projectId, dashboardId },
}: PageProps) { }: PageProps) {
const [dashboard, reports] = await Promise.all([ const [dashboard, reports] = await Promise.all([
getDashboardById(dashboardId, projectId), getDashboardById(dashboardId, projectId),
@@ -26,7 +26,7 @@ export default async function Page({
} }
return ( return (
<PageLayout title={dashboard.name} organizationSlug={organizationId}> <PageLayout title={dashboard.name} organizationSlug={organizationSlug}>
<ListReports reports={reports} /> <ListReports reports={reports} />
</PageLayout> </PageLayout>
); );

View File

@@ -20,7 +20,7 @@ interface ListDashboardsProps {
export function ListDashboards({ dashboards }: ListDashboardsProps) { export function ListDashboards({ dashboards }: ListDashboardsProps) {
const router = useRouter(); const router = useRouter();
const params = useAppParams(); const params = useAppParams();
const { organizationId, projectId } = params; const { organizationSlug, projectId } = params;
const deletion = api.dashboard.delete.useMutation({ const deletion = api.dashboard.delete.useMutation({
onError: (error, variables) => { onError: (error, variables) => {
return handleErrorToastOptions({ return handleErrorToastOptions({
@@ -65,8 +65,8 @@ export function ListDashboards({ dashboards }: ListDashboardsProps) {
<Card key={item.id} hover> <Card key={item.id} hover>
<div> <div>
<Link <Link
href={`/${organizationId}/${projectId}/dashboards/${item.id}`} href={`/${organizationSlug}/${projectId}/dashboards/${item.id}`}
className="block flex flex-col p-4" className="flex flex-col p-4"
> >
<span className="font-medium">{item.name}</span> <span className="font-medium">{item.name}</span>
</Link> </Link>

View File

@@ -13,12 +13,12 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { projectId, organizationId }, params: { projectId, organizationId: organizationSlug },
}: PageProps) { }: PageProps) {
const dashboards = await getDashboardsByProjectId(projectId); const dashboards = await getDashboardsByProjectId(projectId);
return ( return (
<PageLayout title="Dashboards" organizationSlug={organizationId}> <PageLayout title="Dashboards" organizationSlug={organizationSlug}>
{dashboards.length > 0 && <HeaderDashboards />} {dashboards.length > 0 && <HeaderDashboards />}
<ListDashboards dashboards={dashboards} /> <ListDashboards dashboards={dashboards} />
</PageLayout> </PageLayout>

View File

@@ -15,7 +15,7 @@ import { EventIcon } from './event-icon';
type EventListItemProps = IServiceCreateEventPayload; type EventListItemProps = IServiceCreateEventPayload;
export function EventListItem(props: EventListItemProps) { export function EventListItem(props: EventListItemProps) {
const { organizationId, projectId } = useAppParams(); const { organizationSlug, projectId } = useAppParams();
const { createdAt, name, path, duration, meta, profile } = props; const { createdAt, name, path, duration, meta, profile } = props;
const [isDetailsOpen, setIsDetailsOpen] = useState(false); const [isDetailsOpen, setIsDetailsOpen] = useState(false);
@@ -77,7 +77,7 @@ export function EventListItem(props: EventListItemProps) {
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
}} }}
href={`/${organizationId}/${projectId}/profiles/${profile?.id}`} href={`/${organizationSlug}/${projectId}/profiles/${profile?.id}`}
className="max-w-[80px] overflow-hidden text-ellipsis whitespace-nowrap text-sm text-muted-foreground hover:underline" className="max-w-[80px] overflow-hidden text-ellipsis whitespace-nowrap text-sm text-muted-foreground hover:underline"
> >
{profile?.firstName} {profile?.lastName} {profile?.firstName} {profile?.lastName}

View File

@@ -31,7 +31,7 @@ const nuqsOptions = {
}; };
export default async function Page({ export default async function Page({
params: { projectId, organizationId }, params: { projectId, organizationId: organizationSlug },
searchParams, searchParams,
}: PageProps) { }: PageProps) {
const filters = const filters =
@@ -56,7 +56,7 @@ export default async function Page({
]); ]);
return ( return (
<PageLayout title="Events" organizationSlug={organizationId}> <PageLayout title="Events" organizationSlug={organizationSlug}>
<StickyBelowHeader className="flex justify-between p-4"> <StickyBelowHeader className="flex justify-between p-4">
<OverviewFiltersDrawer <OverviewFiltersDrawer
mode="events" mode="events"

View File

@@ -83,49 +83,49 @@ export default function LayoutMenu({ dashboards }: LayoutMenuProps) {
<LinkWithIcon <LinkWithIcon
icon={WallpaperIcon} icon={WallpaperIcon}
label="Overview" label="Overview"
href={`/${params.organizationId}/${projectId}`} href={`/${params.organizationSlug}/${projectId}`}
/> />
<LinkWithIcon <LinkWithIcon
icon={LayoutPanelTopIcon} icon={LayoutPanelTopIcon}
label="Dashboards" label="Dashboards"
href={`/${params.organizationId}/${projectId}/dashboards`} href={`/${params.organizationSlug}/${projectId}/dashboards`}
/> />
<LinkWithIcon <LinkWithIcon
icon={GanttChartIcon} icon={GanttChartIcon}
label="Events" label="Events"
href={`/${params.organizationId}/${projectId}/events`} href={`/${params.organizationSlug}/${projectId}/events`}
/> />
<LinkWithIcon <LinkWithIcon
icon={UsersIcon} icon={UsersIcon}
label="Profiles" label="Profiles"
href={`/${params.organizationId}/${projectId}/profiles`} href={`/${params.organizationSlug}/${projectId}/profiles`}
/> />
<LinkWithIcon <LinkWithIcon
icon={CogIcon} icon={CogIcon}
label="Settings" label="Settings"
href={`/${params.organizationId}/${projectId}/settings/organization`} href={`/${params.organizationSlug}/${projectId}/settings/organization`}
/> />
{pathname?.includes('/settings/') && ( {pathname?.includes('/settings/') && (
<div className="flex flex-col gap-1 pl-7"> <div className="flex flex-col gap-1 pl-7">
<LinkWithIcon <LinkWithIcon
icon={BuildingIcon} icon={BuildingIcon}
label="Organization" label="Organization"
href={`/${params.organizationId}/${projectId}/settings/organization`} href={`/${params.organizationSlug}/${projectId}/settings/organization`}
/> />
<LinkWithIcon <LinkWithIcon
icon={WarehouseIcon} icon={WarehouseIcon}
label="Projects" label="Projects"
href={`/${params.organizationId}/${projectId}/settings/projects`} href={`/${params.organizationSlug}/${projectId}/settings/projects`}
/> />
<LinkWithIcon <LinkWithIcon
icon={UserIcon} icon={UserIcon}
label="Profile (yours)" label="Profile (yours)"
href={`/${params.organizationId}/${projectId}/settings/profile`} href={`/${params.organizationSlug}/${projectId}/settings/profile`}
/> />
<LinkWithIcon <LinkWithIcon
icon={BookmarkIcon} icon={BookmarkIcon}
label="References" label="References"
href={`/${params.organizationId}/${projectId}/settings/references`} href={`/${params.organizationSlug}/${projectId}/settings/references`}
/> />
</div> </div>
)} )}

View File

@@ -18,7 +18,7 @@ export default function LayoutOrganizationSelector({
const router = useRouter(); const router = useRouter();
const organization = organizations.find( const organization = organizations.find(
(item) => item.slug === params.organizationId (item) => item.slug === params.organizationSlug
); );
if (!organization) { if (!organization) {

View File

@@ -13,7 +13,7 @@ export default function LayoutProjectSelector({
projects, projects,
}: LayoutProjectSelectorProps) { }: LayoutProjectSelectorProps) {
const router = useRouter(); const router = useRouter();
const { organizationId, projectId } = useAppParams(); const { organizationSlug, projectId } = useAppParams();
const pathname = usePathname() || ''; const pathname = usePathname() || '';
return ( return (
@@ -24,12 +24,12 @@ export default function LayoutProjectSelector({
className="w-auto min-w-0 max-sm:max-w-[100px]" className="w-auto min-w-0 max-sm:max-w-[100px]"
placeholder={'Select project'} placeholder={'Select project'}
onChange={(value) => { onChange={(value) => {
if (organizationId && projectId) { if (organizationSlug && projectId) {
const split = pathname.replace(projectId, value).split('/'); const split = pathname.replace(projectId, value).split('/');
// slicing here will remove everything after /{orgId}/{projectId}/dashboards [slice here] /xxx/xxx/xxx // slicing here will remove everything after /{orgId}/{projectId}/dashboards [slice here] /xxx/xxx/xxx
router.push(split.slice(0, 4).join('/')); router.push(split.slice(0, 4).join('/'));
} else { } else {
router.push(`/${organizationId}/${value}`); router.push(`/${organizationSlug}/${value}`);
} }
}} }}
value={projectId} value={projectId}

View File

@@ -17,13 +17,13 @@ import LayoutOrganizationSelector from './layout-organization-selector';
interface LayoutSidebarProps { interface LayoutSidebarProps {
organizations: IServiceOrganization[]; organizations: IServiceOrganization[];
dashboards: IServiceDashboards; dashboards: IServiceDashboards;
organizationId: string; organizationSlug: string;
projectId: string; projectId: string;
} }
export function LayoutSidebar({ export function LayoutSidebar({
organizations, organizations,
dashboards, dashboards,
organizationId, organizationSlug,
projectId, projectId,
}: LayoutSidebarProps) { }: LayoutSidebarProps) {
const [active, setActive] = useState(false); const [active, setActive] = useState(false);
@@ -69,7 +69,7 @@ export function LayoutSidebar({
<div className="flex flex-col gap-2 bg-background p-4 pt-0"> <div className="flex flex-col gap-2 bg-background p-4 pt-0">
<Link <Link
className={cn('flex gap-2', buttonVariants())} className={cn('flex gap-2', buttonVariants())}
href={`/${organizationId}/${projectId}/reports`} href={`/${organizationSlug}/${projectId}/reports`}
> >
<PlusIcon size={16} /> <PlusIcon size={16} />
Create a report Create a report

View File

@@ -18,15 +18,15 @@ interface AppLayoutProps {
export default async function AppLayout({ export default async function AppLayout({
children, children,
params: { organizationId, projectId }, params: { organizationId: organizationSlug, projectId },
}: AppLayoutProps) { }: AppLayoutProps) {
const [organizations, projects, dashboards] = await Promise.all([ const [organizations, projects, dashboards] = await Promise.all([
getCurrentOrganizations(), getCurrentOrganizations(),
getCurrentProjects(organizationId), getCurrentProjects(organizationSlug),
getDashboardsByProjectId(projectId), getDashboardsByProjectId(projectId),
]); ]);
if (!organizations.find((item) => item.slug === organizationId)) { if (!organizations.find((item) => item.slug === organizationSlug)) {
return ( return (
<FullPageEmptyState <FullPageEmptyState
title="Could not find organization" title="Could not find organization"
@@ -51,7 +51,7 @@ export default async function AppLayout({
return ( return (
<div id="dashboard"> <div id="dashboard">
<LayoutSidebar <LayoutSidebar
{...{ organizationId, projectId, organizations, dashboards }} {...{ organizationSlug, projectId, organizations, dashboards }}
/> />
<div className="transition-all lg:pl-72">{children}</div> <div className="transition-all lg:pl-72">{children}</div>
</div> </div>

View File

@@ -24,12 +24,12 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { organizationId, projectId }, params: { organizationId: organizationSlug, projectId },
}: PageProps) { }: PageProps) {
const share = await getShareByProjectId(projectId); const share = await getShareByProjectId(projectId);
return ( return (
<PageLayout title="Overview" organizationSlug={organizationId}> <PageLayout title="Overview" organizationSlug={organizationSlug}>
<StickyBelowHeader> <StickyBelowHeader>
<div className="flex justify-between gap-2 p-4"> <div className="flex justify-between gap-2 p-4">
<div className="flex gap-2"> <div className="flex gap-2">

View File

@@ -41,7 +41,7 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { projectId, profileId, organizationId }, params: { projectId, profileId, organizationId: organizationSlug },
searchParams, searchParams,
}: PageProps) { }: PageProps) {
const eventListOptions: GetEventListOptions = { const eventListOptions: GetEventListOptions = {
@@ -125,7 +125,7 @@ export default async function Page({
return ( return (
<PageLayout <PageLayout
organizationSlug={organizationId} organizationSlug={organizationSlug}
title={ title={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ProfileAvatar {...profile} size="sm" className="hidden sm:block" /> <ProfileAvatar {...profile} size="sm" className="hidden sm:block" />

View File

@@ -25,11 +25,11 @@ const nuqsOptions = {
}; };
export default function Page({ export default function Page({
params: { organizationId, projectId }, params: { organizationId: organizationSlug, projectId },
searchParams: { cursor, f }, searchParams: { cursor, f },
}: PageProps) { }: PageProps) {
return ( return (
<PageLayout title="Profiles" organizationSlug={organizationId}> <PageLayout title="Profiles" organizationSlug={organizationSlug}>
{/* <StickyBelowHeader className="flex justify-between p-4"> {/* <StickyBelowHeader className="flex justify-between p-4">
<OverviewFiltersDrawer <OverviewFiltersDrawer
projectId={projectId} projectId={projectId}
@@ -53,7 +53,7 @@ export default function Page({
<ProfileLastSeenServer projectId={projectId} /> <ProfileLastSeenServer projectId={projectId} />
<ProfileTopServer <ProfileTopServer
projectId={projectId} projectId={projectId}
organizationId={organizationId} organizationSlug={organizationSlug}
/> />
</div> </div>
</div> </div>

View File

@@ -21,7 +21,7 @@ interface ProfileListProps {
count: number; count: number;
} }
export function ProfileList({ data, count }: ProfileListProps) { export function ProfileList({ data, count }: ProfileListProps) {
const { organizationId, projectId } = useAppParams(); const { organizationSlug, projectId } = useAppParams();
const { cursor, setCursor } = useCursor(); const { cursor, setCursor } = useCursor();
return ( return (
<Widget> <Widget>
@@ -46,7 +46,7 @@ export function ProfileList({ data, count }: ProfileListProps) {
render(profile) { render(profile) {
return ( return (
<Link <Link
href={`/${organizationId}/${projectId}/profiles/${profile.id}`} href={`/${organizationSlug}/${projectId}/profiles/${profile.id}`}
className="flex items-center gap-2 font-medium" className="flex items-center gap-2 font-medium"
> >
<ProfileAvatar size="sm" {...profile} /> <ProfileAvatar size="sm" {...profile} />

View File

@@ -10,11 +10,11 @@ import { chQuery, getProfiles } from '@openpanel/db';
interface Props { interface Props {
projectId: string; projectId: string;
organizationId: string; organizationSlug: string;
} }
export default async function ProfileTopServer({ export default async function ProfileTopServer({
organizationId, organizationSlug,
projectId, projectId,
}: Props) { }: Props) {
// Days since last event from users // Days since last event from users
@@ -44,7 +44,7 @@ export default async function ProfileTopServer({
render(profile) { render(profile) {
return ( return (
<Link <Link
href={`/${organizationId}/${projectId}/profiles/${profile.id}`} href={`/${organizationSlug}/${projectId}/profiles/${profile.id}`}
className="flex items-center gap-2 font-medium" className="flex items-center gap-2 font-medium"
> >
<ProfileAvatar size="sm" {...profile} /> <ProfileAvatar size="sm" {...profile} />

View File

@@ -15,7 +15,7 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { reportId, organizationId }, params: { reportId, organizationId: organizationSlug },
}: PageProps) { }: PageProps) {
const report = await getReportById(reportId); const report = await getReportById(reportId);
@@ -25,7 +25,7 @@ export default async function Page({
return ( return (
<PageLayout <PageLayout
organizationSlug={organizationId} organizationSlug={organizationSlug}
title={ title={
<div className="flex cursor-pointer items-center gap-2"> <div className="flex cursor-pointer items-center gap-2">
{report.name} {report.name}

View File

@@ -10,10 +10,12 @@ interface PageProps {
}; };
} }
export default function Page({ params: { organizationId } }: PageProps) { export default function Page({
params: { organizationId: organizationSlug },
}: PageProps) {
return ( return (
<PageLayout <PageLayout
organizationSlug={organizationId} organizationSlug={organizationSlug}
title={ title={
<div className="flex cursor-pointer items-center gap-2"> <div className="flex cursor-pointer items-center gap-2">
Unnamed report Unnamed report

View File

@@ -33,7 +33,7 @@ interface Props {
export default function CreateInvite({ projects }: Props) { export default function CreateInvite({ projects }: Props) {
const router = useRouter(); const router = useRouter();
const { organizationId: organizationSlug } = useAppParams(); const { organizationSlug } = useAppParams();
const { register, handleSubmit, formState, reset, control } = useForm<IForm>({ const { register, handleSubmit, formState, reset, control } = useForm<IForm>({
resolver: zodResolver(zInviteUser), resolver: zodResolver(zInviteUser),

View File

@@ -11,12 +11,14 @@ interface PageProps {
organizationId: string; organizationId: string;
}; };
} }
export default async function Page({ params: { organizationId } }: PageProps) { export default async function Page({
params: { organizationId: organizationSlug },
}: PageProps) {
const { userId } = auth(); const { userId } = auth();
const profile = await getUserById(userId!); const profile = await getUserById(userId!);
return ( return (
<PageLayout title={profile.lastName} organizationSlug={organizationId}> <PageLayout title={profile.lastName} organizationSlug={organizationSlug}>
<div className="flex flex-col gap-4 p-4"> <div className="flex flex-col gap-4 p-4">
<EditProfile profile={profile} /> <EditProfile profile={profile} />
<Logout /> <Logout />

View File

@@ -24,7 +24,7 @@ interface ListProjectsProps {
clients: IServiceClientWithProject[]; clients: IServiceClientWithProject[];
} }
export default function ListProjects({ projects, clients }: ListProjectsProps) { export default function ListProjects({ projects, clients }: ListProjectsProps) {
const organizationId = useAppParams().organizationId; const { organizationSlug } = useAppParams();
return ( return (
<> <>
<StickyBelowHeader> <StickyBelowHeader>
@@ -34,7 +34,7 @@ export default function ListProjects({ projects, clients }: ListProjectsProps) {
icon={PlusIcon} icon={PlusIcon}
onClick={() => onClick={() =>
pushModal('AddProject', { pushModal('AddProject', {
organizationId, organizationSlug,
}) })
} }
> >

View File

@@ -1,7 +1,7 @@
import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout'; import PageLayout from '@/app/(app)/[organizationId]/[projectId]/page-layout';
import { import {
getClientsByOrganizationId, getClientsByOrganizationSlug,
getProjectsByOrganizationSlug, getProjectsByOrganizationSlug,
} from '@openpanel/db'; } from '@openpanel/db';
@@ -13,14 +13,16 @@ interface PageProps {
}; };
} }
export default async function Page({ params: { organizationId } }: PageProps) { export default async function Page({
params: { organizationId: organizationSlug },
}: PageProps) {
const [projects, clients] = await Promise.all([ const [projects, clients] = await Promise.all([
getProjectsByOrganizationSlug(organizationId), getProjectsByOrganizationSlug(organizationSlug),
getClientsByOrganizationId(organizationId), getClientsByOrganizationSlug(organizationSlug),
]); ]);
return ( return (
<PageLayout title="Projects" organizationSlug={organizationId}> <PageLayout title="Projects" organizationSlug={organizationSlug}>
<ListProjects projects={projects} clients={clients} /> <ListProjects projects={projects} clients={clients} />
</PageLayout> </PageLayout>
); );

View File

@@ -12,7 +12,7 @@ interface PageProps {
} }
export default async function Page({ export default async function Page({
params: { organizationId, projectId }, params: { organizationId: organizationSlug, projectId },
}: PageProps) { }: PageProps) {
const references = await getReferences({ const references = await getReferences({
where: { where: {
@@ -23,7 +23,7 @@ export default async function Page({
}); });
return ( return (
<PageLayout title="References" organizationSlug={organizationId}> <PageLayout title="References" organizationSlug={organizationSlug}>
<ListReferences data={references} /> <ListReferences data={references} />
</PageLayout> </PageLayout>
); );

View File

@@ -36,7 +36,7 @@ export function CreateProject() {
const onSubmit: SubmitHandler<IForm> = (values) => { const onSubmit: SubmitHandler<IForm> = (values) => {
mutation.mutate({ mutation.mutate({
name: values.name, name: values.name,
organizationId: params.organizationId, organizationSlug: params.organizationSlug,
}); });
}; };

View File

@@ -16,10 +16,12 @@ interface PageProps {
}; };
} }
export default async function Page({ params: { organizationId } }: PageProps) { export default async function Page({
params: { organizationId: organizationSlug },
}: PageProps) {
const [organization, projects] = await Promise.all([ const [organization, projects] = await Promise.all([
getOrganizationBySlug(organizationId), getOrganizationBySlug(organizationSlug),
getCurrentProjects(organizationId), getCurrentProjects(organizationSlug),
]); ]);
if (!organization) { if (!organization) {
@@ -55,7 +57,7 @@ export default async function Page({ params: { organizationId } }: PageProps) {
} }
if (projects.length === 1 && projects[0]) { if (projects.length === 1 && projects[0]) {
return redirect(`/${organizationId}/${projects[0].id}`); return redirect(`/${organizationSlug}/${projects[0].id}`);
} }
return ( return (

View File

@@ -58,9 +58,8 @@ export function OverviewShare({ data }: OverviewShareProps) {
<DropdownMenuItem <DropdownMenuItem
onClick={() => { onClick={() => {
mutation.mutate({ mutation.mutate({
...data,
public: false, public: false,
projectId: data?.projectId,
organizationId: data?.organizationSlug,
password: null, password: null,
}); });
}} }}

View File

@@ -1,16 +1,19 @@
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
// eslint-disable-next-line type AppParamsIn = {
type AppParams = {
organizationId: string; organizationId: string;
projectId: string; projectId: string;
}; };
type AppParamsOut = {
organizationSlug: string;
projectId: string;
};
export function useAppParams<T>() { export function useAppParams<T>() {
const params = useParams<T & AppParams>(); const params = useParams<T & AppParamsIn>();
return { return {
...(params ?? {}), ...(params ?? {}),
organizationId: params?.organizationId, organizationSlug: params?.organizationId,
projectId: params?.projectId, projectId: params?.projectId,
} as T & AppParams; } as T & AppParamsOut;
} }

View File

@@ -43,7 +43,7 @@ interface Props {
projectId: string; projectId: string;
} }
export default function AddClient(props: Props) { export default function AddClient(props: Props) {
const { organizationId, projectId } = useAppParams(); const { organizationSlug, projectId } = useAppParams();
const router = useRouter(); const router = useRouter();
const form = useForm<IForm>({ const form = useForm<IForm>({
resolver: zodResolver(validation), resolver: zodResolver(validation),
@@ -62,14 +62,14 @@ export default function AddClient(props: Props) {
}, },
}); });
const query = api.project.list.useQuery({ const query = api.project.list.useQuery({
organizationId, organizationSlug,
}); });
const onSubmit: SubmitHandler<IForm> = (values) => { const onSubmit: SubmitHandler<IForm> = (values) => {
mutation.mutate({ mutation.mutate({
name: values.name, name: values.name,
cors: values.tab === 'website' ? values.cors : null, cors: values.tab === 'website' ? values.cors : null,
projectId: values.projectId, projectId: values.projectId,
organizationId, organizationSlug,
}); });
}; };

View File

@@ -19,7 +19,7 @@ const validator = z.object({
type IForm = z.infer<typeof validator>; type IForm = z.infer<typeof validator>;
export default function AddDashboard() { export default function AddDashboard() {
const { projectId, organizationId: organizationSlug } = useAppParams(); const { projectId, organizationSlug } = useAppParams();
const router = useRouter(); const router = useRouter();
const { register, handleSubmit, formState } = useForm<IForm>({ const { register, handleSubmit, formState } = useForm<IForm>({

View File

@@ -17,9 +17,9 @@ const validator = z.object({
type IForm = z.infer<typeof validator>; type IForm = z.infer<typeof validator>;
interface AddProjectProps { interface AddProjectProps {
organizationId: string; organizationSlug: string;
} }
export default function AddProject({ organizationId }: AddProjectProps) { export default function AddProject({ organizationSlug }: AddProjectProps) {
const router = useRouter(); const router = useRouter();
const mutation = api.project.create.useMutation({ const mutation = api.project.create.useMutation({
onError: handleError, onError: handleError,
@@ -45,7 +45,7 @@ export default function AddProject({ organizationId }: AddProjectProps) {
onSubmit={handleSubmit((values) => { onSubmit={handleSubmit((values) => {
mutation.mutate({ mutation.mutate({
...values, ...values,
organizationId, organizationSlug,
}); });
})} })}
> >

View File

@@ -30,7 +30,7 @@ type IForm = z.infer<typeof validator>;
export default function SaveReport({ report }: SaveReportProps) { export default function SaveReport({ report }: SaveReportProps) {
const router = useRouter(); const router = useRouter();
const { organizationId: organizationSlug, projectId } = useAppParams(); const { organizationSlug, projectId } = useAppParams();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const dashboardId = searchParams?.get('dashboardId') ?? undefined; const dashboardId = searchParams?.get('dashboardId') ?? undefined;

View File

@@ -20,16 +20,16 @@ const validator = zShareOverview;
type IForm = z.infer<typeof validator>; type IForm = z.infer<typeof validator>;
export default function ShareOverviewModal() { export default function ShareOverviewModal() {
const { projectId, organizationId: organizationSlug } = useAppParams(); const { projectId, organizationSlug } = useAppParams();
const router = useRouter(); const router = useRouter();
const { register, handleSubmit, formState, control } = useForm<IForm>({ const { register, handleSubmit, control } = useForm<IForm>({
resolver: zodResolver(validator), resolver: zodResolver(validator),
defaultValues: { defaultValues: {
public: true, public: true,
password: '', password: '',
projectId, projectId,
organizationId: organizationSlug, organizationSlug,
}, },
}); });

View File

@@ -6,35 +6,6 @@ import { hashPassword, stripTrailingSlash } from '@openpanel/common';
import { db } from '@openpanel/db'; import { db } from '@openpanel/db';
export const clientRouter = createTRPCRouter({ export const clientRouter = createTRPCRouter({
list: protectedProcedure
.input(
z.object({
organizationId: z.string(),
})
)
.query(async ({ input: { organizationId } }) => {
return db.client.findMany({
where: {
organizationSlug: organizationId,
},
include: {
project: true,
},
});
}),
get: protectedProcedure
.input(
z.object({
id: z.string(),
})
)
.query(({ input }) => {
return db.client.findUniqueOrThrow({
where: {
id: input.id,
},
});
}),
update: protectedProcedure update: protectedProcedure
.input( .input(
z.object({ z.object({
@@ -59,7 +30,7 @@ export const clientRouter = createTRPCRouter({
z.object({ z.object({
name: z.string(), name: z.string(),
projectId: z.string(), projectId: z.string(),
organizationId: z.string(), organizationSlug: z.string(),
cors: z.string().nullable(), cors: z.string().nullable(),
}) })
) )
@@ -67,7 +38,7 @@ export const clientRouter = createTRPCRouter({
const secret = randomUUID(); const secret = randomUUID();
const client = await db.client.create({ const client = await db.client.create({
data: { data: {
organizationSlug: input.organizationId, organizationSlug: input.organizationSlug,
projectId: input.projectId, projectId: input.projectId,
name: input.name, name: input.name,
secret: input.cors ? null : await hashPassword(secret), secret: input.cors ? null : await hashPassword(secret),

View File

@@ -8,12 +8,12 @@ export const projectRouter = createTRPCRouter({
list: protectedProcedure list: protectedProcedure
.input( .input(
z.object({ z.object({
organizationId: z.string().nullable(), organizationSlug: z.string().nullable(),
}) })
) )
.query(async ({ input: { organizationId } }) => { .query(async ({ input: { organizationSlug } }) => {
if (organizationId === null) return []; if (organizationSlug === null) return [];
return getProjectsByOrganizationSlug(organizationId); return getProjectsByOrganizationSlug(organizationSlug);
}), }),
update: protectedProcedure update: protectedProcedure
@@ -37,15 +37,15 @@ export const projectRouter = createTRPCRouter({
.input( .input(
z.object({ z.object({
name: z.string().min(1), name: z.string().min(1),
organizationId: z.string(), organizationSlug: z.string(),
}) })
) )
.mutation(async ({ input }) => { .mutation(async ({ input: { name, organizationSlug } }) => {
return db.project.create({ return db.project.create({
data: { data: {
id: await getId('project', input.name), id: await getId('project', name),
organizationSlug: input.organizationId, organizationSlug: organizationSlug,
name: input.name, name: name,
}, },
}); });
}), }),

View File

@@ -16,7 +16,7 @@ export const shareRouter = createTRPCRouter({
}, },
create: { create: {
id: uid.rnd(), id: uid.rnd(),
organizationSlug: input.organizationId, organizationSlug: input.organizationSlug,
projectId: input.projectId, projectId: input.projectId,
public: input.public, public: input.public,
password: input.password || null, password: input.password || null,

View File

@@ -8,10 +8,10 @@ export type IServiceClientWithProject = Prisma.ClientGetPayload<{
}; };
}>; }>;
export async function getClientsByOrganizationId(organizationId: string) { export async function getClientsByOrganizationSlug(organizationSlug: string) {
return db.client.findMany({ return db.client.findMany({
where: { where: {
organizationSlug: organizationId, organizationSlug,
}, },
include: { include: {
project: true, project: true,

View File

@@ -85,7 +85,7 @@ export const zInviteUser = z.object({
}); });
export const zShareOverview = z.object({ export const zShareOverview = z.object({
organizationId: z.string(), organizationSlug: z.string(),
projectId: z.string(), projectId: z.string(),
password: z.string().nullable(), password: z.string().nullable(),
public: z.boolean(), public: z.boolean(),