chore(root): rename organizationSlug to organizationId (#91)
This commit is contained in:
committed by
GitHub
parent
0221948aab
commit
cd16ac878d
@@ -183,12 +183,10 @@ async function createMock(file: string) {
|
|||||||
await db.project.create({
|
await db.project.create({
|
||||||
data: {
|
data: {
|
||||||
organizationId: 'openpanel-dev',
|
organizationId: 'openpanel-dev',
|
||||||
organizationSlug: 'openpanel-dev',
|
|
||||||
name: project.domain,
|
name: project.domain,
|
||||||
clients: {
|
clients: {
|
||||||
create: {
|
create: {
|
||||||
organizationId: 'openpanel-dev',
|
organizationId: 'openpanel-dev',
|
||||||
organizationSlug: 'openpanel-dev',
|
|
||||||
name: project.domain,
|
name: project.domain,
|
||||||
secret: await hashPassword('secret'),
|
secret: await hashPassword('secret'),
|
||||||
id: project.clientId,
|
id: project.clientId,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ async function getProjectId(
|
|||||||
|
|
||||||
const project = await db.project.findUnique({
|
const project = await db.project.findUnique({
|
||||||
where: {
|
where: {
|
||||||
organizationId: request.client?.organizationSlug,
|
organizationId: request.client?.organizationId,
|
||||||
id: projectId,
|
id: projectId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ export async function clerkWebhook(
|
|||||||
data: access
|
data: access
|
||||||
.filter((a) => typeof a === 'string')
|
.filter((a) => typeof a === 'string')
|
||||||
.map((projectId) => ({
|
.map((projectId) => ({
|
||||||
organizationSlug: membership.organizationId,
|
|
||||||
organizationId: membership.organizationId,
|
organizationId: membership.organizationId,
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@@ -114,7 +113,6 @@ export async function clerkWebhook(
|
|||||||
data: access
|
data: access
|
||||||
.filter((a): a is string => typeof a === 'string')
|
.filter((a): a is string => typeof a === 'string')
|
||||||
.map((projectId) => ({
|
.map((projectId) => ({
|
||||||
organizationSlug: payload.data.organization.slug,
|
|
||||||
organizationId: payload.data.organization.slug,
|
organizationId: payload.data.organization.slug,
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
userId: payload.data.public_user_data.user_id,
|
userId: payload.data.public_user_data.user_id,
|
||||||
@@ -152,7 +150,7 @@ export async function clerkWebhook(
|
|||||||
if (payload.type === 'organizationMembership.deleted') {
|
if (payload.type === 'organizationMembership.deleted') {
|
||||||
await db.projectAccess.deleteMany({
|
await db.projectAccess.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug: payload.data.organization.slug,
|
organizationId: payload.data.organization.slug,
|
||||||
userId: payload.data.public_user_data.user_id,
|
userId: payload.data.public_user_data.user_id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export function ListReports({ reports, dashboard }: ListReportsProps) {
|
|||||||
icon={PlusIcon}
|
icon={PlusIcon}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
router.push(
|
router.push(
|
||||||
`/${params.organizationSlug}/${
|
`/${params.organizationId}/${
|
||||||
params.projectId
|
params.projectId
|
||||||
}/reports?${new URLSearchParams({
|
}/reports?${new URLSearchParams({
|
||||||
dashboardId: params.dashboardId,
|
dashboardId: params.dashboardId,
|
||||||
@@ -79,7 +79,7 @@ export function ListReports({ reports, dashboard }: ListReportsProps) {
|
|||||||
return (
|
return (
|
||||||
<div className="card" key={report.id}>
|
<div className="card" key={report.id}>
|
||||||
<Link
|
<Link
|
||||||
href={`/${params.organizationSlug}/${params.projectId}/reports/${report.id}`}
|
href={`/${params.organizationId}/${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
|
||||||
>
|
>
|
||||||
@@ -163,7 +163,7 @@ export function ListReports({ reports, dashboard }: ListReportsProps) {
|
|||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push(
|
||||||
`/${params.organizationSlug}/${
|
`/${params.organizationId}/${
|
||||||
params.projectId
|
params.projectId
|
||||||
}/reports?${new URLSearchParams({
|
}/reports?${new URLSearchParams({
|
||||||
dashboardId: params.dashboardId,
|
dashboardId: params.dashboardId,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { ListReports } from './list-reports';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
dashboardId: string;
|
dashboardId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,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 { organizationSlug, projectId } = params;
|
const { organizationId, projectId } = params;
|
||||||
const deletion = api.dashboard.delete.useMutation({
|
const deletion = api.dashboard.delete.useMutation({
|
||||||
onError: (error, variables) => {
|
onError: (error, variables) => {
|
||||||
return handleErrorToastOptions({
|
return handleErrorToastOptions({
|
||||||
@@ -87,7 +87,7 @@ export function ListDashboards({ dashboards }: ListDashboardsProps) {
|
|||||||
<Card key={item.id} hover>
|
<Card key={item.id} hover>
|
||||||
<div>
|
<div>
|
||||||
<Link
|
<Link
|
||||||
href={`/${organizationSlug}/${projectId}/dashboards/${item.id}`}
|
href={`/${organizationId}/${projectId}/dashboards/${item.id}`}
|
||||||
className="flex flex-col p-4 @container"
|
className="flex flex-col p-4 @container"
|
||||||
>
|
>
|
||||||
<div className="col gap-2">
|
<div className="col gap-2">
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import Events from './events';
|
|||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
organizationSlug: string;
|
|
||||||
};
|
};
|
||||||
searchParams: Record<string, string>;
|
searchParams: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function LayoutOrganizationSelector({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const organization = organizations.find(
|
const organization = organizations.find(
|
||||||
(item) => item.id === params.organizationSlug,
|
(item) => item.id === params.organizationId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ import {
|
|||||||
} from '@/components/ui/dropdown-menu';
|
} from '@/components/ui/dropdown-menu';
|
||||||
import { useAppParams } from '@/hooks/useAppParams';
|
import { useAppParams } from '@/hooks/useAppParams';
|
||||||
import { pushModal } from '@/modals';
|
import { pushModal } from '@/modals';
|
||||||
import { cn } from '@/utils/cn';
|
|
||||||
import {
|
import {
|
||||||
Building2Icon,
|
Building2Icon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
ChevronsUpDown,
|
|
||||||
ChevronsUpDownIcon,
|
ChevronsUpDownIcon,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
@@ -27,12 +25,12 @@ import { useState } from 'react';
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
getCurrentOrganizations,
|
getCurrentOrganizations,
|
||||||
getProjectsByOrganizationSlug,
|
getProjectsByOrganizationId,
|
||||||
} from '@openpanel/db';
|
} from '@openpanel/db';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
interface LayoutProjectSelectorProps {
|
interface LayoutProjectSelectorProps {
|
||||||
projects: Awaited<ReturnType<typeof getProjectsByOrganizationSlug>>;
|
projects: Awaited<ReturnType<typeof getProjectsByOrganizationId>>;
|
||||||
organizations?: Awaited<ReturnType<typeof getCurrentOrganizations>>;
|
organizations?: Awaited<ReturnType<typeof getCurrentOrganizations>>;
|
||||||
align?: 'start' | 'end';
|
align?: 'start' | 'end';
|
||||||
}
|
}
|
||||||
@@ -42,22 +40,22 @@ export default function LayoutProjectSelector({
|
|||||||
align = 'start',
|
align = 'start',
|
||||||
}: LayoutProjectSelectorProps) {
|
}: LayoutProjectSelectorProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { organizationSlug, projectId } = useAppParams();
|
const { organizationId, projectId } = useAppParams();
|
||||||
const pathname = usePathname() || '';
|
const pathname = usePathname() || '';
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const changeProject = (newProjectId: string) => {
|
const changeProject = (newProjectId: string) => {
|
||||||
if (organizationSlug && projectId) {
|
if (organizationId && projectId) {
|
||||||
const split = pathname
|
const split = pathname
|
||||||
.replace(
|
.replace(
|
||||||
`/${organizationSlug}/${projectId}`,
|
`/${organizationId}/${projectId}`,
|
||||||
`/${organizationSlug}/${newProjectId}`,
|
`/${organizationId}/${newProjectId}`,
|
||||||
)
|
)
|
||||||
.split('/');
|
.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(`/${organizationSlug}/${newProjectId}`);
|
router.push(`/${organizationId}/${newProjectId}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,7 +100,7 @@ export default function LayoutProjectSelector({
|
|||||||
))}
|
))}
|
||||||
{projects.length > 10 && (
|
{projects.length > 10 && (
|
||||||
<DropdownMenuItem asChild>
|
<DropdownMenuItem asChild>
|
||||||
<Link href={`/${organizationSlug}`}>All projects</Link>
|
<Link href={`/${organizationId}`}>All projects</Link>
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -126,7 +124,7 @@ export default function LayoutProjectSelector({
|
|||||||
onClick={() => changeOrganization(organization.id)}
|
onClick={() => changeOrganization(organization.id)}
|
||||||
>
|
>
|
||||||
{organization.name}
|
{organization.name}
|
||||||
{organization.id === organizationSlug && (
|
{organization.id === organizationId && (
|
||||||
<DropdownMenuShortcut>
|
<DropdownMenuShortcut>
|
||||||
<CheckIcon size={16} />
|
<CheckIcon size={16} />
|
||||||
</DropdownMenuShortcut>
|
</DropdownMenuShortcut>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import type {
|
import type {
|
||||||
IServiceDashboards,
|
IServiceDashboards,
|
||||||
IServiceOrganization,
|
IServiceOrganization,
|
||||||
getProjectsByOrganizationSlug,
|
getProjectsByOrganizationId,
|
||||||
} from '@openpanel/db';
|
} from '@openpanel/db';
|
||||||
|
|
||||||
import LayoutMenu from './layout-menu';
|
import LayoutMenu from './layout-menu';
|
||||||
@@ -20,9 +20,8 @@ import LayoutProjectSelector from './layout-project-selector';
|
|||||||
interface LayoutSidebarProps {
|
interface LayoutSidebarProps {
|
||||||
organizations: IServiceOrganization[];
|
organizations: IServiceOrganization[];
|
||||||
dashboards: IServiceDashboards;
|
dashboards: IServiceDashboards;
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
projects: Awaited<ReturnType<typeof getProjectsByOrganizationSlug>>;
|
projects: Awaited<ReturnType<typeof getProjectsByOrganizationId>>;
|
||||||
}
|
}
|
||||||
export function LayoutSidebar({
|
export function LayoutSidebar({
|
||||||
organizations,
|
organizations,
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ import SideEffects from './side-effects';
|
|||||||
interface AppLayoutProps {
|
interface AppLayoutProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function AppLayout({
|
export default async function AppLayout({
|
||||||
children,
|
children,
|
||||||
params: { organizationSlug, projectId },
|
params: { organizationId, projectId },
|
||||||
}: AppLayoutProps) {
|
}: AppLayoutProps) {
|
||||||
const [organizations, projects, dashboards] = await Promise.all([
|
const [organizations, projects, dashboards] = await Promise.all([
|
||||||
getCurrentOrganizations(),
|
getCurrentOrganizations(),
|
||||||
getCurrentProjects(organizationSlug),
|
getCurrentProjects(organizationId),
|
||||||
getDashboardsByProjectId(projectId),
|
getDashboardsByProjectId(projectId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!organizations.find((item) => item.id === organizationSlug)) {
|
if (!organizations.find((item) => item.id === organizationId)) {
|
||||||
return (
|
return (
|
||||||
<FullPageEmptyState title="Not found" className="min-h-screen">
|
<FullPageEmptyState title="Not found" className="min-h-screen">
|
||||||
The organization you were looking for could not be found.
|
The organization you were looking for could not be found.
|
||||||
@@ -48,7 +48,7 @@ export default async function AppLayout({
|
|||||||
<div id="dashboard">
|
<div id="dashboard">
|
||||||
<LayoutSidebar
|
<LayoutSidebar
|
||||||
{...{
|
{...{
|
||||||
organizationSlug,
|
organizationId,
|
||||||
projectId,
|
projectId,
|
||||||
organizations,
|
organizations,
|
||||||
projects,
|
projects,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { OverviewReportRange } from './overview-sticky-header';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import ClickToCopy from '@/components/click-to-copy';
|
import ClickToCopy from '@/components/click-to-copy';
|
||||||
import { ListPropertiesIcon } from '@/components/events/list-properties-icon';
|
|
||||||
import { ProfileAvatar } from '@/components/profiles/profile-avatar';
|
import { ProfileAvatar } from '@/components/profiles/profile-avatar';
|
||||||
import { Padding } from '@/components/ui/padding';
|
import { Padding } from '@/components/ui/padding';
|
||||||
import { getProfileName } from '@/utils/getters';
|
import { getProfileName } from '@/utils/getters';
|
||||||
@@ -16,7 +15,6 @@ import ProfileMetrics from './profile-metrics';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
profileId: string;
|
profileId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import Profiles from './profiles';
|
|||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
organizationSlug: string;
|
|
||||||
};
|
};
|
||||||
searchParams: Record<string, string>;
|
searchParams: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import RealtimeReloader from './realtime-reloader';
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ interface Props {
|
|||||||
|
|
||||||
export default function CreateInvite({ projects }: Props) {
|
export default function CreateInvite({ projects }: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { organizationSlug } = useAppParams();
|
const { organizationId } = useAppParams();
|
||||||
|
|
||||||
const { register, handleSubmit, formState, reset, control } = useForm<IForm>({
|
const { register, handleSubmit, formState, reset, control } = useForm<IForm>({
|
||||||
resolver: zodResolver(zInviteUser),
|
resolver: zodResolver(zInviteUser),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
organizationSlug,
|
organizationId,
|
||||||
access: [],
|
access: [],
|
||||||
role: 'org:member',
|
role: 'org:member',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { TableButtons } from '@/components/data-table';
|
import { TableButtons } from '@/components/data-table';
|
||||||
import { InvitesTable } from '@/components/settings/invites';
|
import { InvitesTable } from '@/components/settings/invites';
|
||||||
|
|
||||||
import { getInvites, getProjectsByOrganizationSlug } from '@openpanel/db';
|
import { getInvites, getProjectsByOrganizationId } from '@openpanel/db';
|
||||||
|
|
||||||
import CreateInvite from './create-invite';
|
import CreateInvite from './create-invite';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InvitesServer = async ({ organizationSlug }: Props) => {
|
const InvitesServer = async ({ organizationId }: Props) => {
|
||||||
const [invites, projects] = await Promise.all([
|
const [invites, projects] = await Promise.all([
|
||||||
getInvites(organizationSlug),
|
getInvites(organizationId),
|
||||||
getProjectsByOrganizationSlug(organizationSlug),
|
getProjectsByOrganizationId(organizationId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { MembersTable } from '@/components/settings/members';
|
import { MembersTable } from '@/components/settings/members';
|
||||||
|
|
||||||
import { getMembers, getProjectsByOrganizationSlug } from '@openpanel/db';
|
import { getMembers, getProjectsByOrganizationId } from '@openpanel/db';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MembersServer = async ({ organizationSlug }: Props) => {
|
const MembersServer = async ({ organizationId }: Props) => {
|
||||||
const [members, projects] = await Promise.all([
|
const [members, projects] = await Promise.all([
|
||||||
getMembers(organizationSlug),
|
getMembers(organizationId),
|
||||||
getProjectsByOrganizationSlug(organizationSlug),
|
getProjectsByOrganizationId(organizationId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <MembersTable data={members} projects={projects} />;
|
return <MembersTable data={members} projects={projects} />;
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ import MembersServer from './members';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
};
|
};
|
||||||
searchParams: Record<string, string>;
|
searchParams: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Page({
|
export default async function Page({
|
||||||
params: { organizationSlug },
|
params: { organizationId },
|
||||||
searchParams,
|
searchParams,
|
||||||
}: PageProps) {
|
}: PageProps) {
|
||||||
const tab = parseAsStringEnum(['org', 'members', 'invites'])
|
const tab = parseAsStringEnum(['org', 'members', 'invites'])
|
||||||
@@ -29,7 +29,7 @@ export default async function Page({
|
|||||||
const session = auth();
|
const session = auth();
|
||||||
const organization = await db.organization.findUnique({
|
const organization = await db.organization.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: organizationSlug,
|
id: organizationId,
|
||||||
members: {
|
members: {
|
||||||
some: {
|
some: {
|
||||||
userId: session.userId,
|
userId: session.userId,
|
||||||
@@ -80,12 +80,8 @@ export default async function Page({
|
|||||||
</PageTabs>
|
</PageTabs>
|
||||||
|
|
||||||
{tab === 'org' && <EditOrganization organization={organization} />}
|
{tab === 'org' && <EditOrganization organization={organization} />}
|
||||||
{tab === 'members' && (
|
{tab === 'members' && <MembersServer organizationId={organizationId} />}
|
||||||
<MembersServer organizationSlug={organizationSlug} />
|
{tab === 'invites' && <InvitesServer organizationId={organizationId} />}
|
||||||
)}
|
|
||||||
{tab === 'invites' && (
|
|
||||||
<InvitesServer organizationSlug={organizationSlug} />
|
|
||||||
)}
|
|
||||||
</Padding>
|
</Padding>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
import PageLayout from '@/app/(app)/[organizationSlug]/[projectId]/page-layout';
|
|
||||||
import { Padding } from '@/components/ui/padding';
|
import { Padding } from '@/components/ui/padding';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getClientsByOrganizationSlug,
|
getClientsByOrganizationId,
|
||||||
getProjectsByOrganizationSlug,
|
getProjectsByOrganizationId,
|
||||||
} from '@openpanel/db';
|
} from '@openpanel/db';
|
||||||
|
|
||||||
import ListProjects from './list-projects';
|
import ListProjects from './list-projects';
|
||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Page({
|
export default async function Page({ params: { organizationId } }: PageProps) {
|
||||||
params: { organizationSlug },
|
|
||||||
}: PageProps) {
|
|
||||||
const [projects, clients] = await Promise.all([
|
const [projects, clients] = await Promise.all([
|
||||||
getProjectsByOrganizationSlug(organizationSlug),
|
getProjectsByOrganizationId(organizationId),
|
||||||
getClientsByOrganizationSlug(organizationSlug),
|
getClientsByOrganizationId(organizationId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import ListReferences from './list-references';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,17 @@ import { getCurrentOrganizations, getCurrentProjects } from '@openpanel/db';
|
|||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
params: {
|
params: {
|
||||||
organizationSlug: string;
|
organizationId: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Page({
|
export default async function Page({ params: { organizationId } }: PageProps) {
|
||||||
params: { organizationSlug },
|
|
||||||
}: PageProps) {
|
|
||||||
const [organizations, projects] = await Promise.all([
|
const [organizations, projects] = await Promise.all([
|
||||||
getCurrentOrganizations(),
|
getCurrentOrganizations(),
|
||||||
getCurrentProjects(organizationSlug),
|
getCurrentProjects(organizationId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const organization = organizations.find((org) => org.id === organizationSlug);
|
const organization = organizations.find((org) => org.id === organizationId);
|
||||||
|
|
||||||
if (!organization) {
|
if (!organization) {
|
||||||
return (
|
return (
|
||||||
@@ -35,7 +33,7 @@ export default async function Page({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (projects.length === 1 && projects[0]) {
|
if (projects.length === 1 && projects[0]) {
|
||||||
return redirect(`/${organizationSlug}/${projects[0].id}`);
|
return redirect(`/${organizationId}/${projects[0].id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ type Props = {
|
|||||||
|
|
||||||
const Connect = async ({ params: { projectId } }: Props) => {
|
const Connect = async ({ params: { projectId } }: Props) => {
|
||||||
const orgs = await getCurrentOrganizations();
|
const orgs = await getCurrentOrganizations();
|
||||||
const organizationSlug = orgs[0]?.id;
|
const organizationId = orgs[0]?.id;
|
||||||
if (!organizationSlug) {
|
if (!organizationId) {
|
||||||
throw new Error('No organization found');
|
throw new Error('No organization found');
|
||||||
}
|
}
|
||||||
const project = await getProjectWithClients(projectId);
|
const project = await getProjectWithClients(projectId);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const Verify = ({ project, events }: Props) => {
|
|||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
{!verified && (
|
{!verified && (
|
||||||
<Link
|
<Link
|
||||||
href={`/${project.organizationSlug}/${project.id}`}
|
href={`/${project.organizationId}/${project.id}`}
|
||||||
className=" text-muted-foreground underline"
|
className=" text-muted-foreground underline"
|
||||||
>
|
>
|
||||||
Skip for now
|
Skip for now
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ type Props = {
|
|||||||
|
|
||||||
const Verify = async ({ params: { projectId } }: Props) => {
|
const Verify = async ({ params: { projectId } }: Props) => {
|
||||||
const orgs = await getCurrentOrganizations();
|
const orgs = await getCurrentOrganizations();
|
||||||
const organizationSlug = orgs[0]?.id;
|
const organizationId = orgs[0]?.id;
|
||||||
if (!organizationSlug) {
|
if (!organizationId) {
|
||||||
throw new Error('No organization found');
|
throw new Error('No organization found');
|
||||||
}
|
}
|
||||||
const [project, events] = await Promise.all([
|
const [project, events] = await Promise.all([
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ const Tracking = ({
|
|||||||
{organizations.length > 0 ? (
|
{organizations.length > 0 ? (
|
||||||
<Controller
|
<Controller
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="organizationSlug"
|
name="organizationId"
|
||||||
render={({ field, formState }) => {
|
render={({ field, formState }) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -109,7 +109,7 @@ const Tracking = ({
|
|||||||
className="w-full"
|
className="w-full"
|
||||||
placeholder="Select workspace"
|
placeholder="Select workspace"
|
||||||
icon={Building}
|
icon={Building}
|
||||||
error={formState.errors.organizationSlug?.message}
|
error={formState.errors.organizationId?.message}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
items={
|
items={
|
||||||
organizations
|
organizations
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { StickyBelowHeader } from '@/app/(app)/[organizationSlug]/[projectId]/layout-sticky-below-header';
|
import { StickyBelowHeader } from '@/app/(app)/[organizationSlug]/[projectId]/layout-sticky-below-header';
|
||||||
import { OverviewReportRange } from '@/app/(app)/[organizationSlug]/[projectId]/overview-sticky-header';
|
import { OverviewReportRange } from '@/app/(app)/[organizationSlug]/[projectId]/overview-sticky-header';
|
||||||
import { Logo } from '@/components/logo';
|
|
||||||
import { OverviewFiltersButtons } from '@/components/overview/filters/overview-filters-buttons';
|
import { OverviewFiltersButtons } from '@/components/overview/filters/overview-filters-buttons';
|
||||||
import ServerLiveCounter from '@/components/overview/live-counter';
|
import ServerLiveCounter from '@/components/overview/live-counter';
|
||||||
import { OverviewLiveHistogram } from '@/components/overview/overview-live-histogram';
|
|
||||||
import OverviewMetrics from '@/components/overview/overview-metrics';
|
import OverviewMetrics from '@/components/overview/overview-metrics';
|
||||||
import OverviewTopDevices from '@/components/overview/overview-top-devices';
|
import OverviewTopDevices from '@/components/overview/overview-top-devices';
|
||||||
import OverviewTopEvents from '@/components/overview/overview-top-events';
|
import OverviewTopEvents from '@/components/overview/overview-top-events';
|
||||||
@@ -35,7 +33,7 @@ export default async function Page({
|
|||||||
return notFound();
|
return notFound();
|
||||||
}
|
}
|
||||||
const projectId = share.projectId;
|
const projectId = share.projectId;
|
||||||
const organization = await getOrganizationBySlug(share.organizationSlug);
|
const organization = await getOrganizationBySlug(share.organizationId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ export async function POST(request: Request) {
|
|||||||
data: access
|
data: access
|
||||||
.filter((a) => typeof a === 'string')
|
.filter((a) => typeof a === 'string')
|
||||||
.map((projectId) => ({
|
.map((projectId) => ({
|
||||||
organizationSlug: membership.organizationId,
|
|
||||||
organizationId: membership.organizationId,
|
organizationId: membership.organizationId,
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@@ -72,7 +71,6 @@ export async function POST(request: Request) {
|
|||||||
data: access
|
data: access
|
||||||
.filter((a): a is string => typeof a === 'string')
|
.filter((a): a is string => typeof a === 'string')
|
||||||
.map((projectId) => ({
|
.map((projectId) => ({
|
||||||
organizationSlug: payload.data.organization.slug,
|
|
||||||
organizationId: payload.data.organization.slug,
|
organizationId: payload.data.organization.slug,
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
userId: payload.data.public_user_data.user_id,
|
userId: payload.data.public_user_data.user_id,
|
||||||
@@ -110,7 +108,7 @@ export async function POST(request: Request) {
|
|||||||
if (payload.type === 'organizationMembership.deleted') {
|
if (payload.type === 'organizationMembership.deleted') {
|
||||||
await db.projectAccess.deleteMany({
|
await db.projectAccess.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug: payload.data.organization.slug,
|
organizationId: payload.data.organization.slug,
|
||||||
userId: payload.data.public_user_data.user_id,
|
userId: payload.data.public_user_data.user_id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { EventIcon } from './event-icon';
|
|||||||
type EventListItemProps = IServiceEventMinimal | IServiceEvent;
|
type EventListItemProps = IServiceEventMinimal | IServiceEvent;
|
||||||
|
|
||||||
export function EventListItem(props: EventListItemProps) {
|
export function EventListItem(props: EventListItemProps) {
|
||||||
const { organizationSlug, projectId } = useAppParams();
|
const { organizationId, projectId } = useAppParams();
|
||||||
const { createdAt, name, path, duration, meta } = props;
|
const { createdAt, name, path, duration, meta } = props;
|
||||||
const profile = 'profile' in props ? props.profile : null;
|
const profile = 'profile' in props ? props.profile : null;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ export function EventListItem(props: EventListItemProps) {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
href={`/${organizationSlug}/${projectId}/profiles/${profile?.id}`}
|
href={`/${organizationId}/${projectId}/profiles/${profile?.id}`}
|
||||||
className="max-w-[80px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground hover:underline"
|
className="max-w-[80px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground hover:underline"
|
||||||
>
|
>
|
||||||
{getProfileName(profile)}
|
{getProfileName(profile)}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ export function ProjectLink({
|
|||||||
className?: string;
|
className?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
}) {
|
}) {
|
||||||
const { organizationSlug, projectId } = useAppParams();
|
const { organizationId, projectId } = useAppParams();
|
||||||
if (typeof props.href === 'string') {
|
if (typeof props.href === 'string') {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
{...props}
|
{...props}
|
||||||
href={`/${organizationSlug}/${projectId}/${props.href.replace(
|
href={`/${organizationId}/${projectId}/${props.href.replace(
|
||||||
/^\//,
|
/^\//,
|
||||||
'',
|
'',
|
||||||
)}`}
|
)}`}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import { TABLE_NAMES, chQuery } from '@openpanel/db';
|
|||||||
import { ChartSSR } from '../chart-ssr';
|
import { ChartSSR } from '../chart-ssr';
|
||||||
import { FadeIn } from '../fade-in';
|
import { FadeIn } from '../fade-in';
|
||||||
|
|
||||||
function ProjectCard({ id, name, organizationSlug }: IServiceProject) {
|
function ProjectCard({ id, name, organizationId }: IServiceProject) {
|
||||||
// For some unknown reason I get when navigating back to this page when using <Link />
|
// For some unknown reason I get when navigating back to this page when using <Link />
|
||||||
// Should be solved: https://github.com/vercel/next.js/issues/61336
|
// Should be solved: https://github.com/vercel/next.js/issues/61336
|
||||||
// But still get the error
|
// But still get the error
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={`/${organizationSlug}/${id}`}
|
href={`/${organizationId}/${id}`}
|
||||||
className="card inline-flex flex-col gap-2 p-4 transition-transform hover:-translate-y-1"
|
className="card inline-flex flex-col gap-2 p-4 transition-transform hover:-translate-y-1"
|
||||||
>
|
>
|
||||||
<div className="font-medium">{name}</div>
|
<div className="font-medium">{name}</div>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ function AccessCell({
|
|||||||
setAccess(newAccess);
|
setAccess(newAccess);
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
userId: row.original.user!.id,
|
userId: row.original.user!.id,
|
||||||
organizationSlug: row.original.organizationId,
|
organizationId: row.original.organizationId,
|
||||||
access: newAccess as string[],
|
access: newAccess as string[],
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
import { useParams } from 'next/navigation';
|
import { useParams } from 'next/navigation';
|
||||||
|
|
||||||
type AppParams = {
|
type AppParams = {
|
||||||
organizationSlug: string;
|
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useAppParams<T>() {
|
export function useAppParams<T>() {
|
||||||
const params = useParams<T & AppParams>();
|
const params = useParams<T & AppParams & { organizationSlug: string }>();
|
||||||
return {
|
return {
|
||||||
...(params ?? {}),
|
...(params ?? {}),
|
||||||
organizationSlug: params?.organizationSlug,
|
|
||||||
organizationId: params?.organizationSlug,
|
organizationId: params?.organizationSlug,
|
||||||
projectId: params?.projectId,
|
projectId: params?.projectId,
|
||||||
} as T & AppParams;
|
} as T & AppParams;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ interface Props {
|
|||||||
projectId: string;
|
projectId: string;
|
||||||
}
|
}
|
||||||
export default function AddClient(props: Props) {
|
export default function AddClient(props: Props) {
|
||||||
const { organizationSlug, projectId } = useAppParams();
|
const { organizationId, projectId } = useAppParams();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const form = useForm<IForm>({
|
const form = useForm<IForm>({
|
||||||
resolver: zodResolver(validation),
|
resolver: zodResolver(validation),
|
||||||
@@ -60,7 +60,7 @@ export default function AddClient(props: Props) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const query = api.project.list.useQuery({
|
const query = api.project.list.useQuery({
|
||||||
organizationSlug,
|
organizationId,
|
||||||
});
|
});
|
||||||
const onSubmit: SubmitHandler<IForm> = (values) => {
|
const onSubmit: SubmitHandler<IForm> = (values) => {
|
||||||
if (hasDomain && values.cors === '') {
|
if (hasDomain && values.cors === '') {
|
||||||
@@ -73,7 +73,7 @@ export default function AddClient(props: Props) {
|
|||||||
name: values.name,
|
name: values.name,
|
||||||
cors: hasDomain ? values.cors : null,
|
cors: hasDomain ? values.cors : null,
|
||||||
projectId: values.projectId,
|
projectId: values.projectId,
|
||||||
organizationSlug,
|
organizationId,
|
||||||
type: values.type,
|
type: values.type,
|
||||||
crossDomain: values.crossDomain,
|
crossDomain: values.crossDomain,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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, organizationSlug } = useAppParams();
|
const { projectId, organizationId } = useAppParams();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { register, handleSubmit, formState } = useForm<IForm>({
|
const { register, handleSubmit, formState } = useForm<IForm>({
|
||||||
@@ -32,7 +32,7 @@ export default function AddDashboard() {
|
|||||||
const mutation = api.dashboard.create.useMutation({
|
const mutation = api.dashboard.create.useMutation({
|
||||||
onError: handleError,
|
onError: handleError,
|
||||||
onSuccess(res) {
|
onSuccess(res) {
|
||||||
router.push(`/${organizationSlug}/${projectId}/dashboards/${res.id}`);
|
router.push(`/${organizationId}/${projectId}/dashboards/${res.id}`);
|
||||||
toast('Success', {
|
toast('Success', {
|
||||||
description: 'Dashboard created.',
|
description: 'Dashboard created.',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const validator = z.object({
|
|||||||
type IForm = z.infer<typeof validator>;
|
type IForm = z.infer<typeof validator>;
|
||||||
|
|
||||||
export default function AddProject() {
|
export default function AddProject() {
|
||||||
const { organizationSlug } = useAppParams();
|
const { organizationId } = useAppParams();
|
||||||
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() {
|
|||||||
onSubmit={handleSubmit((values) => {
|
onSubmit={handleSubmit((values) => {
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
...values,
|
...values,
|
||||||
organizationSlug,
|
organizationId,
|
||||||
});
|
});
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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 { organizationSlug, projectId } = useAppParams();
|
const { organizationId, projectId } = useAppParams();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const dashboardId = searchParams?.get('dashboardId') ?? undefined;
|
const dashboardId = searchParams?.get('dashboardId') ?? undefined;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export default function SaveReport({ report }: SaveReportProps) {
|
|||||||
});
|
});
|
||||||
popModal();
|
popModal();
|
||||||
router.push(
|
router.push(
|
||||||
`/${organizationSlug}/${projectId}/reports/${
|
`/${organizationId}/${projectId}/reports/${
|
||||||
res.id
|
res.id
|
||||||
}?${searchParams?.toString()}`,
|
}?${searchParams?.toString()}`,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ 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, organizationSlug } = useAppParams();
|
const { projectId, organizationId } = useAppParams();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const { register, handleSubmit, control } = useForm<IForm>({
|
const { register, handleSubmit, control } = useForm<IForm>({
|
||||||
@@ -29,7 +29,7 @@ export default function ShareOverviewModal() {
|
|||||||
public: true,
|
public: true,
|
||||||
password: '',
|
password: '',
|
||||||
projectId,
|
projectId,
|
||||||
organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -74,13 +74,12 @@ model Member {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Project {
|
model Project {
|
||||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||||
name String
|
name String
|
||||||
organizationSlug String
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id])
|
organizationId String
|
||||||
organizationId String?
|
eventsCount Int @default(0)
|
||||||
eventsCount Int @default(0)
|
types ProjectType[] @default([])
|
||||||
types ProjectType[] @default([])
|
|
||||||
|
|
||||||
events Event[]
|
events Event[]
|
||||||
profiles Profile[]
|
profiles Profile[]
|
||||||
@@ -108,17 +107,16 @@ enum AccessLevel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model ProjectAccess {
|
model ProjectAccess {
|
||||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||||
projectId String
|
projectId String
|
||||||
project Project @relation(fields: [projectId], references: [id])
|
project Project @relation(fields: [projectId], references: [id])
|
||||||
organizationSlug String
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id])
|
organizationId String
|
||||||
organizationId String?
|
userId String
|
||||||
userId String
|
user User @relation(fields: [userId], references: [id])
|
||||||
user User @relation(fields: [userId], references: [id])
|
level AccessLevel
|
||||||
level AccessLevel
|
createdAt DateTime @default(now())
|
||||||
createdAt DateTime @default(now())
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
@@map("project_access")
|
@@map("project_access")
|
||||||
}
|
}
|
||||||
@@ -169,17 +167,16 @@ enum ClientType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Client {
|
model Client {
|
||||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||||
name String
|
name String
|
||||||
secret String?
|
secret String?
|
||||||
type ClientType @default(write)
|
type ClientType @default(write)
|
||||||
projectId String?
|
projectId String?
|
||||||
project Project? @relation(fields: [projectId], references: [id])
|
project Project? @relation(fields: [projectId], references: [id])
|
||||||
organizationSlug String
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id])
|
organizationId String
|
||||||
organizationId String?
|
cors String?
|
||||||
cors String?
|
crossDomain Boolean @default(false)
|
||||||
crossDomain Boolean @default(false)
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
@@ -208,14 +205,13 @@ enum ChartType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Dashboard {
|
model Dashboard {
|
||||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||||
name String
|
name String
|
||||||
organizationSlug String
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id])
|
organizationId String
|
||||||
organizationId String?
|
projectId String
|
||||||
projectId String
|
project Project @relation(fields: [projectId], references: [id])
|
||||||
project Project @relation(fields: [projectId], references: [id])
|
reports Report[]
|
||||||
reports Report[]
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
@@ -269,16 +265,15 @@ model Waitlist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model ShareOverview {
|
model ShareOverview {
|
||||||
id String @unique
|
id String @unique
|
||||||
projectId String @unique
|
projectId String @unique
|
||||||
project Project @relation(fields: [projectId], references: [id])
|
project Project @relation(fields: [projectId], references: [id])
|
||||||
organizationSlug String
|
organization Organization @relation(fields: [organizationId], references: [id])
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id])
|
organizationId String
|
||||||
organizationId String?
|
public Boolean @default(false)
|
||||||
public Boolean @default(false)
|
password String?
|
||||||
password String?
|
createdAt DateTime @default(now())
|
||||||
createdAt DateTime @default(now())
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
|
|
||||||
@@map("shares")
|
@@map("shares")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ export type IServiceClientWithProject = Prisma.ClientGetPayload<{
|
|||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export async function getClientsByOrganizationSlug(organizationSlug: string) {
|
export async function getClientsByOrganizationId(organizationId: string) {
|
||||||
return db.client.findMany({
|
return db.client.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
project: true,
|
project: true,
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ export async function getOrganizationByProjectId(projectId: string) {
|
|||||||
return transformOrganization(project.organization);
|
return transformOrganization(project.organization);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getInvites(organizationSlug: string) {
|
export async function getInvites(organizationId: string) {
|
||||||
return db.member.findMany({
|
return db.member.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationId: organizationSlug,
|
organizationId,
|
||||||
userId: null,
|
userId: null,
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
@@ -78,11 +78,11 @@ export async function getInvites(organizationSlug: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMembers(organizationSlug: string) {
|
export async function getMembers(organizationId: string) {
|
||||||
const [members, access] = await Promise.all([
|
const [members, access] = await Promise.all([
|
||||||
db.member.findMany({
|
db.member.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationId: organizationSlug,
|
organizationId,
|
||||||
userId: {
|
userId: {
|
||||||
not: null,
|
not: null,
|
||||||
},
|
},
|
||||||
@@ -93,7 +93,7 @@ export async function getMembers(organizationSlug: string) {
|
|||||||
}),
|
}),
|
||||||
db.projectAccess.findMany({
|
db.projectAccess.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@@ -104,10 +104,10 @@ export async function getMembers(organizationSlug: string) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMember(organizationSlug: string, userId: string) {
|
export async function getMember(organizationId: string, userId: string) {
|
||||||
return db.member.findFirst({
|
return db.member.findFirst({
|
||||||
where: {
|
where: {
|
||||||
organizationId: organizationSlug,
|
organizationId,
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ export async function getProjectWithClients(id: string) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getProjectsByOrganizationSlug(organizationSlug: string) {
|
export async function getProjectsByOrganizationId(organizationId: string) {
|
||||||
return db.project.findMany({
|
return db.project.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: 'desc',
|
createdAt: 'desc',
|
||||||
@@ -55,7 +55,7 @@ export async function getProjectsByOrganizationSlug(organizationSlug: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCurrentProjects(organizationSlug: string) {
|
export async function getCurrentProjects(organizationId: string) {
|
||||||
const session = auth();
|
const session = auth();
|
||||||
if (!session.userId) {
|
if (!session.userId) {
|
||||||
return [];
|
return [];
|
||||||
@@ -64,7 +64,7 @@ export async function getCurrentProjects(organizationSlug: string) {
|
|||||||
const [projects, members, access] = await Promise.all([
|
const [projects, members, access] = await Promise.all([
|
||||||
db.project.findMany({
|
db.project.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
eventsCount: 'desc',
|
eventsCount: 'desc',
|
||||||
@@ -73,13 +73,13 @@ export async function getCurrentProjects(organizationSlug: string) {
|
|||||||
db.member.findMany({
|
db.member.findMany({
|
||||||
where: {
|
where: {
|
||||||
userId: session.userId,
|
userId: session.userId,
|
||||||
organizationId: organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
db.projectAccess.findMany({
|
db.projectAccess.findMany({
|
||||||
where: {
|
where: {
|
||||||
userId: session.userId,
|
userId: session.userId,
|
||||||
organizationId: organizationSlug,
|
organizationId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export async function getProjectAccess({
|
|||||||
try {
|
try {
|
||||||
// Check if user has access to the project
|
// Check if user has access to the project
|
||||||
const project = await getProjectById(projectId);
|
const project = await getProjectById(projectId);
|
||||||
if (!project?.organizationSlug) {
|
if (!project?.organizationId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,12 +20,12 @@ export async function getProjectAccess({
|
|||||||
db.projectAccess.findMany({
|
db.projectAccess.findMany({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
organizationId: project.organizationSlug,
|
organizationId: project.organizationId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
db.member.findFirst({
|
db.member.findFirst({
|
||||||
where: {
|
where: {
|
||||||
organizationId: project.organizationSlug,
|
organizationId: project.organizationId,
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export const clientRouter = createTRPCRouter({
|
|||||||
z.object({
|
z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
projectId: z.string(),
|
projectId: z.string(),
|
||||||
organizationSlug: z.string(),
|
organizationId: z.string(),
|
||||||
cors: z.string().nullable(),
|
cors: z.string().nullable(),
|
||||||
crossDomain: z.boolean().optional(),
|
crossDomain: z.boolean().optional(),
|
||||||
type: z.enum(['read', 'write', 'root']).optional(),
|
type: z.enum(['read', 'write', 'root']).optional(),
|
||||||
@@ -55,8 +55,7 @@ export const clientRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const secret = `sec_${crypto.randomBytes(10).toString('hex')}`;
|
const secret = `sec_${crypto.randomBytes(10).toString('hex')}`;
|
||||||
const data: Prisma.ClientCreateArgs['data'] = {
|
const data: Prisma.ClientCreateArgs['data'] = {
|
||||||
organizationSlug: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
organizationId: input.organizationSlug,
|
|
||||||
projectId: input.projectId,
|
projectId: input.projectId,
|
||||||
name: input.name,
|
name: input.name,
|
||||||
type: input.type ?? 'write',
|
type: input.type ?? 'write',
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ export const dashboardRouter = createTRPCRouter({
|
|||||||
data: {
|
data: {
|
||||||
id: await getId('dashboard', input.name),
|
id: await getId('dashboard', input.name),
|
||||||
projectId: input.projectId,
|
projectId: input.projectId,
|
||||||
organizationSlug: project.organizationId!,
|
|
||||||
organizationId: project.organizationId,
|
organizationId: project.organizationId,
|
||||||
name: input.name,
|
name: input.name,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ async function createOrGetOrganization(
|
|||||||
input: z.infer<typeof zOnboardingProject>,
|
input: z.infer<typeof zOnboardingProject>,
|
||||||
userId: string,
|
userId: string,
|
||||||
) {
|
) {
|
||||||
if (input.organizationSlug) {
|
if (input.organizationId) {
|
||||||
return await getOrganizationBySlug(input.organizationSlug);
|
return await getOrganizationBySlug(input.organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.organization) {
|
if (input.organization) {
|
||||||
@@ -92,7 +92,6 @@ export const onboardingRouter = createTRPCRouter({
|
|||||||
data: {
|
data: {
|
||||||
id: await getId('project', input.project),
|
id: await getId('project', input.project),
|
||||||
name: input.project,
|
name: input.project,
|
||||||
organizationSlug: organization.id,
|
|
||||||
organizationId: organization.id,
|
organizationId: organization.id,
|
||||||
types,
|
types,
|
||||||
},
|
},
|
||||||
@@ -102,7 +101,6 @@ export const onboardingRouter = createTRPCRouter({
|
|||||||
const client = await db.client.create({
|
const client = await db.client.create({
|
||||||
data: {
|
data: {
|
||||||
name: `${project.name} Client`,
|
name: `${project.name} Client`,
|
||||||
organizationSlug: organization.id,
|
|
||||||
organizationId: organization.id,
|
organizationId: organization.id,
|
||||||
projectId: project.id,
|
projectId: project.id,
|
||||||
type: 'write',
|
type: 'write',
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const organizationRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const access = await getOrganizationAccess({
|
const access = await getOrganizationAccess({
|
||||||
userId: ctx.session.userId,
|
userId: ctx.session.userId,
|
||||||
organizationId: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (access?.role !== 'org:admin') {
|
if (access?.role !== 'org:admin') {
|
||||||
@@ -72,7 +72,7 @@ export const organizationRouter = createTRPCRouter({
|
|||||||
return db.member.create({
|
return db.member.create({
|
||||||
data: {
|
data: {
|
||||||
email,
|
email,
|
||||||
organizationId: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
role: input.role,
|
role: input.role,
|
||||||
invitedById: ctx.session.userId,
|
invitedById: ctx.session.userId,
|
||||||
meta: {
|
meta: {
|
||||||
@@ -175,7 +175,7 @@ export const organizationRouter = createTRPCRouter({
|
|||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
organizationSlug: z.string(),
|
organizationId: z.string(),
|
||||||
access: z.array(z.string()),
|
access: z.array(z.string()),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -186,7 +186,7 @@ export const organizationRouter = createTRPCRouter({
|
|||||||
|
|
||||||
const access = await getOrganizationAccess({
|
const access = await getOrganizationAccess({
|
||||||
userId: ctx.session.userId,
|
userId: ctx.session.userId,
|
||||||
organizationId: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (access?.role !== 'org:admin') {
|
if (access?.role !== 'org:admin') {
|
||||||
@@ -197,14 +197,13 @@ export const organizationRouter = createTRPCRouter({
|
|||||||
db.projectAccess.deleteMany({
|
db.projectAccess.deleteMany({
|
||||||
where: {
|
where: {
|
||||||
userId: input.userId,
|
userId: input.userId,
|
||||||
organizationId: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
db.projectAccess.createMany({
|
db.projectAccess.createMany({
|
||||||
data: input.access.map((projectId) => ({
|
data: input.access.map((projectId) => ({
|
||||||
userId: input.userId,
|
userId: input.userId,
|
||||||
organizationSlug: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
organizationId: input.organizationSlug,
|
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
level: 'read',
|
level: 'read',
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
db,
|
db,
|
||||||
getId,
|
getId,
|
||||||
getProjectByIdCached,
|
getProjectByIdCached,
|
||||||
getProjectsByOrganizationSlug,
|
getProjectsByOrganizationId,
|
||||||
} from '@openpanel/db';
|
} from '@openpanel/db';
|
||||||
|
|
||||||
import { getProjectAccess } from '../access';
|
import { getProjectAccess } from '../access';
|
||||||
@@ -15,12 +15,12 @@ export const projectRouter = createTRPCRouter({
|
|||||||
list: protectedProcedure
|
list: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
organizationSlug: z.string().nullable(),
|
organizationId: z.string().nullable(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.query(async ({ input: { organizationSlug } }) => {
|
.query(async ({ input: { organizationId } }) => {
|
||||||
if (organizationSlug === null) return [];
|
if (organizationId === null) return [];
|
||||||
return getProjectsByOrganizationSlug(organizationSlug);
|
return getProjectsByOrganizationId(organizationId);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
update: protectedProcedure
|
update: protectedProcedure
|
||||||
@@ -54,15 +54,14 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
organizationSlug: z.string(),
|
organizationId: z.string(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.mutation(async ({ input: { name, organizationSlug } }) => {
|
.mutation(async ({ input: { name, organizationId } }) => {
|
||||||
return db.project.create({
|
return db.project.create({
|
||||||
data: {
|
data: {
|
||||||
id: await getId('project', name),
|
id: await getId('project', name),
|
||||||
organizationSlug: organizationSlug,
|
organizationId,
|
||||||
organizationId: organizationSlug,
|
|
||||||
name: name,
|
name: name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ export const shareRouter = createTRPCRouter({
|
|||||||
},
|
},
|
||||||
create: {
|
create: {
|
||||||
id: uid.rnd(),
|
id: uid.rnd(),
|
||||||
organizationSlug: input.organizationSlug,
|
organizationId: input.organizationId,
|
||||||
organizationId: input.organizationSlug,
|
|
||||||
projectId: input.projectId,
|
projectId: input.projectId,
|
||||||
public: input.public,
|
public: input.public,
|
||||||
password: input.password || null,
|
password: input.password || null,
|
||||||
|
|||||||
@@ -88,17 +88,6 @@ const enforceAccess = t.middleware(async ({ ctx, next, rawInput }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has('organizationSlug', rawInput)) {
|
|
||||||
const access = await getOrganizationAccessCached({
|
|
||||||
userId: ctx.session.userId!,
|
|
||||||
organizationId: rawInput.organizationSlug as string,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!access) {
|
|
||||||
throw TRPCAccessError('You do not have access to this organization');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ export const zReportInput = zChartInput.extend({
|
|||||||
|
|
||||||
export const zInviteUser = z.object({
|
export const zInviteUser = z.object({
|
||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
organizationSlug: z.string(),
|
organizationId: z.string(),
|
||||||
role: z.enum(['org:admin', 'org:member']),
|
role: z.enum(['org:admin', 'org:member']),
|
||||||
access: z.array(z.string()),
|
access: z.array(z.string()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const zShareOverview = z.object({
|
export const zShareOverview = z.object({
|
||||||
organizationSlug: z.string(),
|
organizationId: z.string(),
|
||||||
projectId: z.string(),
|
projectId: z.string(),
|
||||||
password: z.string().nullable(),
|
password: z.string().nullable(),
|
||||||
public: z.boolean(),
|
public: z.boolean(),
|
||||||
@@ -110,7 +110,7 @@ export const zCreateReference = z.object({
|
|||||||
export const zOnboardingProject = z
|
export const zOnboardingProject = z
|
||||||
.object({
|
.object({
|
||||||
organization: z.string().optional(),
|
organization: z.string().optional(),
|
||||||
organizationSlug: z.string().optional(),
|
organizationId: z.string().optional(),
|
||||||
project: z.string().min(3),
|
project: z.string().min(3),
|
||||||
domain: z.string().url().or(z.literal('').or(z.null())),
|
domain: z.string().url().or(z.literal('').or(z.null())),
|
||||||
website: z.boolean(),
|
website: z.boolean(),
|
||||||
@@ -118,7 +118,7 @@ export const zOnboardingProject = z
|
|||||||
backend: z.boolean(),
|
backend: z.boolean(),
|
||||||
})
|
})
|
||||||
.superRefine((data, ctx) => {
|
.superRefine((data, ctx) => {
|
||||||
if (!data.organization && !data.organizationSlug) {
|
if (!data.organization && !data.organizationId) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: 'custom',
|
code: 'custom',
|
||||||
message: 'Organization is required',
|
message: 'Organization is required',
|
||||||
@@ -127,7 +127,7 @@ export const zOnboardingProject = z
|
|||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: 'custom',
|
code: 'custom',
|
||||||
message: 'Organization is required',
|
message: 'Organization is required',
|
||||||
path: ['organizationSlug'],
|
path: ['organizationId'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
155
pnpm-lock.yaml
generated
155
pnpm-lock.yaml
generated
@@ -1013,14 +1013,14 @@ importers:
|
|||||||
specifier: 1.0.1-local
|
specifier: 1.0.1-local
|
||||||
version: link:../web
|
version: link:../web
|
||||||
next:
|
next:
|
||||||
specifier: ^12.0.0 || ^13.0.0 || ^14.0.0
|
specifier: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0
|
||||||
version: 14.1.0(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0)
|
version: 15.0.3(@opentelemetry/api@1.8.0)(react-dom@18.3.1)(react@18.3.1)
|
||||||
react:
|
react:
|
||||||
specifier: ^16.8.0 || ^17.0.0 || ^18.0.0
|
specifier: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
version: 18.2.0
|
version: 18.3.1
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^16.8.0 || ^17.0.0 || ^18.0.0
|
specifier: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
version: 18.2.0(react@18.2.0)
|
version: 18.3.1(react@18.3.1)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@openpanel/tsconfig':
|
'@openpanel/tsconfig':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
@@ -3809,7 +3809,7 @@ packages:
|
|||||||
getenv: 1.0.0
|
getenv: 1.0.0
|
||||||
glob: 7.1.6
|
glob: 7.1.6
|
||||||
resolve-from: 5.0.0
|
resolve-from: 5.0.0
|
||||||
semver: 7.6.0
|
semver: 7.6.3
|
||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
slugify: 1.6.6
|
slugify: 1.6.6
|
||||||
xcode: 3.0.1
|
xcode: 3.0.1
|
||||||
@@ -4905,10 +4905,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/env@14.1.0:
|
|
||||||
resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@next/env@14.2.1:
|
/@next/env@14.2.1:
|
||||||
resolution: {integrity: sha512-qsHJle3GU3CmVx7pUoXcghX4sRN+vINkbLdH611T8ZlsP//grzqVW87BSUgOZeSAD4q7ZdZicdwNe/20U2janA==}
|
resolution: {integrity: sha512-qsHJle3GU3CmVx7pUoXcghX4sRN+vINkbLdH611T8ZlsP//grzqVW87BSUgOZeSAD4q7ZdZicdwNe/20U2janA==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -4923,15 +4919,6 @@ packages:
|
|||||||
glob: 7.1.7
|
glob: 7.1.7
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@next/swc-darwin-arm64@14.1.0:
|
|
||||||
resolution: {integrity: sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [darwin]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-darwin-arm64@14.2.1:
|
/@next/swc-darwin-arm64@14.2.1:
|
||||||
resolution: {integrity: sha512-kGjnjcIJehEcd3rT/3NAATJQndAEELk0J9GmGMXHSC75TMnvpOhONcjNHbjtcWE5HUQnIHy5JVkatrnYm1QhVw==}
|
resolution: {integrity: sha512-kGjnjcIJehEcd3rT/3NAATJQndAEELk0J9GmGMXHSC75TMnvpOhONcjNHbjtcWE5HUQnIHy5JVkatrnYm1QhVw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -4950,15 +4937,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-darwin-x64@14.1.0:
|
|
||||||
resolution: {integrity: sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [darwin]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-darwin-x64@14.2.1:
|
/@next/swc-darwin-x64@14.2.1:
|
||||||
resolution: {integrity: sha512-dAdWndgdQi7BK2WSXrx4lae7mYcOYjbHJUhvOUnJjMNYrmYhxbbvJ2xElZpxNxdfA6zkqagIB9He2tQk+l16ew==}
|
resolution: {integrity: sha512-dAdWndgdQi7BK2WSXrx4lae7mYcOYjbHJUhvOUnJjMNYrmYhxbbvJ2xElZpxNxdfA6zkqagIB9He2tQk+l16ew==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -4977,15 +4955,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-arm64-gnu@14.1.0:
|
|
||||||
resolution: {integrity: sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-linux-arm64-gnu@14.2.1:
|
/@next/swc-linux-arm64-gnu@14.2.1:
|
||||||
resolution: {integrity: sha512-2ZctfnyFOGvTkoD6L+DtQtO3BfFz4CapoHnyLTXkOxbZkVRgg3TQBUjTD/xKrO1QWeydeo8AWfZRg8539qNKrg==}
|
resolution: {integrity: sha512-2ZctfnyFOGvTkoD6L+DtQtO3BfFz4CapoHnyLTXkOxbZkVRgg3TQBUjTD/xKrO1QWeydeo8AWfZRg8539qNKrg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5004,15 +4973,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-arm64-musl@14.1.0:
|
|
||||||
resolution: {integrity: sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-linux-arm64-musl@14.2.1:
|
/@next/swc-linux-arm64-musl@14.2.1:
|
||||||
resolution: {integrity: sha512-jazZXctiaanemy4r+TPIpFP36t1mMwWCKMsmrTRVChRqE6putyAxZA4PDujx0SnfvZHosjdkx9xIq9BzBB5tWg==}
|
resolution: {integrity: sha512-jazZXctiaanemy4r+TPIpFP36t1mMwWCKMsmrTRVChRqE6putyAxZA4PDujx0SnfvZHosjdkx9xIq9BzBB5tWg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5031,15 +4991,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-x64-gnu@14.1.0:
|
|
||||||
resolution: {integrity: sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-linux-x64-gnu@14.2.1:
|
/@next/swc-linux-x64-gnu@14.2.1:
|
||||||
resolution: {integrity: sha512-VjCHWCjsAzQAAo8lkBOLEIkBZFdfW+Z18qcQ056kL4KpUYc8o59JhLDCBlhg+hINQRgzQ2UPGma2AURGOH0+Qg==}
|
resolution: {integrity: sha512-VjCHWCjsAzQAAo8lkBOLEIkBZFdfW+Z18qcQ056kL4KpUYc8o59JhLDCBlhg+hINQRgzQ2UPGma2AURGOH0+Qg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5058,15 +5009,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-x64-musl@14.1.0:
|
|
||||||
resolution: {integrity: sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-linux-x64-musl@14.2.1:
|
/@next/swc-linux-x64-musl@14.2.1:
|
||||||
resolution: {integrity: sha512-7HZKYKvAp4nAHiHIbY04finRqjeYvkITOGOurP1aLMexIFG/1+oCnqhGogBdc4lao/lkMW1c+AkwWSzSlLasqw==}
|
resolution: {integrity: sha512-7HZKYKvAp4nAHiHIbY04finRqjeYvkITOGOurP1aLMexIFG/1+oCnqhGogBdc4lao/lkMW1c+AkwWSzSlLasqw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5085,15 +5027,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-arm64-msvc@14.1.0:
|
|
||||||
resolution: {integrity: sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [win32]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-win32-arm64-msvc@14.2.1:
|
/@next/swc-win32-arm64-msvc@14.2.1:
|
||||||
resolution: {integrity: sha512-YGHklaJ/Cj/F0Xd8jxgj2p8po4JTCi6H7Z3Yics3xJhm9CPIqtl8erlpK1CLv+HInDqEWfXilqatF8YsLxxA2Q==}
|
resolution: {integrity: sha512-YGHklaJ/Cj/F0Xd8jxgj2p8po4JTCi6H7Z3Yics3xJhm9CPIqtl8erlpK1CLv+HInDqEWfXilqatF8YsLxxA2Q==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5112,15 +5045,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-ia32-msvc@14.1.0:
|
|
||||||
resolution: {integrity: sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [ia32]
|
|
||||||
os: [win32]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-win32-ia32-msvc@14.2.1:
|
/@next/swc-win32-ia32-msvc@14.2.1:
|
||||||
resolution: {integrity: sha512-o+ISKOlvU/L43ZhtAAfCjwIfcwuZstiHVXq/BDsZwGqQE0h/81td95MPHliWCnFoikzWcYqh+hz54ZB2FIT8RA==}
|
resolution: {integrity: sha512-o+ISKOlvU/L43ZhtAAfCjwIfcwuZstiHVXq/BDsZwGqQE0h/81td95MPHliWCnFoikzWcYqh+hz54ZB2FIT8RA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -5130,15 +5054,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-x64-msvc@14.1.0:
|
|
||||||
resolution: {integrity: sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [win32]
|
|
||||||
requiresBuild: true
|
|
||||||
dev: false
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@next/swc-win32-x64-msvc@14.2.1:
|
/@next/swc-win32-x64-msvc@14.2.1:
|
||||||
resolution: {integrity: sha512-GmRoTiLcvCLifujlisknv4zu9/C4i9r0ktsA8E51EMqJL4bD4CpO7lDYr7SrUxCR0tS4RVcrqKmCak24T0ohaw==}
|
resolution: {integrity: sha512-GmRoTiLcvCLifujlisknv4zu9/C4i9r0ktsA8E51EMqJL4bD4CpO7lDYr7SrUxCR0tS4RVcrqKmCak24T0ohaw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -8702,7 +8617,7 @@ packages:
|
|||||||
hermes-profile-transformer: 0.0.6
|
hermes-profile-transformer: 0.0.6
|
||||||
node-stream-zip: 1.15.0
|
node-stream-zip: 1.15.0
|
||||||
ora: 5.4.1
|
ora: 5.4.1
|
||||||
semver: 7.6.0
|
semver: 7.6.3
|
||||||
strip-ansi: 5.2.0
|
strip-ansi: 5.2.0
|
||||||
wcwidth: 1.0.1
|
wcwidth: 1.0.1
|
||||||
yaml: 2.3.4
|
yaml: 2.3.4
|
||||||
@@ -8780,7 +8695,7 @@ packages:
|
|||||||
node-fetch: 2.7.0
|
node-fetch: 2.7.0
|
||||||
open: 6.4.0
|
open: 6.4.0
|
||||||
ora: 5.4.1
|
ora: 5.4.1
|
||||||
semver: 7.6.0
|
semver: 7.6.3
|
||||||
shell-quote: 1.8.1
|
shell-quote: 1.8.1
|
||||||
sudo-prompt: 9.2.1
|
sudo-prompt: 9.2.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -8815,7 +8730,7 @@ packages:
|
|||||||
fs-extra: 8.1.0
|
fs-extra: 8.1.0
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
prompts: 2.4.2
|
prompts: 2.4.2
|
||||||
semver: 7.6.0
|
semver: 7.6.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- encoding
|
- encoding
|
||||||
@@ -9430,12 +9345,6 @@ packages:
|
|||||||
tslib: 2.7.0
|
tslib: 2.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@swc/helpers@0.5.2:
|
|
||||||
resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==}
|
|
||||||
dependencies:
|
|
||||||
tslib: 2.7.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@swc/helpers@0.5.5:
|
/@swc/helpers@0.5.5:
|
||||||
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -17202,46 +17111,6 @@ packages:
|
|||||||
react-dom: 18.3.1(react@18.3.1)
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next@14.1.0(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0):
|
|
||||||
resolution: {integrity: sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==}
|
|
||||||
engines: {node: '>=18.17.0'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
'@opentelemetry/api': ^1.1.0
|
|
||||||
react: ^18.2.0
|
|
||||||
react-dom: ^18.2.0
|
|
||||||
sass: ^1.3.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@opentelemetry/api':
|
|
||||||
optional: true
|
|
||||||
sass:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@next/env': 14.1.0
|
|
||||||
'@opentelemetry/api': 1.8.0
|
|
||||||
'@swc/helpers': 0.5.2
|
|
||||||
busboy: 1.6.0
|
|
||||||
caniuse-lite: 1.0.30001596
|
|
||||||
graceful-fs: 4.2.11
|
|
||||||
postcss: 8.4.31
|
|
||||||
react: 18.2.0
|
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
|
||||||
styled-jsx: 5.1.1(react@18.2.0)
|
|
||||||
optionalDependencies:
|
|
||||||
'@next/swc-darwin-arm64': 14.1.0
|
|
||||||
'@next/swc-darwin-x64': 14.1.0
|
|
||||||
'@next/swc-linux-arm64-gnu': 14.1.0
|
|
||||||
'@next/swc-linux-arm64-musl': 14.1.0
|
|
||||||
'@next/swc-linux-x64-gnu': 14.1.0
|
|
||||||
'@next/swc-linux-x64-musl': 14.1.0
|
|
||||||
'@next/swc-win32-arm64-msvc': 14.1.0
|
|
||||||
'@next/swc-win32-ia32-msvc': 14.1.0
|
|
||||||
'@next/swc-win32-x64-msvc': 14.1.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@babel/core'
|
|
||||||
- babel-plugin-macros
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/next@14.2.1(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0):
|
/next@14.2.1(@opentelemetry/api@1.8.0)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-SF3TJnKdH43PMkCcErLPv+x/DY1YCklslk3ZmwaVoyUfDgHKexuKlf9sEfBQ69w+ue8jQ3msLb+hSj1T19hGag==}
|
resolution: {integrity: sha512-SF3TJnKdH43PMkCcErLPv+x/DY1YCklslk3ZmwaVoyUfDgHKexuKlf9sEfBQ69w+ue8jQ3msLb+hSj1T19hGag==}
|
||||||
engines: {node: '>=18.17.0'}
|
engines: {node: '>=18.17.0'}
|
||||||
@@ -20919,7 +20788,7 @@ packages:
|
|||||||
execa: 5.1.1
|
execa: 5.1.1
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
joycon: 3.1.1
|
joycon: 3.1.1
|
||||||
postcss-load-config: 4.0.2(postcss@8.4.35)
|
postcss-load-config: 4.0.2(postcss@8.4.47)
|
||||||
resolve-from: 5.0.0
|
resolve-from: 5.0.0
|
||||||
rollup: 4.12.0
|
rollup: 4.12.0
|
||||||
source-map: 0.8.0-beta.0
|
source-map: 0.8.0-beta.0
|
||||||
@@ -21254,7 +21123,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.0
|
browserslist: 4.23.0
|
||||||
escalade: 3.1.2
|
escalade: 3.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.1.1
|
||||||
|
|
||||||
/update-browserslist-db@1.1.1(browserslist@4.24.2):
|
/update-browserslist-db@1.1.1(browserslist@4.24.2):
|
||||||
resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
|
resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
|
||||||
|
|||||||
Reference in New Issue
Block a user