Add schedule management features

- Implemented `HandleSchedules` component for creating and updating schedules with validation.
- Added `ShowSchedules` component to display a list of schedules with options to edit and delete.
- Created API routes for schedule management including create, update, delete, and list functionalities.
- Defined the `schedule` table schema in the database with necessary fields and relationships.
- Integrated schedule management into the application service dashboard, allowing users to manage schedules directly from the UI.
This commit is contained in:
Mauricio Siu
2025-05-02 03:21:13 -06:00
parent 7ae3ff22ee
commit d4064805eb
11 changed files with 5881 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ import { sshRouter } from "./routers/ssh-key";
import { stripeRouter } from "./routers/stripe";
import { swarmRouter } from "./routers/swarm";
import { userRouter } from "./routers/user";
import { scheduleRouter } from "./routers/schedule";
/**
* This is the primary router for your server.
*
@@ -78,6 +79,7 @@ export const appRouter = createTRPCRouter({
swarm: swarmRouter,
ai: aiRouter,
organization: organizationRouter,
schedule: scheduleRouter,
});
// export type definition of API

View File

@@ -0,0 +1,85 @@
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import {
createScheduleSchema,
schedules,
} from "@dokploy/server/db/schema/schedule";
import { eq } from "drizzle-orm";
import { createTRPCRouter, protectedProcedure } from "../trpc";
export const scheduleRouter = createTRPCRouter({
create: protectedProcedure
.input(createScheduleSchema)
.mutation(async ({ ctx, input }) => {
const [schedule] = await ctx.db
.insert(schedules)
.values(input)
.returning();
return schedule;
}),
update: protectedProcedure
.input(createScheduleSchema.extend({ scheduleId: z.string() }))
.mutation(async ({ ctx, input }) => {
const { scheduleId, ...rest } = input;
const [schedule] = await ctx.db
.update(schedules)
.set(rest)
.where(eq(schedules.scheduleId, scheduleId))
.returning();
if (!schedule) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Schedule not found",
});
}
return schedule;
}),
delete: protectedProcedure
.input(z.object({ scheduleId: z.string() }))
.mutation(async ({ ctx, input }) => {
const [schedule] = await ctx.db
.delete(schedules)
.where(eq(schedules.scheduleId, input.scheduleId))
.returning();
if (!schedule) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Schedule not found",
});
}
return schedule;
}),
list: protectedProcedure
.input(z.object({ applicationId: z.string() }))
.query(async ({ ctx, input }) => {
return ctx.db
.select()
.from(schedules)
.where(eq(schedules.applicationId, input.applicationId));
}),
one: protectedProcedure
.input(z.object({ scheduleId: z.string() }))
.query(async ({ ctx, input }) => {
const [schedule] = await ctx.db
.select()
.from(schedules)
.where(eq(schedules.scheduleId, input.scheduleId));
if (!schedule) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Schedule not found",
});
}
return schedule;
}),
});