From 862d0445280ed19837b8e518ba3b7e20de813ba2 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Apr 01 2020 15:56:32 +0000 Subject: Issue 50994 - Fix latest UI bugs found by QE Description: This address many bugs, most of whioch is very small fixes: - [Bug 1816563] Referential integrity scope values are not saved in cockpit - [Bug 1816599] Initializing database from Ldif is broken in Cockpit - [Bug 1816708] Removing objectclass does not ask for confirmation - [Bug 1816712] Removing attribute does not ask for confirmation - [Bug 1816928] Other tabs become unclickable Or unresponsive if you click on Replication tab under Monitoring tab (WORKED FOR ME) - [Bug 1816956] Removing an attribute uniqueness does not ask for confirmation - [Bug 1816958] Run Fixup Task for USN under Plugins tab either Cleanup Suffix Or Cleanup Backend option should be there not the both - [Bug 1817062] Created attribute uniqueness is not visible after page refresh - [Bug 1817098] Instance fails to start after creating attribute uniqueness because of a missing attribute - [Bug 1817396] Various display problems on 'Server Settings'/'Security' Tab - [Bug 1817415] The 'Security Settings' refresh button does not work - [Bug 1817526] Cannot change Bind DN name in agreement - [Bug 1817554] cockpit crashes when creating new sasl mapping - [Bug 1817580] Reindex button is greyed out in Reindex Suffix - [Bug 1817585] Changing the SASL mapping priority prevents to create mapping - [Bug 1817983] Directory Manager Password can only be change when user click on Storage Scheme option - [Bug 1818016] Directory Manager Password is changing before the change in password storage scheme - [Bug 1818020] Confirm password field under Server setting's Directory manager tab not doing field check - [Bug 1818027] Cockpit broken when saving new changelog directory - [Bug 1818823] Can create replication manager without password and then it can't be deleted relates: https://pagure.io/389-ds-base/issue/50994 Reviewed by: firstyear & spichugi(Thanks!!) Updates - Remove excessive/nested spinner toggling for many of the plugins - Updated specfile for cockpit-389-ds to require 389-ds-base - Fixed how attribute uniquness plugins are created and found, and made it more robust to handle enabled and disabled plugins --- diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in index 60bcee9..36fc3cd 100644 --- a/rpm/389-ds-base.spec.in +++ b/rpm/389-ds-base.spec.in @@ -313,7 +313,8 @@ This module contains tools and libraries for accessing, testing, %package -n cockpit-389-ds Summary: Cockpit UI Plugin for configuring and administering the 389 Directory Server BuildArch: noarch -Requires: cockpit >= 198 +Requires: cockpit +Requires: 389-ds-base Requires: python%{python3_pkgversion} Requires: python%{python3_pkgversion}-lib389 diff --git a/src/cockpit/389-console/src/ds.jsx b/src/cockpit/389-console/src/ds.jsx index f83ce55..b8be78e 100644 --- a/src/cockpit/389-console/src/ds.jsx +++ b/src/cockpit/389-console/src/ds.jsx @@ -61,7 +61,8 @@ const staticStates = { export class DSInstance extends React.Component { componentWillMount() { - this.checkPackageAndLoad(); + this.loadInstanceList(); + this.updateProgress(25); } constructor(props) { @@ -94,7 +95,6 @@ export class DSInstance extends React.Component { this.loadInstanceList = this.loadInstanceList.bind(this); this.loadBackups = this.loadBackups.bind(this); this.setServerId = this.setServerId.bind(this); - this.checkPackageAndLoad = this.checkPackageAndLoad.bind(this); this.updateProgress = this.updateProgress.bind(this); this.openCreateInstanceModal = this.openCreateInstanceModal.bind(this); this.closeCreateInstanceModal = this.closeCreateInstanceModal.bind(this); @@ -114,7 +114,7 @@ export class DSInstance extends React.Component { progressValue: prevState.progressValue + value }), () => { - if (this.state.progressValue >= 100) { + if (this.state.progressValue > 100) { this.setState(prevState => ({ pageLoadingState: { ...prevState.pageLoadingState, @@ -135,6 +135,7 @@ export class DSInstance extends React.Component { .done(status_data => { let status_json = JSON.parse(status_data); if (status_json.running) { + this.updateProgress(25); let cmd = [ "dsconf", "-j", @@ -148,17 +149,12 @@ export class DSInstance extends React.Component { cockpit .spawn(cmd, { superuser: true, err: "message" }) .done(_ => { + this.updateProgress(25); this.setState( { serverId: serverId }, () => { - this.setState(prevState => ({ - pageLoadingState: { - ...prevState.pageLoadingState, - state: "success" - } - })); this.loadBackups(); } ); @@ -174,7 +170,6 @@ export class DSInstance extends React.Component { } ); } - this.updateProgress(25); }) .fail(err => { let errMsg = JSON.parse(err); @@ -193,7 +188,6 @@ export class DSInstance extends React.Component { } ); }); - this.updateProgress(25); } else { this.setState( { @@ -229,25 +223,6 @@ export class DSInstance extends React.Component { }); } - checkPackageAndLoad() { - let cmd = ["rpm", "-q", "389-ds-base"]; - log_cmd("checkPackageAndLoad", "Check if 389-ds-base package is installed", cmd); - cockpit - .spawn(cmd, { superuser: true }) - .done(_ => { - this.updateProgress(25); - this.loadInstanceList(); - }) - .fail(_ => { - this.setState({ - pageLoadingState: { - state: "noPackage", - jsx: staticStates["noPackage"] - } - }); - }); - } - loadInstanceList(serverId, action) { if (serverId === undefined) { this.setState(prevState => ({ @@ -262,6 +237,7 @@ export class DSInstance extends React.Component { cockpit .spawn(cmd, { superuser: true }) .done(data => { + this.updateProgress(25); let myObject = JSON.parse(data); this.setState({ instList: myObject.insts, @@ -289,7 +265,6 @@ export class DSInstance extends React.Component { }); } } - this.updateProgress(25); }) .fail(_ => { this.setState({ @@ -308,6 +283,7 @@ export class DSInstance extends React.Component { const cmd = ["dsctl", "-j", this.state.serverId, "backups"]; log_cmd("loadBackupsDSInstance", "Load Backups", cmd); cockpit.spawn(cmd, { superuser: true, err: "message" }).done(content => { + this.updateProgress(25); const config = JSON.parse(content); let rows = []; for (let row of config.items) { diff --git a/src/cockpit/389-console/src/lib/database/databaseModal.jsx b/src/cockpit/389-console/src/lib/database/databaseModal.jsx index de0aed1..92fd79f 100644 --- a/src/cockpit/389-console/src/lib/database/databaseModal.jsx +++ b/src/cockpit/389-console/src/lib/database/databaseModal.jsx @@ -224,7 +224,7 @@ class ExportModal extends React.Component { spinner =
- Exporting database... (You can safely close this window) + Exporting database... (You can safely close this window)
; } @@ -313,7 +313,7 @@ class ImportModal extends React.Component { spinner =
- Importing LDIF file... (You can safely close this window) + Importing LDIF file... (You can safely close this window)
; } @@ -412,7 +412,7 @@ class ReindexModal extends React.Component {
Indexing {msg} ... -

(You can safely close this window)

+

(You can safely close this window)

diff --git a/src/cockpit/389-console/src/lib/database/suffix.jsx b/src/cockpit/389-console/src/lib/database/suffix.jsx index 5f3e19b..3558191 100644 --- a/src/cockpit/389-console/src/lib/database/suffix.jsx +++ b/src/cockpit/389-console/src/lib/database/suffix.jsx @@ -72,6 +72,7 @@ export class Suffix extends React.Component { exportSpinner: false, importSpinner: false, showConfirmLDIFImport: false, + importLDIFName: "", deleleLDIFName: "", modalChecked: false, modalSpinning: false, @@ -196,15 +197,16 @@ export class Suffix extends React.Component { }); } - importLDIF (ldif) { + importLDIF () { // Do import let import_cmd = [ "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", - "backend", "import", this.props.suffix, ldif, "--encrypted" + "backend", "import", this.props.suffix, this.state.importLDIFName, "--encrypted" ]; this.setState({ importSpinner: true, + showConfirmLDIFImport: false, }); log_cmd("doImport", "Do online import", import_cmd); @@ -375,6 +377,7 @@ export class Suffix extends React.Component { ); this.setState({ showReindexModal: false, + showReindexConfirm: false, }); }) .fail(err => { @@ -385,6 +388,7 @@ export class Suffix extends React.Component { ); this.setState({ showReindexModal: false, + showReindexConfirm: false, }); }); } @@ -947,7 +951,7 @@ export class Suffix extends React.Component { { let indexState; if (sort.attrs.vlvenabled[0] == "0") { - indexState = Disabled; + indexState = Disabled; } else { - indexState = Uses: {sort.attrs.vlvuses[0]}; + indexState = Uses: {sort.attrs.vlvuses[0]}; } return (

{sort.attrs.vlvsort[0]} ({indexState})

); }) diff --git a/src/cockpit/389-console/src/lib/monitor/replMonitor.jsx b/src/cockpit/389-console/src/lib/monitor/replMonitor.jsx index 482834b..f70c973 100644 --- a/src/cockpit/389-console/src/lib/monitor/replMonitor.jsx +++ b/src/cockpit/389-console/src/lib/monitor/replMonitor.jsx @@ -1348,8 +1348,8 @@ export class ReplMonitor extends React.Component { ; - let cleanNavTitle = 'CleanAllRUV Tasks (' + cleanTasks.length + ')'; - let abortNavTitle = 'Abort CleanAllRUV Tasks (' + abortTasks.length + ')'; + let cleanNavTitle = 'CleanAllRUV Tasks (' + cleanTasks.length + ')'; + let abortNavTitle = 'Abort CleanAllRUV Tasks (' + abortTasks.length + ')'; let taskContent =
; - let conflictNavTitle = 'Conflict Entries (' + conflictEntries.length + ')'; - let glueNavTitle = 'Glue Entries (' + glueEntries.length + ')'; + let conflictNavTitle = 'Conflict Entries (' + conflictEntries.length + ')'; + let glueNavTitle = 'Glue Entries (' + glueEntries.length + ')'; let conflictContent =
; let fullReportTitle = 'Sync Report'; - let replAgmtNavTitle = 'Agreements (' + replAgmts.length + ')'; - let winsyncNavTitle = 'Winsync (' + replWinsyncAgmts.length + ')'; - let tasksNavTitle = 'Tasks (' + (cleanTasks.length + abortTasks.length) + ')'; - let conflictsNavTitle = 'Conflicts (' + (conflictEntries.length + glueEntries.length) + ')'; + let replAgmtNavTitle = 'Agreements (' + replAgmts.length + ')'; + let winsyncNavTitle = 'Winsync (' + replWinsyncAgmts.length + ')'; + let tasksNavTitle = 'Tasks (' + (cleanTasks.length + abortTasks.length) + ')'; + let conflictsNavTitle = 'Conflicts (' + (conflictEntries.length + glueEntries.length) + ')'; return (
diff --git a/src/cockpit/389-console/src/lib/plugins/attributeUniqueness.jsx b/src/cockpit/389-console/src/lib/plugins/attributeUniqueness.jsx index e31532c..59e7525 100644 --- a/src/cockpit/389-console/src/lib/plugins/attributeUniqueness.jsx +++ b/src/cockpit/389-console/src/lib/plugins/attributeUniqueness.jsx @@ -16,6 +16,7 @@ import { } from "patternfly-react"; import { Typeahead } from "react-bootstrap-typeahead"; import { AttrUniqConfigTable } from "./pluginTables.jsx"; +import { DoubleConfirmModal } from "../notifications.jsx"; import PluginBasicConfig from "./pluginBasicConfig.jsx"; import PropTypes from "prop-types"; import { log_cmd } from "../tools.jsx"; @@ -37,6 +38,8 @@ class AttributeUniqueness extends React.Component { configRows: [], attributes: [], objectClasses: [], + modalChecked: false, + modalSpinning: false, configName: "", configEnabled: false, @@ -48,12 +51,13 @@ class AttributeUniqueness extends React.Component { newEntry: false, showConfigModal: false, - showConfirmDeleteConfig: false + showConfirmDelete: false }; this.handleSwitchChange = this.handleSwitchChange.bind(this); this.handleCheckboxChange = this.handleCheckboxChange.bind(this); this.handleFieldChange = this.handleFieldChange.bind(this); + this.handleTypeaheadChange = this.handleTypeaheadChange.bind(this); this.loadConfigs = this.loadConfigs.bind(this); this.showEditConfigModal = this.showEditConfigModal.bind(this); this.showAddConfigModal = this.showAddConfigModal.bind(this); @@ -62,6 +66,8 @@ class AttributeUniqueness extends React.Component { this.closeModal = this.closeModal.bind(this); this.openModal = this.openModal.bind(this); this.cmdOperation = this.cmdOperation.bind(this); + this.closeConfirmDelete = this.closeConfirmDelete.bind(this); + this.showConfirmDelete = this.showConfirmDelete.bind(this); this.deleteConfig = this.deleteConfig.bind(this); this.addConfig = this.addConfig.bind(this); this.editConfig = this.editConfig.bind(this); @@ -85,6 +91,18 @@ class AttributeUniqueness extends React.Component { }); } + handleTypeaheadChange(values) { + // When typaheads allow new values, an object is returned + // instead of string. Grab the "label" in this case + let new_values = []; + for (let val of values) { + new_values.push(val.label); + } + this.setState({ + subtrees: new_values + }); + } + loadConfigs() { this.setState({ firstLoad: false @@ -98,23 +116,20 @@ class AttributeUniqueness extends React.Component { "attr-uniq", "list" ]; - this.props.toggleLoadingHandler(); log_cmd("loadConfigs", "Get Attribute Uniqueness Plugin configs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) .done(content => { let myObject = JSON.parse(content); this.setState({ - configRows: myObject.items.map(item => JSON.parse(item).attrs) + configRows: myObject.items.map(item => item.attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { if (err != 0) { let errMsg = JSON.parse(err); console.log("loadConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } @@ -153,7 +168,6 @@ class AttributeUniqueness extends React.Component { name ]; - this.props.toggleLoadingHandler(); log_cmd("openModal", "Fetch the Attribute Uniqueness Plugin config entry", cmd); cockpit .spawn(cmd, { @@ -200,7 +214,6 @@ class AttributeUniqueness extends React.Component { } this.setState({ subtrees: configSubtreesList }); } - this.props.toggleLoadingHandler(); }) .fail(_ => { this.setState({ @@ -213,7 +226,6 @@ class AttributeUniqueness extends React.Component { topEntryOc: [], subtreeEnriesOc: [] }); - this.props.toggleLoadingHandler(); }); } } @@ -247,6 +259,15 @@ class AttributeUniqueness extends React.Component { acrossAllSubtrees ? "on" : "off" ]; + if (subtrees.length == 0 && subtreeEnriesOc.length == 0) { + // There me a subtree or entry OC sets + this.props.addNotification( + "error", + `There must be at least one Subtree or Subtree Entries OC set` + ); + return; + } + // Delete attributes if the user set an empty value to the field if (!(action == "add" && attrNames.length == 0)) { cmd = [...cmd, "--attr-name"]; @@ -320,13 +341,29 @@ class AttributeUniqueness extends React.Component { `Error during the config entry ${action} operation - ${errMsg.desc}` ); this.loadConfigs(); - this.closeModal(); this.props.toggleLoadingHandler(); }); } - deleteConfig(rowData) { - let configName = rowData.cn[0]; + showConfirmDelete (name) { + this.setState({ + showConfirmDelete: true, + modalChecked: false, + modalSpinning: false, + deleteName: name + }); + } + + closeConfirmDelete () { + this.setState({ + showConfirmDelete: false, + modalChecked: false, + modalSpinning: false, + deleteName: "" + }); + } + + deleteConfig() { let cmd = [ "dsconf", "-j", @@ -334,10 +371,13 @@ class AttributeUniqueness extends React.Component { "plugin", "attr-uniq", "delete", - configName + this.state.deleteName ]; - this.props.toggleLoadingHandler(); + this.setState({ + modalSpinning: true + }); + log_cmd("deleteConfig", "Delete the Attribute Uniqueness Plugin config entry", cmd); cockpit .spawn(cmd, { @@ -348,11 +388,11 @@ class AttributeUniqueness extends React.Component { console.info("deleteConfig", "Result", content); this.props.addNotification( "success", - `Config entry ${configName} was successfully deleted` + `Config entry ${this.state.deleteName} was successfully deleted` ); this.loadConfigs(); this.closeModal(); - this.props.toggleLoadingHandler(); + this.closeConfirmDelete(); }) .fail(err => { let errMsg = JSON.parse(err); @@ -361,8 +401,8 @@ class AttributeUniqueness extends React.Component { `Error during the config entry removal operation - ${errMsg.desc}` ); this.loadConfigs(); + this.closeConfirmDelete(); this.closeModal(); - this.props.toggleLoadingHandler(); }); } @@ -528,9 +568,7 @@ class AttributeUniqueness extends React.Component { allowNew multiple onChange={values => { - this.setState({ - subtrees: values - }); + this.handleTypeaheadChange(values); }} selected={subtrees} options={[""]} @@ -672,7 +710,7 @@ class AttributeUniqueness extends React.Component {
); } diff --git a/src/cockpit/389-console/src/lib/plugins/autoMembership.jsx b/src/cockpit/389-console/src/lib/plugins/autoMembership.jsx index ab0661c..ff4d9d4 100644 --- a/src/cockpit/389-console/src/lib/plugins/autoMembership.jsx +++ b/src/cockpit/389-console/src/lib/plugins/autoMembership.jsx @@ -99,7 +99,6 @@ class AutoMembership extends React.Component { "list", "definitions" ]; - this.props.toggleLoadingHandler(); log_cmd("loadDefinitions", "Get Auto Membership Plugin definitions", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -108,14 +107,12 @@ class AutoMembership extends React.Component { this.setState({ definitionRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadDefinitions failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } diff --git a/src/cockpit/389-console/src/lib/plugins/dna.jsx b/src/cockpit/389-console/src/lib/plugins/dna.jsx index f4b1e05..f083937 100644 --- a/src/cockpit/389-console/src/lib/plugins/dna.jsx +++ b/src/cockpit/389-console/src/lib/plugins/dna.jsx @@ -138,7 +138,6 @@ class DNA extends React.Component { "list", "configs" ]; - this.props.toggleLoadingHandler(); log_cmd("loadConfigs", "Get DNA Plugin configs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -147,14 +146,12 @@ class DNA extends React.Component { this.setState({ configRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } @@ -169,7 +166,6 @@ class DNA extends React.Component { "shared-configs", basedn ]; - this.props.toggleLoadingHandler(); log_cmd("loadSharedConfigs", "Get DNA Plugin shared configs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -178,14 +174,12 @@ class DNA extends React.Component { this.setState({ sharedConfigRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadSharedConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } diff --git a/src/cockpit/389-console/src/lib/plugins/linkedAttributes.jsx b/src/cockpit/389-console/src/lib/plugins/linkedAttributes.jsx index accd694..88bb399 100644 --- a/src/cockpit/389-console/src/lib/plugins/linkedAttributes.jsx +++ b/src/cockpit/389-console/src/lib/plugins/linkedAttributes.jsx @@ -77,7 +77,6 @@ class LinkedAttributes extends React.Component { "linked-attr", "list" ]; - this.props.toggleLoadingHandler(); log_cmd("loadConfigs", "Get Linked Attributes Plugin configs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -86,14 +85,12 @@ class LinkedAttributes extends React.Component { this.setState({ configRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } diff --git a/src/cockpit/389-console/src/lib/plugins/managedEntries.jsx b/src/cockpit/389-console/src/lib/plugins/managedEntries.jsx index 679e919..7afdd2c 100644 --- a/src/cockpit/389-console/src/lib/plugins/managedEntries.jsx +++ b/src/cockpit/389-console/src/lib/plugins/managedEntries.jsx @@ -93,7 +93,6 @@ class ManagedEntries extends React.Component { "list", "configs" ]; - this.props.toggleLoadingHandler(); log_cmd("loadConfigs", "Get Managed Entries Plugin configs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -102,14 +101,12 @@ class ManagedEntries extends React.Component { this.setState({ configRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } diff --git a/src/cockpit/389-console/src/lib/plugins/passthroughAuthentication.jsx b/src/cockpit/389-console/src/lib/plugins/passthroughAuthentication.jsx index 6b2d067..a7f3b98 100644 --- a/src/cockpit/389-console/src/lib/plugins/passthroughAuthentication.jsx +++ b/src/cockpit/389-console/src/lib/plugins/passthroughAuthentication.jsx @@ -118,7 +118,6 @@ class PassthroughAuthentication extends React.Component { "list", "pam-configs" ]; - this.props.toggleLoadingHandler(); log_cmd("loadPAMConfigs", "Get PAM Passthough Authentication Plugin pamConfigs", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) @@ -127,14 +126,12 @@ class PassthroughAuthentication extends React.Component { this.setState({ pamConfigRows: myObject.items.map(item => JSON.parse(item).attrs) }); - this.props.toggleLoadingHandler(); }) .fail(err => { let errMsg = JSON.parse(err); if (err != 0) { console.log("loadPAMConfigs failed", errMsg.desc); } - this.props.toggleLoadingHandler(); }); } diff --git a/src/cockpit/389-console/src/lib/plugins/pluginTables.jsx b/src/cockpit/389-console/src/lib/plugins/pluginTables.jsx index 49abfa1..ce9de8c 100644 --- a/src/cockpit/389-console/src/lib/plugins/pluginTables.jsx +++ b/src/cockpit/389-console/src/lib/plugins/pluginTables.jsx @@ -258,7 +258,7 @@ class AttrUniqConfigTable extends React.Component { { - this.props.deleteConfig(rowData); + this.props.deleteConfig(rowData.cn[0]); }} > Delete Config diff --git a/src/cockpit/389-console/src/lib/plugins/referentialIntegrity.jsx b/src/cockpit/389-console/src/lib/plugins/referentialIntegrity.jsx index 7419b84..e65cbcc 100644 --- a/src/cockpit/389-console/src/lib/plugins/referentialIntegrity.jsx +++ b/src/cockpit/389-console/src/lib/plugins/referentialIntegrity.jsx @@ -311,17 +311,17 @@ class ReferentialIntegrity extends React.Component { ? "" : pluginRow["referint-update-delay"][0], entryScope: - pluginRow["nsslapd-pluginEntryScope"] === undefined + pluginRow["nsslapd-pluginentryscope"] === undefined ? "" - : pluginRow["nsslapd-pluginEntryScope"][0], + : pluginRow["nsslapd-pluginentryscope"][0], excludeEntryScope: - pluginRow["nsslapd-pluginExcludeEntryScope"] === undefined + pluginRow["nsslapd-pluginexcludeentryscope"] === undefined ? "" - : pluginRow["nsslapd-pluginExcludeEntryScope"][0], + : pluginRow["nsslapd-pluginexcludeentryscope"][0], containerScope: - pluginRow["nsslapd-pluginContainerScope"] === undefined + pluginRow["nsslapd-plugincontainerscope"] === undefined ? "" - : pluginRow["nsslapd-pluginContainerScope"][0], + : pluginRow["nsslapd-plugincontainerscope"][0], referintConfigEntry: pluginRow["nsslapd-pluginConfigArea"] === undefined ? "" diff --git a/src/cockpit/389-console/src/lib/plugins/usn.jsx b/src/cockpit/389-console/src/lib/plugins/usn.jsx index a1080c6..6a3acad 100644 --- a/src/cockpit/389-console/src/lib/plugins/usn.jsx +++ b/src/cockpit/389-console/src/lib/plugins/usn.jsx @@ -22,6 +22,7 @@ class USN extends React.Component { componentWillMount() { if (this.props.wasActiveList.includes(5)) { if (this.state.firstLoad) { + this.loadSuffixList(); this.updateSwitch(); } } @@ -35,6 +36,7 @@ class USN extends React.Component { this.updateSwitch = this.updateSwitch.bind(this); this.handleSwitchChange = this.handleSwitchChange.bind(this); this.handleFieldChange = this.handleFieldChange.bind(this); + this.loadSuffixList = this.loadSuffixList.bind(this); this.state = { firstLoad: true, @@ -42,11 +44,28 @@ class USN extends React.Component { disableSwitch: false, cleanupModalShow: false, cleanupSuffix: "", - cleanupBackend: "", - cleanupMaxUSN: "" + cleanupMaxUSN: "", + suffixList: [], }; } + loadSuffixList () { + const cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", + "backend", "suffix", "list", "--suffix" + ]; + log_cmd("loadSuffixList", "Get a list of all the suffixes", cmd); + cockpit + .spawn(cmd, { superuser: true, err: "message" }) + .done(content => { + const suffixList = JSON.parse(content); + this.setState({ + suffixList: suffixList.items, + cleanupSuffix: suffixList.items[0] + }); + }); + } + handleFieldChange(e) { this.setState({ [e.target.id]: e.target.value @@ -135,15 +154,14 @@ class USN extends React.Component { toggleCleanupModal() { this.setState(prevState => ({ cleanupModalShow: !prevState.cleanupModalShow, - cleanupSuffix: "", - cleanupBackend: "", + cleanupSuffix: prevState.suffixList[0], cleanupMaxUSN: "" })); } runCleanup() { - if (!this.state.cleanupSuffix && !this.state.cleanupBackend) { - this.props.addNotification("warning", "Suffix or backend name is required."); + if (!this.state.cleanupSuffix) { + this.props.addNotification("warning", "Suffix is required."); } else { let cmd = [ "dsconf", @@ -157,9 +175,6 @@ class USN extends React.Component { if (this.state.cleanupSuffix) { cmd = [...cmd, "--suffix", this.state.cleanupSuffix]; } - if (this.state.cleanupBackend) { - cmd = [...cmd, "--backend", this.state.cleanupBackend]; - } if (this.state.cleanupMaxUSN) { cmd = [...cmd, "--max-usn", this.state.cleanupMaxUSN]; } @@ -201,10 +216,14 @@ class USN extends React.Component { disableSwitch, cleanupModalShow, cleanupSuffix, - cleanupBackend, - cleanupMaxUSN + cleanupMaxUSN, + suffixList } = this.state; + let suffixes = suffixList.map((name) => + + ); + return (
@@ -225,42 +244,27 @@ class USN extends React.Component {
- - + + Cleanup Suffix - - - - - - - - Cleanup Backend - - - - + + - + Cleanup Max USN - + diff --git a/src/cockpit/389-console/src/lib/replication/replAgmts.jsx b/src/cockpit/389-console/src/lib/replication/replAgmts.jsx index e3c4781..ec1beef 100644 --- a/src/cockpit/389-console/src/lib/replication/replAgmts.jsx +++ b/src/cockpit/389-console/src/lib/replication/replAgmts.jsx @@ -682,7 +682,7 @@ export class ReplAgmts extends React.Component { cmd.push('--bind-passwd=' + this.state.agmtBindPW); } if (this.state.agmtBindDN != this.state._agmtBindDN) { - cmd.push('--bind-passwd=' + this.state.agmtBindDN); + cmd.push('--bind-dn=' + this.state.agmtBindDN); } if (this.state.agmtFracAttrs != this.state._agmtFracAttrs) { cmd.push('--frac-list=' + this.state.agmtFracAttrs.join(' ')); diff --git a/src/cockpit/389-console/src/lib/replication/replChangelog.jsx b/src/cockpit/389-console/src/lib/replication/replChangelog.jsx index 1386393..b1c318e 100644 --- a/src/cockpit/389-console/src/lib/replication/replChangelog.jsx +++ b/src/cockpit/389-console/src/lib/replication/replChangelog.jsx @@ -151,7 +151,7 @@ export class Changelog extends React.Component { }); return; } - cmd.push("--cl-dir =" + this.state.clDir); + cmd.push("--cl-dir=" + this.state.clDir); } if (this.state.clMaxEntries != this.state._clMaxEntries) { cmd.push("--max-entries=" + this.state.clMaxEntries); diff --git a/src/cockpit/389-console/src/lib/replication/replModals.jsx b/src/cockpit/389-console/src/lib/replication/replModals.jsx index 0ea6f47..4c4fe88 100644 --- a/src/cockpit/389-console/src/lib/replication/replModals.jsx +++ b/src/cockpit/389-console/src/lib/replication/replModals.jsx @@ -1402,7 +1402,7 @@ export class ExportModal extends React.Component { spinner =
- Exporting database... (You can safely close this window) + Exporting database... (You can safely close this window)
; } diff --git a/src/cockpit/389-console/src/lib/replication/replSuffix.jsx b/src/cockpit/389-console/src/lib/replication/replSuffix.jsx index a83ca37..9cbd729 100644 --- a/src/cockpit/389-console/src/lib/replication/replSuffix.jsx +++ b/src/cockpit/389-console/src/lib/replication/replSuffix.jsx @@ -280,8 +280,8 @@ export class ReplSuffix extends React.Component { if (this.props.disabled) { suffixClass = "ds-margin-top-xlg ds-disabled"; } - let replAgmtNavTitle = 'Replication Agreements (' + this.props.agmtRows.length + ')'; - let winsyncNavTitle = 'Winsync Agreements (' + this.props.winsyncRows.length + ')'; + let replAgmtNavTitle = 'Replication Agreements (' + this.props.agmtRows.length + ')'; + let winsyncNavTitle = 'Winsync Agreements (' + this.props.winsyncRows.length + ')'; let enabledContent =
diff --git a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx index 296845c..813ed2f 100644 --- a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx +++ b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx @@ -162,7 +162,7 @@ class ObjectClassesTable extends React.Component { eventKey="2" className="ds-schema-dropdown" onClick={() => { - this.props.deleteHandler(rowData); + this.props.deleteHandler(rowData.name[0]); }} > Delete ObjectClass @@ -374,7 +374,7 @@ class AttributesTable extends React.Component { eventKey="2" className="ds-schema-dropdown" onClick={() => { - this.props.deleteHandler(rowData); + this.props.deleteHandler(rowData.name[0]); }} > Delete Attribute diff --git a/src/cockpit/389-console/src/lib/security/certificateManagement.jsx b/src/cockpit/389-console/src/lib/security/certificateManagement.jsx index 5bf091c..1635372 100644 --- a/src/cockpit/389-console/src/lib/security/certificateManagement.jsx +++ b/src/cockpit/389-console/src/lib/security/certificateManagement.jsx @@ -492,8 +492,8 @@ export class CertificateManagement extends React.Component { } render () { - let CATitle = 'Trusted Certificate Authorites (' + this.state.CACerts.length + ')'; - let ServerTitle = 'TLS Certificates (' + this.state.ServerCerts.length + ')'; + let CATitle = 'Trusted Certificate Authorites (' + this.state.CACerts.length + ')'; + let ServerTitle = 'TLS Certificates (' + this.state.ServerCerts.length + ')'; let certificatePage = ''; diff --git a/src/cockpit/389-console/src/lib/security/ciphers.jsx b/src/cockpit/389-console/src/lib/security/ciphers.jsx index d8af1d6..a4199eb 100644 --- a/src/cockpit/389-console/src/lib/security/ciphers.jsx +++ b/src/cockpit/389-console/src/lib/security/ciphers.jsx @@ -184,20 +184,21 @@ export class Ciphers extends React.Component { ); + let eCiphers = '

Enabled Ciphers (' + enabledList.length + ')

'; + let sCiphers = '

Other Available Ciphers (' + supportedList.length + ')

'; + if (this.state.saving) { cipherPage = -
+

Saving cipher preferences ...

; } else { cipherPage = -
+
-
-

Enabled Ciphers

-
+
@@ -222,7 +223,7 @@ export class Ciphers extends React.Component {

- + Cipher Suite @@ -238,7 +239,7 @@ export class Ciphers extends React.Component { - + Allow Specific Ciphers @@ -256,7 +257,7 @@ export class Ciphers extends React.Component { - + Deny Specific Ciphers @@ -286,7 +287,7 @@ export class Ciphers extends React.Component { } return ( -
+
{cipherPage}
); diff --git a/src/cockpit/389-console/src/lib/server/sasl.jsx b/src/cockpit/389-console/src/lib/server/sasl.jsx index e58a660..28cc330 100644 --- a/src/cockpit/389-console/src/lib/server/sasl.jsx +++ b/src/cockpit/389-console/src/lib/server/sasl.jsx @@ -123,6 +123,8 @@ export class ServerSASL extends React.Component { // Check if a setting was changed, if so enable the save button if (attr == 'mappingFallback' && this.state._mappingFallback != value) { disableSaveBtn = false; + } else if (attr == 'saslPriority' && this.state._saslPriority != value) { + disableSaveBtn = false; } else if (attr == 'maxBufSize' && this.state._maxBufSize != value) { disableSaveBtn = false; } else if (attr == 'allowedMechs' && this.state._allowedMechs.join(' ') != value.join(' ')) { @@ -139,6 +141,8 @@ export class ServerSASL extends React.Component { // Now check for differences in values that we did not touch if (attr != 'mappingFallback' && this.state._mappingFallback != this.state.mappingFallback) { disableSaveBtn = false; + } else if (attr != 'saslPriority' && this.state._saslPriority != this.state.saslPriority) { + disableSaveBtn = false; } else if (attr != 'maxBufSize' && this.state._maxBufSize != this.state.maxBufSize) { disableSaveBtn = false; } else if (attr != 'allowedMechs' && this.state._allowedMechs.join(' ') != this.state.allowedMechs.join(' ')) { @@ -173,6 +177,8 @@ export class ServerSASL extends React.Component { disableSaveBtn = false; } else if (attr == 'saslBase' && value != "") { disableSaveBtn = false; + } else if (attr == 'saslPriority' && value != "0") { + disableSaveBtn = false; } else if (attr == 'saslFilter' && value != "") { disableSaveBtn = false; } @@ -192,7 +198,7 @@ export class ServerSASL extends React.Component { } } - // Handle TEst Text filed and buttons + // Handle Test Text field and buttons if (attr == 'saslTestText' && value != "" && this.state.saslMapRegex != "") { disableRegexTestBtn = false; } diff --git a/src/cockpit/389-console/src/lib/server/settings.jsx b/src/cockpit/389-console/src/lib/server/settings.jsx index bb1ee6e..bc81310 100644 --- a/src/cockpit/389-console/src/lib/server/settings.jsx +++ b/src/cockpit/389-console/src/lib/server/settings.jsx @@ -33,8 +33,9 @@ const general_attrs = [ ]; const rootdn_attrs = [ - 'nsslapd-rootpw', 'nsslapd-rootpwstoragescheme', + 'nsslapd-rootpw', + 'confirmRootpw', ]; const disk_attrs = [ @@ -173,15 +174,15 @@ export class ServerSettings extends React.Component { // Handle validating passwords are in sync if (attr == 'nsslapd-rootpw') { - if (value != this.state._confirmRootpw) { + if (value != this.state.confirmRootpw) { disableSaveBtn = true; errObj['nsslapd-rootpw'] = true; } else { - errObj['nsslapdrootpw'] = false; + errObj['nsslapd-rootpw'] = false; } } if (attr == 'confirmRootpw') { - if (value != this.state['_nsslapd-rootpw']) { + if (value != this.state['nsslapd-rootpw']) { disableSaveBtn = true; errObj['confirmRootpw'] = true; } else { @@ -347,7 +348,7 @@ export class ServerSettings extends React.Component { 'nsslapd-certdir': attrs['nsslapd-certdir'][0], 'nsslapd-rootdn': attrs['nsslapd-rootdn'][0], 'nsslapd-rootpw': attrs['nsslapd-rootpw'][0], - confirmRootpw: attrs['nsslapd-rootpw'][0], + 'confirmRootpw': attrs['nsslapd-rootpw'][0], 'nsslapd-rootpwstoragescheme': attrs['nsslapd-rootpwstoragescheme'][0], 'nsslapd-anonlimitsdn': attrs['nsslapd-anonlimitsdn'][0], 'nsslapd-disk-monitoring-threshold': attrs['nsslapd-disk-monitoring-threshold'][0], @@ -376,7 +377,7 @@ export class ServerSettings extends React.Component { '_nsslapd-certdir': attrs['nsslapd-certdir'][0], '_nsslapd-rootdn': attrs['nsslapd-rootdn'][0], '_nsslapd-rootpw': attrs['nsslapd-rootpw'][0], - _confirmRootpw: attrs['nsslapd-rootpw'][0], + '_confirmRootpw': attrs['nsslapd-rootpw'][0], '_nsslapd-rootpwstoragescheme': attrs['nsslapd-rootpwstoragescheme'][0], '_nsslapd-anonlimitsdn': attrs['nsslapd-anonlimitsdn'][0], '_nsslapd-disk-monitoring-threshold': attrs['nsslapd-disk-monitoring-threshold'][0], @@ -404,7 +405,7 @@ export class ServerSettings extends React.Component { ]; for (let attr of rootdn_attrs) { - if (this.state['_' + attr] != this.state[attr]) { + if (attr != 'confirmRootpw' && this.state['_' + attr] != this.state[attr]) { cmd.push(attr + "=" + this.state[attr]); } } @@ -448,12 +449,12 @@ export class ServerSettings extends React.Component { rootDNReloading: false, 'nsslapd-rootdn': attrs['nsslapd-rootdn'][0], 'nsslapd-rootpw': attrs['nsslapd-rootpw'][0], - confirmRootpw: attrs['nsslapd-rootpw'][0], + 'confirmRootpw': attrs['nsslapd-rootpw'][0], 'nsslapd-rootpwstoragescheme': attrs['nsslapd-rootpwstoragescheme'][0], // Record original values '_nsslapd-rootdn': attrs['nsslapd-rootdn'][0], '_nsslapd-rootpw': attrs['nsslapd-rootpw'][0], - _confirmRootpw: attrs['nsslapd-rootpw'][0], + '_confirmRootpw': attrs['nsslapd-rootpw'][0], '_nsslapd-rootpwstoragescheme': attrs['nsslapd-rootpwstoragescheme'][0], rootDNSaveDisabled: true }) diff --git a/src/cockpit/389-console/src/lib/tools.jsx b/src/cockpit/389-console/src/lib/tools.jsx index 7617a78..ea51c73 100644 --- a/src/cockpit/389-console/src/lib/tools.jsx +++ b/src/cockpit/389-console/src/lib/tools.jsx @@ -31,7 +31,7 @@ export function searchFilter(searchFilterValue, columnsToSearch, rows) { export function log_cmd(js_func, desc, cmd_array) { if (console) { - let pw_args = ["--passwd", "--bind-pw"]; + let pw_args = ["--passwd", "--bind-pw", "--nsslapd-rootpw"]; let cmd_list = []; let converted_pw = false; diff --git a/src/cockpit/389-console/src/plugins.jsx b/src/cockpit/389-console/src/plugins.jsx index 53ef514..15e7cf6 100644 --- a/src/cockpit/389-console/src/plugins.jsx +++ b/src/cockpit/389-console/src/plugins.jsx @@ -94,7 +94,7 @@ export class Plugins extends React.Component { toggleLoading() { this.setState(prevState => ({ - loading: !prevState.loading + loading: !prevState.loading, })); } @@ -138,15 +138,6 @@ export class Plugins extends React.Component { } pluginList() { - if (this.state.firstLoad) { - this.setState(prevState => ({ - firstLoad: false, - pluginTabs: { - ...prevState.pluginTabs, - basicConfig: true - } - })); - } cmd = [ "dsconf", "-j", @@ -154,22 +145,33 @@ export class Plugins extends React.Component { "plugin", "list" ]; - this.toggleLoading(); + log_cmd("pluginList", "Get plugins for table rows", cmd); cockpit .spawn(cmd, { superuser: true, err: "message" }) .done(content => { var myObject = JSON.parse(content); - this.setState({ - rows: myObject.items - }, this.toggleLoading()); + if (this.state.firstLoad) { + this.setState(prevState => ({ + pluginTabs: { + ...prevState.pluginTabs, + basicConfig: true + }, + rows: myObject.items, + firstLoad: false, + })); + } else { + this.setState({ + rows: myObject.items + }); + } }) .fail(err => { - if (err != 0) { - let errMsg = JSON.parse(err); - console.log("pluginList failed: ", errMsg.desc); - } - this.toggleLoading(); + let errMsg = JSON.parse(err); + this.props.addNotification( + "error", + `${errMsg.desc} error during plugin loading` + ); }); } @@ -321,6 +323,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -335,6 +338,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -349,6 +353,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -363,6 +368,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -377,6 +383,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -404,6 +411,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -431,6 +439,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -445,6 +454,7 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) }, @@ -472,67 +482,75 @@ export class Plugins extends React.Component { addNotification={this.props.addNotification} toggleLoadingHandler={this.toggleLoading} wasActiveList={this.props.wasActiveList} + key={this.props.wasActiveList} /> ) } }; + return (
- - - - - - + +
); } diff --git a/src/cockpit/389-console/src/schema.jsx b/src/cockpit/389-console/src/schema.jsx index 0078e47..9c3ac5e 100644 --- a/src/cockpit/389-console/src/schema.jsx +++ b/src/cockpit/389-console/src/schema.jsx @@ -7,6 +7,7 @@ import { MatchingRulesTable } from "./lib/schema/schemaTables.jsx"; import { ObjectClassModal, AttributeTypeModal } from "./lib/schema/schemaModals.jsx"; +import { DoubleConfirmModal } from "./lib/notifications.jsx"; import { Nav, NavItem, @@ -50,6 +51,7 @@ export class Schema extends React.Component { attributes: [], objectclasses: [], matchingrules: [], + deleteName: "", ocModalViewOnly: false, ocName: "", @@ -97,20 +99,24 @@ export class Schema extends React.Component { this.showAddObjectclassModal = this.showAddObjectclassModal.bind(this); this.openObjectclassModal = this.openObjectclassModal.bind(this); this.closeObjectclassModal = this.closeObjectclassModal.bind(this); - this.deleteObjectclass = this.deleteObjectclass.bind(this); + this.doDeleteOC = this.doDeleteOC.bind(this); this.addObjectclass = this.addObjectclass.bind(this); this.editObjectclass = this.editObjectclass.bind(this); this.cmdOperationObjectclass = this.cmdOperationObjectclass.bind(this); + this.showConfirmOCDelete = this.showConfirmOCDelete.bind(this); + this.closeConfirmOCDelete = this.closeConfirmOCDelete.bind(this); this.showViewAttributeModal = this.showViewAttributeModal.bind(this); this.showEditAttributeModal = this.showEditAttributeModal.bind(this); this.showAddAttributeModal = this.showAddAttributeModal.bind(this); this.openAttributeModal = this.openAttributeModal.bind(this); this.closeAttributeModal = this.closeAttributeModal.bind(this); - this.deleteAttribute = this.deleteAttribute.bind(this); + this.doDeleteAttr = this.doDeleteAttr.bind(this); this.addAttribute = this.addAttribute.bind(this); this.editAttribute = this.editAttribute.bind(this); this.cmdOperationAttribute = this.cmdOperationAttribute.bind(this); + this.showConfirmAttrDelete = this.showConfirmAttrDelete.bind(this); + this.closeConfirmAttrDelete = this.closeConfirmAttrDelete.bind(this); } toggleLoading(item) { @@ -371,8 +377,25 @@ export class Schema extends React.Component { this.setState({ objectclassModalShow: false }); } - deleteObjectclass(rowData) { - let name = rowData.name[0]; + closeConfirmOCDelete () { + // call doDeleteOC + this.setState({ + showConfirmDeleteOC: false, + modalChecked: false, + modalSpinning: false, + }); + } + + showConfirmOCDelete(oc_name) { + this.setState({ + showConfirmDeleteOC: true, + modalChecked: false, + modalSpinning: false, + deleteName: oc_name + }); + } + + doDeleteOC() { let cmd = [ "dsconf", "-j", @@ -380,10 +403,13 @@ export class Schema extends React.Component { "schema", "objectclasses", "remove", - name + this.state.deleteName ]; - this.toggleLoading("ocTable"); + this.setState({ + modalSpinning: true, + }); + log_cmd("deleteObjectclass", "Delete ObjectClass from schema", cmd); cockpit .spawn(cmd, { @@ -392,9 +418,9 @@ export class Schema extends React.Component { }) .done(content => { console.info("deleteObjectclass", "Result", content); - this.props.addNotification("success", `ObjectClass ${name} was successfully deleted`); + this.props.addNotification("success", `ObjectClass ${this.state.deleteName} was successfully deleted`); this.loadSchemaData(); - this.toggleLoading("ocTable"); + this.closeConfirmOCDelete(); }) .fail(err => { let errMsg = JSON.parse(err); @@ -403,7 +429,7 @@ export class Schema extends React.Component { `Error during ObjectClass removal operation - ${errMsg.desc}` ); this.loadSchemaData(); - this.toggleLoading("ocTable"); + this.closeConfirmOCDelete(); }); } @@ -644,11 +670,29 @@ export class Schema extends React.Component { } closeAttributeModal() { - this.setState({ attributeModalShow: false }); + this.setState({ + attributeModalShow: false + }); + } + + closeConfirmAttrDelete () { + this.setState({ + showConfirmAttrDelete: false, + modalChecked: false, + modalSpinning: false, + }); + } + + showConfirmAttrDelete(attr_name) { + this.setState({ + showConfirmAttrDelete: true, + modalChecked: false, + modalSpinning: false, + deleteName: attr_name + }); } - deleteAttribute(rowData) { - let name = rowData.name[0]; + doDeleteAttr() { let cmd = [ "dsconf", "-j", @@ -656,10 +700,13 @@ export class Schema extends React.Component { "schema", "attributetypes", "remove", - name + this.state.deleteName ]; - this.toggleLoading("atTable"); + this.setState({ + modalSpinning: true, + }); + log_cmd("deleteAttribute", "Delete Attribute from schema", cmd); cockpit .spawn(cmd, { @@ -668,9 +715,9 @@ export class Schema extends React.Component { }) .done(content => { console.info("deleteAttribute", "Result", content); - this.props.addNotification("success", `Attribute ${name} was successfully deleted`); + this.props.addNotification("success", `Attribute ${this.state.deleteName} was successfully deleted`); this.loadSchemaData(); - this.toggleLoading("atTable"); + this.closeConfirmAttrDelete(); }) .fail(err => { let errMsg = JSON.parse(err); @@ -679,7 +726,7 @@ export class Schema extends React.Component { `Error during Attribute removal operation - ${errMsg.desc}` ); this.loadSchemaData(); - this.toggleLoading("atTable"); + this.closeConfirmAttrDelete(); }); } @@ -895,7 +942,7 @@ export class Schema extends React.Component { rows={this.state.filteredObjectclassRows} viewModalHandler={this.showViewObjectclassModal} editModalHandler={this.showEditObjectclassModal} - deleteHandler={this.deleteObjectclass} + deleteHandler={this.showConfirmOCDelete} loading={this.state.ocTableLoading} />
+ +
); } diff --git a/src/cockpit/389-console/src/security.jsx b/src/cockpit/389-console/src/security.jsx index 815f664..5d6d84f 100644 --- a/src/cockpit/389-console/src/security.jsx +++ b/src/cockpit/389-console/src/security.jsx @@ -84,6 +84,7 @@ export class Security extends React.Component { this.disableSecurity = this.disableSecurity.bind(this); this.saveSecurityConfig = this.saveSecurityConfig.bind(this); this.closeSecurityEnableModal = this.closeSecurityEnableModal.bind(this); + this.reloadConfig = this.reloadConfig.bind(this); } componentWillMount () { @@ -103,6 +104,12 @@ export class Security extends React.Component { } } + reloadConfig () { + this.setState({ + loaded: false + }, this.loadSecurityConfig); + } + loadSupportedCiphers () { const cmd = [ "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", @@ -482,7 +489,7 @@ export class Security extends React.Component { if (sslMin > sslMax) { this.props.addNotification( "error", - `The TLS minimum version but be less than or equal to the TLS maximum version` + `The TLS minimum version must be less than or equal to the TLS maximum version` ); // Reset page this.loadSecurityConfig(); @@ -620,7 +627,7 @@ export class Security extends React.Component { Secure Listen Host - + Server Certificate Name - + Minimum TLS Version - +