Compare commits

...
Author SHA1 Message Date
Sivin VargheseandGitHub 2df0e8cd8b Merge branch 'develop' into chore/upgrade-page 2025-05-07 08:59:09 +05:30
Sivin VargheseandGitHub 687fd71814 Merge branch 'develop' into chore/upgrade-page 2025-05-02 08:49:39 +05:30
Sivin VargheseandGitHub 8741c80fd0 Merge branch 'develop' into chore/upgrade-page 2025-04-11 13:05:25 +05:30
Sivin VargheseandGitHub a3dcc38a2c Merge branch 'develop' into chore/upgrade-page 2025-04-09 09:19:09 +05:30
iamsivin 0de7149a68 chore: Minor fix 2025-04-08 15:52:08 +05:30
Sivin VargheseandGitHub 504b69a1b2 Merge branch 'develop' into chore/upgrade-page 2025-04-08 15:41:12 +05:30
iamsivin 877d4a4339 fix: Warn Runtime directive used on component with non-element root node 2025-04-08 15:39:06 +05:30
Sivin VargheseandGitHub 39211ac75d Merge branch 'develop' into chore/upgrade-page 2025-04-07 10:24:42 +05:30
Sivin VargheseandGitHub 30f1a247db Merge branch 'develop' into chore/upgrade-page 2025-04-03 08:59:58 +05:30
Sivin VargheseandGitHub 5d8406ef4f Merge branch 'develop' into chore/upgrade-page 2025-04-01 09:51:13 +05:30
Sivin VargheseandGitHub 504b65bdac Merge branch 'develop' into chore/upgrade-page 2025-03-31 23:53:56 +05:30
iamsivin d97dd00b77 chore: Revert last commit 2025-03-28 15:23:26 +05:30
iamsivin c3c5cf5bd6 chore: Minor fix 2025-03-28 15:22:19 +05:30
iamsivin db091b54b7 chore: Move bypassUpgradePage logic to upgrade page, now we are not using it in dashboard 2025-03-28 15:19:47 +05:30
iamsivin 8bfcf216c1 chore: Minor fix 2025-03-28 15:06:58 +05:30
iamsivin 64111995ac chore: Adds a loader while fetching limits 2025-03-28 15:04:11 +05:30
7 changed files with 69 additions and 80 deletions
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { onMounted, computed } from 'vue'; import { computed } from 'vue';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
import { useCaptain } from 'dashboard/composables/useCaptain'; import { useCaptain } from 'dashboard/composables/useCaptain';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
@@ -9,7 +9,7 @@ import Banner from 'dashboard/components-next/banner/Banner.vue';
const router = useRouter(); const router = useRouter();
const { accountId } = useAccount(); const { accountId } = useAccount();
const { documentLimits, fetchLimits } = useCaptain(); const { documentLimits } = useCaptain();
const openBilling = () => { const openBilling = () => {
router.push({ router.push({
@@ -24,8 +24,6 @@ const showBanner = computed(() => {
const { currentAvailable } = documentLimits.value; const { currentAvailable } = documentLimits.value;
return currentAvailable === 0; return currentAvailable === 0;
}); });
onMounted(fetchLimits);
</script> </script>
<template> <template>
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { onMounted, computed } from 'vue'; import { computed } from 'vue';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
import { useCaptain } from 'dashboard/composables/useCaptain'; import { useCaptain } from 'dashboard/composables/useCaptain';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
@@ -9,7 +9,7 @@ import Banner from 'dashboard/components-next/banner/Banner.vue';
const router = useRouter(); const router = useRouter();
const { accountId } = useAccount(); const { accountId } = useAccount();
const { responseLimits, fetchLimits } = useCaptain(); const { responseLimits } = useCaptain();
const openBilling = () => { const openBilling = () => {
router.push({ router.push({
@@ -26,8 +26,6 @@ const showBanner = computed(() => {
return consumed / totalCount > 0.8; return consumed / totalCount > 0.8;
}); });
onMounted(fetchLimits);
</script> </script>
<template> <template>
@@ -1,11 +1,9 @@
import { computed } from 'vue'; import { computed } from 'vue';
import { useStore } from 'dashboard/composables/store.js';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
import { useCamelCase } from 'dashboard/composables/useTransformKeys'; import { useCamelCase } from 'dashboard/composables/useTransformKeys';
import { FEATURE_FLAGS } from 'dashboard/featureFlags'; import { FEATURE_FLAGS } from 'dashboard/featureFlags';
export function useCaptain() { export function useCaptain() {
const store = useStore();
const { isCloudFeatureEnabled, currentAccount } = useAccount(); const { isCloudFeatureEnabled, currentAccount } = useAccount();
const captainEnabled = computed(() => { const captainEnabled = computed(() => {
@@ -32,15 +30,10 @@ export function useCaptain() {
return null; return null;
}); });
const fetchLimits = () => {
store.dispatch('accounts/limits');
};
return { return {
captainEnabled, captainEnabled,
captainLimits, captainLimits,
documentLimits, documentLimits,
responseLimits, responseLimits,
fetchLimits,
}; };
} }
@@ -9,6 +9,7 @@ import AccountSelector from 'dashboard/components/layout/sidebarComponents/Accou
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue'; import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue';
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue'; import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue';
import UpgradePage from 'dashboard/routes/dashboard/upgrade/UpgradePage.vue'; import UpgradePage from 'dashboard/routes/dashboard/upgrade/UpgradePage.vue';
import Spinner from 'dashboard/components-next/spinner/Spinner.vue';
import { useUISettings } from 'dashboard/composables/useUISettings'; import { useUISettings } from 'dashboard/composables/useUISettings';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
@@ -37,6 +38,7 @@ export default {
AddLabelModal, AddLabelModal,
NotificationPanel, NotificationPanel,
UpgradePage, UpgradePage,
Spinner,
}, },
setup() { setup() {
const upgradePageRef = ref(null); const upgradePageRef = ref(null);
@@ -64,6 +66,8 @@ export default {
computed: { computed: {
...mapGetters({ ...mapGetters({
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
accountUIFlags: 'accounts/getUIFlags',
isOnChatwootCloud: 'globalConfig/isOnChatwootCloud',
}), }),
currentRoute() { currentRoute() {
return ' '; return ' ';
@@ -71,13 +75,6 @@ export default {
showUpgradePage() { showUpgradePage() {
return this.upgradePageRef?.shouldShowUpgradePage; return this.upgradePageRef?.shouldShowUpgradePage;
}, },
bypassUpgradePage() {
return [
'billing_settings_index',
'settings_inbox_list',
'agent_list',
].includes(this.$route.name);
},
isSidebarOpen() { isSidebarOpen() {
const { show_secondary_sidebar: showSecondarySidebar } = this.uiSettings; const { show_secondary_sidebar: showSecondarySidebar } = this.uiSettings;
return showSecondarySidebar; return showSecondarySidebar;
@@ -116,6 +113,7 @@ export default {
}, },
}, },
mounted() { mounted() {
this.fetchLimits();
this.handleResize(); this.handleResize();
this.$nextTick(this.checkBanner); this.$nextTick(this.checkBanner);
window.addEventListener('resize', this.handleResize); window.addEventListener('resize', this.handleResize);
@@ -129,6 +127,10 @@ export default {
}, },
methods: { methods: {
fetchLimits() {
if (!this.isOnChatwootCloud) return;
this.$store.dispatch('accounts/limits');
},
checkBanner() { checkBanner() {
this.hasBanner = this.hasBanner =
document.getElementsByClassName('woot-banner').length > 0; document.getElementsByClassName('woot-banner').length > 0;
@@ -211,39 +213,43 @@ export default {
@show-add-label-popup="showAddLabelPopup" @show-add-label-popup="showAddLabelPopup"
/> />
<main class="flex flex-1 h-full min-h-0 px-0 overflow-hidden"> <main class="flex flex-1 h-full min-h-0 px-0 overflow-hidden">
<UpgradePage <div
v-show="showUpgradePage" v-if="accountUIFlags.isFetchingLimits"
ref="upgradePageRef" class="flex items-center justify-center w-full h-full"
:bypass-upgrade-page="bypassUpgradePage" >
/> <Spinner :size="24" class="text-n-brand" />
<template v-if="!showUpgradePage"> </div>
<router-view /> <template v-else>
<CommandBar /> <UpgradePage ref="upgradePageRef" />
<NotificationPanel <template v-if="!showUpgradePage">
v-if="isNotificationPanel" <router-view />
@close="closeNotificationPanel" <CommandBar />
<NotificationPanel
v-if="isNotificationPanel"
@close="closeNotificationPanel"
/>
<woot-modal
v-model:show="showAddLabelModal"
:on-close="hideAddLabelPopup"
>
<AddLabelModal @close="hideAddLabelPopup" />
</woot-modal>
</template>
<AccountSelector
:show-account-modal="showAccountModal"
@close-account-modal="toggleAccountModal"
@show-create-account-modal="openCreateAccountModal"
/>
<AddAccountModal
:show="showCreateAccountModal"
@close-account-create-modal="closeCreateAccountModal"
/>
<WootKeyShortcutModal
v-model:show="showShortcutModal"
@close="closeKeyShortcutModal"
@clickaway="closeKeyShortcutModal"
/> />
<woot-modal
v-model:show="showAddLabelModal"
:on-close="hideAddLabelPopup"
>
<AddLabelModal @close="hideAddLabelPopup" />
</woot-modal>
</template> </template>
<AccountSelector
:show-account-modal="showAccountModal"
@close-account-modal="toggleAccountModal"
@show-create-account-modal="openCreateAccountModal"
/>
<AddAccountModal
:show="showCreateAccountModal"
@close-account-create-modal="closeCreateAccountModal"
/>
<WootKeyShortcutModal
v-model:show="showShortcutModal"
@close="closeKeyShortcutModal"
@clickaway="closeKeyShortcutModal"
/>
</main> </main>
</div> </div>
</template> </template>
@@ -14,13 +14,8 @@ import SettingsLayout from '../SettingsLayout.vue';
import ButtonV4 from 'next/button/Button.vue'; import ButtonV4 from 'next/button/Button.vue';
const { currentAccount } = useAccount(); const { currentAccount } = useAccount();
const { const { captainEnabled, captainLimits, documentLimits, responseLimits } =
captainEnabled, useCaptain();
captainLimits,
documentLimits,
responseLimits,
fetchLimits,
} = useCaptain();
const uiFlags = useMapGetter('accounts/getUIFlags'); const uiFlags = useMapGetter('accounts/getUIFlags');
const store = useStore(); const store = useStore();
@@ -62,7 +57,6 @@ const hasABillingPlan = computed(() => {
const fetchAccountDetails = async () => { const fetchAccountDetails = async () => {
if (!hasABillingPlan.value) { if (!hasABillingPlan.value) {
store.dispatch('accounts/subscription'); store.dispatch('accounts/subscription');
fetchLimits();
} }
}; };
@@ -1,8 +1,7 @@
<script setup> <script setup>
import { onMounted, computed, defineExpose, defineProps } from 'vue'; import { computed, defineExpose } from 'vue';
import { useStore } from 'dashboard/composables/store';
import { useMapGetter } from 'dashboard/composables/store.js'; import { useMapGetter } from 'dashboard/composables/store.js';
import { useRouter } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { useAccount } from 'dashboard/composables/useAccount'; import { useAccount } from 'dashboard/composables/useAccount';
import { differenceInDays } from 'date-fns'; import { differenceInDays } from 'date-fns';
import { useAdmin } from 'dashboard/composables/useAdmin'; import { useAdmin } from 'dashboard/composables/useAdmin';
@@ -11,20 +10,14 @@ import { useI18n } from 'vue-i18n';
import NextButton from 'dashboard/components-next/button/Button.vue'; import NextButton from 'dashboard/components-next/button/Button.vue';
import Icon from 'dashboard/components-next/icon/Icon.vue'; import Icon from 'dashboard/components-next/icon/Icon.vue';
const props = defineProps({
bypassUpgradePage: {
type: Boolean,
default: false,
},
});
const router = useRouter(); const router = useRouter();
const store = useStore(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { accountId, currentAccount } = useAccount(); const { accountId, currentAccount } = useAccount();
const { isAdmin } = useAdmin(); const { isAdmin } = useAdmin();
const isOnChatwootCloud = useMapGetter('globalConfig/isOnChatwootCloud'); const isOnChatwootCloud = useMapGetter('globalConfig/isOnChatwootCloud');
const accountUIFlags = useMapGetter('accounts/getUIFlags');
const testLimit = ({ allowed, consumed }) => { const testLimit = ({ allowed, consumed }) => {
return consumed > allowed; return consumed > allowed;
@@ -41,6 +34,14 @@ const isTrialAccount = computed(() => {
return diffDays <= 15; return diffDays <= 15;
}); });
const bypassUpgradePage = computed(() => {
return [
'billing_settings_index',
'settings_inbox_list',
'agent_list',
].includes(route.name);
});
const limitExceededMessage = computed(() => { const limitExceededMessage = computed(() => {
const account = currentAccount.value; const account = currentAccount.value;
if (!account?.limits) return ''; if (!account?.limits) return '';
@@ -80,17 +81,14 @@ const isLimitExceeded = computed(() => {
}); });
const shouldShowUpgradePage = computed(() => { const shouldShowUpgradePage = computed(() => {
// Hide upgrade page while fetching limits
if (accountUIFlags.isFetchingLimits) return false;
// Skip upgrade page in Billing, Inbox, and Agent pages // Skip upgrade page in Billing, Inbox, and Agent pages
if (props.bypassUpgradePage) return false; if (bypassUpgradePage.value) return false;
if (!isOnChatwootCloud.value) return false; if (!isOnChatwootCloud.value) return false;
if (isTrialAccount.value) return false; if (isTrialAccount.value) return false;
return isLimitExceeded.value; return isLimitExceeded.value;
}); });
const fetchLimits = () => {
store.dispatch('accounts/limits');
};
const routeToBilling = () => { const routeToBilling = () => {
router.push({ router.push({
name: 'billing_settings_index', name: 'billing_settings_index',
@@ -98,8 +96,6 @@ const routeToBilling = () => {
}); });
}; };
onMounted(() => fetchLimits());
defineExpose({ shouldShowUpgradePage }); defineExpose({ shouldShowUpgradePage });
</script> </script>
@@ -18,6 +18,7 @@ const state = {
isFetchingItem: false, isFetchingItem: false,
isUpdating: false, isUpdating: false,
isCheckoutInProcess: false, isCheckoutInProcess: false,
isFetchingLimits: false,
}, },
}; };
@@ -133,11 +134,14 @@ export const actions = {
}, },
limits: async ({ commit }) => { limits: async ({ commit }) => {
commit(types.default.SET_ACCOUNT_UI_FLAG, { isFetchingLimits: true });
try { try {
const response = await EnterpriseAccountAPI.getLimits(); const response = await EnterpriseAccountAPI.getLimits();
commit(types.default.SET_ACCOUNT_LIMITS, response.data); commit(types.default.SET_ACCOUNT_LIMITS, response.data);
} catch (error) { } catch (error) {
// silent error // silent error
} finally {
commit(types.default.SET_ACCOUNT_UI_FLAG, { isFetchingLimits: false });
} }
}, },