diff --git a/src/components/SetupRepositoryFilesystem.jsx b/src/components/SetupRepositoryFilesystem.jsx index f5915ae..6f3dbcd 100644 --- a/src/components/SetupRepositoryFilesystem.jsx +++ b/src/components/SetupRepositoryFilesystem.jsx @@ -1,7 +1,6 @@ import React, { Component } from 'react'; -import Row from 'react-bootstrap/Row'; import { handleChange, validateRequiredFields } from '../forms'; -import { RequiredField } from '../forms/RequiredField'; +import { RequiredDirectory } from '../forms/RequiredDirectory'; export class SetupRepositoryFilesystem extends Component { constructor(props) { @@ -19,9 +18,7 @@ export class SetupRepositoryFilesystem extends Component { render() { return <> - - {RequiredField(this, "Directory Path", "path", { autoFocus: true, placeholder: "enter directory path where you want to store repository files" })} - + {RequiredDirectory(this, "Directory Path", "path", { autoFocus: true, placeholder: "enter directory path where you want to store repository files"})} ; } } diff --git a/src/css/index.css b/src/css/index.css index 4a1df4d..662dfda 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -3,8 +3,6 @@ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } code { diff --git a/src/forms/OptionalDirectory.jsx b/src/forms/OptionalDirectory.jsx new file mode 100644 index 0000000..67cb832 --- /dev/null +++ b/src/forms/OptionalDirectory.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import Button from 'react-bootstrap/Button'; +import Form from 'react-bootstrap/Form'; +import { Col, FormGroup, FormControl, InputGroup } from 'react-bootstrap'; +import { faFolderOpen } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { stateProperty } from '.'; +import { setDeepStateProperty } from '../utils/deepstate'; + +/** + * This functions returns a directory selector that allows the user to select a directory. + * The selections is invoked using a button that calls a functions within the electron app. + * If the electron app is not present, the button is not visible. + * + * @param {*} component + * The component that this function is called from + * @param {string} label + * Label, that is added before the input field + * @param {string} name + * Name of the variable in which the directory path is stored + * @param {*} props + * Additional properties of the component + * @returns The form group with the components + */ +export function OptionalDirectory(component, label, name, props = {}) { + /** + * Saves the selected path as a deepstate variable within the component + * @param {The path that has been selected} path + */ + function onDirectorySelected(path) { + setDeepStateProperty(component, name, path) + } + + return + {label && {label}} + + + {window.kopiaUI && + } + + +} \ No newline at end of file diff --git a/src/forms/OptionalField.jsx b/src/forms/OptionalField.jsx index 29ccda4..63b454c 100644 --- a/src/forms/OptionalField.jsx +++ b/src/forms/OptionalField.jsx @@ -3,7 +3,7 @@ import Form from 'react-bootstrap/Form'; import Col from 'react-bootstrap/Col'; import { stateProperty } from '.'; -export function OptionalField(component, label, name, props = {}, helpText = null, invalidFeedback = null) { +export function OptionalField(component, label, name, props = {}, helpText = null) { return {label} {helpText && {helpText}} - {invalidFeedback && {invalidFeedback}} ; } diff --git a/src/forms/RequiredDirectory.jsx b/src/forms/RequiredDirectory.jsx new file mode 100644 index 0000000..ecb40c3 --- /dev/null +++ b/src/forms/RequiredDirectory.jsx @@ -0,0 +1,52 @@ +import React from 'react'; +import Button from 'react-bootstrap/Button'; +import Form from 'react-bootstrap/Form'; +import { Col, FormGroup, FormControl, InputGroup } from 'react-bootstrap'; +import { faFolderOpen } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { stateProperty } from '.'; +import { setDeepStateProperty } from '../utils/deepstate'; + +/** + * This functions returns a directory selector that allows the user to select a directory. + * The selections is invoked using a button that calls a functions within the electron app. + * If the electron app is not present, the button is not visible. The path is required. + * + * @param {*} component + * The component that this function is called from + * @param {string} label + * Label, that is added before the input field + * @param {string} name + * Name of the variable in which the directory path is stored + * @param {*} props + * Additional properties of the component + * @returns The form group with the components + */ +export function RequiredDirectory(component, label, name, props = {}) { + /** + * Saves the selected path as a deepstate variable within the component + * @param {The path that has been selected} path + */ + function onDirectorySelected(path) { + setDeepStateProperty(component, name, path) + } + + return + {label && {label}} + + + {window.kopiaUI && + } + Required field + + +} \ No newline at end of file diff --git a/src/pages/Policies.jsx b/src/pages/Policies.jsx index 9f7ff37..56676d5 100644 --- a/src/pages/Policies.jsx +++ b/src/pages/Policies.jsx @@ -10,8 +10,9 @@ import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import { Link } from 'react-router-dom'; import { handleChange } from '../forms'; +import { OptionalDirectory } from '../forms/OptionalDirectory' import KopiaTable from '../utils/KopiaTable'; -import { CLIEquivalent, compare, DirectorySelector, isAbsolutePath, ownerName, policyEditorURL, redirect } from '../utils/uiutil'; +import { CLIEquivalent, compare, isAbsolutePath, ownerName, policyEditorURL, redirect } from '../utils/uiutil'; const applicablePolicies = "Applicable Policies" const localPolicies = "Local Path Policies" @@ -274,9 +275,7 @@ export class Policies extends Component { {(this.state.selectedOwner === localPolicies || this.state.selectedOwner === this.state.localSourceName || this.state.selectedOwner === applicablePolicies) ? <> - this.setState({ policyPath: p })} - placeholder="enter directory to find or set policy" - name="policyPath" value={this.state.policyPath} onChange={this.handleChange} /> + {OptionalDirectory(this, null, "policyPath", { autoFocus: true, placeholder: "enter directory to find or set policy" })} @@ -295,4 +294,4 @@ export class Policies extends Component { ; } -} +} \ No newline at end of file diff --git a/src/pages/SnapshotCreate.jsx b/src/pages/SnapshotCreate.jsx index 7a85f1b..0bc663a 100644 --- a/src/pages/SnapshotCreate.jsx +++ b/src/pages/SnapshotCreate.jsx @@ -7,7 +7,8 @@ import Row from 'react-bootstrap/Row'; import { handleChange } from '../forms'; import { PolicyEditor } from '../components/policy-editor/PolicyEditor'; import { SnapshotEstimation } from '../components/SnapshotEstimation'; -import { CLIEquivalent, DirectorySelector, errorAlert, GoBackButton, redirect } from '../utils/uiutil'; +import { RequiredDirectory } from '../forms/RequiredDirectory'; +import { CLIEquivalent, errorAlert, GoBackButton, redirect } from '../utils/uiutil'; export class SnapshotCreate extends Component { constructor() { @@ -59,7 +60,7 @@ export class SnapshotCreate extends Component { } else { this.setState({ lastResolvedPath: currentPath, - resolvedSource: null, + resolvedSource: "", }); this.maybeResolveCurrentPath(currentPath); @@ -147,18 +148,15 @@ export class SnapshotCreate extends Component { render() { return <> - - - - -    

New Snapshot

-
+ + + +
+

New Snapshot


- - this.setState({ path: p })} autoFocus placeholder="enter path to snapshot" name="path" value={this.state.path} onChange={this.handleChange} /> - + {RequiredDirectory(this, null, "path", { autoFocus: true, placeholder: "enter path to snapshot" })} -   - ; -} - export function CLIEquivalent(props) { let [visible, setVisible] = useState(false); let [cliInfo, setCLIInfo] = useState({});