From f2d98ea9a40755a870db5896dc0988d4d0373d7e Mon Sep 17 00:00:00 2001 From: Christoph Anderson <37236531+lupusA@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:02:36 +0100 Subject: [PATCH] feat(ui): Change project structure (#212) - Changed the folder structure to follow a more common layout using components, pages and tests. --- .vscode/settings.json | 2 + package.json | 1 + src/App.jsx | 44 +- src/{ => components}/DirectoryBreadcrumbs.jsx | 0 src/{ => components}/DirectoryItems.jsx | 8 +- src/{TaskLogs.jsx => components/Logs.jsx} | 6 +- src/{ => components}/SetupRepository.jsx | 50 +- .../SetupRepositoryAzure.jsx} | 8 +- .../SetupRepositoryB2.jsx} | 8 +- .../SetupRepositoryFilesystem.jsx} | 6 +- .../SetupRepositoryGCS.jsx} | 8 +- .../SetupRepositoryRclone.jsx} | 8 +- .../SetupRepositoryS3.jsx} | 10 +- .../SetupRepositorySFTP.jsx} | 12 +- .../SetupRepositoryServer.jsx} | 8 +- .../SetupRepositoryToken.jsx} | 6 +- .../SetupRepositoryWebDAV.jsx} | 8 +- .../SnapshotEstimation.jsx} | 12 +- .../policy-editor}/ActionRowMode.jsx | 2 +- .../policy-editor}/ActionRowScript.jsx | 2 +- .../policy-editor}/ActionRowTimeout.jsx | 2 +- .../policy-editor}/EffectiveBooleanValue.jsx | 2 +- .../policy-editor}/EffectiveListValue.jsx | 2 +- .../policy-editor}/EffectiveTextAreaValue.jsx | 2 +- .../EffectiveTimesOfDayValue.jsx | 4 +- .../policy-editor}/EffectiveValue.jsx | 2 +- .../policy-editor}/EffectiveValueColumn.jsx | 0 .../policy-editor}/LabelColumn.jsx | 0 .../policy-editor/PolicyEditor.jsx} | 16 +- .../policy-editor}/SectionHeaderRow.jsx | 0 .../policy-editor}/UpcomingSnapshotTimes.jsx | 0 .../policy-editor}/ValueColumn.jsx | 0 .../policy-editor}/WideValueColumn.jsx | 0 src/forms/index.jsx | 2 +- src/{PoliciesTable.jsx => pages/Policies.jsx} | 10 +- .../Policy.jsx} | 6 +- .../Preferences.jsx} | 13 +- src/{RepoStatus.jsx => pages/Repository.jsx} | 16 +- .../SnapshotCreate.jsx} | 12 +- .../SnapshotDirectory.jsx} | 8 +- .../SnapshotHistory.jsx} | 12 +- .../SnapshotRestore.jsx} | 12 +- src/{SourcesTable.jsx => pages/Snapshots.jsx} | 14 +- src/{TaskDetails.jsx => pages/Task.jsx} | 12 +- src/{TasksTable.jsx => pages/Tasks.jsx} | 10 +- src/setupProxy.js | 20 +- src/tests/PolicyEditor.test.jsx | 15 +- src/tests/Preferences.test.js | 60 + src/tests/SetupRepository.test.jsx | 16 +- ...test.jsx => SetupRepositoryAzure.test.jsx} | 4 +- ...jsx => SetupRepositoryFilesystem.test.jsx} | 4 +- ...S.test.jsx => SetupRepositoryGCS.test.jsx} | 4 +- ...S3.test.jsx => SetupRepositoryS3.test.jsx} | 4 +- ....test.jsx => SetupRepositorySFTP.test.jsx} | 4 +- ...test.jsx => SetupRepositoryToken.test.jsx} | 4 +- ...est.jsx => SetupRepositoryWebDAV.test.jsx} | 4 +- .../__snapshots__/Preferences.test.js.snap | 1093 +++++++++++++++++ src/tests/deepstate.test.js | 2 +- src/tests/testutils.js | 2 +- src/tests/uiutil.test.js | 2 +- src/{Table.jsx => utils/KopiaTable.jsx} | 4 +- src/{ => utils}/deepstate.js | 0 src/{ => utils}/uiutil.jsx | 0 63 files changed, 1388 insertions(+), 220 deletions(-) create mode 100644 .vscode/settings.json rename src/{ => components}/DirectoryBreadcrumbs.jsx (100%) rename src/{ => components}/DirectoryItems.jsx (88%) rename src/{TaskLogs.jsx => components/Logs.jsx} (96%) rename src/{ => components}/SetupRepository.jsx (94%) rename src/{SetupAzure.jsx => components/SetupRepositoryAzure.jsx} (85%) rename src/{SetupB2.jsx => components/SetupRepositoryB2.jsx} (81%) rename src/{SetupFilesystem.jsx => components/SetupRepositoryFilesystem.jsx} (76%) rename src/{SetupGCS.jsx => components/SetupRepositoryGCS.jsx} (81%) rename src/{SetupRclone.jsx => components/SetupRepositoryRclone.jsx} (76%) rename src/{SetupS3.jsx => components/SetupRepositoryS3.jsx} (85%) rename src/{SetupSFTP.jsx => components/SetupRepositorySFTP.jsx} (92%) rename src/{SetupKopiaServer.jsx => components/SetupRepositoryServer.jsx} (77%) rename src/{SetupToken.jsx => components/SetupRepositoryToken.jsx} (75%) rename src/{SetupWebDAV.jsx => components/SetupRepositoryWebDAV.jsx} (77%) rename src/{EstimateResults.jsx => components/SnapshotEstimation.jsx} (91%) rename src/{PolicyEditor => components/policy-editor}/ActionRowMode.jsx (96%) rename src/{PolicyEditor => components/policy-editor}/ActionRowScript.jsx (87%) rename src/{PolicyEditor => components/policy-editor}/ActionRowTimeout.jsx (88%) rename src/{PolicyEditor => components/policy-editor}/EffectiveBooleanValue.jsx (92%) rename src/{PolicyEditor => components/policy-editor}/EffectiveListValue.jsx (93%) rename src/{PolicyEditor => components/policy-editor}/EffectiveTextAreaValue.jsx (93%) rename src/{PolicyEditor => components/policy-editor}/EffectiveTimesOfDayValue.jsx (83%) rename src/{PolicyEditor => components/policy-editor}/EffectiveValue.jsx (92%) rename src/{PolicyEditor => components/policy-editor}/EffectiveValueColumn.jsx (100%) rename src/{PolicyEditor => components/policy-editor}/LabelColumn.jsx (100%) rename src/{PolicyEditor/index.jsx => components/policy-editor/PolicyEditor.jsx} (98%) rename src/{PolicyEditor => components/policy-editor}/SectionHeaderRow.jsx (100%) rename src/{PolicyEditor => components/policy-editor}/UpcomingSnapshotTimes.jsx (100%) rename src/{PolicyEditor => components/policy-editor}/ValueColumn.jsx (100%) rename src/{PolicyEditor => components/policy-editor}/WideValueColumn.jsx (100%) rename src/{PoliciesTable.jsx => pages/Policies.jsx} (97%) rename src/{PolicyEditorPage.jsx => pages/Policy.jsx} (87%) rename src/{PreferencesView.jsx => pages/Preferences.jsx} (82%) rename src/{RepoStatus.jsx => pages/Repository.jsx} (96%) rename src/{NewSnapshot.jsx => pages/SnapshotCreate.jsx} (94%) rename src/{DirectoryObject.jsx => pages/SnapshotDirectory.jsx} (95%) rename src/{SnapshotsTable.jsx => pages/SnapshotHistory.jsx} (98%) rename src/{BeginRestore.jsx => pages/SnapshotRestore.jsx} (94%) rename src/{SourcesTable.jsx => pages/Snapshots.jsx} (97%) rename src/{TaskDetails.jsx => pages/Task.jsx} (95%) rename src/{TasksTable.jsx => pages/Tasks.jsx} (95%) create mode 100644 src/tests/Preferences.test.js rename src/tests/{SetupAzure.test.jsx => SetupRepositoryAzure.test.jsx} (88%) rename src/tests/{SetupFilesystem.test.jsx => SetupRepositoryFilesystem.test.jsx} (74%) rename src/tests/{SetupGCS.test.jsx => SetupRepositoryGCS.test.jsx} (86%) rename src/tests/{SetupS3.test.jsx => SetupRepositoryS3.test.jsx} (92%) rename src/tests/{SetupSFTP.test.jsx => SetupRepositorySFTP.test.jsx} (94%) rename src/tests/{SetupToken.test.jsx => SetupRepositoryToken.test.jsx} (76%) rename src/tests/{SetupWebDAV.test.jsx => SetupRepositoryWebDAV.test.jsx} (83%) create mode 100644 src/tests/__snapshots__/Preferences.test.js.snap rename src/{Table.jsx => utils/KopiaTable.jsx} (96%) rename src/{ => utils}/deepstate.js (100%) rename src/{ => utils}/uiutil.jsx (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/package.json b/package.json index f5d1a66..05a89c7 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/App.jsx b/src/App.jsx index c8b5c46..00c456a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -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'; @@ -123,17 +123,17 @@ export default class App extends Component { - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/DirectoryBreadcrumbs.jsx b/src/components/DirectoryBreadcrumbs.jsx similarity index 100% rename from src/DirectoryBreadcrumbs.jsx rename to src/components/DirectoryBreadcrumbs.jsx diff --git a/src/DirectoryItems.jsx b/src/components/DirectoryItems.jsx similarity index 88% rename from src/DirectoryItems.jsx rename to src/components/DirectoryItems.jsx index 8fc2ce8..fac5eea 100644 --- a/src/DirectoryItems.jsx +++ b/src/components/DirectoryItems.jsx @@ -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") { @@ -64,7 +64,7 @@ export class DirectoryItems extends Component { width: 100, }] - return ; + return ; } } DirectoryItems.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/TaskLogs.jsx b/src/components/Logs.jsx similarity index 96% rename from src/TaskLogs.jsx rename to src/components/Logs.jsx index d2c43f4..72c66e6 100644 --- a/src/TaskLogs.jsx +++ b/src/components/Logs.jsx @@ -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 = { diff --git a/src/SetupRepository.jsx b/src/components/SetupRepository.jsx similarity index 94% rename from src/SetupRepository.jsx rename to src/components/SetupRepository.jsx index d172d72..485c153 100644 --- a/src/SetupRepository.jsx +++ b/src/components/SetupRepository.jsx @@ -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 { diff --git a/src/SetupAzure.jsx b/src/components/SetupRepositoryAzure.jsx similarity index 85% rename from src/SetupAzure.jsx rename to src/components/SetupRepositoryAzure.jsx index f1b50d0..b32e22c 100644 --- a/src/SetupAzure.jsx +++ b/src/components/SetupRepositoryAzure.jsx @@ -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(); diff --git a/src/SetupB2.jsx b/src/components/SetupRepositoryB2.jsx similarity index 81% rename from src/SetupB2.jsx rename to src/components/SetupRepositoryB2.jsx index f62c744..73fffd1 100644 --- a/src/SetupB2.jsx +++ b/src/components/SetupRepositoryB2.jsx @@ -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(); diff --git a/src/SetupFilesystem.jsx b/src/components/SetupRepositoryFilesystem.jsx similarity index 76% rename from src/SetupFilesystem.jsx rename to src/components/SetupRepositoryFilesystem.jsx index 97a471f..f5915ae 100644 --- a/src/SetupFilesystem.jsx +++ b/src/components/SetupRepositoryFilesystem.jsx @@ -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(); diff --git a/src/SetupGCS.jsx b/src/components/SetupRepositoryGCS.jsx similarity index 81% rename from src/SetupGCS.jsx rename to src/components/SetupRepositoryGCS.jsx index c308c33..cb303e9 100644 --- a/src/SetupGCS.jsx +++ b/src/components/SetupRepositoryGCS.jsx @@ -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(); diff --git a/src/SetupRclone.jsx b/src/components/SetupRepositoryRclone.jsx similarity index 76% rename from src/SetupRclone.jsx rename to src/components/SetupRepositoryRclone.jsx index a7d9d36..5a59e43 100644 --- a/src/SetupRclone.jsx +++ b/src/components/SetupRepositoryRclone.jsx @@ -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(); diff --git a/src/SetupS3.jsx b/src/components/SetupRepositoryS3.jsx similarity index 85% rename from src/SetupS3.jsx rename to src/components/SetupRepositoryS3.jsx index d22e377..d05da1d 100644 --- a/src/SetupS3.jsx +++ b/src/components/SetupRepositoryS3.jsx @@ -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(); diff --git a/src/SetupSFTP.jsx b/src/components/SetupRepositorySFTP.jsx similarity index 92% rename from src/SetupSFTP.jsx rename to src/components/SetupRepositorySFTP.jsx index a93272f..3f9a58b 100644 --- a/src/SetupSFTP.jsx +++ b/src/components/SetupRepositorySFTP.jsx @@ -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; @@ -18,7 +18,7 @@ function hasExactlyOneOf(component, names) { return count === 1; } -export class SetupSFTP extends Component { +export class SetupRepositorySFTP extends Component { constructor(props) { super(); diff --git a/src/SetupKopiaServer.jsx b/src/components/SetupRepositoryServer.jsx similarity index 77% rename from src/SetupKopiaServer.jsx rename to src/components/SetupRepositoryServer.jsx index e60ca1e..1bf7ab7 100644 --- a/src/SetupKopiaServer.jsx +++ b/src/components/SetupRepositoryServer.jsx @@ -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(); diff --git a/src/SetupToken.jsx b/src/components/SetupRepositoryToken.jsx similarity index 75% rename from src/SetupToken.jsx rename to src/components/SetupRepositoryToken.jsx index 95e528c..b767a35 100644 --- a/src/SetupToken.jsx +++ b/src/components/SetupRepositoryToken.jsx @@ -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(); diff --git a/src/SetupWebDAV.jsx b/src/components/SetupRepositoryWebDAV.jsx similarity index 77% rename from src/SetupWebDAV.jsx rename to src/components/SetupRepositoryWebDAV.jsx index fdceca5..5106763 100644 --- a/src/SetupWebDAV.jsx +++ b/src/components/SetupRepositoryWebDAV.jsx @@ -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(); diff --git a/src/EstimateResults.jsx b/src/components/SnapshotEstimation.jsx similarity index 91% rename from src/EstimateResults.jsx rename to src/components/SnapshotEstimation.jsx index de128d3..86b07b7 100644 --- a/src/EstimateResults.jsx +++ b/src/components/SnapshotEstimation.jsx @@ -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 = { @@ -110,10 +110,10 @@ export class EstimateResults extends Component { } {this.state.showLog ? <> - + : } ; } } -EstimateResults.contextType = UIPreferencesContext \ No newline at end of file +SnapshotEstimation.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/PolicyEditor/ActionRowMode.jsx b/src/components/policy-editor/ActionRowMode.jsx similarity index 96% rename from src/PolicyEditor/ActionRowMode.jsx rename to src/components/policy-editor/ActionRowMode.jsx index fd955ef..43600de 100644 --- a/src/PolicyEditor/ActionRowMode.jsx +++ b/src/components/policy-editor/ActionRowMode.jsx @@ -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'; diff --git a/src/PolicyEditor/ActionRowScript.jsx b/src/components/policy-editor/ActionRowScript.jsx similarity index 87% rename from src/PolicyEditor/ActionRowScript.jsx rename to src/components/policy-editor/ActionRowScript.jsx index 37ddef9..50a7570 100644 --- a/src/PolicyEditor/ActionRowScript.jsx +++ b/src/components/policy-editor/ActionRowScript.jsx @@ -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'; diff --git a/src/PolicyEditor/ActionRowTimeout.jsx b/src/components/policy-editor/ActionRowTimeout.jsx similarity index 88% rename from src/PolicyEditor/ActionRowTimeout.jsx rename to src/components/policy-editor/ActionRowTimeout.jsx index cd2d0dc..fbbf341 100644 --- a/src/PolicyEditor/ActionRowTimeout.jsx +++ b/src/components/policy-editor/ActionRowTimeout.jsx @@ -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'; diff --git a/src/PolicyEditor/EffectiveBooleanValue.jsx b/src/components/policy-editor/EffectiveBooleanValue.jsx similarity index 92% rename from src/PolicyEditor/EffectiveBooleanValue.jsx rename to src/components/policy-editor/EffectiveBooleanValue.jsx index db82173..9781a3d 100644 --- a/src/PolicyEditor/EffectiveBooleanValue.jsx +++ b/src/components/policy-editor/EffectiveBooleanValue.jsx @@ -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) { diff --git a/src/PolicyEditor/EffectiveListValue.jsx b/src/components/policy-editor/EffectiveListValue.jsx similarity index 93% rename from src/PolicyEditor/EffectiveListValue.jsx rename to src/components/policy-editor/EffectiveListValue.jsx index 0a9cd70..8eb72a9 100644 --- a/src/PolicyEditor/EffectiveListValue.jsx +++ b/src/components/policy-editor/EffectiveListValue.jsx @@ -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) { diff --git a/src/PolicyEditor/EffectiveTextAreaValue.jsx b/src/components/policy-editor/EffectiveTextAreaValue.jsx similarity index 93% rename from src/PolicyEditor/EffectiveTextAreaValue.jsx rename to src/components/policy-editor/EffectiveTextAreaValue.jsx index 1babef2..d98e5da 100644 --- a/src/PolicyEditor/EffectiveTextAreaValue.jsx +++ b/src/components/policy-editor/EffectiveTextAreaValue.jsx @@ -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 EffectiveTextAreaValue(component, policyField) { diff --git a/src/PolicyEditor/EffectiveTimesOfDayValue.jsx b/src/components/policy-editor/EffectiveTimesOfDayValue.jsx similarity index 83% rename from src/PolicyEditor/EffectiveTimesOfDayValue.jsx rename to src/components/policy-editor/EffectiveTimesOfDayValue.jsx index cef915a..5f4afe9 100644 --- a/src/PolicyEditor/EffectiveTimesOfDayValue.jsx +++ b/src/components/policy-editor/EffectiveTimesOfDayValue.jsx @@ -1,8 +1,8 @@ import React from 'react'; import Form from 'react-bootstrap/Form'; -import { getDeepStateProperty } from '../deepstate'; +import { getDeepStateProperty } from '../../utils/deepstate'; import { EffectiveValueColumn } from "./EffectiveValueColumn"; -import { TimesOfDayList } from '../forms/TimesOfDayList'; +import { TimesOfDayList } from '../../forms/TimesOfDayList'; export function EffectiveTimesOfDayValue(component, policyField) { return diff --git a/src/PolicyEditor/EffectiveValue.jsx b/src/components/policy-editor/EffectiveValue.jsx similarity index 92% rename from src/PolicyEditor/EffectiveValue.jsx rename to src/components/policy-editor/EffectiveValue.jsx index 2f62f1f..1f05345 100644 --- a/src/PolicyEditor/EffectiveValue.jsx +++ b/src/components/policy-editor/EffectiveValue.jsx @@ -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 EffectiveValue(component, policyField) { diff --git a/src/PolicyEditor/EffectiveValueColumn.jsx b/src/components/policy-editor/EffectiveValueColumn.jsx similarity index 100% rename from src/PolicyEditor/EffectiveValueColumn.jsx rename to src/components/policy-editor/EffectiveValueColumn.jsx diff --git a/src/PolicyEditor/LabelColumn.jsx b/src/components/policy-editor/LabelColumn.jsx similarity index 100% rename from src/PolicyEditor/LabelColumn.jsx rename to src/components/policy-editor/LabelColumn.jsx diff --git a/src/PolicyEditor/index.jsx b/src/components/policy-editor/PolicyEditor.jsx similarity index 98% rename from src/PolicyEditor/index.jsx rename to src/components/policy-editor/PolicyEditor.jsx index 75faaa7..b61554e 100644 --- a/src/PolicyEditor/index.jsx +++ b/src/components/policy-editor/PolicyEditor.jsx @@ -7,14 +7,14 @@ import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import Spinner from 'react-bootstrap/Spinner'; import Accordion from 'react-bootstrap/Accordion'; -import { handleChange, stateProperty, valueToNumber } from '../forms'; -import { StringList } from '../forms/StringList'; -import { LogDetailSelector } from '../forms/LogDetailSelector'; -import { OptionalBoolean } from '../forms/OptionalBoolean'; -import { OptionalNumberField } from '../forms/OptionalNumberField'; -import { RequiredBoolean } from '../forms/RequiredBoolean'; -import { TimesOfDayList } from '../forms/TimesOfDayList'; -import { errorAlert, PolicyEditorLink, sourceQueryStringParams, toAlgorithmOption } from '../uiutil'; +import { handleChange, stateProperty, valueToNumber } from '../../forms'; +import { StringList } from '../../forms/StringList'; +import { LogDetailSelector } from '../../forms/LogDetailSelector'; +import { OptionalBoolean } from '../../forms/OptionalBoolean'; +import { OptionalNumberField } from '../../forms/OptionalNumberField'; +import { RequiredBoolean } from '../../forms/RequiredBoolean'; +import { TimesOfDayList } from '../../forms/TimesOfDayList'; +import { errorAlert, PolicyEditorLink, sourceQueryStringParams, toAlgorithmOption } from '../../utils/uiutil'; import { LabelColumn } from './LabelColumn'; import { ValueColumn } from './ValueColumn'; import { WideValueColumn } from './WideValueColumn'; diff --git a/src/PolicyEditor/SectionHeaderRow.jsx b/src/components/policy-editor/SectionHeaderRow.jsx similarity index 100% rename from src/PolicyEditor/SectionHeaderRow.jsx rename to src/components/policy-editor/SectionHeaderRow.jsx diff --git a/src/PolicyEditor/UpcomingSnapshotTimes.jsx b/src/components/policy-editor/UpcomingSnapshotTimes.jsx similarity index 100% rename from src/PolicyEditor/UpcomingSnapshotTimes.jsx rename to src/components/policy-editor/UpcomingSnapshotTimes.jsx diff --git a/src/PolicyEditor/ValueColumn.jsx b/src/components/policy-editor/ValueColumn.jsx similarity index 100% rename from src/PolicyEditor/ValueColumn.jsx rename to src/components/policy-editor/ValueColumn.jsx diff --git a/src/PolicyEditor/WideValueColumn.jsx b/src/components/policy-editor/WideValueColumn.jsx similarity index 100% rename from src/PolicyEditor/WideValueColumn.jsx rename to src/components/policy-editor/WideValueColumn.jsx diff --git a/src/forms/index.jsx b/src/forms/index.jsx index 010fb00..ec5c418 100644 --- a/src/forms/index.jsx +++ b/src/forms/index.jsx @@ -1,4 +1,4 @@ -import { getDeepStateProperty, setDeepStateProperty } from '../deepstate.js'; +import { getDeepStateProperty, setDeepStateProperty } from '../utils/deepstate'; export function validateRequiredFields(component, fields) { let updateState = {}; diff --git a/src/PoliciesTable.jsx b/src/pages/Policies.jsx similarity index 97% rename from src/PoliciesTable.jsx rename to src/pages/Policies.jsx index 970a124..9f7ff37 100644 --- a/src/PoliciesTable.jsx +++ b/src/pages/Policies.jsx @@ -9,9 +9,9 @@ import Dropdown from 'react-bootstrap/Dropdown'; import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import { Link } from 'react-router-dom'; -import { handleChange } from './forms'; -import MyTable from './Table'; -import { CLIEquivalent, compare, DirectorySelector, isAbsolutePath, ownerName, policyEditorURL, redirect } from './uiutil'; +import { handleChange } from '../forms'; +import KopiaTable from '../utils/KopiaTable'; +import { CLIEquivalent, compare, DirectorySelector, isAbsolutePath, ownerName, policyEditorURL, redirect } from '../utils/uiutil'; const applicablePolicies = "Applicable Policies" const localPolicies = "Local Path Policies" @@ -20,7 +20,7 @@ const globalPolicy = "Global Policy" const perUserPolicies = "Per-User Policies" const perHostPolicies = "Per-Host Policies" -export class PoliciesTable extends Component { +export class Policies extends Component { constructor() { super(); this.state = { @@ -288,7 +288,7 @@ export class PoliciesTable extends Component { {policies.length > 0 ?

Found {policies.length} policies matching criteria.

- +
: ((this.state.selectedOwner === localPolicies && this.state.policyPath) ?

No policy found for directory {this.state.policyPath}. Click Set Policy to define it.

:

No policies found.

)} diff --git a/src/PolicyEditorPage.jsx b/src/pages/Policy.jsx similarity index 87% rename from src/PolicyEditorPage.jsx rename to src/pages/Policy.jsx index 206712e..e759e78 100644 --- a/src/PolicyEditorPage.jsx +++ b/src/pages/Policy.jsx @@ -1,10 +1,10 @@ import React, { Component, createRef } from 'react'; import Col from 'react-bootstrap/esm/Col'; import Row from 'react-bootstrap/esm/Row'; -import { PolicyEditor } from './PolicyEditor'; -import { CLIEquivalent, GoBackButton, parseQuery, PolicyTypeName } from './uiutil'; +import { PolicyEditor } from '../components/policy-editor/PolicyEditor'; +import { CLIEquivalent, GoBackButton, parseQuery, PolicyTypeName } from '../utils/uiutil'; -export class PolicyEditorPage extends Component { +export class Policy extends Component { constructor() { super(); diff --git a/src/PreferencesView.jsx b/src/pages/Preferences.jsx similarity index 82% rename from src/PreferencesView.jsx rename to src/pages/Preferences.jsx index 833212d..958d0f3 100644 --- a/src/PreferencesView.jsx +++ b/src/pages/Preferences.jsx @@ -1,13 +1,16 @@ import { Component } from 'react'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; +import { UIPreferencesContext } from '../contexts/UIPreferencesContext'; -export class PreferencesView extends Component { +/** + * Class that exports preferences + */ +export class Preferences extends Component { render() { const { pageSize, theme, bytesStringBase2, setByteStringBase, setTheme } = this.context; return <>
- + setByteStringBase(e.target.value)}> @@ -36,4 +39,4 @@ export class PreferencesView extends Component { } } -PreferencesView.contextType = UIPreferencesContext +Preferences.contextType = UIPreferencesContext diff --git a/src/RepoStatus.jsx b/src/pages/Repository.jsx similarity index 96% rename from src/RepoStatus.jsx rename to src/pages/Repository.jsx index c1d9265..5e646cb 100644 --- a/src/RepoStatus.jsx +++ b/src/pages/Repository.jsx @@ -7,15 +7,15 @@ import Row from 'react-bootstrap/Row'; import Form from 'react-bootstrap/Form'; import InputGroup from 'react-bootstrap/InputGroup'; import Spinner from 'react-bootstrap/Spinner'; -import { handleChange } from './forms'; -import { SetupRepository } from './SetupRepository'; -import { cancelTask, CLIEquivalent } from './uiutil'; +import { handleChange } from '../forms'; +import { SetupRepository } from '../components/SetupRepository'; +import { cancelTask, CLIEquivalent } from '../utils/uiutil'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCheck, faChevronCircleDown, faChevronCircleUp, faWindowClose } from '@fortawesome/free-solid-svg-icons'; -import { TaskLogs } from './TaskLogs'; -import { AppContext } from './contexts/AppContext'; +import { Logs } from '../components/Logs'; +import { AppContext } from '../contexts/AppContext'; -export class RepoStatus extends Component { +export class Repository extends Component { constructor() { super(); @@ -130,7 +130,7 @@ export class RepoStatus extends Component { return <>

 Initializing Repository...

{this.state.showLog ? <> - + : }
@@ -243,4 +243,4 @@ export class RepoStatus extends Component { } } -RepoStatus.contextType = AppContext; +Repository.contextType = AppContext; diff --git a/src/NewSnapshot.jsx b/src/pages/SnapshotCreate.jsx similarity index 94% rename from src/NewSnapshot.jsx rename to src/pages/SnapshotCreate.jsx index 1a62fd9..7a85f1b 100644 --- a/src/NewSnapshot.jsx +++ b/src/pages/SnapshotCreate.jsx @@ -4,12 +4,12 @@ import Button from 'react-bootstrap/Button'; import Col from 'react-bootstrap/Col'; import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; -import { handleChange } from './forms'; -import { PolicyEditor } from './PolicyEditor'; -import { EstimateResults } from './EstimateResults'; -import { CLIEquivalent, DirectorySelector, errorAlert, GoBackButton, redirect } from './uiutil'; +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'; -export class NewSnapshot extends Component { +export class SnapshotCreate extends Component { constructor() { super(); this.state = { @@ -179,7 +179,7 @@ export class NewSnapshot extends Component { {this.state.estimateTaskID && this.state.estimateTaskVisible && - + }
diff --git a/src/DirectoryObject.jsx b/src/pages/SnapshotDirectory.jsx similarity index 95% rename from src/DirectoryObject.jsx rename to src/pages/SnapshotDirectory.jsx index 96512e7..a51b3f1 100644 --- a/src/DirectoryObject.jsx +++ b/src/pages/SnapshotDirectory.jsx @@ -6,11 +6,11 @@ import Button from 'react-bootstrap/Button'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import Spinner from 'react-bootstrap/Spinner'; -import { DirectoryItems } from "./DirectoryItems"; -import { CLIEquivalent } from './uiutil'; -import { DirectoryBreadcrumbs } from "./DirectoryBreadcrumbs"; +import { DirectoryItems } from "../components/DirectoryItems"; +import { CLIEquivalent } from '../utils/uiutil'; +import { DirectoryBreadcrumbs } from "../components/DirectoryBreadcrumbs"; -export class DirectoryObject extends Component { +export class SnapshotDirectory extends Component { constructor() { super(); diff --git a/src/SnapshotsTable.jsx b/src/pages/SnapshotHistory.jsx similarity index 98% rename from src/SnapshotsTable.jsx rename to src/pages/SnapshotHistory.jsx index 18e3184..cf6324f 100644 --- a/src/SnapshotsTable.jsx +++ b/src/pages/SnapshotHistory.jsx @@ -7,13 +7,13 @@ import Button from 'react-bootstrap/Button'; import Col from 'react-bootstrap/Col'; import Spinner from 'react-bootstrap/Spinner'; import { Link } from "react-router-dom"; -import MyTable from './Table'; -import { CLIEquivalent, compare, errorAlert, GoBackButton, objectLink, parseQuery, redirect, rfc3339TimestampForDisplay, sizeWithFailures, sourceQueryStringParams } from './uiutil'; +import KopiaTable from '../utils/KopiaTable'; +import { CLIEquivalent, compare, errorAlert, GoBackButton, objectLink, parseQuery, redirect, rfc3339TimestampForDisplay, sizeWithFailures, sourceQueryStringParams } from '../utils/uiutil'; import { faSync, faThumbtack } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import Modal from 'react-bootstrap/Modal'; import { faFileAlt } from '@fortawesome/free-regular-svg-icons'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; +import { UIPreferencesContext } from '../contexts/UIPreferencesContext'; function pillVariant(tag) { if (tag.startsWith("latest-")) { @@ -34,7 +34,7 @@ function pillVariant(tag) { return "primary"; } -export class SnapshotsTable extends Component { +export class SnapshotHistory extends Component { constructor() { super(); this.state = { @@ -429,7 +429,7 @@ export class SnapshotsTable extends Component { } - + @@ -510,4 +510,4 @@ export class SnapshotsTable extends Component { ; } } -SnapshotsTable.contextType = UIPreferencesContext +SnapshotHistory.contextType = UIPreferencesContext diff --git a/src/BeginRestore.jsx b/src/pages/SnapshotRestore.jsx similarity index 94% rename from src/BeginRestore.jsx rename to src/pages/SnapshotRestore.jsx index d1d3140..1041fea 100644 --- a/src/BeginRestore.jsx +++ b/src/pages/SnapshotRestore.jsx @@ -5,13 +5,13 @@ import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import { Link } from "react-router-dom"; -import { handleChange, validateRequiredFields } from './forms'; -import { RequiredBoolean } from './forms/RequiredBoolean'; -import { RequiredField } from './forms/RequiredField'; -import { RequiredNumberField } from './forms/RequiredNumberField'; -import { errorAlert, GoBackButton } from './uiutil'; +import { handleChange, validateRequiredFields } from '../forms'; +import { RequiredBoolean } from '../forms/RequiredBoolean'; +import { RequiredField } from '../forms/RequiredField'; +import { RequiredNumberField } from '../forms/RequiredNumberField'; +import { errorAlert, GoBackButton } from '../utils/uiutil'; -export class BeginRestore extends Component { +export class SnapshotRestore extends Component { constructor(props) { super(); diff --git a/src/SourcesTable.jsx b/src/pages/Snapshots.jsx similarity index 97% rename from src/SourcesTable.jsx rename to src/pages/Snapshots.jsx index db3ebe0..de4de36 100644 --- a/src/SourcesTable.jsx +++ b/src/pages/Snapshots.jsx @@ -10,15 +10,15 @@ import Dropdown from 'react-bootstrap/Dropdown'; import Row from 'react-bootstrap/Row'; import Spinner from 'react-bootstrap/Spinner'; import { Link } from 'react-router-dom'; -import { handleChange } from './forms'; -import MyTable from './Table'; -import { CLIEquivalent, compare, errorAlert, ownerName, policyEditorURL, redirect, sizeDisplayName, sizeWithFailures, sourceQueryStringParams } from './uiutil'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; +import { handleChange } from '../forms'; +import KopiaTable from '../utils/KopiaTable'; +import { CLIEquivalent, compare, errorAlert, ownerName, policyEditorURL, redirect, sizeDisplayName, sizeWithFailures, sourceQueryStringParams } from '../utils/uiutil'; +import { UIPreferencesContext } from '../contexts/UIPreferencesContext'; const localSnapshots = "Local Snapshots" const allSnapshots = "All Snapshots" -export class SourcesTable extends Component { +export class Snapshots extends Component { constructor() { super(); this.state = { @@ -323,9 +323,9 @@ export class SourcesTable extends Component {
- + ; } } -SourcesTable.contextType = UIPreferencesContext +Snapshots.contextType = UIPreferencesContext diff --git a/src/TaskDetails.jsx b/src/pages/Task.jsx similarity index 95% rename from src/TaskDetails.jsx rename to src/pages/Task.jsx index 3c458c3..df4bbf9 100644 --- a/src/TaskDetails.jsx +++ b/src/pages/Task.jsx @@ -10,11 +10,11 @@ import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import Table from 'react-bootstrap/Table'; import Spinner from 'react-bootstrap/Spinner'; -import { TaskLogs } from './TaskLogs'; -import { cancelTask, formatDuration, GoBackButton, redirect, sizeDisplayName } from './uiutil'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; +import { Logs } from '../components/Logs'; +import { cancelTask, formatDuration, GoBackButton, redirect, sizeDisplayName } from '../utils/uiutil'; +import { UIPreferencesContext } from '../contexts/UIPreferencesContext'; -export class TaskDetails extends Component { +export class Task extends Component { constructor() { super(); this.state = { @@ -216,11 +216,11 @@ export class TaskDetails extends Component { Logs - + ; } } -TaskDetails.contextType = UIPreferencesContext \ No newline at end of file +Task.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/TasksTable.jsx b/src/pages/Tasks.jsx similarity index 95% rename from src/TasksTable.jsx rename to src/pages/Tasks.jsx index d4a9198..427df65 100644 --- a/src/TasksTable.jsx +++ b/src/pages/Tasks.jsx @@ -10,11 +10,11 @@ import Dropdown from 'react-bootstrap/Dropdown'; import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import { Link } from 'react-router-dom'; -import { handleChange } from './forms'; -import MyTable from './Table'; -import { redirect, taskStatusSymbol } from './uiutil'; +import { handleChange } from '../forms'; +import KopiaTable from '../utils/KopiaTable'; +import { redirect, taskStatusSymbol } from '../utils/uiutil'; -export class TasksTable extends Component { +export class Tasks extends Component { constructor() { super(); this.state = { @@ -160,7 +160,7 @@ export class TasksTable extends Component { {!items.length ? A list of tasks will appear here when you create snapshots, restore, run maintenance, etc. - : } + : } diff --git a/src/setupProxy.js b/src/setupProxy.js index 3c170f2..f4ab648 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -1,11 +1,11 @@ -const { createProxyMiddleware } = require('http-proxy-middleware'); - -module.exports = function(app) { - app.use( - '/api', - createProxyMiddleware({ - target: 'http://127.0.0.1:51515', - changeOrigin: true, - }) - ); +const { createProxyMiddleware } = require('http-proxy-middleware'); + +module.exports = function(app) { + app.use( + '/api', + createProxyMiddleware({ + target: 'http://127.0.0.1:51515', + changeOrigin: true, + }) + ); }; \ No newline at end of file diff --git a/src/tests/PolicyEditor.test.jsx b/src/tests/PolicyEditor.test.jsx index b7a6f4a..c27e461 100644 --- a/src/tests/PolicyEditor.test.jsx +++ b/src/tests/PolicyEditor.test.jsx @@ -1,15 +1,22 @@ import { render, waitFor, logDOM } from '@testing-library/react'; import React from 'react'; -import { PolicyEditor } from '../PolicyEditor/.'; +import { PolicyEditor } from '../components/policy-editor/PolicyEditor'; import { MemoryRouter } from 'react-router-dom'; import { setupAPIMock } from '../tests/api_mocks'; import moment from 'moment'; import { changeControlValue, simulateClick } from '../tests/testutils'; -it('e2e', async () => { - let ref = React.createRef(); - let serverMock = setupAPIMock(); +// Mockup for the server +let serverMock; +let ref; + +// Initialize the server mock before each test +beforeEach(() => { + serverMock = setupAPIMock(); + ref = React.createRef(); +}); +it('e2e', async () => { const ust1 = "2021-01-01T12:00:00Z"; const ust2 = "2021-01-01T13:00:00Z"; diff --git a/src/tests/Preferences.test.js b/src/tests/Preferences.test.js new file mode 100644 index 0000000..2660571 --- /dev/null +++ b/src/tests/Preferences.test.js @@ -0,0 +1,60 @@ +import { render, screen } from '@testing-library/react' +import { expect, test } from '@jest/globals'; +import userEvent from "@testing-library/user-event"; +import { Preferences } from '../pages/Preferences'; +const { setTheme } = jest.requireActual('../pages/Preferences'); +// Wrapper +let wrapper; + +/** + * + */ +beforeEach(() => { + wrapper = render() +}); + +/** + * + */ +describe('Calling the preference page', () => { + test('Should render preferences', () => { + expect(wrapper).toMatchSnapshot(); + }) +}) + +/** + * + */ +describe('Select the light theme', () => { + test('Should select light theme', () => { + userEvent.selectOptions( + screen.getByRole('combobox', { name: "Theme" }), + screen.getByRole('option', { name: 'light' })); + + expect(screen.getByRole('option', { name: 'light' }).selected).toBe(true) + + expect(wrapper).toMatchSnapshot(); + }) +}) + +/** + * + */ +describe('Test number of themes', () => { + test('Should have four themes', () => { + let theme = screen.getByRole('combobox', { name: "Theme" }); + expect(theme).toHaveLength(4); + expect(wrapper).toMatchSnapshot(); + }) +}) + +/** + * + */ +describe('Test byte representation', () => { + test('Should have two options', () => { + let theme = screen.getByRole('combobox', { name: "Byte representation" }); + expect(theme).toHaveLength(2); + expect(wrapper).toMatchSnapshot(); + }) +}) \ No newline at end of file diff --git a/src/tests/SetupRepository.test.jsx b/src/tests/SetupRepository.test.jsx index b462ea8..376711e 100644 --- a/src/tests/SetupRepository.test.jsx +++ b/src/tests/SetupRepository.test.jsx @@ -1,12 +1,18 @@ import { findByTestId, render, waitFor, act } from '@testing-library/react'; import React from 'react'; -import { SetupRepository } from '../SetupRepository'; +import { SetupRepository } from '../components/SetupRepository'; import { setupAPIMock } from './api_mocks'; import { changeControlValue, simulateClick } from './testutils'; -it('can create new repository when not initialized', async () => { - let serverMock = setupAPIMock(); +// Mockup for the server +let serverMock; + +// Initialize the server mock before each test +beforeEach(() => { + serverMock = setupAPIMock(); +}); +it('can create new repository when not initialized', async () => { // first attempt to connect says - NOT_INITIALIZED serverMock.onPost('/api/v1/repo/exists', { storage: { type: 'filesystem', config: { path: 'some-path' } }, @@ -43,8 +49,6 @@ it('can create new repository when not initialized', async () => { }); it('can connect to existing repository when already initialized', async () => { - let serverMock = setupAPIMock(); - // first attempt to connect is immediately successful. serverMock.onPost('/api/v1/repo/exists', { storage: { type: 'filesystem', config: { path: 'some-path' } }, @@ -61,8 +65,6 @@ it('can connect to existing repository when already initialized', async () => { }); it('can connect to existing repository using token', async () => { - let serverMock = setupAPIMock(); - serverMock.onPost('/api/v1/repo/connect', { token: "my-token", }).reply(200, {}); diff --git a/src/tests/SetupAzure.test.jsx b/src/tests/SetupRepositoryAzure.test.jsx similarity index 88% rename from src/tests/SetupAzure.test.jsx rename to src/tests/SetupRepositoryAzure.test.jsx index 3eb50ba..07b7714 100644 --- a/src/tests/SetupAzure.test.jsx +++ b/src/tests/SetupRepositoryAzure.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupAzure } from '../SetupAzure'; +import { SetupRepositoryAzure } from '../components/SetupRepositoryAzure'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupFilesystem.test.jsx b/src/tests/SetupRepositoryFilesystem.test.jsx similarity index 74% rename from src/tests/SetupFilesystem.test.jsx rename to src/tests/SetupRepositoryFilesystem.test.jsx index eae2a65..b71d29d 100644 --- a/src/tests/SetupFilesystem.test.jsx +++ b/src/tests/SetupRepositoryFilesystem.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupFilesystem } from '../SetupFilesystem'; +import { SetupRepositoryFilesystem } from '../components/SetupRepositoryFilesystem'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupGCS.test.jsx b/src/tests/SetupRepositoryGCS.test.jsx similarity index 86% rename from src/tests/SetupGCS.test.jsx rename to src/tests/SetupRepositoryGCS.test.jsx index 927b7d9..29977b9 100644 --- a/src/tests/SetupGCS.test.jsx +++ b/src/tests/SetupRepositoryGCS.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupGCS } from '../SetupGCS'; +import { SetupRepositoryGCS } from '../components/SetupRepositoryGCS'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupS3.test.jsx b/src/tests/SetupRepositoryS3.test.jsx similarity index 92% rename from src/tests/SetupS3.test.jsx rename to src/tests/SetupRepositoryS3.test.jsx index 8557b97..6de0a2a 100644 --- a/src/tests/SetupS3.test.jsx +++ b/src/tests/SetupRepositoryS3.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupS3 } from '../SetupS3'; +import { SetupRepositoryS3 } from '../components/SetupRepositoryS3'; import { changeControlValue, toggleCheckbox } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupSFTP.test.jsx b/src/tests/SetupRepositorySFTP.test.jsx similarity index 94% rename from src/tests/SetupSFTP.test.jsx rename to src/tests/SetupRepositorySFTP.test.jsx index 75a8a18..7427242 100644 --- a/src/tests/SetupSFTP.test.jsx +++ b/src/tests/SetupRepositorySFTP.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupSFTP } from '../SetupSFTP'; +import { SetupRepositorySFTP } from '../components/SetupRepositorySFTP'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupToken.test.jsx b/src/tests/SetupRepositoryToken.test.jsx similarity index 76% rename from src/tests/SetupToken.test.jsx rename to src/tests/SetupRepositoryToken.test.jsx index edefa90..2c23f3f 100644 --- a/src/tests/SetupToken.test.jsx +++ b/src/tests/SetupRepositoryToken.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupToken } from '../SetupToken'; +import { SetupRepositoryToken } from '../components/SetupRepositoryToken'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(()=>expect(ref.current.validate()).toBe(false)); // required diff --git a/src/tests/SetupWebDAV.test.jsx b/src/tests/SetupRepositoryWebDAV.test.jsx similarity index 83% rename from src/tests/SetupWebDAV.test.jsx rename to src/tests/SetupRepositoryWebDAV.test.jsx index 087efc5..aefd6fd 100644 --- a/src/tests/SetupWebDAV.test.jsx +++ b/src/tests/SetupRepositoryWebDAV.test.jsx @@ -1,11 +1,11 @@ import { render, act } from '@testing-library/react'; import React from 'react'; -import { SetupWebDAV } from '../SetupWebDAV'; +import { SetupRepositoryWebDAV } from '../components/SetupRepositoryWebDAV'; import { changeControlValue } from './testutils'; it('can set fields', async () => { let ref = React.createRef(); - const { getByTestId } = render() + const { getByTestId } = render() act(() => expect(ref.current.validate()).toBe(false)); diff --git a/src/tests/__snapshots__/Preferences.test.js.snap b/src/tests/__snapshots__/Preferences.test.js.snap new file mode 100644 index 0000000..2298024 --- /dev/null +++ b/src/tests/__snapshots__/Preferences.test.js.snap @@ -0,0 +1,1093 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Calling the preference page Should render preferences 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
+ , + "container":
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`Select the light theme Should select light theme 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
+ , + "container":
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`Test byte representation Should have two options 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
+ , + "container":
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`Test number of themes Should have four themes 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
+ , + "container":
+
+
+ + + + The current active theme + +
+
+
+ + + + Specifies the representation of bytes + +
+
+
+ + + + Specifies the pagination size in tables + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/tests/deepstate.test.js b/src/tests/deepstate.test.js index 1baf49a..9b14204 100644 --- a/src/tests/deepstate.test.js +++ b/src/tests/deepstate.test.js @@ -1,4 +1,4 @@ -import { getDeepStateProperty, setDeepStateProperty } from '../deepstate'; +import { getDeepStateProperty, setDeepStateProperty } from '../utils/deepstate'; it('can get fields', async () => { const comp = { diff --git a/src/tests/testutils.js b/src/tests/testutils.js index 72f6c3a..79c87e9 100644 --- a/src/tests/testutils.js +++ b/src/tests/testutils.js @@ -1,4 +1,4 @@ -import { fireEvent, act } from '@testing-library/react'; +import { fireEvent } from '@testing-library/react'; export function changeControlValue(selector, value) { fireEvent.change(selector, { target: { value: value } }) diff --git a/src/tests/uiutil.test.js b/src/tests/uiutil.test.js index bb2816e..7cc0192 100644 --- a/src/tests/uiutil.test.js +++ b/src/tests/uiutil.test.js @@ -1,4 +1,4 @@ -import { formatMilliseconds, separateMillisecondsIntoMagnitudes, formatMagnitudesUsingMultipleUnits } from "../uiutil"; +import { formatMilliseconds, separateMillisecondsIntoMagnitudes, formatMagnitudesUsingMultipleUnits } from "../utils/uiutil"; describe("formatMilliseconds", () => { it("uses 'XXs' format by default", () => { diff --git a/src/Table.jsx b/src/utils/KopiaTable.jsx similarity index 96% rename from src/Table.jsx rename to src/utils/KopiaTable.jsx index 93e6c2f..0ce6574 100644 --- a/src/Table.jsx +++ b/src/utils/KopiaTable.jsx @@ -3,7 +3,7 @@ import Dropdown from 'react-bootstrap/Dropdown'; import Pagination from 'react-bootstrap/Pagination'; import Table from 'react-bootstrap/Table'; import { usePagination, useSortBy, useTable } from 'react-table'; -import { PAGE_SIZES, UIPreferencesContext } from './contexts/UIPreferencesContext'; +import { PAGE_SIZES, UIPreferencesContext } from '../contexts/UIPreferencesContext'; function paginationItems(count, active, gotoPage) { let items = []; @@ -46,7 +46,7 @@ function paginationItems(count, active, gotoPage) { return items; } -export default function MyTable({ columns, data }) { +export default function KopiaTable({ columns, data }) { const { pageSize, setPageSize } = useContext(UIPreferencesContext); const { diff --git a/src/deepstate.js b/src/utils/deepstate.js similarity index 100% rename from src/deepstate.js rename to src/utils/deepstate.js diff --git a/src/uiutil.jsx b/src/utils/uiutil.jsx similarity index 100% rename from src/uiutil.jsx rename to src/utils/uiutil.jsx