This commit is contained in:
Fatih Aytekin 2026-04-21 09:27:05 +03:00 committed by GitHub
commit 64586638de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 400 additions and 51 deletions

View file

@ -121,10 +121,18 @@ $header: 120px;
&::before {
font-size: 1.5em;
}
.theme-dark & {
color: $argo-color-gray-4;
}
}
i.selected {
cursor: default;
color: $argo-color-gray-7;
.theme-dark & {
color: $white-color;
}
}
}

View file

@ -22,6 +22,10 @@
font-size: 10px;
top: -9px;
transform: rotate(180deg);
.theme-dark & {
color: $argo-color-gray-5;
}
}
}
}

View file

@ -1,6 +1,6 @@
import {HelpIcon} from 'argo-ui';
import * as React from 'react';
import {ARGO_GRAY6_COLOR, DataLoader} from '../../../shared/components';
import {DataLoader} from '../../../shared/components';
import {Revision} from '../../../shared/components/revision';
import {revisionUrl} from '../../../shared/components/urls';
import {Timestamp} from '../../../shared/components/timestamp';
@ -42,7 +42,7 @@ interface SectionInfo {
}
const sectionLabel = (info: SectionInfo) => (
<label style={{display: 'flex', alignItems: 'flex-start', fontSize: '12px', fontWeight: 600, color: ARGO_GRAY6_COLOR, minHeight: '18px'}}>
<label style={{display: 'flex', alignItems: 'flex-start', fontSize: '12px', fontWeight: 600, minHeight: '18px'}}>
{info.title}
{info.helpContent && (
<span style={{marginLeft: '5px'}}>

View file

@ -1,6 +1,5 @@
import {HelpIcon} from 'argo-ui';
import * as React from 'react';
import {ARGO_GRAY6_COLOR} from '../../../shared/components';
import {Timestamp} from '../../../shared/components/timestamp';
import * as models from '../../../shared/models';
import {getAppSetConditionCategory, getAppSetHealthStatus, HealthStatusIcon} from '../utils';
@ -18,7 +17,7 @@ interface SectionInfo {
}
const sectionLabel = (info: SectionInfo) => (
<label style={{display: 'flex', alignItems: 'flex-start', fontSize: '12px', fontWeight: 600, color: ARGO_GRAY6_COLOR, minHeight: '18px'}}>
<label style={{display: 'flex', alignItems: 'flex-start', fontSize: '12px', fontWeight: 600, minHeight: '18px'}}>
{info.title}
{info.helpContent && (
<span style={{marginLeft: '5px'}}>

View file

@ -12,10 +12,6 @@
}
}
&:nth-of-type(odd) {
background: #e0e0e0;
}
.container {
max-width: 30em;
white-space: nowrap;

View file

@ -10,6 +10,10 @@
border-radius: 25px;
border: $border-width solid white;
.theme-dark & {
border-color: $dark-theme-background-2;
}
&__segment {
&__fill {
height: $height - (2 * $border-width);
@ -28,5 +32,9 @@
&__segment:not(:first-child) {
border-left: 3px solid white;
.theme-dark & {
border-left-color: $dark-theme-background-2;
}
}
}

View file

@ -3,17 +3,7 @@ import {useState, useRef, useEffect} from 'react';
import {ToggleButton} from '../../../shared/components/toggle-button';
// PodHighlightButton is a component that renders a toggle button that toggles pod highlighting.
export const PodHighlightButton = ({
selectedPod,
setSelectedPod,
pods,
darkMode
}: {
selectedPod: string | null;
setSelectedPod: (value: string | null) => void;
pods: string[];
darkMode: boolean;
}) => {
export const PodHighlightButton = ({selectedPod, setSelectedPod, pods}: {selectedPod: string | null; setSelectedPod: (value: string | null) => void; pods: string[]}) => {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
@ -32,12 +22,12 @@ export const PodHighlightButton = ({
<div ref={dropdownRef} style={{position: 'relative'}}>
<ToggleButton title='Select a pod to highlight its logs' onToggle={() => setIsOpen(!isOpen)} icon='highlighter' toggled={selectedPod !== null} />
{isOpen && (
<div className={`select-container ${darkMode ? 'dark-mode' : ''}`} style={{position: 'absolute', top: '100%', left: 0, zIndex: 1}}>
<div className='select-container' style={{position: 'absolute', top: '100%', left: 0, zIndex: 1}}>
<div className='select-options'>
{pods.map(pod => (
<div
key={pod}
className={`select-option ${selectedPod === pod ? 'selected' : ''} ${darkMode ? 'dark-mode' : ''}`}
className={`select-option ${selectedPod === pod ? 'selected' : ''}`}
onClick={() => {
setSelectedPod(pod);
setIsOpen(false);
@ -47,7 +37,7 @@ export const PodHighlightButton = ({
))}
</div>
<div
className={`select-option clear-highlight ${darkMode ? 'dark-mode' : ''}`}
className='select-option clear-highlight'
onClick={() => {
setSelectedPod(null);
setIsOpen(false);

View file

@ -16,6 +16,12 @@ $pod-background-dark: $dark-theme-background-2;
padding: 0;
color: black;
.theme-dark & {
background-color: $dark-theme-background-2;
color: $argo-color-gray-3;
scrollbar-color: $argo-color-gray-5 $dark-theme-background-2;
}
&--inverted {
background-color: black;
color: white;
@ -103,6 +109,14 @@ $pod-background-dark: $dark-theme-background-2;
background-color: black;
color: white;
}
.theme-dark & {
border-color: $argo-color-gray-5;
color: $argo-color-gray-3;
&:hover {
background-color: $argo-color-gray-5;
color: white;
}
}
&.disabled {
opacity: 0.5;
cursor: not-allowed;
@ -233,12 +247,12 @@ $pod-background-dark: $dark-theme-background-2;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
z-index: 1000;
min-width: 200px; // Ensure dropdown is wide enough for pod names
min-width: 200px;
&.dark-mode {
background: #333; /* Dark background for dark mode */
border: 1px solid #555; /* Subtle border for dark mode */
color: #eee; /* Light text for dark mode */
.theme-dark & {
background: #333;
border: 1px solid #555;
color: #eee;
}
}
@ -249,24 +263,23 @@ $pod-background-dark: $dark-theme-background-2;
.select-option {
padding: 8px 10px;
cursor: pointer;
white-space: nowrap; // Prevent pod names from wrapping
white-space: nowrap;
&:hover {
background-color: #f5f5f5;
}
&.dark-mode {
background-color: #444; /* Hover effect in dark mode */
&:hover {
background-color: #555;
}
}
&.selected {
background-color: #e6f3ff;
}
&.dark-mode.selected {
background-color: #666; /* Selection highlight in dark mode */
.theme-dark & {
&:hover {
background-color: #555;
}
&.selected {
background-color: #666;
}
}
}
}
@ -277,12 +290,12 @@ $pod-background-dark: $dark-theme-background-2;
text-align: center;
color: #1750d3;
cursor: pointer;
&:hover {
background-color: #f0f0f0;
}
&.dark-mode {
.theme-dark & {
border-top: 1px solid #555;
color: #5a9bd3;
&:hover {

View file

@ -18,6 +18,7 @@ import {ShowPreviousLogsToggleButton} from './show-previous-logs-toggle-button';
import {PodHighlightButton} from './pod-logs-highlight-button';
import {TimestampsToggleButton} from './timestamps-toggle-button';
import {DarkModeToggleButton} from './dark-mode-toggle-button';
import {getTheme} from '../../../shared/utils';
import {FullscreenButton} from './fullscreen-button';
import {Spacer} from '../../../shared/components/spacer';
import {LogMessageFilter} from './log-message-filter';
@ -272,7 +273,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
{follow && <AutoScrollButton scrollToBottom={scrollToBottom} setScrollToBottom={setScrollToBottom} />}
<ShowPreviousLogsToggleButton setPreviousLogs={setPreviousLogsWithQueryParams} showPreviousLogs={previous} />
<Spacer />
<PodHighlightButton selectedPod={selectedPod} setSelectedPod={setSelectedPod} pods={uniquePods} darkMode={prefs.appDetails.darkMode} />
<PodHighlightButton selectedPod={selectedPod} setSelectedPod={setSelectedPod} pods={uniquePods} />
<Spacer />
<ContainerSelector containerGroups={containerGroups} containerName={containerName} onClickContainer={onClickContainer} />
<Spacer />
@ -290,7 +291,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
<WrapLinesButton prefs={prefs} />
<PodNamesToggleButton viewPodNames={viewPodNames} setViewPodNames={onToggleViewPodNames} />
<TimestampsToggleButton setViewTimestamps={setViewTimestampsWithQueryParams} viewTimestamps={viewTimestamps} timestamp={timestamp} />
<DarkModeToggleButton prefs={prefs} />
{getTheme(prefs.theme) !== 'dark' && <DarkModeToggleButton prefs={prefs} />}
</span>
<Spacer />
<span>

View file

@ -1,3 +1,5 @@
@import 'node_modules/argo-ui/src/styles/config';
.pod-terminal-viewer {
height: 780px;
@ -44,4 +46,19 @@
color: #191826;
}
}
}
.theme-dark {
.pod-terminal-viewer__tab {
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
}
.pod-terminal-viewer__container {
.tooltip {
background-color: $dark-theme-background-2;
border-color: $dark-theme-background-2;
color: #fff;
}
}
}

View file

@ -3,7 +3,9 @@ import React, {useContext, useEffect, useState} from 'react';
import {Form, Text} from 'react-form';
import {RouteComponentProps} from 'react-router';
import {AuthSettings} from '../../shared/models';
import {distinctUntilChanged, map} from 'rxjs/operators';
import {services} from '../../shared/services';
import {useBodyTheme} from '../../shared/components/layout/layout';
import {Context} from '../../shared/context';
require('./login.scss');
@ -23,14 +25,25 @@ export function Login(props: RouteComponentProps<{}>) {
const [authSettings, setAuthSettings] = useState<AuthSettings | null>(null);
const [loginError, setLoginError] = useState<string | null>(null);
const [loginInProgress, setLoginInProgress] = useState<boolean>(false);
const [themePref, setThemePref] = useState('light');
useEffect(() => {
(async () => {
const authSettings = await services.authService.settings();
setAuthSettings(authSettings);
})();
const sub = services.viewPreferences
.getPreferences()
.pipe(
map(prefs => prefs.theme),
distinctUntilChanged()
)
.subscribe(setThemePref);
return () => sub.unsubscribe();
}, []);
const theme = useBodyTheme(themePref);
const login = async (username: string, password: string, returnURL: string) => {
try {
setLoginError('');
@ -58,7 +71,7 @@ export function Login(props: RouteComponentProps<{}>) {
const ssoConfigured = authSettings && ((authSettings.dexConfig && (authSettings.dexConfig.connectors || []).length > 0) || authSettings.oidcConfig);
return (
<div className='login'>
<div className={`login theme-${theme}`}>
<div className='login__content show-for-medium'>
<div className='login__text'>Let's get stuff deployed!</div>
<div className='argo__logo' />

View file

@ -21,7 +21,10 @@
&:hover {
@include themify($themes) {
background-color: themed('light-argo-teal-1');
background-color: themed('light-argo-teal-1');
}
.theme-dark & {
background-color: rgba($argo-color-teal-5, 0.1);
}
}

View file

@ -15,6 +15,9 @@
@include themify($themes) {
background-color: themed('background-1');
}
.theme-dark & {
background-color: #141a20;
}
&__loader {
@include themify($themes) {
background-color: themed('layout-loader-bg');

View file

@ -4,6 +4,7 @@ import {ViewPreferences} from '../../services';
import {useTheme} from '../../utils';
require('./layout.scss');
require('../../dark-mode-overrides.scss');
export interface LayoutProps {
navItems: Array<{path: string; iconClassName: string; title: string}>;
@ -12,7 +13,19 @@ export interface LayoutProps {
pref: ViewPreferences;
}
const getBGColor = (theme: string): string => (theme === 'light' ? '#dee6eb' : '#100f0f');
const LIGHT_BG = '#dee6eb';
const DARK_BG = '#141a20';
export const useBodyTheme = (themePref: string) => {
const [theme] = useTheme({theme: themePref});
React.useEffect(() => {
if (theme) {
document.body.style.background = theme === 'light' ? LIGHT_BG : DARK_BG;
document.body.classList.toggle('dark-theme', theme === 'dark');
}
}, [theme]);
return theme;
};
export const ThemeWrapper = (props: {children: React.ReactNode; theme: string}) => {
const [systemTheme] = useTheme({
@ -22,12 +35,7 @@ export const ThemeWrapper = (props: {children: React.ReactNode; theme: string})
};
export const Layout = (props: LayoutProps) => {
const [theme] = useTheme({theme: props.pref.theme});
React.useEffect(() => {
if (theme) {
document.body.style.background = getBGColor(theme);
}
}, [theme]);
const theme = useBodyTheme(props.pref.theme);
return (
<div className={`theme-${theme}`}>

View file

@ -0,0 +1,286 @@
@import 'node_modules/argo-ui/src/styles/config';
$dark-hover-overlay: rgba(255, 255, 255, 0.08);
// Dropdowns, tooltips, and selects may be portaled to document.body,
// outside the .theme-dark wrapper. body.dark-theme (toggled by Layout)
// ensures these elements are also styled for dark mode.
body.dark-theme {
.argo-dropdown__content {
background-color: $dark-theme-background-2;
box-shadow: 0 0 4px rgba(#000, .5);
&.is-menu ul li {
border-bottom-color: $argo-color-gray-7;
color: $argo-color-gray-3;
&:hover {
background-color: $argo-color-gray-7;
}
}
}
.tippy-tooltip {
background-color: $dark-theme-background-2;
color: $argo-color-gray-3;
box-shadow: 0 0 20px 4px rgba(0, 0, 0, .3);
&[data-placement^=top] > .tippy-arrow {
border-top-color: $dark-theme-background-2;
}
&[data-placement^=bottom] > .tippy-arrow {
border-bottom-color: $dark-theme-background-2;
}
&[data-placement^=left] > .tippy-arrow {
border-left-color: $dark-theme-background-2;
}
&[data-placement^=right] > .tippy-arrow {
border-right-color: $dark-theme-background-2;
}
> .tippy-backdrop {
background-color: $dark-theme-background-2;
}
}
.Toastify__toast-theme--light {
background: $dark-theme-background-2;
color: $argo-color-gray-3;
}
}
.theme-dark {
color: $argo-color-gray-3;
// Buttons
.argo-button {
&:not(.disabled):not([disabled]) {
&:hover,
&:focus {
background-color: $dark-hover-overlay;
}
}
&--base {
background-color: $argo-color-teal-7;
color: #fff;
&:not(.disabled):not([disabled]) {
&:hover,
&:focus {
background-color: $argo-color-teal-6;
color: #fff;
}
}
// !important needed to override argo-ui's &--base[disabled] selector
&.disabled,
&[disabled] {
background-color: $argo-color-gray-7 !important;
color: $argo-color-gray-4 !important;
}
}
&--link {
&:not(.disabled):not([disabled]) {
&:hover,
&:focus {
background-color: $dark-hover-overlay;
}
}
}
}
.argo-split-button__primary,
.argo-split-button__toggle {
background-color: $argo-color-teal-7;
&:not([disabled]):hover {
background-color: $argo-color-teal-6;
}
}
.action-button__background {
border-color: #30303d;
background-color: #22212d;
}
.action-button:hover > .action-button__background,
.action-button--selected > .action-button__background {
background-color: #8b4329;
border-color: #f07548;
}
.action-button--disabled:hover > .action-button__background {
background-color: #22212d;
border-color: #30303d;
}
// Empty state
.empty-state__icon {
background-color: $argo-color-gray-7;
i {
color: $argo-color-gray-3;
}
}
// Tables
.argo-table-list__row {
.title-text {
color: $argo-color-gray-3;
}
&.selected {
background-color: rgba($argo-color-teal-5, 0.15);
}
}
// Forms
.argo-field__with-action-btn {
background-color: $dark-theme-background-2;
color: $argo-color-gray-3;
}
.argo-select {
color: $argo-color-gray-3;
}
.argo-radio input:checked + span {
box-shadow: inset 0 0 0 3px $dark-theme-background-2;
}
.argo-checkbox-slide input {
& + span {
background-color: $argo-color-gray-6;
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.3);
&::before {
background-color: $argo-color-gray-4;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
}
&:checked + span::before {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
}
.argo-checkbox input:disabled + span {
background-color: $argo-color-gray-7;
border-color: $argo-color-gray-6;
}
// Select & dropdown menus
.select__options {
background-color: $dark-theme-background-2;
box-shadow: 0 0 4px rgba(#000, .5);
}
.select__option {
color: $argo-color-gray-3;
&:hover,
&.selected {
background-color: $argo-color-gray-7;
}
}
.select__search {
color: $argo-color-gray-3;
}
// Pod view
.pod-view__node__pod-container__pods,
.pod-view__node__info div,
.pod-view__node__info--large {
background-color: $argo-color-gray-7;
color: $argo-color-gray-3;
}
.pod-view__settings__section {
border-right-color: $argo-color-gray-7;
}
.pod-view__node__pod__stat__bar {
background-color: $argo-color-gray-6;
}
// Resource tree
.application-resource-tree__node-label {
background-color: $argo-color-gray-7;
color: $argo-color-gray-3;
border-color: $argo-color-gray-6;
}
.top-bar__breadcrumbs a:hover {
background-color: $dark-hover-overlay;
}
// Login
.login__box,
.login__saml-separator span {
background-color: $dark-theme-background-2;
}
// Application details
.group-nodes-button:hover {
background-color: $argo-color-gray-7;
}
.zoom-value {
background-color: $argo-color-gray-7;
color: $argo-color-gray-3;
}
// Application node info
.application-node-info__container {
border-bottom-color: rgba($argo-color-gray-6, 0.7);
}
.application-node-info__label {
background-color: $argo-color-gray-6;
color: $argo-color-gray-3;
}
// Panels & popups
.application-sync-options__warning {
background-color: $dark-theme-background-2;
}
.badge-panel {
border-color: $argo-color-gray-7;
}
.progress-popup__title {
color: $argo-color-gray-3;
}
.white-box h6 {
color: $argo-color-gray-3;
}
.stream::before {
background-color: $argo-color-gray-7;
}
.muted {
color: $argo-color-gray-5;
}
// Links
a {
color: $argo-color-teal-5;
&:hover,
&:focus,
&:active {
color: $argo-color-teal-4;
}
}
h1,
h2 {
color: $argo-color-teal-5;
}
}