Files
leadchat/app/javascript/dashboard/routes/dashboard/settings/inbox/Index.vue
Sivin Varghese 418bd177f8 fix: Adjust inbox settings pages layout width (#13590)
# 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
2026-02-20 20:20:32 +05:30

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>