From 7f0cba6b4dd5810d32ebee02d157310415804a65 Mon Sep 17 00:00:00 2001 From: Christoph Anderson Date: Mon, 8 May 2023 22:01:49 +0200 Subject: [PATCH] - Fixed byte representation - Added a darker background for the theme "dark" - Added stripes back to the tables - Moved css files in src/css - Removed the Themeselector as it now implemented in PreferencesView --- src/App.jsx | 8 ++--- src/DirectoryItems.jsx | 5 +++- src/EstimateResults.jsx | 21 +++++++------ src/Preferences.jsx | 41 ------------------------- src/PreferencesView.jsx | 43 +++++++++++++++++++++++++++ src/SnapshotsTable.jsx | 5 +++- src/SourcesTable.jsx | 19 +++++++----- src/TaskDetails.jsx | 5 +++- src/TaskLogs.jsx | 6 ++-- src/ThemeSelector.tsx | 29 ------------------ src/contexts/UIPreferencesContext.tsx | 13 ++++++-- src/{ => css}/App.css | 19 +++++------- src/{ => css}/Theme.css | 9 +++--- src/uiutil.jsx | 19 +++++++----- 14 files changed, 119 insertions(+), 123 deletions(-) delete mode 100644 src/Preferences.jsx create mode 100644 src/PreferencesView.jsx delete mode 100644 src/ThemeSelector.tsx rename src/{ => css}/App.css (94%) rename src/{ => css}/Theme.css (90%) diff --git a/src/App.jsx b/src/App.jsx index 6e9ee7f..31e64ef 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import 'bootstrap/dist/css/bootstrap.min.css'; -import './Theme.css'; -import './App.css'; +import './css/Theme.css'; +import './css/App.css'; import axios from 'axios'; import { React, Component } from 'react'; import { Navbar, Nav, Container } from 'react-bootstrap'; @@ -15,7 +15,7 @@ import { TaskDetails } from './TaskDetails'; import { TasksTable } from './TasksTable'; import { NewSnapshot } from './NewSnapshot'; import { PolicyEditorPage } from './PolicyEditorPage'; -import { Preferences } from './Preferences'; +import { PreferencesView } from './PreferencesView'; import { AppContext } from './contexts/AppContext'; import { UIPreferenceProvider } from './contexts/UIPreferencesContext'; @@ -129,7 +129,7 @@ export default class App extends Component { - + diff --git a/src/DirectoryItems.jsx b/src/DirectoryItems.jsx index 6653cd4..5159e32 100644 --- a/src/DirectoryItems.jsx +++ b/src/DirectoryItems.jsx @@ -2,6 +2,7 @@ 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'; function objectName(name, typeID) { if (typeID === "d") { @@ -33,6 +34,7 @@ function directoryLinkOrDownload(x) { export class DirectoryItems extends Component { render() { + const { bytesStringBase2 } = this.context; const columns = [{ id: "name", Header: 'Name', @@ -49,7 +51,7 @@ export class DirectoryItems extends Component { accessor: x => sizeInfo(x), Header: "Size", width: 100, - Cell: x => sizeWithFailures(x.cell.value, x.row.original.summ), + Cell: x => sizeWithFailures(x.cell.value, x.row.original.summ, bytesStringBase2), }, { id: "files", accessor: "summ.files", @@ -65,3 +67,4 @@ export class DirectoryItems extends Component { return ; } } +DirectoryItems.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/EstimateResults.jsx b/src/EstimateResults.jsx index 24d5fee..de128d3 100644 --- a/src/EstimateResults.jsx +++ b/src/EstimateResults.jsx @@ -8,6 +8,7 @@ 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'; export class EstimateResults extends Component { constructor() { @@ -87,6 +88,7 @@ export class EstimateResults extends Component { render() { const { task, isLoading, error } = this.state; + const { bytesStringBase2 } = this.context if (error) { return

{error.message}

; } @@ -97,20 +99,21 @@ export class EstimateResults extends Component { return <> {task.counters && - {this.taskStatusDescription(task)} Bytes: {sizeDisplayName(task.counters["Bytes"]?.value)} ({sizeDisplayName(task.counters["Excluded Bytes"]?.value)} excluded) + {this.taskStatusDescription(task)} Bytes: {sizeDisplayName(task.counters["Bytes"]?.value, bytesStringBase2)} ({sizeDisplayName(task.counters["Excluded Bytes"]?.value, bytesStringBase2)} excluded) Files: {task.counters["Files"]?.value} ({task.counters["Excluded Files"]?.value} excluded) Directories: {task.counters["Directories"]?.value} ({task.counters["Excluded Directories"]?.value} excluded) Errors: {task.counters["Errors"]?.value} ({task.counters["Ignored Errors"]?.value} ignored) - + } - {task.status === "RUNNING" && <> -   - } - {this.state.showLog ? <> - - - : } + {task.status === "RUNNING" && <> +   + } + {this.state.showLog ? <> + + + : } ; } } +EstimateResults.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/Preferences.jsx b/src/Preferences.jsx deleted file mode 100644 index 348ac31..0000000 --- a/src/Preferences.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Component } from 'react'; -import { ThemeSelector } from './ThemeSelector'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; - -export class Preferences extends Component { - static contextType = UIPreferencesContext; - constructor() { - super(); - this.state = { - status: {}, - error: null, - }; - } - - render() { - const { pageSize, bytesStringBase2 } = this.context; - return <> -
-
- - - The current active theme -
-
-
- - - Represents bytes to the base of 2 -
-
-
- - - The number of items shown in tables -
-
- - } -} \ No newline at end of file diff --git a/src/PreferencesView.jsx b/src/PreferencesView.jsx new file mode 100644 index 0000000..282585c --- /dev/null +++ b/src/PreferencesView.jsx @@ -0,0 +1,43 @@ +import { Component } from 'react'; +import { UIPreferencesContext } from './contexts/UIPreferencesContext'; + +export class PreferencesView extends Component { + constructor() { + super(); + } + + render() { + const { pageSize, theme, bytesStringBase2, setByteStringBase, setTheme } = this.context; + return <> +
+
+ + + The current active theme +
+
+
+ + + Specifies the representation of bytes +
+
+
+ + + Specifies the pagination size in tables +
+
+ + } +} +PreferencesView.contextType = UIPreferencesContext diff --git a/src/SnapshotsTable.jsx b/src/SnapshotsTable.jsx index d4a4ea9..9d89317 100644 --- a/src/SnapshotsTable.jsx +++ b/src/SnapshotsTable.jsx @@ -13,6 +13,7 @@ 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'; function pillVariant(tag) { if (tag.startsWith("latest-")) { @@ -314,6 +315,7 @@ export class SnapshotsTable extends Component { render() { let { snapshots, unfilteredCount, uniqueCount, isLoading, error } = this.state; + const { bytesStringBase2 } = this.context if (error) { return

{error.message}

; } @@ -362,7 +364,7 @@ export class SnapshotsTable extends Component { Header: 'Size', accessor: 'summary.size', width: 100, - Cell: x => sizeWithFailures(x.cell.value, x.row.original.summary), + Cell: x => sizeWithFailures(x.cell.value, x.row.original.summary, bytesStringBase2), }, { Header: 'Files', accessor: 'summary.files', @@ -502,3 +504,4 @@ export class SnapshotsTable extends Component { ; } } +SnapshotsTable.contextType = UIPreferencesContext diff --git a/src/SourcesTable.jsx b/src/SourcesTable.jsx index 02a4479..cacf096 100644 --- a/src/SourcesTable.jsx +++ b/src/SourcesTable.jsx @@ -13,6 +13,7 @@ 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'; const localSnapshots = "Local Snapshots" const allSnapshots = "All Snapshots" @@ -88,7 +89,7 @@ export class SourcesTable extends Component { }); } - statusCell(x, parent) { + statusCell(x, parent, bytesStringBase2) { switch (x.cell.value) { case "IDLE": case "PAUSED": @@ -96,7 +97,7 @@ export class SourcesTable extends Component { ; @@ -111,15 +112,15 @@ export class SourcesTable extends Component { let title = ""; let totals = ""; if (u) { - title = " hashed " + u.hashedFiles + " files (" + sizeDisplayName(u.hashedBytes) + ")\n" + - " cached " + u.cachedFiles + " files (" + sizeDisplayName(u.cachedBytes) + ")\n" + + title = " hashed " + u.hashedFiles + " files (" + sizeDisplayName(u.hashedBytes, bytesStringBase2) + ")\n" + + " cached " + u.cachedFiles + " files (" + sizeDisplayName(u.cachedBytes, bytesStringBase2) + ")\n" + " dir " + u.directory; const totalBytes = u.hashedBytes + u.cachedBytes; - totals = sizeDisplayName(totalBytes); + totals = sizeDisplayName(totalBytes, bytesStringBase2); if (u.estimatedBytes) { - totals += "/" + sizeDisplayName(u.estimatedBytes); + totals += "/" + sizeDisplayName(u.estimatedBytes, bytesStringBase2); const percent = Math.round(totalBytes * 1000.0 / u.estimatedBytes) / 10.0; if (percent <= 100) { @@ -178,6 +179,7 @@ export class SourcesTable extends Component { render() { let { sources, isLoading, error } = this.state; + const { bytesStringBase2 } = this.context if (error) { return

{error.message}

; } @@ -234,7 +236,7 @@ export class SourcesTable extends Component { accessor: x => x.lastSnapshot ? x.lastSnapshot.stats.totalSize : 0, Cell: x => sizeWithFailures( x.cell.value, - x.row.original.lastSnapshot && x.row.original.lastSnapshot.rootEntry ? x.row.original.lastSnapshot.rootEntry.summ : null), + x.row.original.lastSnapshot && x.row.original.lastSnapshot.rootEntry ? x.row.original.lastSnapshot.rootEntry.summ : null, bytesStringBase2), }, { id: 'lastSnapshotTime', Header: 'Last Snapshot', @@ -252,7 +254,7 @@ export class SourcesTable extends Component { Header: '', width: 300, accessor: x => x.status, - Cell: x => this.statusCell(x, this), + Cell: x => this.statusCell(x, this, bytesStringBase2), }] return <> @@ -290,3 +292,4 @@ export class SourcesTable extends Component { ; } } +SourcesTable.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/TaskDetails.jsx b/src/TaskDetails.jsx index 7eef578..3c458c3 100644 --- a/src/TaskDetails.jsx +++ b/src/TaskDetails.jsx @@ -12,6 +12,7 @@ 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'; export class TaskDetails extends Component { constructor() { @@ -157,6 +158,7 @@ export class TaskDetails extends Component { render() { const { task, isLoading, error } = this.state; + const { bytesStringBase2 } = this.context if (error) { return

{error.message}

; } @@ -192,7 +194,7 @@ export class TaskDetails extends Component { - {this.sortedBadges(task.counters)} + {this.sortedBadges(task.counters, bytesStringBase2)} @@ -221,3 +223,4 @@ export class TaskDetails extends Component { ; } } +TaskDetails.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/TaskLogs.jsx b/src/TaskLogs.jsx index 38e5209..d2c43f4 100644 --- a/src/TaskLogs.jsx +++ b/src/TaskLogs.jsx @@ -82,7 +82,7 @@ export class TaskLogs extends Component { formatLogParams(entry) { // if there are any properties other than `msg, ts, level, mod` output them as JSON. - let {msg, ts, level, mod, ...parametersOnly} = entry; + let { msg, ts, level, mod, ...parametersOnly } = entry; const p = JSON.stringify(parametersOnly); if (p !== "{}") { @@ -111,11 +111,11 @@ export class TaskLogs extends Component { if (logs) { return
- {logs.map((v,ndx) => + {logs.map((v, ndx) => )}
{this.formatLogTime(v.ts)} {v.msg} {this.formatLogParams(v)}
-
+
; } diff --git a/src/ThemeSelector.tsx b/src/ThemeSelector.tsx deleted file mode 100644 index e6eb0b6..0000000 --- a/src/ThemeSelector.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import Select from 'react-select' -import { useContext } from 'react'; -import { UIPreferencesContext } from './contexts/UIPreferencesContext'; - -export function ThemeSelector() { - const { theme, setTheme } = useContext(UIPreferencesContext); - - //Contains all supported themes - const themes = [ - { value: 'light', label: 'light' }, - { value: 'dark', label: 'dark' }, - { value: 'pastel', label: 'pastel' }, - { value: 'ocean', label: 'ocean' } - ] - - //Finds the current selected theme within supported themes - const currentTheme = themes.find(o => o.value === theme); - - /** - * Handles the theme selection by the user - * @param event - */ - const handleTheme = (event: any) => { - var selectedTheme = event.value; - setTheme(selectedTheme) - }; - - return