Cb 3584 migrate containers to css modules (#1834)

* CB-3584 migrate containers, migrate form controls to css modules

* CB-3584 remove old container styles, fix layout props, fix styles

* CB-3584: Fix properties table filter style

* CB-3584 fix styles

* CB-3584 fix styles

* CB-3584 fix sizing styles

---------

Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
Tatiana Fokina
2023-07-27 13:24:47 +03:00
committed by GitHub
co-authored by mr-anton-t
parent 8fba6107b2
commit e33eb9fd60
118 changed files with 1031 additions and 1129 deletions
@@ -1,247 +0,0 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 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 { css } from 'reshadow';
export const BASE_CONTAINERS_STYLES = css`
Group {
composes: theme-background-surface theme-text-on-surface from global;
}
ColoredContainer {
composes: theme-background-secondary theme-text-on-secondary from global;
}
GroupSubTitle {
composes: theme-text-text-hint-on-light from global;
}
Container,
ColoredContainer,
Group {
display: flex;
flex-direction: row;
align-content: baseline;
position: relative;
box-sizing: border-box;
&[hideEmpty]:empty {
display: none;
}
&[vertical] {
flex-direction: column;
align-content: stretch;
& > :global(*) {
flex-basis: 0 !important;
}
& > [keepSize] {
flex-basis: auto !important;
}
}
&[baseline] {
align-items: baseline;
}
&[flexStart] {
align-items: flex-start;
}
&[flexEnd] {
align-items: flex-end;
}
&[center] {
align-items: center;
justify-content: center;
align-content: center;
}
&[wrap] {
flex-wrap: wrap;
}
&[overflow] {
overflow: auto;
}
&[parent] {
padding: 24px;
&[compact] {
padding: 16px;
}
&[dense] {
padding: 8px;
}
}
&[gap] {
gap: 24px;
&[compact] {
gap: 16px;
}
&[dense] {
gap: 8px;
}
}
}
Group {
align-content: baseline;
box-sizing: border-box;
padding: 24px;
border-radius: var(--theme-group-element-radius);
&[dense] {
padding: 8px;
}
&[form] > :global(*) {
margin-right: 25%;
}
&[box] {
padding: 0;
overflow: hidden;
}
&[box='no-overflow'] {
padding: 0;
overflow: initial;
}
&[center] {
margin: 0 auto;
}
}
Container,
ColoredContainer,
Group {
&[grid] {
display: grid;
}
/* increase css specificity */
&[grid]:nth-child(n) {
flex-basis: unset;
max-width: unset;
}
&[grid][tiny] {
grid-template-columns: repeat(auto-fit, minmax(140px, max-content));
}
&[grid][small] {
grid-template-columns: repeat(auto-fit, minmax(260px, max-content));
}
&[grid][medium] {
grid-template-columns: repeat(auto-fit, minmax(460px, max-content));
}
&[grid][large] {
grid-template-columns: repeat(auto-fit, minmax(800px, max-content));
}
}
Container,
ColoredContainer,
Group {
flex-wrap: wrap;
flex: 1 1 100%;
& > :global(*) {
flex: 1 1 100%;
}
&[noWrap] {
flex-wrap: nowrap;
}
&[keepSize],
& > [keepSize] {
flex-grow: 0;
flex-basis: 0;
flex-basis: auto; /* test for layout */
}
&[tiny],
& > [tiny],
&[grid][tiny] > * {
flex-basis: 140px;
max-width: 210px;
}
&[small],
& > [small],
&[grid][small] > * {
flex-basis: 260px;
max-width: 390px;
}
&[medium],
& > [medium],
&[grid][medium] > * {
flex-basis: 460px;
max-width: 640px;
}
&[large],
& > [large],
&[grid][large] > * {
flex-basis: 800px;
max-width: 800px;
}
&[maximum],
& > [maximum],
&[grid][maximum] > * {
max-width: 100%;
}
&[fill],
& > [fill] {
max-width: none;
}
}
GroupItem {
min-width: min-content;
}
GroupTitle {
composes: theme-typography--body2 from global;
font-weight: 400;
margin: 0;
text-transform: uppercase;
opacity: 0.9;
}
Group[box] > GroupTitle {
padding: 24px;
}
GroupSubTitle {
composes: theme-typography--caption from global;
display: block;
text-transform: none;
}
GroupClose {
width: 18px;
height: 18px;
cursor: pointer;
display: flex;
position: absolute;
right: 24px;
margin-right: 0 !important;
}
`;
@@ -0,0 +1,3 @@
.coloredContainer {
composes: theme-background-secondary theme-text-on-secondary from global;
}
@@ -7,14 +7,21 @@
*/
import { forwardRef } from 'react';
import { filterContainerFakeProps } from './filterContainerFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import coloredContainerStyles from './ColoredContainer.m.css';
import containerStyles from './Container.m.css';
import { filterContainerFakeProps, getContainerProps } from './filterContainerFakeProps';
import type { IContainerProps } from './IContainerProps';
import elementsSizeStyles from './shared/ElementsSize.m.css';
export const ColoredContainer = forwardRef<HTMLDivElement, IContainerProps & React.HTMLAttributes<HTMLDivElement>>(function ColoredContainer(
props,
{ className, ...rest },
ref,
) {
const divProps = filterContainerFakeProps(props);
const styles = useS(coloredContainerStyles, containerStyles, elementsSizeStyles);
const divProps = filterContainerFakeProps(rest);
const containerProps = getContainerProps(rest);
return <div ref={ref} {...divProps} />;
return <div ref={ref} {...divProps} className={s(styles, { coloredContainer: true, container: true, ...containerProps }, className)} />;
});
@@ -0,0 +1,109 @@
.container {
display: flex;
flex-direction: row;
align-content: baseline;
position: relative;
flex-wrap: wrap;
flex: 1 1 100%;
&.hideEmpty:empty {
display: none;
}
&.vertical {
flex-direction: column;
align-content: stretch;
& > * {
flex-basis: 0 !important;
}
& > .keepSize {
flex-basis: auto !important;
}
}
&.baseline {
align-items: baseline;
}
&.flexStart {
align-items: flex-start;
}
&.flexEnd {
align-items: flex-end;
}
&.center {
align-items: center;
justify-content: center;
align-content: center;
}
&.wrap {
flex-wrap: wrap;
}
&.overflow {
overflow: auto;
}
&.parent {
padding: 24px;
&.compact {
padding: 16px;
}
&.dense {
padding: 8px;
}
}
&.gap {
gap: 24px;
&.compact {
gap: 16px;
}
&.dense {
gap: 8px;
}
}
&.grid {
display: grid;
&.tiny {
grid-template-columns: repeat(auto-fit, minmax(140px, max-content));
}
&.small {
grid-template-columns: repeat(auto-fit, minmax(260px, max-content));
}
&.medium {
grid-template-columns: repeat(auto-fit, minmax(460px, max-content));
}
&.large {
grid-template-columns: repeat(auto-fit, minmax(800px, max-content));
}
/* increase css specificity */
&:nth-child(n) {
flex-basis: unset;
max-width: unset;
}
}
& > * {
flex: 1 1 100%;
}
&.noWrap {
flex-wrap: nowrap;
}
}
@@ -7,11 +7,33 @@
*/
import { forwardRef } from 'react';
import { filterContainerFakeProps } from './filterContainerFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import style from './Container.m.css';
import { filterContainerFakeProps, getContainerProps } from './filterContainerFakeProps';
import type { IContainerProps } from './IContainerProps';
import elementsSizeStyle from './shared/ElementsSize.m.css';
export const Container = forwardRef<HTMLDivElement, IContainerProps & React.HTMLAttributes<HTMLDivElement>>(function Container(props, ref) {
const divProps = filterContainerFakeProps(props);
export const Container = forwardRef<HTMLDivElement, IContainerProps & React.HTMLAttributes<HTMLDivElement>>(function Container(
{ className, ...rest },
ref,
) {
const styles = useS(style, elementsSizeStyle);
const divProps = filterContainerFakeProps(rest);
const containerProps = getContainerProps(rest);
return <div ref={ref} {...divProps} />;
return (
<div
ref={ref}
{...divProps}
className={s(
styles,
{
container: true,
...containerProps,
},
className,
)}
/>
);
});
@@ -0,0 +1,34 @@
.group {
composes: theme-background-surface theme-text-on-surface from global;
align-content: baseline;
box-sizing: border-box;
padding: 24px;
border-radius: var(--theme-group-element-radius);
&.dense {
padding: 8px;
}
&.form > * {
margin-right: 25%;
}
&.box {
padding: 0;
overflow: hidden;
> .groupTitle {
padding: 24px;
}
}
&.boxNoOverflow {
padding: 0;
overflow: initial;
}
&.center {
margin: 0 auto;
}
}
@@ -7,17 +7,46 @@
*/
import { forwardRef } from 'react';
import { filterContainerFakeProps } from './filterContainerFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import containerStyles from './Container.m.css';
import { filterContainerFakeProps, getContainerProps } from './filterContainerFakeProps';
import style from './Group.m.css';
import type { IContainerProps } from './IContainerProps';
import elementsSizeStyles from './shared/ElementsSize.m.css';
interface Props extends IContainerProps {
form?: boolean;
center?: boolean;
box?: boolean | 'no-overflow';
box?: boolean;
boxNoOverflow?: boolean;
}
export const Group = forwardRef<HTMLDivElement, Props & React.HTMLAttributes<HTMLDivElement>>(function Group({ form, center, box, ...rest }, ref) {
export const Group = forwardRef<HTMLDivElement, Props & React.HTMLAttributes<HTMLDivElement>>(function Group(
{ form, center, box, boxNoOverflow, className, ...rest },
ref,
) {
const styles = useS(style, containerStyles, elementsSizeStyles);
const divProps = filterContainerFakeProps(rest);
const containerProps = getContainerProps(rest);
return <div ref={ref} {...divProps} />;
return (
<div
ref={ref}
{...divProps}
className={s(
styles,
{
group: true,
container: true,
form,
center,
boxNoOverflow,
box,
...containerProps,
},
className,
)}
/>
);
});
@@ -0,0 +1,9 @@
.groupClose {
width: 18px;
height: 18px;
cursor: pointer;
display: flex;
position: absolute;
right: 24px;
margin-right: 0 !important;
}
@@ -6,14 +6,18 @@
* you may not use this file except in compliance with the License.
*/
import { Icon } from '../Icon';
import { s } from '../s';
import { useS } from '../useS';
import styles from './GroupClose.m.css';
interface IProps {
onClick?: () => void;
}
export const GroupClose: React.FC<IProps & React.HTMLAttributes<HTMLDivElement>> = function GroupClose({ onClick, ...rest }) {
export const GroupClose: React.FC<IProps & React.HTMLAttributes<HTMLDivElement>> = function GroupClose({ onClick, className, ...rest }) {
const style = useS(styles);
return (
<div {...rest}>
<div {...rest} className={s(style, { groupClose: true }, className)}>
<Icon name="cross" viewBox="0 0 16 16" onClick={onClick} />
</div>
);
@@ -0,0 +1,3 @@
.groupItem {
min-width: min-content;
}
@@ -5,10 +5,15 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { filterLayoutFakeProps } from './filterLayoutFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import { filterLayoutFakeProps, getLayoutProps } from './filterLayoutFakeProps';
import styles from './GroupItem.m.css';
import type { ILayoutSizeProps } from './ILayoutSizeProps';
export const GroupItem: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLDivElement>> = function GroupItem(props) {
const divProps = filterLayoutFakeProps(props);
return <div {...divProps} />;
export const GroupItem: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLDivElement>> = function GroupItem({ className, ...rest }) {
const style = useS(styles);
const divProps = filterLayoutFakeProps(rest);
const layoutProps = getLayoutProps(rest);
return <div {...divProps} className={s(style, { groupItem: true, ...layoutProps }, className)} />;
};
@@ -0,0 +1,7 @@
.groupSubTitle {
composes: theme-text-text-hint-on-light from global;
composes: theme-typography--caption from global;
display: block;
text-transform: none;
}
@@ -5,10 +5,15 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { filterLayoutFakeProps } from './filterLayoutFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import { filterLayoutFakeProps, getLayoutProps } from './filterLayoutFakeProps';
import styles from './GroupSubTitle.m.css';
import type { ILayoutSizeProps } from './ILayoutSizeProps';
export const GroupSubTitle: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLHeadingElement>> = function GroupSubTitle(props) {
const divProps = filterLayoutFakeProps(props);
return <span {...divProps} />;
export const GroupSubTitle: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLHeadingElement>> = function GroupSubTitle({ className, ...rest }) {
const style = useS(styles);
const divProps = filterLayoutFakeProps(rest);
const layoutProps = getLayoutProps(rest);
return <span {...divProps} className={s(style, { groupSubTitle: true, ...layoutProps }, className)} />;
};
@@ -0,0 +1,8 @@
.groupTitle {
composes: theme-typography--body2 from global;
composes: groupTitle from './Group.m.css';
font-weight: 400;
margin: 0;
text-transform: uppercase;
opacity: 0.9;
}
@@ -5,10 +5,16 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { filterLayoutFakeProps } from './filterLayoutFakeProps';
import { s } from '../s';
import { useS } from '../useS';
import { filterLayoutFakeProps, getLayoutProps } from './filterLayoutFakeProps';
import styles from './GroupTitle.m.css';
import type { ILayoutSizeProps } from './ILayoutSizeProps';
import elementsSizeStyles from './shared/ElementsSize.m.css';
export const GroupTitle: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLHeadingElement>> = function GroupTitle(props) {
const divProps = filterLayoutFakeProps(props);
return <h2 {...divProps} />;
export const GroupTitle: React.FC<ILayoutSizeProps & React.HTMLAttributes<HTMLHeadingElement>> = function GroupTitle({ className, ...rest }) {
const style = useS(styles, elementsSizeStyles);
const divProps = filterLayoutFakeProps(rest);
const layoutProps = getLayoutProps(rest);
return <h2 {...divProps} className={s(style, { groupTitle: true, ...layoutProps }, className)} />;
};
@@ -5,7 +5,7 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { filterLayoutFakeProps } from './filterLayoutFakeProps';
import { filterLayoutFakeProps, getLayoutProps } from './filterLayoutFakeProps';
import type { IContainerProps } from './IContainerProps';
export function filterContainerFakeProps<T extends IContainerProps>(props: T): Omit<T, keyof IContainerProps> {
@@ -14,3 +14,8 @@ export function filterContainerFakeProps<T extends IContainerProps>(props: T): O
return rest as Omit<T, keyof IContainerProps>;
}
export function getContainerProps<T extends IContainerProps>(props: T): IContainerProps {
const { hideEmpty, flexStart, flexEnd, baseline, center, vertical, wrap, overflow, parent, gap, grid, dense, compact, ...rest } = props;
return { hideEmpty, flexStart, flexEnd, baseline, center, vertical, wrap, overflow, parent, gap, grid, dense, compact, ...getLayoutProps(props) };
}
@@ -12,3 +12,8 @@ export function filterLayoutFakeProps<T extends ILayoutSizeProps>(props: T): Omi
return rest;
}
export function getLayoutProps<T extends ILayoutSizeProps>(props: T): ILayoutSizeProps {
const { noWrap, keepSize, tiny, small, medium, large, maximum, fill } = props;
return { noWrap, keepSize, tiny, small, medium, large, maximum, fill };
}
@@ -0,0 +1,50 @@
.tiny,
.grid.tiny > *,
.container > .tiny,
.container > .grid.tiny > * {
flex-basis: 140px;
max-width: 210px;
}
.small,
.grid.small > *,
.container > .small,
.container > .grid.small > * {
flex-basis: 260px;
max-width: 390px;
}
.medium,
.grid.medium > *,
.container > .medium,
.container > .grid.medium > * {
flex-basis: 460px;
max-width: 640px;
}
.large,
.grid.large > *,
.container > .large,
.container > .grid.large > * {
flex-basis: 800px;
max-width: 800px;
}
.maximum,
.grid.maximum > *,
.container > .maximum,
.container > .grid.maximum > * {
max-width: 100%;
}
.fill,
.container > .fill {
max-width: none;
}
.keepSize,
.container > .keepSize {
flex-grow: 0;
flex-basis: 0;
flex-basis: auto; /* test for layout */
}
@@ -0,0 +1,19 @@
.field {
display: flex;
align-items: center;
white-space: pre-wrap;
height: 32px;
& .fieldLabel {
cursor: pointer;
user-select: none;
padding-left: 10px;
line-height: 16px;
}
}
.fieldLabel {
composes: theme-typography--body2 from global;
}
.checkbox[disabled] + .fieldLabel {
cursor: auto;
}
@@ -5,52 +5,33 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import styled, { css } from 'reshadow';
import { useStyles } from '../../useStyles';
import { baseFormControlStyles, baseValidFormControlStyles } from '../baseFormControlStyles';
import { getLayoutProps } from '../../Containers/filterLayoutFakeProps';
import elementsSizeStyles from '../../Containers/shared/ElementsSize.m.css';
import { s } from '../../s';
import { useS } from '../../useS';
import formControlStyles from '../FormControl.m.css';
import { isControlPresented } from '../isControlPresented';
import { Checkbox, CheckboxBaseProps, CheckboxType, ICheckboxControlledProps, ICheckboxObjectProps } from './Checkbox';
const style = css`
field {
display: flex;
align-items: center;
white-space: pre-wrap;
height: 32px;
& field-label {
cursor: pointer;
user-select: none;
padding-left: 10px;
line-height: 16px;
}
}
field-label {
composes: theme-typography--body2 from global;
}
Checkbox[disabled] + field-label {
cursor: auto;
}
`;
import fieldCheckboxStyles from './FieldCheckbox.m.css';
export const FieldCheckbox: CheckboxType = function FieldCheckbox({
children,
className,
...rest
}: CheckboxBaseProps & (ICheckboxControlledProps | ICheckboxObjectProps<any>)) {
const styles = useStyles(baseFormControlStyles, baseValidFormControlStyles, style);
const layoutProps = getLayoutProps(rest);
const styles = useS(elementsSizeStyles, formControlStyles, fieldCheckboxStyles);
if (rest.autoHide && !isControlPresented(rest.name, rest.state)) {
return null;
}
return styled(styles)(
<field className={className}>
<Checkbox {...(rest as CheckboxBaseProps & ICheckboxControlledProps)} />
<field-label htmlFor={rest.id || rest.name} title={rest.title} as="label">
return (
<div data-testid="field" className={s(styles, { field: true, ...layoutProps }, className)}>
<Checkbox {...(rest as CheckboxBaseProps & ICheckboxControlledProps)} className={styles.checkbox} />
<label data-testid="field-label" htmlFor={rest.id || rest.name} title={rest.title} className={styles.fieldLabel}>
{children}
</field-label>
</field>,
</label>
</div>
);
};
@@ -0,0 +1,47 @@
.switchControl {
composes: theme-switch from global;
}
.disabled {
composes: theme-switch--disabled mdc-switch--disabled from global;
}
.checked {
composes: theme-switch--checked mdc-switch--checked from global;
}
.switchControlTrack {
composes: theme-switch__track from global;
}
.switchInput {
composes: theme-switch_native-control from global;
}
.switchControlUnderlay {
composes: theme-switch__thumb-underlay from global;
}
.switchControlThumb {
composes: theme-switch__thumb from global;
}
.radioRipple {
composes: theme-radio_ripple from global;
}
.switchBody {
display: flex;
align-items: center;
composes: theme-typography--body1 from global;
& .fieldLabel {
cursor: pointer;
user-select: none;
display: block;
padding-left: 18px;
min-width: 50px;
white-space: pre-wrap;
font-weight: 500;
}
}
@@ -6,82 +6,22 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { filterLayoutFakeProps } from '../../Containers/filterLayoutFakeProps';
import { useStyles } from '../../useStyles';
import { baseFormControlStyles, baseValidFormControlStyles } from '../baseFormControlStyles';
import elementsSizeStyles from '../../Containers/shared/ElementsSize.m.css';
import { s } from '../../s';
import { useS } from '../../useS';
import formControlStyles from '../FormControl.m.css';
import { isControlPresented } from '../isControlPresented';
import type { ICheckboxControlledProps, ICheckboxObjectProps } from './Checkbox';
import switchStyles from './Switch.m.css';
import denseModStyles from './SwitchDense.m.css';
import primaryModStyles from './SwitchPrimary.m.css';
import { useCheckboxState } from './useCheckboxState';
const switchStyles = css`
switch-control {
composes: theme-switch from global;
}
switch-control-track {
composes: theme-switch__track from global;
}
switch-input {
composes: theme-switch_native-control from global;
}
switch-control-underlay {
composes: theme-switch__thumb-underlay from global;
}
switch-control-thumb {
composes: theme-switch__thumb from global;
}
radio-ripple {
composes: theme-radio_ripple from global;
}
switch-body {
display: flex;
align-items: center;
}
switch-body {
composes: theme-typography--body1 from global;
}
switch-body field-label {
cursor: pointer;
user-select: none;
display: block;
padding-left: 18px;
min-width: 50px;
white-space: pre-wrap;
font-weight: 500;
}
`;
const switchMod = {
primary: css`
switch-control {
composes: theme-switch_primary from global;
}
`,
dense: css`
switch-body {
composes: theme-switch_dense from global;
}
field-label {
composes: theme-typography--body2 from global;
}
switch-body field-label {
font-weight: initial;
}
`,
};
const switchState = {
disabled: css`
switch-control {
composes: theme-switch--disabled mdc-switch--disabled from global;
}
`,
checked: css`
switch-control {
composes: theme-switch--checked mdc-switch--checked from global;
}
`,
primary: primaryModStyles,
dense: denseModStyles,
};
interface IBaseProps {
@@ -121,28 +61,20 @@ export const Switch: SwitchType = observer(function Switch({
onChange,
});
rest = filterLayoutFakeProps(rest);
const styles = useStyles(
baseFormControlStyles,
baseValidFormControlStyles,
switchStyles,
...mod.map(mod => switchMod[mod]),
disabled && switchState.disabled,
checkboxState.checked && switchState.checked,
);
const styles = useS(elementsSizeStyles, formControlStyles, switchStyles, ...mod.map(mod => switchMod[mod]));
if (autoHide && !isControlPresented(name, state)) {
return null;
}
return styled(styles)(
<field className={className} title={rest.title}>
<switch-body>
<switch-control>
<switch-control-track />
<switch-control-underlay>
<switch-control-thumb />
<switch-input
as="input"
return (
<div data-testid="field" className={s(styles, { field: true }, className)} title={rest.title}>
<div data-testid="switch-body" className={styles.switchBody}>
<div data-testid="switch-control" className={s(styles, { switchControl: true, disabled: disabled, checked: checkboxState.checked })}>
<div data-testid="switch-control-track" className={styles.switchControlTrack} />
<div data-testid="switch-control-underlay" className={styles.switchControlUnderlay}>
<div data-testid="switch-control-thumb" className={styles.switchControlThumb} />
<input
{...rest}
type="checkbox"
id={id || value || name}
@@ -150,15 +82,21 @@ export const Switch: SwitchType = observer(function Switch({
aria-checked={checkboxState.checked}
checked={checkboxState.checked}
disabled={disabled}
data-testid="switch-input"
className={styles.switchInput}
onChange={checkboxState.change}
/>
</switch-control-underlay>
</switch-control>
<field-label as="label" htmlFor={id || value || name}>
</div>
</div>
<label htmlFor={id || value || name} data-testid="field-label" className={styles.fieldLabel}>
{children}
</field-label>
</switch-body>
{description && <field-description>{description}</field-description>}
</field>,
</label>
</div>
{description && (
<div data-testid="field-description" className={styles.fieldDescription}>
{description}
</div>
)}
</div>
);
});
@@ -0,0 +1,9 @@
.switchBody {
composes: theme-switch_dense from global;
}
.fieldLabel {
composes: theme-typography--body2 from global;
}
.switchBody .fieldLabel {
font-weight: initial;
}
@@ -0,0 +1,3 @@
.switchControl {
composes: theme-switch_primary from global;
}
@@ -0,0 +1,117 @@
.field.inline {
display: flex;
align-items: center;
& .fieldLabel {
padding-right: 8px;
padding-bottom: 0;
}
}
.field .input {
margin: 0;
}
.fieldLabel {
display: block;
padding-bottom: 10px;
composes: theme-typography--body1 from global;
font-weight: 500;
}
.input {
padding-right: 24px !important;
}
.menuButton {
position: absolute;
right: 0;
background: transparent;
outline: none;
display: flex;
align-items: center;
height: 100%;
padding: 0 8px 0 0;
cursor: pointer;
&:hover,
&:focus {
opacity: 0.7;
}
}
.menuItem {
composes: theme-ripple from global;
}
.menu {
composes: theme-text-on-surface theme-background-surface theme-typography--caption theme-elevation-z3 from global;
display: flex;
flex-direction: column;
max-height: 300px;
overflow: auto;
outline: none;
z-index: 999;
border-radius: var(--theme-form-element-radius);
& .menuItem {
background: transparent;
display: flex;
flex-direction: row;
align-items: center;
padding: 8px 12px;
text-align: left;
outline: none;
color: inherit;
cursor: pointer;
gap: 8px;
& .itemIcon,
& .itemTitle {
position: relative;
}
& .itemIcon {
width: 16px;
height: 16px;
overflow: hidden;
flex-shrink: 0;
& .iconOrImage {
width: 100%;
height: 100%;
}
}
}
}
.icon {
height: 16px;
display: block;
}
.menuButton .icon.focus {
transform: rotate(180deg);
}
.inputBox {
flex: 1;
position: relative;
display: flex;
align-items: center;
& .inputIcon {
position: absolute;
left: 0;
width: 16px;
height: 16px;
margin-left: 12px;
& .iconOrImage {
width: 100%;
height: 100%;
}
&:not(:empty) + .input {
padding-left: 34px !important;
}
}
}
@@ -8,131 +8,20 @@
import { observer } from 'mobx-react-lite';
import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { Menu, MenuButton, MenuItem, useMenuState } from 'reakit/Menu';
import styled, { css, use } from 'reshadow';
import { filterLayoutFakeProps } from '../Containers/filterLayoutFakeProps';
import { filterLayoutFakeProps, getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { getComputed } from '../getComputed';
import { Icon } from '../Icon';
import { IconOrImage } from '../IconOrImage';
import { Loader } from '../Loader/Loader';
import { useTranslate } from '../localization/useTranslate';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
import { s } from '../s';
import { useS } from '../useS';
import comboboxStyles from './Combobox.m.css';
import { FormContext } from './FormContext';
const styles = css`
field[|inline] {
display: flex;
align-items: center;
& field-label {
padding-right: 8px;
padding-bottom: 0;
}
}
field input {
margin: 0;
}
field-label {
display: block;
padding-bottom: 10px;
composes: theme-typography--body1 from global;
font-weight: 500;
}
input {
padding-right: 24px !important;
}
MenuButton {
position: absolute;
right: 0;
background: transparent;
outline: none;
display: flex;
align-items: center;
height: 100%;
padding: 0 8px 0 0;
cursor: pointer;
&:hover,
&:focus {
opacity: 0.7;
}
}
MenuItem {
composes: theme-ripple from global;
}
Menu {
composes: theme-text-on-surface theme-background-surface theme-typography--caption theme-elevation-z3 from global;
display: flex;
flex-direction: column;
max-height: 300px;
overflow: auto;
outline: none;
z-index: 999;
border-radius: var(--theme-form-element-radius);
& MenuItem {
background: transparent;
display: flex;
flex-direction: row;
align-items: center;
padding: 8px 12px;
text-align: left;
outline: none;
color: inherit;
cursor: pointer;
gap: 8px;
& item-icon,
& item-title {
position: relative;
}
& item-icon {
width: 16px;
height: 16px;
overflow: hidden;
flex-shrink: 0;
& IconOrImage {
width: 100%;
height: 100%;
}
}
}
}
Icon {
height: 16px;
display: block;
}
MenuButton Icon[|focus] {
transform: rotate(180deg);
}
input-box {
flex: 1;
position: relative;
display: flex;
align-items: center;
& input-icon {
position: absolute;
left: 0;
width: 16px;
height: 16px;
margin-left: 12px;
& IconOrImage {
width: 100%;
height: 100%;
}
&:not(:empty) + input {
padding-left: 34px !important;
}
}
}
`;
import formControlStyles from './FormControl.m.css';
type BaseProps<TKey, TValue> = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onSelect' | 'name' | 'value' | 'defaultValue'> &
ILayoutSizeProps & {
@@ -198,11 +87,13 @@ export const Combobox: ComboboxType = observer(function Combobox({
onSwitch,
...rest
}: ControlledProps<any, any> | ObjectProps<any, any, any>) {
const layoutProps = getLayoutProps(rest);
rest = filterLayoutFakeProps(rest);
const translate = useTranslate();
const context = useContext(FormContext);
const menuRef = useRef<HTMLDivElement>(null);
const [inputRef, setInputRef] = useState<HTMLInputElement | null>(null);
const styles = useS(elementsSizeStyles, formControlStyles, comboboxStyles);
const menu = useMenuState({
placement: 'bottom-end',
@@ -363,17 +254,19 @@ export const Combobox: ComboboxType = observer(function Combobox({
inputValue = translate('ui_processing_loading');
}
return styled(useStyles(baseFormControlStyles, baseValidFormControlStyles, styles))(
<field className={className} {...use({ inline })}>
return (
<div data-testid="field" className={s(styles, { field: true, inline, ...layoutProps }, className)}>
{children && (
<field-label title={title}>
<div title={title} data-testid="field-label" className={styles.fieldLabel}>
{children}
{rest.required && ' *'}
</field-label>
</div>
)}
<input-box>
<div data-testid="input-box" className={styles.inputBox}>
{(icon || loading) && (
<input-icon>{loading ? <Loader small fullSize /> : typeof icon === 'string' ? <IconOrImage icon={icon} /> : icon}</input-icon>
<div data-testid="input-icon" className={styles.inputIcon}>
{loading ? <Loader small fullSize /> : typeof icon === 'string' ? <IconOrImage icon={icon} className={styles.iconOrImage} /> : icon}
</div>
)}
<input
ref={setInputRef}
@@ -385,14 +278,14 @@ export const Combobox: ComboboxType = observer(function Combobox({
readOnly={readOnly || select}
data-focus={focus}
data-select={select}
className={s(styles, { input: true, select, focus })}
onChange={handleChange}
onKeyDown={handleKeyDown}
onClick={handleClick}
{...rest}
{...use({ select, focus })}
/>
<MenuButton {...menu} disabled={readOnly || disabled || hideMenu}>
<Icon name="arrow" viewBox="0 0 16 16" {...use({ focus })} />
<MenuButton {...menu} disabled={readOnly || disabled || hideMenu} className={styles.menuButton}>
<Icon name="arrow" viewBox="0 0 16 16" className={s(styles, { icon: true, focus })} />
</MenuButton>
<Menu
{...menu}
@@ -400,10 +293,11 @@ export const Combobox: ComboboxType = observer(function Combobox({
aria-label={propertyName}
// unstable_finalFocusRef={inputRef || undefined}
// unstable_initialFocusRef={ref}
className={styles.menu}
modal
>
{!filteredItems.length ? (
<MenuItem id="placeholder" disabled {...menu}>
<MenuItem id="placeholder" disabled {...menu} className={styles.menuItem}>
{translate('combobox_no_results_placeholder')}
</MenuItem>
) : (
@@ -420,17 +314,28 @@ export const Combobox: ComboboxType = observer(function Combobox({
title={title}
{...menu}
disabled={disabled}
className={styles.menuItem}
onClick={event => handleSelect(event.currentTarget.id)}
>
{iconSelector && <item-icon>{icon && typeof icon === 'string' ? <IconOrImage icon={icon} /> : icon}</item-icon>}
<item-value>{valueSelector(item)}</item-value>
{iconSelector && (
<div data-testid="item-icon" className={styles.itemIcon}>
{icon && typeof icon === 'string' ? <IconOrImage icon={icon} className={styles.iconOrImage} /> : icon}
</div>
)}
<div data-testid="item-value" className={styles.itemValue}>
{valueSelector(item)}
</div>
</MenuItem>
);
})
)}
</Menu>
</input-box>
{description && <field-description>{description}</field-description>}
</field>,
</div>
{description && (
<div data-testid="field-description" className={styles.fieldDescription}>
{description}
</div>
)}
</div>
);
});
@@ -0,0 +1,41 @@
.field {
box-sizing: border-box;
& .field {
height: 32px;
padding: 0;
}
}
.fieldLabel {
composes: theme-typography--body1 from global;
box-sizing: border-box;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.fieldDescription {
composes: theme-typography--caption from global;
box-sizing: border-box;
padding-top: 4px;
min-height: 24px;
}
.valid {
composes: theme-text-text-hint-on-light from global;
}
.invalid {
composes: theme-text-negative from global;
}
.input,
.textarea {
font-size: 12px;
&.select {
cursor: pointer;
user-select: none;
}
}
@@ -7,8 +7,11 @@
*/
import styled, { css } from 'reshadow';
import { filterLayoutFakeProps } from '../Containers/filterLayoutFakeProps';
import { filterLayoutFakeProps, getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { s } from '../s';
import { useS } from '../useS';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
@@ -36,11 +39,13 @@ export const FormFieldDescription: React.FC<React.PropsWithChildren<Props>> = fu
className,
...rest
}) {
const layoutProps = getLayoutProps(rest);
rest = filterLayoutFakeProps(rest);
const styles = useStyles(baseFormControlStyles, baseValidFormControlStyles, style);
const sizeStyles = useS(elementsSizeStyles);
return styled(styles)(
<field title={title} className={className} {...rest}>
<field title={title} className={s(sizeStyles, { ...layoutProps }, className)} {...rest}>
{label && <field-label as="label">{label}</field-label>}
<field-description>{children}</field-description>
</field>,
@@ -0,0 +1,38 @@
.icon {
composes: theme-text-on-secondary from global;
}
.fieldLabel {
display: block;
composes: theme-typography--body1 from global;
font-weight: 500;
}
.fieldLabel:not(:empty) {
padding-bottom: 10px;
}
.inputContainer {
position: relative;
}
.loaderContainer,
.iconContainer {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
display: flex;
}
.iconContainer {
cursor: pointer;
& .icon {
width: 100%;
height: 100%;
}
}
.input[disabled] + .iconContainer {
cursor: auto;
opacity: 0.8;
}
.input:not(:only-child) {
padding-right: 32px !important;
}
@@ -7,63 +7,27 @@
*/
import { observer } from 'mobx-react-lite';
import { forwardRef, useCallback, useContext, useState } from 'react';
import styled, { css, use } from 'reshadow';
import styled, { use } from 'reshadow';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
import { getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { Icon } from '../Icon';
import { Loader } from '../Loader/Loader';
import { useTranslate } from '../localization/useTranslate';
import { s } from '../s';
import { useCombinedHandler } from '../useCombinedHandler';
import { useS } from '../useS';
import { useStateDelay } from '../useStateDelay';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseInvalidFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
import { FormContext } from './FormContext';
import formControlStyles from './FormControl.m.css';
import inputFieldStyle from './InputField.m.css';
import { isControlPresented } from './isControlPresented';
import { useCapsLockTracker } from './useCapsLockTracker';
const INPUT_FIELD_STYLES = css`
Icon {
composes: theme-text-on-secondary from global;
}
field-label {
display: block;
composes: theme-typography--body1 from global;
font-weight: 500;
}
field-label:not(:empty) {
padding-bottom: 10px;
}
input-container {
position: relative;
}
loader-container,
icon-container {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
display: flex;
}
icon-container {
cursor: pointer;
& Icon {
width: 100%;
height: 100%;
}
}
input[disabled] + icon-container {
cursor: auto;
opacity: 0.8;
}
input:not(:only-child) {
padding-right: 32px !important;
}
`;
type BaseProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'name' | 'value' | 'style'> &
ILayoutSizeProps & {
error?: boolean;
@@ -119,11 +83,6 @@ export const InputField: InputFieldType = observer(
description,
labelTooltip,
mod,
fill,
small,
medium,
large,
tiny,
autoHide,
onChange,
onCustomCopy,
@@ -134,7 +93,9 @@ export const InputField: InputFieldType = observer(
const capsLock = useCapsLockTracker();
const [passwordRevealed, setPasswordRevealed] = useState(false);
const translate = useTranslate();
const styles = useStyles(baseFormControlStyles, error ? baseInvalidFormControlStyles : baseValidFormControlStyles, INPUT_FIELD_STYLES, style);
const layoutProps = getLayoutProps(rest);
const propStyles = useStyles(style);
const styles = useS(inputFieldStyle, formControlStyles, elementsSizeStyles);
const context = useContext(FormContext);
loading = useStateDelay(loading ?? false, 300);
@@ -186,19 +147,20 @@ export const InputField: InputFieldType = observer(
description = translate('ui_capslock_on');
}
return styled(styles)(
<field className={className} {...use({ small, medium, large, tiny })}>
<field-label title={labelTooltip || rest.title}>
return styled(propStyles)(
<div data-testid="field" className={s(styles, { ...layoutProps, field: true }, className)}>
<div data-testid="field-label" title={labelTooltip || rest.title} className={styles.fieldLabel}>
{children}
{required && ' *'}
</field-label>
<input-container>
</div>
<div data-testid="input-container" className={styles.inputContainer}>
<input
ref={ref}
{...rest}
type={passwordRevealed ? 'text' : rest.type}
name={name}
value={value ?? ''}
className={styles.input}
onChange={handleChange}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
@@ -206,23 +168,27 @@ export const InputField: InputFieldType = observer(
required={required}
/>
{loading && (
<loader-container title={translate('ui_processing_loading')}>
<div data-testid="loader-container" title={translate('ui_processing_loading')} className={styles.loaderContainer}>
<Loader small />
</loader-container>
</div>
)}
{showRevealPasswordButton && (
<icon-container title={translate('ui_reveal_password')} onClick={revealPassword}>
<Icon name={passwordRevealed ? 'password-hide' : 'password-show'} viewBox="0 0 16 16" />
</icon-container>
<div data-testid="icon-container" title={translate('ui_reveal_password')} className={styles.iconContainer} onClick={revealPassword}>
<Icon name={passwordRevealed ? 'password-hide' : 'password-show'} viewBox="0 0 16 16" className={styles.icon} />
</div>
)}
{onCustomCopy && (
<icon-container title={translate('ui_copy_to_clipboard')} onClick={onCustomCopy}>
<Icon name="copy" viewBox="0 0 32 32" />
</icon-container>
<div data-testid="icon-container" title={translate('ui_copy_to_clipboard')} className={styles.iconContainer} onClick={onCustomCopy}>
<Icon name="copy" viewBox="0 0 32 32" className={styles.icon} />
</div>
)}
</input-container>
{(description || showRevealPasswordButton) && <field-description>{description}</field-description>}
</field>,
</div>
{(description || showRevealPasswordButton) && (
<div data-testid="field-description" className={s(styles, { fieldDescription: true, valid: !error, invalid: error })}>
{description}
</div>
)}
</div>,
);
}),
);
@@ -7,16 +7,20 @@
*/
import { observer } from 'mobx-react-lite';
import { ReactNode, useContext, useState } from 'react';
import styled, { css, use } from 'reshadow';
import styled, { css } from 'reshadow';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
import { blobToData, bytesToSize } from '@cloudbeaver/core-utils';
import { Button } from '../Button';
import { getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { IconButton } from '../IconButton';
import { useTranslate } from '../localization/useTranslate';
import { s } from '../s';
import { UploadArea } from '../UploadArea';
import { useS } from '../useS';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseInvalidFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
import { FormContext } from './FormContext';
@@ -76,10 +80,6 @@ export const InputFileTextContent: InputFileTextContentType = observer(function
tooltip,
required,
fileName,
small,
medium,
large,
tiny,
style,
maxFileSize = DEFAULT_MAX_FILE_SIZE,
disabled,
@@ -87,6 +87,7 @@ export const InputFileTextContent: InputFileTextContentType = observer(function
children,
onChange,
mapValue,
...rest
}: Props<Record<any, any>>) {
const translate = useTranslate();
const context = useContext(FormContext);
@@ -94,7 +95,9 @@ export const InputFileTextContent: InputFileTextContentType = observer(function
const [selected, setSelected] = useState<File | null>(null);
const [error, setError] = useState<Error | null>(null);
const layoutProps = getLayoutProps(rest);
const styles = useStyles(INPUT_FILE_FIELD_STYLES, baseFormControlStyles, style, error ? baseInvalidFormControlStyles : baseValidFormControlStyles);
const sizeStyles = useS(elementsSizeStyles);
const savedExternally = !!fileName && state[name] !== '';
const saved = savedExternally || !!state[name];
@@ -163,7 +166,7 @@ export const InputFileTextContent: InputFileTextContentType = observer(function
}
return styled(styles)(
<field className={className} {...use({ small, medium, large, tiny })}>
<field className={s(sizeStyles, { ...layoutProps }, className)}>
<field-label title={labelTooltip}>
{children}
{required && ' *'}
@@ -12,13 +12,17 @@ import styled, { css, use } from 'reshadow';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
import { Button } from '../Button';
import { getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { useTranslate } from '../localization/useTranslate';
import { s } from '../s';
import { Tag } from '../Tags/Tag';
import { Tags } from '../Tags/Tags';
import { UploadArea } from '../UploadArea';
import { useCombinedHandler } from '../useCombinedHandler';
import { useRefInherit } from '../useRefInherit';
import { useS } from '../useS';
import { useStateDelay } from '../useStateDelay';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseInvalidFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
@@ -97,11 +101,6 @@ export const InputFiles: InputFilesType = observer(
labelTooltip,
hideTags,
mod,
fill,
small,
medium,
large,
tiny,
autoHide,
aggregate,
onChange,
@@ -110,10 +109,12 @@ export const InputFiles: InputFilesType = observer(
}: ControlledProps | ObjectProps<any, any>,
refInherit: React.Ref<HTMLInputElement>,
) {
const layoutProps = getLayoutProps(rest);
const ref = useRefInherit<HTMLInputElement>(refInherit);
const [innerState, setInnerState] = useState<FileList | null>(null);
const translate = useTranslate();
const styles = useStyles(baseFormControlStyles, error ? baseInvalidFormControlStyles : baseValidFormControlStyles, INPUT_FIELD_STYLES, style);
const sizeStyles = useS(elementsSizeStyles);
const context = useContext(FormContext);
loading = useStateDelay(loading ?? false, 300);
@@ -194,7 +195,7 @@ export const InputFiles: InputFilesType = observer(
const files = Array.from(value ?? []);
return styled(styles)(
<field className={className} {...use({ small, medium, large, tiny })}>
<field className={s(sizeStyles, { ...layoutProps }, className)}>
<field-label title={labelTooltip || rest.title}>
{children}
{required && ' *'}
@@ -9,8 +9,11 @@ import { observer } from 'mobx-react-lite';
import { useCallback, useContext } from 'react';
import styled, { css, use } from 'reshadow';
import { filterLayoutFakeProps } from '../Containers/filterLayoutFakeProps';
import { filterLayoutFakeProps, getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { s } from '../s';
import { useS } from '../useS';
import { useStyles } from '../useStyles';
import { baseFormControlStyles } from './baseFormControlStyles';
import { FormContext } from './FormContext';
@@ -139,7 +142,9 @@ export const Radio: RadioType = observer(function Radio({
children,
...rest
}: ControlledProps | ObjectProps<any, any>) {
const layoutProps = getLayoutProps(rest);
rest = filterLayoutFakeProps(rest);
const sizeStyles = useS(elementsSizeStyles);
const formContext = useContext(FormContext);
const context = useContext(RadioGroupContext);
@@ -188,7 +193,7 @@ export const Radio: RadioType = observer(function Radio({
rest.disabled && radioState.disabled,
),
)(
<field className={className}>
<field className={s(sizeStyles, { ...layoutProps }, className)}>
<radio>
<input {...rest} type="radio" id={id} name={name} value={value ?? ''} checked={checked} onChange={handleChange} />
<radio-background>
@@ -11,7 +11,11 @@ import styled, { css, use } from 'reshadow';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
import { getLayoutProps } from '../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../Containers/shared/ElementsSize.m.css';
import { s } from '../s';
import { useS } from '../useS';
import { useStyles } from '../useStyles';
import { baseFormControlStyles, baseValidFormControlStyles } from './baseFormControlStyles';
import { FormContext } from './FormContext';
@@ -79,11 +83,6 @@ export const Textarea: TextareaType = observer(function Textarea({
required,
children,
className,
fill,
tiny,
small,
medium,
large,
description,
labelTooltip,
mod,
@@ -91,6 +90,8 @@ export const Textarea: TextareaType = observer(function Textarea({
onChange = () => {},
...rest
}: ControlledProps | ObjectProps<any, any>) {
const layoutProps = getLayoutProps(rest);
const sizeStyles = useS(elementsSizeStyles);
const context = useContext(FormContext);
const handleChange = useCallback(
@@ -111,7 +112,7 @@ export const Textarea: TextareaType = observer(function Textarea({
const value = state ? state[name] : controlledValue;
return styled(useStyles(baseFormControlStyles, baseValidFormControlStyles, styles, style))(
<field className={className} {...use({ tiny, small, medium, large, embedded })}>
<field className={s(sizeStyles, { ...layoutProps }, className)} {...use({ embedded })}>
<field-label title={labelTooltip || rest.title}>
{children}
{required && ' *'}
@@ -12,16 +12,6 @@ export const baseFormControlStyles = css`
box-sizing: border-box;
max-width: 100%;
&[|small] {
max-width: 250px;
}
&[|medium] {
max-width: 450px;
}
&[|large] {
max-width: 650px;
}
& field {
height: 32px;
padding: 0;
@@ -1,111 +1,111 @@
.itemList {
composes: theme-background-surface from global;
box-sizing: border-box;
border-collapse: collapse;
z-index: 0;
overflow: auto;
composes: theme-background-surface from global;
box-sizing: border-box;
border-collapse: collapse;
z-index: 0;
overflow: auto;
}
.itemListOverflow,
.itemListOverflowTop {
position: sticky;
flex-shrink: 0;
width: 100%;
height: 8px;
pointer-events: none;
position: sticky;
flex-shrink: 0;
width: 100%;
height: 8px;
pointer-events: none;
}
.itemListOverflow {
composes: branding-overflow from global;
bottom: 0;
composes: branding-overflow from global;
bottom: 0;
}
.itemListOverflowTop {
composes: branding-overflow-inverse from global;
top: 0;
z-index: 1;
composes: branding-overflow-inverse from global;
top: 0;
z-index: 1;
}
.listSearch {
composes: theme-background-surface theme-text-on-surface theme-typography--body1 from global;
position: sticky;
top: 0;
padding: 16px 24px;
z-index: 1;
composes: theme-background-surface theme-text-on-surface theme-typography--body1 from global;
position: sticky;
top: 0;
padding: 16px 24px;
z-index: 1;
& .inputBox {
position: relative;
& .inputBox {
position: relative;
}
& .input {
padding: 4px 32px 4px 8px;
}
& .actionButton {
position: absolute;
display: flex;
align-items: center;
height: 100%;
top: 50%;
right: 4px;
transform: translateY(-50%);
& .iconButton {
position: relative;
box-sizing: border-box;
overflow: hidden;
border-radius: 2px;
height: 24px;
width: 24px;
margin: 0;
}
& .input {
padding: 4px 32px 4px 8px;
}
& .actionButton {
position: absolute;
display: flex;
align-items: center;
height: 100%;
top: 50%;
right: 4px;
transform: translateY(-50%);
& .iconButton {
position: relative;
box-sizing: border-box;
overflow: hidden;
border-radius: 2px;
height: 24px;
width: 24px;
margin: 0;
}
& .crossIcon {
padding: 4px;
}
& .crossIcon {
padding: 4px;
}
}
}
.iconButton {
composes: theme-ripple theme-background-primary theme-text-on-primary from global;
composes: theme-ripple theme-background-primary theme-text-on-primary from global;
}
.listItem:not(:nth-last-child(2)) {
border-bottom: 1px solid;
border-bottom: 1px solid;
}
.listItem {
composes: theme-ripple theme-background-surface theme-border-color-secondary from global;
position: relative;
cursor: pointer;
display: flex;
box-sizing: border-box;
align-items: center;
padding: 0 16px;
composes: theme-ripple theme-background-surface theme-border-color-secondary from global;
position: relative;
cursor: pointer;
display: flex;
box-sizing: border-box;
align-items: center;
padding: 0 16px;
}
.listItemIcon {
display: flex;
align-items: center;
box-sizing: border-box;
padding: 8px;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 8px;
& .staticImage {
box-sizing: border-box;
width: 24px;
}
& .staticImage {
box-sizing: border-box;
width: 24px;
}
}
.listItemName {
composes: theme-border-color-secondary theme-typography--body1 from global;
box-sizing: border-box;
font-weight: 500;
min-width: 250px;
padding: 8px 24px 8px 8px;
border-right: 1px solid;
composes: theme-border-color-secondary theme-typography--body1 from global;
box-sizing: border-box;
font-weight: 500;
min-width: 250px;
padding: 8px 24px 8px 8px;
border-right: 1px solid;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.listItemDescription {
composes: theme-typography--body2 from global;
box-sizing: border-box;
max-width: 460px;
padding: 8px 8px 8px 24px;
composes: theme-typography--body2 from global;
box-sizing: border-box;
max-width: 460px;
padding: 8px 8px 8px 24px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@@ -10,8 +10,12 @@ import { useCallback } from 'react';
import type { ObjectPropertyInfo } from '@cloudbeaver/core-sdk';
import { getLayoutProps } from '../../Containers/filterLayoutFakeProps';
import type { ILayoutSizeProps } from '../../Containers/ILayoutSizeProps';
import elementsSizeStyles from '../../Containers/shared/ElementsSize.m.css';
import { s } from '../../s';
import { TextPlaceholder } from '../../TextPlaceholder';
import { useS } from '../../useS';
import { RenderField } from './RenderField';
interface ObjectPropertyFormProps extends ILayoutSizeProps {
@@ -44,7 +48,9 @@ export const ObjectPropertyInfoForm = observer<ObjectPropertyFormProps>(function
hideEmptyPlaceholder,
isSaved,
onFocus,
...rest
}) {
const layoutProps = getLayoutProps(rest);
const handleFocus = useCallback(
(e: React.FocusEvent<HTMLInputElement>) => {
if (onFocus) {
@@ -54,6 +60,8 @@ export const ObjectPropertyInfoForm = observer<ObjectPropertyFormProps>(function
[onFocus],
);
const sizeStyles = useS(elementsSizeStyles);
if (properties.length === 0 && !hideEmptyPlaceholder) {
return <TextPlaceholder>Properties empty</TextPlaceholder>;
}
@@ -67,7 +75,7 @@ export const ObjectPropertyInfoForm = observer<ObjectPropertyFormProps>(function
return (
<RenderField
key={property.id}
className={className}
className={s(sizeStyles, { ...layoutProps }, className)}
property={property}
state={state}
editable={editable}
@@ -68,6 +68,10 @@ export const PROPERTIES_FILTER_STYLES = css`
margin-left: 8px;
}
InputField {
max-width: 100%;
}
IconButton {
right: 0px;
top: 0px;
-1
View File
@@ -119,7 +119,6 @@ export * from './FormControls/BASE_DROPDOWN_STYLES';
export * from './FormControls/FormBox';
export * from './FormControls/Filter';
export * from './Containers/BASE_CONTAINERS_STYLES';
export * from './Containers/Container';
export * from './Containers/Group';
export * from './Containers/GroupClose';
@@ -10,17 +10,7 @@ import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Button,
Container,
InputField,
SubmittingForm,
useFocus,
useObservableRef,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { Button, Container, InputField, SubmittingForm, useFocus, useObservableRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { throttleAsync } from '@cloudbeaver/core-utils';
import { CommonDialogBody } from './CommonDialog/CommonDialogBody';
@@ -112,7 +102,7 @@ export const RenameDialog: DialogComponent<RenameDialogPayload, string> = observ
const errorMessage = state.valid ? ' ' : translate(state.message ?? 'ui_rename_taken_or_invalid');
return styled(useStyles(style, BASE_CONTAINERS_STYLES))(
return styled(useStyles(style))(
<CommonDialogWrapper size="small" className={className} fixedWidth>
<CommonDialogHeader title={title} subTitle={subTitle} icon={icon} viewBox={viewBox} bigIcon={bigIcon} onReject={rejectDialog} />
<CommonDialogBody>
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Button, Container, GroupItem, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Button, Container, GroupItem, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useAuthenticationAction } from './useAuthenticationAction';
@@ -29,7 +29,7 @@ export type Props = {
export const AuthenticationProvider = observer<Props>(function AuthenticationProvider(props) {
const translate = useTranslate();
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const action = useAuthenticationAction(props);
if (action.authorized) {
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Switch, useTranslate } from '@cloudbeaver/core-blocks';
import type { ServerConfigInput } from '@cloudbeaver/core-sdk';
interface Props {
@@ -17,7 +16,7 @@ interface Props {
export const ServerConfigurationConfigurationForm = observer<Props>(function ServerConfigurationConfigurationForm({ serverConfig }) {
const translate = useTranslate();
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<>
<Switch
name="customConnectionsEnabled"
@@ -29,6 +28,6 @@ export const ServerConfigurationConfigurationForm = observer<Props>(function Ser
>
{translate('administration_configuration_wizard_configuration_custom_connections')}
</Switch>
</>,
</>
);
});
@@ -7,19 +7,9 @@
*/
import { observer } from 'mobx-react-lite';
import { useContext } from 'react';
import styled from 'reshadow';
import { AdministrationSettingsService } from '@cloudbeaver/core-administration';
import {
BASE_CONTAINERS_STYLES,
FormContext,
GroupTitle,
PlaceholderComponent,
Switch,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { FormContext, GroupTitle, PlaceholderComponent, Switch, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { FeaturesResource } from '@cloudbeaver/core-root';
import type { IConfigurationPlaceholderProps } from '@cloudbeaver/plugin-administration';
@@ -35,13 +25,12 @@ export const ServerConfigurationFeaturesForm: PlaceholderComponent<IConfiguratio
const administrationSettingsService = useService(AdministrationSettingsService);
const features = useResource(ServerConfigurationFeaturesForm, FeaturesResource, configurationWizard ? null : undefined);
const translate = useTranslate();
const styles = useStyles(BASE_CONTAINERS_STYLES);
if (features.data.length === 0 || configurationWizard) {
return null;
}
return styled(styles)(
return (
<>
<GroupTitle>{translate('administration_configuration_wizard_configuration_services_group')}</GroupTitle>
{features.data.map(feature => (
@@ -58,7 +47,7 @@ export const ServerConfigurationFeaturesForm: PlaceholderComponent<IConfiguratio
{feature.label}
</Switch>
))}
</>,
</>
);
},
);
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, GroupTitle, InputField, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Group, GroupTitle, InputField, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import type { IServerConfigurationPageState } from '../IServerConfigurationPageState';
@@ -20,7 +19,7 @@ interface Props {
export const ServerConfigurationInfoForm = observer<Props>(function ServerConfigurationInfoForm({ state }) {
const serverConfigLoader = useResource(ServerConfigurationInfoForm, ServerConfigResource, undefined);
const translate = useTranslate();
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<Group form gap>
<GroupTitle>{translate('administration_configuration_wizard_configuration_server_info')}</GroupTitle>
<InputField type="text" name="serverName" state={state.serverConfig} mod="surface" required medium>
@@ -52,6 +51,6 @@ export const ServerConfigurationInfoForm = observer<Props>(function ServerConfig
>
{translate('administration_configuration_wizard_configuration_server_session_lifetime')}
</InputField>
</Group>,
</Group>
);
});
@@ -7,9 +7,8 @@
*/
import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Switch, useTranslate } from '@cloudbeaver/core-blocks';
import { CONNECTION_NAVIGATOR_VIEW_SETTINGS, isNavigatorViewSettingsEqual } from '@cloudbeaver/core-root';
import type { IServerConfigurationPageState } from '../IServerConfigurationPageState';
@@ -34,7 +33,7 @@ export const ServerConfigurationNavigatorViewForm = observer<Props>(function Ser
[configs],
);
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<>
<Switch
name="simpleNavigatorViewEnabled"
@@ -46,6 +45,6 @@ export const ServerConfigurationNavigatorViewForm = observer<Props>(function Ser
>
{translate('administration_configuration_wizard_configuration_navigation_tree_view')}
</Switch>
</>,
</>
);
});
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, GroupTitle, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Group, GroupTitle, Switch, useTranslate } from '@cloudbeaver/core-blocks';
import type { ServerConfigInput } from '@cloudbeaver/core-sdk';
interface Props {
@@ -17,7 +16,7 @@ interface Props {
export const ServerConfigurationSecurityForm = observer<Props>(function ServerConfigurationSecurityForm({ serverConfig }) {
const translate = useTranslate();
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<Group form gap>
<GroupTitle>{translate('administration_configuration_wizard_configuration_security')}</GroupTitle>
<Switch
@@ -41,6 +40,6 @@ export const ServerConfigurationSecurityForm = observer<Props>(function ServerCo
>
{translate('administration_configuration_wizard_configuration_security_public_credentials')}
</Switch>
</Group>,
</Group>
);
});
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
import { useCallback } from 'react';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Combobox, Group, GroupTitle, ITag, Tag, Tags, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Combobox, Group, GroupTitle, ITag, Tag, Tags, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { DBDriverResource } from '@cloudbeaver/core-connections';
import { CachedMapAllKey, resourceKeyList, ServerConfigInput } from '@cloudbeaver/core-sdk';
@@ -57,7 +57,7 @@ export const ServerConfigurationDriversForm = observer<Props>(function ServerCon
}
}, []);
return styled(useStyles(BASE_CONTAINERS_STYLES, style))(
return styled(useStyles(style))(
<Group maximum gap>
<GroupTitle>{translate('administration_disabled_drivers_title')}</GroupTitle>
<Combobox
@@ -10,7 +10,6 @@ import styled, { css } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, AdministrationItemContentComponent, ConfigurationWizardService } from '@cloudbeaver/core-administration';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
@@ -58,7 +57,7 @@ const styles = css`
export const ServerConfigurationPage: AdministrationItemContentComponent = observer(function ServerConfigurationPage({ configurationWizard }) {
const translate = useTranslate();
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES, BASE_CONTAINERS_STYLES);
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const [focusedRef, state] = useFocus<HTMLFormElement>({ focusFirstChild: true });
const service = useService(ServerConfigurationService);
const serverConfigResource = useService(ServerConfigResource);
@@ -7,7 +7,7 @@
*/
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, ColoredContainer, Group, GroupItem, Translate } from '@cloudbeaver/core-blocks';
import { ColoredContainer, Group, GroupItem, Translate } from '@cloudbeaver/core-blocks';
const styles = css`
p {
@@ -21,10 +21,7 @@ const styles = css`
`;
export const WelcomePage: React.FC = function WelcomePage() {
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<ColoredContainer wrap gap overflow parent>
<Group form>
<h3>
@@ -9,16 +9,7 @@ import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
IconOrImage,
Loader,
Placeholder,
useExecutor,
useObjectRef,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { IconOrImage, Loader, Placeholder, useExecutor, useObjectRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import type { AdminAuthProviderConfiguration } from '@cloudbeaver/core-sdk';
import { BASE_TAB_STYLES, TabList, TabPanelList, TabsState, UNDERLINE_TAB_BIG_STYLES, UNDERLINE_TAB_STYLES } from '@cloudbeaver/core-ui';
@@ -107,7 +98,7 @@ export const AuthConfigurationForm = observer<Props>(function AuthConfigurationF
const translate = useTranslate();
const props = useObjectRef({ onSave });
const style = useStyles(BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES, UNDERLINE_TAB_BIG_STYLES);
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
const styles = useStyles(style, topBarStyles, formStyles);
const service = useService(AuthConfigurationFormService);
useExecutor({
@@ -9,17 +9,7 @@ import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, AdministrationItemContentComponent } from '@cloudbeaver/core-administration';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
Loader,
ToolsAction,
ToolsPanel,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { ColoredContainer, Container, Group, Loader, ToolsAction, ToolsPanel, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { AuthConfigurationsTable } from './AuthConfigurationsTable/AuthConfigurationsTable';
@@ -41,7 +31,7 @@ const styles = css`
export const AuthConfigurationsAdministration: AdministrationItemContentComponent = observer(function AuthConfigurationsAdministration({ sub }) {
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES, styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const service = useService(CreateAuthConfigurationService);
const table = useConfigurationsTable();
@@ -85,7 +75,7 @@ export const AuthConfigurationsAdministration: AdministrationItemContentComponen
<CreateAuthConfiguration />
</Group>
)}
<Group box="no-overflow">
<Group boxNoOverflow>
<Loader style={loaderStyle} loading={table.processing} overlay>
<AuthConfigurationsTable
configurations={table.configurations}
@@ -11,7 +11,6 @@ import styled, { css } from 'reshadow';
import { AuthConfigurationParametersResource, AuthProvidersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Combobox,
FieldCheckbox,
@@ -49,7 +48,7 @@ export const AuthConfigurationOptions: TabContainerPanelComponent<IAuthConfigura
const translate = useTranslate();
const copy = useClipboard();
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const providers = useResource(AuthConfigurationOptions, AuthProvidersResource, CachedMapAllKey);
const parameters = useResource(AuthConfigurationOptions, AuthConfigurationParametersResource, state.config.providerId || null);
@@ -7,7 +7,6 @@
*/
import { observer } from 'mobx-react-lite';
import React, { useContext } from 'react';
import styled from 'reshadow';
import {
AUTH_PROVIDER_LOCAL_ID,
@@ -16,19 +15,7 @@ import {
AuthProvidersResource,
AuthSettingsService,
} from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
FormContext,
Group,
GroupTitle,
Loader,
PlaceholderComponent,
Switch,
useExecutor,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { FormContext, Group, GroupTitle, PlaceholderComponent, Switch, useExecutor, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
import type { IConfigurationPlaceholderProps } from '@cloudbeaver/plugin-administration';
@@ -42,7 +29,6 @@ export const AuthenticationProviders: PlaceholderComponent<IConfigurationPlaceho
const authProviderService = useService(AuthProviderService);
const providers = useResource(AuthenticationProviders, AuthProvidersResource, CachedMapAllKey);
const translate = useTranslate();
const styles = useStyles(BASE_CONTAINERS_STYLES);
const formContext = useContext(FormContext);
const authSettingsService = useService(AuthSettingsService);
@@ -91,7 +77,7 @@ export const AuthenticationProviders: PlaceholderComponent<IConfigurationPlaceho
return null;
}
return styled(styles)(
return (
<React.Fragment>
<Group key="authentication" form gap>
<GroupTitle>{translate('administration_configuration_wizard_configuration_authentication_group')}</GroupTitle>
@@ -155,6 +141,6 @@ export const AuthenticationProviders: PlaceholderComponent<IConfigurationPlaceho
})}
</Group>
{configurationWizard && localProvider && <ServerConfigurationAdminForm serverConfig={serverConfig} />}
</React.Fragment>,
</React.Fragment>
);
});
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, GroupTitle, InputField, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Group, GroupTitle, InputField, useTranslate } from '@cloudbeaver/core-blocks';
import type { ServerConfigInput } from '@cloudbeaver/core-sdk';
interface Props {
@@ -17,9 +16,8 @@ interface Props {
export const ServerConfigurationAdminForm = observer<Props>(function ServerConfigurationAdminForm({ serverConfig }) {
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES);
return styled(style)(
return (
<Group form gap medium>
<GroupTitle>{translate('administration_configuration_wizard_configuration_admin')}</GroupTitle>
<InputField type="text" name="adminName" state={serverConfig} minLength={6} mod="surface" required tiny>
@@ -28,6 +26,6 @@ export const ServerConfigurationAdminForm = observer<Props>(function ServerConfi
<InputField type="password" name="adminPassword" state={serverConfig} autoComplete="new-password" mod="surface" required tiny>
{translate('administration_configuration_wizard_configuration_admin_password')}
</InputField>
</Group>,
</Group>
);
});
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, IconOrImage, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { IconOrImage, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import type { UserInfo } from '@cloudbeaver/core-sdk';
import { BASE_TAB_STYLES, TabList, TabsState, UNDERLINE_TAB_BIG_STYLES, UNDERLINE_TAB_STYLES } from '@cloudbeaver/core-ui';
@@ -99,7 +99,7 @@ interface Props {
export const MetaParameterForm = observer<Props>(function MetaParameterForm({ user, state }) {
const translate = useTranslate();
const style = [BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES, UNDERLINE_TAB_BIG_STYLES];
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
const styles = useStyles(style, topBarStyles, formStyles);
return styled(styles)(
<flex-box>
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { UserMetaParametersResource } from '@cloudbeaver/core-authentication';
import { BASE_CONTAINERS_STYLES, Container, ObjectPropertyInfoForm, useResource, useStyles } from '@cloudbeaver/core-blocks';
import { Container, ObjectPropertyInfoForm, useResource, useStyles } from '@cloudbeaver/core-blocks';
import type { UserInfo } from '@cloudbeaver/core-sdk';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
@@ -21,7 +21,7 @@ interface Props {
export const MetaParameterInfoForm = observer<Props>(function MetaParameterInfoForm({ user, className, style }) {
const userMetaParameters = useResource(MetaParameterInfoForm, UserMetaParametersResource, undefined);
const styles = useStyles(style, BASE_CONTAINERS_STYLES);
const styles = useStyles(style);
if (!userMetaParameters.data.length) {
return null;
@@ -8,11 +8,11 @@
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, ColoredContainer, Container, Group, InputField, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { ColoredContainer, Container, Group, InputField, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import type { UserInfo } from '@cloudbeaver/core-sdk';
import type { ComponentStyle } from '@cloudbeaver/core-theming';
import { AuthProvidersList } from '@cloudbeaver/plugin-user-profile';
import { AuthProvidersList } from '../AuthProviders/ConfigurationsList';
import { MetaParameterInfoForm } from './MetaParameterInfoForm';
interface Props {
@@ -22,7 +22,7 @@ interface Props {
}
export const MetaParametersForm = observer<Props>(function MetaParametersForm({ user, className, style }) {
const styles = useStyles(style, BASE_CONTAINERS_STYLES);
const styles = useStyles(style);
const translate = useTranslate();
return styled(styles)(
@@ -11,7 +11,6 @@ import { useCallback, useState } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -67,7 +66,7 @@ interface Props {
export const ConnectionList = observer<Props>(function ConnectionList({ connectionList, grantedSubjects, disabled, onGrant }) {
const props = useObjectRef({ onGrant });
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const translate = useTranslate();
const driversResource = useService(DBDriverResource);
@@ -6,11 +6,9 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
getComputed,
@@ -51,7 +49,7 @@ const styles = css`
`;
export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = observer(function GrantedConnections({ tabId, state: formState }) {
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const translate = useTranslate();
const state = useGrantedConnections(formState.config, formState.mode);
@@ -11,7 +11,6 @@ import { useCallback, useState } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -68,7 +67,7 @@ interface Props {
export const GrantedConnectionList = observer<Props>(function GrantedConnectionList({ grantedConnections, disabled, onRevoke, onEdit }) {
const props = useObjectRef({ onRevoke, onEdit });
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const translate = useTranslate();
const driversResource = useService(DBDriverResource);
@@ -12,7 +12,6 @@ import styled, { css } from 'reshadow';
import { UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -68,7 +67,7 @@ interface Props {
export const GrantedUserList = observer<Props>(function GrantedUserList({ grantedUsers, disabled, onRevoke, onEdit }) {
const props = useObjectRef({ onRevoke, onEdit });
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const translate = useTranslate();
const usersResource = useService(UsersResource);
@@ -10,7 +10,6 @@ import styled, { css } from 'reshadow';
import { AdminUser, UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
getComputed,
@@ -48,7 +47,7 @@ const styles = css`
`;
export const GrantedUsers: TabContainerPanelComponent<ITeamFormProps> = observer(function GrantedUsers({ tabId, state: formState }) {
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const translate = useTranslate();
const state = useGrantedUsers(formState.config, formState.mode);
@@ -12,7 +12,6 @@ import styled, { css } from 'reshadow';
import { UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -67,7 +66,7 @@ interface Props {
export const UserList = observer<Props>(function UserList({ userList, grantedUsers, disabled, onGrant }) {
const props = useObjectRef({ onGrant });
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const translate = useTranslate();
const usersResource = useService(UsersResource);
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { PermissionsResource } from '@cloudbeaver/core-administration';
import { BASE_CONTAINERS_STYLES, FieldCheckbox, Group, GroupTitle, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { FieldCheckbox, Group, GroupTitle, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
import type { ITeamFormProps } from '../ITeamFormProps';
@@ -24,7 +24,7 @@ export const Permissions = observer<ITeamFormProps>(function Permissions({ state
const translate = useTranslate();
const permissionsResource = useResource(Permissions, PermissionsResource, CachedMapAllKey);
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
return styled(style)(
<Group small gap>
@@ -6,10 +6,9 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { TeamMetaParametersResource } from '@cloudbeaver/core-authentication';
import { BASE_CONTAINERS_STYLES, Group, GroupTitle, ObjectPropertyInfoForm, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Group, GroupTitle, ObjectPropertyInfoForm, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import type { ITeamFormState } from '../ITeamFormProps';
@@ -20,16 +19,15 @@ interface IProps {
export const TeamMetaParameters = observer<IProps>(function TeamMetaParameters({ state }) {
const teamMetaParameters = useResource(TeamMetaParameters, TeamMetaParametersResource, undefined);
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES);
if (teamMetaParameters.data.length === 0) {
return null;
}
return styled(style)(
return (
<Group small gap vertical overflow>
<GroupTitle keepSize>{translate('authentication_team_meta_parameters')}</GroupTitle>
<ObjectPropertyInfoForm state={state.config.metaParameters} properties={teamMetaParameters.data} disabled={state.disabled} keepSize tiny />
</Group>,
</Group>
);
});
@@ -9,20 +9,7 @@ import { observer } from 'mobx-react-lite';
import { useRef } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Group,
GroupTitle,
InputField,
Loader,
ObjectPropertyInfoForm,
SubmittingForm,
Textarea,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { ColoredContainer, Group, InputField, SubmittingForm, Textarea, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import type { TabContainerPanelComponent } from '@cloudbeaver/core-ui';
@@ -39,7 +26,7 @@ const styles = css`
export const TeamOptions: TabContainerPanelComponent<ITeamFormProps> = observer(function TeamOptions({ state }) {
const serverConfigResource = useResource(TeamOptions, ServerConfigResource, undefined);
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const formRef = useRef<HTMLFormElement>(null);
const translate = useTranslate();
const edit = state.mode === 'edit';
@@ -10,16 +10,7 @@ import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import type { TeamInfo } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
IconOrImage,
Loader,
Placeholder,
useExecutor,
useObjectRef,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { IconOrImage, Loader, Placeholder, useExecutor, useObjectRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { BASE_TAB_STYLES, TabList, TabPanelList, TabsState, UNDERLINE_TAB_BIG_STYLES, UNDERLINE_TAB_STYLES } from '@cloudbeaver/core-ui';
@@ -107,7 +98,7 @@ export const TeamForm = observer<Props>(function TeamForm({ state, onCancel, onS
const translate = useTranslate();
const props = useObjectRef({ onSave });
const style = [BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES, UNDERLINE_TAB_BIG_STYLES];
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
const styles = useStyles(style, topBarStyles, formStyles);
const service = useService(TeamFormService);
useExecutor({
@@ -9,16 +9,7 @@ import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, IAdministrationItemSubItem } from '@cloudbeaver/core-administration';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
ToolsAction,
ToolsPanel,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { ColoredContainer, Container, Group, ToolsAction, ToolsPanel, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { CreateTeam } from './CreateTeam';
@@ -39,7 +30,7 @@ interface Props {
export const TeamsPage = observer<Props>(function TeamsPage({ sub, param }) {
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES, styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const service = useService(CreateTeamService);
const table = useTeamsTable();
@@ -85,7 +76,7 @@ export const TeamsPage = observer<Props>(function TeamsPage({ sub, param }) {
<CreateTeam />
</Group>
)}
<Group box="no-overflow">
<Group boxNoOverflow>
<TeamsTable teams={table.teams} state={table.state} selectedItems={table.tableState.selected} expandedItems={table.tableState.expanded} />
</Group>
</Container>
@@ -11,7 +11,6 @@ import { useCallback, useMemo } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Group,
StaticImage,
@@ -45,7 +44,7 @@ const styles = css`
`;
export const ConnectionAccess: TabContainerPanelComponent<IUserFormProps> = observer(function ConnectionAccess({ controller, editing }) {
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const translate = useTranslate();
const driversResource = useService(DBDriverResource);
const getConnectionPermission = useCallback(
@@ -63,7 +62,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IUserFormProps> = obse
if (controller.connections.length === 0) {
return styled(style)(
<ColoredContainer parent>
<Group keepSize large>
<Group large>
<TextPlaceholder>{translate('authentication_administration_user_connections_empty')}</TextPlaceholder>
</Group>
</ColoredContainer>,
@@ -73,7 +72,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IUserFormProps> = obse
if (isAdmin) {
return styled(style)(
<ColoredContainer parent>
<Group keepSize large>
<Group large>
<TextPlaceholder>{translate('connections_connection_access_admin_info')}</TextPlaceholder>
</Group>
</ColoredContainer>,
@@ -82,7 +81,7 @@ export const ConnectionAccess: TabContainerPanelComponent<IUserFormProps> = obse
return styled(style)(
<ColoredContainer parent overflow>
<Group box keepSize large>
<Group box large>
<Table selectedItems={controller.selectedConnections} size="big" onSelect={controller.handleConnectionsAccessChange}>
<TableHeader fixed>
<TableColumnHeader min />
@@ -6,11 +6,9 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
ExceptionMessage,
Group,
@@ -20,7 +18,6 @@ import {
TextPlaceholder,
useAutoLoad,
useObjectRef,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
@@ -44,7 +41,6 @@ interface IState {
}
export const OriginInfoPanel: TabContainerPanelComponent<IUserFormProps> = observer(function OriginInfoPanel({ tabId, user }) {
const style = useStyles(BASE_CONTAINERS_STYLES);
const translate = useTranslate();
const usersResource = useService(UsersResource);
const state = useTabState<IState>(() => ({
@@ -125,40 +121,40 @@ export const OriginInfoPanel: TabContainerPanelComponent<IUserFormProps> = obser
}
if (state.loading) {
return styled(style)(
return (
<ColoredContainer parent>
<Group large>
<Loader key="static" />
</Group>
</ColoredContainer>,
</ColoredContainer>
);
}
if (state.exception) {
return styled(style)(
return (
<ColoredContainer parent>
<Group large>
<ExceptionMessage exception={state.exception} onRetry={() => loadableState.reload?.()} />
</Group>
</ColoredContainer>,
</ColoredContainer>
);
}
if (!origin || (state.loaded && state.properties.length === 0)) {
return styled(style)(
return (
<ColoredContainer parent>
<Group large>
<TextPlaceholder>{translate('authentication_administration_user_origin_empty')}</TextPlaceholder>
</Group>
</ColoredContainer>,
</ColoredContainer>
);
}
return styled(style)(
return (
<ColoredContainer parent>
<Group gap large>
<ObjectPropertyInfoForm properties={state.properties} state={state.state} readOnly small autoHide />
</Group>
</ColoredContainer>,
</ColoredContainer>
);
});
@@ -11,7 +11,6 @@ import styled, { css } from 'reshadow';
import { AuthRolesResource, UserMetaParametersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Combobox,
Container,
@@ -40,7 +39,7 @@ const styles = css`
`;
export const UserInfo: TabContainerPanelComponent<IUserFormProps> = observer(function UserInfo({ controller, editing }) {
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const translate = useTranslate();
const userMetaParameters = useResource(UserInfo, UserMetaParametersResource, undefined);
const authRoles = useResource(UserInfo, AuthRolesResource, undefined);
@@ -118,7 +117,7 @@ export const UserInfo: TabContainerPanelComponent<IUserFormProps> = observer(fun
{translate('authentication_user_enabled')}
</FieldCheckbox>
<GroupTitle>{translate('authentication_user_team')}</GroupTitle>
<Group box="no-overflow" gap dense>
<Group boxNoOverflow gap dense>
{controller.teams.map(team => {
const label = `${team.teamId}${team.teamName && team.teamName !== team.teamId ? ' (' + team.teamName + ')' : ''}`;
const tooltip = `${label}${team.description ? '\n' + team.description : ''}`;
@@ -10,7 +10,7 @@ import { useState } from 'react';
import styled, { css, use } from 'reshadow';
import { AuthRolesResource } from '@cloudbeaver/core-authentication';
import { BASE_CONTAINERS_STYLES, Combobox, Filter, Group, IconOrImage, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Combobox, Filter, Group, IconOrImage, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { IUserFilters, USER_ROLE_ALL, USER_STATUSES } from './useUsersTableFilters';
@@ -61,7 +61,7 @@ interface Props {
export const UsersTableFilters = observer<Props>(function UsersTableFilters({ filters }) {
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
const style = useStyles(styles);
const authRolesResource = useResource(UsersTableFilters, AuthRolesResource, undefined);
const [open, setOpen] = useState(false);
@@ -10,18 +10,7 @@ import styled, { css } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, IAdministrationItemSubItem } from '@cloudbeaver/core-administration';
import { AUTH_PROVIDER_LOCAL_ID, AuthProvidersResource, AuthRolesResource, UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
Loader,
ToolsAction,
ToolsPanel,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { ColoredContainer, Container, Group, Loader, ToolsAction, ToolsPanel, useResource, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
@@ -52,7 +41,7 @@ interface Props {
export const UsersPage = observer<Props>(function UsersPage({ sub, param }) {
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES, styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const createUserService = useService(CreateUserService);
@@ -115,7 +104,7 @@ export const UsersPage = observer<Props>(function UsersPage({ sub, param }) {
</Group>
)}
<Group box="no-overflow">
<Group boxNoOverflow>
<Loader style={loaderStyle} state={[usersResource, authRolesResource]} overlay>
<UsersTable
keys={keys}
@@ -6,10 +6,9 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import type { AuthProvider, IAuthCredentials } from '@cloudbeaver/core-authentication';
import { BASE_CONTAINERS_STYLES, Combobox, Group, InputField, useFocus, useStyles } from '@cloudbeaver/core-blocks';
import { Combobox, Group, InputField, useFocus } from '@cloudbeaver/core-blocks';
interface Props {
provider: AuthProvider;
@@ -26,7 +25,7 @@ export const AuthProviderForm = observer<Props>(function AuthProviderForm({ prov
const profile = provider.credentialProfiles[credentials.profile as any as number];
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<Group ref={elementRef} gap small center>
{provider.credentialProfiles.length > 1 && (
<Combobox
@@ -58,6 +57,6 @@ export const AuthProviderForm = observer<Props>(function AuthProviderForm({ prov
</InputField>
),
)}
</Group>,
</Group>
);
});
@@ -10,7 +10,6 @@ import styled, { css } from 'reshadow';
import { ADMINISTRATION_TOOLS_PANEL_STYLES, AdministrationItemContentProps } from '@cloudbeaver/core-administration';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
@@ -56,7 +55,7 @@ export const ConnectionsAdministration = observer<AdministrationItemContentProps
const service = useService(CreateConnectionService);
const controller = useController(ConnectionsAdministrationController);
const translate = useTranslate();
const style = useStyles(BASE_CONTAINERS_STYLES, styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
const style = useStyles(styles, ADMINISTRATION_TOOLS_PANEL_STYLES);
useResource(ConnectionsAdministration, ConnectionInfoResource, {
key: ConnectionInfoActiveProjectKey,
@@ -109,7 +108,7 @@ export const ConnectionsAdministration = observer<AdministrationItemContentProps
<CreateConnection method={param} configurationWizard={configurationWizard} />
</Group>
)}
<Group box="no-overflow">
<Group boxNoOverflow>
<Loader style={loaderStyle} loading={controller.isProcessing} overlay>
<ConnectionsTable
keys={controller.keys}
@@ -12,7 +12,6 @@ import styled, { css } from 'reshadow';
import { TeamsResource, UsersResource } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Container,
Group,
@@ -85,16 +84,10 @@ export const ConnectionAccess: TabContainerPanelComponent<IConnectionFormProps>
info = 'cloud_connections_access_placeholder';
}
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<Loader state={[users, teams, state.state]}>
{() =>
styled(
styles,
BASE_CONTAINERS_STYLES,
)(
styled(styles)(
<ColoredContainer parent gap vertical>
{!users.resource.values.length && !teams.resource.values.length ? (
<Group keepSize large>
@@ -12,7 +12,6 @@ import styled, { css } from 'reshadow';
import type { TeamInfo } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -97,10 +96,7 @@ export const ConnectionAccessGrantedList = observer<Props>(function ConnectionAc
}
}
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<Group box medium overflow>
<container>
<ConnectionAccessTableHeader filterState={filterState} disabled={disabled}>
@@ -12,7 +12,6 @@ import styled, { css } from 'reshadow';
import type { TeamInfo } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
Button,
getComputed,
getSelectedItems,
@@ -81,10 +80,7 @@ export const ConnectionAccessList = observer<Props>(function ConnectionAccessLis
selectedSubjects.clear();
}, []);
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<Group box medium overflow>
<container>
<ConnectionAccessTableHeader filterState={filterState} disabled={disabled}>
@@ -6,10 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Container,
FieldCheckbox,
Group,
@@ -17,7 +15,6 @@ import {
ObjectPropertyInfoForm,
TextPlaceholder,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { DatabaseAuthModelsResource } from '@cloudbeaver/core-connections';
@@ -62,7 +59,7 @@ export const ConnectionAuthenticationForm = observer<Props>(function ConnectionA
properties = properties.filter(property => !property.features.some(feature => hideFeatures.includes(feature)));
}
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<Container className={className}>
{authModelId && (
<Group gap small>
@@ -98,6 +95,6 @@ export const ConnectionAuthenticationForm = observer<Props>(function ConnectionA
disabled={disabled}
/>
)}
</Container>,
</Container>
);
});
@@ -6,18 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
FieldCheckbox,
GroupTitle,
InputField,
ObjectPropertyInfoForm,
useResource,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { FieldCheckbox, GroupTitle, InputField, ObjectPropertyInfoForm, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { NetworkHandlerResource, SSH_TUNNEL_ID } from '@cloudbeaver/core-connections';
import { NetworkHandlerAuthType, NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
@@ -56,7 +46,7 @@ export const NetworkHandlerAuthForm = observer<Props>(function NetworkHandlerAut
: translate(`connections_network_handler_${id}_password`, 'connections_network_handler_default_password');
const properties = handler.data?.properties.filter(p => p.features.includes(PROPERTY_FEATURE_SECURED));
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<>
<GroupTitle>
{handler.data?.label || translate(`connections_network_handler_${id}_title`, 'connections_network_handler_default_title')}
@@ -84,6 +74,6 @@ export const NetworkHandlerAuthForm = observer<Props>(function NetworkHandlerAut
disabled={disabled}
/>
)}
</>,
</>
);
});
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, useStyles } from '@cloudbeaver/core-blocks';
import { Group } from '@cloudbeaver/core-blocks';
import type { NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
import { NetworkHandlerAuthForm } from './NetworkHandlerAuthForm';
@@ -21,13 +20,11 @@ interface Props {
}
export const NetworkHandlers = observer<Props>(function NetworkHandlers({ networkHandlers, networkHandlersConfig, allowSaveCredentials, disabled }) {
const styles = useStyles(BASE_CONTAINERS_STYLES);
if (!networkHandlers.length) {
return null;
}
return styled(styles)(
return (
<Group gap small>
{networkHandlers.map(handler => (
<NetworkHandlerAuthForm
@@ -38,6 +35,6 @@ export const NetworkHandlers = observer<Props>(function NetworkHandlers({ networ
disabled={disabled}
/>
))}
</Group>,
</Group>
);
});
@@ -9,17 +9,7 @@ import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ExceptionMessage,
IconOrImage,
Loader,
Placeholder,
useExecutor,
useObjectRef,
useStyles,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { ExceptionMessage, IconOrImage, Loader, Placeholder, useExecutor, useObjectRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
import { BASE_TAB_STYLES, TabList, TabPanelList, TabsState, UNDERLINE_TAB_BIG_STYLES, UNDERLINE_TAB_STYLES } from '@cloudbeaver/core-ui';
@@ -114,7 +104,7 @@ export const ConnectionForm = observer<Props>(function ConnectionForm({ state, o
const translate = useTranslate();
const props = useObjectRef({ onSave });
const style = [BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES, UNDERLINE_TAB_BIG_STYLES];
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
const styles = useStyles(style, topBarStyles, formStyles);
const service = useService(ConnectionFormService);
useExecutor({
@@ -10,16 +10,7 @@ import { observer } from 'mobx-react-lite';
import { useMemo, useState } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Group,
IProperty,
Loader,
PropertiesTable,
useResource,
useStyles,
} from '@cloudbeaver/core-blocks';
import { ColoredContainer, Group, IProperty, PropertiesTable, useResource, useStyles } from '@cloudbeaver/core-blocks';
import { DBDriverResource } from '@cloudbeaver/core-connections';
import { TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
import { uuid } from '@cloudbeaver/core-utils';
@@ -42,7 +33,7 @@ const styles = css`
`;
export const DriverProperties: TabContainerPanelComponent<IConnectionFormProps> = observer(function DriverProperties({ tabId, state: formState }) {
const style = useStyles(styles, BASE_CONTAINERS_STYLES);
const style = useStyles(styles);
const { selected } = useTab(tabId);
const [state] = useState(() => {
@@ -104,7 +95,7 @@ export const DriverProperties: TabContainerPanelComponent<IConnectionFormProps>
return styled(style)(
<ColoredContainer parent>
<Group box keepSize large>
<Group box large>
<PropertiesTable
properties={joinedProperties.get()}
propertiesState={formState.config.properties}
@@ -11,7 +11,6 @@ import styled, { css } from 'reshadow';
import { AUTH_PROVIDER_LOCAL_ID, EAdminPermission } from '@cloudbeaver/core-authentication';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Combobox,
Container,
@@ -168,10 +167,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
properties = info.authProperties;
}
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<SubmittingForm ref={formRef} disabled={driverMap.isLoading()} onChange={handleFormChange}>
<ColoredContainer wrap overflow parent gap>
<Container medium gap>
@@ -257,18 +253,7 @@ export const Options: TabContainerPanelComponent<IConnectionFormProps> = observe
</Group>
<Group form gap>
<Container wrap gap>
<InputField
type="text"
name="name"
minLength={1}
state={config}
disabled={disabled}
readOnly={readonly}
mod="surface"
required
tiny
fill
>
<InputField type="text" name="name" minLength={1} state={config} disabled={disabled} readOnly={readonly} mod="surface" required fill>
{translate('connections_connection_name')}
</InputField>
<ProjectSelect
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Container, InputField, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Container, InputField, useTranslate } from '@cloudbeaver/core-blocks';
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
interface Props {
@@ -23,7 +22,7 @@ interface Props {
export const ParametersForm = observer<Props>(function ParametersForm({ config, embedded, requiresServerName, disabled, readOnly, originLocal }) {
const translate = useTranslate();
return styled(useStyles(BASE_CONTAINERS_STYLES))(
return (
<Container gap>
{!embedded && (
<Container wrap gap>
@@ -43,6 +42,6 @@ export const ParametersForm = observer<Props>(function ParametersForm({ config,
{translate('customConnection_custom_server_name')}
</InputField>
)}
</Container>,
</Container>
);
});
@@ -6,9 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, Container, Group, GroupTitle, ObjectPropertyInfoForm, useTranslate } from '@cloudbeaver/core-blocks';
import { Container, Group, GroupTitle, ObjectPropertyInfoForm, useTranslate } from '@cloudbeaver/core-blocks';
import type { ConnectionConfig, DriverProviderPropertyInfoFragment } from '@cloudbeaver/core-sdk';
type DriverProviderPropertyInfo = DriverProviderPropertyInfoFragment;
@@ -32,7 +31,7 @@ export const ProviderPropertiesForm = observer<Props>(function ProviderPropertie
const booleanProperties = supportedProperties.filter(property => property.dataType === 'Boolean');
const nonBooleanProperties = supportedProperties.filter(property => property.dataType !== 'Boolean');
return styled(BASE_CONTAINERS_STYLES)(
return (
<Group form gap>
<GroupTitle>{translate('ui_settings')}</GroupTitle>
{booleanProperties.length > 0 && (
@@ -59,6 +58,6 @@ export const ProviderPropertiesForm = observer<Props>(function ProviderPropertie
/>
</Container>
)}
</Group>,
</Group>
);
});
@@ -10,7 +10,6 @@ import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
ExceptionMessage,
Group,
@@ -44,7 +43,7 @@ export const OriginInfo: TabContainerPanelComponent<IConnectionFormProps> = obse
const translate = useTranslate();
// const userInfoService = useService(UserInfoResource);
const state = useTabState<Record<string, any>>();
const styles = useStyles(style, BASE_CONTAINERS_STYLES);
const styles = useStyles(style);
const connection = useResource(
OriginInfo,
@@ -10,7 +10,6 @@ import { useCallback, useState } from 'react';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Button,
ColoredContainer,
Combobox,
@@ -74,7 +73,7 @@ export const SSH: TabContainerPanelComponent<Props> = observer(function SSH({ st
setLoading(false);
};
const styles = useStyles(SSH_STYLES, BASE_CONTAINERS_STYLES);
const styles = useStyles(SSH_STYLES);
const translate = useTranslate();
const disabled = formDisabled || loading;
const enabled = handlerState.enabled || false;
@@ -9,7 +9,6 @@ import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
FieldCheckbox,
Group,
@@ -47,7 +46,7 @@ export const SSL: TabContainerPanelComponent<Props> = observer(function SSL({ st
const translate = useTranslate();
const styles = useStyles(SSl_STYLES, BASE_CONTAINERS_STYLES);
const styles = useStyles(SSl_STYLES);
const { credentialsSavingEnabled } = useAdministrationSettings();
const { categories, isUncategorizedExists } = useObjectPropertyCategories(handler.properties);
@@ -58,7 +57,7 @@ export const SSL: TabContainerPanelComponent<Props> = observer(function SSL({ st
return styled(styles)(
<SubmittingForm>
<ColoredContainer parent>
<Group gap form keepSize large vertical>
<Group gap form large vertical>
<Switch name="enabled" state={handlerState} description={handler.description} mod={['primary']} disabled={disabled || readonly}>
{translate('connections_public_connection_ssl_enable')}
</Switch>
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Combobox, Container, FieldCheckbox, Loader, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { Combobox, Container, FieldCheckbox, Loader, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import type { DataTransferOutputSettings } from '@cloudbeaver/core-sdk';
import { DefaultExportOutputSettingsResource } from './DefaultExportOutputSettingsResource';
@@ -37,10 +37,7 @@ export const OutputOptionsForm = observer(function OutputOptionsForm(props: Prop
return null;
}
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<Container gap parent>
<Container wrap gap flexEnd>
<Combobox name="encoding" state={props.outputSettings} items={data.supportedEncodings} tiny searchable>
@@ -9,7 +9,7 @@ import { observer } from 'mobx-react-lite';
import { useRef } from 'react';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Button, Container, FieldCheckbox, Group, InputField, SubmittingForm, useTranslate } from '@cloudbeaver/core-blocks';
import { Button, Container, FieldCheckbox, Group, InputField, SubmittingForm, useTranslate } from '@cloudbeaver/core-blocks';
import { CommonDialogBody, CommonDialogFooter, CommonDialogHeader, CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
import type { IAutoRefreshSettings } from './IAutoRefreshSettings';
@@ -61,10 +61,7 @@ export const AutoRefreshSettingsDialog = observer<DialogComponentProps<Payload>>
}
}
return styled(
styles,
BASE_CONTAINERS_STYLES,
)(
return styled(styles)(
<CommonDialogWrapper size="small">
<CommonDialogHeader title="data_viewer_auto_refresh_settings" icon="/icons/settings_cog_m.svg" onReject={rejectDialog} />
<CommonDialogBody noBodyPadding noOverflow>
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css, use } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, useStyles } from '@cloudbeaver/core-blocks';
import { useStyles } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import type { ResultDataFormat } from '@cloudbeaver/core-sdk';
import { BASE_TAB_STYLES, TabList, TabsState, VERTICAL_ROTATED_TAB_STYLES } from '@cloudbeaver/core-ui';
@@ -61,7 +61,7 @@ export const TablePresentationBar = observer<Props>(function TablePresentationBa
onPresentationChange,
onClose,
}) {
const style = useStyles(styles, BASE_TAB_STYLES, VERTICAL_ROTATED_TAB_STYLES, BASE_CONTAINERS_STYLES);
const style = useStyles(styles, BASE_TAB_STYLES, VERTICAL_ROTATED_TAB_STYLES);
const dataPresentationService = useService(DataPresentationService);
const presentations = dataPresentationService.getSupportedList(type, supportedDataFormat, dataFormat, model, resultIndex);
const Tab = PresentationTab; // alias for styles matching
@@ -10,7 +10,7 @@ import { observer } from 'mobx-react-lite';
import { useMemo } from 'react';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Button, useObservableRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Button, useObservableRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';
import { QuotasService } from '@cloudbeaver/core-root';
@@ -77,7 +77,7 @@ export const TextValuePresentation: TabContainerPanelComponent<IDataValuePanelPr
const notificationService = useService(NotificationService);
const quotasService = useService(QuotasService);
const textValuePresentationService = useService(TextValuePresentationService);
const style = useStyles(styles, BASE_CONTAINERS_STYLES, UNDERLINE_TAB_STYLES, VALUE_PANEL_TOOLS_STYLES);
const style = useStyles(styles, UNDERLINE_TAB_STYLES, VALUE_PANEL_TOOLS_STYLES);
const state = useObservableRef(
() => ({
@@ -7,7 +7,7 @@
*/
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Button, Container, Group, GroupTitle, Link, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Button, Container, Group, GroupTitle, Link, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { CommonDialogBody, CommonDialogFooter, CommonDialogHeader, CommonDialogWrapper, DialogComponent } from '@cloudbeaver/core-dialogs';
import { Shortcut } from './Shortcut';
@@ -35,7 +35,7 @@ const style = css`
export const ShortcutsDialog: DialogComponent<null> = function ShortcutsDialog({ rejectDialog }) {
const translate = useTranslate();
const styles = useStyles(BASE_CONTAINERS_STYLES, style);
const styles = useStyles(style);
return styled(styles)(
<CommonDialogWrapper size="large">
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, type PlaceholderComponent, PlaceholderElement, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { type PlaceholderComponent, PlaceholderElement, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { ProjectsService } from '@cloudbeaver/core-projects';
import type { IElementsTreeSettingsProps } from '@cloudbeaver/plugin-navigation-tree';
@@ -18,7 +18,7 @@ export const ProjectsSettingsForm: PlaceholderComponent<IElementsTreeSettingsPro
style,
}) {
const projectsService = useService(ProjectsService);
const styles = useStyles(BASE_CONTAINERS_STYLES, style);
const styles = useStyles(style);
const translate = useTranslate();
if (!settings || projectsService.activeProjects.length <= 1) {
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, GroupTitle, type PlaceholderComponent, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { GroupTitle, type PlaceholderComponent, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import type { IElementsTreeSettingsProps } from './ElementsTreeSettingsService';
@@ -16,7 +16,7 @@ export const ElementsTreeBaseSettingsForm: PlaceholderComponent<IElementsTreeSet
tree: { root, settings },
style,
}) {
const styles = useStyles(BASE_CONTAINERS_STYLES, style);
const styles = useStyles(style);
const translate = useTranslate();
if (!settings) {
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import { BASE_CONTAINERS_STYLES, Group, Loader, Placeholder, PlaceholderElement, useStyles } from '@cloudbeaver/core-blocks';
import { Group, Loader, Placeholder, PlaceholderElement, useStyles } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { ElementsTreeSettingsService, IElementsTreeSettingsProps } from './ElementsTreeSettingsService';
@@ -34,7 +34,7 @@ interface Props extends IElementsTreeSettingsProps {
}
export const NavigationTreeSettings = observer<Props>(function NavigationTreeSettings({ elements, tree, style, className }) {
const styles = useStyles(BASE_CONTAINERS_STYLES, expandStyles, style);
const styles = useStyles(expandStyles, style);
const elementsTreeSettingsService = useService(ElementsTreeSettingsService);
return styled(styles)(
@@ -8,7 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import { BASE_CONTAINERS_STYLES, type PlaceholderComponent, PlaceholderElement, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { type PlaceholderComponent, PlaceholderElement, Switch, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { ProjectsService } from '@cloudbeaver/core-projects';
@@ -19,7 +19,7 @@ export const ProjectsSettingsForm: PlaceholderComponent<IElementsTreeSettingsPro
style,
}) {
const projectsService = useService(ProjectsService);
const styles = useStyles(BASE_CONTAINERS_STYLES, style);
const styles = useStyles(style);
const translate = useTranslate();
if (!settings || projectsService.activeProjects.length <= 1) {
@@ -6,10 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { observer } from 'mobx-react-lite';
import styled from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
ColoredContainer,
Group,
GroupTitle,
@@ -37,7 +35,7 @@ export const ObjectProperties = observer<Props>(function ObjectProperties({ obje
const { categories, isUncategorizedExists } = useObjectPropertyCategories(dbObject.data?.object?.properties ?? emptyArray);
const properties = dbObject.data?.object?.properties;
return styled(BASE_CONTAINERS_STYLES)(
return (
<>
{!properties || properties.length === 0 ? (
<TextPlaceholder>{translate('plugin_object_viewer_table_no_items')}</TextPlaceholder>
@@ -56,6 +54,6 @@ export const ObjectProperties = observer<Props>(function ObjectProperties({ obje
))}
</ColoredContainer>
)}
</>,
</>
);
});
@@ -8,17 +8,7 @@
import { observer } from 'mobx-react-lite';
import styled, { css } from 'reshadow';
import {
BASE_CONTAINERS_STYLES,
Button,
ColoredContainer,
FormFieldDescription,
Group,
IconOrImage,
Link,
TextPlaceholder,
useTranslate,
} from '@cloudbeaver/core-blocks';
import { Button, ColoredContainer, FormFieldDescription, Group, IconOrImage, Link, TextPlaceholder, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { CommonDialogBody, CommonDialogFooter, CommonDialogHeader, CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
import { ServerConfigResource } from '@cloudbeaver/core-root';
@@ -53,10 +43,7 @@ export const ProductInfoDialog = observer<DialogComponentProps<null>>(function P
const productInfo = serverConfigResource.data?.productInfo;
const logoIcon = themeService.currentThemeId === 'light' ? '/icons/product-logo_light.svg' : '/icons/product-logo_dark.svg';
return styled(
BASE_CONTAINERS_STYLES,
productInfoDialogStyles,
)(
return styled(productInfoDialogStyles)(
<CommonDialogWrapper size="large">
<CommonDialogHeader title="app_product_info" onReject={props.rejectDialog} />
<CommonDialogBody>

Some files were not shown because too many files have changed in this diff Show More