feat: import cards from trello

This commit is contained in:
Henry
2024-02-26 22:26:45 +00:00
parent 95da7aa5f6
commit ac54348503
9 changed files with 1065 additions and 52 deletions

View File

@@ -8,18 +8,16 @@ export function BoardsList() {
if (data?.length === 0) return <></>;
return (
<>
{data?.map((board) => {
return (
<Link key={board.publicId} href={`boards/${board.publicId}`}>
<div className="align-center mr-5 flex w-72 justify-center rounded-md border border-dashed border-dark-600 bg-dark-100 p-14 hover:bg-dark-200">
<p className="text-md px-4 font-medium text-dark-1000">
{board.name}
</p>
</div>
</Link>
);
})}
</>
<div className="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
{data?.map((board) => (
<Link key={board.publicId} href={`boards/${board.publicId}`}>
<div className="align-center mr-5 flex w-72 justify-center rounded-md border border-dashed border-dark-600 bg-dark-100 p-14 hover:bg-dark-200">
<p className="text-md px-4 font-medium text-dark-1000">
{board.name}
</p>
</div>
</Link>
))}
</div>
);
}

View File

@@ -97,13 +97,37 @@ const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
);
};
interface ImportTrelloProps {
handleSetAuthDetails: (apiKey: string, token: string) => void;
}
const ImportTrello: React.FC = () => {
const utils = api.useUtils();
const [apiKey, setApiKey] = useState("");
const [token, setToken] = useState("");
const { closeModal } = useModal();
const refetchBoards = () => utils.board.all.refetch();
const boards = api.import.trello.getBoards.useQuery(
{ apiKey, token },
{
enabled: apiKey && token ? true : false,
},
);
const handleSetAuthDetails = (apiKey: string, token: string) => {
setApiKey(apiKey);
setToken(token);
};
const importBoards = api.import.trello.importBoards.useMutation({
onSuccess: async () => {
try {
await refetchBoards();
closeModal();
} catch (e) {
console.log(e);
}
},
});
const ImportTrello: React.FC<ImportTrelloProps> = ({
handleSetAuthDetails,
}) => {
const formik = useFormik({
initialValues: {
apiKey: "",
@@ -114,6 +138,72 @@ const ImportTrello: React.FC<ImportTrelloProps> = ({
},
});
const boardsFormik = useFormik({
initialValues: {
...Object.fromEntries(
boards?.data?.map((board) => [board.id, true]) ?? [],
),
},
onSubmit: () => {
const boardIds = Object.keys(boardsFormik.values).filter(
(key) => boardsFormik.values[key] === true,
);
importBoards.mutate({
boardIds,
apiKey: formik.values.apiKey,
token: formik.values.token,
});
},
enableReinitialize: true,
});
if (boards?.data?.length)
return (
<form onSubmit={boardsFormik.handleSubmit}>
<div className="h-[105px] overflow-scroll">
{boards.data.map((board) => (
<div key={board.id}>
<div
className="flex items-center rounded-[5px] p-2 hover:bg-dark-300"
onClick={async (e) => {
e.preventDefault();
await boardsFormik.setFieldValue(
board.id,
!boardsFormik.values[board.id],
);
}}
>
<input
id={board.id}
name={board.id}
type="checkbox"
className="h-[14px] w-[14px] rounded bg-transparent"
onClick={(event) => event.stopPropagation()}
checked={boardsFormik.values[board.id]}
/>
<label
htmlFor={board.id}
className="ml-3 text-sm text-dark-1000"
>
{board.name}
</label>
</div>
</div>
))}
</div>
<div className="mt-5 sm:mt-6">
<button
type="submit"
className="inline-flex w-full justify-center rounded-md bg-dark-1000 px-3 py-2 text-sm font-semibold text-dark-50 shadow-sm focus-visible:outline-none"
>
Import selected
</button>
</div>
</form>
);
return (
<form onSubmit={formik.handleSubmit}>
<label
@@ -155,25 +245,8 @@ const ImportTrello: React.FC<ImportTrelloProps> = ({
};
export function ImportBoardsForm() {
// const utils = api.useUtils();
const { closeModal } = useModal();
const [step, setStep] = useState(1);
const [apiKey, setApiKey] = useState("");
const [token, setToken] = useState("");
const boards = api.import.trello.getBoards.useQuery(
{ apiKey, token },
{
enabled: apiKey && token ? true : false,
},
);
const handleSetAuthDetails = (apiKey: string, token: string) => {
setApiKey(apiKey);
setToken(token);
};
// const refetchBoards = () => utils.board.all.refetch();
return (
<>
@@ -188,9 +261,7 @@ export function ImportBoardsForm() {
</div>
{step === 1 && <SelectSource handleNextStep={() => setStep(step + 1)} />}
{step === 2 && (
<ImportTrello handleSetAuthDetails={handleSetAuthDetails} />
)}
{step === 2 && <ImportTrello />}
</>
);
}

View File

@@ -18,10 +18,10 @@ export default function BoardsPage() {
<h1 className="font-medium tracking-tight text-dark-1000 sm:text-[1.2rem]">
Boards
</h1>
<div>
<div className="flex">
<button
type="button"
className="bg-dark-3000 mr-2 inline-flex items-center gap-x-1.5 rounded-md border-[1px] border-dark-600 px-3 py-2 text-sm text-dark-1000 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
className="bg-dark-3000 mr-2 flex items-center gap-x-1.5 rounded-md border-[1px] border-dark-600 px-3 py-2 text-sm text-dark-1000 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
onClick={() => openModal("IMPORT_BOARDS")}
>
<div className="flex h-5 w-5 items-center">
@@ -31,7 +31,7 @@ export default function BoardsPage() {
</button>
<button
type="button"
className="inline-flex items-center gap-x-1.5 rounded-md bg-dark-1000 px-3 py-2 text-sm font-semibold text-dark-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
className="flex items-center gap-x-1.5 rounded-md bg-dark-1000 px-3 py-2 text-sm font-semibold text-dark-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
onClick={() => openModal("NEW_BOARD")}
>
<div className="h-5 w-5 items-center">

View File

@@ -1,15 +1,33 @@
import { z } from "zod";
import { eq } from "drizzle-orm";
import {
createTRPCRouter,
publicProcedure,
} from "~/server/api/trpc";
import { boards, cards, imports, lists } from "~/server/db/schema";
import { generateUID } from "~/utils/generateUID";
const TRELLO_API_URL = 'https://api.trello.com/1';
interface BoardData {
interface TrelloBoard {
id: string;
name: string;
lists: TrelloList[];
cards: TrelloCard[];
}
interface TrelloList {
id: string;
name: string;
}
interface TrelloCard {
id: string;
name: string;
desc: string;
idList: string;
}
interface MemberData {
@@ -30,8 +48,6 @@ export const importRouter = createTRPCRouter({
if (!userId) return;
console.log({ input })
const fetchMemberRes = await fetch(`${TRELLO_API_URL}/tokens/${input.token}/member?key=${input.apiKey}`)
const member = await fetchMemberRes.json() as MemberData;
@@ -41,7 +57,7 @@ export const importRouter = createTRPCRouter({
const fetchBoard = async (boardId: string) => {
try {
const response = await fetch(`${TRELLO_API_URL}/boards/${boardId}?key=${input.apiKey}&token=${input.token}`);
const data = await response.json() as BoardData;
const data = await response.json() as TrelloBoard;
return data;
} catch (error) {
@@ -59,5 +75,95 @@ export const importRouter = createTRPCRouter({
return boardDataArray.map((board) => ({ id: board.id, name: board.name }));
}),
importBoards: publicProcedure
.input(
z.object({
boardIds: z.array(z.string()),
apiKey: z.string().length(32),
token: z.string().length(76),
}),
)
.mutation(async ({ ctx, input }) => {
const userId = ctx.session?.user.id;
if (!userId) return;
const newImport = await ctx.db.insert(imports).values({
publicId: generateUID(),
source: 'trello',
createdBy: userId,
status: 'started'
})
let boardsCreated = 0;
for (const boardId of input.boardIds) {
const response = await fetch(`${TRELLO_API_URL}/boards/${boardId}?key=${input.apiKey}&token=${input.token}&lists=open&cards=open`);
const data = await response.json() as TrelloBoard;
const formattedData = {
name: data.name,
lists: data.lists.map((list) => ({
name: list.name,
cards: data.cards
.filter((card) => card.idList === list.id)
.map((_card) => ({
name: _card.name,
description: _card.desc
}))
}))
}
await ctx.db.transaction(async (tx) => {
const newBoard = await tx.insert(boards).values({
publicId: generateUID(),
name: data.name,
createdBy: userId,
importId: newImport.insertId
});
if (!newBoard?.insertId) return;
let listIndex = 0;
for (const list of formattedData.lists) {
const newList = await tx.insert(lists).values({
publicId: generateUID(),
name: list.name,
createdBy: userId,
boardId: Number(newBoard.insertId),
index: listIndex,
importId: newImport.insertId
});
if (list.cards.length) {
const cardsInsert = list.cards.map((card, index) => ({
publicId: generateUID(),
title: card.name,
description: card.description,
createdBy: userId,
listId: Number(newList.insertId),
index,
importId: newImport.insertId
}))
await tx.insert(cards).values(cardsInsert);
}
listIndex ++
}
})
boardsCreated ++
}
if (boardsCreated > 0) {
await ctx.db.update(imports)
.set({ status: 'success' })
.where(eq(imports.id, Number(newImport.insertId)))
}
return { boardsCreated }
}),
})
});

View File

@@ -0,0 +1,15 @@
CREATE TABLE `import` (
`id` bigint AUTO_INCREMENT NOT NULL,
`publicId` varchar(12) NOT NULL,
`source` enum('trello') NOT NULL,
`createdBy` varchar(255) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` enum('started','success','failed') NOT NULL,
CONSTRAINT `import_id` PRIMARY KEY(`id`),
CONSTRAINT `import_publicId_unique` UNIQUE(`publicId`)
);
--> statement-breakpoint
ALTER TABLE `board` ADD `importId` varchar(255);--> statement-breakpoint
ALTER TABLE `card` ADD `importId` varchar(255);--> statement-breakpoint
ALTER TABLE `label` ADD `importId` varchar(255);--> statement-breakpoint
ALTER TABLE `list` ADD `importId` varchar(255);

View File

@@ -0,0 +1,769 @@
{
"version": "5",
"dialect": "mysql",
"id": "c397ed55-04bb-4ae5-9847-fe359c267155",
"prevId": "dbc12511-6c1b-4580-b95b-eb8365a5b090",
"tables": {
"account": {
"name": "account",
"columns": {
"userId": {
"name": "userId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"type": {
"name": "type",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"provider": {
"name": "provider",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"providerAccountId": {
"name": "providerAccountId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"expires_at": {
"name": "expires_at",
"type": "int",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"token_type": {
"name": "token_type",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"scope": {
"name": "scope",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"id_token": {
"name": "id_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"session_state": {
"name": "session_state",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"userId_idx": {
"name": "userId_idx",
"columns": [
"userId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"account_provider_providerAccountId": {
"name": "account_provider_providerAccountId",
"columns": [
"provider",
"providerAccountId"
]
}
},
"uniqueConstraints": {}
},
"board": {
"name": "board",
"columns": {
"id": {
"name": "id",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": true
},
"publicId": {
"name": "publicId",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"onUpdate": true
},
"deletedAt": {
"name": "deletedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"deletedBy": {
"name": "deletedBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"importId": {
"name": "importId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"board_id": {
"name": "board_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"board_publicId_unique": {
"name": "board_publicId_unique",
"columns": [
"publicId"
]
}
}
},
"card": {
"name": "card",
"columns": {
"id": {
"name": "id",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": true
},
"publicId": {
"name": "publicId",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"onUpdate": true
},
"listId": {
"name": "listId",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"index": {
"name": "index",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"deletedAt": {
"name": "deletedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"deletedBy": {
"name": "deletedBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"importId": {
"name": "importId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"card_id": {
"name": "card_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"card_publicId_unique": {
"name": "card_publicId_unique",
"columns": [
"publicId"
]
}
}
},
"card_label": {
"name": "card_label",
"columns": {
"cardId": {
"name": "cardId",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"labelId": {
"name": "labelId",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {
"card_label_cardId_card_id_fk": {
"name": "card_label_cardId_card_id_fk",
"tableFrom": "card_label",
"tableTo": "card",
"columnsFrom": [
"cardId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"card_label_labelId_label_id_fk": {
"name": "card_label_labelId_label_id_fk",
"tableFrom": "card_label",
"tableTo": "label",
"columnsFrom": [
"labelId"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"card_label_cardId_labelId": {
"name": "card_label_cardId_labelId",
"columns": [
"cardId",
"labelId"
]
}
},
"uniqueConstraints": {}
},
"import": {
"name": "import",
"columns": {
"id": {
"name": "id",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": true
},
"publicId": {
"name": "publicId",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"source": {
"name": "source",
"type": "enum('trello')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP"
},
"status": {
"name": "status",
"type": "enum('started','success','failed')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"import_id": {
"name": "import_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"import_publicId_unique": {
"name": "import_publicId_unique",
"columns": [
"publicId"
]
}
}
},
"label": {
"name": "label",
"columns": {
"id": {
"name": "id",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": true
},
"publicId": {
"name": "publicId",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"colourCode": {
"name": "colourCode",
"type": "varchar(12)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"onUpdate": true
},
"boardId": {
"name": "boardId",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"importId": {
"name": "importId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"label_id": {
"name": "label_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"label_publicId_unique": {
"name": "label_publicId_unique",
"columns": [
"publicId"
]
}
}
},
"list": {
"name": "list",
"columns": {
"id": {
"name": "id",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": true
},
"publicId": {
"name": "publicId",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdBy": {
"name": "createdBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"onUpdate": true
},
"boardId": {
"name": "boardId",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"index": {
"name": "index",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"deletedAt": {
"name": "deletedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"deletedBy": {
"name": "deletedBy",
"type": "varchar(256)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"importId": {
"name": "importId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"list_id": {
"name": "list_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"list_publicId_unique": {
"name": "list_publicId_unique",
"columns": [
"publicId"
]
}
}
},
"session": {
"name": "session",
"columns": {
"sessionToken": {
"name": "sessionToken",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"userId": {
"name": "userId",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"expires": {
"name": "expires",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"userId_idx": {
"name": "userId_idx",
"columns": [
"userId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"session_sessionToken": {
"name": "session_sessionToken",
"columns": [
"sessionToken"
]
}
},
"uniqueConstraints": {}
},
"user": {
"name": "user",
"columns": {
"id": {
"name": "id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"emailVerified": {
"name": "emailVerified",
"type": "timestamp(3)",
"primaryKey": false,
"notNull": false,
"autoincrement": false,
"default": "CURRENT_TIMESTAMP(3)"
},
"image": {
"name": "image",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"user_id": {
"name": "user_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"user_email_unique": {
"name": "user_email_unique",
"columns": [
"email"
]
}
}
},
"verificationToken": {
"name": "verificationToken",
"columns": {
"identifier": {
"name": "identifier",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"token": {
"name": "token",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"expires": {
"name": "expires",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"verificationToken_identifier_token": {
"name": "verificationToken_identifier_token",
"columns": [
"identifier",
"token"
]
}
},
"uniqueConstraints": {}
}
},
"schemas": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

View File

@@ -50,6 +50,13 @@
"when": 1704196792662,
"tag": "0006_lame_pepper_potts",
"breakpoints": true
},
{
"idx": 7,
"version": "5",
"when": 1708882995081,
"tag": "0007_open_nuke",
"breakpoints": true
}
]
}

View File

@@ -3,6 +3,7 @@ import {
bigint,
index,
int,
mysqlEnum,
mysqlTableCreator,
primaryKey,
text,
@@ -32,7 +33,8 @@ export const boards = mySqlTable(
.notNull(),
updatedAt: timestamp("updatedAt").onUpdateNow(),
deletedAt: timestamp("deletedAt"),
deletedBy: varchar("deletedBy", { length: 256 })
deletedBy: varchar("deletedBy", { length: 256 }),
importId: varchar("importId", { length: 255 }),
},
);
@@ -47,6 +49,35 @@ export const boardsRelations = relations(boards, ({ one, many }) => ({
fields: [boards.deletedBy],
references: [users.id],
}),
import: one(imports, {
fields: [boards.importId],
references: [imports.id],
}),
}));
export const imports = mySqlTable(
"import",
{
id: bigint("id", { mode: "number" }).primaryKey().autoincrement(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
source: mysqlEnum('source', ['trello']).notNull(),
createdBy: varchar("createdBy", { length: 255 }).notNull(),
createdAt: timestamp("createdAt")
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
status: mysqlEnum('status', ['started', 'success', 'failed']).notNull(),
},
);
export const importsRelations = relations(imports, ({ one, many }) => ({
createdBy: one(users, {
fields: [imports.createdBy],
references: [users.id],
}),
boards: many(boards),
cards: many(cards),
lists: many(lists),
labels: many(labels)
}));
export const labels = mySqlTable(
@@ -62,6 +93,7 @@ export const labels = mySqlTable(
.notNull(),
updatedAt: timestamp("updatedAt").onUpdateNow(),
boardId: bigint("boardId", { mode: "number" }).notNull(),
importId: varchar("importId", { length: 255 }),
}
);
@@ -74,7 +106,11 @@ export const labelsRelations = relations(labels, ({ one, many }) => ({
fields: [labels.boardId],
references: [boards.id],
}),
cards: many(cardsToLabels)
cards: many(cardsToLabels),
import: one(imports, {
fields: [labels.importId],
references: [imports.id],
}),
}));
export const cardsToLabels = mySqlTable(
@@ -112,7 +148,8 @@ export const lists = mySqlTable(
boardId: bigint("boardId", { mode: "number" }).notNull(),
index: int("index").notNull(),
deletedAt: timestamp("deletedAt"),
deletedBy: varchar("deletedBy", { length: 256 })
deletedBy: varchar("deletedBy", { length: 256 }),
importId: varchar("importId", { length: 255 }),
}
);
@@ -130,6 +167,10 @@ export const listsRelations = relations(lists, ({ one, many }) => ({
fields: [lists.deletedBy],
references: [users.id],
}),
import: one(imports, {
fields: [lists.importId],
references: [imports.id],
}),
}));
export const cards = mySqlTable(
@@ -147,7 +188,8 @@ export const cards = mySqlTable(
listId: bigint("listId", { mode: "number" }).notNull(),
index: int("index").notNull(),
deletedAt: timestamp("deletedAt"),
deletedBy: varchar("deletedBy", { length: 256 })
deletedBy: varchar("deletedBy", { length: 256 }),
importId: varchar("importId", { length: 255 }),
}
);
@@ -164,7 +206,11 @@ export const cardsRelations = relations(cards, ({ one, many }) => ({
fields: [cards.deletedBy],
references: [users.id],
}),
labels: many(cardsToLabels)
labels: many(cardsToLabels),
import: one(imports, {
fields: [cards.importId],
references: [imports.id],
}),
}));
export const users = mySqlTable("user", {
@@ -182,6 +228,7 @@ export const usersRelations = relations(users, ({ many }) => ({
accounts: many(accounts),
boards: many(boards),
cards: many(cards),
imports: many(imports),
lists: many(lists),
}));

View File

@@ -5,7 +5,7 @@ export default {
theme: {
extend: {
fontFamily: {
sans: ['var(--font-plus-jakarta-sans)']
sans: ['Plus Jakarta Sans']
},
fontSize: {
sm: "0.8rem",