feat: add notification dialog component and integrate with main layout
This commit is contained in:
parent
ede8e80181
commit
65bf510386
3 changed files with 370 additions and 22 deletions
|
|
@ -1,10 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, computed, reactive } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { getUserId, getUsername, logout, getRole } from 'src/services/keycloak';
|
||||
import { Icon } from '@iconify/vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import moment from 'moment';
|
||||
|
||||
import useLoader from 'stores/loader';
|
||||
import ProfileMenu from './ProfileMenu.vue';
|
||||
|
|
@ -18,8 +19,7 @@ import { useNavigator } from 'src/stores/navigator';
|
|||
import { initLang, initTheme, Lang, setLang } from 'src/utils/ui';
|
||||
import { baseUrl } from 'stores/utils';
|
||||
import { useNotification } from 'src/stores/notification';
|
||||
import moment from 'moment';
|
||||
import { computed } from 'vue';
|
||||
import NotiDialog from 'src/pages/00_notification/NotiDialog.vue';
|
||||
|
||||
const useMyBranch = useMyBranchStore();
|
||||
const { fetchListMyBranch } = useMyBranch;
|
||||
|
|
@ -47,7 +47,6 @@ const canvasModal = ref(false);
|
|||
const leftDrawerOpen = ref<boolean>(false);
|
||||
const leftDrawerMini = ref(false);
|
||||
|
||||
const filterUnread = ref(false);
|
||||
const unread = computed<number>(
|
||||
() => notificationData.value.filter((v) => !v.read).length || 0,
|
||||
);
|
||||
|
|
@ -66,15 +65,20 @@ const language: {
|
|||
{ value: Lang.English, label: 'English', icon: 'us', date: 'en-gb' },
|
||||
];
|
||||
|
||||
const notiOpen = ref(false);
|
||||
const state = reactive({
|
||||
filterUnread: false,
|
||||
notiOpen: false,
|
||||
notiDialog: false,
|
||||
notiId: '',
|
||||
});
|
||||
const notiMenu = ref<NotificationButton[]>([
|
||||
{
|
||||
item: 'ทั้งหมด',
|
||||
item: 'all',
|
||||
color: 'noti-switch-on',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
item: 'ยังไม่ได้อ่าน',
|
||||
item: 'unread',
|
||||
color: 'noti-switch-off',
|
||||
active: false,
|
||||
},
|
||||
|
|
@ -86,12 +90,12 @@ function setActive(button: NotificationButton) {
|
|||
color: current.item !== button.item ? 'noti-switch-off' : 'noti-switch-on',
|
||||
active: current.item === button.item,
|
||||
}));
|
||||
if (button.item === 'ยังไม่ได้อ่าน') {
|
||||
if (button.item === 'unread') {
|
||||
// noti.value?.result &&
|
||||
filterUnread.value = true;
|
||||
state.filterUnread = true;
|
||||
}
|
||||
if (button.item === 'ทั้งหมด') {
|
||||
filterUnread.value = false;
|
||||
if (button.item === 'all') {
|
||||
state.filterUnread = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +114,11 @@ function doLogout() {
|
|||
});
|
||||
}
|
||||
|
||||
function readNoti(id: string) {
|
||||
state.notiDialog = true;
|
||||
state.notiId = id;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
initTheme();
|
||||
initLang();
|
||||
|
|
@ -281,7 +290,7 @@ onMounted(async () => {
|
|||
:size="$q.screen.lt.sm ? 'sm' : ''"
|
||||
:class="{ bordered: $q.dark.isActive, dark: $q.dark.isActive }"
|
||||
style="color: var(--surface-1)"
|
||||
@click="notiOpen = !notiOpen"
|
||||
@click="state.notiOpen = !state.notiOpen"
|
||||
>
|
||||
<q-icon name="mdi-bell" />
|
||||
<q-badge v-if="unread !== 0" rounded floating color="negative">
|
||||
|
|
@ -292,10 +301,16 @@ onMounted(async () => {
|
|||
:offset="[0, 10]"
|
||||
anchor="bottom middle"
|
||||
self="top middle"
|
||||
@before-hide="notiOpen = false"
|
||||
@before-hide="
|
||||
() => {
|
||||
state.notiOpen = false;
|
||||
}
|
||||
"
|
||||
>
|
||||
<div class="q-px-md q-py-sm row col-12 items-center">
|
||||
<div class="text-subtitle1 text-weight-bold">แจ้งเตือน</div>
|
||||
<div class="text-subtitle1 text-weight-bold">
|
||||
{{ $t('noti.title') }}
|
||||
</div>
|
||||
<q-space />
|
||||
</div>
|
||||
<div class="q-px-md q-pb-md q-gutter-x-md">
|
||||
|
|
@ -307,22 +322,29 @@ onMounted(async () => {
|
|||
:flat="!btn.active"
|
||||
:unelevated="btn.active"
|
||||
:key="index"
|
||||
:label="btn.item"
|
||||
:label="$t('noti.' + btn.item)"
|
||||
:class="btn.color"
|
||||
@click="setActive(btn)"
|
||||
/>
|
||||
</div>
|
||||
<div style="max-height: 30vh; overflow-y: auto">
|
||||
<div class="caption cursor-pointer">
|
||||
<div style="max-height: 30vh; width: 400px; overflow-y: auto">
|
||||
<section
|
||||
v-if="
|
||||
state.filterUnread
|
||||
? notificationData.filter((v) => !v.read).length
|
||||
: notificationData.length
|
||||
"
|
||||
class="caption cursor-pointer"
|
||||
>
|
||||
<q-item
|
||||
v-for="(item, i) in state.filterUnread
|
||||
? notificationData.filter((v) => !v.read)
|
||||
: notificationData"
|
||||
dense
|
||||
clickable
|
||||
class="q-py-sm"
|
||||
v-ripple
|
||||
v-for="(item, i) in filterUnread
|
||||
? notificationData.filter((v) => !v.read)
|
||||
: notificationData"
|
||||
@click="notificationStore.getNotification(item.id)"
|
||||
@click="readNoti(item.id)"
|
||||
:key="i"
|
||||
>
|
||||
<q-avatar
|
||||
|
|
@ -354,7 +376,23 @@ onMounted(async () => {
|
|||
{{ item.detail }}
|
||||
</q-tooltip>
|
||||
</q-item>
|
||||
</div>
|
||||
</section>
|
||||
<section v-else class="text-center q-py-sm">
|
||||
<span class="app-text-muted">
|
||||
{{ $t('general.noData') }}
|
||||
</span>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col bordered-t">
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
color="info"
|
||||
class="full-width"
|
||||
@click="() => $router.push('/notification')"
|
||||
>
|
||||
{{ $t('noti.viewAll') }}
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
|
|
@ -455,6 +493,8 @@ onMounted(async () => {
|
|||
</template>
|
||||
</DialogForm>
|
||||
|
||||
<NotiDialog v-model="state.notiDialog" v-model:id="state.notiId" />
|
||||
|
||||
<global-loading :visibility="visible" />
|
||||
</q-layout>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue