Skip to content

Commit

Permalink
feat: create miro board
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroki0525 committed Jan 9, 2024
1 parent 8b2db54 commit 291a2c2
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 35 deletions.
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"build": "tsup --config ../../tsup.config.ts",
"test": "vitest run",
"dev:core": "tsx src/core/cli.ts",
"dev:miro": "tsx src/miro/cli.ts",
"dev:miro": "tsx src/miro/cli.ts ./tmp/tmp.txt",
"dev:notion": "tsx src/notion/cli.ts"
},
"bin": {
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/miro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export default class DandoriMiroCli extends DandoriCoreCli {
return super
.buildCommand()
.option("-a, --app-card", "use app card")
.option("-b, --board-id <board-id>", "miro board id");
.option(
"-b, --board-id <board-id>",
"miro board id. if not set, create new board",
);
}
}
75 changes: 47 additions & 28 deletions packages/ui/src/__tests__/miro.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, beforeEach, afterEach, vi, Mock, it, expect } from "vitest";
import { runPromisesSequentially } from "@dandori/libs";
import { Board } from "@mirohq/miro-api";
import { Board, MiroApi } from "@mirohq/miro-api";
import { generateDandoriMiroCards } from "../index";
import { DandoriTask } from "@dandori/core";

Expand All @@ -14,6 +14,7 @@ vi.mock("@mirohq/miro-api", () => {
};
MiroApi.prototype = {
getBoard: vi.fn(() => new Board()),
createBoard: vi.fn(() => new Board()),
};
return { MiroApi, Board };
});
Expand All @@ -38,6 +39,7 @@ const mockRunPromisesSequentially = runPromisesSequentially as Mock;

describe("generateDandoriMiroCards", () => {
let board: Board;
let miroApi: MiroApi;

const defaultCardMarginX = 130;
const defaultCardMarginY = defaultCardMarginX / 2;
Expand Down Expand Up @@ -204,47 +206,64 @@ describe("generateDandoriMiroCards", () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
board = new Board();
miroApi = new MiroApi("test");
});

afterEach(() => {
vi.clearAllMocks();
});

describe("card", () => {
beforeEach(async () => {
await generateDandoriMiroCards(tasks, {
boardId: "boardId",
describe("with boardId", () => {
beforeEach(async () => {
await generateDandoriMiroCards(tasks, {
boardId: "boardId",
});
});
});

it("createCardItem called", () => {
expect((board.createCardItem as Mock).mock.calls.flat()).toEqual(
expect.arrayContaining(cardParams),
);
});
it("getBoard called", () => {
expect(miroApi.getBoard as Mock).toHaveBeenCalled();
});

it("createConnector called", () => {
expect((board.createConnector as Mock).mock.calls.flat()).toStrictEqual(
expect.arrayContaining(connectorParams),
);
});
it("createCardItem called", () => {
expect((board.createCardItem as Mock).mock.calls.flat()).toEqual(
expect.arrayContaining(cardParams),
);
});

it("runPromisesSequentially called with creating cards log", () => {
expect(mockRunPromisesSequentially.mock.calls[0][1]).toBe(
"Creating cards",
);
});
it("createConnector called", () => {
expect((board.createConnector as Mock).mock.calls.flat()).toStrictEqual(
expect.arrayContaining(connectorParams),
);
});

it("runPromisesSequentially called with creating connectors log", () => {
expect(mockRunPromisesSequentially.mock.calls[1][1]).toBe(
"Creating connectors",
);
it("runPromisesSequentially called with creating cards log", () => {
expect(mockRunPromisesSequentially.mock.calls[0][1]).toBe(
"Creating cards",
);
});

it("runPromisesSequentially called with creating connectors log", () => {
expect(mockRunPromisesSequentially.mock.calls[1][1]).toBe(
"Creating connectors",
);
});

it("called log info", () => {
expect(mockLogInfo.mock.lastCall[0]).toBe(
"Create miro cards and connectors successfully!",
);
});
});

it("called log info", () => {
expect(mockLogInfo.mock.lastCall[0]).toBe(
"Create miro cards and connectors successfully!",
);
describe("without boardId", () => {
beforeEach(async () => {
await generateDandoriMiroCards(tasks);
});

it("createBoard called", () => {
expect(miroApi.createBoard as Mock).toHaveBeenCalled();
});
});
});
});
15 changes: 10 additions & 5 deletions packages/ui/src/miro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import {
} from "@dandori/libs";

export type GenerateDandoriMiroCardsOptions = {
boardId: Parameters<MiroApi["getBoard"]>[0];
boardId?: Parameters<MiroApi["getBoard"]>[0];
isAppCard?: boolean;
apiKey?: Parameters<typeof checkApiKey>[2];
};

export type GenerateDandoriMiroCardsResult = ReturnType<MiroApi["getBoard"]>;

// miro settings
const defaultCardMarginX = 130;
const defaultCardMarginY = defaultCardMarginX / 2;
Expand Down Expand Up @@ -57,12 +59,12 @@ function iterateBreadthNodes<T>(

export async function generateDandoriMiroCards(
tasks: DandoriTask[],
options: GenerateDandoriMiroCardsOptions,
): Promise<void> {
options?: GenerateDandoriMiroCardsOptions,
): Promise<GenerateDandoriMiroCardsResult> {
const key = checkApiKey(
"miro api key",
process.env.MIRO_API_KEY,
options.apiKey,
options?.apiKey,
);
const logger = getLogger();
const miroApi = new MiroApi(key, undefined, (...thing) => {
Expand All @@ -73,7 +75,9 @@ export async function generateDandoriMiroCards(
logger[logLevel](thing);
}
});
const miroBoard = await miroApi.getBoard(options.boardId);
const miroBoard = options?.boardId
? await miroApi.getBoard(options.boardId)
: await miroApi.createBoard(undefined);
const taskFlat: (DandoriTask & { [taskParentPropName]?: string })[] = tasks
.map((task) =>
task.fromTaskIdList.length === 0
Expand Down Expand Up @@ -187,4 +191,5 @@ export async function generateDandoriMiroCards(
"Creating connectors",
);
logger.info("Create miro cards and connectors successfully!");
return miroBoard;
}

0 comments on commit 291a2c2

Please sign in to comment.