mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Working on project creation and patch with multiselect.
This commit is contained in:
@@ -1,62 +0,0 @@
|
|||||||
"use server"
|
|
||||||
|
|
||||||
import {userAction} from "@/safe-actions";
|
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema";
|
|
||||||
import {z} from "zod";
|
|
||||||
import {ServerActionResult} from "@/types/action-type";
|
|
||||||
import {Projects} from "@prisma/client";
|
|
||||||
|
|
||||||
|
|
||||||
export const createProjectAction = userAction
|
|
||||||
.schema(
|
|
||||||
z.object({
|
|
||||||
data: ProjectSchema,
|
|
||||||
organizationId: z.string(),
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.action(async ({parsedInput, ctx}): Promise<ServerActionResult<Projects>> => {
|
|
||||||
try {
|
|
||||||
|
|
||||||
const project = await prisma.project.create({
|
|
||||||
data: {
|
|
||||||
name: parsedInput.data.name,
|
|
||||||
slug: parsedInput.data.slug,
|
|
||||||
organizationId: parsedInput.organizationId,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
for (const db of parsedInput.data.databases) {
|
|
||||||
|
|
||||||
await prisma.database.update({
|
|
||||||
where: {
|
|
||||||
id: db,
|
|
||||||
},
|
|
||||||
data:{
|
|
||||||
projectId: project.id,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
value: project,
|
|
||||||
actionSuccess: {
|
|
||||||
message: "Project has been successfully created.",
|
|
||||||
messageParams: {projectName: parsedInput.data.name},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
actionError: {
|
|
||||||
message: "Failed to create Project.",
|
|
||||||
status: 500, // Optional: Use a meaningful status code
|
|
||||||
cause: error instanceof Error ? error.message : "Unknown error",
|
|
||||||
messageParams: {projectName: parsedInput.data.name},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -7,4 +7,4 @@ export const ProjectSchema = z.object({
|
|||||||
databases: z.array(z.string()),
|
databases: z.array(z.string()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ProjectSchema = z.infer<typeof ProjectSchema>;
|
export type ProjectType = z.infer<typeof ProjectSchema>;
|
||||||
|
|||||||
@@ -14,16 +14,18 @@ import {Input} from "@/components/ui/input";
|
|||||||
import {Form} from "@/components/ui/form"
|
import {Form} from "@/components/ui/form"
|
||||||
import {Button} from "@/components/ui/button";
|
import {Button} from "@/components/ui/button";
|
||||||
import {useMutation} from "@tanstack/react-query";
|
import {useMutation} from "@tanstack/react-query";
|
||||||
import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema";
|
import {ProjectSchema, ProjectType} from "@/components/wrappers/Project/ProjectForm.schema";
|
||||||
import {createProjectAction} from "@/components/wrappers/Project/ProjectForm.action";
|
import {createProjectAction, updateProjectAction} from "@/components/wrappers/Project/project-form.action";
|
||||||
import {useRouter} from "next/navigation";
|
import {useRouter} from "next/navigation";
|
||||||
import {Database, Organization} from "@prisma/client"
|
import {Database, Organization, Project, Projects} from "@prisma/client"
|
||||||
import {MultiSelect} from "@/components/wrappers/MultiSelect/MultiSelect";
|
import {MultiSelect} from "@/components/wrappers/MultiSelect/MultiSelect";
|
||||||
import {ZodString} from "zod";
|
import {ZodString} from "zod";
|
||||||
|
import {toast} from "sonner";
|
||||||
|
import {ServerActionResult} from "@/types/action-type";
|
||||||
|
|
||||||
|
|
||||||
export type projectFormProps = {
|
export type projectFormProps = {
|
||||||
defaultValues?: ProjectSchema;
|
defaultValues?: ProjectType;
|
||||||
databases: Database[],
|
databases: Database[],
|
||||||
organization: Organization,
|
organization: Organization,
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
@@ -43,7 +45,7 @@ export const ProjectForm = (props: projectFormProps) => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatDefaultDatabases = (databases: ProjectSchema["databases"]): string[] => {
|
const formatDefaultDatabases = (databases: ProjectType['databases']): string[] => {
|
||||||
return databases.map(database => database.id);
|
return databases.map(database => database.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,21 +62,18 @@ export const ProjectForm = (props: projectFormProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: async (values: ProjectSchema) => {
|
mutationFn: async (values: ProjectType) => {
|
||||||
console.log(values)
|
console.log(values)
|
||||||
const projectCreated = await createProjectAction({data: values, organizationId: props.organization.id});
|
const project: Projects = isCreate ? await createProjectAction({data: values, organizationId: props.organization.id}) : await updateProjectAction({data: values, organizationId: props.organization.id, projectId: props.projectId});
|
||||||
console.log(projectCreated)
|
console.log(project)
|
||||||
//
|
|
||||||
// if (data) {
|
if (project.data.success) {
|
||||||
// toast.success(`Success`);
|
toast.success(project.data.actionSuccess.message);
|
||||||
// router.push(`/dashboard/projects/${data.id}`);
|
router.push(`/dashboard/projects/${project.data.value.id}`);
|
||||||
// router.refresh()
|
router.refresh()
|
||||||
// }
|
}else{
|
||||||
//
|
toast.success(project.data.actionError.message);
|
||||||
// if (validationErrors) {
|
}
|
||||||
// toast.success(`Error`);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -147,7 +146,7 @@ export const ProjectForm = (props: projectFormProps) => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Button>
|
<Button>
|
||||||
Create Project
|
{isCreate ? `Create Project` : `Update Project`}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
"use server"
|
||||||
|
|
||||||
|
import {userAction} from "@/safe-actions";
|
||||||
|
import {prisma} from "@/prisma";
|
||||||
|
import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema";
|
||||||
|
import {z} from "zod";
|
||||||
|
import {ServerActionResult} from "@/types/action-type";
|
||||||
|
import {Projects} from "@prisma/client";
|
||||||
|
|
||||||
|
|
||||||
|
export const createProjectAction = userAction
|
||||||
|
.schema(
|
||||||
|
z.object({
|
||||||
|
data: ProjectSchema,
|
||||||
|
organizationId: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.action(async ({parsedInput, ctx}): Promise<ServerActionResult<Projects>> => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const project = await prisma.project.create({
|
||||||
|
data: {
|
||||||
|
name: parsedInput.data.name,
|
||||||
|
slug: parsedInput.data.slug,
|
||||||
|
organizationId: parsedInput.organizationId,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const db of parsedInput.data.databases) {
|
||||||
|
|
||||||
|
await prisma.database.update({
|
||||||
|
where: {
|
||||||
|
id: db,
|
||||||
|
},
|
||||||
|
data:{
|
||||||
|
projectId: project.id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
value: project,
|
||||||
|
actionSuccess: {
|
||||||
|
message: "Project has been successfully created.",
|
||||||
|
messageParams: {projectName: parsedInput.data.name},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
actionError: {
|
||||||
|
message: "Failed to create Project.",
|
||||||
|
status: 500, // Optional: Use a meaningful status code
|
||||||
|
cause: error instanceof Error ? error.message : "Unknown error",
|
||||||
|
messageParams: {projectName: parsedInput.data.name},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export const updateProjectAction = userAction
|
||||||
|
.schema(
|
||||||
|
z.object({
|
||||||
|
data: ProjectSchema,
|
||||||
|
organizationId: z.string(),
|
||||||
|
projectId: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.action(async ({parsedInput, ctx}): Promise<ServerActionResult<Projects>> => {
|
||||||
|
try {
|
||||||
|
const newDatabaseList = parsedInput.data.databases
|
||||||
|
const project = await prisma.project.findFirst({
|
||||||
|
where:{
|
||||||
|
id: parsedInput.projectId,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
databases : {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const existingItemIds = project.databases.map((db) => db.id);
|
||||||
|
|
||||||
|
const databasesToAdd = newDatabaseList.filter(
|
||||||
|
(id) => !existingItemIds.includes(id)
|
||||||
|
);
|
||||||
|
const databasesToRemove = existingItemIds.filter(
|
||||||
|
(id) => !newDatabaseList.includes(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(databasesToAdd);
|
||||||
|
console.log(databasesToRemove);
|
||||||
|
|
||||||
|
if (databasesToAdd.length > 0) {
|
||||||
|
await prisma.database.updateMany({
|
||||||
|
where: {
|
||||||
|
id: { in: databasesToAdd },
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
projectId: parsedInput.projectId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (databasesToRemove.length > 0) {
|
||||||
|
await prisma.database.updateMany({
|
||||||
|
where: {
|
||||||
|
id: { in: databasesToRemove },
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
projectId: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedProject = await prisma.project.update({
|
||||||
|
where:{
|
||||||
|
id: parsedInput.projectId
|
||||||
|
},
|
||||||
|
data:{
|
||||||
|
name: parsedInput.data.name,
|
||||||
|
slug: parsedInput.data.slug,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
value: updatedProject,
|
||||||
|
actionSuccess: {
|
||||||
|
message: "Project has been successfully updated.",
|
||||||
|
messageParams: {projectName: parsedInput.data.name},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
actionError: {
|
||||||
|
message: "Failed to update Project.",
|
||||||
|
status: 500, // Optional: Use a meaningful status code
|
||||||
|
cause: error instanceof Error ? error.message : "Unknown error",
|
||||||
|
messageParams: {projectName: parsedInput.data.name},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user