diff --git a/frontend/package.json b/frontend/package.json index f0edc5c959..4a57943602 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -36,6 +36,7 @@ "@mdx-js/loader": "2.3.0", "@mdx-js/react": "2.3.0", "@monaco-editor/react": "^4.3.1", + "@signozhq/design-tokens": "0.0.6", "@uiw/react-md-editor": "3.23.5", "@xstate/react": "^3.0.0", "ansi-to-html": "0.7.2", diff --git a/frontend/public/Logos/signoz-brand-logo.svg b/frontend/public/Logos/signoz-brand-logo.svg new file mode 100644 index 0000000000..aaa8a77669 --- /dev/null +++ b/frontend/public/Logos/signoz-brand-logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/frontend/public/locales/en/titles.json b/frontend/public/locales/en/titles.json index 24b0f45269..71ec805100 100644 --- a/frontend/public/locales/en/titles.json +++ b/frontend/public/locales/en/titles.json @@ -31,6 +31,7 @@ "NOT_FOUND": "SigNoz | Page Not Found", "LOGS": "SigNoz | Logs", "LOGS_EXPLORER": "SigNoz | Logs Explorer", + "OLD_LOGS_EXPLORER": "SigNoz | Old Logs Explorer", "LIVE_LOGS": "SigNoz | Live Logs", "LOGS_PIPELINES": "SigNoz | Logs Pipelines", "HOME_PAGE": "Open source Observability Platform | SigNoz", diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts index 638c019506..aca7de9730 100644 --- a/frontend/src/AppRoutes/pageComponents.ts +++ b/frontend/src/AppRoutes/pageComponents.ts @@ -112,17 +112,25 @@ export const MySettings = Loadable( ); export const Logs = Loadable( - () => import(/* webpackChunkName: "Logs" */ 'pages/Logs'), + () => import(/* webpackChunkName: "Logs" */ 'pages/LogsModulePage'), ); export const LogsExplorer = Loadable( - () => import(/* webpackChunkName: "Logs Explorer" */ 'pages/LogsExplorer'), + () => import(/* webpackChunkName: "Logs Explorer" */ 'pages/LogsModulePage'), +); + +export const OldLogsExplorer = Loadable( + () => import(/* webpackChunkName: "Logs Explorer" */ 'pages/Logs'), ); export const LiveLogs = Loadable( () => import(/* webpackChunkName: "Live Logs" */ 'pages/LiveLogs'), ); +export const PipelinePage = Loadable( + () => import(/* webpackChunkName: "Pipelines" */ 'pages/LogsModulePage'), +); + export const Login = Loadable( () => import(/* webpackChunkName: "Login" */ 'pages/Login'), ); @@ -151,10 +159,6 @@ export const LogsIndexToFields = Loadable( import(/* webpackChunkName: "LogsIndexToFields Page" */ 'pages/LogsSettings'), ); -export const PipelinePage = Loadable( - () => import(/* webpackChunkName: "Pipelines" */ 'pages/Pipelines'), -); - export const BillingPage = Loadable( () => import(/* webpackChunkName: "BillingPage" */ 'pages/Billing'), ); diff --git a/frontend/src/AppRoutes/routes.ts b/frontend/src/AppRoutes/routes.ts index 2f4142c809..6fa3accde0 100644 --- a/frontend/src/AppRoutes/routes.ts +++ b/frontend/src/AppRoutes/routes.ts @@ -23,6 +23,7 @@ import { LogsIndexToFields, MySettings, NewDashboardPage, + OldLogsExplorer, Onboarding, OrganizationSettings, PasswordReset, @@ -246,6 +247,13 @@ const routes: AppRoutes[] = [ key: 'LOGS_EXPLORER', isPrivate: true, }, + { + path: ROUTES.OLD_LOGS_EXPLORER, + exact: true, + component: OldLogsExplorer, + key: 'OLD_LOGS_EXPLORER', + isPrivate: true, + }, { path: ROUTES.LIVE_LOGS, exact: true, diff --git a/frontend/src/components/Logs/RawLogView/styles.ts b/frontend/src/components/Logs/RawLogView/styles.ts index 4944d05f74..a3df1c3dca 100644 --- a/frontend/src/components/Logs/RawLogView/styles.ts +++ b/frontend/src/components/Logs/RawLogView/styles.ts @@ -48,8 +48,9 @@ export const RawLogContent = styled.div` line-clamp: ${linesPerRow}; -webkit-box-orient: vertical;`}; - font-size: 1rem; - line-height: 2rem; + font-size: 12px; + line-height: 24px; + padding: 4px; cursor: ${({ $isActiveLog, $isReadOnly }): string => $isActiveLog || $isReadOnly ? 'initial' : 'pointer'}; diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index 208e83e525..39456318a7 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -6,7 +6,6 @@ const ROUTES = { TRACE: '/trace', TRACE_DETAIL: '/trace/:id', TRACES_EXPLORER: '/traces-explorer', - SETTINGS: '/settings', GET_STARTED: '/get-started', USAGE_EXPLORER: '/usage-explorer', APPLICATION: '/services', @@ -23,15 +22,18 @@ const ROUTES = { ERROR_DETAIL: '/error-detail', VERSION: '/status', MY_SETTINGS: '/my-settings', + SETTINGS: '/settings', ORG_SETTINGS: '/settings/org-settings', INGESTION_SETTINGS: '/settings/ingestion-settings', SOMETHING_WENT_WRONG: '/something-went-wrong', UN_AUTHORIZED: '/un-authorized', NOT_FOUND: '/not-found', - LOGS: '/logs', - LOGS_EXPLORER: '/logs-explorer', - LIVE_LOGS: '/logs-explorer/live', - LOGS_PIPELINES: '/pipelines', + LOGS_BASE: '/logs', + LOGS: '/logs/logs-explorer', + OLD_LOGS_EXPLORER: '/logs/old-logs-explorer', + LOGS_EXPLORER: '/logs/logs-explorer', + LIVE_LOGS: '/logs/logs-explorer/live', + LOGS_PIPELINES: '/logs/pipelines', HOME_PAGE: '/', PASSWORD_RESET: '/password-reset', LIST_LICENSES: '/licenses', diff --git a/frontend/src/constants/theme.ts b/frontend/src/constants/theme.ts index 757926c0fe..427a13efe8 100644 --- a/frontend/src/constants/theme.ts +++ b/frontend/src/constants/theme.ts @@ -1,5 +1,6 @@ const themeColors = { chartcolors: { + robin: '#3F5ECC', dodgerBlue: '#2F80ED', mediumOrchid: '#BB6BD9', seaBuckthorn: '#F2994A', diff --git a/frontend/src/container/AllAlertChannels/styles.ts b/frontend/src/container/AllAlertChannels/styles.ts index 209860b867..454e48aeaf 100644 --- a/frontend/src/container/AllAlertChannels/styles.ts +++ b/frontend/src/container/AllAlertChannels/styles.ts @@ -15,6 +15,7 @@ export const ButtonContainer = styled.div` align-items: center; margin-top: 1rem; margin-bottom: 1rem; + padding-right: 1rem; } `; diff --git a/frontend/src/container/AppLayout/AppLayout.styles.scss b/frontend/src/container/AppLayout/AppLayout.styles.scss new file mode 100644 index 0000000000..b62cab0a0d --- /dev/null +++ b/frontend/src/container/AppLayout/AppLayout.styles.scss @@ -0,0 +1,53 @@ +@import '@signozhq/design-tokens'; + +.app-layout { + height: 100%; + width: 100%; + + .app-content { + width: 100%; + overflow: auto; + } +} + +.isDarkMode { + .app-layout { + .app-content { + background: #0b0c0e; + } + } +} + +.isLightMode { + .app-layout { + .app-content { + background: #ffffff; + } + } +} + +.trial-expiry-banner { + padding: 8px; + background-color: #f25733; + color: white; + text-align: center; +} + +.upgrade-link { + padding: 0px; + padding-right: 4px; + display: inline !important; + color: white; + text-decoration: underline; + text-decoration-color: white; + text-decoration-thickness: 2px; + text-underline-offset: 2px; + + &:hover { + color: white; + text-decoration: underline; + text-decoration-color: white; + text-decoration-thickness: 2px; + text-underline-offset: 2px; + } +} diff --git a/frontend/src/container/AppLayout/index.tsx b/frontend/src/container/AppLayout/index.tsx index 15f71fc692..28b48223b4 100644 --- a/frontend/src/container/AppLayout/index.tsx +++ b/frontend/src/container/AppLayout/index.tsx @@ -1,13 +1,22 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable jsx-a11y/anchor-is-valid */ +import './AppLayout.styles.scss'; + +import { Flex } from 'antd'; import getDynamicConfigs from 'api/dynamicConfigs/getDynamicConfigs'; import getUserLatestVersion from 'api/user/getLatestVersion'; import getUserVersion from 'api/user/getVersion'; +import cx from 'classnames'; import ROUTES from 'constants/routes'; -import Header from 'container/Header'; import SideNav from 'container/SideNav'; import TopNav from 'container/TopNav'; +import { useIsDarkMode } from 'hooks/useDarkMode'; +import useLicense from 'hooks/useLicense'; import { useNotifications } from 'hooks/useNotifications'; +import history from 'lib/history'; import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback'; -import { ReactNode, useEffect, useMemo, useRef } from 'react'; +import { ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { Helmet } from 'react-helmet-async'; import { useTranslation } from 'react-i18next'; @@ -25,15 +34,20 @@ import { UPDATE_LATEST_VERSION_ERROR, } from 'types/actions/app'; import AppReducer from 'types/reducer/app'; +import { getFormattedDate, getRemainingDays } from 'utils/timeUtils'; import { ChildrenContainer, Layout, LayoutContent } from './styles'; import { getRouteKey } from './utils'; function AppLayout(props: AppLayoutProps): JSX.Element { - const { isLoggedIn, user } = useSelector( + const { isLoggedIn, user, role } = useSelector( (state) => state.app, ); + const isDarkMode = useIsDarkMode(); + + const { data: licenseData, isFetching } = useLicense(); + const { pathname } = useLocation(); const { t } = useTranslation(['titles']); @@ -196,25 +210,68 @@ function AppLayout(props: AppLayoutProps): JSX.Element { const renderFullScreen = pathname === ROUTES.GET_STARTED || pathname === ROUTES.WORKSPACE_LOCKED; + const [showTrialExpiryBanner, setShowTrialExpiryBanner] = useState(false); + + useEffect(() => { + if ( + !isFetching && + licenseData?.payload?.onTrial && + !licenseData?.payload?.trialConvertedToSubscription && + !licenseData?.payload?.workSpaceBlock && + getRemainingDays(licenseData?.payload.trialEnd) < 7 + ) { + setShowTrialExpiryBanner(true); + } + }, [licenseData, isFetching]); + + const handleUpgrade = (): void => { + if (role === 'ADMIN') { + history.push(ROUTES.BILLING); + } + }; + return ( - + {pageTitle} - {isToDisplayLayout &&
} - - {isToDisplayLayout && !renderFullScreen && } + {showTrialExpiryBanner && ( +
+ You are in free trial period. Your free trial will end on{' '} + + {getFormattedDate(licenseData?.payload?.trialEnd || Date.now())}. + + {role === 'ADMIN' ? ( + + {' '} + Please{' '} + + upgrade + + to continue using SigNoz features. + + ) : ( + 'Please contact your administrator for upgrading to a paid plan.' + )} +
+ )} - - - - {isToDisplayLayout && !renderFullScreen && } - {children} - - - -
+ + {isToDisplayLayout && !renderFullScreen && ( + + )} +
+ + + + {isToDisplayLayout && !renderFullScreen && } + {children} + + + +
+
); } diff --git a/frontend/src/container/AppLayout/styles.ts b/frontend/src/container/AppLayout/styles.ts index 8bed914d66..f266087895 100644 --- a/frontend/src/container/AppLayout/styles.ts +++ b/frontend/src/container/AppLayout/styles.ts @@ -13,6 +13,7 @@ export const Layout = styled(LayoutComponent)` export const LayoutContent = styled(LayoutComponent.Content)` overflow-y: auto; + height: 100%; `; export const ChildrenContainer = styled.div` diff --git a/frontend/src/container/FullViewHeader/FullViewHeader.styles.scss b/frontend/src/container/FullViewHeader/FullViewHeader.styles.scss new file mode 100644 index 0000000000..b894ea4f12 --- /dev/null +++ b/frontend/src/container/FullViewHeader/FullViewHeader.styles.scss @@ -0,0 +1,37 @@ +.full-view-header-container { + display: flex; + justify-content: center; + align-items: center; + padding: 24px 0; + + .brand-logo { + display: flex; + justify-content: center; + align-items: center; + gap: 16px; + cursor: pointer; + + img { + height: 32px; + width: 32px; + } + + .brand-logo-name { + font-family: 'Work Sans', sans-serif; + font-size: 24px; + font-style: normal; + font-weight: 500; + line-height: 18px; + + color: #fff; + } + } +} + +.lightMode { + .brand-logo { + .brand-logo-name { + color: black; + } + } +} diff --git a/frontend/src/container/FullViewHeader/FullViewHeader.tsx b/frontend/src/container/FullViewHeader/FullViewHeader.tsx new file mode 100644 index 0000000000..8fa19b8ee4 --- /dev/null +++ b/frontend/src/container/FullViewHeader/FullViewHeader.tsx @@ -0,0 +1,28 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import './FullViewHeader.styles.scss'; + +import history from 'lib/history'; + +export default function FullViewHeader({ + overrideRoute, +}: { + overrideRoute?: string; +}): React.ReactElement { + const handleLogoClick = (): void => { + history.push(overrideRoute || '/'); + }; + return ( +
+
+ SigNoz + +
SigNoz
+
+
+ ); +} + +FullViewHeader.defaultProps = { + overrideRoute: '/', +}; diff --git a/frontend/src/container/ListOfDashboard/DashboardsList.tsx b/frontend/src/container/ListOfDashboard/DashboardsList.tsx index 8bb56490e8..9b416c65f4 100644 --- a/frontend/src/container/ListOfDashboard/DashboardsList.tsx +++ b/frontend/src/container/ListOfDashboard/DashboardsList.tsx @@ -332,7 +332,7 @@ function DashboardsList(): JSX.Element { ); return ( - + {GetHeader} diff --git a/frontend/src/container/ListOfDashboard/TableComponents/styles.ts b/frontend/src/container/ListOfDashboard/TableComponents/styles.ts index 78c382700b..477da90004 100644 --- a/frontend/src/container/ListOfDashboard/TableComponents/styles.ts +++ b/frontend/src/container/ListOfDashboard/TableComponents/styles.ts @@ -1,8 +1,7 @@ -import { blue } from '@ant-design/colors'; import { Typography } from 'antd'; import styled from 'styled-components'; export const TableLinkText = styled(Typography.Text)` - color: ${blue.primary} !important; + color: #4e74f8 !important; cursor: pointer; `; diff --git a/frontend/src/container/LiveLogsTopNav/styles.ts b/frontend/src/container/LiveLogsTopNav/styles.ts index f6c58b9415..1fb150e1e0 100644 --- a/frontend/src/container/LiveLogsTopNav/styles.ts +++ b/frontend/src/container/LiveLogsTopNav/styles.ts @@ -1,19 +1,18 @@ import { Button, ButtonProps } from 'antd'; -import { themeColors } from 'constants/theme'; import styled, { css, FlattenSimpleInterpolation } from 'styled-components'; export const LiveButtonStyled = styled(Button)` - background-color: rgba(${themeColors.buttonSuccessRgb}, 0.9); + background-color: #1eb475; ${({ danger }): FlattenSimpleInterpolation => !danger ? css` &:hover { - background-color: rgba(${themeColors.buttonSuccessRgb}, 1) !important; + background-color: #1eb475 !important; } &:active { - background-color: rgba(${themeColors.buttonSuccessRgb}, 0.7) !important; + background-color: #1eb475 !important; } ` : css``} diff --git a/frontend/src/container/LocalTopNav/index.tsx b/frontend/src/container/LocalTopNav/index.tsx index 3de2f823ef..ff864e94c7 100644 --- a/frontend/src/container/LocalTopNav/index.tsx +++ b/frontend/src/container/LocalTopNav/index.tsx @@ -1,7 +1,9 @@ -import { Col, Row, Space } from 'antd'; +import { Col, Row, Space, Typography } from 'antd'; +import ROUTES from 'constants/routes'; import NewExplorerCTA from 'container/NewExplorerCTA'; +import { FileText } from 'lucide-react'; +import { useLocation } from 'react-use'; -import ShowBreadcrumbs from '../TopNav/Breadcrumbs'; import DateTimeSelector from '../TopNav/DateTimeSelection'; import { Container } from './styles'; import { LocalTopNavProps } from './types'; @@ -10,13 +12,25 @@ function LocalTopNav({ actions, renderPermissions, }: LocalTopNavProps): JSX.Element | null { + const { pathname } = useLocation(); + + const isLiveLogsPage = pathname === ROUTES.LIVE_LOGS; + return ( - - - + {isLiveLogsPage && ( + + + - + + Live Logs + + + + )} + + diff --git a/frontend/src/container/LocalTopNav/styles.ts b/frontend/src/container/LocalTopNav/styles.ts index feda027d24..9c936b664b 100644 --- a/frontend/src/container/LocalTopNav/styles.ts +++ b/frontend/src/container/LocalTopNav/styles.ts @@ -3,7 +3,7 @@ import styled from 'styled-components'; export const Container = styled(Row)` &&& { - margin-top: 2rem; + margin-top: 1rem; min-height: 8vh; } `; diff --git a/frontend/src/container/LogDetailedView/index.tsx b/frontend/src/container/LogDetailedView/index.tsx index fe5b2cd3af..588cc7e240 100644 --- a/frontend/src/container/LogDetailedView/index.tsx +++ b/frontend/src/container/LogDetailedView/index.tsx @@ -63,7 +63,7 @@ function LogDetailedView({ queryString, ); - history.replace(`${ROUTES.LOGS}?q=${updatedQueryString}`); + history.replace(`${ROUTES.OLD_LOGS_EXPLORER}?q=${updatedQueryString}`); }, [history, queryString], ); diff --git a/frontend/src/container/LogsTopNav/index.tsx b/frontend/src/container/LogsTopNav/index.tsx index 6bb8f93530..40ce480e30 100644 --- a/frontend/src/container/LogsTopNav/index.tsx +++ b/frontend/src/container/LogsTopNav/index.tsx @@ -74,6 +74,7 @@ function LogsTopNav(): JSX.Element { icon={} onClick={handleGoLive} type="primary" + size="small" > Go Live diff --git a/frontend/src/container/LogsTopNav/styles.ts b/frontend/src/container/LogsTopNav/styles.ts index f6c58b9415..1fb150e1e0 100644 --- a/frontend/src/container/LogsTopNav/styles.ts +++ b/frontend/src/container/LogsTopNav/styles.ts @@ -1,19 +1,18 @@ import { Button, ButtonProps } from 'antd'; -import { themeColors } from 'constants/theme'; import styled, { css, FlattenSimpleInterpolation } from 'styled-components'; export const LiveButtonStyled = styled(Button)` - background-color: rgba(${themeColors.buttonSuccessRgb}, 0.9); + background-color: #1eb475; ${({ danger }): FlattenSimpleInterpolation => !danger ? css` &:hover { - background-color: rgba(${themeColors.buttonSuccessRgb}, 1) !important; + background-color: #1eb475 !important; } &:active { - background-color: rgba(${themeColors.buttonSuccessRgb}, 0.7) !important; + background-color: #1eb475 !important; } ` : css``} diff --git a/frontend/src/container/MySettings/MySettings.styles.scss b/frontend/src/container/MySettings/MySettings.styles.scss new file mode 100644 index 0000000000..c936bcb20a --- /dev/null +++ b/frontend/src/container/MySettings/MySettings.styles.scss @@ -0,0 +1,5 @@ +.flexBtn { + display: flex; + align-items: center; + gap: 8px; +} diff --git a/frontend/src/container/MySettings/Password/index.tsx b/frontend/src/container/MySettings/Password/index.tsx index 493f5662b7..0bc9513c4e 100644 --- a/frontend/src/container/MySettings/Password/index.tsx +++ b/frontend/src/container/MySettings/Password/index.tsx @@ -1,6 +1,7 @@ -import { Button, Space, Typography } from 'antd'; +import { Button, Card, Space, Typography } from 'antd'; import changeMyPassword from 'api/user/changeMyPassword'; import { useNotifications } from 'hooks/useNotifications'; +import { Save } from 'lucide-react'; import { isPasswordNotValidMessage, isPasswordValid } from 'pages/SignUp/utils'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -20,9 +21,7 @@ function PasswordContainer(): JSX.Element { false, ); - const defaultPlaceHolder = t('input_password', { - ns: 'settings', - }); + const defaultPlaceHolder = '*************'; const { notifications } = useNotifications(); @@ -89,66 +88,69 @@ function PasswordContainer(): JSX.Element { currentPassword === updatePassword; return ( - - - {t('change_password', { - ns: 'settings', - })} - - - - {t('current_password', { + + + + {t('change_password', { ns: 'settings', })} - - { - setCurrentPassword(event.target.value); - }} - value={currentPassword} - /> - - - - {t('new_password', { - ns: 'settings', - })} - - { - const updatedValue = event.target.value; - setUpdatePassword(updatedValue); - }} - value={updatePassword} - /> - - - {isPasswordPolicyError && ( - + + + {t('current_password', { + ns: 'settings', + })} + + { + setCurrentPassword(event.target.value); }} - > - {isPasswordNotValidMessage} - - )} + value={currentPassword} + /> + + + + {t('new_password', { + ns: 'settings', + })} + + { + const updatedValue = event.target.value; + setUpdatePassword(updatedValue); + }} + value={updatePassword} + /> + + + {isPasswordPolicyError && ( + + {isPasswordNotValidMessage} + + )} + + - - + ); } diff --git a/frontend/src/container/MySettings/UserInfo/UserInfo.styles.scss b/frontend/src/container/MySettings/UserInfo/UserInfo.styles.scss new file mode 100644 index 0000000000..d1cfae649c --- /dev/null +++ b/frontend/src/container/MySettings/UserInfo/UserInfo.styles.scss @@ -0,0 +1,7 @@ +.userInfo-label { + min-width: 150px; +} + +.userInfo-value { + min-width: 20rem; +} diff --git a/frontend/src/container/MySettings/UpdateName/index.tsx b/frontend/src/container/MySettings/UserInfo/index.tsx similarity index 58% rename from frontend/src/container/MySettings/UpdateName/index.tsx rename to frontend/src/container/MySettings/UserInfo/index.tsx index 6da15a237a..23187a9bf4 100644 --- a/frontend/src/container/MySettings/UpdateName/index.tsx +++ b/frontend/src/container/MySettings/UserInfo/index.tsx @@ -1,6 +1,10 @@ -import { Button, Space, Typography } from 'antd'; +import '../MySettings.styles.scss'; +import './UserInfo.styles.scss'; + +import { Button, Card, Flex, Input, Space, Typography } from 'antd'; import editUser from 'api/user/editUser'; import { useNotifications } from 'hooks/useNotifications'; +import { PencilIcon, UserSquare } from 'lucide-react'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; @@ -12,7 +16,7 @@ import AppReducer from 'types/reducer/app'; import { NameInput } from '../styles'; -function UpdateName(): JSX.Element { +function UserInfo(): JSX.Element { const { user, role, org, userFlags } = useSelector( (state) => state.app, ); @@ -72,28 +76,51 @@ function UpdateName(): JSX.Element { }; return ( -
+ - Name - { - setChangedName(event.target.value); - }} - value={changedName} - disabled={loading} - /> - + + {' '} + + User Details + + + + + + Name + { + setChangedName(event.target.value); + }} + value={changedName} + disabled={loading} + /> + + + + + + + Email + + + + + Role + + -
+
); } -export default UpdateName; +export default UserInfo; diff --git a/frontend/src/container/MySettings/index.tsx b/frontend/src/container/MySettings/index.tsx index f0938e6440..e3945c4d12 100644 --- a/frontend/src/container/MySettings/index.tsx +++ b/frontend/src/container/MySettings/index.tsx @@ -1,16 +1,28 @@ -import { Space, Typography } from 'antd'; -import { useTranslation } from 'react-i18next'; +import './MySettings.styles.scss'; + +import { Button, Space } from 'antd'; +import { Logout } from 'api/utils'; +import { LogOut } from 'lucide-react'; import Password from './Password'; -import UpdateName from './UpdateName'; +import UserInfo from './UserInfo'; function MySettings(): JSX.Element { - const { t } = useTranslation(['routes']); return ( - - {t('my_settings')} - + + + + + ); } diff --git a/frontend/src/container/NewExplorerCTA/config.ts b/frontend/src/container/NewExplorerCTA/config.ts index b2feeff572..886f044e57 100644 --- a/frontend/src/container/NewExplorerCTA/config.ts +++ b/frontend/src/container/NewExplorerCTA/config.ts @@ -7,5 +7,5 @@ export const RIBBON_STYLES = { export const buttonText = { [ROUTES.LOGS_EXPLORER]: 'Switch to Old Logs Explorer', [ROUTES.TRACE]: 'Try new Traces Explorer', - [ROUTES.LOGS]: 'Switch to New Logs Explorer', + [ROUTES.OLD_LOGS_EXPLORER]: 'Switch to New Logs Explorer', }; diff --git a/frontend/src/container/NewExplorerCTA/index.tsx b/frontend/src/container/NewExplorerCTA/index.tsx index 6b1a5b577c..5b6d4532e2 100644 --- a/frontend/src/container/NewExplorerCTA/index.tsx +++ b/frontend/src/container/NewExplorerCTA/index.tsx @@ -14,16 +14,16 @@ function NewExplorerCTA(): JSX.Element | null { () => location.pathname === ROUTES.LOGS_EXPLORER || location.pathname === ROUTES.TRACE || - location.pathname === ROUTES.LOGS, + location.pathname === ROUTES.OLD_LOGS_EXPLORER, [location.pathname], ); const onClickHandler = useCallback((): void => { if (location.pathname === ROUTES.LOGS_EXPLORER) { - history.push(ROUTES.LOGS); + history.push(ROUTES.OLD_LOGS_EXPLORER); } else if (location.pathname === ROUTES.TRACE) { history.push(ROUTES.TRACES_EXPLORER); - } else if (location.pathname === ROUTES.LOGS) { + } else if (location.pathname === ROUTES.OLD_LOGS_EXPLORER) { history.push(ROUTES.LOGS_EXPLORER); } }, [location.pathname]); @@ -36,6 +36,7 @@ function NewExplorerCTA(): JSX.Element | null { danger data-testid="newExplorerCTA" type="primary" + size="small" > {buttonText[location.pathname]} diff --git a/frontend/src/container/OnboardingContainer/Onboarding.styles.scss b/frontend/src/container/OnboardingContainer/Onboarding.styles.scss index b5498f5074..4e00b629c8 100644 --- a/frontend/src/container/OnboardingContainer/Onboarding.styles.scss +++ b/frontend/src/container/OnboardingContainer/Onboarding.styles.scss @@ -32,12 +32,12 @@ .onboardingHeader { text-align: center; margin-top: 48px; - margin-bottom: 24px; } .onboardingHeader h1 { font-size: 24px; font-weight: 500; + margin: 0; } .modulesContainer { diff --git a/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx b/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx index 82aa14cadc..4354349304 100644 --- a/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx +++ b/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx @@ -6,6 +6,7 @@ import { ArrowRightOutlined } from '@ant-design/icons'; import { Button, Card, Typography } from 'antd'; import getIngestionData from 'api/settings/getIngestionData'; import cx from 'classnames'; +import FullViewHeader from 'container/FullViewHeader/FullViewHeader'; import useAnalytics from 'hooks/analytics/useAnalytics'; import { useIsDarkMode } from 'hooks/useDarkMode'; import { useEffect, useState } from 'react'; @@ -218,11 +219,10 @@ export default function Onboarding(): JSX.Element {
{activeStep === 1 && ( <> +
-

Get Started with SigNoz

-
Select a use-case to get started
+

Select a use-case to get started

-
{Object.keys(ModulesMap).map((module) => { @@ -261,7 +261,6 @@ export default function Onboarding(): JSX.Element { })}
-
+
+ )} + +
+ {menuItems.map((item, index) => ( + { + if (item) { + onClickHandler(item?.key as string); + } + }} + /> + ))} +
+ +
+ {licenseData && !isLicenseActive && ( + + )} + + {userManagementMenuItems.map( + (item, index): JSX.Element => ( + { + handleUserManagentMenuItemClick(item?.key as string); + }} + /> + ), + )} + + {inviteMembers && ( + { + history.push(`${inviteMemberMenuItem.key}`); + }} + /> + )} + + {user && ( + { + handleUserManagentMenuItemClick(userSettingsMenuItem?.key as string); + }} + /> + )} + +
+ {collapsed ? ( + + ) : ( + + )} +
+
+
); } diff --git a/frontend/src/container/SideNav/config.ts b/frontend/src/container/SideNav/config.ts index 2fbfa1e244..95028b0a05 100644 --- a/frontend/src/container/SideNav/config.ts +++ b/frontend/src/container/SideNav/config.ts @@ -31,6 +31,7 @@ export const routeConfig: Record = { [ROUTES.LIST_LICENSES]: [QueryParams.resourceAttributes], [ROUTES.LOGIN]: [QueryParams.resourceAttributes], [ROUTES.LOGS]: [QueryParams.resourceAttributes], + [ROUTES.LOGS_BASE]: [QueryParams.resourceAttributes], [ROUTES.MY_SETTINGS]: [QueryParams.resourceAttributes], [ROUTES.NOT_FOUND]: [QueryParams.resourceAttributes], [ROUTES.ORG_SETTINGS]: [QueryParams.resourceAttributes], diff --git a/frontend/src/container/SideNav/menuItems.tsx b/frontend/src/container/SideNav/menuItems.tsx index ae0acdd8c6..00ac98d259 100644 --- a/frontend/src/container/SideNav/menuItems.tsx +++ b/frontend/src/container/SideNav/menuItems.tsx @@ -1,88 +1,111 @@ -import { - AlertOutlined, - AlignLeftOutlined, - BarChartOutlined, - BugOutlined, - DashboardFilled, - DeploymentUnitOutlined, - FileDoneOutlined, - LineChartOutlined, - MenuOutlined, - RocketOutlined, - SearchOutlined, - SettingOutlined, -} from '@ant-design/icons'; +import { RocketOutlined } from '@ant-design/icons'; import ROUTES from 'constants/routes'; +import { + AreaChart, + BarChart2, + BellDot, + BugIcon, + Cloudy, + DraftingCompass, + FileKey2, + LayoutGrid, + MessageSquare, + Receipt, + Route, + ScrollText, + Settings, + Slack, + UserPlus, +} from 'lucide-react'; -import { SidebarMenu } from './sideNav.types'; +import { SecondaryMenuItemKey, SidebarItem } from './sideNav.types'; -const menuItems: SidebarMenu[] = [ - { - key: ROUTES.GET_STARTED, - label: 'Get Started', - icon: , - }, +export const getStartedMenuItem = { + key: ROUTES.GET_STARTED, + label: 'Get Started', + icon: , +}; + +export const inviteMemberMenuItem = { + key: `${ROUTES.ORG_SETTINGS}#invite-team-members`, + label: 'Invite Team Member', + icon: , +}; + +export const manageLicenseMenuItem = { + key: ROUTES.LIST_LICENSES, + label: 'Manage Licenses', + icon: , +}; + +export const helpSupportMenuItem = { + key: ROUTES.SUPPORT, + label: 'Help & Support', + icon: , +}; + +export const slackSupportMenuItem = { + key: SecondaryMenuItemKey.Slack, + label: 'Slack Support', + icon: , +}; + +export const trySignozCloudMenuItem: SidebarItem = { + key: 'trySignozCloud', + label: 'Try Signoz Cloud', + icon: , +}; + +const menuItems: SidebarItem[] = [ { key: ROUTES.APPLICATION, label: 'Services', - icon: , + icon: , }, { key: ROUTES.TRACE, label: 'Traces', - icon: , + icon: , }, { - key: ROUTES.LOGS_EXPLORER, + key: ROUTES.LOGS, label: 'Logs', - icon: , - children: [ - { - key: ROUTES.LOGS_EXPLORER, - icon: , - label: 'Logs Explorer', - }, - { - key: ROUTES.LOGS_PIPELINES, - icon: , - label: 'Logs Pipelines', - }, - ], + icon: , }, { key: ROUTES.ALL_DASHBOARD, label: 'Dashboards', - icon: , + icon: , }, { key: ROUTES.LIST_ALL_ALERT, label: 'Alerts', - icon: , + icon: , }, { key: ROUTES.ALL_ERROR, label: 'Exceptions', - icon: , + icon: , }, { key: ROUTES.SERVICE_MAP, label: 'Service Map', - icon: , + icon: , }, { key: ROUTES.USAGE_EXPLORER, label: 'Usage Explorer', - icon: , + icon: , }, { key: ROUTES.BILLING, label: 'Billing', - icon: , + icon: , }, { key: ROUTES.SETTINGS, label: 'Settings', - icon: , + icon: , }, ]; @@ -90,7 +113,7 @@ const menuItems: SidebarMenu[] = [ export const NEW_ROUTES_MENU_ITEM_KEY_MAP = { [ROUTES.TRACES_EXPLORER]: ROUTES.TRACE, [ROUTES.TRACE_EXPLORER]: ROUTES.TRACE, - [ROUTES.LOGS_EXPLORER]: ROUTES.LOGS_EXPLORER, + [ROUTES.LOGS_BASE]: ROUTES.LOGS_EXPLORER, }; export default menuItems; diff --git a/frontend/src/container/SideNav/sideNav.types.ts b/frontend/src/container/SideNav/sideNav.types.ts index 804cad8d18..8bc7860478 100644 --- a/frontend/src/container/SideNav/sideNav.types.ts +++ b/frontend/src/container/SideNav/sideNav.types.ts @@ -8,10 +8,9 @@ export type SidebarMenu = MenuItem & { }; export interface SidebarItem { - onClick: VoidFunction; icon?: ReactNode; text?: ReactNode; - key: string; + key: string | number; label?: ReactNode; } diff --git a/frontend/src/container/TopNav/Breadcrumbs/index.tsx b/frontend/src/container/TopNav/Breadcrumbs/index.tsx index f7b8bf5f21..d5e4941142 100644 --- a/frontend/src/container/TopNav/Breadcrumbs/index.tsx +++ b/frontend/src/container/TopNav/Breadcrumbs/index.tsx @@ -22,6 +22,7 @@ const breadcrumbNameMap = { [ROUTES.ALL_DASHBOARD]: 'Dashboard', [ROUTES.LOGS]: 'Logs', [ROUTES.LOGS_EXPLORER]: 'Logs Explorer', + [ROUTES.OLD_LOGS_EXPLORER]: 'Old Logs Explorer', [ROUTES.LIVE_LOGS]: 'Live View', [ROUTES.LOGS_PIPELINES]: 'Logs Pipelines', [ROUTES.BILLING]: 'Billing', diff --git a/frontend/src/container/TopNav/DateTimeSelection/config.ts b/frontend/src/container/TopNav/DateTimeSelection/config.ts index b99f6f6ae2..0ece952909 100644 --- a/frontend/src/container/TopNav/DateTimeSelection/config.ts +++ b/frontend/src/container/TopNav/DateTimeSelection/config.ts @@ -90,6 +90,9 @@ export const routesToSkip = [ ROUTES.BILLING, ROUTES.SUPPORT, ROUTES.WORKSPACE_LOCKED, + ROUTES.LOGS, + ROUTES.MY_SETTINGS, + ROUTES.LIST_LICENSES, ]; export const routesToDisable = [ROUTES.LOGS_EXPLORER, ROUTES.LIVE_LOGS]; diff --git a/frontend/src/container/TopNav/index.tsx b/frontend/src/container/TopNav/index.tsx index 6592faa569..3b2667eaf6 100644 --- a/frontend/src/container/TopNav/index.tsx +++ b/frontend/src/container/TopNav/index.tsx @@ -4,14 +4,8 @@ import { useMemo } from 'react'; import { matchPath, useHistory } from 'react-router-dom'; import NewExplorerCTA from '../NewExplorerCTA'; -import ShowBreadcrumbs from './Breadcrumbs'; import DateTimeSelector from './DateTimeSelection'; -import { - routesToDisable, - routesToHideBreadCrumbs, - routesToSkip, -} from './DateTimeSelection/config'; -import { Container } from './styles'; +import { routesToDisable, routesToSkip } from './DateTimeSelection/config'; function TopNav(): JSX.Element | null { const { location } = useHistory(); @@ -24,14 +18,6 @@ function TopNav(): JSX.Element | null { [location.pathname], ); - const isRouteToHideBreadCrumbs = useMemo( - () => - routesToHideBreadCrumbs.some((route) => - matchPath(location.pathname, { path: route, exact: true }), - ), - [location.pathname], - ); - const isDisabled = useMemo( () => routesToDisable.some((route) => @@ -50,15 +36,9 @@ function TopNav(): JSX.Element | null { } return ( - - {!isRouteToHideBreadCrumbs && ( - - - - )} - + {!isRouteToSkip && ( - + @@ -69,7 +49,7 @@ function TopNav(): JSX.Element | null { )} - + ); } diff --git a/frontend/src/container/TopNav/styles.ts b/frontend/src/container/TopNav/styles.ts index ef3cb15c37..4c88c63246 100644 --- a/frontend/src/container/TopNav/styles.ts +++ b/frontend/src/container/TopNav/styles.ts @@ -3,6 +3,6 @@ import styled from 'styled-components'; export const Container = styled(Row)` &&& { - margin-top: 2rem; + margin-top: 1rem; } `; diff --git a/frontend/src/hooks/logs/useActiveLog.ts b/frontend/src/hooks/logs/useActiveLog.ts index 8dbd58976b..a56c13c72e 100644 --- a/frontend/src/hooks/logs/useActiveLog.ts +++ b/frontend/src/hooks/logs/useActiveLog.ts @@ -36,7 +36,9 @@ export const useActiveLog = (): UseActiveLog => { const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder(); const { notifications } = useNotifications(); - const isLogsPage = useMemo(() => pathname === ROUTES.LOGS, [pathname]); + const isLogsPage = useMemo(() => pathname === ROUTES.OLD_LOGS_EXPLORER, [ + pathname, + ]); const [activeLog, setActiveLog] = useState(null); @@ -135,7 +137,7 @@ export const useActiveLog = (): UseActiveLog => { queryString, ); - history.replace(`${ROUTES.LOGS}?q=${updatedQueryString}`); + history.replace(`${ROUTES.OLD_LOGS_EXPLORER}?q=${updatedQueryString}`); }, [history, queryString], ); diff --git a/frontend/src/hooks/useDarkMode/index.tsx b/frontend/src/hooks/useDarkMode/index.tsx index 069e08b2de..baf0c21511 100644 --- a/frontend/src/hooks/useDarkMode/index.tsx +++ b/frontend/src/hooks/useDarkMode/index.tsx @@ -76,6 +76,11 @@ export const useThemeConfig = (): ThemeConfig => { borderRadiusXS: 2, fontFamily: 'Inter', fontSize: 13, + colorPrimary: '#4E74F8', + colorBgBase: isDarkMode ? '#0B0C0E' : '#fff', + colorBgContainer: isDarkMode ? '#121317' : '#fff', + colorLink: '#4E74F8', + colorPrimaryText: '#3F5ECC', }, }; }; diff --git a/frontend/src/index.html.ejs b/frontend/src/index.html.ejs index f46fd07f01..8d756463cd 100644 --- a/frontend/src/index.html.ejs +++ b/frontend/src/index.html.ejs @@ -67,7 +67,7 @@ diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 17320546af..405a9c6bc4 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -8,7 +8,6 @@ import { createRoot } from 'react-dom/client'; import { ErrorBoundary } from 'react-error-boundary'; import { HelmetProvider } from 'react-helmet-async'; import { QueryClient, QueryClientProvider } from 'react-query'; -import { ReactQueryDevtools } from 'react-query/devtools'; import { Provider } from 'react-redux'; import store from 'store'; @@ -33,7 +32,6 @@ if (container) { - {process.env.NODE_ENV === 'development' && } diff --git a/frontend/src/pages/Logs/index.tsx b/frontend/src/pages/Logs/index.tsx index d690f40f9c..cbbcc22c4c 100644 --- a/frontend/src/pages/Logs/index.tsx +++ b/frontend/src/pages/Logs/index.tsx @@ -30,7 +30,7 @@ import { useSelectedLogView } from './hooks'; import PopoverContent from './PopoverContent'; import SpaceContainer from './styles'; -function Logs(): JSX.Element { +function OldLogsExplorer(): JSX.Element { const dispatch = useDispatch>(); const { order } = useSelector((store) => store.logs); const location = useLocation(); @@ -148,4 +148,4 @@ function Logs(): JSX.Element { ); } -export default Logs; +export default OldLogsExplorer; diff --git a/frontend/src/pages/LogsModulePage/LogsModulePage.tsx b/frontend/src/pages/LogsModulePage/LogsModulePage.tsx new file mode 100644 index 0000000000..ecd8d2dcfc --- /dev/null +++ b/frontend/src/pages/LogsModulePage/LogsModulePage.tsx @@ -0,0 +1,28 @@ +import RouteTab from 'components/RouteTab'; +import ROUTES from 'constants/routes'; +import history from 'lib/history'; +import LogsExplorer from 'pages/LogsExplorer'; +import Pipelines from 'pages/Pipelines'; +import { useLocation } from 'react-use'; + +export const logsExplorer = { + Component: LogsExplorer, + name: 'Explorer', + route: ROUTES.LOGS, + key: ROUTES.LOGS, +}; + +export const logsPipelines = { + Component: Pipelines, + name: 'Pipelines', + route: ROUTES.LOGS_PIPELINES, + key: ROUTES.LOGS_PIPELINES, +}; + +export default function LogsModulePage(): JSX.Element { + const { pathname } = useLocation(); + + const routes = [logsExplorer, logsPipelines]; + + return ; +} diff --git a/frontend/src/pages/LogsModulePage/index.tsx b/frontend/src/pages/LogsModulePage/index.tsx new file mode 100644 index 0000000000..680368481f --- /dev/null +++ b/frontend/src/pages/LogsModulePage/index.tsx @@ -0,0 +1,3 @@ +import LogsModulePage from './LogsModulePage'; + +export default LogsModulePage; diff --git a/frontend/src/pages/Pipelines/index.tsx b/frontend/src/pages/Pipelines/index.tsx index 1a05a4010a..d646390dda 100644 --- a/frontend/src/pages/Pipelines/index.tsx +++ b/frontend/src/pages/Pipelines/index.tsx @@ -81,7 +81,7 @@ function Pipelines(): JSX.Element { return ( - ; + ); } diff --git a/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.styles.scss b/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.styles.scss index f80a4925bc..7e5b32ab29 100644 --- a/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.styles.scss +++ b/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.styles.scss @@ -1,7 +1,7 @@ .workspace-locked-container { text-align: center; padding: 48px; - margin: 48px; + margin: 24px; } .workpace-locked-details { diff --git a/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.tsx b/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.tsx index 924509de82..1a19e3d6a5 100644 --- a/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.tsx +++ b/frontend/src/pages/WorkspaceLocked/WorkspaceLocked.tsx @@ -6,6 +6,7 @@ import { Button, Card, Skeleton, Typography } from 'antd'; import updateCreditCardApi from 'api/billing/checkout'; import { SOMETHING_WENT_WRONG } from 'constants/api'; import ROUTES from 'constants/routes'; +import FullViewHeader from 'container/FullViewHeader/FullViewHeader'; import useLicense from 'hooks/useLicense'; import { useNotifications } from 'hooks/useNotifications'; import history from 'lib/history'; @@ -75,42 +76,46 @@ export default function WorkspaceBlocked(): JSX.Element { }, [activeLicense?.key, updateCreditCard]); return ( - - {isLoadingLicenseData || !licensesData?.payload?.workSpaceBlock ? ( - - ) : ( - <> - - Workspace Locked - - You have been locked out of your workspace because your trial ended - without an upgrade to a paid plan. Your data will continue to be ingested - till{' '} - {getFormattedDate(licensesData?.payload?.gracePeriodEnd || Date.now())} , - at which point we will drop all the ingested data and terminate the - account. - {!isAdmin && 'Please contact your administrator for further help'} - - {isAdmin && ( - - )} -
- Got Questions? - - Contact Us - -
- - )} -
+ <> + + + + {isLoadingLicenseData || !licensesData?.payload?.workSpaceBlock ? ( + + ) : ( + <> + + Workspace Locked + + You have been locked out of your workspace because your trial ended + without an upgrade to a paid plan. Your data will continue to be ingested + till{' '} + {getFormattedDate(licensesData?.payload?.gracePeriodEnd || Date.now())} , + at which point we will drop all the ingested data and terminate the + account. + {!isAdmin && 'Please contact your administrator for further help'} + + {isAdmin && ( + + )} +
+ Got Questions? + + Contact Us + +
+ + )} +
+ ); } diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 6712b4c59a..f2b1a3d413 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -1,3 +1,5 @@ +@import '@signozhq/design-tokens'; + #root, html, body { diff --git a/frontend/src/utils/permission/index.ts b/frontend/src/utils/permission/index.ts index ee1a7a09e9..91372d237b 100644 --- a/frontend/src/utils/permission/index.ts +++ b/frontend/src/utils/permission/index.ts @@ -86,4 +86,6 @@ export const routePermission: Record = { BILLING: ['ADMIN', 'EDITOR', 'VIEWER'], SUPPORT: ['ADMIN', 'EDITOR', 'VIEWER'], SOMETHING_WENT_WRONG: ['ADMIN', 'EDITOR', 'VIEWER'], + LOGS_BASE: [], + OLD_LOGS_EXPLORER: [], }; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 2099c438bb..fe33785fb5 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3082,6 +3082,13 @@ resolved "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@signozhq/design-tokens@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@signozhq/design-tokens/-/design-tokens-0.0.6.tgz#42449052dca644c4d52448f9c2c521d39e535720" + integrity sha512-i+aG0YCuYL2KVUtRFj3qgAVDU6GbKmTdFXpqCqLUQp8diKMWH5Svzzxj4B14Q6+yE79+wbm1iZ0Nr6nYgkBA8Q== + dependencies: + style-dictionary "3.8.0" + "@sinclair/typebox@^0.25.16": version "0.25.24" resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz" @@ -5422,6 +5429,15 @@ canvas-color-tracker@1: dependencies: tinycolor2 "^1.6.0" +capital-case@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" + integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + cardboard-vr-display@^1.0.19: version "1.0.19" resolved "https://registry.npmjs.org/cardboard-vr-display/-/cardboard-vr-display-1.0.19.tgz" @@ -5461,6 +5477,24 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" + integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== + dependencies: + camel-case "^4.1.2" + capital-case "^1.0.4" + constant-case "^3.0.4" + dot-case "^3.0.4" + header-case "^2.0.4" + no-case "^3.0.4" + param-case "^3.0.4" + pascal-case "^3.1.2" + path-case "^3.0.4" + sentence-case "^3.0.4" + snake-case "^3.0.4" + tslib "^2.0.3" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" @@ -5842,6 +5876,15 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +constant-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-3.0.4.tgz#3b84a9aeaf4cf31ec45e6bf5de91bdfb0589faf1" + integrity sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case "^2.0.2" + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" @@ -7993,7 +8036,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -8329,6 +8372,14 @@ he@^1.2.0: resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-2.0.4.tgz#5a42e63b55177349cf405beb8d775acabb92c063" + integrity sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q== + dependencies: + capital-case "^1.0.4" + tslib "^2.0.3" + headers-polyfill@3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-3.2.5.tgz#6e67d392c9d113d37448fe45014e0afdd168faed" @@ -9871,6 +9922,11 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +jsonc-parser@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" @@ -11789,6 +11845,14 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" +path-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-3.0.4.tgz#9168645334eb942658375c56f80b4c0cb5f82c6f" + integrity sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" @@ -13841,6 +13905,15 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +sentence-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" + integrity sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + serialize-javascript@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz" @@ -14017,6 +14090,14 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" @@ -14397,6 +14478,21 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-dictionary@3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/style-dictionary/-/style-dictionary-3.8.0.tgz#7cb8d64360c53431f768d44def665f61e971a73e" + integrity sha512-wHlB/f5eO3mDcYv6WtOz6gvQC477jBKrwuIXe+PtHskTCBsJdAOvL8hCquczJxDui2TnwpeNE+2msK91JJomZg== + dependencies: + chalk "^4.0.0" + change-case "^4.1.2" + commander "^8.3.0" + fs-extra "^10.0.0" + glob "^7.2.0" + json5 "^2.2.2" + jsonc-parser "^3.0.0" + lodash "^4.17.15" + tinycolor2 "^1.4.1" + style-loader@1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz" @@ -14698,7 +14794,7 @@ tiny-warning@^1.0.0: resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -tinycolor2@1, tinycolor2@1.6.0, tinycolor2@^1.6.0: +tinycolor2@1, tinycolor2@1.6.0, tinycolor2@^1.4.1, tinycolor2@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== @@ -15156,6 +15252,20 @@ uplot@1.6.26: resolved "https://registry.yarnpkg.com/uplot/-/uplot-1.6.26.tgz#a6012fd141ad4a71741c75af0c71283d0ade45a7" integrity sha512-qN0mveL6UsP40TnHzHAJkUQvpfA3y8zSLXtXKVlJo/sLfj2+vjan/Z3g81MCZjy/hEDUFNtnLftPmETDA4s7Rg== +upper-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" + integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== + dependencies: + tslib "^2.0.3" + +upper-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-2.0.2.tgz#d89810823faab1df1549b7d97a76f8662bae6f7a" + integrity sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg== + dependencies: + tslib "^2.0.3" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"