@vigilant-broccoli/slackbots 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +7 -0
  2. package/package.json +18 -0
  3. package/src/index.d.ts +6 -0
  4. package/src/index.js +11 -0
  5. package/src/index.js.map +1 -0
  6. package/src/lib/consts.d.ts +3 -0
  7. package/src/lib/consts.js +8 -0
  8. package/src/lib/consts.js.map +1 -0
  9. package/src/lib/utils/modal.utils.d.ts +13 -0
  10. package/src/lib/utils/modal.utils.js +63 -0
  11. package/src/lib/utils/modal.utils.js.map +1 -0
  12. package/src/lib/utils/utils.d.ts +13 -0
  13. package/src/lib/utils/utils.js +54 -0
  14. package/src/lib/utils/utils.js.map +1 -0
  15. package/src/lib/utils/view-builder.utils.d.ts +22 -0
  16. package/src/lib/utils/view-builder.utils.js +34 -0
  17. package/src/lib/utils/view-builder.utils.js.map +1 -0
  18. package/src/office-presence-app/app-reminder.d.ts +2 -0
  19. package/src/office-presence-app/app-reminder.js +69 -0
  20. package/src/office-presence-app/app-reminder.js.map +1 -0
  21. package/src/office-presence-app/consts/app-copy.const.d.ts +54 -0
  22. package/src/office-presence-app/consts/app-copy.const.js +66 -0
  23. package/src/office-presence-app/consts/app-copy.const.js.map +1 -0
  24. package/src/office-presence-app/consts/app.consts.d.ts +10 -0
  25. package/src/office-presence-app/consts/app.consts.js +14 -0
  26. package/src/office-presence-app/consts/app.consts.js.map +1 -0
  27. package/src/office-presence-app/consts/data.consts.d.ts +2 -0
  28. package/src/office-presence-app/consts/data.consts.js +27 -0
  29. package/src/office-presence-app/consts/data.consts.js.map +1 -0
  30. package/src/office-presence-app/consts/modals.const.d.ts +5 -0
  31. package/src/office-presence-app/consts/modals.const.js +199 -0
  32. package/src/office-presence-app/consts/modals.const.js.map +1 -0
  33. package/src/office-presence-app/office-presence-app.d.ts +10 -0
  34. package/src/office-presence-app/office-presence-app.js +100 -0
  35. package/src/office-presence-app/office-presence-app.js.map +1 -0
  36. package/src/office-presence-app/types.d.ts +25 -0
  37. package/src/office-presence-app/types.js +9 -0
  38. package/src/office-presence-app/types.js.map +1 -0
  39. package/src/office-presence-app/utils/action.utils.d.ts +6 -0
  40. package/src/office-presence-app/utils/action.utils.js +83 -0
  41. package/src/office-presence-app/utils/action.utils.js.map +1 -0
  42. package/src/office-presence-app/utils/date.utils.d.ts +4 -0
  43. package/src/office-presence-app/utils/date.utils.js +43 -0
  44. package/src/office-presence-app/utils/date.utils.js.map +1 -0
  45. package/src/office-presence-app/utils/db.utils.d.ts +4 -0
  46. package/src/office-presence-app/utils/db.utils.js +66 -0
  47. package/src/office-presence-app/utils/db.utils.js.map +1 -0
  48. package/src/office-presence-app/utils/view.utils.d.ts +12 -0
  49. package/src/office-presence-app/utils/view.utils.js +130 -0
  50. package/src/office-presence-app/utils/view.utils.js.map +1 -0
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createInputScheduleModal = createInputScheduleModal;
4
+ exports.getSettingModal = getSettingModal;
5
+ exports.getAskLunchModal = getAskLunchModal;
6
+ const types_1 = require("../types");
7
+ const view_builder_utils_1 = require("../../lib/utils/view-builder.utils");
8
+ const app_consts_1 = require("./app.consts");
9
+ const app_copy_const_1 = require("./app-copy.const");
10
+ const db_utils_1 = require("../utils/db.utils");
11
+ const date_utils_1 = require("../utils/date.utils");
12
+ const view_utils_1 = require("../utils/view.utils");
13
+ function createInputScheduleModal(appConfig) {
14
+ return function getInputScheduleModal() {
15
+ const dates = (0, date_utils_1.getUpcomingWeekdays)(10);
16
+ const options = (0, view_utils_1.buildModalDateOptionSlackBlocks)(dates);
17
+ const initialOptions = [options[0]];
18
+ const officeBlocks = appConfig.OFFICES.length > 0 ? [buildOfficeBlock(appConfig.OFFICES)] : [];
19
+ return {
20
+ type: 'modal',
21
+ callback_id: app_consts_1.APP_ACTION.SUBMIT_SCHEDULE,
22
+ title: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.TITLE),
23
+ submit: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.COMMON.SUBMIT),
24
+ close: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.COMMON.CANCEL),
25
+ blocks: [
26
+ {
27
+ type: 'input',
28
+ block_id: 'date_block',
29
+ element: {
30
+ type: 'checkboxes',
31
+ action_id: 'date',
32
+ options,
33
+ initial_options: initialOptions,
34
+ },
35
+ label: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.SELECT_DAYS_LABEL),
36
+ },
37
+ ...officeBlocks,
38
+ {
39
+ type: 'input',
40
+ block_id: 'presence_block',
41
+ element: {
42
+ type: 'radio_buttons',
43
+ action_id: 'presence',
44
+ options: [
45
+ {
46
+ text: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.WHOLE_DAY),
47
+ value: types_1.PRESENCE_TIME.WHOLE_DAY,
48
+ },
49
+ {
50
+ text: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.MORNING_ONLY),
51
+ value: types_1.PRESENCE_TIME.MORNING,
52
+ },
53
+ {
54
+ text: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.AFTERNOON_ONLY),
55
+ value: types_1.PRESENCE_TIME.AFTERNOON,
56
+ },
57
+ ],
58
+ },
59
+ label: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.PRESENCE_LABEL),
60
+ optional: true,
61
+ },
62
+ {
63
+ type: 'input',
64
+ block_id: 'dog_block',
65
+ element: {
66
+ type: 'checkboxes',
67
+ action_id: 'dog',
68
+ options: [
69
+ {
70
+ text: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.COMMON.YES),
71
+ value: 'dog',
72
+ },
73
+ ],
74
+ },
75
+ label: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.BRINGING_DOG_LABEL),
76
+ optional: true,
77
+ },
78
+ {
79
+ type: 'input',
80
+ block_id: 'message_block',
81
+ element: {
82
+ type: 'plain_text_input',
83
+ action_id: 'message',
84
+ multiline: true,
85
+ },
86
+ label: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.PRESENCE_MODAL.MESSAGE_LABEL),
87
+ optional: true,
88
+ },
89
+ ],
90
+ };
91
+ };
92
+ }
93
+ function buildOfficeBlock(offices, blockId = 'office_block') {
94
+ return {
95
+ type: 'input',
96
+ block_id: blockId,
97
+ element: {
98
+ type: 'radio_buttons',
99
+ action_id: 'office',
100
+ options: offices.map(office => ({
101
+ text: { type: 'plain_text', text: office },
102
+ value: office,
103
+ })),
104
+ },
105
+ label: {
106
+ type: 'plain_text',
107
+ text: app_copy_const_1.APP_COPY.PRESENCE_MODAL.OFFICE_LABEL,
108
+ },
109
+ optional: true,
110
+ };
111
+ }
112
+ function getSettingModal() {
113
+ return {
114
+ type: 'modal',
115
+ callback_id: app_consts_1.APP_ACTION.SUBMIT_SETTINGS,
116
+ title: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.SETTINGS_MODAL.TITLE),
117
+ close: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.COMMON.CLOSE),
118
+ submit: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.COMMON.SAVE),
119
+ blocks: [
120
+ view_builder_utils_1.SlackViewBuilder.generateMarkdownSection(app_copy_const_1.APP_COPY.SETTINGS_MODAL.COMING_SOON_MARKDOWN),
121
+ {
122
+ type: 'input',
123
+ block_id: 'new_office_input',
124
+ label: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.SETTINGS_MODAL.ADD_OFFICE_LABEL),
125
+ element: {
126
+ type: 'plain_text_input',
127
+ action_id: 'new_office',
128
+ placeholder: view_builder_utils_1.SlackViewBuilder.generatePlainText(app_copy_const_1.APP_COPY.SETTINGS_MODAL.ADD_OFFICE_PLACEHOLDER),
129
+ },
130
+ optional: true,
131
+ },
132
+ ],
133
+ };
134
+ }
135
+ function getAskLunchModal(userId) {
136
+ const chunkArray = (arr, size) => {
137
+ const chunks = [];
138
+ for (let i = 0; i < arr.length; i += size) {
139
+ chunks.push(arr.slice(i, i + size));
140
+ }
141
+ return chunks;
142
+ };
143
+ const userPresences = (0, db_utils_1.loadAllPresences)();
144
+ const today = new Date().toISOString().split('T')[0];
145
+ const usersInOffice = [];
146
+ for (const [uid, presences] of Object.entries(userPresences)) {
147
+ if (presences[today] && uid !== userId) {
148
+ usersInOffice.push({
149
+ label: presences[today].office
150
+ ? `<@${uid}> | 🏢 ${presences[today].office}`
151
+ : `<@${uid}>`,
152
+ value: uid,
153
+ });
154
+ }
155
+ }
156
+ let blocks;
157
+ if (usersInOffice.length === 0) {
158
+ blocks = [
159
+ {
160
+ type: 'section',
161
+ text: {
162
+ type: 'mrkdwn',
163
+ text: app_copy_const_1.APP_COPY.ASK_LUNCH_MODAL.NO_USERS_MARKDOWN,
164
+ },
165
+ },
166
+ ];
167
+ }
168
+ else {
169
+ const userChunks = chunkArray(usersInOffice, 10);
170
+ blocks = userChunks.map((chunk, index) => ({
171
+ type: 'section',
172
+ block_id: `users_select_block_${index}`,
173
+ text: {
174
+ type: 'mrkdwn',
175
+ text: index === 0 ? app_copy_const_1.APP_COPY.ASK_LUNCH_MODAL.SELECT_USERS_MARKDOWN : ' ',
176
+ },
177
+ accessory: {
178
+ type: 'checkboxes',
179
+ action_id: `users_checkbox_${index}`,
180
+ options: chunk.map(user => ({
181
+ text: { type: 'plain_text', text: user.label },
182
+ value: user.value,
183
+ })),
184
+ },
185
+ }));
186
+ }
187
+ const modal = {
188
+ type: 'modal',
189
+ callback_id: app_consts_1.APP_ACTION.ASK_LUNCH,
190
+ title: { type: 'plain_text', text: app_copy_const_1.APP_COPY.ASK_LUNCH_MODAL.TITLE },
191
+ submit: usersInOffice.length
192
+ ? { type: 'plain_text', text: app_copy_const_1.APP_COPY.ASK_LUNCH_MODAL.SUBMIT }
193
+ : undefined,
194
+ close: { type: 'plain_text', text: app_copy_const_1.APP_COPY.COMMON.CLOSE },
195
+ blocks,
196
+ };
197
+ return modal;
198
+ }
199
+ //# sourceMappingURL=modals.const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modals.const.js","sourceRoot":"","sources":["../../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/consts/modals.const.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type OfficePresenceAppRunConfig = {
2
+ id?: string;
3
+ APP_NAME?: string;
4
+ OFFICES?: string[];
5
+ port?: number;
6
+ reminderCron?: string;
7
+ reminderTimezone?: string;
8
+ enableReminders?: boolean;
9
+ };
10
+ export declare function runOfficePresenceApp(config?: OfficePresenceAppRunConfig): Promise<void>;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runOfficePresenceApp = runOfficePresenceApp;
4
+ const tslib_1 = require("tslib");
5
+ const cron = require("node-cron");
6
+ const consts_1 = require("../lib/consts");
7
+ const modal_utils_1 = require("../lib/utils/modal.utils");
8
+ const utils_1 = require("../lib/utils/utils");
9
+ const modals_const_1 = require("./consts/modals.const");
10
+ const action_utils_1 = require("./utils/action.utils");
11
+ const view_utils_1 = require("./utils/view.utils");
12
+ const app_consts_1 = require("./consts/app.consts");
13
+ const db_utils_1 = require("./utils/db.utils");
14
+ const app_reminder_1 = require("./app-reminder");
15
+ const DEFAULT_PORT = 3000;
16
+ const DEFAULT_REMINDER_CRON = '0 8 * * 1';
17
+ const DEFAULT_REMINDER_TIMEZONE = 'Europe/Stockholm';
18
+ const DEFAULT_APP_NAME = 'OK-IN';
19
+ const DEFAULT_OFFICES = [];
20
+ // eslint-disable-next-line complexity
21
+ function runOfficePresenceApp() {
22
+ return tslib_1.__awaiter(this, arguments, void 0, function* (config = {}) {
23
+ var _a, _b, _c, _d;
24
+ const { id, APP_NAME, OFFICES } = config;
25
+ const appConfig = {
26
+ id,
27
+ APP_NAME: APP_NAME !== null && APP_NAME !== void 0 ? APP_NAME : DEFAULT_APP_NAME,
28
+ OFFICES: OFFICES !== null && OFFICES !== void 0 ? OFFICES : DEFAULT_OFFICES,
29
+ };
30
+ const publishHomeView = (0, view_utils_1.createPublishHomeView)(appConfig);
31
+ const getInputScheduleModal = (0, modals_const_1.createInputScheduleModal)(appConfig);
32
+ const sendReminders = (0, app_reminder_1.createReminderSender)(appConfig);
33
+ const app = utils_1.SlackUtils.getSocketApp();
34
+ app.event(consts_1.SLACK_EVENT.HOME_OPENED, (_a) => tslib_1.__awaiter(this, [_a], void 0, function* ({ event, client }) {
35
+ yield publishHomeView(client, event);
36
+ }));
37
+ app.action(app_consts_1.APP_ACTION.WORKDAY_CHECKBOXES, (_a) => tslib_1.__awaiter(this, [_a], void 0, function* ({ ack, body, client }) {
38
+ yield ack();
39
+ (0, action_utils_1.handleCheckboxAction)(body);
40
+ yield publishHomeView(client, body);
41
+ }));
42
+ app.view(app_consts_1.APP_ACTION.SUBMIT_SCHEDULE, (_a) => tslib_1.__awaiter(this, [_a], void 0, function* ({ ack, body, view, client }) {
43
+ yield ack();
44
+ (0, action_utils_1.handleScheduleModalSubmit)(body, view);
45
+ yield publishHomeView(client, body);
46
+ }));
47
+ app.view(app_consts_1.APP_ACTION.SUBMIT_SETTINGS, (_a) => tslib_1.__awaiter(this, [_a], void 0, function* ({ ack, body, view, client }) {
48
+ yield ack();
49
+ (0, action_utils_1.handleUpdateSettings)(body, view);
50
+ yield publishHomeView(client, body);
51
+ }));
52
+ app.action(app_consts_1.APP_ACTION.OPEN_SCHEDULE_MODAL, modal_utils_1.SlackModalUtils.createModalHandler(getInputScheduleModal));
53
+ app.action(app_consts_1.APP_ACTION.OPEN_ASK_LUNCH_MODAL, modal_utils_1.SlackModalUtils.createModalHandlerWithUserId(modals_const_1.getAskLunchModal));
54
+ app.action(app_consts_1.APP_ACTION.OPEN_SETTINGS_MODAL, modal_utils_1.SlackModalUtils.createModalHandler(modals_const_1.getSettingModal));
55
+ app.view(app_consts_1.APP_ACTION.ASK_LUNCH, (_a) => tslib_1.__awaiter(this, [_a], void 0, function* ({ body, ack, client }) {
56
+ var _b;
57
+ yield ack();
58
+ const userId = body.user.id;
59
+ const stateValues = body.view.state.values;
60
+ const selectedUsers = [];
61
+ for (const actionMap of Object.values(stateValues)) {
62
+ for (const action of Object.values(actionMap)) {
63
+ if (action.type === 'checkboxes' && ((_b = action.selected_options) === null || _b === void 0 ? void 0 : _b.length)) {
64
+ for (const opt of action.selected_options) {
65
+ selectedUsers.push(opt.value);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ yield (0, action_utils_1.handleAskLunchAction)(userId, selectedUsers, client);
71
+ }));
72
+ app.action(app_consts_1.APP_ACTION.SUBMIT_CHECKOUT, createCheckoutAction(publishHomeView));
73
+ yield app.start((_a = config.port) !== null && _a !== void 0 ? _a : DEFAULT_PORT);
74
+ // eslint-disable-next-line no-console
75
+ console.log(`⚡️ ${appConfig.APP_NAME} is running!`);
76
+ if ((_b = config.enableReminders) !== null && _b !== void 0 ? _b : true) {
77
+ cron.schedule((_c = config.reminderCron) !== null && _c !== void 0 ? _c : DEFAULT_REMINDER_CRON, () => tslib_1.__awaiter(this, void 0, void 0, function* () {
78
+ yield sendReminders();
79
+ }), {
80
+ timezone: (_d = config.reminderTimezone) !== null && _d !== void 0 ? _d : DEFAULT_REMINDER_TIMEZONE,
81
+ });
82
+ }
83
+ });
84
+ }
85
+ function createCheckoutAction(publishHomeView) {
86
+ return function handleCheckoutAction(_a) {
87
+ return tslib_1.__awaiter(this, arguments, void 0, function* ({ body, ack, client, }) {
88
+ yield ack();
89
+ const userId = body.user.id;
90
+ const today = new Date().toISOString().split('T')[0];
91
+ const allPresences = (0, db_utils_1.loadAllPresences)();
92
+ const userPresences = allPresences[userId];
93
+ const presence = userPresences[today];
94
+ presence.message = 'has left the building!';
95
+ (0, db_utils_1.savePresence)(userId, today, presence);
96
+ yield publishHomeView(client, body);
97
+ });
98
+ };
99
+ }
100
+ //# sourceMappingURL=office-presence-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"office-presence-app.js","sourceRoot":"","sources":["../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/office-presence-app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export type AppConfig = {
2
+ id?: string;
3
+ APP_NAME: string;
4
+ OFFICES: string[];
5
+ };
6
+ export declare const PRESENCE_TIME: {
7
+ readonly WHOLE_DAY: "whole day";
8
+ readonly MORNING: "morning";
9
+ readonly AFTERNOON: "afternoon";
10
+ };
11
+ export type UserPresences = Record<string, Record<string, UserPresence>>;
12
+ export type UserPresence = {
13
+ office?: string;
14
+ presenceTime?: string;
15
+ isBringingDog?: boolean;
16
+ message?: string;
17
+ };
18
+ export type UserPresenceRow = {
19
+ user_id: string;
20
+ date: string;
21
+ office?: string;
22
+ presence_time?: string;
23
+ is_bringing_dog?: number;
24
+ message?: string;
25
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRESENCE_TIME = void 0;
4
+ exports.PRESENCE_TIME = {
5
+ WHOLE_DAY: 'whole day',
6
+ MORNING: 'morning',
7
+ AFTERNOON: 'afternoon',
8
+ };
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/types.ts"],"names":[],"mappings":";;;AAMa,QAAA,aAAa,GAAG;IAC3B,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;CACd,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { BlockAction, SlackViewAction, ViewOutput } from '@slack/bolt';
2
+ import { WebClient } from '@slack/web-api';
3
+ export declare function handleCheckboxAction(body: BlockAction): void;
4
+ export declare function handleScheduleModalSubmit(body: SlackViewAction, view: ViewOutput): void;
5
+ export declare function handleUpdateSettings(_body: SlackViewAction, _view: ViewOutput): void;
6
+ export declare function handleAskLunchAction(userId: string, selectedUserIds: string[], client: WebClient): Promise<void>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleCheckboxAction = handleCheckboxAction;
4
+ exports.handleScheduleModalSubmit = handleScheduleModalSubmit;
5
+ exports.handleUpdateSettings = handleUpdateSettings;
6
+ exports.handleAskLunchAction = handleAskLunchAction;
7
+ const tslib_1 = require("tslib");
8
+ const db_utils_1 = require("./db.utils");
9
+ const app_copy_const_1 = require("../consts/app-copy.const");
10
+ function handleCheckboxAction(body) {
11
+ const action = body.actions[0];
12
+ if (action.type !== 'checkboxes')
13
+ return;
14
+ const selectedDates = action.selected_options.map(opt => opt.value);
15
+ const userPresences = (0, db_utils_1.loadAllPresences)();
16
+ if (!userPresences[body.user.id]) {
17
+ userPresences[body.user.id] = {};
18
+ }
19
+ for (const date of selectedDates) {
20
+ (0, db_utils_1.savePresence)(body.user.id, date, userPresences[body.user.id][date] ||
21
+ {
22
+ isWholeDay: true,
23
+ });
24
+ }
25
+ for (const date of Object.keys(userPresences[body.user.id])) {
26
+ if (!selectedDates.includes(date)) {
27
+ delete userPresences[body.user.id][date];
28
+ (0, db_utils_1.deletePresence)(body.user.id, date);
29
+ }
30
+ }
31
+ }
32
+ function handleScheduleModalSubmit(body, view) {
33
+ var _a, _b, _c;
34
+ const userId = body.user.id;
35
+ const dateOptions = view.state.values.date_block.date.selected_options || [];
36
+ const selectedDates = dateOptions.map(opt => opt.value);
37
+ const office = (_b = (_a = view.state.values.office_block) === null || _a === void 0 ? void 0 : _a.office.selected_option) === null || _b === void 0 ? void 0 : _b.value;
38
+ const presenceTime = (_c = view.state.values.presence_block.presence.selected_option) === null || _c === void 0 ? void 0 : _c.value;
39
+ const isBringingDog = view.state.values.dog_block.dog
40
+ .selected_options.length > 0;
41
+ const message = view.state.values.message_block.message.value || '';
42
+ const userPresence = {
43
+ office,
44
+ isBringingDog,
45
+ presenceTime,
46
+ message,
47
+ };
48
+ // Save for each selected date
49
+ selectedDates.forEach(date => {
50
+ (0, db_utils_1.savePresence)(userId, date, userPresence);
51
+ });
52
+ }
53
+ function handleUpdateSettings(_body, _view) {
54
+ // eslint-disable-next-line no-console
55
+ console.log('Update Settings');
56
+ }
57
+ function handleAskLunchAction(userId, selectedUserIds, client) {
58
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
59
+ var _a;
60
+ if (selectedUserIds.length === 0) {
61
+ yield client.chat.postEphemeral({
62
+ channel: userId,
63
+ user: userId,
64
+ text: app_copy_const_1.APP_COPY.ACTIONS.NO_USERS_SELECTED,
65
+ });
66
+ return;
67
+ }
68
+ const allUserIds = [userId, ...selectedUserIds];
69
+ const conv = yield client.conversations.open({
70
+ users: allUserIds.join(','),
71
+ });
72
+ yield client.chat.postMessage({
73
+ channel: (_a = conv.channel) === null || _a === void 0 ? void 0 : _a.id,
74
+ text: app_copy_const_1.APP_COPY.ACTIONS.askingAboutLunch(userId),
75
+ });
76
+ yield client.chat.postEphemeral({
77
+ channel: userId,
78
+ user: userId,
79
+ text: app_copy_const_1.APP_COPY.ACTIONS.createdGroupChat(selectedUserIds.length),
80
+ });
81
+ });
82
+ }
83
+ //# sourceMappingURL=action.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.utils.js","sourceRoot":"","sources":["../../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/utils/action.utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function formatDateShort(date: Date): string;
2
+ export declare function formatDateLong(date: Date): string;
3
+ export declare function formatISODateLocal(date: Date): string;
4
+ export declare function getUpcomingWeekdays(numDays?: number): Date[];
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDateShort = formatDateShort;
4
+ exports.formatDateLong = formatDateLong;
5
+ exports.formatISODateLocal = formatISODateLocal;
6
+ exports.getUpcomingWeekdays = getUpcomingWeekdays;
7
+ const data_consts_1 = require("../consts/data.consts");
8
+ function formatDateShort(date) {
9
+ const dayName = data_consts_1.WEEKDAYS[date.getDay()];
10
+ const d = String(date.getDate()).padStart(2, '0');
11
+ const m = String(date.getMonth() + 1).padStart(2, '0');
12
+ return `${dayName} ${d}/${m}`;
13
+ }
14
+ function formatDateLong(date) {
15
+ const dayName = data_consts_1.WEEKDAYS[date.getDay()];
16
+ const dayNumber = date.getDate();
17
+ const monthName = data_consts_1.MONTHS[date.getMonth()];
18
+ return `${dayName}, ${dayNumber} ${monthName}`;
19
+ }
20
+ function addDays(date, days) {
21
+ const copy = new Date(date);
22
+ copy.setDate(copy.getDate() + days);
23
+ return copy;
24
+ }
25
+ function formatISODateLocal(date) {
26
+ const y = date.getFullYear();
27
+ const m = String(date.getMonth() + 1).padStart(2, '0');
28
+ const d = String(date.getDate()).padStart(2, '0');
29
+ return `${y}-${m}-${d}`;
30
+ }
31
+ function getUpcomingWeekdays(numDays = 10) {
32
+ const today = new Date();
33
+ const days = [];
34
+ for (let i = 0; i < numDays; i++) {
35
+ const d = addDays(today, i);
36
+ const day = d.getDay();
37
+ if (day >= 1 && day <= 5) {
38
+ days.push(d);
39
+ }
40
+ }
41
+ return days;
42
+ }
43
+ //# sourceMappingURL=date.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.utils.js","sourceRoot":"","sources":["../../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/utils/date.utils.ts"],"names":[],"mappings":";;AAEA,0CAKC;AAED,wCAKC;AAQD,gDAKC;AAED,kDAWC;AAxCD,uDAAyD;AAEzD,SAAgB,eAAe,CAAC,IAAU;IACxC,MAAM,OAAO,GAAG,sBAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAChC,CAAC;AAED,SAAgB,cAAc,CAAC,IAAU;IACvC,MAAM,OAAO,GAAG,sBAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,oBAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,OAAO,GAAG,OAAO,KAAK,SAAS,IAAI,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,OAAO,CAAC,IAAU,EAAE,IAAY;IACvC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAAU;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAAO,GAAG,EAAE;IAC9C,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,MAAM,IAAI,GAAW,EAAE,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { UserPresence, UserPresences } from '../types';
2
+ export declare function loadAllPresences(): UserPresences;
3
+ export declare function savePresence(userId: string, date: string, presence: UserPresence): void;
4
+ export declare function deletePresence(userId: string, date: string): void;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadAllPresences = loadAllPresences;
4
+ exports.savePresence = savePresence;
5
+ exports.deletePresence = deletePresence;
6
+ const Database = require("better-sqlite3");
7
+ const date_utils_1 = require("./date.utils");
8
+ const db = new Database('state.db');
9
+ db.prepare(`
10
+ CREATE TABLE IF NOT EXISTS user_presences (
11
+ user_id TEXT NOT NULL,
12
+ date TEXT NOT NULL,
13
+ office TEXT,
14
+ presence_time TEXT,
15
+ is_bringing_dog INTEGER,
16
+ message TEXT,
17
+ PRIMARY KEY (user_id, date)
18
+ )
19
+ `).run();
20
+ function loadAllPresences() {
21
+ const rows = db
22
+ .prepare('SELECT * FROM user_presences')
23
+ .all();
24
+ const result = {};
25
+ const todayISO = (0, date_utils_1.formatISODateLocal)(new Date());
26
+ for (const r of rows) {
27
+ if (r.date < todayISO)
28
+ continue;
29
+ if (!result[r.user_id])
30
+ result[r.user_id] = {};
31
+ result[r.user_id][r.date] = {
32
+ office: r.office,
33
+ presenceTime: r.presence_time,
34
+ isBringingDog: !!r.is_bringing_dog,
35
+ message: r.message,
36
+ };
37
+ }
38
+ return result;
39
+ }
40
+ function savePresence(userId, date, presence) {
41
+ var _a;
42
+ db.prepare(`
43
+ INSERT INTO user_presences
44
+ (user_id, date, office, presence_time, is_bringing_dog, message)
45
+ VALUES (@user_id, @date, @office, @presence_time, @is_bringing_dog, @message)
46
+ ON CONFLICT(user_id, date) DO UPDATE SET
47
+ office=excluded.office,
48
+ presence_time=excluded.presence_time,
49
+ is_bringing_dog=excluded.is_bringing_dog,
50
+ message=excluded.message
51
+ `).run({
52
+ user_id: userId,
53
+ date,
54
+ office: presence.office,
55
+ presence_time: (_a = presence.presenceTime) !== null && _a !== void 0 ? _a : null,
56
+ is_bringing_dog: presence.isBringingDog ? 1 : 0,
57
+ message: presence.message,
58
+ });
59
+ }
60
+ function deletePresence(userId, date) {
61
+ db.prepare(`
62
+ DELETE FROM user_presences
63
+ WHERE user_id = ? AND date = ?
64
+ `).run(userId, date);
65
+ }
66
+ //# sourceMappingURL=db.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.utils.js","sourceRoot":"","sources":["../../../../../../../libs/@vigilant-broccoli/slackbots/src/office-presence-app/utils/db.utils.ts"],"names":[],"mappings":";;AAoBA,4CAiBC;AAED,oCAwBC;AAED,wCAOC;AAvED,2CAA2C;AAC3C,6CAAkD;AAElD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;AAEpC,EAAE,CAAC,OAAO,CACR;;;;;;;;;;CAUD,CACA,CAAC,GAAG,EAAE,CAAC;AAER,SAAgB,gBAAgB;IAC9B,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,8BAA8B,CAAC;SACvC,GAAG,EAAuB,CAAC;IAC9B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAA,+BAAkB,EAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,GAAG,QAAQ;YAAE,SAAS;QAChC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAC/C,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,YAAY,EAAE,CAAC,CAAC,aAAa;YAC7B,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe;YAClC,OAAO,EAAE,CAAC,CAAC,OAAO;SACnB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,YAAY,CAC1B,MAAc,EACd,IAAY,EACZ,QAAsB;;IAEtB,EAAE,CAAC,OAAO,CACR;;;;;;;;;GASD,CACA,CAAC,GAAG,CAAC;QACJ,OAAO,EAAE,MAAM;QACf,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,aAAa,EAAE,MAAA,QAAQ,CAAC,YAAY,mCAAI,IAAI;QAC5C,eAAe,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,cAAc,CAAC,MAAc,EAAE,IAAY;IACzD,EAAE,CAAC,OAAO,CACR;;;KAGC,CACF,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { AppHomeOpenedEvent } from '@slack/types';
2
+ import { AppConfig } from '../types';
3
+ import { WebClient } from '@slack/web-api';
4
+ import { BlockAction, SlackViewAction } from '@slack/bolt';
5
+ export declare function createPublishHomeView(appConfig: AppConfig): (client: WebClient, source: BlockAction | AppHomeOpenedEvent | SlackViewAction) => Promise<void>;
6
+ export declare function buildModalDateOptionSlackBlocks(dates: Date[]): {
7
+ text: {
8
+ type: string;
9
+ text: string;
10
+ };
11
+ value: string;
12
+ }[];