diff --git a/package-lock.json b/package-lock.json index 11a9c4e70..ed6c61b06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-0", + "version": "1.13.0-pre-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-0", + "version": "1.13.0-pre-1", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 897a8a4e9..e81850c89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-0", + "version": "1.13.0-pre-1", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", diff --git a/src/Assets/IconV2/ic-disconnect.svg b/src/Assets/IconV2/ic-disconnect.svg new file mode 100644 index 000000000..1ad7ac9c1 --- /dev/null +++ b/src/Assets/IconV2/ic-disconnect.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-gift.svg b/src/Assets/IconV2/ic-gift.svg new file mode 100644 index 000000000..5aea477d9 --- /dev/null +++ b/src/Assets/IconV2/ic-gift.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-gitlab.svg b/src/Assets/IconV2/ic-gitlab.svg index ae6ed4f8c..1b4df0aaa 100644 --- a/src/Assets/IconV2/ic-gitlab.svg +++ b/src/Assets/IconV2/ic-gitlab.svg @@ -16,16 +16,16 @@ - + - - - - - - - - + + + + + + + + diff --git a/src/Assets/IconV2/ic-megaphone-left.svg b/src/Assets/IconV2/ic-megaphone-left.svg new file mode 100644 index 000000000..48001f96b --- /dev/null +++ b/src/Assets/IconV2/ic-megaphone-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Assets/IconV2/ic-sparkle-color.svg b/src/Assets/IconV2/ic-sparkle-color.svg new file mode 100644 index 000000000..a2aa5c5d3 --- /dev/null +++ b/src/Assets/IconV2/ic-sparkle-color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Shared/Components/AnnouncementBanner/AnnouncementBanner.tsx b/src/Shared/Components/AnnouncementBanner/AnnouncementBanner.tsx deleted file mode 100644 index 131c4670e..000000000 --- a/src/Shared/Components/AnnouncementBanner/AnnouncementBanner.tsx +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useState } from 'react' -import DOMPurify from 'dompurify' - -import { ReactComponent as Close } from '../../../Assets/Icon/ic-close.svg' -import { ReactComponent as MegaphoneIcon } from '../../../Assets/Icon/ic-megaphone.svg' -import { InfoColourBar } from '../../../Common' -import { getDateInMilliseconds, setActionWithExpiry } from '../Header/utils' - -interface AnnouncementBannerType { - parentClassName?: string - isCDMaterial?: boolean -} - -const AnnouncementBanner = ({ parentClassName = '', isCDMaterial = false }: AnnouncementBannerType) => { - const rawMessage = window?._env_?.ANNOUNCEMENT_BANNER_MSG - const message = rawMessage ? DOMPurify.sanitize(rawMessage) : null - const showAnnouncementBanner = (): boolean => { - const expiryDateOfHidingAnnouncementBanner: string = - typeof Storage !== 'undefined' && - localStorage.getItem( - // it will store date and time of next day i.e, it will hide banner until this date - 'expiryDateOfHidingAnnouncementBanner', - ) - const showAnnouncementBannerNextDay: boolean = - typeof Storage !== 'undefined' && - getDateInMilliseconds(localStorage.getItem('dashboardLoginTime')) > - getDateInMilliseconds(expiryDateOfHidingAnnouncementBanner) - - if (showAnnouncementBannerNextDay && !expiryDateOfHidingAnnouncementBanner) { - return true - } - - return getDateInMilliseconds(new Date().valueOf()) > getDateInMilliseconds(expiryDateOfHidingAnnouncementBanner) - } - - const [showAnouncementBanner, setshowAnouncementBanner] = useState(message ? showAnnouncementBanner() : false) - - if (!message) { - return null - } - - const onClickCloseAnnouncememtBanner = () => { - setshowAnouncementBanner(false) - if (typeof Storage !== 'undefined') { - setActionWithExpiry('expiryDateOfHidingAnnouncementBanner', 1) - } - } - - const renderAnnouncementBanner = () => ( -
-
- {isCDMaterial ? null : ( - - )} -
- ) - - return showAnouncementBanner || isCDMaterial ? ( -
- -
- ) : null -} - -export default AnnouncementBanner diff --git a/src/Shared/Components/AnnouncementBanner/index.ts b/src/Shared/Components/AnnouncementBanner/index.ts deleted file mode 100644 index 2da2ff104..000000000 --- a/src/Shared/Components/AnnouncementBanner/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2024. Devtron Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// eslint-disable-next-line import/prefer-default-export -export { default as AnnouncementBanner } from './AnnouncementBanner' diff --git a/src/Shared/Components/Button/button.scss b/src/Shared/Components/Button/button.scss index fd05f8390..bfe89e7f1 100644 --- a/src/Shared/Components/Button/button.scss +++ b/src/Shared/Components/Button/button.scss @@ -79,7 +79,7 @@ @if ($color) { color: $color; - + @include svg-styles($color); } } @@ -216,6 +216,14 @@ &--neutral { @include button-variant-styles($background, var(--N700), $border-color); } + + &--neutral-n0 { + @include button-variant-styles($background, var(--N0), $border-color); + } + + &--neutral-white { + @include button-variant-styles($background, var(--white), $border-color); + } } // Pseudo states for border-less button @@ -243,6 +251,14 @@ &--neutral { @include pseudo-states(var(--N100), var(--N200)); } + + &--neutral-n0 { + @include pseudo-states(var(--N000), var(--N100)); + } + + &--neutral-white { + @include pseudo-states(var(--white), var(--N100)); + } } // Overrides for text button @@ -253,7 +269,9 @@ &--negative-grey, &--positive, &--warning, - &--neutral { + &--neutral, + &--neutral-n0, + &--neutral-white { padding: 0 !important; min-width: 0 !important; border: none; @@ -279,4 +297,4 @@ text-decoration: none; } } -} +} \ No newline at end of file diff --git a/src/Shared/Components/Button/types.ts b/src/Shared/Components/Button/types.ts index 4c6128377..5ed004be5 100644 --- a/src/Shared/Components/Button/types.ts +++ b/src/Shared/Components/Button/types.ts @@ -35,6 +35,8 @@ export enum ButtonStyleType { positive = 'positive', warning = 'warning', neutral = 'neutral', + neutralN0 = 'neutral-n0', + neutralWhite = 'neutral-white', } export enum ButtonComponentType { diff --git a/src/Shared/Components/Header/PageHeader.tsx b/src/Shared/Components/Header/PageHeader.tsx index b31e9034f..6ad4ca278 100644 --- a/src/Shared/Components/Header/PageHeader.tsx +++ b/src/Shared/Components/Header/PageHeader.tsx @@ -26,7 +26,6 @@ import { ReactComponent as ICMediumPaintBucket } from '@IconsV2/ic-medium-paintb import { getAlphabetIcon, TippyCustomized, TippyTheme } from '../../../Common' import { MAX_LOGIN_COUNT, POSTHOG_EVENT_ONBOARDING } from '../../../Common/Constants' import { useMainContext, useTheme, useUserEmail } from '../../Providers' -import AnnouncementBanner from '../AnnouncementBanner/AnnouncementBanner' import GettingStartedCard from '../GettingStartedCard/GettingStarted' import { InfoIconTippy } from '../InfoIconTippy' import LogoutCard from '../LogoutCard' @@ -49,7 +48,6 @@ const PageHeader = ({ showCloseButton = false, onClose, markAsBeta, - showAnnouncementHeader, tippyProps, }: PageHeaderType) => { const { @@ -313,7 +311,6 @@ const PageHeader = ({ {renderLogoutHelpSection()}
)} - {showAnnouncementHeader && } ) } diff --git a/src/Shared/Components/Header/types.ts b/src/Shared/Components/Header/types.ts index dc352b95a..51a12814e 100644 --- a/src/Shared/Components/Header/types.ts +++ b/src/Shared/Components/Header/types.ts @@ -35,7 +35,6 @@ export interface PageHeaderType { showCloseButton?: boolean onClose?: () => void markAsBeta?: boolean - showAnnouncementHeader?: boolean tippyProps?: Pick & { isTippyCustomized?: boolean tippyRedirectLink?: string diff --git a/src/Shared/Components/Icon/Icon.tsx b/src/Shared/Components/Icon/Icon.tsx index f979f59d8..0ed7ebaeb 100644 --- a/src/Shared/Components/Icon/Icon.tsx +++ b/src/Shared/Components/Icon/Icon.tsx @@ -48,6 +48,7 @@ import { ReactComponent as ICDeleteLightning } from '@IconsV2/ic-delete-lightnin import { ReactComponent as ICDelhivery } from '@IconsV2/ic-delhivery.svg' import { ReactComponent as ICDevtron } from '@IconsV2/ic-devtron.svg' import { ReactComponent as ICDevtronHeaderLogo } from '@IconsV2/ic-devtron-header-logo.svg' +import { ReactComponent as ICDisconnect } from '@IconsV2/ic-disconnect.svg' import { ReactComponent as ICDockerhub } from '@IconsV2/ic-dockerhub.svg' import { ReactComponent as ICEcr } from '@IconsV2/ic-ecr.svg' import { ReactComponent as ICEnv } from '@IconsV2/ic-env.svg' @@ -57,6 +58,7 @@ import { ReactComponent as ICFailure } from '@IconsV2/ic-failure.svg' import { ReactComponent as ICFileKey } from '@IconsV2/ic-file-key.svg' import { ReactComponent as ICFolderUser } from '@IconsV2/ic-folder-user.svg' import { ReactComponent as ICGear } from '@IconsV2/ic-gear.svg' +import { ReactComponent as ICGift } from '@IconsV2/ic-gift.svg' import { ReactComponent as ICGiftGradient } from '@IconsV2/ic-gift-gradient.svg' import { ReactComponent as ICGit } from '@IconsV2/ic-git.svg' import { ReactComponent as ICGithub } from '@IconsV2/ic-github.svg' @@ -92,6 +94,7 @@ import { ReactComponent as ICLoginDevtronLogo } from '@IconsV2/ic-login-devtron- import { ReactComponent as ICLogout } from '@IconsV2/ic-logout.svg' import { ReactComponent as ICMediumDelete } from '@IconsV2/ic-medium-delete.svg' import { ReactComponent as ICMediumPaintbucket } from '@IconsV2/ic-medium-paintbucket.svg' +import { ReactComponent as ICMegaphoneLeft } from '@IconsV2/ic-megaphone-left.svg' import { ReactComponent as ICMemory } from '@IconsV2/ic-memory.svg' import { ReactComponent as ICMicrosoft } from '@IconsV2/ic-microsoft.svg' import { ReactComponent as ICMinikube } from '@IconsV2/ic-minikube.svg' @@ -116,6 +119,7 @@ import { ReactComponent as ICSlidersVertical } from '@IconsV2/ic-sliders-vertica import { ReactComponent as ICSortAscending } from '@IconsV2/ic-sort-ascending.svg' import { ReactComponent as ICSortDescending } from '@IconsV2/ic-sort-descending.svg' import { ReactComponent as ICSortable } from '@IconsV2/ic-sortable.svg' +import { ReactComponent as ICSparkleColor } from '@IconsV2/ic-sparkle-color.svg' import { ReactComponent as ICSpinny } from '@IconsV2/ic-spinny.svg' import { ReactComponent as ICStack } from '@IconsV2/ic-stack.svg' import { ReactComponent as ICStamp } from '@IconsV2/ic-stamp.svg' @@ -189,6 +193,7 @@ export const iconMap = { 'ic-delhivery': ICDelhivery, 'ic-devtron-header-logo': ICDevtronHeaderLogo, 'ic-devtron': ICDevtron, + 'ic-disconnect': ICDisconnect, 'ic-dockerhub': ICDockerhub, 'ic-ecr': ICEcr, 'ic-env': ICEnv, @@ -199,6 +204,7 @@ export const iconMap = { 'ic-folder-user': ICFolderUser, 'ic-gear': ICGear, 'ic-gift-gradient': ICGiftGradient, + 'ic-gift': ICGift, 'ic-git': ICGit, 'ic-github': ICGithub, 'ic-gitlab': ICGitlab, @@ -233,6 +239,7 @@ export const iconMap = { 'ic-logout': ICLogout, 'ic-medium-delete': ICMediumDelete, 'ic-medium-paintbucket': ICMediumPaintbucket, + 'ic-megaphone-left': ICMegaphoneLeft, 'ic-memory': ICMemory, 'ic-microsoft': ICMicrosoft, 'ic-minikube': ICMinikube, @@ -257,6 +264,7 @@ export const iconMap = { 'ic-sort-ascending': ICSortAscending, 'ic-sort-descending': ICSortDescending, 'ic-sortable': ICSortable, + 'ic-sparkle-color': ICSparkleColor, 'ic-spinny': ICSpinny, 'ic-stack': ICStack, 'ic-stamp': ICStamp, diff --git a/src/Shared/Components/InfoBlock/InfoBlock.component.tsx b/src/Shared/Components/InfoBlock/InfoBlock.component.tsx index e87831c04..0f5309242 100644 --- a/src/Shared/Components/InfoBlock/InfoBlock.component.tsx +++ b/src/Shared/Components/InfoBlock/InfoBlock.component.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ComponentSizeType } from '@Shared/constants' +import { ComponentSizeType, VARIANT_TO_BG_MAP, VARIANT_TO_BORDER_MAP } from '@Shared/constants' import { deriveBorderRadiusAndBorderClassFromConfig } from '@Shared/Helpers' import { Button } from '../Button' @@ -22,7 +22,6 @@ import { CONTAINER_SIZE_TO_BUTTON_SIZE, CONTAINER_SIZE_TO_CLASS_MAP, SIZE_TO_ICON_CLASS_MAP, - VARIANT_TO_BG_MAP, VARIANT_TO_ICON_MAP, } from './constants' import { InfoBlockProps } from './types' @@ -38,7 +37,7 @@ const InfoBlock = ({ borderRadiusConfig, borderConfig, }: InfoBlockProps) => { - const baseContainerClass = `${CONTAINER_SIZE_TO_CLASS_MAP[size]} ${VARIANT_TO_BG_MAP[variant]} ${deriveBorderRadiusAndBorderClassFromConfig({ borderConfig, borderRadiusConfig })} w-100 py-8 br-4 bw-1` + const baseContainerClass = `${CONTAINER_SIZE_TO_CLASS_MAP[size]} ${VARIANT_TO_BG_MAP[variant]} ${VARIANT_TO_BORDER_MAP[variant]} ${deriveBorderRadiusAndBorderClassFromConfig({ borderConfig, borderRadiusConfig })} w-100 py-8 br-4 bw-1` const iconClass = `dc__no-shrink flex dc__fill-available-space ${SIZE_TO_ICON_CLASS_MAP[size]}` const icon = customIcon ?? VARIANT_TO_ICON_MAP[variant] diff --git a/src/Shared/Components/InfoBlock/constants.tsx b/src/Shared/Components/InfoBlock/constants.tsx index 7d6867861..037ad7b23 100644 --- a/src/Shared/Components/InfoBlock/constants.tsx +++ b/src/Shared/Components/InfoBlock/constants.tsx @@ -14,28 +14,19 @@ * limitations under the License. */ -import { ComponentSizeType } from '@Shared/constants' +import { ComponentSizeType, InfoBlockVariant } from '@Shared/constants' import { ButtonProps } from '../Button' import { Icon } from '../Icon' import { InfoBlockProps } from './types' -export const VARIANT_TO_BG_MAP: Record = { - error: 'bcr-1 er-2', - help: 'bcv-1 ev-2', - information: 'bcb-1 eb-2', - success: 'bcg-1 eg-2', - warning: 'bcy-1 ey-2', - neutral: 'bcn-1 en-2', -} - -export const VARIANT_TO_ICON_MAP: Record = { - error: , - help: , - information: , - success: , - warning: , - neutral: , +export const VARIANT_TO_ICON_MAP: Record = { + [InfoBlockVariant.ERROR]: , + [InfoBlockVariant.HELP]: , + [InfoBlockVariant.INFORMATION]: , + [InfoBlockVariant.SUCCESS]: , + [InfoBlockVariant.WARNING]: , + [InfoBlockVariant.NEUTRAL]: , } export const CONTAINER_SIZE_TO_CLASS_MAP: Record = { diff --git a/src/Shared/Components/InfoBlock/types.ts b/src/Shared/Components/InfoBlock/types.ts index 776488e81..53009853f 100644 --- a/src/Shared/Components/InfoBlock/types.ts +++ b/src/Shared/Components/InfoBlock/types.ts @@ -16,7 +16,7 @@ import { ReactElement, ReactNode } from 'react' -import { ComponentSizeType } from '@Shared/constants' +import { ComponentSizeType, InfoBlockVariantType } from '@Shared/constants' import { BorderConfigType, ComponentLayoutType } from '@Shared/types' import { ButtonComponentType, ButtonProps } from '../Button' @@ -29,7 +29,7 @@ export type InfoBlockProps = { /** * @default 'information' */ - variant?: 'error' | 'help' | 'information' | 'success' | 'warning' | 'neutral' + variant?: InfoBlockVariantType /** * @default ComponentSizeType.large */ diff --git a/src/Shared/Components/index.ts b/src/Shared/Components/index.ts index abcb23727..897056ef4 100644 --- a/src/Shared/Components/index.ts +++ b/src/Shared/Components/index.ts @@ -19,7 +19,6 @@ export * from './ActionMenu' export * from './ActivityIndicator' export * from './AnimatedDeployButton' export * from './AnimatedTimer' -export * from './AnnouncementBanner' export * from './APIResponseHandler' export * from './ArtifactInfoModal' export * from './Backdrop' diff --git a/src/Shared/Providers/index.ts b/src/Shared/Providers/index.ts index 3e07be345..1ba004223 100644 --- a/src/Shared/Providers/index.ts +++ b/src/Shared/Providers/index.ts @@ -17,5 +17,5 @@ export * from './ImageSelectionUtility' export * from './MainContextProvider' export * from './ThemeProvider' -export type { MainContext } from './types' +export type { MainContext, ReloadVersionConfigTypes } from './types' export * from './UserEmailProvider' diff --git a/src/Shared/Providers/types.ts b/src/Shared/Providers/types.ts index d3d456ad2..82f1630cb 100644 --- a/src/Shared/Providers/types.ts +++ b/src/Shared/Providers/types.ts @@ -18,8 +18,17 @@ import { Dispatch, MutableRefObject, ReactNode, SetStateAction } from 'react' import { SERVER_MODE } from '../../Common' import { ServerInfo } from '../Components/Header/types' -import { DevtronLicenseInfo, IntelligenceConfig, LicenseInfoDialogType } from '..' +import { DevtronLicenseInfo, IntelligenceConfig, LicenseInfoDialogType, ToastManager } from '..' +export interface ReloadVersionConfigTypes { + bgUpdated: boolean + handleAppUpdate: () => void + doesNeedRefresh: boolean + updateServiceWorker: () => Promise + handleControllerChange: () => void + updateToastRef: MutableRefObject> | null + isRefreshing: boolean +} export interface MainContext { serverMode: SERVER_MODE setServerMode: (serverMode: SERVER_MODE) => void @@ -66,6 +75,7 @@ export interface MainContext { licenseData: DevtronLicenseInfo setLicenseData: Dispatch> canFetchHelmAppStatus: boolean + reloadVersionConfig: ReloadVersionConfigTypes intelligenceConfig: IntelligenceConfig setIntelligenceConfig: Dispatch> } diff --git a/src/Shared/constants.tsx b/src/Shared/constants.tsx index a3f91e257..b7dec2721 100644 --- a/src/Shared/constants.tsx +++ b/src/Shared/constants.tsx @@ -16,7 +16,8 @@ import { DeploymentNodeType, OptionType } from '@Common/Types' -import { CDMaterialSidebarType, ConfigKeysWithLockType, ConfigurationType } from './types' +import { InfoBlockProps } from './Components' +import { CDMaterialSidebarType, ConfigKeysWithLockType, ConfigurationType, IconBaseColorType } from './types' export const ARTIFACT_STATUS = { PROGRESSING: 'Progressing', @@ -556,6 +557,43 @@ export const ENTERPRISE_SUPPORT_LINK = 'enterprise@devtron.ai' export const INVALID_LICENSE_KEY = 'inValid' +export enum InfoBlockVariant { + ERROR = 'error', + HELP = 'help', + INFORMATION = 'information', + SUCCESS = 'success', + WARNING = 'warning', + NEUTRAL = 'neutral', +} + +export type InfoBlockVariantType = 'error' | 'help' | 'information' | 'success' | 'warning' | 'neutral' + +export const VARIANT_TO_BG_MAP: Record = { + [InfoBlockVariant.ERROR]: 'bcr-1', + [InfoBlockVariant.HELP]: 'bcv-1', + [InfoBlockVariant.INFORMATION]: 'bcb-1', + [InfoBlockVariant.SUCCESS]: 'bcg-1', + [InfoBlockVariant.WARNING]: 'bcy-1', + [InfoBlockVariant.NEUTRAL]: 'bcn-1', +} + +export const VARIANT_TO_ICON_COLOR_MAP: Record = { + [InfoBlockVariant.ERROR]: 'R500', + [InfoBlockVariant.HELP]: 'V500', + [InfoBlockVariant.INFORMATION]: 'B500', + [InfoBlockVariant.SUCCESS]: 'G500', + [InfoBlockVariant.WARNING]: 'Y700', + [InfoBlockVariant.NEUTRAL]: 'N500', +} + +export const VARIANT_TO_BORDER_MAP: Record = { + [InfoBlockVariant.ERROR]: 'er-2', + [InfoBlockVariant.HELP]: 'ev-2', + [InfoBlockVariant.INFORMATION]: 'eb-2', + [InfoBlockVariant.SUCCESS]: 'eg-2', + [InfoBlockVariant.WARNING]: 'ey-2', + [InfoBlockVariant.NEUTRAL]: 'en-2', +} export const DEPLOYMENT_STAGE_TO_NODE_MAP: Readonly> = { [DeploymentStageType.DEPLOY]: DeploymentNodeType.CD, [DeploymentStageType.POST]: DeploymentNodeType.POSTCD, diff --git a/src/index.ts b/src/index.ts index 4d5f80fe0..2a0afb927 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,6 +57,9 @@ export interface customEnv { ENABLE_SCOPED_VARIABLES?: boolean DEFAULT_CI_TRIGGER_TYPE_MANUAL: boolean ANNOUNCEMENT_BANNER_MSG?: string + ANNOUNCEMENT_BANNER_TYPE?: string + ANNOUNCEMENT_BANNER_BUTTON_TEXT?: string + ANNOUNCEMENT_BANNER_BUTTON_LINK?: string HIDE_DEFAULT_CLUSTER?: boolean GLOBAL_API_TIMEOUT?: number TRIGGER_API_TIMEOUT?: number