Merge branch 'develop' into feat/CW-3082

This commit is contained in:
Sivin Varghese
2024-04-24 09:27:10 +05:30
committed by GitHub
574 changed files with 10083 additions and 1785 deletions
@@ -1,6 +1,6 @@
<template>
<div
class="w-1/4 bg-white dark:bg-slate-900 border-slate-50 dark:border-slate-800/50 h-full text-sm overflow-y-auto relative"
class="relative w-1/4 h-full overflow-y-auto text-sm bg-white dark:bg-slate-900 border-slate-50 dark:border-slate-800/50"
:class="showAvatar ? 'border-l border-solid ' : 'border-r border-solid'"
>
<contact-info
@@ -40,6 +40,9 @@
attribute-class="conversation--attribute"
attribute-from="contact_panel"
:custom-attributes="contact.custom_attributes"
:empty-state-message="
$t('CONTACT_PANEL.SIDEBAR_SECTIONS.NO_RECORDS_FOUND')
"
class="even"
/>
</accordion-item>
@@ -1,6 +1,6 @@
<template>
<div
class="bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-300 border-slate-50 dark:border-slate-800/50 border-l rtl:border-l-0 rtl:border-r contact--panel overflow-y-auto"
class="overflow-y-auto bg-white border-l dark:bg-slate-900 text-slate-900 dark:text-slate-300 border-slate-50 dark:border-slate-800/50 rtl:border-l-0 rtl:border-r contact--panel"
>
<contact-info
:contact="contact"
@@ -89,6 +89,9 @@
class="even"
attribute-from="conversation_contact_panel"
:contact-id="contact.id"
:empty-state-message="
$t('CONVERSATION_CUSTOM_ATTRIBUTES.NO_RECORDS_FOUND')
"
/>
</accordion-item>
</div>
@@ -17,6 +17,12 @@
@delete="onDelete"
@copy="onCopy"
/>
<p
v-if="!displayedAttributes.length && emptyStateMessage"
class="p-3 text-center"
>
{{ emptyStateMessage }}
</p>
<!-- Show more and show less buttons show it if the filteredAttributes length is greater than 5 -->
<div v-if="filteredAttributes.length > 5" class="flex px-2 py-2">
<woot-button
@@ -59,6 +65,10 @@ export default {
type: String,
required: true,
},
emptyStateMessage: {
type: String,
default: '',
},
},
data() {
return {
@@ -94,8 +94,8 @@ export default {
const type = 'sla';
try {
this.$store.dispatch('slaReports/download', {
fileName: generateFileName({ type, to: this.to }),
...this.requestPayload,
fileName: generateFileName({ type, to: this.activeFilter.to }),
...this.activeFilter,
});
} catch (error) {
this.showAlert(this.$t('SLA_REPORTS.DOWNLOAD_FAILED'));
@@ -1,7 +1,7 @@
<template>
<div class="flex flex-col md:flex-row justify-between mb-4">
<div class="flex flex-col justify-between gap-3 mb-4 md:flex-row">
<div
class="md:grid flex-col gap-3 w-full grid grid-cols-[repeat(auto-fit,minmax(200px,1fr))] p-5"
class="w-full grid gap-y-2 gap-x-1.5 grid-cols-[repeat(auto-fill,minmax(250px,1fr))]"
>
<reports-filters-date-range @on-range-change="onDateRangeChange" />
<woot-date-range-picker
@@ -41,7 +41,7 @@
/>
</div>
<div v-if="showBusinessHoursSwitch" class="flex items-center">
<span class="text-sm whitespace-nowrap mx-2">
<span class="mx-2 text-sm whitespace-nowrap">
{{ $t('REPORT.BUSINESS_HOURS') }}
</span>
<span>
@@ -231,9 +231,3 @@ export default {
},
};
</script>
<style scoped>
.filter-container {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
</style>
@@ -10,44 +10,17 @@
<SLAListItemLoading v-for="ii in 2" :key="ii" class="mb-3" />
</template>
<template #body>
<div v-if="!records.length" class="w-full min-h-[12rem] relative">
<div class="w-full space-y-3">
<SLA-list-item
class="opacity-25 dark:opacity-20"
:sla-name="$t('SLA.LIST.EMPTY.TITLE_1')"
:description="$t('SLA.LIST.EMPTY.DESC_1')"
first-response="20m"
next-response="1h"
resolution-time="24h"
has-business-hours
/>
<SLA-list-item
class="opacity-25 dark:opacity-20"
:sla-name="$t('SLA.LIST.EMPTY.TITLE_2')"
:description="$t('SLA.LIST.EMPTY.DESC_2')"
first-response="2h"
next-response="4h"
resolution-time="4d"
has-business-hours
/>
</div>
<div
class="absolute inset-0 flex flex-col items-center justify-center w-full h-full bg-gradient-to-t from-white dark:from-slate-900 to-transparent"
>
<p class="max-w-xs text-sm font-medium text-center">
{{ $t('SLA.LIST.404') }}
</p>
<woot-button
color-scheme="primary"
icon="plus-sign"
class="px-5 mt-4 rounded-xl"
@click="openAddPopup"
>
{{ $t('SLA.ADD_ACTION_LONG') }}
</woot-button>
</div>
</div>
<div v-if="records.length" class="flex flex-col w-full h-full gap-3">
<SLAPaywallEnterprise
v-if="isBehindAPaywall"
:is-super-admin="isSuperAdmin"
:is-on-chatwoot-cloud="isOnChatwootCloud"
@click="onClickCTA"
/>
<SLAEmptyState
v-else-if="!records.length"
@primary-action="openAddPopup"
/>
<div v-else class="flex flex-col w-full h-full gap-3">
<SLA-list-item
v-for="sla in records"
:key="sla.title"
@@ -80,25 +53,30 @@
</settings-layout>
</template>
<script>
import AddSLA from './AddSLA.vue';
import SettingsLayout from '../SettingsLayout.vue';
import SLAEmptyState from './components/SLAEmptyState.vue';
import SLAHeader from './components/SLAHeader.vue';
import SLAListItem from './components/SLAListItem.vue';
import SLAListItemLoading from './components/SLAListItemLoading.vue';
import SLAPaywallEnterprise from './components/SLAPaywallEnterprise.vue';
import { mapGetters } from 'vuex';
import { convertSecondsToTimeUnit } from '@chatwoot/utils';
import AddSLA from './AddSLA.vue';
import alertMixin from 'shared/mixins/alertMixin';
import configMixin from 'shared/mixins/configMixin';
export default {
components: {
AddSLA,
SettingsLayout,
SLAEmptyState,
SLAHeader,
SLAListItem,
SLAListItemLoading,
SettingsLayout,
SLAPaywallEnterprise,
},
mixins: [alertMixin],
mixins: [alertMixin, configMixin],
data() {
return {
loading: {},
@@ -109,7 +87,12 @@ export default {
},
computed: {
...mapGetters({
globalConfig: 'globalConfig/get',
isOnChatwootCloud: 'globalConfig/isOnChatwootCloud',
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
records: 'sla/getSLA',
currentUser: 'getCurrentUser',
accountId: 'getCurrentAccountId',
uiFlags: 'sla/getUIFlags',
}),
deleteConfirmText() {
@@ -121,12 +104,21 @@ export default {
deleteMessage() {
return ` ${this.selectedResponse.name}`;
},
isBehindAPaywall() {
return !this.isFeatureEnabledonAccount(this.accountId, 'sla');
},
isSuperAdmin() {
return this.currentUser.type === 'SuperAdmin';
},
},
mounted() {
this.$store.dispatch('sla/get');
},
methods: {
openAddPopup() {
if (this.isBehindAPaywall) {
return;
}
this.showAddPopup = true;
},
hideAddPopup() {
@@ -166,6 +158,12 @@ export default {
if (!time) return '-';
return `${time}${unit}`;
},
onClickCTA() {
this.$router.push({
name: 'billing_settings_index',
params: { accountId: this.accountId },
});
},
},
};
</script>
@@ -0,0 +1,33 @@
<script setup>
import SLAListItem from './SLAListItem.vue';
</script>
<template>
<div class="w-full min-h-[12rem] relative">
<div class="w-full space-y-3">
<SLA-list-item
class="opacity-25 dark:opacity-20"
:sla-name="$t('SLA.LIST.EMPTY.TITLE_1')"
:description="$t('SLA.LIST.EMPTY.DESC_1')"
first-response="20m"
next-response="1h"
resolution-time="24h"
has-business-hours
/>
<SLA-list-item
class="opacity-25 dark:opacity-20"
:sla-name="$t('SLA.LIST.EMPTY.TITLE_2')"
:description="$t('SLA.LIST.EMPTY.DESC_2')"
first-response="2h"
next-response="4h"
resolution-time="4d"
has-business-hours
/>
</div>
<div
class="absolute inset-0 flex flex-col items-center justify-center w-full h-full bg-gradient-to-t from-white dark:from-slate-900 to-transparent"
>
<slot />
</div>
</div>
</template>
@@ -0,0 +1,22 @@
<script setup>
import BaseEmptyState from './BaseEmptyState.vue';
const emit = defineEmits(['primary-action']);
const primaryAction = () => emit('primary-action');
</script>
<template>
<base-empty-state>
<p class="max-w-xs text-sm font-medium text-center">
{{ $t('SLA.LIST.404') }}
</p>
<woot-button
color-scheme="primary"
icon="plus-sign"
class="px-5 mt-4 rounded-xl"
@click="primaryAction"
>
{{ $t('SLA.ADD_ACTION_LONG') }}
</woot-button>
</base-empty-state>
</template>
@@ -0,0 +1,73 @@
<script setup>
import BaseEmptyState from './BaseEmptyState.vue';
const props = defineProps({
isSuperAdmin: {
type: Boolean,
default: false,
},
isOnChatwootCloud: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['click']);
const i18nKey = props.isOnChatwootCloud ? 'PAYWALL' : 'ENTERPRISE_PAYWALL';
</script>
<template>
<base-empty-state>
<div
class="flex flex-col max-w-md px-6 py-6 bg-white border shadow dark:bg-slate-800 rounded-xl border-slate-100 dark:border-slate-900"
>
<div class="flex items-center w-full gap-2 mb-4">
<span
class="flex items-center justify-center w-6 h-6 rounded-full bg-woot-75/70 dark:bg-woot-800/40"
>
<fluent-icon
size="14"
class="flex-shrink-0 text-woot-500 dark:text-woot-500"
icon="lock-closed"
/>
</span>
<span class="text-base font-medium text-slate-900 dark:text-white">
{{ $t('SLA.PAYWALL.TITLE') }}
</span>
</div>
<p
class="text-sm font-normal"
v-html="$t(`SLA.${i18nKey}.AVAILABLE_ON`)"
/>
<p class="text-sm font-normal">
{{ $t(`SLA.${i18nKey}.UPGRADE_PROMPT`) }}
<span v-if="!isOnChatwootCloud && !isSuperAdmin">
{{ $t('SLA.ENTERPRISE_PAYWALL.ASK_ADMIN') }}
</span>
</p>
<template v-if="isOnChatwootCloud">
<woot-button
color-scheme="primary"
class="w-full mt-2 text-center rounded-xl"
size="expanded"
is-expanded
@click="emit('click')"
>
{{ $t('SLA.PAYWALL.UPGRADE_NOW') }}
</woot-button>
</template>
<template v-if="isSuperAdmin">
<a href="/super_admin" class="block w-full">
<woot-button
color-scheme="primary"
class="w-full mt-2 text-center rounded-xl"
size="expanded"
is-expanded
>
{{ $t('SLA.PAYWALL.UPGRADE_NOW') }}
</woot-button>
</a>
</template>
</div>
</base-empty-state>
</template>