1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 07:49:41 +02:00

feat(docker/services): show port ranges [EE-4012] (#10657)
Some checks failed
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
ci / build_images (map[arch:arm platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:s390x platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
/ triage (push) Has been cancelled
Lint / Run linters (push) Has been cancelled
Test / test-client (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:linux]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
Test / test-server (map[arch:arm64 platform:linux]) (push) Has been cancelled
ci / build_manifests (push) Has been cancelled

This commit is contained in:
Chaim Lev-Ari 2024-03-27 09:56:00 +02:00 committed by GitHub
parent 4ca6292805
commit d336a14e50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 1406 additions and 148 deletions

View file

@ -1,24 +1,39 @@
import { createContext, PropsWithChildren, useContext } from 'react';
import clsx from 'clsx';
import { createContext, PropsWithChildren, Ref, useContext } from 'react';
const Context = createContext<null | boolean>(null);
Context.displayName = 'WidgetContext';
export function useWidgetContext() {
const context = useContext(Context);
if (context == null) {
throw new Error('Should be inside a Widget component');
}
}
export function Widget({
children,
className,
mRef,
id,
'aria-label': ariaLabel,
}: PropsWithChildren<{
className?: string;
mRef?: Ref<HTMLDivElement>;
id?: string;
'aria-label'?: string;
}>) {
return (
<Context.Provider value>
<div id={id} className="widget">
<section
id={id}
className={clsx('widget', className)}
ref={mRef}
aria-label={ariaLabel}
>
{children}
</div>
</section>
</Context.Provider>
);
}

View file

@ -24,11 +24,11 @@ export function TableContainer({
return (
<div className="row">
<div className="col-sm-12">
<section className="datatable" aria-label={ariaLabel}>
<Widget>
<div className="datatable">
<Widget aria-label={ariaLabel}>
<WidgetBody className="no-padding">{children}</WidgetBody>
</Widget>
</section>
</div>
</div>
</div>
);

View file

@ -13,7 +13,7 @@ interface Props extends HTMLProps<HTMLInputElement> {
indeterminate?: boolean;
title?: string;
label?: string;
id: string;
id?: string;
className?: string;
role?: string;
onChange?: ChangeEventHandler<HTMLInputElement>;
@ -51,7 +51,7 @@ export const Checkbox = forwardRef<HTMLInputElement, Props>(
}, [resolvedRef, indeterminate]);
return (
<div className="md-checkbox flex" title={title || label}>
<div className="md-checkbox flex items-center" title={title || label}>
<input
id={id}
type="checkbox"
@ -61,7 +61,7 @@ export const Checkbox = forwardRef<HTMLInputElement, Props>(
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
<label htmlFor={id} className={clsx({ '!font-normal': !bold })}>
<label htmlFor={id} className={clsx('m-0', { '!font-normal': !bold })}>
{label}
</label>
</div>

View file

@ -9,6 +9,10 @@ interface Props {
}
export function FormError({ children, className }: PropsWithChildren<Props>) {
if (!children) {
return null;
}
return (
<div
className={clsx(

View file

@ -106,6 +106,21 @@ export function InputList<T = DefaultType>({
const initialItemsCount = useRef(value.length);
const isAddButtonVisible = !(isAddButtonHidden || readOnly);
const isDeleteButtonVisible = !(isDeleteButtonHidden || readOnly);
const {
handleMoveUp,
handleMoveDown,
handleRemoveItem,
handleAdd,
handleChangeItem,
toggleNeedsDeletion,
} = useInputList<T>({
value,
onChange,
itemBuilder,
itemKeyGetter,
movable,
});
return (
<div className="form-group" aria-label={ariaLabel || label}>
{label && (
@ -187,7 +202,7 @@ export function InputList<T = DefaultType>({
itemIndex={index}
initialItemsCount={initialItemsCount.current}
handleRemoveItem={handleRemoveItem}
handleToggleNeedsDeletion={handleToggleNeedsDeletion}
handleToggleNeedsDeletion={toggleNeedsDeletion}
dataCy={`${deleteButtonDataCy}_${index}`}
/>
)}
@ -223,7 +238,21 @@ export function InputList<T = DefaultType>({
)}
</div>
);
}
export function useInputList<T = DefaultType>({
value,
onChange,
itemBuilder = defaultItemBuilder as unknown as () => T,
itemKeyGetter = (item: T, index: number) => index,
movable = false,
}: {
value: T[];
onChange(value: T[], e: OnChangeEvent<T>): void;
itemBuilder?(): T;
itemKeyGetter?(item: T, index: number): Key;
movable?: boolean;
}) {
function handleMoveUp(index: number) {
if (index <= 0) {
return;
@ -260,7 +289,7 @@ export function InputList<T = DefaultType>({
);
}
function handleToggleNeedsDeletion(key: Key, item: CanUndoDeleteItem<T>) {
function toggleNeedsDeletion(key: Key, item: CanUndoDeleteItem<T>) {
handleChangeItem(key, { ...item, needsDeletion: !item.needsDeletion });
}
@ -282,6 +311,15 @@ export function InputList<T = DefaultType>({
item: newItemValue,
});
}
return {
handleMoveUp,
handleMoveDown,
handleRemoveItem,
handleAdd,
handleChangeItem,
toggleNeedsDeletion,
};
}
function defaultItemBuilder(): DefaultType {