chore: Update settings to match the new design (#11084)
This commit is contained in:
@@ -19,12 +19,21 @@ const { t } = useI18n();
|
||||
const showNewButton = computed(
|
||||
() => props.newButtonRoutes.length && !props.showBackButton
|
||||
);
|
||||
|
||||
const showSettingsHeader = computed(
|
||||
() =>
|
||||
props.headerTitle ||
|
||||
props.icon ||
|
||||
props.showBackButton ||
|
||||
showNewButton.value
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-1 flex-col m-0 bg-n-background overflow-auto">
|
||||
<div class="max-w-6xl mx-auto w-full flex flex-col flex-1">
|
||||
<SettingsHeader
|
||||
v-if="showSettingsHeader"
|
||||
button-route="new"
|
||||
:icon="icon"
|
||||
:header-title="t(headerTitle)"
|
||||
|
||||
@@ -1,59 +1,87 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useMapGetter, useStore } from 'dashboard/composables/store';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { frontendURL } from 'dashboard/helper/URLHelper';
|
||||
|
||||
import AgentBotRow from './components/AgentBotRow.vue';
|
||||
|
||||
export default {
|
||||
components: { AgentBotRow },
|
||||
computed: {
|
||||
...mapGetters({
|
||||
accountId: 'getCurrentAccountId',
|
||||
agentBots: 'agentBots/getBots',
|
||||
uiFlags: 'agentBots/getUIFlags',
|
||||
}),
|
||||
newAgentBotsURL() {
|
||||
return frontendURL(
|
||||
`accounts/${this.accountId}/settings/agent-bots/csml/new`
|
||||
);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('agentBots/get');
|
||||
},
|
||||
methods: {
|
||||
async onDeleteAgentBot(bot) {
|
||||
const ok = await this.$refs.confirmDialog.showConfirmation();
|
||||
if (ok) {
|
||||
try {
|
||||
await this.$store.dispatch('agentBots/delete', bot.id);
|
||||
useAlert(this.$t('AGENT_BOTS.DELETE.API.SUCCESS_MESSAGE'));
|
||||
} catch (error) {
|
||||
useAlert(this.$t('AGENT_BOTS.DELETE.API.ERROR_MESSAGE'));
|
||||
}
|
||||
}
|
||||
},
|
||||
onEditAgentBot(bot) {
|
||||
this.$router.push(
|
||||
frontendURL(
|
||||
`accounts/${this.accountId}/settings/agent-bots/csml/${bot.id}`
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
import SettingsLayout from '../SettingsLayout.vue';
|
||||
import BaseSettingsHeader from '../components/BaseSettingsHeader.vue';
|
||||
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const accountId = useMapGetter('getCurrentAccountId');
|
||||
const agentBots = useMapGetter('agentBots/getBots');
|
||||
const uiFlags = useMapGetter('agentBots/getUIFlags');
|
||||
|
||||
const confirmDialog = ref(null);
|
||||
|
||||
const onConfigureNewBot = () => {
|
||||
router.push({
|
||||
name: 'agent_bots_csml_new',
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
store.dispatch('agentBots/get');
|
||||
});
|
||||
|
||||
const onDeleteAgentBot = async bot => {
|
||||
const ok = await confirmDialog.value.showConfirmation();
|
||||
|
||||
if (ok) {
|
||||
try {
|
||||
await store.dispatch('agentBots/delete', bot.id);
|
||||
useAlert(t('AGENT_BOTS.DELETE.API.SUCCESS_MESSAGE'));
|
||||
} catch (error) {
|
||||
useAlert(t('AGENT_BOTS.DELETE.API.ERROR_MESSAGE'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onEditAgentBot = bot => {
|
||||
router.push(
|
||||
frontendURL(
|
||||
`accounts/${accountId.value}/settings/agent-bots/csml/${bot.id}`
|
||||
)
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1 p-4 overflow-auto">
|
||||
<div class="flex flex-row gap-4">
|
||||
<div class="w-full lg:w-3/5">
|
||||
<woot-loading-state
|
||||
v-if="uiFlags.isFetching"
|
||||
:message="$t('AGENT_BOTS.LIST.LOADING')"
|
||||
/>
|
||||
<table v-else-if="agentBots.length" class="woot-table">
|
||||
<tbody>
|
||||
<SettingsLayout
|
||||
:is-loading="uiFlags.isFetching"
|
||||
:loading-message="$t('AGENT_BOTS.LIST.LOADING')"
|
||||
:no-records-found="!agentBots.length"
|
||||
:no-records-message="$t('AGENT_BOTS.LIST.404')"
|
||||
>
|
||||
<template #header>
|
||||
<BaseSettingsHeader
|
||||
:title="$t('AGENT_BOTS.HEADER')"
|
||||
:description="$t('AGENT_BOTS.DESCRIPTION')"
|
||||
:link-text="$t('AGENT_BOTS.LEARN_MORE')"
|
||||
feature-name="agent_bots"
|
||||
>
|
||||
<template #actions>
|
||||
<woot-button
|
||||
class="rounded-md button nice"
|
||||
icon="add-circle"
|
||||
@click="onConfigureNewBot"
|
||||
>
|
||||
{{ $t('AGENT_BOTS.ADD.TITLE') }}
|
||||
</woot-button>
|
||||
</template>
|
||||
</BaseSettingsHeader>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<table class="divide-y divide-slate-75 dark:divide-slate-700">
|
||||
<tbody class="divide-y divide-n-weak text-n-slate-11">
|
||||
<AgentBotRow
|
||||
v-for="(agentBot, index) in agentBots"
|
||||
:key="agentBot.id"
|
||||
@@ -64,42 +92,12 @@ export default {
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
<p v-else class="flex flex-col items-center justify-center h-full">
|
||||
{{ $t('AGENT_BOTS.LIST.404') }}
|
||||
</p>
|
||||
<woot-confirm-modal
|
||||
ref="confirmDialog"
|
||||
:title="$t('AGENT_BOTS.DELETE.TITLE')"
|
||||
:description="$t('AGENT_BOTS.DELETE.DESCRIPTION')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="hidden w-1/3 lg:block">
|
||||
<p v-dompurify-html="$t('AGENT_BOTS.SIDEBAR_TXT')" />
|
||||
</div>
|
||||
</div>
|
||||
<woot-button
|
||||
color-scheme="success"
|
||||
class-names="button--fixed-top"
|
||||
icon="add-circle"
|
||||
>
|
||||
<router-link :to="newAgentBotsURL" class="white-text">
|
||||
{{ $t('AGENT_BOTS.ADD.TITLE') }}
|
||||
</router-link>
|
||||
</woot-button>
|
||||
<woot-confirm-modal
|
||||
ref="confirmDialog"
|
||||
:title="$t('AGENT_BOTS.DELETE.TITLE')"
|
||||
:description="$t('AGENT_BOTS.DELETE.DESCRIPTION')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.bots-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.white-text {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,6 +4,7 @@ import CsmlEditBot from './csml/Edit.vue';
|
||||
import CsmlNewBot from './csml/New.vue';
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
import SettingsContent from '../Wrapper.vue';
|
||||
import SettingsWrapper from '../SettingsWrapper.vue';
|
||||
|
||||
export default {
|
||||
routes: [
|
||||
@@ -12,12 +13,7 @@ export default {
|
||||
meta: {
|
||||
permissions: ['administrator'],
|
||||
},
|
||||
component: SettingsContent,
|
||||
props: {
|
||||
headerTitle: 'AGENT_BOTS.HEADER',
|
||||
icon: 'bot',
|
||||
showNewButton: false,
|
||||
},
|
||||
component: SettingsWrapper,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
@@ -28,6 +24,19 @@ export default {
|
||||
permissions: ['administrator'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/settings/agent-bots'),
|
||||
component: SettingsContent,
|
||||
props: () => {
|
||||
return {
|
||||
headerTitle: 'AGENT_BOTS.HEADER',
|
||||
icon: 'bot',
|
||||
showBackButton: true,
|
||||
};
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'csml/new',
|
||||
name: 'agent_bots_csml_new',
|
||||
|
||||
+40
-63
@@ -1,81 +1,58 @@
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import ShowMore from 'dashboard/components/widgets/ShowMore.vue';
|
||||
import AgentBotType from './AgentBotType.vue';
|
||||
|
||||
export default {
|
||||
components: { ShowMore, AgentBotType },
|
||||
props: {
|
||||
agentBot: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
const props = defineProps({
|
||||
agentBot: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
emits: ['edit', 'delete'],
|
||||
computed: {
|
||||
isACSMLTypeBot() {
|
||||
const { bot_type: botType } = this.agentBot;
|
||||
return botType === 'csml';
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const emit = defineEmits(['edit', 'delete']);
|
||||
|
||||
const isACSMLTypeBot = computed(() => {
|
||||
const { bot_type: botType } = props.agentBot;
|
||||
return botType === 'csml';
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tr class="space-x-2">
|
||||
<td class="agent-bot--details">
|
||||
<div class="agent-bot--link">
|
||||
<td class="py-4 ltr:pl-0 ltr:pr-4 rtl:pl-4 rtl:pr-0">
|
||||
<div class="flex items-center break-words font-medium">
|
||||
{{ agentBot.name }}
|
||||
(<AgentBotType :bot-type="agentBot.bot_type" />)
|
||||
</div>
|
||||
<div class="agent-bot--description">
|
||||
<div class="text-sm">
|
||||
<ShowMore :text="agentBot.description || ''" :limit="120" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="flex justify-end gap-1">
|
||||
<woot-button
|
||||
v-if="isACSMLTypeBot"
|
||||
v-tooltip.top="$t('AGENT_BOTS.EDIT.BUTTON_TEXT')"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
icon="edit"
|
||||
@click="$emit('edit', agentBot)"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top="$t('AGENT_BOTS.DELETE.BUTTON_TEXT')"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
@click="$emit('delete', agentBot, index)"
|
||||
/>
|
||||
<td class="align-middle">
|
||||
<div class="flex justify-end gap-1 h-full items-center">
|
||||
<woot-button
|
||||
v-if="isACSMLTypeBot"
|
||||
v-tooltip.top="$t('AGENT_BOTS.EDIT.BUTTON_TEXT')"
|
||||
variant="smooth"
|
||||
size="tiny"
|
||||
color-scheme="secondary"
|
||||
icon="edit"
|
||||
@click="emit('edit', agentBot)"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top="$t('AGENT_BOTS.DELETE.BUTTON_TEXT')"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
size="tiny"
|
||||
icon="dismiss-circle"
|
||||
@click="emit('delete', agentBot, index)"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.agent-bot--link {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-weight: var(--font-weight-medium);
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.agent-bot--description {
|
||||
font-size: var(--font-size-mini);
|
||||
}
|
||||
|
||||
.agent-bot--type {
|
||||
color: var(--s-600);
|
||||
font-weight: var(--font-weight-medium);
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
|
||||
.agent-bot--details {
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
|
||||
+22
-29
@@ -1,43 +1,36 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
botType: {
|
||||
type: String,
|
||||
default: 'webhook',
|
||||
},
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
defineProps({
|
||||
botType: {
|
||||
type: String,
|
||||
default: 'webhook',
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
botTypeConfig: {
|
||||
csml: {
|
||||
label: this.$t('AGENT_BOTS.TYPES.CSML'),
|
||||
thumbnail: '/dashboard/images/agent-bots/csml.png',
|
||||
},
|
||||
webhook: {
|
||||
label: this.$t('AGENT_BOTS.TYPES.WEBHOOK'),
|
||||
thumbnail: '/dashboard/images/agent-bots/webhook.svg',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const botTypeConfig = computed(() => ({
|
||||
csml: {
|
||||
label: t('AGENT_BOTS.TYPES.CSML'),
|
||||
thumbnail: '/dashboard/images/agent-bots/csml.png',
|
||||
},
|
||||
};
|
||||
webhook: {
|
||||
label: t('AGENT_BOTS.TYPES.WEBHOOK'),
|
||||
thumbnail: '/dashboard/images/agent-bots/webhook.svg',
|
||||
},
|
||||
}));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="inline-flex items-center gap-1">
|
||||
<img
|
||||
v-tooltip="botTypeConfig[botType].label"
|
||||
class="agent-bot-type--thumbnail"
|
||||
class="h-3 w-auto"
|
||||
:src="botTypeConfig[botType].thumbnail"
|
||||
:alt="botTypeConfig[botType].label"
|
||||
/>
|
||||
<span>{{ botTypeConfig[botType].label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.agent-bot-type--thumbnail {
|
||||
width: auto;
|
||||
height: var(--space-slab);
|
||||
}
|
||||
</style>
|
||||
|
||||
+3
-12
@@ -108,22 +108,13 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="overflow-auto p-4 max-w-6xl mx-auto my-auto flex flex-wrap h-full"
|
||||
>
|
||||
<woot-button
|
||||
v-if="showAddButton"
|
||||
color-scheme="success"
|
||||
class-names="button--fixed-top"
|
||||
icon="add-circle"
|
||||
@click="openAddHookModal"
|
||||
>
|
||||
{{ $t('INTEGRATION_APPS.ADD_BUTTON') }}
|
||||
</woot-button>
|
||||
<div class="overflow-auto p-4 w-full my-auto flex flex-wrap h-full">
|
||||
<div v-if="showIntegrationHooks" class="w-full">
|
||||
<div v-if="isIntegrationMultiple">
|
||||
<MultipleIntegrationHooks
|
||||
:integration-id="integrationId"
|
||||
:show-add-button="showAddButton"
|
||||
@add="openAddHookModal"
|
||||
@delete="openDeletePopup"
|
||||
/>
|
||||
</div>
|
||||
|
||||
+40
-18
@@ -1,14 +1,23 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { useIntegrationHook } from 'dashboard/composables/useIntegrationHook';
|
||||
import BaseSettingsHeader from 'dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BaseSettingsHeader,
|
||||
},
|
||||
props: {
|
||||
integrationId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
showAddButton: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['delete'],
|
||||
emits: ['delete', 'add'],
|
||||
setup(props) {
|
||||
const { integration, isHookTypeInbox, hasConnectedHooks } =
|
||||
useIntegrationHook(props.integrationId);
|
||||
@@ -45,11 +54,37 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-row gap-4">
|
||||
<div class="w-full lg:w-3/5">
|
||||
<div class="flex flex-col flex-1 gap-8 overflow-auto">
|
||||
<BaseSettingsHeader
|
||||
:title="integration.name"
|
||||
:description="
|
||||
$t(
|
||||
`INTEGRATION_APPS.SIDEBAR_DESCRIPTION.${integration.name.toUpperCase()}`,
|
||||
{ installationName: globalConfig.installationName }
|
||||
)
|
||||
"
|
||||
:feature-name="integrationId"
|
||||
:back-button-label="$t('INTEGRATION_SETTINGS.HEADER')"
|
||||
>
|
||||
<template #actions>
|
||||
<woot-button
|
||||
v-if="showAddButton"
|
||||
class="rounded-md button nice"
|
||||
icon="add-circle"
|
||||
@click="$emit('add')"
|
||||
>
|
||||
{{ $t('INTEGRATION_APPS.ADD_BUTTON') }}
|
||||
</woot-button>
|
||||
</template>
|
||||
</BaseSettingsHeader>
|
||||
<div class="w-full">
|
||||
<table v-if="hasConnectedHooks" class="woot-table">
|
||||
<thead>
|
||||
<th v-for="hookHeader in hookHeaders" :key="hookHeader">
|
||||
<th
|
||||
v-for="hookHeader in hookHeaders"
|
||||
:key="hookHeader"
|
||||
class="ltr:!pl-0 rtl:!pr-0"
|
||||
>
|
||||
{{ hookHeader }}
|
||||
</th>
|
||||
<th v-if="isHookTypeInbox">
|
||||
@@ -61,7 +96,7 @@ export default {
|
||||
<td
|
||||
v-for="property in hook.properties"
|
||||
:key="property"
|
||||
class="break-words"
|
||||
class="ltr:!pl-0 rtl:!pr-0"
|
||||
>
|
||||
{{ property }}
|
||||
</td>
|
||||
@@ -90,18 +125,5 @@ export default {
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden w-1/3 lg:block">
|
||||
<p>
|
||||
<b>{{ integration.name }}</b>
|
||||
</p>
|
||||
<p
|
||||
v-dompurify-html="
|
||||
$t(
|
||||
`INTEGRATION_APPS.SIDEBAR_DESCRIPTION.${integration.name.toUpperCase()}`,
|
||||
{ installationName: globalConfig.installationName }
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -48,6 +48,14 @@ export default {
|
||||
path: frontendURL('accounts/:accountId/settings/integrations'),
|
||||
component: SettingsContent,
|
||||
props: params => {
|
||||
const integrationId = params.params?.integration_id;
|
||||
const hideHeader = ['dialogflow'].includes(integrationId);
|
||||
|
||||
// Don't show header
|
||||
if (hideHeader) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const showBackButton = params.name !== 'settings_integrations';
|
||||
const backUrl =
|
||||
params.name === 'settings_integrations_integration'
|
||||
|
||||
Reference in New Issue
Block a user