Files
cloudbeaver/webapp/packages/plugin-resource-manager-scripts/src/SaveScriptDialog.tsx
T
ffe3d45017 dbeaver/pro#5789 replace Buttons styles (#3468)
* dbeaver/pro#5789 refactor: add ButtonIcon component instead of Button.Icon

* dbeaver/pro#5789 refactor: button components across whole application to use UIKit button and UIKit variables

- Rewrite Button.css(former button.module.css) file to define button styles for better maintainability and scalability
- Added props to the Button component for Icons: 'size' and 'placement', currently used only in PropertiesTable (Add property)
- Changed button modifiers to 'variant' swapping unelevated mod to primary(default one, so mod just deleted) and outlined mod to variant secondary.
- In one case changed raised mod to danger variant (deleting a license)

* dbeaver/pro#5789 refactor: fix Button component styling and removed redundant css file

* dbeaver/pro#5789 style: clean up button formatting across multiple components

* dbeaver/pro#5789 refactor: update Tailwind CSS import to use layer directive

* dbeaver/pro#5789 refactor[kit]: add disabled state styles for buttons

* dbeaver/pro#5789 refactor: enhance button styles for disabled state

* dbeaver/pro#5789 fix button problems

* dbeaver/pro#5789 fix: change layer name from theme to base in color styles

* dbeaver/pro#5789 refactor: update button padding from 16px to 15px

* dbeaver/pro#5789 refactor: adjust button gap and update InputFiles button props

* dbeaver/pro#5789 style: center align button in SSHKeyUploader component

* dbeaver/pro#5789 fix: update button classes to use inline-flex for better alignment

* dbeaver/pro#5789 fix: remove initial background from tab styles

* dbeaver/pro#5789 fix: move cursor pointer rule to button container

* dbeaver/pro#5789 fix: update checkbox SVG fill property for proper rendering

* dbeaver/pro#5789 fix: add variant prop to Button component for styling options

* dbeaver/pro#5789 fix: add InlineEditor to CSS layer to compete with theme Important! border-color

* dbeaver/pro#5789 fix: add min-width to button styles for consistency

* dbeaver/pro#5789 refactor: adjust margin for trigger element in context menu

first of all it's done to fix autotests and the second reason is to visually balance the cell with menu

* dbeaver/pro#5789 fix: make boolean great again

---------

Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com>
2025-05-27 16:59:01 +08:00

139 lines
4.0 KiB
TypeScript

/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { action, observable } from 'mobx';
import { observer } from 'mobx-react-lite';
import {
Button,
CommonDialogBody,
CommonDialogFooter,
CommonDialogHeader,
CommonDialogWrapper,
Container,
Fill,
Form,
InputField,
Translate,
useFocus,
useObservableRef,
useTranslate,
} from '@cloudbeaver/core-blocks';
import type { DialogComponent } from '@cloudbeaver/core-dialogs';
import { ProjectSelect } from '@cloudbeaver/plugin-projects';
export interface ISaveScriptDialogResult {
name: string;
projectId: string | null;
}
interface Payload {
defaultScriptName?: string;
projectId?: string | null;
validation?: (result: ISaveScriptDialogResult, setMessage: (message: string) => void) => Promise<boolean> | boolean;
}
interface State extends ISaveScriptDialogResult {
message: string | null;
valid: boolean;
validate: () => Promise<void>;
submit: () => Promise<void>;
}
export const SaveScriptDialog: DialogComponent<Payload, ISaveScriptDialogResult> = observer(function SaveScriptDialog({
payload,
resolveDialog,
rejectDialog,
className,
}) {
const translate = useTranslate();
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
const state = useObservableRef<State>(
() => ({
name: payload.defaultScriptName ?? '',
projectId: payload.projectId ?? null,
message: null,
valid: true,
async validate() {
this.message = null;
let valid: boolean | undefined;
try {
valid = await payload.validation?.({ name: this.name, projectId: this.projectId }, (message: string) => {
this.message = message;
});
} catch {}
this.valid = valid ?? true;
},
async submit() {
await this.validate();
if (state.valid) {
resolveDialog(this);
}
},
}),
{
name: observable.ref,
projectId: observable.ref,
message: observable.ref,
valid: observable.ref,
submit: action.bound,
validate: action.bound,
},
false,
);
const errorMessage = state.valid ? ' ' : translate(state.message ?? 'ui_rename_taken_or_invalid');
return (
<CommonDialogWrapper size="small" className={className} fixedWidth>
<CommonDialogHeader title={translate('plugin_resource_manager_scripts_save_script')} icon="/icons/sql_script_m.svg" onReject={rejectDialog} />
<CommonDialogBody>
<Form ref={focusedRef} onSubmit={state.submit}>
<Container center gap>
<ProjectSelect
value={state.projectId}
filter={p => p.canEditResources && p.id === (payload.projectId ?? p.id)}
descriptionGetter={(_, options) =>
options.length <= 1 ? translate('plugin_resource_manager_scripts_save_script_project_restriction_descripion') : undefined
}
autoHide
onChange={projectId => {
state.projectId = projectId;
state.validate();
}}
/>
<InputField
name="name"
state={state}
error={!state.valid}
readOnly={state.projectId === null}
description={errorMessage}
onChange={state.validate}
>
{translate('ui_name')}
</InputField>
</Container>
</Form>
</CommonDialogBody>
<CommonDialogFooter>
<Button type="button" variant="secondary" onClick={rejectDialog}>
<Translate token="ui_processing_cancel" />
</Button>
<Fill />
<Button type="button" disabled={!state.valid} onClick={state.submit}>
<Translate token="ui_processing_save" />
</Button>
</CommonDialogFooter>
</CommonDialogWrapper>
);
});