# Pull Request Template ## Description This PR includes, 1. Adjusting the inbox settings page layout width from 3xl to 4xl for the collaborators, configuration, and bot configuration sections. 2. Adding a dynamic max-width for inbox settings banners based on the selected tab. 3. Making the sender name preview layout responsive. 4. Reordering automation rule row buttons so Clone appears before Delete. 5. Update the Gmail icon ratio. 6. Fix height issues with team/inbox pages 7. The delete button changes to red on hover 8. Add border to conversation header when no dashboard apps present ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules
195 lines
6.2 KiB
Vue
195 lines
6.2 KiB
Vue
<script setup>
|
|
import { computed, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useAlert } from 'dashboard/composables';
|
|
import { picoSearch } from '@scmmishra/pico-search';
|
|
import Avatar from 'next/avatar/Avatar.vue';
|
|
import { useAdmin } from 'dashboard/composables/useAdmin';
|
|
import SettingsLayout from '../SettingsLayout.vue';
|
|
import BaseSettingsHeader from '../components/BaseSettingsHeader.vue';
|
|
import {
|
|
useMapGetter,
|
|
useStoreGetters,
|
|
useStore,
|
|
} from 'dashboard/composables/store';
|
|
import ChannelName from './components/ChannelName.vue';
|
|
import ChannelIcon from 'next/icon/ChannelIcon.vue';
|
|
import Button from 'dashboard/components-next/button/Button.vue';
|
|
|
|
const getters = useStoreGetters();
|
|
const store = useStore();
|
|
const { t } = useI18n();
|
|
const { isAdmin } = useAdmin();
|
|
|
|
const showDeletePopup = ref(false);
|
|
const selectedInbox = ref({});
|
|
const searchQuery = ref('');
|
|
|
|
const inboxes = useMapGetter('inboxes/getInboxes');
|
|
|
|
const inboxesList = computed(() => {
|
|
return inboxes.value?.slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
});
|
|
|
|
const filteredInboxesList = computed(() => {
|
|
const query = searchQuery.value.trim();
|
|
if (!query) return inboxesList.value;
|
|
return picoSearch(inboxesList.value, query, ['name', 'channel_type']);
|
|
});
|
|
|
|
const uiFlags = computed(() => getters['inboxes/getUIFlags'].value);
|
|
|
|
const deleteConfirmText = computed(
|
|
() => `${t('INBOX_MGMT.DELETE.CONFIRM.YES')} ${selectedInbox.value.name}`
|
|
);
|
|
|
|
const deleteRejectText = computed(
|
|
() => `${t('INBOX_MGMT.DELETE.CONFIRM.NO')} ${selectedInbox.value.name}`
|
|
);
|
|
|
|
const confirmDeleteMessage = computed(
|
|
() => `${t('INBOX_MGMT.DELETE.CONFIRM.MESSAGE')} ${selectedInbox.value.name}?`
|
|
);
|
|
const confirmPlaceHolderText = computed(
|
|
() =>
|
|
`${t('INBOX_MGMT.DELETE.CONFIRM.PLACE_HOLDER', {
|
|
inboxName: selectedInbox.value.name,
|
|
})}`
|
|
);
|
|
|
|
const deleteInbox = async ({ id }) => {
|
|
try {
|
|
await store.dispatch('inboxes/delete', id);
|
|
useAlert(t('INBOX_MGMT.DELETE.API.SUCCESS_MESSAGE'));
|
|
} catch (error) {
|
|
useAlert(t('INBOX_MGMT.DELETE.API.ERROR_MESSAGE'));
|
|
}
|
|
};
|
|
const closeDelete = () => {
|
|
showDeletePopup.value = false;
|
|
selectedInbox.value = {};
|
|
};
|
|
|
|
const confirmDeletion = () => {
|
|
deleteInbox(selectedInbox.value);
|
|
closeDelete();
|
|
};
|
|
const openDelete = inbox => {
|
|
showDeletePopup.value = true;
|
|
selectedInbox.value = inbox;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<SettingsLayout
|
|
:no-records-found="!inboxesList.length"
|
|
:no-records-message="$t('INBOX_MGMT.LIST.404')"
|
|
:is-loading="uiFlags.isFetching"
|
|
>
|
|
<template #header>
|
|
<BaseSettingsHeader
|
|
v-model:search-query="searchQuery"
|
|
:title="$t('INBOX_MGMT.HEADER')"
|
|
:description="$t('INBOX_MGMT.DESCRIPTION')"
|
|
:link-text="$t('INBOX_MGMT.LEARN_MORE')"
|
|
:search-placeholder="$t('INBOX_MGMT.SEARCH_PLACEHOLDER')"
|
|
feature-name="inboxes"
|
|
>
|
|
<template v-if="inboxesList?.length" #count>
|
|
<span class="text-body-main text-n-slate-11">
|
|
{{ $t('INBOX_MGMT.COUNT', { n: inboxesList.length }) }}
|
|
</span>
|
|
</template>
|
|
<template #actions>
|
|
<router-link v-if="isAdmin" :to="{ name: 'settings_inbox_new' }">
|
|
<Button :label="$t('SETTINGS.INBOXES.NEW_INBOX')" size="sm" />
|
|
</router-link>
|
|
</template>
|
|
</BaseSettingsHeader>
|
|
</template>
|
|
<template #body>
|
|
<span
|
|
v-if="!filteredInboxesList.length && searchQuery"
|
|
class="flex-1 flex items-center justify-center py-20 text-center text-body-main !text-base text-n-slate-11"
|
|
>
|
|
{{ $t('INBOX_MGMT.NO_RESULTS') }}
|
|
</span>
|
|
<div v-else class="divide-y divide-n-weak border-t border-n-weak">
|
|
<div
|
|
v-for="inbox in filteredInboxesList"
|
|
:key="inbox.id"
|
|
class="flex justify-between flex-row items-start gap-4 py-4"
|
|
>
|
|
<div class="flex items-center gap-4">
|
|
<div
|
|
v-if="inbox.avatar_url"
|
|
class="bg-n-alpha-3 rounded-xl size-10 ring ring-n-solid-1 border border-n-strong shadow-sm grid place-items-center"
|
|
>
|
|
<Avatar
|
|
:src="inbox.avatar_url"
|
|
:name="inbox.name"
|
|
:size="24"
|
|
rounded-full
|
|
/>
|
|
</div>
|
|
<div
|
|
v-else
|
|
class="size-10 justify-center bg-n-alpha-3 rounded-xl ring ring-n-solid-1 border border-n-strong shadow-sm grid place-items-center"
|
|
>
|
|
<ChannelIcon class="size-6 text-n-slate-10" :inbox="inbox" />
|
|
</div>
|
|
<div class="flex flex-col items-start gap-1">
|
|
<span class="block text-heading-3 text-n-slate-12 capitalize">
|
|
{{ inbox.name }}
|
|
</span>
|
|
<ChannelName
|
|
:channel-type="inbox.channel_type"
|
|
:medium="inbox.medium"
|
|
class="text-body-main text-n-slate-11"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="flex gap-3 justify-end">
|
|
<router-link
|
|
:to="{
|
|
name: 'settings_inbox_show',
|
|
params: { inboxId: inbox.id },
|
|
}"
|
|
>
|
|
<Button
|
|
v-if="isAdmin"
|
|
v-tooltip.top="$t('INBOX_MGMT.SETTINGS')"
|
|
icon="i-woot-settings"
|
|
slate
|
|
sm
|
|
/>
|
|
</router-link>
|
|
<Button
|
|
v-if="isAdmin"
|
|
v-tooltip.top="$t('INBOX_MGMT.DELETE.BUTTON_TEXT')"
|
|
icon="i-woot-bin"
|
|
slate
|
|
sm
|
|
class="hover:enabled:text-n-ruby-11 hover:enabled:bg-n-ruby-2"
|
|
@click="openDelete(inbox)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<woot-confirm-delete-modal
|
|
v-if="showDeletePopup"
|
|
v-model:show="showDeletePopup"
|
|
:title="$t('INBOX_MGMT.DELETE.CONFIRM.TITLE')"
|
|
:message="confirmDeleteMessage"
|
|
:confirm-text="deleteConfirmText"
|
|
:reject-text="deleteRejectText"
|
|
:confirm-value="selectedInbox.name"
|
|
:confirm-place-holder-text="confirmPlaceHolderText"
|
|
@on-confirm="confirmDeletion"
|
|
@on-close="closeDelete"
|
|
/>
|
|
</SettingsLayout>
|
|
</template>
|