Skip to content

Commit

Permalink
Create miro board (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroki0525 authored Jan 9, 2024
1 parent 67d496a commit b4add76
Show file tree
Hide file tree
Showing 10 changed files with 557 additions and 683 deletions.
7 changes: 7 additions & 0 deletions .changeset/tender-cherries-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@dandori/core": patch
"@dandori/cli": patch
"@dandori/ui": patch
---

Create miro board
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@
"devDependencies": {
"@changesets/changelog-github": "^0.5.0",
"@changesets/cli": "^2.27.1",
"@types/node": "^18.19.3",
"@typescript-eslint/eslint-plugin": "6.14.0",
"@typescript-eslint/parser": "6.14.0",
"eslint": "8.55.0",
"@types/node": "^18",
"@typescript-eslint/eslint-plugin": "6.18.1",
"@typescript-eslint/parser": "6.18.1",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-unused-imports": "3.0.0",
"eslint-plugin-vitest": "^0.3.10",
"eslint-plugin-vitest": "^0.3.20",
"husky": "^8.0.3",
"lint-staged": "^15.2.0",
"prettier": "3.1.1",
"tsup": "^8.0.1",
"tsx": "^4.6.2",
"turbo": "^1.11.1",
"tsx": "^4.7.0",
"turbo": "^1.11.3",
"typescript": "5.3.3",
"vitest": "^1.0.0"
"vitest": "^0.34.6"
},
"packageManager": "[email protected]",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Options:
-m, --model <model> Chat GPT model which supports function_calling
-o, --optional-task-props <optional-task-props> optional output task props which delimiter is a comma
-a, --app-card use app card
-b, --board-id <board-id> miro board id
-b, --board-id <board-id> miro board id. if not set, create new board
-h, --help display help for command
```
Expand Down
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",
);
}
}
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
"license": "MIT",
"dependencies": {
"@dandori/libs": "workspace:*",
"openai": "^4.20.1"
"openai": "^4.24.1"
}
}
8 changes: 4 additions & 4 deletions packages/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The tasks which are generated by `generateDandoriTasks` of `@dandori/core`.

```ts
interface GenerateDandoriMiroCardsOptions {
boardId: string;
boardId?: string;
isAppCard?: boolean;
apiKey?: string;
}
Expand All @@ -79,6 +79,8 @@ You can get the board id from the miro url of the board.

For example, if the url is `https://miro.com/app/board/1234567890/`, the board id is `1234567890`.

If not set, the new board is created.

* isAppCard

**default is `false`**
Expand All @@ -89,9 +91,7 @@ If you set `true` , the cards are created as [App cards](https://developers.miro

The api key of miro. You can also set `MIRO_API_KEY` environment variable instead of this option.

```ts

### generateDandoriNotionTasks
### generateDandoriNotionPages

```ts
async function generateDandoriNotionPages(
Expand Down
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("createCardItem called", () => {
expect((board.createCardItem as Mock).mock.calls.flat()).toEqual(
expect.arrayContaining(cardParams),
);
});

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

it("runPromisesSequentially called with creating cards log", () => {
expect(mockRunPromisesSequentially.mock.calls[0][1]).toBe(
"Creating cards",
);
});
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("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("getBoard called", () => {
expect(miroApi.getBoard as Mock).toHaveBeenCalled();
});
});

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;
}
Loading

0 comments on commit b4add76

Please sign in to comment.