Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Commit

Permalink
First release
Browse files Browse the repository at this point in the history
  • Loading branch information
attepulkkinen committed May 24, 2022
0 parents commit fa0b93b
Show file tree
Hide file tree
Showing 21 changed files with 3,766 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SLACK_SIGNING_SECRET=
SLACK_BOT_TOKEN=
SLACK_APP_TOKEN=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.env
db.sqlite3
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Seat King 👑
24 changes: 24 additions & 0 deletions actions_listeners/edit_teams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const teamModal = require("../views/team_modal");
const knex = require('../db.js');

module.exports = async ({body, client, ack, logger}) => {
await ack();
logger.info("edit_teams", body)
try {
const teams = await knex('teams')
.where('server_id', body.team.id)
.select('*');

await client.views.open({
trigger_id: body.trigger_id,
view: await teamModal(teams.map((team) => {
return {
name: team.name,
id: '' + team.id,
};
})),
});
} catch (error) {
logger.error(error);
}
};
36 changes: 36 additions & 0 deletions actions_listeners/edit_teams_select_team.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const teamModal = require("../views/team_modal");
const knex = require("../db");
const {findSelectedOption} = require("../helpers");

module.exports = async ({body, client, ack, logger}) => {
await ack();
logger.info("edit_teams_select_team", body)
try {
const teams = await knex('teams')
.where('server_id', body.team.id)
.select('*');

const selectedTeamId = findSelectedOption(body.view.state, 'edit_teams_select_team');

const currentMembersOfTeam = await knex('memberships')
.where('team_id', selectedTeamId)
.select('user_id');

await client.views.update({
view_id: body.view.id,
hash: body.view.hash,
view: await teamModal(
teams.map((team) => {
return {
name: team.name,
id: '' + team.id,
};
}),
selectedTeamId,
currentMembersOfTeam.map(membership => membership.user_id)
),
});
} catch (error) {
logger.error(error);
}
};
34 changes: 34 additions & 0 deletions actions_listeners/edit_teams_submit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const {findSelectedOption, findSelectedUsers} = require("../helpers");
const knex = require("../db");

module.exports = async ({body, view, ack, logger}) => {
await ack();
logger.info("edit_teams_submit", body)
try {
const selectedTeamId = findSelectedOption(view.state, 'edit_teams_select_team');
const selectedMembers = findSelectedUsers(view.state, 'edit_teams_select_members');

const currentMembers = (await knex('memberships')
.where('team_id', selectedTeamId)
.select('user_id'))
.map((membership) => membership.user_id);

const membersToBeAdded = selectedMembers.filter(x => !currentMembers.includes(x));
const membersToBeRemoved = currentMembers.filter(x => !selectedMembers.includes(x));

if(membersToBeAdded.length > 0) {
await knex('memberships')
.insert(membersToBeAdded.map((user) => ({ team_id: selectedTeamId, user_id: user })));
}

if(membersToBeRemoved.length > 0) {
await knex('memberships')
.where('team_id', selectedTeamId)
.whereIn('user_id', membersToBeRemoved)
.del();
}

} catch (error) {
logger.error(error);
}
};
28 changes: 28 additions & 0 deletions actions_listeners/set_status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const homeView = require("../views/home_tab");
const {insertOrUpdate, ensureUserExist} = require("../helpers");

module.exports = async ({body, client, ack, logger}) => {
await ack();
try {
await ensureUserExist(body.user.id, body.user.team_id, body.user.name);

await insertOrUpdate(
'deskings',
{
user_id: body.user.id,
server_id: body.user.team_id,
date: body.actions[0].value,
},
{
status: body.actions[0].action_id.replace('set_', '')
}
);

await client.views.publish({
user_id: body.user.id,
view: await homeView(body.user.id, body.user.team_id),
});
} catch (error) {
logger.error(error);
}
};
3 changes: 3 additions & 0 deletions db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const knex = require('knex')(require('./knexfile.js'));

module.exports = knex;
14 changes: 14 additions & 0 deletions event_listeners/app_home_opened.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const homeView = require('../views/home_tab')

module.exports = async ({event, client, logger}) => {
try {
if (event.tab !== 'home') return;

await client.views.publish({
user_id: event.user,
view: await homeView(event.user, event.view.team_id),
});
} catch (error) {
logger.error(error);
}
};
84 changes: 84 additions & 0 deletions helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const knex = require('./db.js');
const util = require("util");

function getIcon(state) {
switch (state) {
case 'remote':
return ':house: Remote';
case 'office':
return ':office: Office';
case 'ooo':
return ':desert_island: Out of Office';
default:
return ':warning: Not selected'
}
}

function findSelectedOption(state, name) {
return Object.keys(state.values)
.filter((id) => state.values[id].hasOwnProperty(name))
.map((id) => state.values[id])[0][name].selected_option.value;
}

function findSelectedUsers(state, name) {
return Object.keys(state.values)
.filter((id) => state.values[id].hasOwnProperty(name))
.map((id) => state.values[id])[0][name].selected_users;
}

function log(...msgs) {
console.log(util.inspect(msgs, {showHidden: false, depth: null, colors: true}))
}

async function insertIfNotExist(tableName, keys, values) {
const value = await knex(tableName)
.where(keys)
.first()

if (value === undefined) {
await knex(tableName).insert({
...keys,
...values
})
}
}

async function insertOrUpdate(tableName, keys, values) {
const value = await knex(tableName)
.where(keys)
.first()

if (value === undefined) {
await knex(tableName).insert({
...keys,
...values
})
} else {
await knex(tableName)
.where(keys)
.update(values)
}
}

async function ensureUserExist(userId, serverId, name) {
await insertIfNotExist(
'users',
{
id: userId,
server_id: serverId,
},
{
name: name,
}
);
}

module.exports = {
getIcon,
log,
findSelectedOption,
findSelectedUsers,
insertIfNotExist,
insertOrUpdate,
ensureUserExist,
}
39 changes: 39 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use strict";

const {App, LogLevel } = require('@slack/bolt');
const {log} = require("./helpers");
require("dotenv").config();

const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true,
appToken: process.env.SLACK_APP_TOKEN,
port: process.env.PORT || 3000,
logLevel: LogLevel.INFO,
logger: {
debug: log,
info: log,
warn: log,
error: log,
setLevel: (level) => {
},
getLevel: () => {
},
setName: (name) => {
},
},
});

app.event('app_home_opened', require('./event_listeners/app_home_opened'));

app.action(/^set_(remote|office|ooo)$/, require('./actions_listeners/set_status'));

app.action('edit_teams', require('./actions_listeners/edit_teams'));
app.action('edit_teams_select_team', require('./actions_listeners/edit_teams_select_team'));
app.view('edit_teams_submit', require('./actions_listeners/edit_teams_submit'));

(async () => {
await app.start();
log('⚡️ Bolt app is running!');
})();
8 changes: 8 additions & 0 deletions knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
client: 'sqlite3',
connection: {
filename: './db.sqlite3'
},
debug: true,
useNullAsDefault: true
};
20 changes: 20 additions & 0 deletions migrations/20220524134506_create_teams_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable('teams', (table) => {
table.increments('id');
table.string('server_id', 15);
table.string('name');
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable('teams');
}

22 changes: 22 additions & 0 deletions migrations/20220524134543_create_users_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable('users', (table) => {
table.string('id', 15);
table.string('server_id', 15);
table.string('name');

table.unique(['id', 'server_id']);
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable('users');
}

23 changes: 23 additions & 0 deletions migrations/20220524140703_create_deskings_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable('deskings', (table) => {
table.string('server_id', 15);
table.string('user_id', 15);
table.datetime('date');
table.string('status');

table.unique(['user_id', 'server_id', 'date']);
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable('deskings');
}

23 changes: 23 additions & 0 deletions migrations/20220524180704_create_memberships_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable('memberships', (table) => {
table.integer('team_id').unsigned();
table.foreign('team_id').references('id').inTable('teams');

table.string('user_id', 15);
table.foreign('user_id').references('id').inTable('users');

table.unique(['team_id', 'user_id']);
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable('memberships');
};
Loading

0 comments on commit fa0b93b

Please sign in to comment.