diff --git a/app/javascript/dashboard/helper/portalHelper.js b/app/javascript/dashboard/helper/portalHelper.js index 09b648330..ec681ef1b 100644 --- a/app/javascript/dashboard/helper/portalHelper.js +++ b/app/javascript/dashboard/helper/portalHelper.js @@ -1,16 +1,55 @@ -export const buildPortalURL = portalSlug => { - const { hostURL, helpCenterURL } = window.chatwootConfig; +/** + * Formats a custom domain with https protocol if needed + * @param {string} customDomain - The custom domain to format + * @returns {string} Formatted domain with https protocol + */ +const formatCustomDomain = customDomain => + customDomain.startsWith('https') ? customDomain : `https://${customDomain}`; + +/** + * Gets the default base URL from configuration + * @returns {string} The default base URL + * @throws {Error} If no valid base URL is found + */ +const getDefaultBaseURL = () => { + const { hostURL, helpCenterURL } = window.chatwootConfig || {}; const baseURL = helpCenterURL || hostURL || ''; - return `${baseURL}/hc/${portalSlug}`; + + if (!baseURL) { + throw new Error('No valid base URL found in configuration'); + } + + return `${baseURL}/hc`; +}; + +/** + * Gets the base URL from configuration or custom domain + * @param {string} [customDomain] - Optional custom domain for the portal + * @returns {string} The base URL for the portal + */ +const getPortalBaseURL = customDomain => + customDomain ? formatCustomDomain(customDomain) : getDefaultBaseURL(); + +/** + * Builds a portal URL using the provided portal slug and optional custom domain + * @param {string} portalSlug - The slug identifier for the portal + * @param {string} [customDomain] - Optional custom domain for the portal + * @returns {string} The complete portal URL + * @throws {Error} If portalSlug is not provided or invalid + */ +export const buildPortalURL = (portalSlug, customDomain) => { + const baseURL = getPortalBaseURL(customDomain); + return `${baseURL}/${portalSlug}`; }; export const buildPortalArticleURL = ( portalSlug, categorySlug, locale, - articleSlug + articleSlug, + customDomain ) => { - const portalURL = buildPortalURL(portalSlug); + const portalURL = buildPortalURL(portalSlug, customDomain); return `${portalURL}/articles/${articleSlug}`; }; diff --git a/app/javascript/dashboard/helper/specs/portalHelper.spec.js b/app/javascript/dashboard/helper/specs/portalHelper.spec.js index 9c1a47255..daa188b28 100644 --- a/app/javascript/dashboard/helper/specs/portalHelper.spec.js +++ b/app/javascript/dashboard/helper/specs/portalHelper.spec.js @@ -25,5 +25,47 @@ describe('PortalHelper', () => { ).toEqual('https://help.chatwoot.com/hc/handbook/articles/article-slug'); window.chatwootConfig = {}; }); + + it('returns the correct url with custom domain', () => { + window.chatwootConfig = { + hostURL: 'https://app.chatwoot.com', + helpCenterURL: 'https://help.chatwoot.com', + }; + expect( + buildPortalArticleURL( + 'handbook', + 'culture', + 'fr', + 'article-slug', + 'custom-domain.dev' + ) + ).toEqual('https://custom-domain.dev/handbook/articles/article-slug'); + }); + + it('handles https in custom domain correctly', () => { + window.chatwootConfig = { + hostURL: 'https://app.chatwoot.com', + helpCenterURL: 'https://help.chatwoot.com', + }; + expect( + buildPortalArticleURL( + 'handbook', + 'culture', + 'fr', + 'article-slug', + 'https://custom-domain.dev' + ) + ).toEqual('https://custom-domain.dev/handbook/articles/article-slug'); + }); + + it('uses hostURL when helpCenterURL is not available', () => { + window.chatwootConfig = { + hostURL: 'https://app.chatwoot.com', + helpCenterURL: '', + }; + expect( + buildPortalArticleURL('handbook', 'culture', 'fr', 'article-slug') + ).toEqual('https://app.chatwoot.com/hc/handbook/articles/article-slug'); + }); }); }); diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue b/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue index d0e1610e9..4b86841f6 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ConversationView.vue @@ -120,6 +120,7 @@ export default { mounted() { this.$store.dispatch('agents/get'); + this.$store.dispatch('portals/index'); this.initialize(); this.$watch('$store.state.route', () => this.initialize()); this.$watch('chatList.length', () => { diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/components/ArticleSearch/SearchPopover.vue b/app/javascript/dashboard/routes/dashboard/helpcenter/components/ArticleSearch/SearchPopover.vue index 809e58249..f54db1597 100644 --- a/app/javascript/dashboard/routes/dashboard/helpcenter/components/ArticleSearch/SearchPopover.vue +++ b/app/javascript/dashboard/routes/dashboard/helpcenter/components/ArticleSearch/SearchPopover.vue @@ -1,6 +1,7 @@