| borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/ReposRest.java | ●●●●● patch | view | raw | blame | history | |
| borgbutler-webapp/src/components/views/repos/RepoArchiveListView.jsx | ●●●●● patch | view | raw | blame | history | |
| borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx | ●●●●● patch | view | raw | blame | history |
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 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>; borgbutler-webapp/src/components/views/repos/RepoConfigPanel.jsx
New file @@ -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;