mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
feat(system): path to upgrade standalone to BE [EE-4071] (#8095)
This commit is contained in:
parent
756ac034ec
commit
5cbf52377d
73 changed files with 1374 additions and 421 deletions
22
app/react/components/modals/Modal/CloseButton.module.css
Normal file
22
app/react/components/modals/Modal/CloseButton.module.css
Normal file
|
@ -0,0 +1,22 @@
|
|||
.close {
|
||||
color: var(--button-close-color);
|
||||
opacity: var(--button-opacity);
|
||||
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
|
||||
font-size: 21px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
filter: alpha(opacity=20);
|
||||
}
|
||||
|
||||
.close:hover,
|
||||
.close:focus {
|
||||
color: var(--button-close-color);
|
||||
opacity: var(--button-opacity-hover);
|
||||
}
|
21
app/react/components/modals/Modal/CloseButton.tsx
Normal file
21
app/react/components/modals/Modal/CloseButton.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import styles from './CloseButton.module.css';
|
||||
|
||||
export function CloseButton({
|
||||
onClose,
|
||||
className,
|
||||
}: {
|
||||
onClose: () => void;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(styles.close, className, 'absolute top-2 right-2')}
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
);
|
||||
}
|
20
app/react/components/modals/Modal/Modal.module.css
Normal file
20
app/react/components/modals/Modal/Modal.module.css
Normal file
|
@ -0,0 +1,20 @@
|
|||
.modal-dialog {
|
||||
width: 450px;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--bg-modal-content-color);
|
||||
padding: 20px;
|
||||
|
||||
position: relative;
|
||||
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
|
||||
outline: 0;
|
||||
|
||||
box-shadow: 0 5px 15px rgb(0 0 0 / 50%);
|
||||
}
|
53
app/react/components/modals/Modal/Modal.tsx
Normal file
53
app/react/components/modals/Modal/Modal.tsx
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { DialogContent, DialogOverlay } from '@reach/dialog';
|
||||
import clsx from 'clsx';
|
||||
import { createContext, PropsWithChildren, useContext } from 'react';
|
||||
|
||||
import { CloseButton } from './CloseButton';
|
||||
import styles from './Modal.module.css';
|
||||
|
||||
const Context = createContext<boolean | null>(null);
|
||||
Context.displayName = 'ModalContext';
|
||||
|
||||
export function useModalContext() {
|
||||
const context = useContext(Context);
|
||||
if (!context) {
|
||||
throw new Error('should be nested under Modal');
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
onDismiss?(): void;
|
||||
'aria-label'?: string;
|
||||
'aria-labelledby'?: string;
|
||||
}
|
||||
|
||||
export function Modal({
|
||||
children,
|
||||
onDismiss,
|
||||
'aria-label': ariaLabel,
|
||||
'aria-labelledby': ariaLabelledBy,
|
||||
}: PropsWithChildren<Props>) {
|
||||
return (
|
||||
<Context.Provider value>
|
||||
<DialogOverlay
|
||||
isOpen
|
||||
className="flex items-center justify-center z-50"
|
||||
onDismiss={onDismiss}
|
||||
role="dialog"
|
||||
>
|
||||
<DialogContent
|
||||
aria-label={ariaLabel}
|
||||
aria-labelledby={ariaLabelledBy}
|
||||
className={clsx(styles.modalDialog, 'p-0 bg-transparent')}
|
||||
>
|
||||
<div className={clsx(styles.modalContent, 'relative')}>
|
||||
{children}
|
||||
{onDismiss && <CloseButton onClose={onDismiss} />}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
</Context.Provider>
|
||||
);
|
||||
}
|
4
app/react/components/modals/Modal/ModalBody.module.css
Normal file
4
app/react/components/modals/Modal/ModalBody.module.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
.modal-body {
|
||||
padding: 10px 0px;
|
||||
border-bottom: none;
|
||||
}
|
9
app/react/components/modals/Modal/ModalBody.tsx
Normal file
9
app/react/components/modals/Modal/ModalBody.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { useModalContext } from './Modal';
|
||||
import styles from './ModalBody.module.css';
|
||||
|
||||
export function ModalBody({ children }: PropsWithChildren<unknown>) {
|
||||
useModalContext();
|
||||
return <div className={styles.modalBody}>{children}</div>;
|
||||
}
|
5
app/react/components/modals/Modal/ModalFooter.module.css
Normal file
5
app/react/components/modals/Modal/ModalFooter.module.css
Normal file
|
@ -0,0 +1,5 @@
|
|||
.modal-footer {
|
||||
padding: 10px 0px;
|
||||
border-top: none;
|
||||
display: flex;
|
||||
}
|
15
app/react/components/modals/Modal/ModalFooter.tsx
Normal file
15
app/react/components/modals/Modal/ModalFooter.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import clsx from 'clsx';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { useModalContext } from './Modal';
|
||||
import styles from './ModalFooter.module.css';
|
||||
|
||||
export function ModalFooter({ children }: PropsWithChildren<unknown>) {
|
||||
useModalContext();
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.modalFooter, 'flex justify-end')}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
19
app/react/components/modals/Modal/ModalHeader.module.css
Normal file
19
app/react/components/modals/Modal/ModalHeader.module.css
Normal file
|
@ -0,0 +1,19 @@
|
|||
.modal-header {
|
||||
margin-bottom: 10px;
|
||||
padding: 0px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.background-error {
|
||||
padding-top: 55px;
|
||||
background-image: url(~assets/images/icon-error.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top left;
|
||||
}
|
||||
|
||||
.background-warning {
|
||||
padding-top: 55px;
|
||||
background-image: url(~assets/images/icon-warning.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top left;
|
||||
}
|
33
app/react/components/modals/Modal/ModalHeader.tsx
Normal file
33
app/react/components/modals/Modal/ModalHeader.tsx
Normal file
|
@ -0,0 +1,33 @@
|
|||
import clsx from 'clsx';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { ModalType } from './types';
|
||||
import { useModalContext } from './Modal';
|
||||
import styles from './ModalHeader.module.css';
|
||||
|
||||
interface Props {
|
||||
title: ReactNode;
|
||||
modalType?: ModalType;
|
||||
}
|
||||
|
||||
export function ModalHeader({ title, modalType }: Props) {
|
||||
useModalContext();
|
||||
|
||||
return (
|
||||
<div className={styles.modalHeader}>
|
||||
{modalType && (
|
||||
<div
|
||||
className={clsx({
|
||||
[styles.backgroundError]: modalType === ModalType.Destructive,
|
||||
[styles.backgroundWarning]: modalType === ModalType.Warn,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{typeof title === 'string' ? (
|
||||
<h5 className="font-bold">{title}</h5>
|
||||
) : (
|
||||
title
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
18
app/react/components/modals/Modal/index.tsx
Normal file
18
app/react/components/modals/Modal/index.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Modal as MainComponent } from './Modal';
|
||||
import { ModalHeader } from './ModalHeader';
|
||||
import { ModalBody } from './ModalBody';
|
||||
import { ModalFooter } from './ModalFooter';
|
||||
|
||||
interface WithSubComponents {
|
||||
Header: typeof ModalHeader;
|
||||
Body: typeof ModalBody;
|
||||
Footer: typeof ModalFooter;
|
||||
}
|
||||
|
||||
const Modal = MainComponent as typeof MainComponent & WithSubComponents;
|
||||
|
||||
Modal.Header = ModalHeader;
|
||||
Modal.Body = ModalBody;
|
||||
Modal.Footer = ModalFooter;
|
||||
|
||||
export { Modal };
|
6
app/react/components/modals/Modal/types.ts
Normal file
6
app/react/components/modals/Modal/types.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export type OnSubmit<TResult> = (result?: TResult) => void;
|
||||
|
||||
export enum ModalType {
|
||||
Warn = 'warning',
|
||||
Destructive = 'error',
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue