ServerConfiguration is also stored in json.
1 files deleted
12 files modified
| | |
| | | * A name describing this config. Only used for displaying purposes. |
| | | */ |
| | | @Getter @Setter |
| | | @JsonProperty("display_name") |
| | | private String displayName; |
| | | @Getter @Setter |
| | | private String repo; |
| | |
| | | * Default dir name for restoring archives. |
| | | */ |
| | | private static final String RESTORE_DIRNAME = "restore"; |
| | | |
| | | @JsonIgnore |
| | | private File workingDir; |
| | | |
| | | @Getter |
| | | private String borgCommand = "borg"; |
| | | /** |
| | | * Default is 100 MB (approximately). |
| | | */ |
| | | @Getter |
| | | @JsonProperty("max_archive_ontent_cache_capacity_mb") |
| | | private int maxArchiveContentCacheCapacityMb = 100; |
| | | |
| | | /** |
| | | * Default is restore inside BorgButler's home dir (~/.borgbutler/restore). |
| | | */ |
| | | @Getter |
| | | @JsonProperty("restore_dir") |
| | | @JsonProperty("restoreDir") |
| | | private String restoreDirPath; |
| | | @JsonIgnore |
| | | private File restoreHomeDir; |
| | | |
| | | @Getter |
| | | @JsonProperty("repo-configs") |
| | | private List<BorgRepoConfig> repoConfigs = new ArrayList<>(); |
| | | |
| | | public void add(BorgRepoConfig repoConfig) { |
| | |
| | | if (StringUtils.isNotBlank(restoreDirPath)) { |
| | | restoreHomeDir = new File(restoreDirPath); |
| | | } else { |
| | | restoreHomeDir = new File(ConfigurationHandler.getInstance().getWorkingDir(), RESTORE_DIRNAME); |
| | | restoreHomeDir = new File(workingDir, RESTORE_DIRNAME); |
| | | } |
| | | if (!restoreHomeDir.exists()) { |
| | | log.info("Creating dir '" + restoreHomeDir.getAbsolutePath() + "' for restoring backup files and directories."); |
| | |
| | | } |
| | | return restoreHomeDir; |
| | | } |
| | | |
| | | public void copyFrom(Configuration other) { |
| | | this.borgCommand = other.borgCommand; |
| | | this.maxArchiveContentCacheCapacityMb = other.maxArchiveContentCacheCapacityMb; |
| | | } |
| | | } |
| | |
| | | |
| | | import de.micromata.borgbutler.json.JsonUtils; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import org.apache.commons.io.FileUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | |
| | | |
| | | public class ConfigurationHandler { |
| | | private static Logger log = LoggerFactory.getLogger(ConfigurationHandler.class); |
| | | private static ConfigurationHandler instance = new ConfigurationHandler(); |
| | | private static ConfigurationHandler instance; |
| | | private static final String BUTLER_HOME_DIR = ".borgbutler"; |
| | | private static final String CONFIG_FILENAME = "borgbutler-config.json"; |
| | | private static final String CONFIG_BACKUP_FILENAME = "borgbutler-config-bak.json"; |
| | |
| | | private File configBackupFile; |
| | | @Getter |
| | | private File workingDir; |
| | | private Configuration configuration = new Configuration(); |
| | | private Configuration configuration; |
| | | @Setter |
| | | private static Class<? extends Configuration> configClazz = Configuration.class; |
| | | |
| | | public static ConfigurationHandler getInstance() { |
| | | if (instance == null) instance = new ConfigurationHandler(); |
| | | return instance; |
| | | } |
| | | |
| | | public static Configuration getConfiguration() { |
| | | return instance.configuration; |
| | | return getInstance().configuration; |
| | | } |
| | | |
| | | private void read() { |
| | | log.info("Reading config file '" + configFile.getAbsolutePath() + "'"); |
| | | try { |
| | | String json = FileUtils.readFileToString(configFile, Definitions.STD_CHARSET); |
| | | this.configuration = JsonUtils.fromJson(Configuration.class, json); |
| | | for (BorgRepoConfig repoConfig : this.configuration.getRepoConfigs()) { |
| | | if (StringUtils.isBlank(repoConfig.getDisplayName())) { |
| | | repoConfig.setDisplayName(repoConfig.getRepo()); |
| | | String json = "{}"; |
| | | if (configFile.exists()) { |
| | | json = FileUtils.readFileToString(configFile, Definitions.STD_CHARSET); |
| | | // Migrate from first version: |
| | | if (json.contains("repo-configs")) { |
| | | json = json.replace("repo-configs", "repoConfigs"); |
| | | json = json.replace("display_name", "displayName"); |
| | | } |
| | | } |
| | | this.configuration = JsonUtils.fromJson(configClazz, json); |
| | | if (this.configuration.getRepoConfigs() != null) { |
| | | for (BorgRepoConfig repoConfig : this.configuration.getRepoConfigs()) { |
| | | if (StringUtils.isBlank(repoConfig.getDisplayName())) { |
| | | repoConfig.setDisplayName(repoConfig.getRepo()); |
| | | } |
| | | } |
| | | } |
| | | } catch (IOException ex) { |
| | |
| | | } |
| | | } |
| | | |
| | | public void write() { |
| | | public void save() { |
| | | String json = JsonUtils.toJson(configuration, true); |
| | | try { |
| | | if (configFile.exists()) { |
| | |
| | | File workingDir = ConfigurationHandler.getInstance().getWorkingDir(); |
| | | File origConfigFile = new File(workingDir, ".borgbutler-orig.json"); |
| | | FileUtils.copyFile(ConfigurationHandler.getInstance().getConfigFile(), origConfigFile); |
| | | ConfigurationHandler.getInstance().write(); |
| | | ConfigurationHandler.getInstance().save(); |
| | | FileUtils.copyFile(origConfigFile, ConfigurationHandler.getInstance().getConfigFile()); |
| | | } |
| | | } |
| | |
| | | package de.micromata.borgbutler.server; |
| | | |
| | | import de.micromata.borgbutler.cache.ButlerCache; |
| | | import de.micromata.borgbutler.config.ConfigurationHandler; |
| | | import de.micromata.borgbutler.json.borg.BorgFilesystemItem; |
| | | import de.micromata.borgbutler.server.jetty.JettyServer; |
| | | import de.micromata.borgbutler.server.user.SingleUserManager; |
| | |
| | | |
| | | |
| | | private void _start(String[] args) { |
| | | ConfigurationHandler.setConfigClazz(ServerConfiguration.class); |
| | | // create Options object |
| | | Options options = new Options(); |
| | | options.addOption("e", "extract-archive-content", true, "Extracts the content of an archive cache file only (doesn't start the server). A complete file list of the archive will be extracted to stdout."); |
| | |
| | | System.err.println("Port outside range."); |
| | | return; |
| | | } |
| | | ServerConfigurationHandler.getDefaultConfiguration().setPort(port); |
| | | ServerConfiguration.get().setPort(port); |
| | | } catch (NumberFormatException ex) { |
| | | printHelp(options); |
| | | return; |
| | |
| | | package de.micromata.borgbutler.server; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.fasterxml.jackson.annotation.JsonProperty; |
| | | import de.micromata.borgbutler.config.Configuration; |
| | | import de.micromata.borgbutler.config.ConfigurationHandler; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import org.apache.commons.lang3.StringUtils; |
| | |
| | | |
| | | import java.beans.Transient; |
| | | |
| | | public class ServerConfiguration { |
| | | public class ServerConfiguration extends Configuration { |
| | | private static Logger log = LoggerFactory.getLogger(ServerConfiguration.class); |
| | | private final static String[] SUPPORTED_LANGUAGES = {"en", "de"}; |
| | | public static final int WEBSERVER_PORT_DEFAULT = 9042; |
| | | private static final boolean SHOW_TEST_DATA_PREF_DEFAULT = false; |
| | | private static final boolean WEB_DEVELOPMENT_MODE_PREF_DEFAULT = false; |
| | | |
| | | private static String applicationHome; |
| | | |
| | | private int port; |
| | | private int port = WEBSERVER_PORT_DEFAULT; |
| | | @Getter |
| | | @Setter |
| | | private boolean showTestData = true; |
| | | private boolean webDevelopmentMode = false; |
| | | private boolean templatesDirModified = false; |
| | | @JsonIgnore |
| | | private boolean showTestData = SHOW_TEST_DATA_PREF_DEFAULT; |
| | | private boolean webDevelopmentMode = WEB_DEVELOPMENT_MODE_PREF_DEFAULT; |
| | | |
| | | public static ServerConfiguration getDefault() { |
| | | return ServerConfigurationHandler.getDefaultConfiguration(); |
| | | public static ServerConfiguration get() { |
| | | return (ServerConfiguration)ConfigurationHandler.getConfiguration(); |
| | | } |
| | | |
| | | public static String[] getSupportedLanguages() { |
| | |
| | | return applicationHome; |
| | | } |
| | | |
| | | public void resetModifiedFlag() { |
| | | templatesDirModified = false; |
| | | } |
| | | |
| | | @Transient |
| | | public boolean isTemplatesDirModified() { |
| | | return templatesDirModified; |
| | | } |
| | | |
| | | public int getPort() { |
| | | return port; |
| | | } |
| | |
| | | } |
| | | |
| | | public void copyFrom(ServerConfiguration other) { |
| | | super.copyFrom(other); |
| | | this.port = other.port; |
| | | this.showTestData = other.showTestData; |
| | | this.webDevelopmentMode = other.webDevelopmentMode; |
| | |
| | | package de.micromata.borgbutler.server.jetty; |
| | | |
| | | import de.micromata.borgbutler.server.ServerConfiguration; |
| | | import de.micromata.borgbutler.server.ServerConfigurationHandler; |
| | | import de.micromata.borgbutler.server.RunningMode; |
| | | import de.micromata.borgbutler.server.rest.ConfigurationRest; |
| | | import de.micromata.borgbutler.server.user.UserFilter; |
| | |
| | | errorHandler.addErrorPage(404, "/"); |
| | | ctx.setErrorHandler(errorHandler); |
| | | |
| | | if (RunningMode.isDevelopmentMode() || ServerConfigurationHandler.getDefaultConfiguration().isWebDevelopmentMode()) { |
| | | if (RunningMode.isDevelopmentMode() || ServerConfiguration.get().isWebDevelopmentMode()) { |
| | | log.warn("*********************************"); |
| | | log.warn("*********** **********"); |
| | | log.warn("*********** ATTENTION! **********"); |
| | |
| | | } |
| | | |
| | | private int findFreePort() { |
| | | int port = ServerConfigurationHandler.getInstance().getConfiguration().getPort(); |
| | | int port = ServerConfiguration.get().getPort(); |
| | | return findFreePort(port); |
| | | } |
| | | |
| | |
| | | int port = startPort > 0 ? startPort : 1; |
| | | if (port > MAX_PORT_NUMBER) { |
| | | log.warn("Port can't be higher than " + MAX_PORT_NUMBER + ": " + port + ". It's a possible mis-configuration."); |
| | | port = ServerConfigurationHandler.WEBSERVER_PORT_DEFAULT; |
| | | port = ServerConfiguration.WEBSERVER_PORT_DEFAULT; |
| | | } |
| | | for (int i = port; i < port + 10; i++) { |
| | | try (ServerSocket socket = new ServerSocket()) { |
| | |
| | | continue; // try next port |
| | | } |
| | | } |
| | | if (startPort != ServerConfigurationHandler.WEBSERVER_PORT_DEFAULT) { |
| | | if (startPort != ServerConfiguration.WEBSERVER_PORT_DEFAULT) { |
| | | log.info("Trying to fix port due to a possible mis-configuration."); |
| | | return findFreePort(ServerConfigurationHandler.WEBSERVER_PORT_DEFAULT); |
| | | return findFreePort(ServerConfiguration.WEBSERVER_PORT_DEFAULT); |
| | | } |
| | | log.error("No free port found! Giving up."); |
| | | return -1; |
| | |
| | | package de.micromata.borgbutler.server.rest; |
| | | |
| | | import de.micromata.borgbutler.cache.ButlerCache; |
| | | import de.micromata.borgbutler.config.ConfigurationHandler; |
| | | import de.micromata.borgbutler.json.JsonUtils; |
| | | import de.micromata.borgbutler.server.ServerConfiguration; |
| | | import de.micromata.borgbutler.server.ServerConfigurationHandler; |
| | | import de.micromata.borgbutler.server.user.UserData; |
| | | import de.micromata.borgbutler.server.user.UserManager; |
| | | import org.apache.commons.lang3.StringUtils; |
| | |
| | | * @see JsonUtils#toJson(Object, boolean) |
| | | */ |
| | | public String getConfig(@QueryParam("prettyPrinter") boolean prettyPrinter) { |
| | | ServerConfiguration config = new ServerConfiguration(); |
| | | config.copyFrom(ServerConfigurationHandler.getInstance().getConfiguration()); |
| | | String json = JsonUtils.toJson(config, prettyPrinter); |
| | | String json = JsonUtils.toJson(ServerConfiguration.get(), prettyPrinter); |
| | | return json; |
| | | } |
| | | |
| | |
| | | @Path("config") |
| | | @Produces(MediaType.TEXT_PLAIN) |
| | | public void setConfig(String jsonConfig) { |
| | | ServerConfigurationHandler configurationHandler = ServerConfigurationHandler.getInstance(); |
| | | ServerConfiguration config = configurationHandler.getConfiguration(); |
| | | ConfigurationHandler configurationHandler = ConfigurationHandler.getInstance(); |
| | | ServerConfiguration config = (ServerConfiguration)configurationHandler.getConfiguration(); |
| | | ServerConfiguration srcConfig = JsonUtils.fromJson(ServerConfiguration.class, jsonConfig); |
| | | config.copyFrom(srcConfig); |
| | | configurationHandler.save(); |
| | |
| | | * Resets the settings to default values (deletes all settings). |
| | | */ |
| | | @GET |
| | | @Path("reset") |
| | | @Produces(MediaType.APPLICATION_JSON) |
| | | public String resetConfig(@QueryParam("IKnowWhatImDoing") boolean securityQuestion) { |
| | | if (securityQuestion) { |
| | | ServerConfigurationHandler.getInstance().removeAllSettings(); |
| | | } |
| | | return getConfig(false); |
| | | } |
| | | |
| | | /** |
| | | * Resets the settings to default values (deletes all settings). |
| | | */ |
| | | @GET |
| | | @Path("clearAllCaches") |
| | | @Produces(MediaType.APPLICATION_JSON) |
| | | public String clearAllCaches() { |
| | |
| | | |
| | | import de.micromata.borgbutler.server.Languages; |
| | | import de.micromata.borgbutler.server.RunningMode; |
| | | import de.micromata.borgbutler.server.ServerConfigurationHandler; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.util.Locale; |
| | | import java.util.prefs.BackingStoreException; |
| | | import java.util.prefs.Preferences; |
| | | |
| | | /** |
| | | * Contains only one (dummy) user (for desktop version). |
| | |
| | | private static final String USER_LOCAL_PREF_KEY = "userLocale"; |
| | | private static Logger log = LoggerFactory.getLogger(SingleUserManager.class); |
| | | private UserData singleUser; |
| | | private Preferences preferences; |
| | | |
| | | public SingleUserManager() { |
| | | if (RunningMode.getUserManagement() != RunningMode.UserManagement.SINGLE) { |
| | |
| | | + "'. Only allowed in '" + RunningMode.UserManagement.SINGLE + "'."); |
| | | } |
| | | log.info("Using SingleUserManger as user manager."); |
| | | preferences = Preferences.userRoot().node("de").node("micromata").node("borgbutler"); |
| | | singleUser = new UserData(); |
| | | singleUser.setUsername("admin"); |
| | | singleUser.setAdmin(true); |
| | | String language = ServerConfigurationHandler.getInstance().get("userLocale", null); |
| | | Locale locale = Languages.asLocale(language); |
| | | singleUser.setLocale(locale); |
| | | String dateFormat = ServerConfigurationHandler.getInstance().get("userDateFormat", null); |
| | | singleUser.setDateFormat(dateFormat); |
| | | load(singleUser); |
| | | } |
| | | |
| | | public UserData getUser(String id) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Stores only the user's configured locale. |
| | | * Stores only the user's configured locale as preference. |
| | | * |
| | | * @param userData |
| | | * @see ServerConfigurationHandler#save(String, String) |
| | | * @see Preferences |
| | | */ |
| | | @Override |
| | | public void saveUser(UserData userData) { |
| | |
| | | String dateFormat = userData.getDateFormat(); |
| | | this.singleUser.setDateFormat(dateFormat); |
| | | String lang = Languages.asString(locale); |
| | | ServerConfigurationHandler.getInstance().save("userLocale", lang); |
| | | ServerConfigurationHandler.getInstance().save("userDateFormat", dateFormat); |
| | | preferences.put(USER_LOCAL_PREF_KEY, lang); |
| | | try { |
| | | preferences.flush(); |
| | | } catch (BackingStoreException ex) { |
| | | log.error("Can't save user locale to preferences: " + ex.getMessage(), ex); |
| | | } |
| | | } |
| | | |
| | | private void load(UserData userData) { |
| | | String language = preferences.get(USER_LOCAL_PREF_KEY, "en"); |
| | | Locale locale = Languages.asLocale(language); |
| | | singleUser.setLocale(locale); |
| | | } |
| | | } |
| | |
| | | return resp.json() |
| | | }) |
| | | .then((data) => { |
| | | const {locale, dateFormat, ...user} = data; |
| | | const {locale, ...user} = data; |
| | | this.setState({ |
| | | loading: false, |
| | | locale: locale ? locale : '', |
| | | dateFormat: dateFormat ? dateFormat : '', |
| | | ...user |
| | | }) |
| | | }) |
| | |
| | | this.state = { |
| | | loading: true, |
| | | failed: false, |
| | | locale: null, |
| | | dateFormat: null |
| | | locale: null |
| | | }; |
| | | |
| | | this.handleTextChange = this.handleTextChange.bind(this); |
| | |
| | | |
| | | save() { |
| | | var user = { |
| | | locale: this.state.locale, |
| | | dateFormat: this.state.dateFormat |
| | | locale: this.state.locale |
| | | }; |
| | | return fetch(getRestServiceUrl("configuration/user"), { |
| | | method: 'POST', |
| | |
| | | <FormOption value={'de'} i18nKey={'language.german'}/> |
| | | </FormSelect> |
| | | </FormLabelField> |
| | | <FormGroup> |
| | | <FormLabel length={2} htmlFor={'dateFormat'}> |
| | | <I18n name={'configuration.application.dateFormat'}/> |
| | | </FormLabel> |
| | | <FormField length={2}> |
| | | <FormSelect value={this.state.dateFormat} name={'dateFormat'} onChange={this.handleTextChange}> |
| | | <FormOption value={''} i18nKey={'configuration.application.dateFormat.option.auto'}/> |
| | | <FormOption value={'dd.MM.yyyy'} label={'16.01.2018'}/> |
| | | <FormOption value={'d.M.yy'} label={'16.1.18'}/> |
| | | <FormOption value={'yyyy-MM-dd'} label={'2018-01-16'}/> |
| | | <FormOption value={'dd/MM/yyyy'} label={'16/01/2018'}/> |
| | | <FormOption value={'d/M/yy'} label={'16/1/18'}/> |
| | | <FormOption value={'MM/dd/yyyy'} label={'01/16/2018'}/> |
| | | <FormOption value={'M/d/yy'} label={'1/16/18'}/> |
| | | </FormSelect> |
| | | </FormField> |
| | | </FormGroup> |
| | | </form> |
| | | ); |
| | | } |
| | |
| | | className={classNames({active: this.state.activeTab === '1'})} |
| | | onClick={this.toggleTab('1')} |
| | | > |
| | | <I18n name={'configuration.account'}/> |
| | | <I18n name={'configuration.server'}/> |
| | | </NavLink> |
| | | <NavLink |
| | | className={classNames({active: this.state.activeTab === '2'})} |
| | | onClick={this.toggleTab('2')} |
| | | > |
| | | <I18n name={'configuration.server'}/> |
| | | <I18n name={'configuration.account'}/> |
| | | </NavLink> |
| | | </Nav> |
| | | <TabContent activeTab={this.state.activeTab}> |
| | | <TabPane tabId={'1'}> |
| | | <ConfigAccountTab ref={this.accountTabRef}/> |
| | | <ConfigServerTab ref={this.serverTabRef}/> |
| | | </TabPane> |
| | | </TabContent> |
| | | <TabContent activeTab={this.state.activeTab}> |
| | | <TabPane tabId={'2'}> |
| | | <ConfigServerTab ref={this.serverTabRef}/> |
| | | <ConfigAccountTab ref={this.accountTabRef}/> |
| | | </TabPane> |
| | | </TabContent> |
| | | <FormGroup> |
| | |
| | | import React from 'react'; |
| | | import {FormButton, FormCheckbox, FormLabelField, FormLabelInputField} from "../../general/forms/FormComponents"; |
| | | import {getRestServiceUrl} from "../../../utilities/global"; |
| | | import {IconDanger} from '../../general/IconComponents'; |
| | | import {getTranslation} from "../../../utilities/i18n"; |
| | | import I18n from "../../general/translation/I18n"; |
| | | import ErrorAlertGenericRestFailure from '../../general/ErrorAlertGenericRestFailure'; |
| | | import Loading from "../../general/Loading"; |
| | |
| | | loading: true, |
| | | failed: false, |
| | | port: 9042, |
| | | webDevelopmentMode: false, |
| | | webdevelopmentMode: false, |
| | | maxArchiveContentCacheCapacityMb: 100, |
| | | redirect: false |
| | | }; |
| | | |
| | | this.handleTextChange = this.handleTextChange.bind(this); |
| | | this.handleCheckboxChange = this.handleCheckboxChange.bind(this); |
| | | this.onResetConfiguration = this.onResetConfiguration.bind(this); |
| | | this.onClearAllCaches = this.onClearAllCaches.bind(this); |
| | | this.loadConfig = this.loadConfig.bind(this); |
| | | } |
| | |
| | | save() { |
| | | var config = { |
| | | port: this.state.port, |
| | | maxArchiveContentCacheCapacityMb : this.state.maxArchiveContentCacheCapacityMb, |
| | | webDevelopmentMode: this.state.webDevelopmentMode |
| | | }; |
| | | return fetch(getRestServiceUrl("configuration/config"), { |
| | |
| | | }) |
| | | } |
| | | |
| | | onResetConfiguration() { |
| | | if (window.confirm(getTranslation('configuration.resetAllSettings.question'))) { |
| | | fetch(getRestServiceUrl("configuration/reset?IKnowWhatImDoing=true"), { |
| | | method: "GET", |
| | | dataType: "JSON", |
| | | headers: { |
| | | "Content-Type": "text/plain; charset=utf-8" |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | onClearAllCaches() { |
| | | if (window.confirm('Do you really want to clear all caches? All Archive file lists and caches for repo and archive informatino will be cleared.')) { |
| | | fetch(getRestServiceUrl("configuration/clearAllCaches"), { |
| | |
| | | if (this.state.failed) { |
| | | return <ErrorAlertGenericRestFailure handleClick={this.loadConfig}/>; |
| | | } |
| | | |
| | | return ( |
| | | <form> |
| | | <FormLabelField> |
| | |
| | | name={'port'} value={this.state.port} |
| | | onChange={this.handleTextChange} |
| | | placeholder="Enter port"/> |
| | | <FormLabelInputField label={'Maximum disc capacity (MB)'} fieldLength={2} type="number" min={50} max={10000} |
| | | step={50} |
| | | name={'maxArchiveContentCacheCapacityMb'} value={this.state.maxArchiveContentCacheCapacityMb} |
| | | onChange={this.handleTextChange} |
| | | placeholder="Enter maximum Capacity"/> |
| | | <FormLabelField label={<I18n name={'configuration.webDevelopmentMode'}/>} fieldLength={2}> |
| | | <FormCheckbox checked={this.state.webDevelopmentMode} |
| | | hintKey={'configuration.webDevelopmentMode.hint'} |
| | | name="webDevelopmentMode" |
| | | onChange={this.handleCheckboxChange}/> |
| | | </FormLabelField> |
| | | <FormLabelField> |
| | | <FormButton id={'resetFactorySettings'} onClick={this.onResetConfiguration} |
| | | hintKey={'configuration.resetAllSettings.hint'}> <IconDanger/> <I18n |
| | | name={'configuration.resetAllSettings'}/> |
| | | </FormButton> |
| | | </FormLabelField> |
| | | </form> |
| | | ); |
| | | } |