From c4a08913f9e054e5413cb915672663ee4c603f0d Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Fri, 18 Jan 2019 07:09:18 +0000
Subject: [PATCH] Repo config...

---
 borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx                   |  144 ++++++++++++++++++++++++++++++++++++++++++++++++
 borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx               |   16 ++++-
 borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java |   14 ++--
 3 files changed, 165 insertions(+), 9 deletions(-)

diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
index a7673f7..125f2a0 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java
@@ -1,6 +1,8 @@
 package de.micromata.borgbutler.server.rest;
 
 import de.micromata.borgbutler.cache.ButlerCache;
+import de.micromata.borgbutler.config.BorgRepoConfig;
+import de.micromata.borgbutler.config.ConfigurationHandler;
 import de.micromata.borgbutler.data.Repository;
 import de.micromata.borgbutler.json.JsonUtils;
 import de.micromata.borgbutler.json.borg.BorgRepository;
@@ -40,7 +42,7 @@
      *
      * @param id id or name of repo.
      * @param prettyPrinter If true then the json output will be in pretty format.
-     * @return Repository (without list of archives) as json string.
+     * @return {@link Repository} (without list of archives) as json string.
      * @see JsonUtils#toJson(Object, boolean)
      */
     @GET
@@ -55,22 +57,22 @@
      *
      * @param id id or name of repo.
      * @param prettyPrinter If true then the json output will be in pretty format.
-     * @return BorgRepoConf as json string.
+     * @return {@link BorgRepoConfig} as json string.
      * @see JsonUtils#toJson(Object, boolean)
      */
     @GET
-    @Path("repo-config")
+    @Path("repoConfig")
     @Produces(MediaType.APPLICATION_JSON)
     public String getRepoConfig(@QueryParam("id") String id, @QueryParam("prettyPrinter") boolean prettyPrinter) {
-        Repository repository = ButlerCache.getInstance().getRepository(id);
-        return JsonUtils.toJson(repository, prettyPrinter);
+        BorgRepoConfig repoConfig = ConfigurationHandler.getConfiguration().getRepoConfig(id);
+        return JsonUtils.toJson(repoConfig, prettyPrinter);
     }
 
     /**
      *
      * @param id id or name of repo.
      * @param prettyPrinter If true then the json output will be in pretty format.
-     * @return Repository (including list of archives) as json string.
+     * @return {@link Repository} (including list of archives) as json string.
      * @see JsonUtils#toJson(Object, boolean)
      */
     @GET
diff --git a/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx b/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
index 32b1b91..e92d80b 100644
--- a/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
+++ b/borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx
@@ -1,12 +1,13 @@
 import React from 'react'
 import {Nav, NavLink, TabContent, Table, TabPane} from 'reactstrap';
-import { Link } from "react-router-dom";
+import {Link} from "react-router-dom";
 import classNames from 'classnames';
 import {PageHeader} from '../../general/BootstrapComponents';
 import {getRestServiceUrl, humanFileSize} from '../../../utilities/global';
 import ErrorAlert from '../../general/ErrorAlert';
 import {IconCheck, IconRefresh} from '../../general/IconComponents';
 import JobMonitorPanel from '../jobs/JobMonitorPanel';
+import RepoConfigPanel from "./RepoConfigPanel";
 
 class RepoArchiveListView extends React.Component {
 
@@ -57,7 +58,7 @@
         let pageHeader = '';
 
         if (this.state.isFetching) {
-            content = <JobMonitorPanel repo={this.state.id} />;
+            content = <JobMonitorPanel repo={this.state.id}/>;
         } else if (this.state.failed) {
             content = <ErrorAlert
                 title={'Cannot load Repositories'}
@@ -141,6 +142,12 @@
                     >
                         Information
                     </NavLink>
+                    <NavLink
+                        className={classNames({active: this.state.activeTab === '3'})}
+                        onClick={this.toggleTab('3')}
+                    >
+                        Configuration
+                    </NavLink>
                 </Nav>
                 <TabContent activeTab={this.state.activeTab}>
                     <TabPane tabId={'1'}>
@@ -156,7 +163,7 @@
                                 // Return the element. Also pass key
                                 let loaded = '';
                                 if (archive.fileListAlreadyCached) {
-                                    loaded = <IconCheck />;
+                                    loaded = <IconCheck/>;
                                 }
                                 return (
                                     <tr key={archive.id}>
@@ -194,6 +201,9 @@
                             </tbody>
                         </Table>
                     </TabPane>
+                    <TabPane tabId={'3'}>
+                        <RepoConfigPanel id={repo.id}/>
+                    </TabPane>
                 </TabContent>
             </React.Fragment>;
 
diff --git a/borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx b/borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx
new file mode 100644
index 0000000..2e239fd
--- /dev/null
+++ b/borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx
@@ -0,0 +1,144 @@
+import React from 'react';
+import {FormGroup, Input} from 'reactstrap';
+import {
+    FormButton,
+    FormField,
+    FormInput,
+    FormLabelField,
+    FormLabelInputField
+} from '../../general/forms/FormComponents';
+import {getRestServiceUrl} from '../../../utilities/global';
+import I18n from "../../general/translation/I18n";
+import LoadingOverlay from '../../general/loading/LoadingOverlay';
+import PropTypes from "prop-types";
+import ErrorAlert from "../../general/ErrorAlert";
+
+class RepoConfigPanel
+    extends React
+        .Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            loading: false,
+            repoConfig: undefined
+        };
+
+        this.fetch = this.fetch.bind(this);
+        this.handleTextChange = this.handleTextChange.bind(this);
+        this.onSave = this.onSave.bind(this);
+        this.onCancel = this.onCancel.bind(this);
+    }
+
+    componentDidMount = () => this.fetch();
+
+    fetch = () => {
+        this.setState({
+            isFetching: true,
+            failed: false,
+            repoConfig: undefined
+        });
+        fetch(getRestServiceUrl('repos/repoConfig', {
+            id: this.props.id
+        }), {
+            method: 'GET',
+            headers: {
+                'Accept': 'application/json'
+            }
+        })
+            .then(response => response.json())
+            .then(json => {
+                this.setState({
+                    isFetching: false,
+                    repoConfig: json
+                })
+            })
+            .catch((error) => {
+                console.log("error", error);
+                this.setState({
+                    isFetching: false,
+                    failed: true
+                });
+            })
+    };
+
+    handleTextChange = event => {
+        event.preventDefault();
+        this.setState({[event.target.name]: event.target.value});
+    }
+
+    onSave(event) {
+        this.setState({
+            loading: true
+        })
+        this.setState({
+            loading: false
+        })
+        this.setReload();
+    }
+
+    onCancel() {
+        this.setReload();
+    }
+
+    render() {
+        let content;
+        if (this.state.isFetching) {
+            content = <React.Fragment>Loading...</React.Fragment>;
+        } else if (this.state.failed) {
+            content = <ErrorAlert
+                title={'Cannot load config or repository'}
+                description={'Something went wrong during contacting the rest api.'}
+                action={{
+                    handleClick: this.fetchRepo,
+                    title: 'Try again'
+                }}
+            />;
+        } else if (this.state.repoConfig) {
+            const repoConfig = this.state.repoConfig;
+            content = <React.Fragment>
+                <FormGroup>
+                    <FormLabelInputField label={'Display name'} fieldLength={12}
+                                         name={'displayName'} value={repoConfig.displayName}
+                                         onChange={this.handleTextChange}
+                                         placeholder="Enter display name (only for displaying purposes)."/>
+                    <FormLabelInputField label={'Repo'} fieldLength={12}
+                                         name={'repo'} value={repoConfig.repo}
+                                         onChange={this.handleTextChange}
+                                         placeholder="Enter the name of the repo, used by Borg."/>
+                    <FormLabelInputField label={'RSH'} fieldLength={12}
+                                         name={'rsh'} value={repoConfig.rsh}
+                                         onChange={this.handleTextChange}
+                                         placeholder="Enter the rsh value (ssh command) for remote repository."/>
+                    <FormLabelInputField label={'Password command'} fieldLength={12}
+                                         name={'passwordCommand'} value={repoConfig.passwordCommand}
+                                         onChange={this.handleTextChange}
+                                         placeholder="Enter the password command to get the command from."/>
+                    <FormLabelInputField label={'Password'} fieldLength={6} type={'password'}
+                                         name={'passwordCommand'} value={repoConfig.password}
+                                         onChange={this.handleTextChange}
+                                         hint={"It's recommended to use password command instead."}
+                    />
+                    <FormField length={12}>
+                        <FormButton onClick={this.onCancel}
+                                    hintKey="configuration.cancel.hint"><I18n name={'common.cancel'}/>
+                        </FormButton>
+                        <FormButton onClick={this.onSave} bsStyle="primary"
+                                    hintKey="configuration.save.hint"><I18n name={'common.save'}/>
+                        </FormButton>
+                    </FormField>
+                </FormGroup>
+                <LoadingOverlay active={this.state.loading}/>
+            </React.Fragment>;
+        }
+        return <React.Fragment>{content}</React.Fragment>;
+    }
+}
+
+RepoConfigPanel
+    .propTypes = {
+    id: PropTypes.string
+};
+
+export default RepoConfigPanel;
+

--
Gitblit v1.10.0