diff --git a/app-nest/package-lock.json b/app-nest/package-lock.json index c1e4bc3..51a4bee 100644 --- a/app-nest/package-lock.json +++ b/app-nest/package-lock.json @@ -16,10 +16,11 @@ "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.0", "@slack/bolt": "^3.13.2", + "dayjs": "^1.11.9", + "lodash": "^4.17.21", "pg": "^8.11.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", - "slack-block-builder": "^2.7.2", "typeorm": "^0.3.17" }, "devDependencies": { @@ -29,6 +30,7 @@ "@nestjs/testing": "^10.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", + "@types/lodash": "^4.14.196", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^5.59.11", @@ -2117,6 +2119,12 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.14.196", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.196.tgz", + "integrity": "sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -3667,6 +3675,11 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -8234,11 +8247,6 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, - "node_modules/slack-block-builder": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/slack-block-builder/-/slack-block-builder-2.7.2.tgz", - "integrity": "sha512-EhoXDveGZWrHL0+AKnm3wu8n9K9usMjJGlbYLLwMSq62J7Qv+a4lO1iJI+NmCE04dm37d/3OlGKxBVoASnynog==" - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/app-nest/package.json b/app-nest/package.json index 2cf747a..c78f88d 100644 --- a/app-nest/package.json +++ b/app-nest/package.json @@ -35,10 +35,11 @@ "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.0", "@slack/bolt": "^3.13.2", + "dayjs": "^1.11.9", + "lodash": "^4.17.21", "pg": "^8.11.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", - "slack-block-builder": "^2.7.2", "typeorm": "^0.3.17" }, "devDependencies": { @@ -48,6 +49,7 @@ "@nestjs/testing": "^10.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.5.2", + "@types/lodash": "^4.14.196", "@types/node": "^20.3.1", "@types/supertest": "^2.0.12", "@typescript-eslint/eslint-plugin": "^5.59.11", @@ -81,4 +83,4 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" } -} \ No newline at end of file +} diff --git a/app-nest/src/gui/gui.module.ts b/app-nest/src/gui/gui.module.ts index 5f31ac3..afc423d 100644 --- a/app-nest/src/gui/gui.module.ts +++ b/app-nest/src/gui/gui.module.ts @@ -1,7 +1,7 @@ import { Module } from "@nestjs/common"; import { UserModule } from "../entities/user/user.module"; import { UserService } from "../entities/user/user.service"; -import { HomeTabController } from "./tabs/home-tab.controller"; +import { HomeTabController } from "./tabs/home/home-tab.controller"; @Module({ imports: [UserModule], diff --git a/app-nest/src/gui/tabs/home/day-list.blocks.ts b/app-nest/src/gui/tabs/home/day-list.blocks.ts new file mode 100644 index 0000000..8878373 --- /dev/null +++ b/app-nest/src/gui/tabs/home/day-list.blocks.ts @@ -0,0 +1,33 @@ +import dayjs, { Dayjs } from "dayjs"; +import { flatten } from "lodash"; +import getDayListItemBlocks from "./day-list.item.blocks"; + +/** + * Get range of days from today (inclusive) for the next `len` working days (defined as Mon-Fri). + */ +const dayRange = (len: number, days: Dayjs[] = [], i = 0): Dayjs[] => { + if (i >= len) { + return days; + } + + if (days.length === 0) { + days.push(dayjs()); + return dayRange(len, days, i + 1); + } + + const prevDate = days.at(-1); + const prevDay = prevDate.day(); + // Skip Saturdays (day 6) and Sundays (day 0). + const daysToAdd = prevDay === 5 ? 3 : prevDay === 6 ? 2 : 1; + days.push(prevDate.add(daysToAdd, "d")); + + return dayRange(len, days, i + 1); +}; + +const getDayListBlocks = () => { + const dates = dayRange(14); + const blockLists = dates.map((date) => getDayListItemBlocks({ date })); + return flatten(blockLists); +}; + +export default getDayListBlocks; diff --git a/app-nest/src/gui/tabs/home-tab.view.ts b/app-nest/src/gui/tabs/home/day-list.item.blocks.ts similarity index 86% rename from app-nest/src/gui/tabs/home-tab.view.ts rename to app-nest/src/gui/tabs/home/day-list.item.blocks.ts index 2f9a571..87c85de 100644 --- a/app-nest/src/gui/tabs/home-tab.view.ts +++ b/app-nest/src/gui/tabs/home/day-list.item.blocks.ts @@ -1,12 +1,15 @@ -import devTools from "../dev/dev-tools"; +import { Dayjs } from "dayjs"; -const getHomeTabBlocks = () => [ - ...devTools, +type DayListItemProps = { + date: Dayjs; +}; + +const getDayListItemBlocks = ({ date }: DayListItemProps) => [ { type: "header", text: { type: "plain_text", - text: "Ilmoittautumiset", + text: date.format("dd D.M."), }, }, { @@ -75,4 +78,4 @@ const getHomeTabBlocks = () => [ }, ]; -export default getHomeTabBlocks; +export default getDayListItemBlocks; diff --git a/app-nest/src/gui/tabs/home-tab.controller.ts b/app-nest/src/gui/tabs/home/home-tab.controller.ts similarity index 65% rename from app-nest/src/gui/tabs/home-tab.controller.ts rename to app-nest/src/gui/tabs/home/home-tab.controller.ts index 6a47971..6d8ac1b 100644 --- a/app-nest/src/gui/tabs/home-tab.controller.ts +++ b/app-nest/src/gui/tabs/home/home-tab.controller.ts @@ -1,8 +1,9 @@ import { Controller } from "@nestjs/common"; -import BoltEvent from "../../bolt/decorators/bolt-event.decorator"; -import BoltEvents from "../../bolt/enums/bolt-events.enum"; -import { AppHomeOpenedArgs } from "../../bolt/types/bolt-event-types"; -import { UserService } from "../../entities/user/user.service"; +import BoltEvent from "../../../bolt/decorators/bolt-event.decorator"; +import BoltEvents from "../../../bolt/enums/bolt-events.enum"; +import { AppHomeOpenedArgs } from "../../../bolt/types/bolt-event-types"; +import { UserService } from "../../../entities/user/user.service"; +import getDayListBlocks from "./day-list.blocks"; import getHomeTabBlocks from "./home-tab.view"; @Controller() @@ -13,6 +14,7 @@ export class HomeTabController { async getView({ event, client, logger }: AppHomeOpenedArgs) { const users = await this.userService.findAll(); const { slackId } = users[0]; + getDayListBlocks(); try { const result = await client.views.publish({ diff --git a/app-nest/src/gui/tabs/home/home-tab.view.ts b/app-nest/src/gui/tabs/home/home-tab.view.ts new file mode 100644 index 0000000..22b7f6f --- /dev/null +++ b/app-nest/src/gui/tabs/home/home-tab.view.ts @@ -0,0 +1,16 @@ +import devTools from "../../dev/dev-tools"; +import getDayListBlocks from "./day-list.blocks"; + +const getHomeTabBlocks = () => [ + ...devTools, + { + type: "header", + text: { + type: "plain_text", + text: "Ilmoittautumiset", + }, + }, + ...getDayListBlocks(), +]; + +export default getHomeTabBlocks; diff --git a/app-nest/tsconfig.json b/app-nest/tsconfig.json index 95f5641..28ed2de 100644 --- a/app-nest/tsconfig.json +++ b/app-nest/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "module": "commonjs", + "esModuleInterop": true, "declaration": true, "removeComments": true, "emitDecoratorMetadata": true,