Skip to content

Commit

Permalink
feat(ui): Change project structure (#212)
Browse files Browse the repository at this point in the history
- Changed the folder structure to follow a more common layout using components, pages and tests.
  • Loading branch information
lupusA authored Nov 18, 2023
1 parent 644d9af commit f2d98ea
Show file tree
Hide file tree
Showing 63 changed files with 1,388 additions and 220 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --coverage --transformIgnorePatterns \"node_modules/(?!axios)/\"",
"test:update": "react-scripts test --updateSnapshot --coverage --transformIgnorePatterns \"node_modules/(?!axios)/\"",
"eject": "react-scripts eject"
},
"eslintConfig": {
Expand Down
44 changes: 22 additions & 22 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import axios from 'axios';
import { React, Component } from 'react';
import { Navbar, Nav, Container } from 'react-bootstrap';
import { BrowserRouter as Router, NavLink, Redirect, Route, Switch } from 'react-router-dom';
import { BeginRestore } from './BeginRestore';
import { DirectoryObject } from "./DirectoryObject";
import { PoliciesTable } from "./PoliciesTable";
import { RepoStatus } from "./RepoStatus";
import { SnapshotsTable } from "./SnapshotsTable";
import { SourcesTable } from "./SourcesTable";
import { TaskDetails } from './TaskDetails';
import { TasksTable } from './TasksTable';
import { NewSnapshot } from './NewSnapshot';
import { PolicyEditorPage } from './PolicyEditorPage';
import { PreferencesView } from './PreferencesView';
import { Policy } from './pages/Policy';
import { Preferences } from './pages/Preferences';
import { Policies } from "./pages/Policies";
import { Repository } from "./pages/Repository";
import { Task } from './pages/Task';
import { Tasks } from './pages/Tasks';
import { Snapshots } from "./pages/Snapshots";
import { SnapshotCreate } from './pages/SnapshotCreate';
import { SnapshotDirectory } from "./pages/SnapshotDirectory";
import { SnapshotHistory } from "./pages/SnapshotHistory";
import { SnapshotRestore } from './pages/SnapshotRestore';
import { AppContext } from './contexts/AppContext';
import { UIPreferenceProvider } from './contexts/UIPreferencesContext';

Expand Down Expand Up @@ -123,17 +123,17 @@ export default class App extends Component {
</NavLink>

<Switch>
<Route path="/snapshots/new" component={NewSnapshot} />
<Route path="/snapshots/single-source/" component={SnapshotsTable} />
<Route path="/snapshots/dir/:oid/restore" component={BeginRestore} />
<Route path="/snapshots/dir/:oid" component={DirectoryObject} />
<Route path="/snapshots" component={SourcesTable} />
<Route path="/policies/edit/" component={PolicyEditorPage} />
<Route path="/policies" component={PoliciesTable} />
<Route path="/tasks/:tid" component={TaskDetails} />
<Route path="/tasks" component={TasksTable} />
<Route path="/repo" component={RepoStatus} />
<Route path="/preferences" component={PreferencesView} />
<Route path="/snapshots/new" component={SnapshotCreate} />
<Route path="/snapshots/single-source/" component={SnapshotHistory} />
<Route path="/snapshots/dir/:oid/restore" component={SnapshotRestore} />
<Route path="/snapshots/dir/:oid" component={SnapshotDirectory} />
<Route path="/snapshots" component={Snapshots} />
<Route path="/policies/edit/" component={Policy} />
<Route path="/policies" component={Policies} />
<Route path="/tasks/:tid" component={Task} />
<Route path="/tasks" component={Tasks} />
<Route path="/repo" component={Repository} />
<Route path="/preferences" component={Preferences} />
<Route exact path="/">
<Redirect to="/snapshots" />
</Route>
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions src/DirectoryItems.jsx → src/components/DirectoryItems.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import MyTable from './Table';
import { objectLink, rfc3339TimestampForDisplay, sizeWithFailures } from './uiutil';
import { UIPreferencesContext } from './contexts/UIPreferencesContext';
import KopiaTable from '../utils/KopiaTable';
import { objectLink, rfc3339TimestampForDisplay, sizeWithFailures } from '../utils/uiutil';
import { UIPreferencesContext } from '../contexts/UIPreferencesContext';

function objectName(name, typeID) {
if (typeID === "d") {
Expand Down Expand Up @@ -64,7 +64,7 @@ export class DirectoryItems extends Component {
width: 100,
}]

return <MyTable data={this.props.items} columns={columns} />;
return <KopiaTable data={this.props.items} columns={columns} />;
}
}
DirectoryItems.contextType = UIPreferencesContext
6 changes: 3 additions & 3 deletions src/TaskLogs.jsx → src/components/Logs.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import axios from 'axios';
import React, { Component } from 'react';
import Table from 'react-bootstrap/Table';
import { handleChange } from './forms';
import { redirect } from './uiutil';
import { handleChange } from '../forms';
import { redirect } from '../utils/uiutil';

export class TaskLogs extends Component {
export class Logs extends Component {
constructor() {
super();
this.state = {
Expand Down
50 changes: 25 additions & 25 deletions src/SetupRepository.jsx → src/components/SetupRepository.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@ import Collapse from 'react-bootstrap/Collapse';
import Form from 'react-bootstrap/Form';
import Row from 'react-bootstrap/Row';
import Spinner from 'react-bootstrap/Spinner';
import { AppContext } from './contexts/AppContext';
import { handleChange, validateRequiredFields } from './forms';
import { RequiredBoolean } from './forms/RequiredBoolean';
import { RequiredField } from './forms/RequiredField';
import { SetupAzure } from './SetupAzure';
import { SetupB2 } from "./SetupB2";
import { SetupFilesystem } from './SetupFilesystem';
import { SetupGCS } from './SetupGCS';
import { SetupKopiaServer } from './SetupKopiaServer';
import { SetupRclone } from './SetupRclone';
import { SetupS3 } from './SetupS3';
import { SetupSFTP } from './SetupSFTP';
import { SetupToken } from './SetupToken';
import { SetupWebDAV } from './SetupWebDAV';
import { toAlgorithmOption } from './uiutil';
import { AppContext } from '../contexts/AppContext';
import { handleChange, validateRequiredFields } from '../forms';
import { RequiredBoolean } from '../forms/RequiredBoolean';
import { RequiredField } from '../forms/RequiredField';
import { SetupRepositoryAzure } from './SetupRepositoryAzure';
import { SetupRepositoryB2 } from "./SetupRepositoryB2";
import { SetupRepositoryFilesystem } from './SetupRepositoryFilesystem';
import { SetupRepositoryGCS } from './SetupRepositoryGCS';
import { SetupRepositoryServer } from './SetupRepositoryServer';
import { SetupRepositoryRclone } from './SetupRepositoryRclone';
import { SetupRepositoryS3 } from './SetupRepositoryS3';
import { SetupRepositorySFTP } from './SetupRepositorySFTP';
import { SetupRepositoryToken } from './SetupRepositoryToken';
import { SetupRepositoryWebDAV } from './SetupRepositoryWebDAV';
import { toAlgorithmOption } from '../utils/uiutil';

const supportedProviders = [
{ provider: "filesystem", description: "Local Directory or NAS", component: SetupFilesystem },
{ provider: "gcs", description: "Google Cloud Storage", component: SetupGCS },
{ provider: "s3", description: "Amazon S3 or Compatible Storage", component: SetupS3 },
{ provider: "b2", description: "Backblaze B2", component: SetupB2 },
{ provider: "azureBlob", description: "Azure Blob Storage", component: SetupAzure },
{ provider: "sftp", description: "SFTP Server", component: SetupSFTP },
{ provider: "rclone", description: "Rclone Remote", component: SetupRclone },
{ provider: "webdav", description: "WebDAV Server", component: SetupWebDAV },
{ provider: "_server", description: "Kopia Repository Server", component: SetupKopiaServer },
{ provider: "_token", description: "Use Repository Token", component: SetupToken },
{ provider: "filesystem", description: "Local Directory or NAS", component: SetupRepositoryFilesystem },
{ provider: "gcs", description: "Google Cloud Storage", component: SetupRepositoryGCS },
{ provider: "s3", description: "Amazon S3 or Compatible Storage", component: SetupRepositoryS3 },
{ provider: "b2", description: "Backblaze B2", component: SetupRepositoryB2 },
{ provider: "azureBlob", description: "Azure Blob Storage", component: SetupRepositoryAzure },
{ provider: "sftp", description: "SFTP Server", component: SetupRepositorySFTP },
{ provider: "rclone", description: "Rclone Remote", component: SetupRepositoryRclone },
{ provider: "webdav", description: "WebDAV Server", component: SetupRepositoryWebDAV },
{ provider: "_server", description: "Kopia Repository Server", component: SetupRepositoryServer },
{ provider: "_token", description: "Use Repository Token", component: SetupRepositoryToken },
];

export class SetupRepository extends Component {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredField } from '../forms/RequiredField';

export class SetupAzure extends Component {
export class SetupRepositoryAzure extends Component {
constructor(props) {
super();

Expand Down
8 changes: 4 additions & 4 deletions src/SetupB2.jsx → src/components/SetupRepositoryB2.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { RequiredField } from './forms/RequiredField';
import { OptionalField } from './forms/OptionalField';
import { handleChange, validateRequiredFields } from '../forms';
import { RequiredField } from '../forms/RequiredField';
import { OptionalField } from '../forms/OptionalField';

export class SetupB2 extends Component {
export class SetupRepositoryB2 extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { RequiredField } from '../forms/RequiredField';

export class SetupFilesystem extends Component {
export class SetupRepositoryFilesystem extends Component {
constructor(props) {
super();

Expand Down
8 changes: 4 additions & 4 deletions src/SetupGCS.jsx → src/components/SetupRepositoryGCS.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredField } from '../forms/RequiredField';

export class SetupGCS extends Component {
export class SetupRepositoryGCS extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredField } from '../forms/RequiredField';

export class SetupRclone extends Component {
export class SetupRepositoryRclone extends Component {
constructor(props) {
super();

Expand Down
10 changes: 5 additions & 5 deletions src/SetupS3.jsx → src/components/SetupRepositoryS3.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredBoolean } from './forms/RequiredBoolean';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredBoolean } from '../forms/RequiredBoolean';
import { RequiredField } from '../forms/RequiredField';

export class SetupS3 extends Component {
export class SetupRepositoryS3 extends Component {
constructor(props) {
super();

Expand Down
12 changes: 6 additions & 6 deletions src/SetupSFTP.jsx → src/components/SetupRepositorySFTP.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields, stateProperty } from './forms';
import { OptionalField } from './forms/OptionalField';
import { OptionalNumberField } from './forms/OptionalNumberField';
import { RequiredBoolean } from './forms/RequiredBoolean';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields, stateProperty } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { OptionalNumberField } from '../forms/OptionalNumberField';
import { RequiredBoolean } from '../forms/RequiredBoolean';
import { RequiredField } from '../forms/RequiredField';

function hasExactlyOneOf(component, names) {
let count = 0;
Expand All @@ -18,7 +18,7 @@ function hasExactlyOneOf(component, names) {
return count === 1;
}

export class SetupSFTP extends Component {
export class SetupRepositorySFTP extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredField } from '../forms/RequiredField';

export class SetupKopiaServer extends Component {
export class SetupRepositoryServer extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { RequiredField } from '../forms/RequiredField';

export class SetupToken extends Component {
export class SetupRepositoryToken extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { Component } from 'react';
import Row from 'react-bootstrap/Row';
import { handleChange, validateRequiredFields } from './forms';
import { OptionalField } from './forms/OptionalField';
import { RequiredField } from './forms/RequiredField';
import { handleChange, validateRequiredFields } from '../forms';
import { OptionalField } from '../forms/OptionalField';
import { RequiredField } from '../forms/RequiredField';

export class SetupWebDAV extends Component {
export class SetupRepositoryWebDAV extends Component {
constructor(props) {
super();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import React, { Component } from 'react';
import Button from 'react-bootstrap/Button';
import Spinner from 'react-bootstrap/esm/Spinner';
import Form from 'react-bootstrap/Form';
import { TaskLogs } from './TaskLogs';
import { cancelTask, redirect, sizeDisplayName } from './uiutil';
import { UIPreferencesContext } from './contexts/UIPreferencesContext';
import { Logs } from './Logs';
import { cancelTask, redirect, sizeDisplayName } from '../utils/uiutil';
import { UIPreferencesContext } from '../contexts/UIPreferencesContext';

export class EstimateResults extends Component {
export class SnapshotEstimation extends Component {
constructor() {
super();
this.state = {
Expand Down Expand Up @@ -110,10 +110,10 @@ export class EstimateResults extends Component {
</>}
{this.state.showLog ? <>
<Button size="sm" variant="light" onClick={() => this.setState({ showLog: false })}><FontAwesomeIcon icon={faChevronCircleUp} /> Hide Log</Button>
<TaskLogs taskID={this.taskID(this.props)} />
<Logs taskID={this.taskID(this.props)} />
</> : <Button size="sm" variant="light" onClick={() => this.setState({ showLog: true })}><FontAwesomeIcon icon={faChevronCircleDown} /> Show Log</Button>}
</>
;
}
}
EstimateResults.contextType = UIPreferencesContext
SnapshotEstimation.contextType = UIPreferencesContext
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import Form from 'react-bootstrap/Form';
import Row from 'react-bootstrap/Row';
import { stateProperty } from '../forms';
import { stateProperty } from '../../forms';
import { LabelColumn } from './LabelColumn';
import { WideValueColumn } from './WideValueColumn';
import { EffectiveValue } from './EffectiveValue';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Row from 'react-bootstrap/Row';
import { OptionalFieldNoLabel } from '../forms/OptionalFieldNoLabel';
import { OptionalFieldNoLabel } from '../../forms/OptionalFieldNoLabel';
import { LabelColumn } from './LabelColumn';
import { WideValueColumn } from './WideValueColumn';
import { EffectiveValue } from './EffectiveValue';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Row from 'react-bootstrap/Row';
import { OptionalNumberField } from '../forms/OptionalNumberField';
import { OptionalNumberField } from '../../forms/OptionalNumberField';
import { LabelColumn } from './LabelColumn';
import { WideValueColumn } from './WideValueColumn';
import { EffectiveValue } from './EffectiveValue';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Form from 'react-bootstrap/Form';
import { getDeepStateProperty } from '../deepstate';
import { getDeepStateProperty } from '../../utils/deepstate';
import { EffectiveValueColumn } from "./EffectiveValueColumn";

export function EffectiveBooleanValue(component, policyField) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Form from 'react-bootstrap/Form';
import { getDeepStateProperty } from '../deepstate';
import { getDeepStateProperty } from '../../utils/deepstate';
import { EffectiveValueColumn } from "./EffectiveValueColumn";

export function EffectiveListValue(component, policyField) {
Expand Down
Loading

0 comments on commit f2d98ea

Please sign in to comment.