feat: Update Captain pages UI (#13184)
This commit is contained in:
@@ -212,7 +212,7 @@ const addAllExample = () => {
|
||||
</template>
|
||||
</SuggestedRules>
|
||||
</div>
|
||||
<div class="flex mt-7 flex-col gap-4">
|
||||
<div class="flex mt-7 flex-col gap-4 pb-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<BulkSelectBar
|
||||
v-model="bulkSelectedIds"
|
||||
|
||||
@@ -221,7 +221,7 @@ const addAllExample = async () => {
|
||||
</template>
|
||||
</SuggestedRules>
|
||||
</div>
|
||||
<div class="flex mt-7 flex-col gap-4">
|
||||
<div class="flex mt-7 flex-col gap-4 pb-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<BulkSelectBar
|
||||
v-model="bulkSelectedIds"
|
||||
|
||||
@@ -73,7 +73,7 @@ onMounted(() =>
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-4 pb-4">
|
||||
<InboxCard
|
||||
v-for="captainInbox in captainInboxes"
|
||||
:id="captainInbox.id"
|
||||
|
||||
@@ -277,7 +277,7 @@ onMounted(() => {
|
||||
{{ t('CAPTAIN.ASSISTANTS.SCENARIOS.SEARCH_EMPTY_MESSAGE') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else class="flex flex-col gap-2">
|
||||
<div v-else class="flex flex-col gap-2 pb-4">
|
||||
<ScenariosCard
|
||||
v-for="scenario in filteredScenarios"
|
||||
:id="scenario.id"
|
||||
|
||||
@@ -129,7 +129,7 @@ onMounted(() => {
|
||||
<template #body>
|
||||
<LimitBanner class="mb-5" />
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-4 pb-4">
|
||||
<DocumentCard
|
||||
v-for="doc in documents"
|
||||
:id="doc.id"
|
||||
|
||||
@@ -7,6 +7,7 @@ import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
import { debounce } from '@chatwoot/utils';
|
||||
import { useAccount } from 'dashboard/composables/useAccount';
|
||||
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
import Banner from 'dashboard/components-next/banner/Banner.vue';
|
||||
import Input from 'dashboard/components-next/input/Input.vue';
|
||||
import BulkSelectBar from 'dashboard/components-next/captain/assistant/BulkSelectBar.vue';
|
||||
@@ -113,7 +114,6 @@ const fetchResponses = (page = 1) => {
|
||||
|
||||
// Bulk action
|
||||
const bulkSelectedIds = ref(new Set());
|
||||
const hoveredCard = ref(null);
|
||||
|
||||
const buildSelectedCountLabel = computed(() => {
|
||||
const count = responses.value?.length || 0;
|
||||
@@ -129,10 +129,6 @@ const selectedCountLabel = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
const handleCardHover = (isHovered, id) => {
|
||||
hoveredCard.value = isHovered ? id : null;
|
||||
};
|
||||
|
||||
const handleCardSelect = id => {
|
||||
const selected = new Set(bulkSelectedIds.value);
|
||||
selected[selected.has(id) ? 'delete' : 'add'](id);
|
||||
@@ -157,6 +153,10 @@ const fetchResponseAfterBulkAction = () => {
|
||||
bulkSelectedIds.value = new Set();
|
||||
};
|
||||
|
||||
const clearSelection = () => {
|
||||
bulkSelectedIds.value = new Set();
|
||||
};
|
||||
|
||||
const onPageChange = page => {
|
||||
const hadSelection = bulkSelectedIds.value.size > 0;
|
||||
|
||||
@@ -252,12 +252,23 @@ onMounted(() => {
|
||||
:select-all-label="buildSelectedCountLabel"
|
||||
:selected-count-label="selectedCountLabel"
|
||||
:delete-label="$t('CAPTAIN.RESPONSES.BULK_DELETE_BUTTON')"
|
||||
class="w-fit"
|
||||
:class="{
|
||||
'mb-2': bulkSelectedIds.size > 0,
|
||||
'mt-2': bulkSelectedIds.size > 0,
|
||||
}"
|
||||
class="justify-between"
|
||||
animation-direction="vertical"
|
||||
@bulk-delete="bulkDeleteDialog.dialogRef.open()"
|
||||
/>
|
||||
>
|
||||
<template #secondary-actions>
|
||||
<Button
|
||||
sm
|
||||
ghost
|
||||
:label="t('CAPTAIN.RESPONSES.CLEAR_SELECTION')"
|
||||
class="!px-1"
|
||||
@click="clearSelection"
|
||||
/>
|
||||
</template>
|
||||
</BulkSelectBar>
|
||||
</template>
|
||||
|
||||
<template #emptyState>
|
||||
@@ -271,16 +282,16 @@ onMounted(() => {
|
||||
<template #body>
|
||||
<LimitBanner class="mb-5" />
|
||||
<Banner
|
||||
v-if="pendingCount > 0"
|
||||
v-if="pendingCount > 0 && bulkSelectedIds.size === 0"
|
||||
color="blue"
|
||||
class="mb-4 -mt-3"
|
||||
class="mb-4 -mt-2"
|
||||
:action-label="$t('CAPTAIN.RESPONSES.PENDING_BANNER.ACTION')"
|
||||
@action="navigateToPendingFAQs"
|
||||
>
|
||||
{{ $t('CAPTAIN.RESPONSES.PENDING_BANNER.TITLE') }}
|
||||
</Banner>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col divide-y divide-n-weak">
|
||||
<ResponseCard
|
||||
v-for="response in responses"
|
||||
:id="response.id"
|
||||
@@ -293,13 +304,11 @@ onMounted(() => {
|
||||
:created-at="response.created_at"
|
||||
:updated-at="response.updated_at"
|
||||
:is-selected="bulkSelectedIds.has(response.id)"
|
||||
:selectable="hoveredCard === response.id || bulkSelectedIds.size > 0"
|
||||
:show-menu="!bulkSelectedIds.has(response.id)"
|
||||
:show-actions="false"
|
||||
@action="handleAction"
|
||||
@navigate="handleNavigationAction"
|
||||
@select="handleCardSelect"
|
||||
@hover="isHovered => handleCardHover(isHovered, response.id)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -140,7 +140,6 @@ const fetchResponses = (page = 1) => {
|
||||
|
||||
// Bulk action
|
||||
const bulkSelectedIds = ref(new Set());
|
||||
const hoveredCard = ref(null);
|
||||
|
||||
const buildSelectedCountLabel = computed(() => {
|
||||
const count = filteredResponses.value?.length || 0;
|
||||
@@ -156,10 +155,6 @@ const selectedCountLabel = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
const handleCardHover = (isHovered, id) => {
|
||||
hoveredCard.value = isHovered ? id : null;
|
||||
};
|
||||
|
||||
const handleCardSelect = id => {
|
||||
const selected = new Set(bulkSelectedIds.value);
|
||||
selected[selected.has(id) ? 'delete' : 'add'](id);
|
||||
@@ -196,6 +191,10 @@ const handleBulkApprove = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const clearSelection = () => {
|
||||
bulkSelectedIds.value = new Set();
|
||||
};
|
||||
|
||||
const onPageChange = page => {
|
||||
const hadSelection = bulkSelectedIds.value.size > 0;
|
||||
|
||||
@@ -291,10 +290,11 @@ onMounted(() => {
|
||||
:select-all-label="buildSelectedCountLabel"
|
||||
:selected-count-label="selectedCountLabel"
|
||||
:delete-label="$t('CAPTAIN.RESPONSES.BULK_DELETE_BUTTON')"
|
||||
class="w-fit"
|
||||
:class="{
|
||||
'mb-2': bulkSelectedIds.size > 0,
|
||||
}"
|
||||
class="justify-between"
|
||||
animation-direction="vertical"
|
||||
@bulk-delete="bulkDeleteDialog.dialogRef.open()"
|
||||
>
|
||||
<template #secondary-actions>
|
||||
@@ -306,6 +306,14 @@ onMounted(() => {
|
||||
class="!px-1.5"
|
||||
@click="handleBulkApprove"
|
||||
/>
|
||||
<div class="h-4 w-px bg-n-strong" />
|
||||
<Button
|
||||
sm
|
||||
ghost
|
||||
:label="$t('CAPTAIN.RESPONSES.CLEAR_SELECTION')"
|
||||
class="!px-1"
|
||||
@click="clearSelection"
|
||||
/>
|
||||
</template>
|
||||
</BulkSelectBar>
|
||||
</template>
|
||||
@@ -325,7 +333,7 @@ onMounted(() => {
|
||||
<template #body>
|
||||
<LimitBanner class="mb-5" />
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col divide-y divide-n-weak">
|
||||
<ResponseCard
|
||||
v-for="response in filteredResponses"
|
||||
:id="response.id"
|
||||
@@ -338,13 +346,11 @@ onMounted(() => {
|
||||
:created-at="response.created_at"
|
||||
:updated-at="response.updated_at"
|
||||
:is-selected="bulkSelectedIds.has(response.id)"
|
||||
:selectable="hoveredCard === response.id || bulkSelectedIds.size > 0"
|
||||
:show-menu="false"
|
||||
:show-actions="!bulkSelectedIds.has(response.id)"
|
||||
@action="handleAction"
|
||||
@navigate="handleNavigationAction"
|
||||
@select="handleCardSelect"
|
||||
@hover="isHovered => handleCardHover(isHovered, response.id)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -100,7 +100,7 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-4 pb-4">
|
||||
<CustomToolCard
|
||||
v-for="tool in customTools"
|
||||
:id="tool.id"
|
||||
|
||||
+3
-2
@@ -88,7 +88,8 @@ const handleAssignLabels = labels => {
|
||||
:all-items="allItems"
|
||||
:select-all-label="selectAllLabel"
|
||||
:selected-count-label="selectedCountLabel"
|
||||
class="py-2 ltr:!pr-2 rtl:!pl-2 justify-between"
|
||||
animation-direction="vertical"
|
||||
class="justify-between"
|
||||
>
|
||||
<template #secondary-actions>
|
||||
<Button
|
||||
@@ -105,7 +106,7 @@ const handleAssignLabels = labels => {
|
||||
type="contact"
|
||||
:is-loading="isLoading"
|
||||
:disabled="!selectedCount"
|
||||
class="[&>button]:!text-n-blue-11 [&>button]:!px-2"
|
||||
class="[&>button]:!text-n-blue-11 [&>button>span]:!text-n-blue-11 [&>button]:!px-2"
|
||||
@assign="handleAssignLabels"
|
||||
/>
|
||||
<div class="w-px h-3 bg-n-weak rounded-lg" />
|
||||
|
||||
@@ -438,7 +438,7 @@ onMounted(async () => {
|
||||
|
||||
<template v-else>
|
||||
<ContactsBulkActionBar
|
||||
v-if="hasSelection"
|
||||
v-show="hasSelection"
|
||||
:visible-contact-ids="visibleContactIds"
|
||||
:selected-contact-ids="selectedContactIds"
|
||||
:is-loading="isBulkActionLoading"
|
||||
|
||||
Reference in New Issue
Block a user