From 1fcb3df02f7384667a74cd0886086a2fd1bb3855 Mon Sep 17 00:00:00 2001 From: Wroud Date: Wed, 1 Sep 2021 13:47:46 +0300 Subject: [PATCH] refactor: CB-971 dialog styles --- .../SessionExpiredDialog.tsx | 6 +- .../SessionExpireWarningDialog.tsx | 6 +- .../ConnectionAuthenticationDialog.tsx | 5 +- .../DatabaseAuthDialog/DatabaseAuthDialog.tsx | 5 +- .../CommonDialog/CommonDialogWrapper.tsx | 6 +- .../src/CommonDialog/CommonDialog/styles.ts | 59 +++++++-- .../src/CommonDialog/ConfirmationDialog.tsx | 4 +- .../src/CommonDialog/DialogsPortal.tsx | 119 +++++++++--------- .../core-dialogs/src/CommonDialog/styles.ts | 11 +- .../ErrorDetailsDialog/ErrorDetailsDialog.tsx | 1 + .../ErrorDetailsDialog/styles.ts | 3 +- .../src/Dialog/AuthDialog.tsx | 7 +- .../ChangeUserPasswordDialog.tsx | 4 +- .../DriverSelectorDialog.tsx | 6 +- .../src/ConnectionDialog/ConnectionDialog.tsx | 8 +- .../src/Dialog/ProcessorConfigureDialog.tsx | 6 +- .../src/Dialog/ProcessorSelectDialog.tsx | 6 +- .../FilterCustomValueDialog.tsx | 4 +- .../src/ScriptPreview/ScriptPreviewDialog.tsx | 5 +- .../plugin-product/src/ProductInfoDialog.tsx | 4 +- 20 files changed, 144 insertions(+), 131 deletions(-) diff --git a/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx b/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx index 17e400fc10..840668d049 100644 --- a/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx +++ b/webapp/packages/core-app/src/shared/SessionExpireDialog/SessionExpiredDialog.tsx @@ -16,10 +16,6 @@ import { useTranslate } from '@cloudbeaver/core-localization'; import { useStyles } from '@cloudbeaver/core-theming'; const styles = css` - CommonDialogWrapper { - width: 400px; - min-width: auto; - } controls { display: flex; flex: 1; @@ -42,6 +38,7 @@ export const SessionExpiredDialog: DialogComponent = observer(functi return styled(useStyles(styles))( @@ -54,6 +51,7 @@ export const SessionExpiredDialog: DialogComponent = observer(functi )} + fixedSize noOverflow onReject={rejectDialog} > diff --git a/webapp/packages/core-app/src/shared/SessionExpireWarningDialog/SessionExpireWarningDialog.tsx b/webapp/packages/core-app/src/shared/SessionExpireWarningDialog/SessionExpireWarningDialog.tsx index 2cd4b952c5..6d0b65b5d5 100644 --- a/webapp/packages/core-app/src/shared/SessionExpireWarningDialog/SessionExpireWarningDialog.tsx +++ b/webapp/packages/core-app/src/shared/SessionExpireWarningDialog/SessionExpireWarningDialog.tsx @@ -15,10 +15,6 @@ import { useTranslate } from '@cloudbeaver/core-localization'; import { useStyles } from '@cloudbeaver/core-theming'; const styles = css` - CommonDialogWrapper { - width: 400px; - min-width: auto; - } controls { display: flex; flex: 1; @@ -39,6 +35,7 @@ export const SessionExpireWarningDialog: DialogComponent = observer( return styled(useStyles(styles))( @@ -51,6 +48,7 @@ export const SessionExpireWarningDialog: DialogComponent = observer( )} + fixedSize noOverflow onReject={rejectDialog} > diff --git a/webapp/packages/core-connections/src/ConnectionAuthentication/ConnectionAuthenticationDialog.tsx b/webapp/packages/core-connections/src/ConnectionAuthentication/ConnectionAuthenticationDialog.tsx index 194f3acd7d..47c01b4d4a 100644 --- a/webapp/packages/core-connections/src/ConnectionAuthentication/ConnectionAuthenticationDialog.tsx +++ b/webapp/packages/core-connections/src/ConnectionAuthentication/ConnectionAuthenticationDialog.tsx @@ -19,10 +19,6 @@ import { useDBDriver } from '../useDBDriver'; import { ConnectionAuthenticationForm } from './ConnectionAuthenticationForm'; const styles = css` - CommonDialogWrapper { - min-height: 400px; - min-width: 500px; - } SubmittingForm { overflow: auto; margin: auto; @@ -56,6 +52,7 @@ export const ConnectionAuthenticationDialog: DialogComponent = observer return styled(useStyles(styles))( = observer(function Da return styled(useStyles(styles))( = function CommonDialogWrapper({ + size = 'medium', + fixedSize, title, subTitle, icon, @@ -41,7 +45,7 @@ export const CommonDialogWrapper: React.FC = function children, }) { return styled(useStyles(commonDialogThemeStyle, commonDialogBaseStyle))( - +
{icon && } diff --git a/webapp/packages/core-dialogs/src/CommonDialog/CommonDialog/styles.ts b/webapp/packages/core-dialogs/src/CommonDialog/CommonDialog/styles.ts index f303fb8548..450c2dcb49 100644 --- a/webapp/packages/core-dialogs/src/CommonDialog/CommonDialog/styles.ts +++ b/webapp/packages/core-dialogs/src/CommonDialog/CommonDialog/styles.ts @@ -44,12 +44,43 @@ export const commonDialogBaseStyle = composes( margin: 0; border: none; height: auto; - min-width: 748px; max-height: 100%; border-radius: 0.25rem; padding: 0px; + + &[|size=small] { + min-width: 404px; + min-height: 262px; + max-height: max(100vh - 48px, 262px); + + &[|fixedSize] { + width: 404px; + height: 262px; + } + } + &[|size=medium] { + min-width: 576px; + min-height: 374px; + max-height: max(100vh - 48px, 374px); + + &[|fixedSize] { + width: 576px; + height: 374px; + } + } + &[|size=large] { + min-width: 720px; + min-height: 468px; + max-height: max(100vh - 48px, 468px); + + &[|fixedSize] { + width: 720px; + height: 468px; + } + } } header, dialog-body, footer { + flex-shrink: 0; padding: 24px; &[|no-padding] { @@ -58,6 +89,7 @@ export const commonDialogBaseStyle = composes( } dialog-body { padding-top: 0px; + padding-right: 0px; } footer { padding-top: 0px; @@ -89,41 +121,42 @@ export const commonDialogBaseStyle = composes( } } dialog-body { - position: relative; - box-sizing: border-box; - display: flex; - flex-direction: row; flex: 1; + box-sizing: content-box; + display: flex; max-width: 748px; max-height: 100%; overflow: auto; } dialog-body-overflow-box { position: relative; + flex: 1; box-sizing: border-box; display: flex; - flex-direction: row; - flex: 1; + flex-direction: column; + overflow: auto; + padding-right: 24px; } dialog-body-content { - position: relative; flex: 1; + position: relative; display: flex; flex-direction: column; box-sizing: border-box; - overflow: auto; - padding-bottom: 24px; } dialog-body[|no-padding] + footer { padding-top: 24px; } + dialog-body[|no-padding] dialog-body-overflow-box { + padding-right: 0; + } dialog-body[|no-overflow] dialog-body-content { - padding-bottom: 0; + overflow: auto; } dialog-body-overflow { - position: absolute; - flex-shrink: 0; + position: sticky; bottom: 0; + flex-shrink: 0; width: 100%; height: 24px; pointer-events: none; diff --git a/webapp/packages/core-dialogs/src/CommonDialog/ConfirmationDialog.tsx b/webapp/packages/core-dialogs/src/CommonDialog/ConfirmationDialog.tsx index 0d00b8909b..fc65568ad2 100644 --- a/webapp/packages/core-dialogs/src/CommonDialog/ConfirmationDialog.tsx +++ b/webapp/packages/core-dialogs/src/CommonDialog/ConfirmationDialog.tsx @@ -50,7 +50,7 @@ export const ConfirmationDialog: DialogComponent = fu const { icon, title, subTitle, bigIcon, viewBox, message, confirmActionText } = payload; return styled(useStyles(commonDialogThemeStyle, commonDialogBaseStyle, style))( - +
{icon && } @@ -65,7 +65,7 @@ export const ConfirmationDialog: DialogComponent = fu {subTitle && {subTitle}}
- + diff --git a/webapp/packages/core-dialogs/src/CommonDialog/DialogsPortal.tsx b/webapp/packages/core-dialogs/src/CommonDialog/DialogsPortal.tsx index a95276c019..d26592187f 100644 --- a/webapp/packages/core-dialogs/src/CommonDialog/DialogsPortal.tsx +++ b/webapp/packages/core-dialogs/src/CommonDialog/DialogsPortal.tsx @@ -7,7 +7,7 @@ */ import { observer } from 'mobx-react-lite'; -import { useCallback, useEffect, useRef } from 'react'; +import { useEffect } from 'react'; import { Dialog, DialogBackdrop, @@ -15,6 +15,7 @@ import { } from 'reakit/Dialog'; import styled from 'reshadow'; +import { useObjectRef } from '@cloudbeaver/core-blocks'; import { useService } from '@cloudbeaver/core-di'; import { useStyles } from '@cloudbeaver/core-theming'; @@ -22,87 +23,85 @@ import { CommonDialogService, DialogInternal } from './CommonDialogService'; import { dialogStyles } from './styles'; export const DialogsPortal = observer(function DialogsPortal() { + const styles = useStyles(dialogStyles); const commonDialogService = useService(CommonDialogService); - const handleReject = useCallback( - (dialog: DialogInternal) => commonDialogService.rejectDialog(dialog.promise), - [commonDialogService] - ); - const handleResolve = useCallback( - (dialog: DialogInternal, result: any) => commonDialogService.resolveDialog(dialog.promise, result), - [commonDialogService] - ); - return ( - <> - {commonDialogService.dialogs.map((dialog, i, arr) => ( - - ))} - + let activeDialog: DialogInternal | undefined; + + if (commonDialogService.dialogs.length > 0) { + activeDialog = commonDialogService.dialogs[commonDialogService.dialogs.length - 1]; + } + + const state = useObjectRef(() => ({ + reject() { + if (this.dialog) { + commonDialogService.rejectDialog(this.dialog.promise); + } + }, + resolve(result: any) { + if (this.dialog) { + commonDialogService.resolveDialog(this.dialog.promise, result); + } + }, + backdropClick(e: React.MouseEvent) { + if (!this.dialog?.options?.persistent && e.currentTarget.isEqualNode(e.target as HTMLElement)) { + this.reject(); + } + }, + }), { + dialog: activeDialog, + }, ['reject', 'resolve', 'backdropClick']); + + return styled(styles)( + + + {commonDialogService.dialogs.map((dialog, i, arr) => ( + + ))} + + ); }); interface NestedDialogType { dialog: DialogInternal; - resolveDialog: (dialog: DialogInternal, result: any) => void; - rejectDialog: (dialog: DialogInternal) => void; + resolveDialog: (result: any) => void; + rejectDialog: () => void; visible: boolean; } -function NestedDialog({ +const NestedDialog: React.FC = function NestedDialog({ dialog, resolveDialog, rejectDialog, visible, -}: NestedDialogType) { - const lastVisibility = useRef(visible); - const dialogState = useDialogState({ visible }); +}) { + const dialogState = useDialogState({ visible: true }); const styles = useStyles(dialogStyles); useEffect(() => { - if (!dialogState.visible - && dialogState.visible !== lastVisibility.current - && !dialog.options?.persistent - ) { - rejectDialog(dialog); - } else { - lastVisibility.current = visible; - dialogState.setVisible(visible); + if (!dialogState.visible && !dialog.options?.persistent) { + rejectDialog(); } }); - const handleReject = useCallback(() => rejectDialog(dialog), [dialog, rejectDialog]); - const handleResolve = useCallback( - (result: any) => resolveDialog(dialog, result), - [dialog, resolveDialog] - ); - const DialogComponent = dialog.component; - const backdropClickHandler = (e: React.MouseEvent) => { - if (!dialog.options?.persistent && e.currentTarget.isEqualNode(e.target as HTMLElement)) { - rejectDialog(dialog); - } - }; - // TODO: place Dialog inside CommonDialogWrapper, so we can pass aria-label return styled(styles)( - <> - - - - - - + + + ); -} +}; diff --git a/webapp/packages/core-dialogs/src/CommonDialog/styles.ts b/webapp/packages/core-dialogs/src/CommonDialog/styles.ts index 489aee7be2..a3139d499b 100644 --- a/webapp/packages/core-dialogs/src/CommonDialog/styles.ts +++ b/webapp/packages/core-dialogs/src/CommonDialog/styles.ts @@ -21,15 +21,20 @@ export const dialogStyles = css` left: 0px; z-index: 999; display: flex; + overflow: auto; + } + + inner-box { + display: flex; + margin: auto; + padding: 24px; + flex-direction: column; align-items: center; - justify-content: center; } Dialog { box-sizing: border-box; display: flex; - max-height: calc(100vh); - z-index: 999; outline: none; } `; diff --git a/webapp/packages/core-notifications/src/NotificationsItem/ErrorDetailsDialog/ErrorDetailsDialog.tsx b/webapp/packages/core-notifications/src/NotificationsItem/ErrorDetailsDialog/ErrorDetailsDialog.tsx index 2d7d410b55..b6ea253e0f 100644 --- a/webapp/packages/core-notifications/src/NotificationsItem/ErrorDetailsDialog/ErrorDetailsDialog.tsx +++ b/webapp/packages/core-notifications/src/NotificationsItem/ErrorDetailsDialog/ErrorDetailsDialog.tsx @@ -54,6 +54,7 @@ export const ErrorDetailsDialog: DialogComponent = observe return styled(useStyles(styles))( = observer(function return styled(useStyles(styles, UNDERLINE_TAB_STYLES))( = observer(function )} )} + noBodyPadding onReject={options?.persistent ? undefined : rejectDialog} > {showTabs && ( diff --git a/webapp/packages/plugin-authentication/src/UserMenu/ChangeUserPasswordDialog/ChangeUserPasswordDialog.tsx b/webapp/packages/plugin-authentication/src/UserMenu/ChangeUserPasswordDialog/ChangeUserPasswordDialog.tsx index 0a67f499f3..44eedc90de 100644 --- a/webapp/packages/plugin-authentication/src/UserMenu/ChangeUserPasswordDialog/ChangeUserPasswordDialog.tsx +++ b/webapp/packages/plugin-authentication/src/UserMenu/ChangeUserPasswordDialog/ChangeUserPasswordDialog.tsx @@ -29,9 +29,6 @@ const styles = composes( } `, css` - CommonDialogWrapper { - min-width: 500px; - } ErrorMessage { flex: 1; } @@ -93,6 +90,7 @@ export const ChangeUserPasswordDialog: DialogComponent = observer( return styled(style)( (function DriverSelectorDial }) { return styled(styles)( = observer(function C return styled(useStyles(styles))( = observer(function C onConnect={controller.onConnect} /> )} - noBodyPadding + noBodyPadding={controller.step === ConnectionStep.ConnectionTemplateSelect} + fixedSize noOverflow onReject={rejectDialog} > diff --git a/webapp/packages/plugin-data-export/src/Dialog/ProcessorConfigureDialog.tsx b/webapp/packages/plugin-data-export/src/Dialog/ProcessorConfigureDialog.tsx index 6229425d8a..d311f9a8c9 100644 --- a/webapp/packages/plugin-data-export/src/Dialog/ProcessorConfigureDialog.tsx +++ b/webapp/packages/plugin-data-export/src/Dialog/ProcessorConfigureDialog.tsx @@ -27,10 +27,6 @@ const styles = composes( } `, css` - CommonDialogWrapper { - max-height: 500px; - min-height: 500px; - } PropertiesTable { flex: 1; overflow: hidden; @@ -74,6 +70,7 @@ export const ProcessorConfigureDialog = observer(function ProcessorConfig return styled(useStyles(styles))( (function ProcessorConfig onCancel={onClose} /> )} + fixedSize noOverflow noBodyPadding onReject={onClose} diff --git a/webapp/packages/plugin-data-export/src/Dialog/ProcessorSelectDialog.tsx b/webapp/packages/plugin-data-export/src/Dialog/ProcessorSelectDialog.tsx index f2a220cba4..075e2d7a3e 100644 --- a/webapp/packages/plugin-data-export/src/Dialog/ProcessorSelectDialog.tsx +++ b/webapp/packages/plugin-data-export/src/Dialog/ProcessorSelectDialog.tsx @@ -19,10 +19,6 @@ import type { IExportContext } from '../IExportContext'; import { ExportProcessorList } from './ExportProcessorList/ExportProcessorList'; const styles = css` - CommonDialogWrapper { - max-height: 500px; - min-height: 500px; - } ExportProcessorList { flex: 1; } @@ -61,7 +57,9 @@ export const ProcessorSelectDialog = observer(function ProcessorSelectDia return styled(styles)( return styled(styles)( diff --git a/webapp/packages/plugin-data-viewer/src/ScriptPreview/ScriptPreviewDialog.tsx b/webapp/packages/plugin-data-viewer/src/ScriptPreview/ScriptPreviewDialog.tsx index f5bdf2dbe0..9d4eccdd2b 100644 --- a/webapp/packages/plugin-data-viewer/src/ScriptPreview/ScriptPreviewDialog.tsx +++ b/webapp/packages/plugin-data-viewer/src/ScriptPreview/ScriptPreviewDialog.tsx @@ -22,10 +22,6 @@ import type { IDatabaseDataModel } from '../DatabaseDataModel/IDatabaseDataModel import type { IDatabaseDataResult } from '../DatabaseDataModel/IDatabaseDataResult'; const styles = css` - CommonDialogWrapper { - min-height: 400px; - min-width: 650px; - } wrapper { display: flex; align-items: center; @@ -94,6 +90,7 @@ export const ScriptPreviewDialog = observer>(funct return styled(styles)( >( return styled(styles)(