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