Merge branch 'develop' into feat/contacts-redesign
This commit is contained in:
@@ -83,61 +83,55 @@ const inboxIcon = computed(() => {
|
||||
|
||||
<template>
|
||||
<CardLayout layout="row">
|
||||
<template #header>
|
||||
<div class="flex flex-col items-start justify-between flex-1 min-w-0 gap-2">
|
||||
<div class="flex justify-between gap-3 w-fit">
|
||||
<span
|
||||
class="text-base font-medium capitalize text-n-slate-12 line-clamp-1"
|
||||
>
|
||||
{{ title }}
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-medium inline-flex items-center h-6 px-2 py-0.5 rounded-md bg-n-alpha-2"
|
||||
:class="statusTextColor"
|
||||
>
|
||||
{{ campaignStatus }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col items-start justify-between flex-1 min-w-0 gap-2"
|
||||
>
|
||||
<div class="flex justify-between gap-3 w-fit">
|
||||
<span
|
||||
class="text-base font-medium capitalize text-n-slate-12 line-clamp-1"
|
||||
>
|
||||
{{ title }}
|
||||
</span>
|
||||
<span
|
||||
class="text-xs font-medium inline-flex items-center h-6 px-2 py-0.5 rounded-md bg-n-alpha-2"
|
||||
:class="statusTextColor"
|
||||
>
|
||||
{{ campaignStatus }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-dompurify-html="formatMessage(message)"
|
||||
class="text-sm text-n-slate-11 line-clamp-1 [&>p]:mb-0 h-6"
|
||||
/>
|
||||
<div class="flex items-center w-full h-6 gap-2 overflow-hidden">
|
||||
<LiveChatCampaignDetails
|
||||
v-if="isLiveChatType"
|
||||
:sender="sender"
|
||||
:inbox-name="inboxName"
|
||||
:inbox-icon="inboxIcon"
|
||||
/>
|
||||
<SMSCampaignDetails
|
||||
v-else
|
||||
:inbox-name="inboxName"
|
||||
:inbox-icon="inboxIcon"
|
||||
:scheduled-at="scheduledAt"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-end w-20 gap-2">
|
||||
<Button
|
||||
v-dompurify-html="formatMessage(message)"
|
||||
class="text-sm text-n-slate-11 line-clamp-1 [&>p]:mb-0 h-6"
|
||||
/>
|
||||
<div class="flex items-center w-full h-6 gap-2 overflow-hidden">
|
||||
<LiveChatCampaignDetails
|
||||
v-if="isLiveChatType"
|
||||
variant="faded"
|
||||
size="sm"
|
||||
color="slate"
|
||||
icon="i-lucide-sliders-vertical"
|
||||
@click="emit('edit')"
|
||||
:sender="sender"
|
||||
:inbox-name="inboxName"
|
||||
:inbox-icon="inboxIcon"
|
||||
/>
|
||||
<Button
|
||||
variant="faded"
|
||||
color="ruby"
|
||||
size="sm"
|
||||
icon="i-lucide-trash"
|
||||
@click="emit('delete')"
|
||||
<SMSCampaignDetails
|
||||
v-else
|
||||
:inbox-name="inboxName"
|
||||
:inbox-icon="inboxIcon"
|
||||
:scheduled-at="scheduledAt"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex items-center justify-end w-20 gap-2">
|
||||
<Button
|
||||
v-if="isLiveChatType"
|
||||
variant="faded"
|
||||
size="sm"
|
||||
color="slate"
|
||||
icon="i-lucide-sliders-vertical"
|
||||
@click="emit('edit')"
|
||||
/>
|
||||
<Button
|
||||
variant="faded"
|
||||
color="ruby"
|
||||
size="sm"
|
||||
icon="i-lucide-trash"
|
||||
@click="emit('delete')"
|
||||
/>
|
||||
</div>
|
||||
</CardLayout>
|
||||
</template>
|
||||
|
||||
+7
-9
@@ -63,14 +63,12 @@ defineExpose({ dialogRef });
|
||||
overflow-y-auto
|
||||
@confirm="handleSubmit"
|
||||
>
|
||||
<template #form>
|
||||
<LiveChatCampaignForm
|
||||
ref="liveChatCampaignFormRef"
|
||||
mode="edit"
|
||||
:selected-campaign="selectedCampaign"
|
||||
:show-action-buttons="false"
|
||||
@submit="handleSubmit"
|
||||
/>
|
||||
</template>
|
||||
<LiveChatCampaignForm
|
||||
ref="liveChatCampaignFormRef"
|
||||
mode="edit"
|
||||
:selected-campaign="selectedCampaign"
|
||||
:show-action-buttons="false"
|
||||
@submit="handleSubmit"
|
||||
/>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@@ -15,7 +15,7 @@ const handleClick = () => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="relative flex flex-col w-full shadow outline-1 outline outline-n-container group/cardLayout rounded-2xl bg-n-solid-2"
|
||||
class="flex flex-col w-full shadow outline-1 outline outline-n-container group/cardLayout rounded-2xl bg-n-solid-2"
|
||||
>
|
||||
<div
|
||||
class="flex w-full gap-3 px-6 py-5"
|
||||
@@ -24,10 +24,9 @@ const handleClick = () => {
|
||||
"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot name="header" />
|
||||
<slot name="footer" />
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<slot name="expanded" />
|
||||
<slot name="after" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -124,76 +124,72 @@ const handleClick = id => {
|
||||
|
||||
<template>
|
||||
<CardLayout>
|
||||
<template #header>
|
||||
<div class="flex justify-between w-full gap-1">
|
||||
<div class="flex justify-between w-full gap-1">
|
||||
<span
|
||||
class="text-base cursor-pointer hover:underline underline-offset-2 hover:text-n-blue-text text-n-slate-12 line-clamp-1"
|
||||
@click="handleClick(id)"
|
||||
>
|
||||
{{ title }}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
class="text-base cursor-pointer hover:underline underline-offset-2 hover:text-n-blue-text text-n-slate-12 line-clamp-1"
|
||||
@click="handleClick(id)"
|
||||
class="text-xs font-medium inline-flex items-center h-6 px-2 py-0.5 rounded-md bg-n-alpha-2"
|
||||
:class="statusTextColor"
|
||||
>
|
||||
{{ title }}
|
||||
{{ statusText }}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
class="text-xs font-medium inline-flex items-center h-6 px-2 py-0.5 rounded-md bg-n-alpha-2"
|
||||
:class="statusTextColor"
|
||||
>
|
||||
{{ statusText }}
|
||||
</span>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative flex items-center group"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
<DropdownMenu
|
||||
v-if="showActionsDropdown"
|
||||
:menu-items="articleMenuItems"
|
||||
class="mt-1 ltr:right-0 rtl:left-0 xl:ltr:left-0 xl:rtl:right-0 top-full"
|
||||
@action="handleArticleAction($event)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative flex items-center group"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
<DropdownMenu
|
||||
v-if="showActionsDropdown"
|
||||
:menu-items="articleMenuItems"
|
||||
class="mt-1 ltr:right-0 rtl:left-0 xl:ltr:left-0 xl:rtl:right-0 top-full"
|
||||
@action="handleArticleAction($event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between w-full gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center gap-1">
|
||||
<Avatar
|
||||
:name="authorName"
|
||||
:src="authorThumbnailSrc"
|
||||
:size="16"
|
||||
rounded-full
|
||||
/>
|
||||
<span class="text-sm truncate text-n-slate-11">
|
||||
{{ authorName || '-' }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="block text-sm whitespace-nowrap text-n-slate-11">
|
||||
{{ categoryName }}
|
||||
</div>
|
||||
<div class="flex items-center justify-between w-full gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center gap-1">
|
||||
<Avatar
|
||||
:name="authorName"
|
||||
:src="authorThumbnailSrc"
|
||||
:size="16"
|
||||
rounded-full
|
||||
/>
|
||||
<span class="text-sm truncate text-n-slate-11">
|
||||
{{ authorName || '-' }}
|
||||
</span>
|
||||
<div
|
||||
class="inline-flex items-center gap-1 text-n-slate-11 whitespace-nowrap"
|
||||
>
|
||||
<Icon icon="i-lucide-eye" class="size-4" />
|
||||
<span class="text-sm">
|
||||
{{
|
||||
t('HELP_CENTER.ARTICLES_PAGE.ARTICLE_CARD.CARD.VIEWS', {
|
||||
count: views,
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-sm text-n-slate-11 line-clamp-1">
|
||||
{{ lastUpdatedAt }}
|
||||
<span class="block text-sm whitespace-nowrap text-n-slate-11">
|
||||
{{ categoryName }}
|
||||
</span>
|
||||
<div
|
||||
class="inline-flex items-center gap-1 text-n-slate-11 whitespace-nowrap"
|
||||
>
|
||||
<Icon icon="i-lucide-eye" class="size-4" />
|
||||
<span class="text-sm">
|
||||
{{
|
||||
t('HELP_CENTER.ARTICLES_PAGE.ARTICLE_CARD.CARD.VIEWS', {
|
||||
count: views,
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<span class="text-sm text-n-slate-11 line-clamp-1">
|
||||
{{ lastUpdatedAt }}
|
||||
</span>
|
||||
</div>
|
||||
</CardLayout>
|
||||
</template>
|
||||
|
||||
@@ -79,59 +79,55 @@ const handleAction = ({ action, value }) => {
|
||||
|
||||
<template>
|
||||
<CardLayout>
|
||||
<template #header>
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="flex justify-between w-full gap-2">
|
||||
<div class="flex items-center justify-start w-full min-w-0 gap-2">
|
||||
<span
|
||||
class="text-base truncate cursor-pointer hover:underline underline-offset-2 hover:text-n-blue-text text-n-slate-12"
|
||||
@click="handleClick(slug)"
|
||||
>
|
||||
{{ categoryTitleWithIcon }}
|
||||
</span>
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-6 px-2 py-1 text-xs text-center border rounded-lg bg-n-slate-1 whitespace-nowrap shrink-0 text-n-slate-11 border-n-slate-4"
|
||||
>
|
||||
{{
|
||||
t('HELP_CENTER.CATEGORY_PAGE.CATEGORY_CARD.ARTICLES_COUNT', {
|
||||
count: articlesCount,
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative group"
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="flex justify-between w-full gap-2">
|
||||
<div class="flex items-center justify-start w-full min-w-0 gap-2">
|
||||
<span
|
||||
class="text-base truncate cursor-pointer hover:underline underline-offset-2 hover:text-n-blue-text text-n-slate-12"
|
||||
@click="handleClick(slug)"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
<DropdownMenu
|
||||
v-if="showActionsDropdown"
|
||||
:menu-items="categoryMenuItems"
|
||||
class="mt-1 ltr:right-0 rtl:left-0 xl:ltr:left-0 xl:rtl:right-0 top-full z-60"
|
||||
@action="handleAction"
|
||||
/>
|
||||
</div>
|
||||
{{ categoryTitleWithIcon }}
|
||||
</span>
|
||||
<span
|
||||
class="inline-flex items-center justify-center h-6 px-2 py-1 text-xs text-center border rounded-lg bg-n-slate-1 whitespace-nowrap shrink-0 text-n-slate-11 border-n-slate-4"
|
||||
>
|
||||
{{
|
||||
t('HELP_CENTER.CATEGORY_PAGE.CATEGORY_CARD.ARTICLES_COUNT', {
|
||||
count: articlesCount,
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative group"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
<DropdownMenu
|
||||
v-if="showActionsDropdown"
|
||||
:menu-items="categoryMenuItems"
|
||||
class="mt-1 ltr:right-0 rtl:left-0 xl:ltr:left-0 xl:rtl:right-0 top-full z-60"
|
||||
@action="handleAction"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<span
|
||||
class="text-sm line-clamp-3"
|
||||
:class="
|
||||
hasDescription
|
||||
? 'text-slate-500 dark:text-slate-400'
|
||||
: 'text-slate-400 dark:text-slate-700'
|
||||
"
|
||||
>
|
||||
{{ description }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
<span
|
||||
class="text-sm line-clamp-3"
|
||||
:class="
|
||||
hasDescription
|
||||
? 'text-slate-500 dark:text-slate-400'
|
||||
: 'text-slate-400 dark:text-slate-700'
|
||||
"
|
||||
>
|
||||
{{ description }}
|
||||
</span>
|
||||
</CardLayout>
|
||||
</template>
|
||||
|
||||
@@ -53,66 +53,64 @@ const handleAction = ({ action, value }) => {
|
||||
|
||||
<template>
|
||||
<CardLayout>
|
||||
<template #header>
|
||||
<div class="flex justify-between gap-2">
|
||||
<div class="flex items-center justify-start gap-2">
|
||||
<div class="flex justify-between gap-2">
|
||||
<div class="flex items-center justify-start gap-2">
|
||||
<span
|
||||
class="text-sm font-medium text-slate-900 dark:text-slate-50 line-clamp-1"
|
||||
>
|
||||
{{ locale }} ({{ localeCode }})
|
||||
</span>
|
||||
<span
|
||||
v-if="isDefault"
|
||||
class="bg-n-alpha-2 h-6 inline-flex items-center justify-center rounded-md text-xs border-px border-transparent text-n-blue-text px-2 py-0.5"
|
||||
>
|
||||
{{ $t('HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.DEFAULT') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<span
|
||||
class="text-sm font-medium text-slate-900 dark:text-slate-50 line-clamp-1"
|
||||
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
|
||||
>
|
||||
{{ locale }} ({{ localeCode }})
|
||||
{{
|
||||
$t(
|
||||
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.ARTICLES_COUNT',
|
||||
articleCount
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<div class="w-px h-3 bg-slate-75 dark:bg-slate-800" />
|
||||
<span
|
||||
v-if="isDefault"
|
||||
class="bg-n-alpha-2 h-6 inline-flex items-center justify-center rounded-md text-xs border-px border-transparent text-n-blue-text px-2 py-0.5"
|
||||
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
|
||||
>
|
||||
{{ $t('HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.DEFAULT') }}
|
||||
{{
|
||||
$t(
|
||||
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.CATEGORIES_COUNT',
|
||||
categoryCount
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<span
|
||||
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
|
||||
>
|
||||
{{
|
||||
$t(
|
||||
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.ARTICLES_COUNT',
|
||||
articleCount
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<div class="w-px h-3 bg-slate-75 dark:bg-slate-800" />
|
||||
<span
|
||||
class="text-sm text-slate-500 dark:text-slate-400 whitespace-nowrap"
|
||||
>
|
||||
{{
|
||||
$t(
|
||||
'HELP_CENTER.LOCALES_PAGE.LOCALE_CARD.CATEGORIES_COUNT',
|
||||
categoryCount
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative group"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
<div
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
class="relative group"
|
||||
>
|
||||
<Button
|
||||
icon="i-lucide-ellipsis-vertical"
|
||||
color="slate"
|
||||
size="xs"
|
||||
class="rounded-md group-hover:bg-n-alpha-2"
|
||||
@click="toggleDropdown()"
|
||||
/>
|
||||
|
||||
<DropdownMenu
|
||||
v-if="showDropdownMenu"
|
||||
:menu-items="localeMenuItems"
|
||||
class="ltr:right-0 rtl:left-0 mt-1 xl:ltr:left-0 xl:rtl:right-0 top-full z-60 min-w-[150px]"
|
||||
@action="handleAction"
|
||||
/>
|
||||
</div>
|
||||
<DropdownMenu
|
||||
v-if="showDropdownMenu"
|
||||
:menu-items="localeMenuItems"
|
||||
class="ltr:right-0 rtl:left-0 mt-1 xl:ltr:left-0 xl:rtl:right-0 top-full z-60 min-w-[150px]"
|
||||
@action="handleAction"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</CardLayout>
|
||||
</template>
|
||||
|
||||
+9
-11
@@ -97,16 +97,14 @@ defineExpose({ dialogRef });
|
||||
:disable-confirm-button="isUpdatingCategory || isInvalidForm"
|
||||
@confirm="onUpdateCategory"
|
||||
>
|
||||
<template #form>
|
||||
<CategoryForm
|
||||
ref="categoryFormRef"
|
||||
mode="edit"
|
||||
:selected-category="selectedCategory"
|
||||
:active-locale-code="activeLocaleCode"
|
||||
:portal-name="route.params.portalSlug"
|
||||
:active-locale-name="activeLocaleName"
|
||||
:show-action-buttons="false"
|
||||
/>
|
||||
</template>
|
||||
<CategoryForm
|
||||
ref="categoryFormRef"
|
||||
mode="edit"
|
||||
:selected-category="selectedCategory"
|
||||
:active-locale-code="activeLocaleCode"
|
||||
:portal-name="route.params.portalSlug"
|
||||
:active-locale-name="activeLocaleName"
|
||||
:show-action-buttons="false"
|
||||
/>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
+10
-12
@@ -85,17 +85,15 @@ defineExpose({ dialogRef });
|
||||
:description="t('HELP_CENTER.LOCALES_PAGE.ADD_LOCALE_DIALOG.DESCRIPTION')"
|
||||
@confirm="onCreate"
|
||||
>
|
||||
<template #form>
|
||||
<div class="flex flex-col gap-6">
|
||||
<ComboBox
|
||||
v-model="selectedLocale"
|
||||
:options="locales"
|
||||
:placeholder="
|
||||
t('HELP_CENTER.LOCALES_PAGE.ADD_LOCALE_DIALOG.COMBOBOX.PLACEHOLDER')
|
||||
"
|
||||
class="[&>div>button]:!border-n-slate-5 [&>div>button]:dark:!border-n-slate-5"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex flex-col gap-6">
|
||||
<ComboBox
|
||||
v-model="selectedLocale"
|
||||
:options="locales"
|
||||
:placeholder="
|
||||
t('HELP_CENTER.LOCALES_PAGE.ADD_LOCALE_DIALOG.COMBOBOX.PLACEHOLDER')
|
||||
"
|
||||
class="[&>div>button]:!border-n-slate-5 [&>div>button]:dark:!border-n-slate-5"
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
+13
-15
@@ -55,20 +55,18 @@ defineExpose({ dialogRef });
|
||||
"
|
||||
@confirm="handleDialogConfirm"
|
||||
>
|
||||
<template #form>
|
||||
<Input
|
||||
v-model="formState.customDomain"
|
||||
:label="
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DIALOG.LABEL'
|
||||
)
|
||||
"
|
||||
:placeholder="
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DIALOG.PLACEHOLDER'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<Input
|
||||
v-model="formState.customDomain"
|
||||
:label="
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DIALOG.LABEL'
|
||||
)
|
||||
"
|
||||
:placeholder="
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DIALOG.PLACEHOLDER'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
+15
-16
@@ -59,21 +59,20 @@ defineExpose({ dialogRef });
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
<template #form>
|
||||
<div class="flex flex-col gap-6">
|
||||
<span
|
||||
class="h-10 px-3 py-2.5 text-sm select-none bg-transparent border rounded-lg text-n-slate-11 border-n-strong"
|
||||
>
|
||||
{{ subdomainCNAME }}
|
||||
</span>
|
||||
<p class="text-sm text-n-slate-12">
|
||||
{{
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DNS_CONFIGURATION_DIALOG.HELP_TEXT'
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<span
|
||||
class="h-10 px-3 py-2.5 text-sm select-none bg-transparent border rounded-lg text-n-slate-11 border-n-strong"
|
||||
>
|
||||
{{ subdomainCNAME }}
|
||||
</span>
|
||||
<p class="text-sm text-n-slate-12">
|
||||
{{
|
||||
t(
|
||||
'HELP_CENTER.PORTAL_SETTINGS.CONFIGURATION_FORM.CUSTOM_DOMAIN.DNS_CONFIGURATION_DIALOG.HELP_TEXT'
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
+22
-24
@@ -120,29 +120,27 @@ defineExpose({ dialogRef });
|
||||
:is-loading="isCreatingPortal"
|
||||
@confirm="handleDialogConfirm"
|
||||
>
|
||||
<template #form>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Input
|
||||
id="portal-name"
|
||||
v-model="state.name"
|
||||
type="text"
|
||||
:placeholder="t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.PLACEHOLDER')"
|
||||
:label="t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.LABEL')"
|
||||
:message-type="nameError ? 'error' : 'info'"
|
||||
:message="
|
||||
nameError || t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.MESSAGE')
|
||||
"
|
||||
/>
|
||||
<Input
|
||||
id="portal-slug"
|
||||
v-model="state.slug"
|
||||
type="text"
|
||||
:placeholder="t('HELP_CENTER.CREATE_PORTAL_DIALOG.SLUG.PLACEHOLDER')"
|
||||
:label="t('HELP_CENTER.CREATE_PORTAL_DIALOG.SLUG.LABEL')"
|
||||
:message-type="slugError ? 'error' : 'info'"
|
||||
:message="slugError || buildPortalURL(state.slug)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Input
|
||||
id="portal-name"
|
||||
v-model="state.name"
|
||||
type="text"
|
||||
:placeholder="t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.PLACEHOLDER')"
|
||||
:label="t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.LABEL')"
|
||||
:message-type="nameError ? 'error' : 'info'"
|
||||
:message="
|
||||
nameError || t('HELP_CENTER.CREATE_PORTAL_DIALOG.NAME.MESSAGE')
|
||||
"
|
||||
/>
|
||||
<Input
|
||||
id="portal-slug"
|
||||
v-model="state.slug"
|
||||
type="text"
|
||||
:placeholder="t('HELP_CENTER.CREATE_PORTAL_DIALOG.SLUG.PLACEHOLDER')"
|
||||
:label="t('HELP_CENTER.CREATE_PORTAL_DIALOG.SLUG.LABEL')"
|
||||
:message-type="slugError ? 'error' : 'info'"
|
||||
:message="slugError || buildPortalURL(state.slug)"
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@@ -118,13 +118,12 @@ watch(
|
||||
|
||||
<ComboBoxDropdown
|
||||
ref="dropdownRef"
|
||||
v-model:search-value="search"
|
||||
:open="open"
|
||||
:options="filteredOptions"
|
||||
:search-value="search"
|
||||
:search-placeholder="searchPlaceholder"
|
||||
:empty-state="emptyState"
|
||||
:selected-values="selectedValue"
|
||||
@update:search-value="search = $event"
|
||||
@search="emit('search', $event)"
|
||||
@select="selectOption"
|
||||
/>
|
||||
|
||||
@@ -11,10 +11,6 @@ const props = defineProps({
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
searchValue: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
searchPlaceholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
@@ -33,10 +29,15 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:searchValue', 'select', 'search']);
|
||||
const emit = defineEmits(['select', 'search']);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const searchValue = defineModel('searchValue', {
|
||||
type: String,
|
||||
default: '',
|
||||
});
|
||||
|
||||
const searchInput = ref(null);
|
||||
|
||||
const isSelected = option => {
|
||||
@@ -47,7 +48,7 @@ const isSelected = option => {
|
||||
};
|
||||
|
||||
const onInputSearch = event => {
|
||||
emit('update:searchValue', event.target.value);
|
||||
searchValue.value = event.target.value;
|
||||
emit('search', event.target.value);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import Input from 'dashboard/components-next/input/Input.vue';
|
||||
const alertDialog = ref(null);
|
||||
const editDialog = ref(null);
|
||||
const confirmDialog = ref(null);
|
||||
const confirmDialogWithCustomFooter = ref(null);
|
||||
|
||||
const openAlertDialog = () => {
|
||||
alertDialog.value.open();
|
||||
@@ -17,6 +18,9 @@ const openEditDialog = () => {
|
||||
const openConfirmDialog = () => {
|
||||
confirmDialog.value.open();
|
||||
};
|
||||
const openConfirmDialogWithCustomFooter = () => {
|
||||
confirmDialogWithCustomFooter.value.open();
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const onConfirm = dialog => {};
|
||||
@@ -44,24 +48,22 @@ const onConfirm = dialog => {};
|
||||
confirm-button-label="Save"
|
||||
@confirm="onConfirm()"
|
||||
>
|
||||
<template #form>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Input
|
||||
id="portal-name"
|
||||
type="text"
|
||||
placeholder="User Guide | Chatwoot"
|
||||
label="Name"
|
||||
message="This will be the name of your public facing portal"
|
||||
/>
|
||||
<Input
|
||||
id="portal-slug"
|
||||
type="text"
|
||||
placeholder="user-guide"
|
||||
label="Slug"
|
||||
message="app.chatwoot.com/hc/my-portal/en-US/categories/my-slug"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Input
|
||||
id="portal-name"
|
||||
type="text"
|
||||
placeholder="User Guide | Chatwoot"
|
||||
label="Name"
|
||||
message="This will be the name of your public facing portal"
|
||||
/>
|
||||
<Input
|
||||
id="portal-slug"
|
||||
type="text"
|
||||
placeholder="user-guide"
|
||||
label="Slug"
|
||||
message="app.chatwoot.com/hc/my-portal/en-US/categories/my-slug"
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Variant>
|
||||
|
||||
@@ -77,5 +79,21 @@ const onConfirm = dialog => {};
|
||||
@confirm="onConfirm()"
|
||||
/>
|
||||
</Variant>
|
||||
|
||||
<Variant title="With custom footer">
|
||||
<Button
|
||||
label="Open Confirm Dialog with custom footer"
|
||||
@click="openConfirmDialogWithCustomFooter"
|
||||
/>
|
||||
<Dialog
|
||||
ref="confirmDialogWithCustomFooter"
|
||||
title="Confirm Action"
|
||||
description="Are you sure you want to perform this action?"
|
||||
>
|
||||
<template #footer>
|
||||
<Button label="Custom Button" @click="onConfirm()" />
|
||||
</template>
|
||||
</Dialog>
|
||||
</Variant>
|
||||
</Story>
|
||||
</template>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { OnClickOutside } from '@vueuse/components';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useMapGetter } from 'dashboard/composables/store.js';
|
||||
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'edit',
|
||||
@@ -48,9 +48,10 @@ defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
maxWidth: {
|
||||
width: {
|
||||
type: String,
|
||||
default: 'max-w-lg',
|
||||
default: 'lg',
|
||||
validator: value => ['3xl', '2xl', 'xl', 'lg', 'md', 'sm'].includes(value),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -63,6 +64,19 @@ const isRTL = useMapGetter('accounts/isRTL');
|
||||
const dialogRef = ref(null);
|
||||
const dialogContentRef = ref(null);
|
||||
|
||||
const maxWidthClass = computed(() => {
|
||||
const classesMap = {
|
||||
'3xl': 'max-w-3xl',
|
||||
'2xl': 'max-w-2xl',
|
||||
xl: 'max-w-xl',
|
||||
lg: 'max-w-lg',
|
||||
md: 'max-w-md',
|
||||
sm: 'max-w-sm',
|
||||
};
|
||||
|
||||
return classesMap[props.width] ?? 'max-w-md';
|
||||
});
|
||||
|
||||
const open = () => {
|
||||
dialogRef.value?.showModal();
|
||||
};
|
||||
@@ -83,7 +97,7 @@ defineExpose({ open, close });
|
||||
ref="dialogRef"
|
||||
class="w-full transition-all duration-300 ease-in-out shadow-xl rounded-xl"
|
||||
:class="[
|
||||
maxWidth,
|
||||
maxWidthClass,
|
||||
overflowYAuto ? 'overflow-y-auto' : 'overflow-visible',
|
||||
]"
|
||||
:dir="isRTL ? 'rtl' : 'ltr'"
|
||||
@@ -105,9 +119,8 @@ defineExpose({ open, close });
|
||||
</p>
|
||||
</slot>
|
||||
</div>
|
||||
<slot name="form">
|
||||
<!-- Form content will be injected here -->
|
||||
</slot>
|
||||
<slot />
|
||||
<!-- Dialog content will be injected here -->
|
||||
<slot name="footer">
|
||||
<div class="flex items-center justify-between w-full gap-3">
|
||||
<Button
|
||||
|
||||
@@ -51,5 +51,19 @@ const handleAction = () => {
|
||||
/>
|
||||
</div>
|
||||
</Variant>
|
||||
|
||||
<Variant title="With search">
|
||||
<div class="p-4 bg-white h-72 dark:bg-slate-900">
|
||||
<DropdownMenu
|
||||
:menu-items="[
|
||||
{ label: 'Custom 1', action: 'custom1', icon: 'file-upload' },
|
||||
{ label: 'Custom 2', action: 'custom2', icon: 'document' },
|
||||
{ label: 'Danger', action: 'delete', icon: 'delete' },
|
||||
]"
|
||||
show-search
|
||||
@action="handleAction"
|
||||
/>
|
||||
</div>
|
||||
</Variant>
|
||||
</Story>
|
||||
</template>
|
||||
|
||||
@@ -46,6 +46,13 @@ const handleClickOutside = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeydown = event => {
|
||||
if (event.key === ',') {
|
||||
event.preventDefault();
|
||||
addTag();
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
newValue => {
|
||||
@@ -81,6 +88,7 @@ watch(
|
||||
:placeholder="placeholder"
|
||||
custom-input-class="flex-grow"
|
||||
@enter-press="addTag"
|
||||
@keydown="handleKeydown"
|
||||
/>
|
||||
</div>
|
||||
</OnClickOutside>
|
||||
|
||||
Reference in New Issue
Block a user