2023-03-22 16:42:54 +08:00
|
|
|
<template>
|
|
|
|
<div class="sci--navigation--top-menu-container">
|
2023-06-15 08:59:34 +08:00
|
|
|
<div v-if="user" class="sci--navigation--top-menu-search left-icon sci-input-container-v2" :class="{'disabled' : !currentTeam}" :title="i18n.t('nav.search')">
|
2023-06-13 18:38:55 +08:00
|
|
|
<input type="text" :placeholder="i18n.t('nav.search')" @change="searchValue"/>
|
|
|
|
<i class="sn-icon sn-icon-search"></i>
|
|
|
|
</div>
|
2023-08-03 21:14:44 +08:00
|
|
|
<div v-if="currentTeam" class="w-64">
|
2023-11-29 06:47:20 +08:00
|
|
|
<SelectDropdown
|
2023-06-13 17:51:00 +08:00
|
|
|
:value="currentTeam"
|
2023-03-22 16:42:54 +08:00
|
|
|
:options="teams"
|
2023-06-13 17:51:00 +08:00
|
|
|
@change="switchTeam"
|
2023-11-29 06:47:20 +08:00
|
|
|
></SelectDropdown>
|
2023-03-22 16:42:54 +08:00
|
|
|
</div>
|
2023-09-22 17:59:39 +08:00
|
|
|
<MenuDropdown
|
|
|
|
class="ml-auto"
|
2023-10-02 20:31:28 +08:00
|
|
|
v-if="settingsMenu && settingsMenu.length > 0"
|
|
|
|
:listItems="settingsMenuItems"
|
2023-10-16 15:52:06 +08:00
|
|
|
:title="i18n.t('nav.settings')"
|
2023-09-22 17:59:39 +08:00
|
|
|
:btnClasses="'btn btn-light icon-btn btn-black'"
|
|
|
|
:position="'right'"
|
|
|
|
:btnIcon="'sn-icon sn-icon-settings'"
|
2024-01-16 00:17:55 +08:00
|
|
|
:data-e2e="'e2e-DD-topMenu-settings'"
|
2023-09-22 17:59:39 +08:00
|
|
|
></MenuDropdown>
|
2024-01-15 23:09:19 +08:00
|
|
|
<GeneralDropdown
|
|
|
|
v-if="user"
|
|
|
|
ref="notificationDropdown"
|
|
|
|
position="right"
|
|
|
|
class="sci--navigation--notificaitons-flyout-container">
|
|
|
|
<template v-slot:field>
|
2024-01-19 18:10:32 +08:00
|
|
|
<button class="btn btn-light icon-btn btn-black" :data-e2e="'e2e-DD-topMenu-notifications'"
|
2023-06-22 17:55:23 +08:00
|
|
|
:title="i18n.t('nav.notifications.title')"
|
2023-04-12 17:14:53 +08:00
|
|
|
:class="{ 'has-unseen': unseenNotificationsCount > 0 }"
|
|
|
|
:data-unseen="unseenNotificationsCount"
|
2024-01-15 23:09:19 +08:00
|
|
|
data-toggle="dropdown">
|
|
|
|
<i class="sn-icon sn-icon-notifications"></i>
|
|
|
|
</button>
|
|
|
|
</template>
|
|
|
|
<template v-slot:flyout >
|
|
|
|
<NotificationsFlyout
|
|
|
|
:notificationsUrl="notificationsUrl"
|
|
|
|
:unseenNotificationsCount="unseenNotificationsCount"
|
|
|
|
@update:unseenNotificationsCount="checkUnseenNotifications()"
|
|
|
|
@close="$refs.notificationDropdown.$refs.field.click();"/>
|
|
|
|
</template>
|
|
|
|
</GeneralDropdown>
|
2023-06-15 08:59:34 +08:00
|
|
|
<div v-if="user" class="dropdown" :title="i18n.t('nav.user_profile')">
|
2024-01-16 00:17:55 +08:00
|
|
|
<div class="sci--navigation--top-menu-user btn btn-light icon-btn btn-black" data-toggle="dropdown" data-e2e="e2e-DD-topMenu-avatar">
|
2023-06-13 18:38:55 +08:00
|
|
|
<img class="avatar w-6 h-6" :src="user.avatar_url">
|
2023-03-22 16:42:54 +08:00
|
|
|
</div>
|
2023-09-22 17:59:39 +08:00
|
|
|
<div class="dropdown-menu dropdown-menu-right rounded !p-2.5 sn-shadow-menu-sm">
|
2023-05-08 20:44:50 +08:00
|
|
|
<li v-for="(item, i) in userMenu" :key="i">
|
2023-09-22 17:59:39 +08:00
|
|
|
<a :href="item.url" class="!px-3 !py-2.5 rounded hover:!bg-sn-super-light-grey !text-sn-blue block">
|
2023-03-22 16:42:54 +08:00
|
|
|
{{ item.name }}
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
2023-09-22 17:59:39 +08:00
|
|
|
<a rel="nofollow" data-method="delete" :href="user.sign_out_url" class="!px-3 !py-2.5 rounded hover:!bg-sn-super-light-grey !text-sn-blue block">
|
2023-03-22 16:42:54 +08:00
|
|
|
{{ i18n.t('nav.user.logout') }}
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2024-01-11 22:40:03 +08:00
|
|
|
/* global HelperModule */
|
2024-01-04 23:34:36 +08:00
|
|
|
import NotificationsFlyout from './notifications/notifications_flyout.vue';
|
2024-01-11 22:14:36 +08:00
|
|
|
import DropdownSelector from '../shared/legacy/dropdown_selector.vue';
|
2024-01-11 22:40:03 +08:00
|
|
|
import SelectDropdown from '../shared/select_dropdown.vue';
|
2024-01-04 23:34:36 +08:00
|
|
|
import MenuDropdown from '../shared/menu_dropdown.vue';
|
2024-01-15 23:09:19 +08:00
|
|
|
import GeneralDropdown from '../shared/general_dropdown.vue';
|
2023-03-22 16:42:54 +08:00
|
|
|
|
2024-01-04 23:34:36 +08:00
|
|
|
export default {
|
|
|
|
name: 'TopMenuContainer',
|
|
|
|
components: {
|
|
|
|
DropdownSelector,
|
|
|
|
NotificationsFlyout,
|
2024-01-11 22:40:03 +08:00
|
|
|
SelectDropdown,
|
2024-01-15 23:09:19 +08:00
|
|
|
MenuDropdown,
|
|
|
|
GeneralDropdown
|
2024-01-04 23:34:36 +08:00
|
|
|
},
|
|
|
|
props: {
|
|
|
|
url: String,
|
|
|
|
notificationsUrl: String,
|
|
|
|
unseenNotificationsUrl: String
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
rootUrl: null,
|
|
|
|
teamSwitchUrl: null,
|
|
|
|
currentTeam: null,
|
|
|
|
teams: null,
|
|
|
|
searchUrl: null,
|
|
|
|
user: null,
|
|
|
|
helpMenu: null,
|
|
|
|
settingsMenu: null,
|
|
|
|
userMenu: null,
|
|
|
|
unseenNotificationsCount: 0
|
|
|
|
};
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
this.fetchData();
|
|
|
|
this.checkUnseenNotifications();
|
2023-04-12 17:14:53 +08:00
|
|
|
|
2024-01-04 23:34:36 +08:00
|
|
|
$(document).on('turbolinks:load', () => {
|
|
|
|
this.notificationsOpened = false;
|
|
|
|
this.checkUnseenNotifications();
|
|
|
|
this.refreshCurrentTeam();
|
|
|
|
});
|
2023-05-09 21:21:07 +08:00
|
|
|
|
2024-01-04 23:34:36 +08:00
|
|
|
// Track name update in user profile settings
|
|
|
|
$(document).on('inlineEditing::updated', '.inline-editing-container[data-field-to-update="full_name"]', this.fetchData);
|
|
|
|
},
|
|
|
|
beforeUnmount() {
|
|
|
|
clearTimeout(this.unseenNotificationsTimeout);
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
settingsMenuItems() {
|
|
|
|
return this.settingsMenu.map((item) => ({ text: item.name, url: item.url })).concat(
|
|
|
|
{
|
|
|
|
text: this.i18n.t('left_menu_bar.support_links.core_version'),
|
|
|
|
modalTarget: '#aboutModal',
|
|
|
|
url: ''
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
fetchData() {
|
|
|
|
$.get(this.url, (result) => {
|
|
|
|
this.rootUrl = result.root_url;
|
|
|
|
this.teamSwitchUrl = result.team_switch_url;
|
|
|
|
this.currentTeam = result.current_team;
|
|
|
|
this.teams = result.teams;
|
|
|
|
this.searchUrl = result.search_url;
|
|
|
|
this.helpMenu = result.help_menu;
|
|
|
|
this.settingsMenu = result.settings_menu;
|
|
|
|
this.userMenu = result.user_menu;
|
|
|
|
this.user = result.user;
|
|
|
|
});
|
2023-11-24 22:32:32 +08:00
|
|
|
},
|
2024-01-04 23:34:36 +08:00
|
|
|
switchTeam(team) {
|
2024-01-11 22:40:03 +08:00
|
|
|
if (this.currentTeam === team) return;
|
2023-03-22 16:42:54 +08:00
|
|
|
|
2024-01-11 22:40:03 +08:00
|
|
|
const newTeam = this.teams.find((e) => e[0] === team);
|
2023-04-21 18:25:42 +08:00
|
|
|
|
2024-01-04 23:34:36 +08:00
|
|
|
if (!newTeam) return;
|
2023-04-21 18:25:42 +08:00
|
|
|
|
2024-01-04 23:34:36 +08:00
|
|
|
$.post(this.teamSwitchUrl, { team_id: team }, (result) => {
|
|
|
|
this.currentTeam = result.current_team;
|
|
|
|
$('body').attr('data-current-team-id', this.currentTeam);
|
|
|
|
window.open(this.rootUrl, '_self');
|
|
|
|
}).fail((msg) => {
|
|
|
|
HelperModule.flashAlertMsg(msg.responseJSON.message, 'danger');
|
|
|
|
});
|
|
|
|
},
|
|
|
|
searchValue(e) {
|
|
|
|
window.open(`${this.searchUrl}?q=${e.target.value}`, '_self');
|
|
|
|
},
|
|
|
|
checkUnseenNotifications() {
|
|
|
|
clearTimeout(this.unseenNotificationsTimeout);
|
|
|
|
$.get(this.unseenNotificationsUrl, (result) => {
|
|
|
|
this.unseenNotificationsCount = result.unseen;
|
|
|
|
this.unseenNotificationsTimeout = setTimeout(this.checkUnseenNotifications, 30000);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
refreshCurrentTeam() {
|
2024-01-11 22:40:03 +08:00
|
|
|
const newTeam = parseInt($('body').attr('data-current-team-id'), 10);
|
2024-01-04 23:34:36 +08:00
|
|
|
if (newTeam !== this.currentTeam) {
|
|
|
|
this.currentTeam = newTeam;
|
2023-03-22 16:42:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-01-04 23:34:36 +08:00
|
|
|
};
|
2023-03-22 16:42:54 +08:00
|
|
|
</script>
|