Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: #quickwin #162

Merged
merged 25 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions config/Migrations/20240302162526_TaggedMessages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class TaggedMessages extends AbstractMigration
{
/**
* Up Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-up-method
* @return void
*/
public function up(): void
{
$this->table('tagged_messages', ['id' => false, 'primary_key' => ['id']])
->addColumn('id', 'uuid', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('message', 'string', [
'default' => null,
'limit' => 4096,
'null' => false,
])
->addColumn('permalink', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
cleptric marked this conversation as resolved.
Show resolved Hide resolved
->addColumn('sender_user_id', 'uuid', [
'default' => null,
'limit' => null,
'null' => false,
])
->addColumn('created', 'datetime', [
'default' => null,
'limit' => null,
'null' => true,
])
->addIndex(
[
'sender_user_id',
]
)
->addIndex(
[
'receiver_user_id',
]
)
->addIndex(
[
'permalink',
]
)
->create();

$this->table('messages')
->addColumn('permalink', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
->addIndex(
[
'permalink',
]
)
->update();
}
cleptric marked this conversation as resolved.
Show resolved Hide resolved

/**
* Down Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-down-method
* @return void
*/
public function down(): void
{
$this->table('tagged_messages')->drop()->save();

$this->table('messages')
->removeIndexByName('permalink')
->removeColumn('permalink')
->update();
}
}
2 changes: 2 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
$builder->connect('/', ['controller' => 'Home', 'action' => 'index']);
$builder->connect('/shop', ['controller' => 'Home', 'action' => 'index']);
$builder->connect('/collection', ['controller' => 'Home', 'action' => 'index']);
$builder->connect('/quickwins', ['controller' => 'Home', 'action' => 'index']);
$builder->connect('/profile', ['controller' => 'Home', 'action' => 'index']);
$builder->connect('/settings', ['controller' => 'Home', 'action' => 'index']);

Expand All @@ -77,6 +78,7 @@
$builder->post('/shop/purchase', ['prefix' => 'Api', 'controller' => 'Shop', 'action' => 'purchase']);

$builder->get('/collection', ['prefix' => 'Api', 'controller' => 'Collection', 'action' => 'get']);
$builder->get('/taggedMessages', ['prefix' => 'Api', 'controller' => 'Tags', 'action' => 'get']);
HazAT marked this conversation as resolved.
Show resolved Hide resolved
});
});

Expand Down
18 changes: 18 additions & 0 deletions frontend/src/components/FormattedMessage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<p class="text-sm font-normal py-2.5 text-gray-900 dark:text-white" v-html="formattedMessage">

</p>
</template>

<script>
export default {
props: ['message'],
computed: {
formattedMessage() {
return this.message
.replace(/<(@[^>]+)>/g, (_match, p1) => `<span class="bg-blue-700 p-0.5 px-1 rounded-lg">${p1}</span>`)
.replace(/:potato:/g, '🥔');
},
},
}
</script>
14 changes: 14 additions & 0 deletions frontend/src/components/MainMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
>
Collection
</RouterLink>
<RouterLink
to="/quickwins"
class="rounded-md px-3 py-2 text-sm font-medium text-zinc-900"
:class="{ '!bg-zinc-900 !text-zinc-50': $route.path === '/quickwins' }"
>
#QuickWins
</RouterLink>
</div>
</div>
</div>
Expand Down Expand Up @@ -104,6 +111,13 @@
>
Collection
</RouterLink>
<RouterLink
to="/quickwins"
class="block rounded-md px-3 py-2 text-base font-medium text-zinc-900"
:class="{ '!bg-zinc-900 text-zinc-50': $route.path === '/quickwins' }"
>
Collection
</RouterLink>
</div>
<div class="border-t border-zinc-900 pt-4 pb-3">
<div class="flex items-center px-5">
Expand Down
1 change: 1 addition & 0 deletions frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import './assets/main.css'
store.dispatch('getUsers'),
store.dispatch('getProducts'),
store.dispatch('getCollection'),
store.dispatch('getTaggedMessages'),
])

app
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ const router = createRouter({
name: 'collection',
component: () => import('@/views/Collection.vue')
},
{
path: '/quickwins',
name: 'quickwins',
component: () => import('@/views/Quickwins.vue')
},
{
path: '/profile',
name: 'profile',
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const store = createStore({
users: [],
products: [],
collection: [],
taggedMessages: [],
filter: {
range: helper.getRangeFilter(),
order: helper.getOrderFilter(),
Expand All @@ -22,6 +23,7 @@ const store = createStore({
users: state => state.users,
products: state => state.products,
collection: state => state.collection,
taggedMessages: state => state.taggedMessages,
filter: state => state.filter,
range: state => state.filter.range,
order: state => state.filter.order,
Expand Down Expand Up @@ -71,6 +73,14 @@ const store = createStore({
console.log(error)
}
},
async getTaggedMessages({ commit }) {
try {
const response = await api.get('taggedMessages')
commit('SET_TAGGEDMESSAGES', response.data)
} catch (error) {
console.log(error)
}
},
async toggleSentNotifications({ commit, getters }) {
commit('TOGGLE_SENT_NOTIFICATIONS')
try {
Expand Down Expand Up @@ -110,6 +120,9 @@ const store = createStore({
SET_COLLECTION(state, collection) {
state.collection = collection
},
SET_TAGGEDMESSAGES(state, taggedMessages) {
state.taggedMessages = taggedMessages
},
TOGGLE_SENT_NOTIFICATIONS(state) {
state.user.notifications.sent = !state.user.notifications.sent
},
Expand Down
59 changes: 59 additions & 0 deletions frontend/src/views/Quickwins.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div
v-if="taggedMessages.length"
class="grid grid-cols-1 gap-y-12 sm:grid-cols-2 sm:gap-x-6 lg:grid-cols-4 xl:gap-x-8 mb-32"
>
<div
v-for="(item, index) in taggedMessages"
class="h-full flex flex-col"
>
<div
:index="index"
class="relative"
>
<div class="flex items-start gap-2.5">
<img class="w-8 h-8 rounded-full" :src="item.user.slack_picture" :alt="item.user.slack_name">
<div class="flex flex-col w-full max-w-[320px] leading-1.5 p-4 border-gray-200 bg-gray-100 rounded-e-xl rounded-es-xl dark:bg-gray-700">
<div class="flex items-center space-x-2 rtl:space-x-reverse">
<span class="text-sm font-semibold text-gray-900 dark:text-white">{{item.user.slack_name}}</span>
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">{{ new Date(item.created).toLocaleDateString('en-us', { year:"numeric", month:"short", day:"numeric"}) }}</span>
</div>
<FormattedMessage :message="item.message" />
<span v-if="item.reaction_count >= 2" class="relative text-sm font-normal text-gray-500 dark:text-gray-400">
<span v-for="(i, index2) in item.reaction_count" :key="i" :class="index2 === 0 ? '' : '-ml-2'">🥔</span>
</span>
</div>
</div>
</div>
</div>
</div>
<div
v-else
class="absolute inset-0 flex items-center justify-center"
>
<h1 class="text-2xl font-extrabold">
No #quickwins recorded yet
</h1>
</div>
</template>

<script>
import { computed } from 'vue'
import { useStore } from 'vuex'
import FormattedMessage from '../components/FormattedMessage.vue';

export default {
name: 'Quickwins',
components: {
FormattedMessage,
},
setup() {
const store = useStore()

return {
taggedMessages: computed(() => store.getters.taggedMessages),
}
},
}

</script>
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions src/Controller/Api/TagsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);

namespace App\Controller\Api;

use Cake\Http\Response;

/**
* @property \Authentication\Controller\Component\AuthenticationComponent $Authentication
*/
class TagsController extends ApiController
{
/**
* @return \Cake\Http\Response
*/
public function get(): Response
{
$taggedMessagesTable = $this->fetchTable('TaggedMessages');
$messages = $this->fetchTable('Messages');

$collection = $taggedMessagesTable->find();
$collection->contain(['Users']);

$collection->orderBy(['TaggedMessages.created' => 'DESC'])
->enableAutoFields(true)
->all();

$collectedUsersInMessages = [];
foreach ($collection as $taggedMessage) {
$reactionCount = $messages->find()
->where(['permalink' => $taggedMessage->permalink])
->count();
$taggedMessage->reaction_count = $reactionCount;
// extract all user ids from message: "<@U042CECCR7A> has tagged you in a message"
preg_match_all('/<@([A-Z0-9]+)>/', $taggedMessage->message, $matches);
$collectedUsersInMessages += $matches[1];
$taggedMessage->tagged_users = $matches[1];
}

$usersTable = $this->fetchTable('Users');
$users = $usersTable->find()
->where(['Users.slack_user_id IN' => array_unique($collectedUsersInMessages)])
->all();

foreach ($collection as $taggedMessage) {
foreach ($users as $markedUsers) {
// replace all user ids with user names
$taggedMessage->message = str_replace(
"<@{$markedUsers->slack_user_id}>",
"<@{$markedUsers->slack_name}>",
$taggedMessage->message
);
}
}
cleptric marked this conversation as resolved.
Show resolved Hide resolved

return $this->response
->withStatus(200)
->withType('json')
->withStringBody(json_encode($collection));
}
}
13 changes: 13 additions & 0 deletions src/Event/MessageEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Service\AwardService;
use App\Service\NotificationService;
use App\Service\UserService;
use App\Service\TaggedMessageService;

class MessageEvent extends AbstractEvent
{
Expand Down Expand Up @@ -53,6 +54,7 @@ public function process(): void
$userService = new UserService();
$awardService = new AwardService();
$notificationService = new NotificationService();
$taggedMessagesService = new TaggedMessageService();

$fromUser = $userService->getOrCreateUser($this->sender);
$validator = new Validation(
Expand Down Expand Up @@ -87,6 +89,17 @@ public function process(): void
toUsers: $toUsers,
event: $this,
);
$quickwinId = $taggedMessagesService->storeMessageIfTagged(
fromUser: $fromUser,
event: $this,
);
if ($quickwinId !== false) {
$notificationService->notifyChannelNewQuickwin(
fromUser: $fromUser,
taggedMessageId: $quickwinId,
event: $this
);
}
$notificationService->notifyUsers(
fromUser: $fromUser,
toUsers: $toUsers,
Expand Down
Loading
Loading