Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68ed5a4b4f | ||
|
|
7ecb993d06 | ||
|
|
c00a157c03 | ||
|
|
3750689bee | ||
|
|
0511bf4ba6 | ||
|
|
9f50638a40 | ||
|
|
f5ac272e3b | ||
|
|
2ba7318817 | ||
|
|
412303d1cd | ||
|
|
47b9399208 | ||
|
|
0830ad78b6 | ||
|
|
0b8df762f9 | ||
|
|
f24c87f9b2 | ||
|
|
f62a4170b6 | ||
|
|
2f090dbc61 | ||
|
|
ec17682d7a | ||
|
|
7861ce8c47 | ||
|
|
e5de41fea4 | ||
|
|
adb0e94cbd | ||
|
|
42fb083491 | ||
|
|
9101e1e221 | ||
|
|
91bac16c29 | ||
|
|
97699f3087 | ||
|
|
1242cfd704 | ||
|
|
6963c668bf |
@@ -1,15 +1,6 @@
|
|||||||
class Google::CallbacksController < OauthCallbackController
|
class Google::CallbacksController < OauthCallbackController
|
||||||
include GoogleConcern
|
include GoogleConcern
|
||||||
|
|
||||||
def find_channel_by_email
|
|
||||||
# find by imap_login first, and then by email
|
|
||||||
# this ensures the legacy users can migrate correctly even if inbox email address doesn't match
|
|
||||||
imap_channel = Channel::Email.find_by(imap_login: users_data['email'], account: account)
|
|
||||||
return imap_channel if imap_channel
|
|
||||||
|
|
||||||
Channel::Email.find_by(email: users_data['email'], account: account)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def provider_name
|
def provider_name
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class OauthCallbackController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_inbox
|
def find_or_create_inbox
|
||||||
channel_email = find_channel_by_email
|
channel_email = Channel::Email.find_by(email: users_data['email'], account: account)
|
||||||
# we need this value to know where to redirect on sucessful processing of the callback
|
# we need this value to know where to redirect on sucessful processing of the callback
|
||||||
channel_exists = channel_email.present?
|
channel_exists = channel_email.present?
|
||||||
|
|
||||||
@@ -39,10 +39,6 @@ class OauthCallbackController < ApplicationController
|
|||||||
[channel_email.inbox, channel_exists]
|
[channel_email.inbox, channel_exists]
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_channel_by_email
|
|
||||||
Channel::Email.find_by(email: users_data['email'], account: account)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_channel(channel_email)
|
def update_channel(channel_email)
|
||||||
channel_email.update!({
|
channel_email.update!({
|
||||||
imap_login: users_data['email'], imap_address: imap_address,
|
imap_login: users_data['email'], imap_address: imap_address,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { useStore } from 'dashboard/composables/store';
|
|||||||
import WootSnackbarBox from './components/SnackbarContainer.vue';
|
import WootSnackbarBox from './components/SnackbarContainer.vue';
|
||||||
import { setColorTheme } from './helper/themeHelper';
|
import { setColorTheme } from './helper/themeHelper';
|
||||||
import { isOnOnboardingView } from 'v3/helpers/RouteHelper';
|
import { isOnOnboardingView } from 'v3/helpers/RouteHelper';
|
||||||
import { useAccount } from 'dashboard/composables/useAccount';
|
|
||||||
import {
|
import {
|
||||||
registerSubscription,
|
registerSubscription,
|
||||||
verifyServiceWorkerExistence,
|
verifyServiceWorkerExistence,
|
||||||
@@ -36,9 +35,8 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { accountId } = useAccount();
|
|
||||||
|
|
||||||
return { router, store, currentAccountId: accountId };
|
return { router, store };
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -54,7 +52,11 @@ export default {
|
|||||||
currentUser: 'getCurrentUser',
|
currentUser: 'getCurrentUser',
|
||||||
authUIFlags: 'getAuthUIFlags',
|
authUIFlags: 'getAuthUIFlags',
|
||||||
accountUIFlags: 'accounts/getUIFlags',
|
accountUIFlags: 'accounts/getUIFlags',
|
||||||
|
// currentAccountId: 'getCurrentAccountId',
|
||||||
}),
|
}),
|
||||||
|
currentAccountId() {
|
||||||
|
return this.$route.params.accountId;
|
||||||
|
},
|
||||||
hasAccounts() {
|
hasAccounts() {
|
||||||
const { accounts = [] } = this.currentUser || {};
|
const { accounts = [] } = this.currentUser || {};
|
||||||
return accounts.length > 0;
|
return accounts.length > 0;
|
||||||
@@ -70,19 +72,23 @@ export default {
|
|||||||
this.showAddAccountModal = true;
|
this.showAddAccountModal = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
currentAccountId: {
|
currentAccountId() {
|
||||||
immediate: true,
|
console.log('THIS CALL', this.currentAccountId);
|
||||||
handler() {
|
if (this.currentAccountId) {
|
||||||
if (this.currentAccountId) {
|
this.initializeAccount();
|
||||||
this.initializeAccount();
|
} else {
|
||||||
}
|
console.log('NO ACCOUNT ID');
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
created() {
|
||||||
|
this.setLocale(window.chatwootConfig.selectedLocale);
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.setLocale(window.chatwootConfig.selectedLocale);
|
||||||
this.initializeColorTheme();
|
this.initializeColorTheme();
|
||||||
this.listenToThemeChanges();
|
this.listenToThemeChanges();
|
||||||
this.setLocale(window.chatwootConfig.selectedLocale);
|
await this.$store.dispatch('accounts/get');
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
if (this.reconnectService) {
|
if (this.reconnectService) {
|
||||||
@@ -98,7 +104,7 @@ export default {
|
|||||||
mql.onchange = e => setColorTheme(e.matches);
|
mql.onchange = e => setColorTheme(e.matches);
|
||||||
},
|
},
|
||||||
setLocale(locale) {
|
setLocale(locale) {
|
||||||
this.$root.$i18n.locale = locale;
|
this.$i18n.locale = locale;
|
||||||
},
|
},
|
||||||
async initializeAccount() {
|
async initializeAccount() {
|
||||||
await this.$store.dispatch('accounts/get');
|
await this.$store.dispatch('accounts/get');
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { getSidebarItems } from './config/default-sidebar';
|
import { getSidebarItems } from './config/default-sidebar';
|
||||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||||
import { useAccount } from 'dashboard/composables/useAccount';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
import PrimarySidebar from './sidebarComponents/Primary.vue';
|
import PrimarySidebar from './sidebarComponents/Primary.vue';
|
||||||
@@ -34,7 +33,6 @@ export default {
|
|||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { accountId } = useAccount();
|
|
||||||
|
|
||||||
const toggleKeyShortcutModal = () => {
|
const toggleKeyShortcutModal = () => {
|
||||||
emit('openKeyShortcutModal');
|
emit('openKeyShortcutModal');
|
||||||
@@ -74,7 +72,6 @@ export default {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
toggleKeyShortcutModal,
|
toggleKeyShortcutModal,
|
||||||
accountId,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -85,6 +82,7 @@ export default {
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
|
accountId: 'getCurrentAccountId',
|
||||||
currentUser: 'getCurrentUser',
|
currentUser: 'getCurrentUser',
|
||||||
globalConfig: 'globalConfig/get',
|
globalConfig: 'globalConfig/get',
|
||||||
inboxes: 'inboxes/getInboxes',
|
inboxes: 'inboxes/getInboxes',
|
||||||
@@ -122,6 +120,7 @@ export default {
|
|||||||
this.currentUser,
|
this.currentUser,
|
||||||
this.accountId
|
this.accountId
|
||||||
);
|
);
|
||||||
|
|
||||||
const menuItems = this.sideMenuConfig.primaryMenu;
|
const menuItems = this.sideMenuConfig.primaryMenu;
|
||||||
return menuItems.filter(menuItem => {
|
return menuItems.filter(menuItem => {
|
||||||
const isAvailableForTheUser = hasPermissions(
|
const isAvailableForTheUser = hasPermissions(
|
||||||
@@ -132,6 +131,7 @@ export default {
|
|||||||
if (!isAvailableForTheUser) {
|
if (!isAvailableForTheUser) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
menuItem.alwaysVisibleOnChatwootInstances &&
|
menuItem.alwaysVisibleOnChatwootInstances &&
|
||||||
!this.isACustomBrandedInstance
|
!this.isACustomBrandedInstance
|
||||||
@@ -139,10 +139,12 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (menuItem.featureFlag) {
|
if (menuItem.featureFlag) {
|
||||||
return this.isFeatureEnabledonAccount(
|
const isEnabled = this.isFeatureEnabledonAccount(
|
||||||
this.accountId,
|
this.accountId,
|
||||||
menuItem.featureFlag
|
menuItem.featureFlag
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return isEnabled;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ export default {
|
|||||||
showOptionsMenu: false,
|
showOptionsMenu: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log('MENU ITEMS', this.menuItems);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
frontendURL,
|
frontendURL,
|
||||||
toggleOptions() {
|
toggleOptions() {
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log(
|
||||||
|
'MOUNTED: PRIMARY NAV ITEM',
|
||||||
|
this.name,
|
||||||
|
this.$t(`SIDEBAR.${this.name}`)
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { Letter } from 'vue-letter';
|
import Letter from 'vue-letter';
|
||||||
import GalleryView from '../components/GalleryView.vue';
|
import GalleryView from '../components/GalleryView.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { ref } from 'vue';
|
||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
import { useAccount } from '../useAccount';
|
import { useAccount } from '../useAccount';
|
||||||
import { useRoute } from 'vue-router';
|
import { useStoreGetters } from 'dashboard/composables/store';
|
||||||
|
|
||||||
vi.mock('vue-router');
|
vi.mock('dashboard/composables/store');
|
||||||
|
|
||||||
describe('useAccount', () => {
|
describe('useAccount', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
useRoute.mockReturnValue({
|
useStoreGetters.mockReturnValue({
|
||||||
params: {
|
getCurrentAccountId: ref(123),
|
||||||
accountId: 123,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useStoreGetters } from 'dashboard/composables/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composable for account-related operations.
|
* Composable for account-related operations.
|
||||||
* @returns {Object} An object containing account-related properties and methods.
|
* @returns {Object} An object containing account-related properties and methods.
|
||||||
*/
|
*/
|
||||||
export function useAccount() {
|
export function useAccount() {
|
||||||
|
const getters = useStoreGetters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computed property for the current account ID.
|
* Computed property for the current account ID.
|
||||||
* @type {import('vue').ComputedRef<number>}
|
* @type {import('vue').ComputedRef<number>}
|
||||||
*/
|
*/
|
||||||
const route = useRoute();
|
const accountId = computed(() => getters.getCurrentAccountId.value);
|
||||||
|
|
||||||
const accountId = computed(() => {
|
|
||||||
return Number(route.params.accountId);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an account-scoped URL.
|
* Generates an account-scoped URL.
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const showNewButton = computed(
|
|||||||
button-route="new"
|
button-route="new"
|
||||||
:icon="icon"
|
:icon="icon"
|
||||||
:header-title="t(headerTitle)"
|
:header-title="t(headerTitle)"
|
||||||
:button-text="t(headerButtonText)"
|
:button-text="headerButtonText ? t(headerButtonText) : ''"
|
||||||
:show-back-button="showBackButton"
|
:show-back-button="showBackButton"
|
||||||
:back-url="backUrl"
|
:back-url="backUrl"
|
||||||
:show-new-button="showNewButton"
|
:show-new-button="showNewButton"
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { mapGetters } from 'vuex';
|
|||||||
import { useAlert } from 'dashboard/composables';
|
import { useAlert } from 'dashboard/composables';
|
||||||
import { useUISettings } from 'dashboard/composables/useUISettings';
|
import { useUISettings } from 'dashboard/composables/useUISettings';
|
||||||
import { useConfig } from 'dashboard/composables/useConfig';
|
import { useConfig } from 'dashboard/composables/useConfig';
|
||||||
import { useAccount } from 'dashboard/composables/useAccount';
|
|
||||||
import { FEATURE_FLAGS } from '../../../../featureFlags';
|
import { FEATURE_FLAGS } from '../../../../featureFlags';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import { getLanguageDirection } from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
|
import { getLanguageDirection } from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
|
||||||
@@ -14,10 +13,9 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const { updateUISettings } = useUISettings();
|
const { updateUISettings } = useUISettings();
|
||||||
const { enabledLanguages } = useConfig();
|
const { enabledLanguages } = useConfig();
|
||||||
const { accountId } = useAccount();
|
|
||||||
const v$ = useVuelidate();
|
const v$ = useVuelidate();
|
||||||
|
|
||||||
return { updateUISettings, v$, enabledLanguages, accountId };
|
return { updateUISettings, v$, enabledLanguages };
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -48,6 +46,7 @@ export default {
|
|||||||
globalConfig: 'globalConfig/get',
|
globalConfig: 'globalConfig/get',
|
||||||
getAccount: 'accounts/getAccount',
|
getAccount: 'accounts/getAccount',
|
||||||
uiFlags: 'accounts/getUIFlags',
|
uiFlags: 'accounts/getUIFlags',
|
||||||
|
accountId: 'getCurrentAccountId',
|
||||||
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
|
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
|
||||||
}),
|
}),
|
||||||
showAutoResolutionConfig() {
|
showAutoResolutionConfig() {
|
||||||
@@ -96,8 +95,8 @@ export default {
|
|||||||
return this.id.toString();
|
return this.id.toString();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.initializeAccount();
|
await this.initializeAccount();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async initializeAccount() {
|
async initializeAccount() {
|
||||||
@@ -113,7 +112,7 @@ export default {
|
|||||||
latest_chatwoot_version: latestChatwootVersion,
|
latest_chatwoot_version: latestChatwootVersion,
|
||||||
} = this.getAccount(this.accountId);
|
} = this.getAccount(this.accountId);
|
||||||
|
|
||||||
this.$root.$i18n.locale = locale;
|
this.$i18n.locale = locale;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -141,7 +140,7 @@ export default {
|
|||||||
support_email: this.supportEmail,
|
support_email: this.supportEmail,
|
||||||
auto_resolve_duration: this.autoResolveDuration,
|
auto_resolve_duration: this.autoResolveDuration,
|
||||||
});
|
});
|
||||||
this.$root.$i18n.locale = this.locale;
|
this.$i18n.locale = this.locale;
|
||||||
this.getAccount(this.id).locale = this.locale;
|
this.getAccount(this.id).locale = this.locale;
|
||||||
this.updateDirectionView(this.locale);
|
this.updateDirectionView(this.locale);
|
||||||
useAlert(this.$t('GENERAL_SETTINGS.UPDATE.SUCCESS'));
|
useAlert(this.$t('GENERAL_SETTINGS.UPDATE.SUCCESS'));
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const emailProviderList = computed(() => {
|
|||||||
|
|
||||||
function onClick(emailProvider) {
|
function onClick(emailProvider) {
|
||||||
if (emailProvider.isEnabled) {
|
if (emailProvider.isEnabled) {
|
||||||
provider.value = emailProvider.key;
|
this.provider = emailProvider.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+2
-9
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref } from 'vue';
|
||||||
import InboxReconnectionRequired from '../../components/InboxReconnectionRequired.vue';
|
import InboxReconnectionRequired from '../../components/InboxReconnectionRequired.vue';
|
||||||
import googleClient from 'dashboard/api/channel/googleClient';
|
import googleClient from 'dashboard/api/channel/googleClient';
|
||||||
|
|
||||||
@@ -17,18 +17,11 @@ const { t } = useI18n();
|
|||||||
|
|
||||||
const isRequestingAuthorization = ref(false);
|
const isRequestingAuthorization = ref(false);
|
||||||
|
|
||||||
const inboxEmail = computed(() => {
|
|
||||||
if (props.inbox.imap_login && props.inbox.imap_enabled) {
|
|
||||||
return props.inbox.imap_login;
|
|
||||||
}
|
|
||||||
return props.inbox.email;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function requestAuthorization() {
|
async function requestAuthorization() {
|
||||||
try {
|
try {
|
||||||
isRequestingAuthorization.value = true;
|
isRequestingAuthorization.value = true;
|
||||||
const response = await googleClient.generateAuthorization({
|
const response = await googleClient.generateAuthorization({
|
||||||
email: inboxEmail.value,
|
email: props.inbox.email,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -43,7 +43,11 @@ export const getters = {
|
|||||||
return diffDays <= TRIAL_PERIOD_DAYS;
|
return diffDays <= TRIAL_PERIOD_DAYS;
|
||||||
},
|
},
|
||||||
isFeatureEnabledonAccount: $state => (id, featureName) => {
|
isFeatureEnabledonAccount: $state => (id, featureName) => {
|
||||||
|
console.log('----------------------------------------------------');
|
||||||
|
console.log('CHECK ENABLED for', featureName, id);
|
||||||
|
console.log($state, findRecordById($state, id));
|
||||||
const { features = {} } = findRecordById($state, id);
|
const { features = {} } = findRecordById($state, id);
|
||||||
|
console.log('FEATURES', features, features[featureName]);
|
||||||
return features[featureName] || false;
|
return features[featureName] || false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Multiselect from 'vue-multiselect';
|
|||||||
import { plugin, defaultConfig } from '@formkit/vue';
|
import { plugin, defaultConfig } from '@formkit/vue';
|
||||||
import WootSwitch from 'components/ui/Switch.vue';
|
import WootSwitch from 'components/ui/Switch.vue';
|
||||||
import WootWizard from 'components/ui/Wizard.vue';
|
import WootWizard from 'components/ui/Wizard.vue';
|
||||||
|
import { sync } from 'vuex-router-sync';
|
||||||
import FloatingVue from 'floating-vue';
|
import FloatingVue from 'floating-vue';
|
||||||
import WootUiKit from 'dashboard/components';
|
import WootUiKit from 'dashboard/components';
|
||||||
import App from 'dashboard/App.vue';
|
import App from 'dashboard/App.vue';
|
||||||
@@ -17,7 +18,6 @@ import i18nMessages from 'dashboard/i18n';
|
|||||||
import createAxios from 'dashboard/helper/APIHelper';
|
import createAxios from 'dashboard/helper/APIHelper';
|
||||||
|
|
||||||
import commonHelpers, { isJSONValid } from 'dashboard/helper/commons';
|
import commonHelpers, { isJSONValid } from 'dashboard/helper/commons';
|
||||||
import { sync } from 'vuex-router-sync';
|
|
||||||
import router, { initalizeRouter } from 'dashboard/routes';
|
import router, { initalizeRouter } from 'dashboard/routes';
|
||||||
import store from 'dashboard/store';
|
import store from 'dashboard/store';
|
||||||
import constants from 'dashboard/constants/globals';
|
import constants from 'dashboard/constants/globals';
|
||||||
@@ -39,11 +39,10 @@ import 'floating-vue/dist/style.css';
|
|||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
legacy: false, // https://github.com/intlify/vue-i18n/issues/1902
|
legacy: false, // https://github.com/intlify/vue-i18n/issues/1902
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
|
fallbackLocale: 'en',
|
||||||
messages: i18nMessages,
|
messages: i18nMessages,
|
||||||
});
|
});
|
||||||
|
|
||||||
sync(store, router);
|
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
app.use(store);
|
app.use(store);
|
||||||
@@ -99,9 +98,11 @@ app.component('fluent-icon', FluentIcon);
|
|||||||
app.directive('resize', vResizeObserver);
|
app.directive('resize', vResizeObserver);
|
||||||
app.directive('on-clickaway', onClickaway);
|
app.directive('on-clickaway', onClickaway);
|
||||||
|
|
||||||
|
sync(store, router);
|
||||||
// load common helpers into js
|
// load common helpers into js
|
||||||
commonHelpers();
|
commonHelpers();
|
||||||
window.WOOT_STORE = store;
|
window.WOOT_STORE = store;
|
||||||
|
window.dashboardApp = app;
|
||||||
window.WootConstants = constants;
|
window.WootConstants = constants;
|
||||||
window.axios = createAxios(axios);
|
window.axios = createAxios(axios);
|
||||||
// [VITE] Disabled this we don't need it, we can use `useEmitter` directly
|
// [VITE] Disabled this we don't need it, we can use `useEmitter` directly
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
legacy: false, // https://github.com/intlify/vue-i18n/issues/1902
|
legacy: false, // https://github.com/intlify/vue-i18n/issues/1902
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
|
fallbackLocale: 'en',
|
||||||
messages: i18nMessages,
|
messages: i18nMessages,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setLocale(locale) {
|
setLocale(locale) {
|
||||||
this.$root.$i18n.locale = locale || 'en';
|
this.$i18n.locale = locale || 'en';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
setLocale(locale) {
|
setLocale(locale) {
|
||||||
this.$root.$i18n.locale = locale;
|
this.$i18n.locale = locale;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -66,6 +66,33 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
const { websiteToken, locale, widgetColor } = window.chatwootWebChannel;
|
const { websiteToken, locale, widgetColor } = window.chatwootWebChannel;
|
||||||
this.setLocale(locale);
|
this.setLocale(locale);
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE AGAIN 100');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 100);
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE AGAIN 200');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE AGAIN 300');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE AGAIN 400');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 400);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE AGAIN 500');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 500);
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('SET LOCALE YET AGAIN');
|
||||||
|
this.setLocale(locale);
|
||||||
|
}, 5000);
|
||||||
this.setWidgetColor(widgetColor);
|
this.setWidgetColor(widgetColor);
|
||||||
setHeader(window.authToken);
|
setHeader(window.authToken);
|
||||||
if (this.isIFrame) {
|
if (this.isIFrame) {
|
||||||
@@ -121,6 +148,7 @@ export default {
|
|||||||
},
|
},
|
||||||
setLocale(localeWithVariation) {
|
setLocale(localeWithVariation) {
|
||||||
if (!localeWithVariation) return;
|
if (!localeWithVariation) return;
|
||||||
|
console.log('SETTING LOCALE HAHAHAHAHA!', localeWithVariation);
|
||||||
const { enabledLanguages } = window.chatwootWebChannel;
|
const { enabledLanguages } = window.chatwootWebChannel;
|
||||||
const localeWithoutVariation = localeWithVariation.split('_')[0];
|
const localeWithoutVariation = localeWithVariation.split('_')[0];
|
||||||
const hasLocaleWithoutVariation = enabledLanguages.some(
|
const hasLocaleWithoutVariation = enabledLanguages.some(
|
||||||
@@ -131,9 +159,9 @@ export default {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (hasLocaleWithVariation) {
|
if (hasLocaleWithVariation) {
|
||||||
this.$root.$i18n.locale = localeWithVariation;
|
this.$i18n.locale = localeWithVariation;
|
||||||
} else if (hasLocaleWithoutVariation) {
|
} else if (hasLocaleWithoutVariation) {
|
||||||
this.$root.$i18n.locale = localeWithoutVariation;
|
this.$i18n.locale = localeWithoutVariation;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
registerUnreadEvents() {
|
registerUnreadEvents() {
|
||||||
|
|||||||
@@ -60,12 +60,7 @@ export default {
|
|||||||
chatwootWebChannel: { websiteToken },
|
chatwootWebChannel: { websiteToken },
|
||||||
authToken,
|
authToken,
|
||||||
} = window;
|
} = window;
|
||||||
popoutChatWindow(
|
popoutChatWindow(origin, websiteToken, this.$i18n.locale, authToken);
|
||||||
origin,
|
|
||||||
websiteToken,
|
|
||||||
this.$root.$i18n.locale,
|
|
||||||
authToken
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
closeWindow() {
|
closeWindow() {
|
||||||
if (IFrameHelper.isIFrame()) {
|
if (IFrameHelper.isIFrame()) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
locale: this.$root.$i18n.locale,
|
locale: this.$i18n.locale,
|
||||||
hasErrorInPhoneInput: false,
|
hasErrorInPhoneInput: false,
|
||||||
message: '',
|
message: '',
|
||||||
formValues: {},
|
formValues: {},
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default {
|
|||||||
messageId: this.messageId,
|
messageId: this.messageId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default {
|
|||||||
);
|
);
|
||||||
this.dyteAuthToken = authToken;
|
this.dyteAuthToken = authToken;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore Error for now
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ export default createRouter({
|
|||||||
component: () => import('./views/Messages.vue'),
|
component: () => import('./views/Messages.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/article/:link',
|
path: '/article',
|
||||||
name: 'article-viewer',
|
name: 'article-viewer',
|
||||||
props: true,
|
|
||||||
component: () => import('./views/ArticleViewer.vue'),
|
component: () => import('./views/ArticleViewer.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const actions = {
|
|||||||
const { data } = await ContactsAPI.get();
|
const { data } = await ContactsAPI.get();
|
||||||
commit(SET_CURRENT_USER, data);
|
commit(SET_CURRENT_USER, data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update: async ({ dispatch }, { user }) => {
|
update: async ({ dispatch }, { user }) => {
|
||||||
@@ -39,7 +39,7 @@ export const actions = {
|
|||||||
await ContactsAPI.update(user);
|
await ContactsAPI.update(user);
|
||||||
dispatch('get');
|
dispatch('get');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setUser: async ({ dispatch }, { identifier, user: userObject }) => {
|
setUser: async ({ dispatch }, { identifier, user: userObject }) => {
|
||||||
@@ -91,14 +91,14 @@ export const actions = {
|
|||||||
try {
|
try {
|
||||||
await ContactsAPI.setCustomAttributes(customAttributes);
|
await ContactsAPI.setCustomAttributes(customAttributes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteCustomAttribute: async (_, customAttribute) => {
|
deleteCustomAttribute: async (_, customAttribute) => {
|
||||||
try {
|
try {
|
||||||
await ContactsAPI.deleteCustomAttribute(customAttribute);
|
await ContactsAPI.deleteCustomAttribute(customAttribute);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const actions = {
|
|||||||
// Emit event to notify that conversation is created and show the chat screen
|
// Emit event to notify that conversation is created and show the chat screen
|
||||||
emitter.emit(ON_CONVERSATION_CREATED);
|
emitter.emit(ON_CONVERSATION_CREATED);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
} finally {
|
} finally {
|
||||||
commit('setConversationUIFlag', { isCreating: false });
|
commit('setConversationUIFlag', { isCreating: false });
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ export const actions = {
|
|||||||
commit('conversation/setMetaUserLastSeenAt', lastSeen, { root: true });
|
commit('conversation/setMetaUserLastSeenAt', lastSeen, { root: true });
|
||||||
commit('setMissingMessagesInConversation', updatedConversation);
|
commit('setMissingMessagesInConversation', updatedConversation);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// IgnoreError
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ export const actions = {
|
|||||||
try {
|
try {
|
||||||
await toggleTyping(data);
|
await toggleTyping(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// IgnoreError
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ export const actions = {
|
|||||||
commit('setMetaUserLastSeenAt', lastSeen);
|
commit('setMetaUserLastSeenAt', lastSeen);
|
||||||
await setUserLastSeenAt({ lastSeen });
|
await setUserLastSeenAt({ lastSeen });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// IgnoreError
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ export const actions = {
|
|||||||
try {
|
try {
|
||||||
await setCustomAttributes(customAttributes);
|
await setCustomAttributes(customAttributes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// IgnoreError
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ export const actions = {
|
|||||||
try {
|
try {
|
||||||
await deleteCustomAttribute(customAttribute);
|
await deleteCustomAttribute(customAttribute);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// IgnoreError
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const actions = {
|
|||||||
commit(SET_CONVERSATION_ATTRIBUTES, data);
|
commit(SET_CONVERSATION_ATTRIBUTES, data);
|
||||||
commit('conversation/setMetaUserLastSeenAt', lastSeen, { root: true });
|
commit('conversation/setMetaUserLastSeenAt', lastSeen, { root: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update({ commit }, data) {
|
update({ commit }, data) {
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ export const actions = {
|
|||||||
try {
|
try {
|
||||||
await conversationLabels.create(label);
|
await conversationLabels.create(label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy: async (_, label) => {
|
destroy: async (_, label) => {
|
||||||
try {
|
try {
|
||||||
await conversationLabels.destroy(label);
|
await conversationLabels.destroy(label);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const actions = {
|
|||||||
try {
|
try {
|
||||||
await events.create(name);
|
await events.create(name);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export const actions = {
|
|||||||
);
|
);
|
||||||
dispatch('contacts/get', {}, { root: true });
|
dispatch('contacts/get', {}, { root: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore error
|
console.log(error);
|
||||||
}
|
}
|
||||||
commit('toggleUpdateStatus', false);
|
commit('toggleUpdateStatus', false);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script setup>
|
<script>
|
||||||
import IframeLoader from 'shared/components/IframeLoader.vue';
|
import IframeLoader from 'shared/components/IframeLoader.vue';
|
||||||
|
|
||||||
defineProps({
|
export default {
|
||||||
link: {
|
name: 'ArticleViewer',
|
||||||
type: String,
|
components: {
|
||||||
required: true,
|
IframeLoader,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bg-white h-full">
|
<div class="bg-white h-full">
|
||||||
<IframeLoader :url="link" />
|
<IframeLoader :url="$route.query.link" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'article-viewer',
|
name: 'article-viewer',
|
||||||
params: { link: linkToOpen },
|
query: { link: linkToOpen },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
viewAllArticles() {
|
viewAllArticles() {
|
||||||
|
|||||||
@@ -39,9 +39,8 @@ RSpec.describe 'Google::CallbacksController', type: :request do
|
|||||||
expect(Redis::Alfred.get(cache_key)).to be_nil
|
expect(Redis::Alfred.get(cache_key)).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates inbox channel config if inbox exists with imap_login and authentication is successful' do
|
it 'creates updates inbox channel config if inbox exists and authentication is successful' do
|
||||||
channel_email = create(:channel_email, account: account, imap_login: email)
|
inbox = create(:channel_email, account: account, email: email)&.inbox
|
||||||
inbox = channel_email.inbox
|
|
||||||
expect(inbox.channel.provider_config).to eq({})
|
expect(inbox.channel.provider_config).to eq({})
|
||||||
|
|
||||||
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
stub_request(:post, 'https://accounts.google.com/o/oauth2/token')
|
||||||
@@ -51,7 +50,7 @@ RSpec.describe 'Google::CallbacksController', type: :request do
|
|||||||
|
|
||||||
get google_callback_url, params: { code: code }
|
get google_callback_url, params: { code: code }
|
||||||
|
|
||||||
expect(response).to redirect_to app_email_inbox_settings_url(account_id: account.id, inbox_id: inbox.id)
|
expect(response).to redirect_to app_email_inbox_settings_url(account_id: account.id, inbox_id: account.inboxes.last.id)
|
||||||
expect(account.inboxes.count).to be 1
|
expect(account.inboxes.count).to be 1
|
||||||
expect(inbox.channel.reload.provider_config.keys).to include('access_token', 'refresh_token', 'expires_on')
|
expect(inbox.channel.reload.provider_config.keys).to include('access_token', 'refresh_token', 'expires_on')
|
||||||
expect(inbox.channel.reload.provider_config['access_token']).to eq response_body_success[:access_token]
|
expect(inbox.channel.reload.provider_config['access_token']).to eq response_body_success[:access_token]
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ export default defineConfig({
|
|||||||
lib: isLibraryMode
|
lib: isLibraryMode
|
||||||
? {
|
? {
|
||||||
entry: path.resolve(__dirname, './app/javascript/entrypoints/sdk.js'),
|
entry: path.resolve(__dirname, './app/javascript/entrypoints/sdk.js'),
|
||||||
formats: ['cjs'], // CJS format for single file
|
formats: ['umd'], // UMD format for single file
|
||||||
name: 'sdk',
|
name: 'sdk',
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user