mirror of
https://github.com/portainer/portainer.git
synced 2025-07-22 23:09:41 +02:00
fix(home): dark mode for edit buttons [EE-4828] (#8241)
This commit is contained in:
parent
adf92ce5e0
commit
5942f4ff58
9 changed files with 96 additions and 54 deletions
|
@ -210,25 +210,12 @@ input[type='checkbox'] {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item--disabled {
|
|
||||||
cursor: auto;
|
|
||||||
background-color: var(--grey-12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklist-item--selected {
|
.blocklist-item--selected {
|
||||||
background-color: var(--bg-blocklist-item-selected-color);
|
background-color: var(--bg-blocklist-item-selected-color);
|
||||||
border: 2px solid var(--border-blocklist-item-selected-color);
|
border: 2px solid var(--border-blocklist-item-selected-color);
|
||||||
color: var(--text-blocklist-item-selected-color);
|
color: var(--text-blocklist-item-selected-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item:not(.blocklist-item-not-interactive):hover {
|
|
||||||
@apply border border-blue-7;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
background-color: var(--bg-blocklist-hover-color);
|
|
||||||
color: var(--text-blocklist-hover-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blocklist-item-box {
|
.blocklist-item-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,7 +222,6 @@
|
||||||
--border-table-color: var(--grey-19);
|
--border-table-color: var(--grey-19);
|
||||||
--border-table-top-color: var(--grey-19);
|
--border-table-top-color: var(--grey-19);
|
||||||
--border-datatable-top-color: var(--grey-10);
|
--border-datatable-top-color: var(--grey-10);
|
||||||
--border-blocklist-color: var(--grey-44);
|
|
||||||
--border-input-group-addon-color: var(--grey-44);
|
--border-input-group-addon-color: var(--grey-44);
|
||||||
--border-btn-default-color: var(--grey-44);
|
--border-btn-default-color: var(--grey-44);
|
||||||
--border-boxselector-color: var(--grey-6);
|
--border-boxselector-color: var(--grey-6);
|
||||||
|
@ -231,7 +230,6 @@
|
||||||
--border-navtabs-color: var(--ui-white);
|
--border-navtabs-color: var(--ui-white);
|
||||||
--border-codemirror-cursor-color: var(--black-color);
|
--border-codemirror-cursor-color: var(--black-color);
|
||||||
--border-pre-color: var(--grey-43);
|
--border-pre-color: var(--grey-43);
|
||||||
--border-blocklist-item-selected-color: var(--grey-46);
|
|
||||||
--border-pagination-span-color: var(--ui-white);
|
--border-pagination-span-color: var(--ui-white);
|
||||||
--border-pagination-hover-color: var(--ui-white);
|
--border-pagination-hover-color: var(--ui-white);
|
||||||
--border-panel-color: var(--white-color);
|
--border-panel-color: var(--white-color);
|
||||||
|
@ -245,6 +243,7 @@
|
||||||
--border-sortbutton: var(--grey-8);
|
--border-sortbutton: var(--grey-8);
|
||||||
--border-bootbox: var(--ui-gray-5);
|
--border-bootbox: var(--ui-gray-5);
|
||||||
--border-blocklist: var(--ui-gray-5);
|
--border-blocklist: var(--ui-gray-5);
|
||||||
|
--border-blocklist-item-selected-color: var(--grey-46);
|
||||||
--border-widget: var(--ui-gray-5);
|
--border-widget: var(--ui-gray-5);
|
||||||
--border-nav-container-color: var(--ui-gray-5);
|
--border-nav-container-color: var(--ui-gray-5);
|
||||||
--border-stepper-color: var(--ui-gray-4);
|
--border-stepper-color: var(--ui-gray-4);
|
||||||
|
@ -408,7 +407,6 @@
|
||||||
--border-table-color: var(--grey-3);
|
--border-table-color: var(--grey-3);
|
||||||
--border-table-top-color: var(--grey-3);
|
--border-table-top-color: var(--grey-3);
|
||||||
--border-datatable-top-color: var(--grey-3);
|
--border-datatable-top-color: var(--grey-3);
|
||||||
--border-blocklist-color: var(--grey-3);
|
|
||||||
--border-input-group-addon-color: var(--grey-38);
|
--border-input-group-addon-color: var(--grey-38);
|
||||||
--border-btn-default-color: var(--grey-38);
|
--border-btn-default-color: var(--grey-38);
|
||||||
--border-boxselector-color: var(--grey-1);
|
--border-boxselector-color: var(--grey-1);
|
||||||
|
@ -417,6 +415,7 @@
|
||||||
--border-navtabs-color: var(--grey-38);
|
--border-navtabs-color: var(--grey-38);
|
||||||
--border-codemirror-cursor-color: var(--white-color);
|
--border-codemirror-cursor-color: var(--white-color);
|
||||||
--border-pre-color: var(--grey-3);
|
--border-pre-color: var(--grey-3);
|
||||||
|
--border-blocklist: var(--ui-gray-9);
|
||||||
--border-blocklist-item-selected-color: var(--grey-38);
|
--border-blocklist-item-selected-color: var(--grey-38);
|
||||||
--border-pagination-span-color: var(--grey-1);
|
--border-pagination-span-color: var(--grey-1);
|
||||||
--border-pagination-hover-color: var(--grey-3);
|
--border-pagination-hover-color: var(--grey-3);
|
||||||
|
@ -430,7 +429,6 @@
|
||||||
--border-modal: 0px;
|
--border-modal: 0px;
|
||||||
--border-sortbutton: var(--grey-3);
|
--border-sortbutton: var(--grey-3);
|
||||||
--border-bootbox: var(--ui-gray-9);
|
--border-bootbox: var(--ui-gray-9);
|
||||||
--border-blocklist: var(--ui-gray-9);
|
|
||||||
--border-widget: var(--grey-3);
|
--border-widget: var(--grey-3);
|
||||||
--border-pagination-color: var(--grey-1);
|
--border-pagination-color: var(--grey-1);
|
||||||
--border-nav-container-color: var(--ui-gray-neutral-8);
|
--border-nav-container-color: var(--ui-gray-neutral-8);
|
||||||
|
@ -600,7 +598,6 @@
|
||||||
--border-pre-color: var(--grey-3);
|
--border-pre-color: var(--grey-3);
|
||||||
--border-codemirror-cursor-color: var(--white-color);
|
--border-codemirror-cursor-color: var(--white-color);
|
||||||
--border-modal: 1px solid var(--white-color);
|
--border-modal: 1px solid var(--white-color);
|
||||||
--border-blocklist-color: var(--white-color);
|
|
||||||
--border-sortbutton: var(--black-color);
|
--border-sortbutton: var(--black-color);
|
||||||
--border-bootbox: var(--black-color);
|
--border-bootbox: var(--black-color);
|
||||||
--border-blocklist: var(--white-color);
|
--border-blocklist: var(--white-color);
|
||||||
|
|
|
@ -16,7 +16,6 @@ export function LinkButton({
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
title={title}
|
title={title}
|
||||||
size="medium"
|
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...props}
|
{...props}
|
||||||
className={clsx(className, '!m-0 no-link')}
|
className={clsx(className, '!m-0 no-link')}
|
||||||
|
|
|
@ -20,6 +20,12 @@ export function EditButtons({ environment }: { environment: Environment }) {
|
||||||
const isEdgeAsync = checkEdgeAsync(environment);
|
const isEdgeAsync = checkEdgeAsync(environment);
|
||||||
|
|
||||||
const configRoute = getConfigRoute(environment);
|
const configRoute = getConfigRoute(environment);
|
||||||
|
|
||||||
|
const buttonsClasses = clsx(
|
||||||
|
'w-full h-full !ml-0 !rounded-none',
|
||||||
|
'hover:bg-gray-3 th-dark:hover:bg-gray-9 th-highcontrast:hover:bg-white'
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonsGrid className="w-11 ml-3">
|
<ButtonsGrid className="w-11 ml-3">
|
||||||
<LinkButton
|
<LinkButton
|
||||||
|
@ -29,7 +35,7 @@ export function EditButtons({ environment }: { environment: Environment }) {
|
||||||
color="none"
|
color="none"
|
||||||
icon={Edit2}
|
icon={Edit2}
|
||||||
size="medium"
|
size="medium"
|
||||||
className="w-full h-full !ml-0 hover:bg-gray-3 !rounded-none"
|
className={buttonsClasses}
|
||||||
title="Edit"
|
title="Edit"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -40,7 +46,7 @@ export function EditButtons({ environment }: { environment: Environment }) {
|
||||||
color="none"
|
color="none"
|
||||||
icon={Settings}
|
icon={Settings}
|
||||||
size="medium"
|
size="medium"
|
||||||
className="w-full h-full !ml-0 hover:bg-gray-3 !rounded-none"
|
className={buttonsClasses}
|
||||||
title="Configuration"
|
title="Configuration"
|
||||||
/>
|
/>
|
||||||
</ButtonsGrid>
|
</ButtonsGrid>
|
||||||
|
@ -79,7 +85,9 @@ function ButtonsGrid({
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'grid border border-solid border-gray-5 rounded-r-lg',
|
'grid border border-solid rounded-r-lg',
|
||||||
|
'border-gray-5 th-dark:border-gray-9 th-highcontrast:border-white',
|
||||||
|
'overflow-hidden',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
@ -87,7 +95,7 @@ function ButtonsGrid({
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
'border-0 border-b border-solid border-b-gray-5':
|
'border-0 border-b border-solid border-b-inherit':
|
||||||
index < children.length - 1,
|
index < children.length - 1,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { History, Wifi, WifiOff } from 'lucide-react';
|
import { History, Wifi, WifiOff, X } from 'lucide-react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { Environment } from '@/react/portainer/environments/types';
|
import { Environment } from '@/react/portainer/environments/types';
|
||||||
import {
|
import {
|
||||||
|
@ -9,16 +10,19 @@ import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
||||||
|
|
||||||
import { Icon } from '@@/Icon';
|
import { Icon } from '@@/Icon';
|
||||||
import { LinkButton } from '@@/LinkButton';
|
import { LinkButton } from '@@/LinkButton';
|
||||||
|
import { Button } from '@@/buttons';
|
||||||
|
|
||||||
type BrowseStatus = 'snapshot' | 'connected' | 'disconnected';
|
type BrowseStatus = 'snapshot' | 'connected' | 'disconnected';
|
||||||
|
|
||||||
export function EnvironmentBrowseButtons({
|
export function EnvironmentBrowseButtons({
|
||||||
environment,
|
environment,
|
||||||
onClickBrowse,
|
onClickBrowse,
|
||||||
|
onClickDisconnect,
|
||||||
isActive,
|
isActive,
|
||||||
}: {
|
}: {
|
||||||
environment: Environment;
|
environment: Environment;
|
||||||
onClickBrowse(): void;
|
onClickBrowse(): void;
|
||||||
|
onClickDisconnect(): void;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
}) {
|
}) {
|
||||||
const isEdgeAsync = checkEdgeAsync(environment);
|
const isEdgeAsync = checkEdgeAsync(environment);
|
||||||
|
@ -26,34 +30,59 @@ export function EnvironmentBrowseButtons({
|
||||||
|
|
||||||
const dashboardRoute = getDashboardRoute(environment);
|
const dashboardRoute = getDashboardRoute(environment);
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-1 justify-center [&>*]:h-1/3 h-24">
|
<div className="flex flex-col gap-2 justify-center [&>*]:h-1/3 h-24 w-full">
|
||||||
{isBE && (
|
{isBE &&
|
||||||
|
(browseStatus !== 'snapshot' ? (
|
||||||
<LinkButton
|
<LinkButton
|
||||||
icon={History}
|
icon={History}
|
||||||
disabled={!isEdgeAsync || browseStatus === 'snapshot'}
|
disabled={!isEdgeAsync}
|
||||||
to="edge.browse.dashboard"
|
to="edge.browse.dashboard"
|
||||||
params={{
|
params={{
|
||||||
environmentId: environment.Id,
|
environmentId: environment.Id,
|
||||||
}}
|
}}
|
||||||
|
size="medium"
|
||||||
color="light"
|
color="light"
|
||||||
className="w-full !py-0 !m-0"
|
className="w-full !py-0 !m-0"
|
||||||
>
|
>
|
||||||
Browse snapshot
|
Browse snapshot
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
)}
|
) : (
|
||||||
|
<Button
|
||||||
|
icon={X}
|
||||||
|
onClick={onClickDisconnect}
|
||||||
|
className="w-full !py-0 !m-0 opacity-60"
|
||||||
|
size="medium"
|
||||||
|
color="light"
|
||||||
|
>
|
||||||
|
Close snapshot
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{browseStatus !== 'connected' ? (
|
||||||
<LinkButton
|
<LinkButton
|
||||||
title="Live connection is not available for async environments"
|
title="Live connection is not available for async environments"
|
||||||
icon={Wifi}
|
icon={Wifi}
|
||||||
disabled={isEdgeAsync || browseStatus === 'connected'}
|
disabled={isEdgeAsync}
|
||||||
to={dashboardRoute.to}
|
to={dashboardRoute.to}
|
||||||
params={dashboardRoute.params}
|
params={dashboardRoute.params}
|
||||||
|
size="medium"
|
||||||
onClick={onClickBrowse}
|
onClick={onClickBrowse}
|
||||||
color="primary"
|
color="primary"
|
||||||
className="w-full !py-0 !m-0"
|
className="w-full !py-0 !m-0"
|
||||||
>
|
>
|
||||||
Live connect
|
Live connect
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
icon={WifiOff}
|
||||||
|
onClick={onClickDisconnect}
|
||||||
|
className="w-full !py-0 !m-0 opacity-60"
|
||||||
|
size="medium"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
<BrowseStatusTag status={browseStatus} />
|
<BrowseStatusTag status={browseStatus} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,7 +116,7 @@ function BrowseStatusTag({ status }: { status: BrowseStatus }) {
|
||||||
|
|
||||||
function Disconnected() {
|
function Disconnected() {
|
||||||
return (
|
return (
|
||||||
<div className="vertical-center justify-center opacity-50">
|
<div className="flex items-center gap-2 justify-center opacity-50">
|
||||||
<Icon icon={WifiOff} />
|
<Icon icon={WifiOff} />
|
||||||
Disconnected
|
Disconnected
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,8 +125,14 @@ function Disconnected() {
|
||||||
|
|
||||||
function Connected() {
|
function Connected() {
|
||||||
return (
|
return (
|
||||||
<div className="vertical-center gap-2 justify-center text-green-8 bg-green-3 rounded-lg">
|
<div
|
||||||
<div className="rounded-full h-2 w-2 bg-green-8" />
|
className={clsx(
|
||||||
|
'flex items-center gap-2 justify-center rounded-lg',
|
||||||
|
'text-green-8 th-dark:text-green-4',
|
||||||
|
'bg-green-3 th-dark:bg-green-3/30'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="rounded-full h-2 w-2 bg-green-8 th-dark:bg-green-4" />
|
||||||
Connected
|
Connected
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -105,7 +140,13 @@ function Connected() {
|
||||||
|
|
||||||
function Snapshot() {
|
function Snapshot() {
|
||||||
return (
|
return (
|
||||||
<div className="vertical-center gap-2 justify-center text-warning-7 bg-warning-3 rounded-lg">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
'flex items-center gap-2 justify-center rounded-lg',
|
||||||
|
'text-warning-7 th-dark:text-warning-4',
|
||||||
|
'bg-warning-3 th-dark:bg-warning-3/10 th-highcontrast:bg-warning-3/30'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className="rounded-full h-2 w-2 bg-warning-7" />
|
<div className="rounded-full h-2 w-2 bg-warning-7" />
|
||||||
Browsing Snapshot
|
Browsing Snapshot
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,6 +23,7 @@ function Template({ environment }: Args) {
|
||||||
<EnvironmentItem
|
<EnvironmentItem
|
||||||
environment={environment}
|
environment={environment}
|
||||||
onClickBrowse={() => {}}
|
onClickBrowse={() => {}}
|
||||||
|
onClickDisconnect={() => {}}
|
||||||
isActive={false}
|
isActive={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -46,6 +46,7 @@ function renderComponent(
|
||||||
<EnvironmentItem
|
<EnvironmentItem
|
||||||
isActive={false}
|
isActive={false}
|
||||||
onClickBrowse={() => {}}
|
onClickBrowse={() => {}}
|
||||||
|
onClickDisconnect={() => {}}
|
||||||
environment={env}
|
environment={env}
|
||||||
groupName={group.Name}
|
groupName={group.Name}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -33,12 +33,14 @@ interface Props {
|
||||||
environment: Environment;
|
environment: Environment;
|
||||||
groupName?: string;
|
groupName?: string;
|
||||||
onClickBrowse(): void;
|
onClickBrowse(): void;
|
||||||
|
onClickDisconnect(): void;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EnvironmentItem({
|
export function EnvironmentItem({
|
||||||
environment,
|
environment,
|
||||||
onClickBrowse,
|
onClickBrowse,
|
||||||
|
onClickDisconnect,
|
||||||
groupName,
|
groupName,
|
||||||
isActive,
|
isActive,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
@ -113,10 +115,11 @@ export function EnvironmentItem({
|
||||||
see https://stackoverflow.com/questions/66409964/warning-validatedomnesting-a-cannot-appear-as-a-descendant-of-a
|
see https://stackoverflow.com/questions/66409964/warning-validatedomnesting-a-cannot-appear-as-a-descendant-of-a
|
||||||
*/}
|
*/}
|
||||||
<div className="absolute inset-y-0 right-0 flex justify-end w-56">
|
<div className="absolute inset-y-0 right-0 flex justify-end w-56">
|
||||||
<div className="py-3 flex items-center">
|
<div className="py-3 flex items-center flex-1">
|
||||||
<EnvironmentBrowseButtons
|
<EnvironmentBrowseButtons
|
||||||
environment={environment}
|
environment={environment}
|
||||||
onClickBrowse={onClickBrowse}
|
onClickBrowse={onClickBrowse}
|
||||||
|
onClickDisconnect={onClickDisconnect}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -46,7 +46,7 @@ const storageKey = 'home_endpoints';
|
||||||
|
|
||||||
export function EnvironmentList({ onClickBrowse, onRefresh }: Props) {
|
export function EnvironmentList({ onClickBrowse, onRefresh }: Props) {
|
||||||
const { isAdmin } = useUser();
|
const { isAdmin } = useUser();
|
||||||
const { environmentId: currentEnvironmentId } = useStore(environmentStore);
|
const currentEnvStore = useStore(environmentStore);
|
||||||
|
|
||||||
const [platformTypes, setPlatformTypes] = useHomePageFilter<
|
const [platformTypes, setPlatformTypes] = useHomePageFilter<
|
||||||
Filter<PlatformType>[]
|
Filter<PlatformType>[]
|
||||||
|
@ -223,7 +223,12 @@ export function EnvironmentList({ onClickBrowse, onRefresh }: Props) {
|
||||||
groupsQuery.data?.find((g) => g.Id === env.GroupId)?.Name
|
groupsQuery.data?.find((g) => g.Id === env.GroupId)?.Name
|
||||||
}
|
}
|
||||||
onClickBrowse={() => onClickBrowse(env)}
|
onClickBrowse={() => onClickBrowse(env)}
|
||||||
isActive={env.Id === currentEnvironmentId}
|
onClickDisconnect={() =>
|
||||||
|
env.Id === currentEnvStore.environmentId
|
||||||
|
? currentEnvStore.clear()
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
isActive={env.Id === currentEnvStore.environmentId}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue