diff --git a/modules/ROOT/pages/customize-homepage-full-embed.adoc b/modules/ROOT/pages/customize-homepage-full-embed.adoc index 3d4f40ac2..e97bdff66 100644 --- a/modules/ROOT/pages/customize-homepage-full-embed.adoc +++ b/modules/ROOT/pages/customize-homepage-full-embed.adoc @@ -8,26 +8,31 @@ Developers can customize the home page experience in full application embedding to show either the classic layout or the new modular home page. -In the classic (V1) experience, the home page has a static layout and does not support SDK modular customization settings. - -In the V2 and V3 experience modes, you can customize the home page by specifying which modules are visible, their order, and the overall layout using configuration options available in the SDK. - [div announcementBlock] -- [IMPORTANT] The classic (V1) experience and V2 experience modes will be deprecated in an upcoming release in 2026. Therefore, ThoughtSpot recommends upgrading the UI experience of your full application embedding to the V3 experience. -- +== Home page layout -== Home page layout in the V3 experience +In the classic (V1) experience, the home page has a static layout and does not support SDK modular customization settings. -In the V3 experience, the SDK provides the xref:HomePage.adoc[homePage] attribute that allows you to choose the desired home page layout: +In the V3 experience, the SDK provides the xref:HomePage.adoc[homePage] attribute to set the desired home page layout: * `homePage: HomePage.ModularWithStylingChanges` + -Enables the V3 modular home page experience with customizable components, styling options, and enhanced layout and visual elements. +Enables the V3 modular home page experience with customizable components, styling options, and enhanced layout. * `homePage: HomePage.Modular` + Enables the basic modular home page experience with customizable components. +After migrating from V2 to V3 experience, the home page experience shows the following changes: + +* The **Watchlist** module is vertically arranged, includes menu actions to remove the KPI charts from the watchlist and create alerts, and allows drag-and-drop reordering of charts. +* The **Trending** module displays separate lists for Liveboards and Answers objects. Both these lists show the objects trending for the last 15 days, or based on the overall views, or both. +* The **Favorites** and **Learning** modules have enhanced visual styles and improved look and feel. + +In both V2 and V3, the SDK allows customization to include or exclude modules, change their order, and adjust the overall layout. + == Customization settings for home page The following customization settings are available for the modular home page in the V2 and V3 experience modes. diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index 40437acc7..f7cd8b912 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -8,6 +8,10 @@ This page lists new features, enhancements, and deprecated functionality in ThoughtSpot Embedded instances. +== Version 26.2.0.cl + +The ThoughtSpot Cloud 26.2.0.cl version is now available for ThoughtSpot Embedded instances. For information about the new features and enhancements introduced in this release, see link:https://developers.thoughtspot.com/docs/26.2.0.cl?pageid=whats-new[26.2.0.cl Developer Documentation]. + == Version 10.15.0.cl === Theme Builder diff --git a/src/components/AnnouncementBanner/index.scss b/src/components/AnnouncementBanner/index.scss new file mode 100644 index 000000000..bff42281f --- /dev/null +++ b/src/components/AnnouncementBanner/index.scss @@ -0,0 +1,38 @@ +.announcementBanner { + width: 100%; + border-bottom: 1px solid var(--border-color); + background: #dce5f9; + color: var(--primary-color); +} + +.announcementBanner__inner { + display: flex; + gap: 12px; + align-items: center; + justify-content: center; + padding-top: 10px; + padding-bottom: 10px; +} + +.announcementBanner__content { + font-size: 15px; + line-height: 21px; + text-align: center; + flex: 1 1 auto; + font-weight: 500; + color: #4b5563; +} + +.announcementBanner__link { + color: #1a73e8; + text-decoration: underline; + font-size: 15px; +} + +@media screen and (max-width: 767px) { + .announcementBanner__inner { + flex-direction: column; + align-items: flex-start; + } +} + diff --git a/src/components/AnnouncementBanner/index.tsx b/src/components/AnnouncementBanner/index.tsx new file mode 100644 index 000000000..e88c22e38 --- /dev/null +++ b/src/components/AnnouncementBanner/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import './index.scss'; + +type AnnouncementBannerProps = { + enabled?: boolean; + message: React.ReactNode; +}; + +const AnnouncementBanner = (props: AnnouncementBannerProps) => { + const { enabled = true, message } = props; + + if (!enabled) return null; + + return ( +
+
+
{message}
+
+
+ ); +}; + +export default AnnouncementBanner; + diff --git a/src/components/DevDocTemplate/index.tsx b/src/components/DevDocTemplate/index.tsx index ad9f331ca..03d1b953e 100644 --- a/src/components/DevDocTemplate/index.tsx +++ b/src/components/DevDocTemplate/index.tsx @@ -23,6 +23,7 @@ import { getAlgoliaIndex } from '../../configs/algolia-search-config'; import RenderPlayGround from './playGround/RESTAPI'; import GraphQLPlayGround from './playGround/GraphQL'; import { AskDocs } from './askDocs'; +import AnnouncementBanner from '../AnnouncementBanner'; import { TS_HOST_PARAM, TS_ORIGIN_PARAM, @@ -34,6 +35,7 @@ import { DEFAULT_PREVIEW_HOST, DEFAULT_APP_ROOT, HOME_PAGE_ID, + HOME_ANNOUNCEMENT_BANNER, CUSTOM_PAGE_ID, BUILD_ENVS, VERSION_DROPDOWN, @@ -491,6 +493,82 @@ const DevDocTemplate: FC = (props) => { return cName; }; + const getCloudLatestVersion = () => { + const cloudLatest = VERSION_DROPDOWN?.find( + (v) => v?.subLabel && v.subLabel.toLowerCase().includes('cloud (latest)'), + ); + return cloudLatest?.label; + }; + + const extractVersionString = (text: string | undefined | null) => { + if (!text) return undefined; + // Matches versions like 26.2.0.cl or 10.15.0.cl / 10.10.0.sw + const match = text.match(/\b\d+\.\d+\.\d+\.(?:cl|sw)\b/i); + return match?.[0]?.toLowerCase(); + }; + + const getVersionFromPath = (pathname?: string) => { + if (!pathname) return undefined; + const normalizedPath = pathname.toLowerCase(); + + const versionFromOptions = VERSION_DROPDOWN?.find((option) => { + const link = option?.link?.trim(); + if (!link || link === '') return false; + + const linkPath = link.startsWith('/') ? link : `/${link}`; + const hyphenPath = link.replace(/\./g, '-'); + const hyphenPathWithSlash = hyphenPath.startsWith('/') + ? hyphenPath + : `/${hyphenPath}`; + + return ( + normalizedPath.includes(linkPath.toLowerCase()) || + normalizedPath.includes(hyphenPathWithSlash.toLowerCase()) + ); + }); + + const optionVersion = + extractVersionString(versionFromOptions?.label) || + extractVersionString(versionFromOptions?.link); + if (optionVersion) return optionVersion; + + return extractVersionString(normalizedPath.replace(/-/g, '.')); + }; + + const getVersionFromHost = (hostname?: string) => { + if (!hostname) return undefined; + return extractVersionString(hostname.replace(/-/g, '.').toLowerCase()); + }; + + const getCurrentDocVersion = () => + getVersionFromPath(location?.pathname) || getVersionFromHost(location?.hostname); + + const shouldShowAnnouncementBanner = () => { + if (!isPublicSiteOpen) return false; + if (!HOME_ANNOUNCEMENT_BANNER?.enabled) return false; + + const cloudLatest = extractVersionString(getCloudLatestVersion()); + const bannerVersion = + extractVersionString(HOME_ANNOUNCEMENT_BANNER?.linkText) || + extractVersionString(HOME_ANNOUNCEMENT_BANNER?.message) || + extractVersionString(HOME_ANNOUNCEMENT_BANNER?.linkHref); + const currentDocVersion = getCurrentDocVersion(); + + // Only hide when we can confidently compare and they match. + if (cloudLatest && bannerVersion && cloudLatest === bannerVersion) return false; + if (currentDocVersion && bannerVersion && currentDocVersion === bannerVersion) { + return false; + } + return true; + }; + + const isExternalLink = (href?: string) => /^https?:\/\//i.test(href || ''); + const shouldOpenBannerLinkNewTab = (href?: string) => + Boolean(HOME_ANNOUNCEMENT_BANNER?.openInNewTab) || isExternalLink(href); + const bannerLinkOpensInNewTab = shouldOpenBannerLinkNewTab( + HOME_ANNOUNCEMENT_BANNER?.linkHref, + ); + return ( <> @@ -515,6 +593,38 @@ const DevDocTemplate: FC = (props) => { : { height: '0px' } } > + {shouldShowAnnouncementBanner() && ( + + {HOME_ANNOUNCEMENT_BANNER?.linkHref && + HOME_ANNOUNCEMENT_BANNER?.linkText && ( + + {HOME_ANNOUNCEMENT_BANNER.linkText} + + )} + {(HOME_ANNOUNCEMENT_BANNER?.linkHref && + HOME_ANNOUNCEMENT_BANNER?.linkText) && ' '} + {HOME_ANNOUNCEMENT_BANNER?.message || + (VERSION_DROPDOWN?.[0]?.label + ? `Version ${VERSION_DROPDOWN[0].label} is now available!` + : 'A new version is now available!')} + + } + /> + )}
} diff --git a/src/configs/doc-configs.js b/src/configs/doc-configs.js index 783645484..96855667b 100644 --- a/src/configs/doc-configs.js +++ b/src/configs/doc-configs.js @@ -13,6 +13,19 @@ module.exports = { NOT_FOUND_PAGE_ID: '404-error', HOME_PAGE_ID: 'introduction', NOT_FOUND_GO_HOME_PAGE_ID: 'introduction', + HOME_ANNOUNCEMENT_BANNER: { + enabled: true, + message: + 'is now available. Read about the new features and enhancements.', + // Swap this between: + // - Pre-GA: release-specific URL (full http(s) URL), ex: + // 'https://developers.thoughtspot.com/docs/26.2.0.cl?pageid=whats-new' + // - GA: ' /docs/whats-new' + //linkHref: '/docs/whats-new', + linkHref: '/docs/26.2.0.cl?pageid=whats-new', + linkText: 'Version 26.2.0.cl', + openInNewTab: true, + }, TYPE_DOC_PREFIX: 'typedoc', DEFAULT_HOST: 'https://try-everywhere.thoughtspot.cloud', DEFAULT_PREVIEW_HOST: 'https://try-everywhere.thoughtspot.cloud/v2', @@ -63,7 +76,12 @@ module.exports = { subLabel: 'Software', iframeUrl: 'https://visual-embed-sdk-10-1.vercel.app/docs/', }, - + { + label: '26.2.0.cl', + link: '26.2.0.cl', + subLabel: 'Coming soon', + iframeUrl: 'https://developer-docs-26-2-0-cl.vercel.app/docs/', + }, ], CUSTOM_PAGE_ID: { API_PLAYGROUND: 'restV2-playground',