mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +00:00
removed formik, used own FormProvider instead
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
"dbgate-tools": "^1.0.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-react": "^7.17.0",
|
||||
"formik": "^2.1.0",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"localforage": "^1.9.0",
|
||||
"react": "^16.12.0",
|
||||
|
||||
@@ -6,8 +6,8 @@ import useDimensions from '../utility/useDimensions';
|
||||
import { HorizontalSplitter } from '../widgets/Splitter';
|
||||
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
|
||||
import { FormCheckboxField, FormSelectField } from '../utility/forms';
|
||||
import { Formik, Form } from 'formik';
|
||||
import DataChart from './DataChart';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
const LeftContainer = styled.div`
|
||||
background-color: ${(props) => props.theme.manager_background};
|
||||
@@ -21,36 +21,34 @@ export default function ChartEditor({ data }) {
|
||||
const availableColumnNames = data ? data.structure.columns.map((x) => x.columnName) : [];
|
||||
|
||||
return (
|
||||
<Formik initialValues={{ chartType: 'bar' }} onSubmit={() => {}}>
|
||||
<Form>
|
||||
<HorizontalSplitter initialValue="300px" size={managerSize} setSize={setManagerSize}>
|
||||
<LeftContainer theme={theme}>
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Style" name="style" height="40%">
|
||||
<FormSelectField label="Chart type" name="chartType">
|
||||
<option value="bar">Bar</option>
|
||||
<option value="line">Line</option>
|
||||
</FormSelectField>
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Data" name="data">
|
||||
<FormSelectField label="Label column" name="labelColumn">
|
||||
<option value=""></option>
|
||||
{availableColumnNames.map((col) => (
|
||||
<option value={col} key={col}>
|
||||
{col}
|
||||
</option>
|
||||
))}
|
||||
</FormSelectField>
|
||||
<FormProvider initialValues={{ chartType: 'bar' }}>
|
||||
<HorizontalSplitter initialValue="300px" size={managerSize} setSize={setManagerSize}>
|
||||
<LeftContainer theme={theme}>
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Style" name="style" height="40%">
|
||||
<FormSelectField label="Chart type" name="chartType">
|
||||
<option value="bar">Bar</option>
|
||||
<option value="line">Line</option>
|
||||
</FormSelectField>
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Data" name="data">
|
||||
<FormSelectField label="Label column" name="labelColumn">
|
||||
<option value=""></option>
|
||||
{availableColumnNames.map((col) => (
|
||||
<FormCheckboxField label={col} name={`dataColumn_${col}`} key={col} />
|
||||
<option value={col} key={col}>
|
||||
{col}
|
||||
</option>
|
||||
))}
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
</LeftContainer>
|
||||
</FormSelectField>
|
||||
{availableColumnNames.map((col) => (
|
||||
<FormCheckboxField label={col} name={`dataColumn_${col}`} key={col} />
|
||||
))}
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
</LeftContainer>
|
||||
|
||||
<DataChart data={data} />
|
||||
</HorizontalSplitter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<DataChart data={data} />
|
||||
</HorizontalSplitter>
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import useDimensions from '../utility/useDimensions';
|
||||
import { HorizontalSplitter } from '../widgets/Splitter';
|
||||
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
|
||||
import { FormSelectField } from '../utility/forms';
|
||||
import { Formik, Form, useFormikContext } from 'formik';
|
||||
import { useForm } from '../utility/FormProvider';
|
||||
|
||||
const ChartWrapper = styled.div`
|
||||
flex: 1;
|
||||
@@ -75,7 +75,7 @@ function createChartData(freeData, labelColumn, dataColumns) {
|
||||
|
||||
export default function DataChart({ data }) {
|
||||
const [containerRef, { height: containerHeight, width: containerWidth }] = useDimensions();
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
|
||||
const { labelColumn } = values;
|
||||
const dataColumns = [];
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import { Formik, Form, useFormikContext } from 'formik';
|
||||
import FormArgumentList from '../utility/FormArgumentList';
|
||||
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
export default function MacroParameters({ args, onChangeValues, macroValues, namePrefix }) {
|
||||
if (!args || args.length == 0) return null;
|
||||
@@ -11,10 +10,8 @@ export default function MacroParameters({ args, onChangeValues, macroValues, nam
|
||||
...macroValues,
|
||||
};
|
||||
return (
|
||||
<Formik initialValues={initialValues} onSubmit={() => {}}>
|
||||
<Form>
|
||||
<FormArgumentList args={args} onChangeValues={onChangeValues} namePrefix={namePrefix} />
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormProvider initialValues={initialValues}>
|
||||
<FormArgumentList args={args} onChangeValues={onChangeValues} namePrefix={namePrefix} />
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import FormStyledButton from '../widgets/FormStyledButton';
|
||||
import { useFormikContext } from 'formik';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
FormReactSelect,
|
||||
@@ -30,6 +29,7 @@ import useExtensions from '../utility/useExtensions';
|
||||
import UploadButton from '../utility/UploadButton';
|
||||
import useShowModal from '../modals/showModal';
|
||||
import ChangeDownloadUrlModal from '../modals/ChangeDownloadUrlModal';
|
||||
import { useForm } from '../utility/FormProvider';
|
||||
|
||||
const Container = styled.div`
|
||||
// max-height: 50vh;
|
||||
@@ -142,7 +142,7 @@ async function addFilesToSourceList(extensions, files, values, setValues, prefer
|
||||
}
|
||||
|
||||
function ElectronFilesInput() {
|
||||
const { values, setValues } = useFormikContext();
|
||||
const { values, setValues } = useForm();
|
||||
const electron = getElectron();
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const extensions = useExtensions();
|
||||
@@ -195,7 +195,7 @@ function FilesInput({ setPreviewSource = undefined }) {
|
||||
const theme = useTheme();
|
||||
const electron = getElectron();
|
||||
const showModal = useShowModal();
|
||||
const { values, setValues } = useFormikContext();
|
||||
const { values, setValues } = useForm();
|
||||
const extensions = useExtensions();
|
||||
const doAddUrl = (url) => {
|
||||
addFilesToSourceList(
|
||||
@@ -239,7 +239,7 @@ function SourceTargetConfig({
|
||||
}) {
|
||||
const extensions = useExtensions();
|
||||
const theme = useTheme();
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
const { values, setFieldValue } = useForm();
|
||||
const types =
|
||||
values[storageTypeField] == 'jsldata'
|
||||
? [{ value: 'jsldata', label: 'Query result data', directions: ['source'] }]
|
||||
@@ -375,7 +375,7 @@ function SourceTargetConfig({
|
||||
}
|
||||
|
||||
function SourceName({ name }) {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
const { values, setFieldValue } = useForm();
|
||||
const theme = useTheme();
|
||||
const showModal = useShowModal();
|
||||
const obj = values[`sourceFile_${name}`];
|
||||
@@ -412,7 +412,7 @@ function SourceName({ name }) {
|
||||
}
|
||||
|
||||
export default function ImportExportConfigurator({ uploadedFile = undefined, onChangePreview = undefined }) {
|
||||
const { values, setFieldValue, setValues } = useFormikContext();
|
||||
const { values, setFieldValue, setValues } = useForm();
|
||||
const targetDbinfo = useDatabaseInfo({ conid: values.targetConnectionId, database: values.targetDatabaseName });
|
||||
const sourceConnectionInfo = useConnectionInfo({ conid: values.sourceConnectionId });
|
||||
const { engine: sourceEngine } = sourceConnectionInfo || {};
|
||||
|
||||
@@ -1,38 +1,33 @@
|
||||
import React from 'react';
|
||||
import axios from '../utility/axios';
|
||||
import ModalBase from './ModalBase';
|
||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormButton, FormSubmit, FormTextField } from '../utility/forms';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import FormStyledButton from '../widgets/FormStyledButton';
|
||||
// import FormikForm from '../utility/FormikForm';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
export default function ChangeDownloadUrlModal({ modalState, url = '', onConfirm = undefined }) {
|
||||
const textFieldRef = React.useRef(null);
|
||||
React.useEffect(() => {
|
||||
if (textFieldRef.current) textFieldRef.current.focus();
|
||||
}, [textFieldRef.current]);
|
||||
// const textFieldRef = React.useRef(null);
|
||||
// React.useEffect(() => {
|
||||
// if (textFieldRef.current) textFieldRef.current.focus();
|
||||
// }, [textFieldRef.current]);
|
||||
const handleSubmit = async (values) => {
|
||||
onConfirm(values.url);
|
||||
modalState.close();
|
||||
};
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<ModalHeader modalState={modalState}>Dwonload imported file from web</ModalHeader>
|
||||
<Formik onSubmit={handleSubmit} initialValues={{ url }}>
|
||||
<Form>
|
||||
<ModalContent>
|
||||
<FormTextField label="URL" name="url" editorRef={textFieldRef} style={{ width: '30vw' }} />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit text="OK" />
|
||||
<FormStyledButton value="Cancel" onClick={() => modalState.close()} />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<ModalHeader modalState={modalState}>Download imported file from web</ModalHeader>
|
||||
<FormProvider initialValues={{ url }}>
|
||||
<ModalContent>
|
||||
<FormTextField label="URL" name="url" style={{ width: '30vw' }} focused />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit value="OK" onClick={handleSubmit} />
|
||||
<FormStyledButton value="Cancel" onClick={() => modalState.close()} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import React from 'react';
|
||||
import axios from '../utility/axios';
|
||||
import ModalBase from './ModalBase';
|
||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import ModalContent from './ModalContent';
|
||||
import useExtensions from '../utility/useExtensions';
|
||||
import LoadingInfo from '../widgets/LoadingInfo';
|
||||
import { FontIcon } from '../icons';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
// import FormikForm from '../utility/FormikForm';
|
||||
|
||||
export default function ConnectionModal({ modalState, connection = undefined }) {
|
||||
@@ -41,49 +40,47 @@ export default function ConnectionModal({ modalState, connection = undefined })
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<ModalHeader modalState={modalState}>{connection ? 'Edit connection' : 'Add connection'}</ModalHeader>
|
||||
<Formik onSubmit={handleSubmit} initialValues={connection || { server: 'localhost', engine: 'mssql' }}>
|
||||
<Form>
|
||||
<ModalContent>
|
||||
<FormSelectField label="Database engine" name="engine">
|
||||
<option value=""></option>
|
||||
{extensions.drivers.map((driver) => (
|
||||
<option value={driver.engine} key={driver.engine}>
|
||||
{driver.title}
|
||||
</option>
|
||||
))}
|
||||
{/* <option value="mssql">Microsoft SQL Server</option>
|
||||
<FormProvider initialValues={connection || { server: 'localhost', engine: 'mssql' }}>
|
||||
<ModalContent>
|
||||
<FormSelectField label="Database engine" name="engine">
|
||||
<option value=""></option>
|
||||
{extensions.drivers.map((driver) => (
|
||||
<option value={driver.engine} key={driver.engine}>
|
||||
{driver.title}
|
||||
</option>
|
||||
))}
|
||||
{/* <option value="mssql">Microsoft SQL Server</option>
|
||||
<option value="mysql">MySQL</option>
|
||||
<option value="postgres">Postgre SQL</option> */}
|
||||
</FormSelectField>
|
||||
<FormTextField label="Server" name="server" />
|
||||
<FormTextField label="Port" name="port" />
|
||||
<FormTextField label="User" name="user" />
|
||||
<FormTextField label="Password" name="password" type="password" />
|
||||
<FormTextField label="Display name" name="displayName" />
|
||||
{!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'connected' && (
|
||||
<div>
|
||||
Connected: <FontIcon icon="img ok" /> {sqlConnectResult.version}
|
||||
</div>
|
||||
)}
|
||||
{!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'error' && (
|
||||
<div>
|
||||
Connect failed: <FontIcon icon="img error" /> {sqlConnectResult.error}
|
||||
</div>
|
||||
)}
|
||||
{isTesting && <LoadingInfo message="Testing connection" />}
|
||||
</ModalContent>
|
||||
</FormSelectField>
|
||||
<FormTextField label="Server" name="server" />
|
||||
<FormTextField label="Port" name="port" />
|
||||
<FormTextField label="User" name="user" />
|
||||
<FormTextField label="Password" name="password" type="password" />
|
||||
<FormTextField label="Display name" name="displayName" />
|
||||
{!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'connected' && (
|
||||
<div>
|
||||
Connected: <FontIcon icon="img ok" /> {sqlConnectResult.version}
|
||||
</div>
|
||||
)}
|
||||
{!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'error' && (
|
||||
<div>
|
||||
Connect failed: <FontIcon icon="img error" /> {sqlConnectResult.error}
|
||||
</div>
|
||||
)}
|
||||
{isTesting && <LoadingInfo message="Testing connection" />}
|
||||
</ModalContent>
|
||||
|
||||
<ModalFooter>
|
||||
{isTesting ? (
|
||||
<FormButton text="Cancel" onClick={handleCancel} />
|
||||
) : (
|
||||
<FormButton text="Test" onClick={handleTest} />
|
||||
)}
|
||||
<ModalFooter>
|
||||
{isTesting ? (
|
||||
<FormButton value="Cancel" onClick={handleCancel} />
|
||||
) : (
|
||||
<FormButton value="Test" onClick={handleTest} />
|
||||
)}
|
||||
|
||||
<FormSubmit text="Save" />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormSubmit value="Save" onClick={handleSubmit} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import axios from '../utility/axios';
|
||||
import ModalBase from './ModalBase';
|
||||
import { FormTextField, FormSubmit } from '../utility/forms';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormButton, FormSubmit, FormTextField } from '../utility/forms';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
export default function CreateDatabaseModal({ modalState, conid }) {
|
||||
const handleSubmit = async (values) => {
|
||||
@@ -17,16 +17,14 @@ export default function CreateDatabaseModal({ modalState, conid }) {
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<ModalHeader modalState={modalState}>Create database</ModalHeader>
|
||||
<Formik onSubmit={handleSubmit} initialValues={{ name: 'newdb' }}>
|
||||
<Form>
|
||||
<ModalContent>
|
||||
<FormTextField label="Database name" name="name" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit text="Create" />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormProvider initialValues={{ name: 'newdb' }}>
|
||||
<ModalContent>
|
||||
<FormTextField label="Database name" name="name" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit value="Create" onClick={handleSubmit} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
import moment from 'moment';
|
||||
import ModalBase from './ModalBase';
|
||||
import FormStyledButton from '../widgets/FormStyledButton';
|
||||
import { Formik, Form, useFormikContext } from 'formik';
|
||||
import styled from 'styled-components';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalFooter from './ModalFooter';
|
||||
@@ -21,9 +20,10 @@ import PreviewDataGrid from '../impexp/PreviewDataGrid';
|
||||
import useSocket from '../utility/SocketProvider';
|
||||
import LoadingInfo from '../widgets/LoadingInfo';
|
||||
import { FontIcon } from '../icons';
|
||||
import LargeButton from '../widgets/LargeButton';
|
||||
import LargeButton, { LargeFormButton } from '../widgets/LargeButton';
|
||||
import { getDefaultFileFormat } from '../utility/fileformats';
|
||||
import useExtensions from '../utility/useExtensions';
|
||||
import { FormProvider, useForm } from '../utility/FormProvider';
|
||||
|
||||
const headerHeight = '60px';
|
||||
const footerHeight = '100px';
|
||||
@@ -54,7 +54,7 @@ const WidgetColumnWrapper = styled.div`
|
||||
border-left: 1px solid ${(props) => props.theme.border};
|
||||
`;
|
||||
|
||||
const StyledForm = styled(Form)`
|
||||
const FormWrapper = styled.div`
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -92,7 +92,7 @@ const FooterButtons = styled.div`
|
||||
|
||||
function GenerateSctriptButton({ modalState }) {
|
||||
const setOpenedTabs = useSetOpenedTabs();
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
const extensions = useExtensions();
|
||||
|
||||
const handleGenerateScript = async () => {
|
||||
@@ -116,18 +116,6 @@ function GenerateSctriptButton({ modalState }) {
|
||||
);
|
||||
}
|
||||
|
||||
function RunButton() {
|
||||
const { submitForm } = useFormikContext();
|
||||
const handleSubmit = () => {
|
||||
submitForm();
|
||||
};
|
||||
return (
|
||||
<LargeButton onClick={handleSubmit} icon="icon run">
|
||||
Run
|
||||
</LargeButton>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ImportExportModal({
|
||||
modalState,
|
||||
initialValues,
|
||||
@@ -194,8 +182,7 @@ export default function ImportExportModal({
|
||||
|
||||
return (
|
||||
<ModalBase modalState={modalState} fullScreen isFlex>
|
||||
<Formik
|
||||
onSubmit={handleExecute}
|
||||
<FormProvider
|
||||
initialValues={{
|
||||
sourceStorageType: 'database',
|
||||
targetStorageType: importToArchive ? 'archive' : getDefaultFileFormat(extensions).storageType,
|
||||
@@ -204,7 +191,7 @@ export default function ImportExportModal({
|
||||
...initialValues,
|
||||
}}
|
||||
>
|
||||
<StyledForm>
|
||||
<FormWrapper>
|
||||
<ModalHeader modalState={modalState}>Import/Export {busy && <FontIcon icon="icon loading" />}</ModalHeader>
|
||||
<Wrapper>
|
||||
<ContentWrapper theme={theme}>
|
||||
@@ -236,7 +223,9 @@ export default function ImportExportModal({
|
||||
Cancel
|
||||
</LargeButton>
|
||||
) : (
|
||||
<RunButton />
|
||||
<LargeFormButton onClick={handleExecute} icon="icon run">
|
||||
Run
|
||||
</LargeFormButton>
|
||||
)}
|
||||
<GenerateSctriptButton modalState={modalState} />
|
||||
<LargeButton onClick={modalState.close} icon="icon close">
|
||||
@@ -244,8 +233,8 @@ export default function ImportExportModal({
|
||||
</LargeButton>
|
||||
</FooterButtons>
|
||||
</Footer>
|
||||
</StyledForm>
|
||||
</Formik>
|
||||
</FormWrapper>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import ModalBase from './ModalBase';
|
||||
import { FormTextField, FormSubmit, FormArchiveFolderSelect, FormRow, FormLabel } from '../utility/forms';
|
||||
import { Formik, Form } from 'formik';
|
||||
import styled from 'styled-components';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
const SelectWrapper = styled.div`
|
||||
width: 150px;
|
||||
@@ -22,23 +22,21 @@ export default function SaveArchiveModal({ file = 'new-table', folder = 'default
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<ModalHeader modalState={modalState}>Save to archive</ModalHeader>
|
||||
<Formik onSubmit={handleSubmit} initialValues={{ file, folder }}>
|
||||
<Form>
|
||||
<ModalContent>
|
||||
{/* <Label>Archive folder</Label> */}
|
||||
<FormRow>
|
||||
<FormLabel>Folder</FormLabel>
|
||||
<SelectWrapper>
|
||||
<FormArchiveFolderSelect name="folder" />
|
||||
</SelectWrapper>
|
||||
</FormRow>
|
||||
<FormTextField label="File name" name="file" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit text="Save" />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormProvider initialValues={{ file, folder }}>
|
||||
<ModalContent>
|
||||
{/* <Label>Archive folder</Label> */}
|
||||
<FormRow>
|
||||
<FormLabel>Folder</FormLabel>
|
||||
<SelectWrapper>
|
||||
<FormArchiveFolderSelect name="folder" />
|
||||
</SelectWrapper>
|
||||
</FormRow>
|
||||
<FormTextField label="File name" name="file" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit value="Save" onClick={handleSubmit} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ import axios from '../utility/axios';
|
||||
import ModalBase from './ModalBase';
|
||||
import { FormButtonRow, FormButton, FormTextField, FormSelectField, FormSubmit } from '../utility/forms';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { Formik, Form } from 'formik';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalContent from './ModalContent';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
// import FormikForm from '../utility/FormikForm';
|
||||
|
||||
export default function SaveFileModal({ data, folder, format, modalState, name, onSave = undefined }) {
|
||||
@@ -19,16 +19,14 @@ export default function SaveFileModal({ data, folder, format, modalState, name,
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<ModalHeader modalState={modalState}>Save file</ModalHeader>
|
||||
<Formik onSubmit={handleSubmit} initialValues={{ name }}>
|
||||
<Form>
|
||||
<ModalContent>
|
||||
<FormTextField label="File name" name="name" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit text="Save" />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormProvider initialValues={{ name }}>
|
||||
<ModalContent>
|
||||
<FormTextField label="File name" name="name" />
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit value="Save" onClick={handleSubmit} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,19 @@ import React from 'react';
|
||||
import ModalBase from './ModalBase';
|
||||
import FormStyledButton from '../widgets/FormStyledButton';
|
||||
import styled from 'styled-components';
|
||||
import { FormButtonRow, FormSubmit, FormSelectFieldRaw, FormRow, FormRadioGroupItem, FormTextFieldRaw } from '../utility/forms';
|
||||
import {
|
||||
FormButtonRow,
|
||||
FormSubmit,
|
||||
FormSelectFieldRaw,
|
||||
FormRow,
|
||||
FormRadioGroupItem,
|
||||
FormTextFieldRaw,
|
||||
} from '../utility/forms';
|
||||
import ModalHeader from './ModalHeader';
|
||||
import ModalFooter from './ModalFooter';
|
||||
import ModalContent from './ModalContent';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { TextField } from '../utility/inputs';
|
||||
import { FormProvider } from '../utility/FormProvider';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
@@ -104,30 +111,28 @@ export default function SetFilterModal({ modalState, onFilter, filterType, condi
|
||||
|
||||
return (
|
||||
<ModalBase modalState={modalState}>
|
||||
<Formik onSubmit={handleOk} initialValues={{ condition1, condition2: '=', joinOperator: ' ' }}>
|
||||
<Form>
|
||||
<ModalHeader modalState={modalState}>Set filter</ModalHeader>
|
||||
<ModalContent>
|
||||
<FormRow>Show rows where</FormRow>
|
||||
<FormRow>
|
||||
<Select filterType={filterType} name="condition1" />
|
||||
<FormTextFieldRaw name="value1" editorRef={editorRef} />
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<FormRadioGroupItem name="joinOperator" value=" " text="And" />
|
||||
<FormRadioGroupItem name="joinOperator" value="," text="Or" />
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Select filterType={filterType} name="condition2" />
|
||||
<FormTextFieldRaw name="value2" />
|
||||
</FormRow>
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit text="OK" />
|
||||
<FormStyledButton type="button" value="Close" onClick={modalState.close} />
|
||||
</ModalFooter>
|
||||
</Form>
|
||||
</Formik>
|
||||
<FormProvider initialValues={{ condition1, condition2: '=', joinOperator: ' ' }}>
|
||||
<ModalHeader modalState={modalState}>Set filter</ModalHeader>
|
||||
<ModalContent>
|
||||
<FormRow>Show rows where</FormRow>
|
||||
<FormRow>
|
||||
<Select filterType={filterType} name="condition1" />
|
||||
<FormTextFieldRaw name="value1" editorRef={editorRef} />
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<FormRadioGroupItem name="joinOperator" value=" " text="And" />
|
||||
<FormRadioGroupItem name="joinOperator" value="," text="Or" />
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Select filterType={filterType} name="condition2" />
|
||||
<FormTextFieldRaw name="value2" />
|
||||
</FormRow>
|
||||
</ModalContent>
|
||||
<ModalFooter>
|
||||
<FormSubmit value="OK" onClick={handleOk} />
|
||||
<FormStyledButton type="button" value="Close" onClick={modalState.close} />
|
||||
</ModalFooter>
|
||||
</FormProvider>
|
||||
</ModalBase>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
FormTextField,
|
||||
FormSubmit,
|
||||
FormArchiveFolderSelect,
|
||||
FormRow,
|
||||
FormLabel,
|
||||
FormSelectField,
|
||||
FormCheckboxField,
|
||||
} from './forms';
|
||||
import { Formik, Form, useFormikContext } from 'formik';
|
||||
import { FormTextField, FormSelectField, FormCheckboxField } from './forms';
|
||||
import { useForm } from './FormProvider';
|
||||
|
||||
const FormArgumentsWrapper = styled.div``;
|
||||
|
||||
@@ -35,7 +27,7 @@ function FormArgument({ arg, namePrefix }) {
|
||||
}
|
||||
|
||||
export default function FormArgumentList({ args, onChangeValues = undefined, namePrefix }) {
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
React.useEffect(() => {
|
||||
if (onChangeValues) onChangeValues(values);
|
||||
}, [values]);
|
||||
|
||||
25
packages/web/src/utility/FormProvider.js
Normal file
25
packages/web/src/utility/FormProvider.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
const FormContext = React.createContext(null);
|
||||
|
||||
export function FormProvider({ children, initialValues }) {
|
||||
const [values, setValues] = React.useState(initialValues);
|
||||
const setFieldValue = React.useCallback(
|
||||
(field, value) =>
|
||||
setValues((v) => ({
|
||||
...v,
|
||||
[field]: value,
|
||||
})),
|
||||
[setValues]
|
||||
);
|
||||
const provider = {
|
||||
values,
|
||||
setValues,
|
||||
setFieldValue,
|
||||
};
|
||||
return <FormContext.Provider value={provider}>{children}</FormContext.Provider>;
|
||||
}
|
||||
|
||||
export function useForm() {
|
||||
return React.useContext(FormContext);
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import styled from 'styled-components';
|
||||
import Select from 'react-select';
|
||||
import Creatable from 'react-select/creatable';
|
||||
import { TextField, SelectField, CheckboxField } from './inputs';
|
||||
import { Field, useFormikContext } from 'formik';
|
||||
import FormStyledButton from '../widgets/FormStyledButton';
|
||||
import {
|
||||
useConnectionList,
|
||||
@@ -12,10 +11,10 @@ import {
|
||||
useArchiveFolders,
|
||||
useArchiveFiles,
|
||||
} from './metadataLoaders';
|
||||
import useSocket from './SocketProvider';
|
||||
import getAsArray from './getAsArray';
|
||||
import axios from './axios';
|
||||
import useTheme from '../theme/useTheme';
|
||||
import { useForm } from './FormProvider';
|
||||
|
||||
export const FormRow = styled.div`
|
||||
display: flex;
|
||||
@@ -35,23 +34,32 @@ export const FormLabel = styled.div`
|
||||
|
||||
export const FormValue = styled.div``;
|
||||
|
||||
export function FormTextFieldRaw({ ...other }) {
|
||||
return <Field {...other} as={TextField} />;
|
||||
export function FormTextFieldRaw({ name, focused = false, ...other }) {
|
||||
const { values, setFieldValue } = useForm();
|
||||
const handleChange = (event) => {
|
||||
setFieldValue(name, event.target.value);
|
||||
};
|
||||
const textFieldRef = React.useRef(null);
|
||||
React.useEffect(() => {
|
||||
if (textFieldRef.current && focused) textFieldRef.current.focus();
|
||||
}, [textFieldRef.current, focused]);
|
||||
|
||||
return <TextField {...other} value={values[name]} onChange={handleChange} editorRef={textFieldRef} />;
|
||||
}
|
||||
|
||||
export function FormTextField({ label, ...other }) {
|
||||
export function FormTextField({ name, label, focused = false, ...other }) {
|
||||
return (
|
||||
<FormRow>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
<FormValue>
|
||||
<FormTextFieldRaw {...other} />
|
||||
<FormTextFieldRaw name={name} focused={focused} {...other} />
|
||||
</FormValue>
|
||||
</FormRow>
|
||||
);
|
||||
}
|
||||
|
||||
export function FormCheckboxFieldRaw({ name = undefined, defaultValue = undefined, ...other }) {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
const { values, setFieldValue } = useForm();
|
||||
const handleChange = (event) => {
|
||||
setFieldValue(name, event.target.checked);
|
||||
};
|
||||
@@ -72,36 +80,43 @@ export function FormCheckboxField({ label, ...other }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function FormSelectFieldRaw({ children, ...other }) {
|
||||
export function FormSelectFieldRaw({ children, name, ...other }) {
|
||||
const { values, setFieldValue } = useForm();
|
||||
const handleChange = (event) => {
|
||||
setFieldValue(name, event.target.value);
|
||||
};
|
||||
return (
|
||||
<Field {...other} as={SelectField}>
|
||||
<SelectField {...other} value={values[name]} onChange={handleChange}>
|
||||
{children}
|
||||
</Field>
|
||||
</SelectField>
|
||||
);
|
||||
}
|
||||
|
||||
export function FormSelectField({ label, children = null, ...other }) {
|
||||
export function FormSelectField({ label, name, children = null, ...other }) {
|
||||
return (
|
||||
<FormRow>
|
||||
<FormLabel>{label}</FormLabel>
|
||||
<FormValue>
|
||||
<FormSelectFieldRaw {...other}>{children}</FormSelectFieldRaw>
|
||||
<FormSelectFieldRaw name={name} {...other}>
|
||||
{children}
|
||||
</FormSelectFieldRaw>
|
||||
</FormValue>
|
||||
</FormRow>
|
||||
);
|
||||
}
|
||||
|
||||
export function FormSubmit({ text }) {
|
||||
return <FormStyledButton type="submit" value={text} />;
|
||||
export function FormSubmit({ onClick, value, ...other }) {
|
||||
const { values } = useForm();
|
||||
return <FormStyledButton type="submit" value={value} onClick={() => onClick(values)} {...other} />;
|
||||
}
|
||||
|
||||
export function FormButton({ text, onClick, ...other }) {
|
||||
const { values } = useFormikContext();
|
||||
return <FormStyledButton type="button" value={text} onClick={() => onClick(values)} {...other} />;
|
||||
export function FormButton({ onClick, value, ...other }) {
|
||||
const { values } = useForm();
|
||||
return <FormStyledButton type="button" value={value} onClick={() => onClick(values)} {...other} />;
|
||||
}
|
||||
|
||||
export function FormRadioGroupItem({ name, text, value }) {
|
||||
const { setFieldValue, values } = useFormikContext();
|
||||
const { setFieldValue, values } = useForm();
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
@@ -117,7 +132,7 @@ export function FormRadioGroupItem({ name, text, value }) {
|
||||
}
|
||||
|
||||
export function FormReactSelect({ options, name, isMulti = false, Component = Select, ...other }) {
|
||||
const { setFieldValue, values } = useFormikContext();
|
||||
const { setFieldValue, values } = useForm();
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
@@ -177,7 +192,7 @@ export function FormConnectionSelect({ name }) {
|
||||
}
|
||||
|
||||
export function FormDatabaseSelect({ conidName, name }) {
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
const databases = useDatabaseList({ conid: values[conidName] });
|
||||
const databaseOptions = React.useMemo(
|
||||
() =>
|
||||
@@ -193,7 +208,7 @@ export function FormDatabaseSelect({ conidName, name }) {
|
||||
}
|
||||
|
||||
export function FormSchemaSelect({ conidName, databaseName, name }) {
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
const dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
||||
const schemaOptions = React.useMemo(
|
||||
() =>
|
||||
@@ -209,7 +224,7 @@ export function FormSchemaSelect({ conidName, databaseName, name }) {
|
||||
}
|
||||
|
||||
export function FormTablesSelect({ conidName, databaseName, schemaName, name }) {
|
||||
const { values } = useFormikContext();
|
||||
const { values } = useForm();
|
||||
const dbinfo = useDatabaseInfo({ conid: values[conidName], database: values[databaseName] });
|
||||
const tablesOptions = React.useMemo(
|
||||
() =>
|
||||
@@ -243,7 +258,7 @@ export function FormArchiveFilesSelect({ folderName, name }) {
|
||||
}
|
||||
|
||||
export function FormArchiveFolderSelect({ name, additionalFolders = [], ...other }) {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
const { setFieldValue } = useForm();
|
||||
const folders = useArchiveFolders();
|
||||
const folderOptions = React.useMemo(
|
||||
() => [
|
||||
|
||||
@@ -4,6 +4,7 @@ import styled from 'styled-components';
|
||||
import { FontIcon } from '../icons';
|
||||
import dimensions from '../theme/dimensions';
|
||||
import useTheme from '../theme/useTheme';
|
||||
import { useForm } from '../utility/FormProvider';
|
||||
|
||||
const ButtonDiv = styled.div`
|
||||
padding: 5px 15px;
|
||||
@@ -58,3 +59,12 @@ export default function LargeButton({ children, onClick, icon = undefined, disab
|
||||
</ButtonDiv>
|
||||
);
|
||||
}
|
||||
|
||||
export function LargeFormButton({ children, onClick, icon = undefined, disabled = undefined }) {
|
||||
const { values } = useForm();
|
||||
return (
|
||||
<LargeButton icon={icon} disabled={disabled} onClick={() => onClick(values)}>
|
||||
{children}
|
||||
</LargeButton>
|
||||
);
|
||||
}
|
||||
|
||||
36
yarn.lock
36
yarn.lock
@@ -3932,11 +3932,6 @@ deep-is@~0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||
|
||||
deepmerge@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||
|
||||
default-gateway@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
|
||||
@@ -5230,20 +5225,6 @@ form-data@~2.3.2:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formik@^2.1.0:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/formik/-/formik-2.1.3.tgz#bd168011436393c8426a70cf8dfa5ddbbb95fd23"
|
||||
integrity sha512-twK9sxWt+M2NSXxHBw6TiXNJ72iPVhgUUjeZMD8RYQC+VU7Hrxu6ElCz1xGmbT0q2DbHk4IxoupCkGEPwERzEA==
|
||||
dependencies:
|
||||
deepmerge "^2.1.1"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
lodash "^4.17.14"
|
||||
lodash-es "^4.17.14"
|
||||
react-fast-compare "^2.0.1"
|
||||
scheduler "^0.18.0"
|
||||
tiny-warning "^1.0.2"
|
||||
tslib "^1.10.0"
|
||||
|
||||
forwarded@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
@@ -7317,11 +7298,6 @@ locate-path@^5.0.0:
|
||||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash-es@^4.17.14:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
||||
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
||||
|
||||
lodash._reinterpolate@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||
@@ -9770,11 +9746,6 @@ react-error-overlay@^6.0.5:
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.5.tgz#55d59c2a3810e8b41922e0b4e5f85dcf239bd533"
|
||||
integrity sha512-+DMR2k5c6BqMDSMF8hLH0vYKtKTeikiFW+fj0LClN+XZg4N9b8QUAdHC62CGWNLTi/gnuuemNcNcTFrCvK1f+A==
|
||||
|
||||
react-fast-compare@^2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||
|
||||
react-fast-compare@^3.1.1:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||
@@ -11477,11 +11448,6 @@ timsort@^0.3.0:
|
||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||
|
||||
tiny-warning@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
@@ -11607,7 +11573,7 @@ ts-pnp@1.1.5, ts-pnp@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.5.tgz#840e0739c89fce5f3abd9037bb091dbff16d9dec"
|
||||
integrity sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA==
|
||||
|
||||
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||
tslib@^1.8.1, tslib@^1.9.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
|
||||
|
||||
Reference in New Issue
Block a user