rename organizationId -> organizationSlug
This commit is contained in:
@@ -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
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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} />
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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>({
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
Reference in New Issue
Block a user