theme - modals, react select, tables

This commit is contained in:
Jan Prochazka
2020-11-12 14:20:02 +01:00
parent a49f429f13
commit a8d88d05db
17 changed files with 148 additions and 83 deletions

View File

@@ -118,6 +118,7 @@ export default function Screen() {
{!!currentWidget && (
<ScreenHorizontalSplitHandle
onMouseDown={onSplitDown}
theme={theme}
style={{ left: leftPanelWidth + dimensions.widgetMenu.iconSize }}
/>
)}

View File

@@ -3,6 +3,7 @@ import React from 'react';
import styled from 'styled-components';
import { ManagerInnerContainer } from '../datagrid/ManagerStyles';
import { FontIcon } from '../icons';
import useTheme from '../theme/useTheme';
import keycodes from '../utility/keycodes';
const Row = styled.div`
@@ -13,7 +14,7 @@ const Row = styled.div`
// padding: 5px;
cursor: pointer;
&:hover {
background-color: lightblue;
background-color: ${(props) => props.theme.manager_background_blue[1]};
}
`;
const Name = styled.div`
@@ -28,7 +29,7 @@ const Icon = styled(FontIcon)`
position: relative;
top: 5px;
&:hover {
background-color: gray;
background-color: ${(props) => props.theme.manager_background3};
}
padding: 5px;
`;
@@ -36,7 +37,7 @@ const EditorInput = styled.input`
width: calc(100% - 10px);
background-color: ${(props) =>
// @ts-ignore
props.isError ? '#FFCCCC' : 'white'};
props.isError ? props.theme.manager_background_red[1] : props.theme.manager_background};
`;
function ColumnNameEditor({
@@ -48,6 +49,7 @@ function ColumnNameEditor({
defaultValue = '',
...other
}) {
const theme = useTheme();
const [value, setValue] = React.useState(defaultValue || '');
const editorRef = React.useRef(null);
const isError = value && existingNames && existingNames.includes(value);
@@ -74,6 +76,7 @@ function ColumnNameEditor({
}, [focusOnCreate]);
return (
<EditorInput
theme={theme}
ref={editorRef}
type="text"
onKeyDown={handleKeyDown}
@@ -97,14 +100,15 @@ function exchange(array, i1, i2) {
function ColumnManagerRow({ column, onEdit, onRemove, onUp, onDown }) {
const [isHover, setIsHover] = React.useState(false);
const theme = useTheme();
return (
<Row onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
<Row onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)} theme={theme}>
<Name>{column.columnName}</Name>
<Buttons>
<Icon icon="icon edit" onClick={onEdit} />
<Icon icon="icon delete" onClick={onRemove} />
<Icon icon="icon arrow-up" onClick={onUp} />
<Icon icon="icon arrow-down" onClick={onDown} />
<Icon icon="icon edit" onClick={onEdit} theme={theme} />
<Icon icon="icon delete" onClick={onRemove} theme={theme} />
<Icon icon="icon arrow-up" onClick={onUp} theme={theme} />
<Icon icon="icon arrow-down" onClick={onDown} theme={theme} />
</Buttons>
</Row>
);

View File

@@ -9,9 +9,10 @@ import FreeTableGridCore from './FreeTableGridCore';
import MacroDetail from './MacroDetail';
import MacroManager from './MacroManager';
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
import useTheme from '../theme/useTheme';
const LeftContainer = styled.div`
background-color: white;
background-color: ${(props) => props.theme.manager_background};
display: flex;
flex: 1;
`;
@@ -31,6 +32,7 @@ function extractMacroValuesForMacro(macroValues, macro) {
export default function FreeTableGrid(props) {
const { modelState, dispatchModel } = props;
const theme = useTheme();
const [managerSize, setManagerSize] = React.useState(0);
const [selectedMacro, setSelectedMacro] = React.useState(null);
const [macroValues, setMacroValues] = React.useState({});
@@ -49,7 +51,7 @@ export default function FreeTableGrid(props) {
// console.log('macroValues', macroValues);
return (
<HorizontalSplitter initialValue="300px" size={managerSize} setSize={setManagerSize}>
<LeftContainer>
<LeftContainer theme={theme}>
<WidgetColumnBar>
<WidgetColumnBarItem title="Columns" name="columns" height="40%">
<FreeTableColumnEditor {...props} />

View File

@@ -24,6 +24,7 @@ import LoadingInfo from '../widgets/LoadingInfo';
import SqlEditor from '../sqleditor/SqlEditor';
import { useUploadsProvider } from '../utility/UploadsProvider';
import { FontIcon } from '../icons';
import useTheme from '../theme/useTheme';
const Container = styled.div`
// max-height: 50vh;
@@ -67,12 +68,12 @@ const SqlWrapper = styled.div`
const DragWrapper = styled.div`
padding: 10px;
background: #ddd;
background: ${(props) => props.theme.modal_background2};
`;
const ArrowWrapper = styled.div`
font-size: 30px;
color: blue;
color: ${(props) => props.theme.modal_font_blue[7]};
align-self: center;
`;
@@ -151,11 +152,12 @@ function ElectronFilesInput() {
}
function FilesInput() {
const theme = useTheme();
const electron = getElectron();
if (electron) {
return <ElectronFilesInput />;
}
return <DragWrapper>Drag &amp; drop imported files here</DragWrapper>;
return <DragWrapper theme={theme}>Drag &amp; drop imported files here</DragWrapper>;
}
function SourceTargetConfig({
@@ -308,6 +310,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
const { engine: sourceEngine } = sourceConnectionInfo || {};
const { sourceList } = values;
const { uploadListener, setUploadListener } = useUploadsProvider();
const theme = useTheme();
const handleUpload = React.useCallback(
(file) => {
@@ -352,7 +355,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined }) {
tablesField="sourceList"
engine={sourceEngine}
/>
<ArrowWrapper>
<ArrowWrapper theme={theme}>
<FontIcon icon="icon arrow-right" />
</ArrowWrapper>
<SourceTargetConfig

View File

@@ -15,6 +15,7 @@ import axios from '../utility/axios';
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
import SocketMessagesView from '../query/SocketMessagesView';
import RunnerOutputFiles from '../query/RunnerOuputFiles';
import useTheme from '../theme/useTheme';
const headerHeight = '60px';
const footerHeight = '60px';
@@ -72,9 +73,9 @@ const Footer = styled.div`
left: 0;
right: 0;
bottom: 0px;
background-color: #eeffff;
background-color: ${(props) => props.theme.modalheader_background};
border-top: 1px solid #ccc;
border-top: 1px solid ${(props) => props.theme.border};
// padding: 15px;
`;
@@ -106,6 +107,7 @@ export default function ImportExportModal({ modalState, initialValues, uploadedF
const [executeNumber, setExecuteNumber] = React.useState(0);
const [runnerId, setRunnerId] = React.useState(null);
const archive = useCurrentArchive();
const theme = useTheme();
const handleExecute = async (values) => {
const script = await createImpExpScript(values);
@@ -153,7 +155,7 @@ export default function ImportExportModal({ modalState, initialValues, uploadedF
</WidgetColumnBar>
</WidgetColumnWrapper>
</Wrapper>
<Footer>
<Footer theme={theme}>
<FooterButtons>
<FormStyledButton type="submit" value="Run" />
<GenerateSctriptButton modalState={modalState} />

View File

@@ -19,8 +19,8 @@ import useTheme from '../theme/useTheme';
// `;
const StyledModal = styled(Modal)`
border: 1px solid #ccc;
background: #fff;
border: 1px solid ${(props) => props.theme.border};
background: ${(props) => props.theme.modal_background};
overflow: auto;
webkitoverflowscrolling: touch;
outline: none;
@@ -64,6 +64,7 @@ export default function ModalBase({ modalState, children, isFlex = false, fullSc
const theme = useTheme();
return (
<StyledModal
theme={theme}
isOpen={modalState.isOpen}
onRequestClose={modalState.close}
overlayClassName="RactModalOverlay"

View File

@@ -1,12 +1,14 @@
import React from 'react';
import styled from 'styled-components';
import useTheme from '../theme/useTheme';
const Wrapper = styled.div`
border-bottom: 1px solid #ccc;
padding: 15px;
background-color: #eeffff;
background-color: ${(props) => props.theme.modalheader_background};
`;
export default function ModalFooter({ children }) {
return <Wrapper>{children}</Wrapper>;
const theme = useTheme();
return <Wrapper theme={theme}>{children}</Wrapper>;
}

View File

@@ -1,29 +1,31 @@
import React from 'react';
import styled from 'styled-components';
import { FontIcon } from '../icons';
import useTheme from '../theme/useTheme';
const Wrapper = styled.div`
font-size: 15pt;
padding: 15px;
display: flex;
justify-content: space-between;
background-color: #eeffff;
background-color: ${(props) => props.theme.modalheader_background};
`;
const CloseWrapper = styled.div`
font-size: 12pt;
&:hover {
background-color: #ccccff;
background-color: ${(props) => props.theme.modalheader_background2};
}
padding: 5px 10px;
border-radius: 10px;
border-radius: 10px;
`;
export default function ModalHeader({ children, modalState }) {
const theme = useTheme();
return (
<Wrapper>
<Wrapper theme={theme}>
<div>{children}</div>
<CloseWrapper onClick={modalState.close}>
<CloseWrapper onClick={modalState.close} theme={theme}>
<FontIcon icon="icon close" />
</CloseWrapper>
</Wrapper>

View File

@@ -1,11 +1,13 @@
import React from 'react';
import styled from 'styled-components';
import moment from 'moment';
import useTheme from '../theme/useTheme';
const MainContainer = styled.div`
flex:1
display:flex
overflow-y: scroll
flex: 1;
display: flex;
overflow-y: scroll;
background-color: ${(props) => props.theme.gridbody_background};
`;
const StyledTable = styled.table`
@@ -14,28 +16,29 @@ const StyledTable = styled.table`
border-collapse: collapse;
`;
const StyledHeader = styled.th`
const StyledHeader = styled.td`
text-align: left;
border-bottom: 2px solid #ddd;
border-bottom: 2px solid ${(props) => props.theme.border};
background-color: ${(props) => props.theme.gridheader_background};
padding: 5px;
`;
const StyledCell = styled.td`
border-top: 1px solid #ddd;
border-top: 1px solid ${(props) => props.theme.border};
padding: 5px;
`;
const StyledRow = styled.tr`
color: ${(props) =>
// @ts-ignore
props.severity == 'error' ? 'red' : 'black'};
props.severity == 'error' ? props.theme.gridbody_font_red[5] : props.theme.gridbody_font1};
${(props) =>
// @ts-ignore
props.line != null &&
`
&:hover {
background-color: #ccc;
background-color: ${props.theme.gridbody_background2};
}
`}
`;
@@ -55,6 +58,7 @@ function MessagesView({ items, onMessageClick, showProcedure = false, showLine =
const handleClick = (row) => {
if (onMessageClick) onMessageClick(row);
};
const theme = useTheme();
const mainDiv = React.useRef(null);
@@ -68,31 +72,31 @@ function MessagesView({ items, onMessageClick, showProcedure = false, showLine =
const time0 = items[0] && new Date(items[0].time).getTime();
return (
<MainContainer ref={mainDiv}>
<StyledTable>
<MainContainer ref={mainDiv} theme={theme}>
<StyledTable theme={theme}>
<tr>
<StyledHeader>Number</StyledHeader>
<StyledHeader>Message</StyledHeader>
<StyledHeader>Time</StyledHeader>
<StyledHeader>Delta</StyledHeader>
<StyledHeader>Duration</StyledHeader>
{showProcedure && <StyledHeader>Procedure</StyledHeader>}
{showLine && <StyledHeader>Line</StyledHeader>}
<StyledHeader theme={theme}>Number</StyledHeader>
<StyledHeader theme={theme}>Message</StyledHeader>
<StyledHeader theme={theme}>Time</StyledHeader>
<StyledHeader theme={theme}>Delta</StyledHeader>
<StyledHeader theme={theme}>Duration</StyledHeader>
{showProcedure && <StyledHeader theme={theme}>Procedure</StyledHeader>}
{showLine && <StyledHeader theme={theme}>Line</StyledHeader>}
</tr>
{items.map((row, index) => (
// @ts-ignore
<StyledRow key={index} severity={row.severity} line={row.line} onClick={() => handleClick(row)}>
<StyledCell>{index + 1}</StyledCell>
<StyledCell>{row.message}</StyledCell>
<StyledCell>{moment(row.time).format('HH:mm:ss')}</StyledCell>
<StyledCell>{formatDuration(new Date(row.time).getTime() - time0)}</StyledCell>
<StyledCell>
<StyledRow key={index} severity={row.severity} line={row.line} onClick={() => handleClick(row)} theme={theme}>
<StyledCell theme={theme}>{index + 1}</StyledCell>
<StyledCell theme={theme}>{row.message}</StyledCell>
<StyledCell theme={theme}>{moment(row.time).format('HH:mm:ss')}</StyledCell>
<StyledCell theme={theme}>{formatDuration(new Date(row.time).getTime() - time0)}</StyledCell>
<StyledCell theme={theme}>
{index > 0
? formatDuration(new Date(row.time).getTime() - new Date(items[index - 1].time).getTime())
: 'n/a'}
</StyledCell>
{showProcedure && <StyledCell>{row.procedure}</StyledCell>}
{showLine && <StyledCell>{row.line}</StyledCell>}
{showProcedure && <StyledCell theme={theme}>{row.procedure}</StyledCell>}
{showLine && <StyledCell theme={theme}>{row.line}</StyledCell>}
</StyledRow>
))}
</StyledTable>

View File

@@ -10,6 +10,7 @@ const theme = {
aceEditorTheme: 'twilight',
border: '#555',
border_background: '#555',
toolbar_background: '#333',
content_background: '#333',
@@ -22,6 +23,9 @@ const theme = {
gridbody_background: '#000',
scrollbar_background: '#444',
input_background: '#333',
modal_background: '#222',
modalheader_background: '#555',
button_background: '#337ab7',
statusBarBackground: '#00c',
};

View File

@@ -8,6 +8,7 @@ const theme = {
aceEditorTheme: 'github',
border: '#ccc',
border_background: '#ccc',
toolbar_background: '#eee',
content_background: '#eee',
@@ -16,11 +17,14 @@ const theme = {
title_background: '#888',
manager_background: '#fff',
tabs_background: '#eee',
gridheader_background: '#f6f7f9',
gridheader_background: '#eee',
gridheader_type: 'light',
gridbody_background: '#fff',
scrollbar_background: '#ddd',
input_background: '#fff',
modal_background: '#fff',
modalheader_background: '#eff',
button_background: '#337ab7',
statusBarBackground: '#00c',
};

View File

@@ -2,6 +2,7 @@ import React from 'react';
import _ from 'lodash';
import styled from 'styled-components';
import keycodes from './keycodes';
import useTheme from '../theme/useTheme';
const Table = styled.table`
border-collapse: collapse;
@@ -17,15 +18,15 @@ const TableHeaderRow = styled.tr``;
const TableBodyRow = styled.tr`
background-color: ${(props) =>
// @ts-ignore
props.isSelected ? '#ccccff' : ''};
props.isSelected ? props.theme.gridbody_background_blue[1] : props.theme.gridbody_background};
`;
const TableHeaderCell = styled.td`
border: 1px solid #e8eef4;
background-color: #e8eef4;
border: 1px solid ${(props) => props.theme.gridheader_background};
background-color: ${(props) => props.theme.gridheader_background};
padding: 5px;
`;
const TableBodyCell = styled.td`
border: 1px solid #e8eef4;
border: 1px solid ${(props) => props.theme.gridbody_background2};
padding: 5px;
`;
@@ -55,6 +56,7 @@ export default function TableControl({
const myTableRef = React.useRef(null);
const currentTableRef = tableRef || myTableRef;
const theme = useTheme();
React.useEffect(() => {
if (focusOnCreate) {
@@ -62,15 +64,18 @@ export default function TableControl({
}
}, []);
const handleKeyDown = React.useCallback((event) => {
if (event.keyCode == keycodes.downArrow) {
setSelectedIndex((i) => Math.min(i + 1, rows.length - 1));
}
if (event.keyCode == keycodes.upArrow) {
setSelectedIndex((i) => Math.max(0, i - 1));
}
if (onKeyDown) onKeyDown(event);
}, [setSelectedIndex, rows]);
const handleKeyDown = React.useCallback(
(event) => {
if (event.keyCode == keycodes.downArrow) {
setSelectedIndex((i) => Math.min(i + 1, rows.length - 1));
}
if (event.keyCode == keycodes.upArrow) {
setSelectedIndex((i) => Math.max(0, i - 1));
}
if (onKeyDown) onKeyDown(event);
},
[setSelectedIndex, rows]
);
return (
<Table
@@ -83,7 +88,9 @@ export default function TableControl({
<TableHead>
<TableHeaderRow>
{columns.map((x) => (
<TableHeaderCell key={x.fieldName}>{x.header}</TableHeaderCell>
<TableHeaderCell key={x.fieldName} theme={theme}>
{x.header}
</TableHeaderCell>
))}
</TableHeaderRow>
</TableHead>
@@ -91,6 +98,7 @@ export default function TableControl({
{rows.map((row, index) => (
<TableBodyRow
key={index}
theme={theme}
// @ts-ignore
isSelected={index == selectedIndex}
onClick={
@@ -103,7 +111,7 @@ export default function TableControl({
}
>
{columns.map((col) => (
<TableBodyCell key={col.fieldName}>{format(row, col)}</TableBodyCell>
<TableBodyCell key={col.fieldName} theme={theme}>{format(row, col)}</TableBodyCell>
))}
</TableBodyRow>
))}

View File

@@ -15,6 +15,7 @@ import {
import useSocket from './SocketProvider';
import getAsArray from './getAsArray';
import axios from './axios';
import useTheme from '../theme/useTheme';
export const FormRow = styled.div`
display: flex;
@@ -115,9 +116,32 @@ export function FormRadioGroupItem({ name, text, value }) {
export function FormReactSelect({ options, name, isMulti = false, Component = Select, ...other }) {
const { setFieldValue, values } = useFormikContext();
const theme = useTheme();
return (
<Component
theme={(t) => ({
...t,
colors: {
...t.colors,
neutral0: theme.input_background,
neutral10: theme.input_background2,
neutral20: theme.input_background3,
neutral30: theme.input_background4,
neutral40: theme.input_font3,
neutral50: theme.input_font3,
neutral60: theme.input_font2,
neutral70: theme.input_font2,
neutral80: theme.input_font2,
neutral90: theme.input_font1,
primary: theme.input_background_blue[5],
primary75: theme.input_background_blue[3],
primary50: theme.input_background_blue[2],
primary25: theme.input_background_blue[0],
danger: theme.input_background_red[5],
dangerLight: theme.input_background_red[1],
},
})}
options={options}
value={
isMulti

View File

@@ -2,40 +2,40 @@
import React from 'react';
import styled from 'styled-components';
import dimensions from '../theme/dimensions';
import useTheme from '../theme/useTheme';
const ButtonInput = styled.input`
// height: ${dimensions.toolBar.height - 5}px;
border: 1px solid #2e6da4;
border: 1px solid ${(props) => props.theme.button_background2};
padding: 5px;
margin: 2px;
width: 100px;
//background-color: #777;
background-color: #337ab7;
// border-color: #2e6da4;
color: white;
background-color: ${(props) => props.theme.button_background};
color: ${(props) => props.theme.button_font1};
border-radius: 2px;
${(props) =>
!props.disabled &&
`
&:hover {
background-color: #286090;
background-color: ${props.theme.button_background2};
}
&:active:hover {
background-color: #204d74;
background-color: ${props.theme.button_background3};
}
`}
${(props) =>
props.disabled &&
`
background-color: #ccc;
color: gray;
background-color: ${props.theme.button_background3};
color: ${props.theme.button_font3} ;
`}
`;
// ${props.theme.button_background_gray[1]};
export default function FormStyledButton({
onClick = undefined,
type = 'button',
@@ -43,9 +43,11 @@ export default function FormStyledButton({
disabled = undefined,
...other
}) {
const theme = useTheme();
return (
<ButtonInput
type={type}
theme={theme}
onClick={
onClick
? () => {

View File

@@ -28,11 +28,11 @@ const HorizontalMainContainer = styled(SplitterMainBase)`
`;
export const VerticalSplitHandle = styled.div`
background-color: ${(props) => props.theme.border};
height: ${dimensions.splitter.thickness}px;
background-color: ${(props) => props.theme.border};
height: ${dimensions.splitter.thickness}px;
cursor: row-resize;
&:hover {
background-color: #aaa;
background-color: ${(props) => props.theme.border_background2};
}
`;
@@ -41,7 +41,7 @@ export const HorizontalSplitHandle = styled.div`
width: ${dimensions.splitter.thickness}px;
cursor: col-resize;
&:hover {
background-color: #aaa;
background-color: ${(props) => props.theme.border_background2};
}
`;

View File

@@ -108,7 +108,7 @@ export default function ToolBar({ toolbarPortalRef }) {
Import data
</ToolbarButton>
<ToolbarButton onClick={switchTheme} icon="icon theme">
Switch theme
{currentTheme == 'dark' ? 'Light mode' : 'Dark mode'}
</ToolbarButton>
<ToolbarContainer ref={toolbarPortalRef}></ToolbarContainer>

View File

@@ -9,6 +9,7 @@ import {
} from './WidgetStyles';
import { VerticalSplitHandle, useSplitterDrag } from './Splitter';
import useDimensions from '../utility/useDimensions';
import useTheme from '../theme/useTheme';
export function WidgetColumnBarItem({ title, children, name, height = undefined, collapsed = false }) {
return <></>;
@@ -16,6 +17,7 @@ export function WidgetColumnBarItem({ title, children, name, height = undefined,
function WidgetContainer({ widget, visible, splitterVisible, parentHeight, initialSize = undefined }) {
const [size, setSize] = React.useState(null);
const theme = useTheme();
const handleResizeDown = useSplitterDrag('clientY', (diff) => setSize((v) => v + diff));
@@ -33,7 +35,7 @@ function WidgetContainer({ widget, visible, splitterVisible, parentHeight, initi
<WidgetsOuterContainer style={splitterVisible ? { height: size } : null}>
{widget.props.children}
</WidgetsOuterContainer>
{splitterVisible && <VerticalSplitHandle onMouseDown={handleResizeDown} />}
{splitterVisible && <VerticalSplitHandle onMouseDown={handleResizeDown} theme={theme} />}
</>
);
}