From 48e6f4d53f5ae57ab20182f91852a83cff1447cc Mon Sep 17 00:00:00 2001 From: Himanshu Verma <2019kucp1120@iiitkota.ac.in> Date: Fri, 27 Oct 2023 15:05:01 +0530 Subject: [PATCH] ISPN-15105 Console black theme --- src/app/AppLayout/AppLayout.tsx | 14 ++++++- .../Configuration/CacheConfiguration.tsx | 10 ++--- .../Configuration/DetailConfigurations.tsx | 8 ++-- src/app/Caches/Entries/CacheEntries.tsx | 8 ++-- src/app/Caches/Query/QueryEntries.tsx | 9 ++-- src/app/Common/Health.tsx | 15 +++++-- src/app/Common/Status.tsx | 2 +- .../ProtoSchema/ProtobufSchemasDisplay.tsx | 7 ++-- src/app/Welcome/Welcome.tsx | 1 - src/app/index.tsx | 13 +++--- src/app/providers/ThemeProvider.tsx | 41 +++++++++++++++++++ src/app/utils/themeUtils.ts | 12 ++++++ 12 files changed, 111 insertions(+), 29 deletions(-) create mode 100644 src/app/providers/ThemeProvider.tsx create mode 100644 src/app/utils/themeUtils.ts diff --git a/src/app/AppLayout/AppLayout.tsx b/src/app/AppLayout/AppLayout.tsx index fe71a9413..c7fb4f8da 100644 --- a/src/app/AppLayout/AppLayout.tsx +++ b/src/app/AppLayout/AppLayout.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useContext } from 'react'; import { Brand, @@ -25,7 +25,8 @@ import { ToolbarGroup, ToolbarItem, Tooltip, - PageSidebarBody + PageSidebarBody, + Switch } from '@patternfly/react-core'; import { Dropdown, @@ -50,6 +51,7 @@ import { useConnectedUser } from '@app/services/userManagementHook'; import { KeycloakService } from '@services/keycloakService'; import { BarsIcon, ExternalLinkAltIcon, InfoCircleIcon, QuestionCircleIcon } from '@patternfly/react-icons'; import { ConsoleACL } from '@services/securityService'; +import { ThemeContext } from '@app/providers/ThemeProvider'; interface IAppLayout { init: string; @@ -59,6 +61,7 @@ interface IAppLayout { const AppLayout: React.FunctionComponent = ({ init, children }) => { const { t } = useTranslation(); const brandname = t('brandname.brandname'); + const {theme,toggleTheme} = useContext(ThemeContext); const history = useHistory(); const { connectedUser } = useConnectedUser(); @@ -161,6 +164,13 @@ const AppLayout: React.FunctionComponent = ({ init, children }) => { align={{ default: 'alignRight' }} spacer={{ default: 'spacerNone', md: 'spacerMd' }} > + { const { t } = useTranslation(); const encodingDocs = t('brandname.encoding-docs-link'); - + const {syntaxHighLighterTheme} = useContext(ThemeContext) const yamlConfig = useFetchConfigurationYAML(props.cacheName); const xmlConfig = useFetchConfigurationXML(props.cacheName); @@ -68,7 +68,7 @@ const CacheConfiguration = (props: { cacheName: string; editable: boolean; confi {config} - + {config} @@ -78,7 +78,7 @@ const CacheConfiguration = (props: { cacheName: string; editable: boolean; confi return ( - + JSON} tabContentId="tab1" tabContentRef={contentRef1} /> XML} tabContentId="tab2" tabContentRef={contentRef2} /> YAML} tabContentId="tab3" tabContentRef={contentRef3} /> diff --git a/src/app/Caches/Configuration/DetailConfigurations.tsx b/src/app/Caches/Configuration/DetailConfigurations.tsx index 40124bb6b..dab8bc268 100644 --- a/src/app/Caches/Configuration/DetailConfigurations.tsx +++ b/src/app/Caches/Configuration/DetailConfigurations.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useContext } from 'react'; import { Button, Bullseye, @@ -28,13 +28,13 @@ import { Thead, Tr, Th, Tbody, Td, ExpandableRowContent } from '@patternfly/reac import { Table } from '@patternfly/react-table/deprecated'; import { DataContainerBreadcrumb } from '@app/Common/DataContainerBreadcrumb'; import SyntaxHighlighter from 'react-syntax-highlighter'; -import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import { useTranslation } from 'react-i18next'; import { SearchIcon, CubeIcon } from '@patternfly/react-icons'; import { useFetchCacheTemplates } from '@app/services/cachesHook'; import { TableErrorState } from '@app/Common/TableErrorState'; import { onSearch } from '@app/utils/searchFilter'; import { global_spacer_sm, global_spacer_md } from '@patternfly/react-tokens'; +import { ThemeContext } from '@app/providers/ThemeProvider'; const DetailConfigurations: React.FunctionComponent = (props) => { const { t } = useTranslation(); @@ -49,6 +49,8 @@ const DetailConfigurations: React.FunctionComponent = (props) => { perPage: 10 }); + const {syntaxHighLighterTheme} = useContext(ThemeContext) + useEffect(() => { setFilteredTemplates(cacheTemplates); }, [cacheTemplates]); @@ -223,7 +225,7 @@ const DetailConfigurations: React.FunctionComponent = (props) => { diff --git a/src/app/Caches/Entries/CacheEntries.tsx b/src/app/Caches/Entries/CacheEntries.tsx index 6019e5a0d..4bd8cb438 100644 --- a/src/app/Caches/Entries/CacheEntries.tsx +++ b/src/app/Caches/Entries/CacheEntries.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useContext } from 'react'; import { Bullseye, Button, @@ -28,7 +28,6 @@ import { ActionsColumn, IAction, Table, Tbody, Td, Th, Thead, Tr } from '@patter import { FilterIcon, HelpIcon, PlusCircleIcon, SearchIcon } from '@patternfly/react-icons'; import { global_spacer_md, global_spacer_sm } from '@patternfly/react-tokens'; import SyntaxHighlighter from 'react-syntax-highlighter'; -import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import displayUtils from '@services/displayUtils'; import { useTranslation } from 'react-i18next'; import { useCacheDetail, useCacheEntries } from '@app/services/cachesHook'; @@ -40,6 +39,7 @@ import { ContentType, EncodingType } from '@services/infinispanRefData'; import { CreateOrUpdateEntryForm } from '@app/Caches/Entries/CreateOrUpdateEntryForm'; import { ClearAllEntries } from '@app/Caches/Entries/ClearAllEntries'; import { DeleteEntry } from '@app/Caches/Entries/DeleteEntry'; +import { ThemeContext } from '@app/providers/ThemeProvider'; const CacheEntries = (props: { cacheName: string }) => { const { cacheEntries, totalEntriesCount, loadingEntries, errorEntries, infoEntries, reloadEntries, getByKey } = @@ -64,6 +64,8 @@ const CacheEntries = (props: { cacheName: string }) => { perPage: 10 }); + const {syntaxHighLighterTheme} = useContext(ThemeContext) + useEffect(() => { if (cache.encoding.key == EncodingType.Protobuf) { setSelectSearchOption(ContentType.string); @@ -145,7 +147,7 @@ const CacheEntries = (props: { cacheName: string }) => { diff --git a/src/app/Caches/Query/QueryEntries.tsx b/src/app/Caches/Query/QueryEntries.tsx index 00ef49a57..fdee5852e 100644 --- a/src/app/Caches/Query/QueryEntries.tsx +++ b/src/app/Caches/Query/QueryEntries.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect,useContext } from 'react'; import { Bullseye, Button, @@ -20,12 +20,12 @@ import { import { SearchIcon, ExclamationCircleIcon, HelpIcon } from '@patternfly/react-icons'; import displayUtils from '../../../services/displayUtils'; import SyntaxHighlighter from 'react-syntax-highlighter'; -import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import { useTranslation } from 'react-i18next'; import { ConsoleServices } from '@services/ConsoleServices'; import { Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table'; import { Table } from '@patternfly/react-table/deprecated'; import { global_danger_color_200, global_spacer_md, global_spacer_sm } from '@patternfly/react-tokens'; +import { ThemeContext } from '@app/providers/ThemeProvider'; const QueryEntries = (props: { cacheName: string; indexed: boolean; changeTab: () => void }) => { const [query, setQuery] = useState(''); @@ -41,6 +41,9 @@ const QueryEntries = (props: { cacheName: string; indexed: boolean; changeTab: ( total: 0 }); + const {syntaxHighLighterTheme} = useContext(ThemeContext) + + const columnNames = { value: 'Value' }; @@ -57,7 +60,7 @@ const QueryEntries = (props: { cacheName: string; indexed: boolean; changeTab: ( return ( diff --git a/src/app/Common/Health.tsx b/src/app/Common/Health.tsx index f5864da90..a026db979 100644 --- a/src/app/Common/Health.tsx +++ b/src/app/Common/Health.tsx @@ -1,13 +1,22 @@ -import React from 'react'; +import React,{useContext} from 'react'; import { Flex, FlexItem, Text, TextContent } from '@patternfly/react-core'; import { AlertIcon } from '@patternfly/react-core/dist/js/components/Alert/AlertIcon'; import displayUtils from '@services/displayUtils'; import { ComponentHealth } from '@services/infinispanRefData'; +import { ThemeContext } from '@app/providers/ThemeProvider'; +import { chart_global_label_Fill, global_Color_light_100 } from '@patternfly/react-tokens'; const Health = (props: { health: string; displayIcon?: boolean; cacheName?: string }) => { const health = ComponentHealth[props.health]; const displayIcon = props.displayIcon == undefined ? true : props.displayIcon; - + const {theme} = useContext(ThemeContext); + + const getHealthLabelColor = ()=>{ + const color = displayUtils.healthColor(health, false); + return (theme === 'dark' && color === chart_global_label_Fill.value) + ? global_Color_light_100.value + : color; + } return ( {displayIcon && ( @@ -28,7 +37,7 @@ const Health = (props: { health: string; displayIcon?: boolean; cacheName?: stri {displayUtils.healthLabel(health)} diff --git a/src/app/Common/Status.tsx b/src/app/Common/Status.tsx index d055d88fd..60c4c8432 100644 --- a/src/app/Common/Status.tsx +++ b/src/app/Common/Status.tsx @@ -20,7 +20,7 @@ const Status = (props: { status?: Status }) => { - + {status.name} diff --git a/src/app/ProtoSchema/ProtobufSchemasDisplay.tsx b/src/app/ProtoSchema/ProtobufSchemasDisplay.tsx index 5389af394..cdee08a80 100644 --- a/src/app/ProtoSchema/ProtobufSchemasDisplay.tsx +++ b/src/app/ProtoSchema/ProtobufSchemasDisplay.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useContext } from 'react'; import { Alert, AlertVariant, @@ -26,7 +26,6 @@ import { Table, Thead, Tr, Th, Tbody, Td, ExpandableRowContent, ActionsColumn, I import { DatabaseIcon, SearchIcon } from '@patternfly/react-icons'; import { global_spacer_md, global_spacer_sm, global_spacer_xl } from '@patternfly/react-tokens'; import SyntaxHighlighter from 'react-syntax-highlighter'; -import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import { useApiAlert } from '@app/utils/useApiAlert'; import { useTranslation } from 'react-i18next'; import { ConsoleServices } from '@services/ConsoleServices'; @@ -38,6 +37,7 @@ import { EditSchema } from './EditSchema'; import { useFetchProtobufSchemas } from '@app/services/protobufHooks'; import { onSearch } from '@app/utils/searchFilter'; import './ProtobufSchemasDisplay.css'; +import { ThemeContext } from '@app/providers/ThemeProvider'; const ProtobufSchemasDisplay = (props: { setProtoSchemasCount: (number) => void; isVisible: boolean }) => { const { t } = useTranslation(); @@ -59,6 +59,7 @@ const ProtobufSchemasDisplay = (props: { setProtoSchemasCount: (number) => void; page: 1, perPage: 10 }); + const {syntaxHighLighterTheme} = useContext(ThemeContext) const isSchemaExpanded = (row) => expandedSchemaNames.includes(row.name); @@ -217,7 +218,7 @@ const ProtobufSchemasDisplay = (props: { setProtoSchemasCount: (number) => void; return ( - + {schemasContent.get(name)} diff --git a/src/app/Welcome/Welcome.tsx b/src/app/Welcome/Welcome.tsx index 443316c16..34e39c8a5 100644 --- a/src/app/Welcome/Welcome.tsx +++ b/src/app/Welcome/Welcome.tsx @@ -87,7 +87,6 @@ const Welcome = (props) => { }} component={'button'} className={'button'} - style={{ backgroundColor: global_BackgroundColor_100.value }} > {goToTheConsole} diff --git a/src/app/index.tsx b/src/app/index.tsx index 5a2d3acad..def8bad8a 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -7,6 +7,7 @@ import '@app/app.css'; import { KeycloakService } from '@services/keycloakService'; import { ConsoleServices } from '@services/ConsoleServices'; import { UserContextProvider } from '@app/providers/UserContextProvider'; +import { ThemeProvider } from './providers/ThemeProvider'; const App = () => { const [init, setInit] = useState< @@ -74,11 +75,13 @@ const App = () => { const load = () => { return ( - - - - - + + + + + + + ); }; diff --git a/src/app/providers/ThemeProvider.tsx b/src/app/providers/ThemeProvider.tsx new file mode 100644 index 000000000..b3e90c9c2 --- /dev/null +++ b/src/app/providers/ThemeProvider.tsx @@ -0,0 +1,41 @@ +import React, { useEffect, useState } from 'react'; +import { getInitialTheme } from '@app/utils/themeUtils'; +import { githubGist, dracula } from 'react-syntax-highlighter/dist/esm/styles/hljs'; + +const initialState = { + theme : '', + toggleTheme : ()=>{}, + syntaxHighLighterTheme : '' +} + +export const ThemeContext = React.createContext(initialState); + + +const ThemeProvider = ({children})=>{ + const [theme,setTheme] = useState(getInitialTheme); + const syntaxHighLighterTheme = theme === 'dark'? dracula : githubGist; + + useEffect(()=>{ + if (theme === 'dark') { + document.documentElement.classList.add('pf-v5-theme-dark'); + } else { + document.documentElement.classList.remove('pf-v5-theme-dark'); + } + + if(localStorage){ + localStorage.setItem('theme',theme); + } + },[theme]) + + const toggleTheme = ()=>{ + setTheme((previousTheme)=> previousTheme === 'light'?'dark':'light'); + } + const themeState = { + theme, + toggleTheme, + syntaxHighLighterTheme + } + return {children} +} + +export {ThemeProvider} \ No newline at end of file diff --git a/src/app/utils/themeUtils.ts b/src/app/utils/themeUtils.ts new file mode 100644 index 000000000..72d5136d2 --- /dev/null +++ b/src/app/utils/themeUtils.ts @@ -0,0 +1,12 @@ + + +export const getInitialTheme = () : string => { + // Get theme from local storage cookie + if(localStorage && localStorage.getItem('theme')) + return localStorage.getItem('theme') || 'light'; + + // Check System preferred Theme + const prefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches; + + return prefersDarkTheme? 'dark' :'light'; +}