feat: Improve the initial screen placeholder (#7708)

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese
2023-08-15 06:20:34 +05:30
committed by GitHub
parent ebefb2e201
commit 396ef02b0c
11 changed files with 248 additions and 137 deletions

View File

@@ -61,7 +61,7 @@ import { mapGetters } from 'vuex';
import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel';
import ConversationHeader from './ConversationHeader';
import DashboardAppFrame from '../DashboardApp/Frame.vue';
import EmptyState from './EmptyState';
import EmptyState from './EmptyState/EmptyState';
import MessagesView from './MessagesView';
export default {

View File

@@ -10,45 +10,40 @@
class="clearfix"
>
<onboarding-view v-if="isAdmin" />
<div v-else class="current-chat">
<div>
<img src="~dashboard/assets/images/inboxes.svg" alt="No Inboxes" />
<span>
{{ $t('CONVERSATION.NO_INBOX_AGENT') }}
</span>
</div>
</div>
<empty-state-message
v-else
:message="$t('CONVERSATION.NO_INBOX_AGENT')"
/>
</div>
<!-- Show empty state images if not loading -->
<div
v-else-if="!uiFlags.isFetching && !loadingChatList"
class="current-chat"
class="flex flex-col items-center justify-center h-full"
>
<!-- No conversations available -->
<div v-if="!allConversations.length">
<img src="~dashboard/assets/images/chat.svg" alt="No Chat" />
<span>
{{ $t('CONVERSATION.NO_MESSAGE_1') }}
<br />
</span>
</div>
<!-- No conversation selected -->
<div v-else-if="allConversations.length && !currentChat.id">
<img src="~dashboard/assets/images/chat.svg" alt="No Chat" />
<span>{{ conversationMissingMessage }}</span>
</div>
<empty-state-message
v-if="!allConversations.length"
:message="$t('CONVERSATION.NO_MESSAGE_1')"
/>
<empty-state-message
v-else-if="allConversations.length && !currentChat.id"
:message="conversationMissingMessage"
/>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import adminMixin from '../../../mixins/isAdmin';
import accountMixin from '../../../mixins/account';
import OnboardingView from './OnboardingView';
import adminMixin from 'dashboard/mixins/isAdmin';
import accountMixin from 'dashboard/mixins/account';
import OnboardingView from '../OnboardingView';
import EmptyStateMessage from './EmptyStateMessage';
export default {
components: {
OnboardingView,
EmptyStateMessage,
},
mixins: [accountMixin, adminMixin],
props: {
@@ -87,51 +82,10 @@ export default {
!this.loadingChatList &&
this.isAdmin
) {
return 'inbox-empty-state';
return 'h-full overflow-auto';
}
return 'columns conv-empty-state';
return 'flex-1 min-w-0 px-0 flex flex-col items-center justify-center h-full';
},
},
};
</script>
<style lang="scss" scoped>
.inbox-empty-state {
height: 100%;
overflow: auto;
}
.current-chat {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
img {
margin: var(--space-normal);
width: 6.25rem;
}
span {
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
text-align: center;
}
}
}
.conv-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<div class="flex flex-col items-center justify-center h-full">
<img
class="m-4 w-32 hidden dark:block"
src="~dashboard/assets/images/no-chat-dark.svg"
alt="No Chat dark"
/>
<img
class="m-4 w-32 block dark:hidden"
src="~dashboard/assets/images/no-chat.svg"
alt="No Chat"
/>
<span
class="text-sm text-slate-800 dark:text-slate-200 font-medium text-center"
>
{{ message }}
<br />
</span>
<!-- Cmd bar, keyboard shortcuts placeholder -->
<feature-placeholder />
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true,
},
},
};
</script>

View File

@@ -0,0 +1,51 @@
<template>
<div class="flex flex-col gap-2 mt-9">
<div
v-for="keyShortcut in keyShortcuts"
:key="keyShortcut.key"
class="flex gap-2 items-center"
>
<div class="flex gap-2 items-center">
<hotkey
custom-class="h-6 w-8 text-sm font-medium text-slate-700 dark:text-slate-100 bg-slate-100 dark:bg-slate-700 border-b-2 border-slate-300 dark:border-slate-500"
>
</hotkey>
<hotkey
custom-class="h-6 w-8 text-sm font-medium text-slate-700 dark:text-slate-100 bg-slate-100 dark:bg-slate-700 border-b-2 border-slate-300 dark:border-slate-500"
>
{{ keyShortcut.key }}
</hotkey>
</div>
<span
class="text-sm text-slate-700 dark:text-slate-300 font-medium text-center"
>
{{ keyShortcut.description }}
</span>
</div>
</div>
</template>
<script>
import Hotkey from 'dashboard/components/base/Hotkey';
export default {
components: {
Hotkey,
},
data() {
return {
keyShortcuts: [
{
key: 'K',
description: this.$t('CONVERSATION.EMPTY_STATE.CMD_BAR'),
},
{
key: '/',
description: this.$t('CONVERSATION.EMPTY_STATE.KEYBOARD_SHORTCUTS'),
},
],
};
},
};
</script>

View File

@@ -4,22 +4,18 @@
<woot-modal-header
:header-title="$t('SIDEBAR_ITEMS.KEYBOARD_SHORTCUTS')"
/>
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-8 mt-6">
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-4 mt-6">
<div class="flex justify-between items-center min-w-[25rem]">
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TOGGLE_MODAL') }}
</h5>
<div class="flex items-center mb-1 ml-2">
<p
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
<div class="flex items-center mb-1 ml-2 gap-2">
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
</p>
<p
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
</hotkey>
<hotkey custom-class="min-h-[28px] min-w-[36px] key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
</p>
</hotkey>
</div>
</div>
</div>
@@ -29,34 +25,26 @@
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TITLE.OPEN_CONVERSATION') }}
</h5>
<div class="flex items-center mb-1 ml-2">
<div class="flex mr-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
<div class="flex items-center mb-1 ml-2 gap-2">
<div class="flex gap-2">
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
</hotkey>
<hotkey custom-class="min-h-[28px] w-9 key">
J
</span>
</hotkey>
<span
class="flex items-center font-semibold text-sm text-slate-800 dark:text-slate-100"
>
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
</span>
</div>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
</hotkey>
<hotkey custom-class="w-9 key">
K
</span>
</hotkey>
</div>
</div>
@@ -64,22 +52,16 @@
<h5 class="text-sm text-slate-800 dark:text-slate-100">
{{ $t('KEYBOARD_SHORTCUTS.TITLE.RESOLVE_AND_NEXT') }}
</h5>
<div class="flex items-center mb-1 ml-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
<div class="flex items-center mb-1 ml-2 gap-2">
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
</span>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
>
</hotkey>
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
</span>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
>
</hotkey>
<hotkey custom-class="w-9 key">
E
</span>
</hotkey>
</div>
</div>
<div
@@ -87,20 +69,22 @@
:key="shortcutKey.id"
class="flex justify-between items-center min-w-[25rem]"
>
<h5 class="text-sm text-slate-800 dark:text-slate-100">
<h5 class="text-sm text-slate-800 min-w-[36px] dark:text-slate-100">
{{ title(shortcutKey) }}
</h5>
<div class="flex items-center mb-1 ml-2">
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
<div class="flex items-center mb-1 ml-2 gap-2">
<hotkey
:class="{ 'min-w-[60px]': shortcutKey.firstKey !== 'Up' }"
custom-class="min-h-[28px] normal-case key"
>
{{ shortcutKey.firstkey }}
</span>
<span
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
{{ shortcutKey.firstKey }}
</hotkey>
<hotkey
:class="{ 'normal-case': shortcutKey.secondKey === 'Down' }"
custom-class="min-h-[28px] min-w-[36px] key"
>
{{ shortcutKey.secondKey }}
</span>
</hotkey>
</div>
</div>
</div>
@@ -111,8 +95,12 @@
<script>
import { mixin as clickaway } from 'vue-clickaway';
import { SHORTCUT_KEYS } from './constants';
import Hotkey from 'dashboard/components/base/Hotkey';
export default {
components: {
Hotkey,
},
mixins: [clickaway],
props: {
show: {
@@ -132,8 +120,8 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.shortcut-key {
@apply py-2 px-2.5;
<style scoped>
.key {
@apply py-2 px-2.5 font-semibold text-xs text-slate-700 dark:text-slate-100 bg-slate-75 dark:bg-slate-900 shadow border-b-2 rtl:border-l-2 ltr:border-r-2 border-slate-200 dark:border-slate-700;
}
</style>

View File

@@ -2,79 +2,79 @@ export const SHORTCUT_KEYS = [
{
id: 1,
label: 'NAVIGATE_DROPDOWN',
firstkey: 'Up',
firstKey: 'Up',
secondKey: 'Down',
},
{
id: 2,
label: 'RESOLVE_CONVERSATION',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'E',
},
{
id: 3,
label: 'GO_TO_CONVERSATION_DASHBOARD',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'C',
},
{
id: 4,
label: 'ADD_ATTACHMENT',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'A',
},
{
id: 5,
label: 'GO_TO_CONTACTS_DASHBOARD',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'V',
},
{
id: 6,
label: 'TOGGLE_SIDEBAR',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'O',
},
{
id: 7,
label: 'GO_TO_REPORTS_SIDEBAR',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'R',
},
{
id: 8,
label: 'MOVE_TO_NEXT_TAB',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'N',
},
{
id: 9,
label: 'GO_TO_SETTINGS',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'S',
},
{
id: 10,
label: 'SWITCH_CONVERSATION_STATUS',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'B',
},
{
id: 11,
label: 'SWITCH_TO_PRIVATE_NOTE',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'P',
},
{
id: 13,
label: 'SWITCH_TO_REPLY',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'L',
},
{
id: 14,
label: 'TOGGLE_SNOOZE_DROPDOWN',
firstkey: 'Alt / ⌥',
firstKey: 'Alt / ⌥',
secondKey: 'M',
},
];