#50837 Issue 50836 - Port Schema UI tab to React
Closed 3 years ago by spichugi. Opened 4 years ago by spichugi.
spichugi/389-ds-base schema_webui  into  master

@@ -1021,6 +1021,11 @@ 

      width: 120px;

  }

  

+ .ds-schema-dropdown {

+     border-color: #06c !important;

+     color: #06c !important;

+ }

+ 

  .treeview .list-group-item {

      /* remove focus border */

      outline: none;

@@ -12,7 +12,7 @@ 

  var db_page_loaded = 1;

  var repl_page_loaded = 1;

  var plugin_page_loaded = 1;

- var schema_page_loaded = 0;

+ var schema_page_loaded = 1;

  var monitor_page_loaded = 1;

  var config_loaded = 0;

  
@@ -412,10 +412,6 @@ 

      get_and_set_localpwp();

      update_progress();

  

-     // Schema page

-     get_and_set_schema_tables();

-     update_progress();

- 

      // Initialize the tabs

      $(".ds-tab-list").css( 'color', '#777');

      $("#server-tab").css( 'color', '#228bc0');
@@ -472,6 +468,10 @@ 

      $(".all-pages").hide();

      $("#security-content").show();

    });

+   $("#schema-tab").on("click", function() {

+     $(".all-pages").hide();

+     $("#schema-content").show();

+   });

    $("#replication-tab").on("click", function() {

      $(".all-pages").hide();

      $("#replication-content").show();

@@ -3,6 +3,7 @@ 

  import { Plugins } from "./plugins.jsx";

  import { Database } from "./database.jsx";

  import { Monitor } from "./monitor.jsx";

+ import { Schema } from "./schema.jsx";

  import { Security } from "./security.jsx";

  import { Replication } from "./replication.jsx";

  
@@ -49,6 +50,12 @@ 

          <Security serverId={serverIdElem} key={tabKey} />,

          document.getElementById("security")

      );

+ 

+     // Schema tab

+     ReactDOM.render(

+         <Schema serverId={serverIdElem} key={tabKey} />,

+         document.getElementById("schema")

+     );

  }

  

  // We have to create the wrappers because this is no simple way

@@ -18,7 +18,6 @@ 

    <script src="static/c3.min.js"></script>

    <script src="static/d3.min.js"></script>

    <script src="ds.js"></script>

-   <script src="schema.js"></script>

    <script src="servers.js"></script>

    <link href="static/bootstrap.min.css" rel="stylesheet">

    <link href="static/jquery.dataTables.min.css" type="text/css" rel="stylesheet">
@@ -109,15 +108,9 @@ 

  

              <!-- Schema navtab -->

              <li class="dropdown ds-nav-tab">

-               <a href="#0" class="ds-tab-list" data-toggle="dropdown" id="schema-tab">

+               <a href="#0" class="ds-tab-list ds-tab-standalone" id="schema-tab">

                  Schema

-                 <b class="caret"></b>

                </a>

-               <ul class="dropdown-menu ds-nav-item">

-                 <li><a href="#0"class="ds-nav-choice" id="objectclass-btn" parent-id="schema-tab">Objectclasses</a></li>

-                 <li><a href="#0"class="ds-nav-choice" id="attribute-btn" parent-id="schema-tab">Attributes</a></li>

-                 <li><a href="#0" class="ds-nav-choice" id="schema-mr-btn" parent-id="schema-tab">Matching Rules</a></li>

-               </ul>

              </li>

  

              <!-- Plugins navtab -->
@@ -514,6 +507,7 @@ 

        </div>

  

        <div id="schema-content" class="all-pages" hidden>

+           <div id="schema"></div>

        </div>

  

        <div id="plugin-content" class="all-pages" hidden>

@@ -0,0 +1,660 @@ 

+ import React from "react";

+ import {

+     Row,

+     Spinner,

+     Modal,

+     Icon,

+     Button,

+     Checkbox,

+     noop,

+     Form,

+     FormControl,

+     FormGroup,

+     ControlLabel,

+     Col

+ } from "patternfly-react";

+ import { Typeahead } from "react-bootstrap-typeahead";

+ import PropTypes from "prop-types";

+ import "../../css/ds.css";

+ 

+ class ObjectClassModal extends React.Component {

+     render() {

+         const {

+             newOcEntry,

+             ocModalViewOnly,

+             addHandler,

+             editHandler,

+             handleTypeaheadChange,

+             handleFieldChange,

+             objectclasses,

+             attributes,

+             ocName,

+             ocDesc,

+             ocOID,

+             ocParent,

+             ocKind,

+             ocMust,

+             ocMay,

+             objectclassModalShow,

+             closeModal,

+             loading

+         } = this.props;

+         let spinner = "";

+         if (loading) {

+             spinner = (

+                 <Row>

+                     <div className="ds-margin-top-lg ds-modal-spinner">

+                         <Spinner loading inline size="lg" />

+                         Saving objectClass...

+                     </div>

+                 </Row>

+             );

+         }

+ 

+         return (

+             <div>

+                 <Modal show={objectclassModalShow} onHide={closeModal}>

+                     <div className="ds-no-horizontal-scrollbar">

+                         <Modal.Header>

+                             <button

+                                 className="close"

+                                 onClick={closeModal}

+                                 aria-hidden="true"

+                                 aria-label="Close"

+                             >

+                                 <Icon type="pf" name="close" />

+                             </button>

+                             <Modal.Title>

+                                 {ocModalViewOnly ? (

+                                     `View ObjectClass - ${ocName}`

+                                 ) : (

+                                     <div>

+                                         {newOcEntry ? "Add" : "Edit"} ObjectClass

+                                         {ocName != "" ? ` - ${ocName}` : ""}{" "}

+                                     </div>

+                                 )}

+                             </Modal.Title>

+                         </Modal.Header>

+                         <Modal.Body>

+                             <Form horizontal>

+                                 <FormGroup controlId="ocName">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Name of the objectClass">

+                                             Objectclass Name

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             id="ocName"

+                                             type="text"

+                                             value={ocName}

+                                             onChange={handleFieldChange}

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup controlId="ocDesc">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Describes what is the objectClass's purpose">

+                                             Description

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             type="text"

+                                             value={ocDesc}

+                                             onChange={handleFieldChange}

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup controlId="ocOID">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Object identifier">

+                                             OID (optional)

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             type="text"

+                                             value={ocOID}

+                                             onChange={handleFieldChange}

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="ocParent" controlId="ocParent" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An objectClass's parent">

+                                             Parent Objectclass

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             allowNew

+                                             onChange={values => {

+                                                 handleTypeaheadChange("ocParent", values);

+                                             }}

+                                             selected={ocParent}

+                                             newSelectionPrefix="Add a parent: "

+                                             options={objectclasses}

+                                             placeholder="Type a parent objectClass..."

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="ocKind" controlId="ocKind" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An objectClass kind">

+                                             Objectclass Kind

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <select

+                                             id="ocKind"

+                                             className="btn btn-default dropdown"

+                                             onChange={handleFieldChange}

+                                             value={ocKind}

+                                             disabled={ocModalViewOnly}

+                                         >

+                                             <option>STRUCTURAL</option>

+                                             <option>ABSTRACT</option>

+                                             <option>AUXILIARY</option>

+                                         </select>

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="ocMust" controlId="ocMust" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="A must attribute name">

+                                             Required Attributes

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             allowNew

+                                             multiple

+                                             onChange={values => {

+                                                 handleTypeaheadChange("ocMust", values);

+                                             }}

+                                             selected={ocMust}

+                                             newSelectionPrefix="Add a required attribute: "

+                                             options={attributes}

+                                             placeholder="Type an attribute name..."

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="ocMay" controlId="ocMay" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="A may attribute name">

+                                             Allowed Attributes

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             allowNew

+                                             multiple

+                                             onChange={values => {

+                                                 handleTypeaheadChange("ocMay", values);

+                                             }}

+                                             selected={ocMay}

+                                             newSelectionPrefix="Add an allowed attribute: "

+                                             options={attributes}

+                                             placeholder="Type an attribute name..."

+                                             disabled={ocModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                             </Form>

+                             {spinner}

+                         </Modal.Body>

+                         <Modal.Footer>

+                             {ocModalViewOnly ? (

+                                 <Button

+                                     bsStyle="default"

+                                     className="btn-cancel"

+                                     onClick={closeModal}

+                                 >

+                                     Close

+                                 </Button>

+                             ) : (

+                                 <div>

+                                     <Button

+                                         bsStyle="default"

+                                         className="btn-cancel"

+                                         onClick={closeModal}

+                                     >

+                                         Cancel

+                                     </Button>

+                                     <Button

+                                         bsStyle="primary"

+                                         onClick={newOcEntry ? addHandler : editHandler}

+                                     >

+                                         {newOcEntry ? "Add" : "Save"}

+                                     </Button>

+                                 </div>

+                             )}

+                         </Modal.Footer>

+                     </div>

+                 </Modal>

+             </div>

+         );

+     }

+ }

+ 

+ ObjectClassModal.propTypes = {

+     addHandler: PropTypes.func,

+     editHandler: PropTypes.func,

+     newOcEntry: PropTypes.bool,

+     ocModalViewOnly: PropTypes.bool,

+     handleTypeaheadChange: PropTypes.func,

+     handleFieldChange: PropTypes.func,

+     objectclasses: PropTypes.array,

+     attributes: PropTypes.array,

+     ocName: PropTypes.string,

+     ocDesc: PropTypes.string,

+     ocOID: PropTypes.string,

+     ocParent: PropTypes.array,

+     ocKind: PropTypes.string,

+     ocMust: PropTypes.array,

+     ocMay: PropTypes.array,

+     objectclassModalShow: PropTypes.bool,

+     closeModal: PropTypes.func,

+     loading: PropTypes.bool

+ };

+ 

+ ObjectClassModal.defaultProps = {

+     addHandler: noop,

+     editHandler: noop,

+     newOcEntry: true,

+     ocModalViewOnly: false,

+     handleTypeaheadChange: noop,

+     handleFieldChange: noop,

+     objectclasses: [],

+     attributes: [],

+     ocName: "",

+     ocDesc: "",

+     ocOID: "",

+     ocParent: [],

+     ocKind: "",

+     ocMust: [],

+     ocMay: [],

+     objectclassModalShow: false,

+     closeModal: noop,

+     loading: false

+ };

+ 

+ class AttributeTypeModal extends React.Component {

+     render() {

+         const {

+             atName,

+             atDesc,

+             atOID,

+             atParent,

+             atSyntax,

+             atUsage,

+             atMultivalued,

+             atNoUserMod,

+             atAlias,

+             atEqMr,

+             atOrder,

+             atSubMr,

+             atModalViewOnly,

+             attributeModalShow,

+             newAtEntry,

+             addHandler,

+             editHandler,

+             handleTypeaheadChange,

+             handleFieldChange,

+             attributes,

+             syntaxes,

+             matchingrules,

+             closeModal,

+             loading

+         } = this.props;

+         let spinner = "";

+         if (loading) {

+             spinner = (

+                 <Row>

+                     <div className="ds-margin-top-lg ds-modal-spinner">

+                         <Spinner loading inline size="lg" />

+                         Saving attribute...

+                     </div>

+                 </Row>

+             );

+         }

+ 

+         return (

+             <div>

+                 <Modal show={attributeModalShow} onHide={closeModal}>

+                     <div className="ds-no-horizontal-scrollbar">

+                         <Modal.Header>

+                             <button

+                                 className="close"

+                                 onClick={closeModal}

+                                 aria-hidden="true"

+                                 aria-label="Close"

+                             >

+                                 <Icon type="pf" name="close" />

+                             </button>

+                             <Modal.Title>

+                                 {atModalViewOnly ? (

+                                     `View Attribute - ${atName}`

+                                 ) : (

+                                     <div>

+                                         {newAtEntry ? "Add" : "Edit"} Attribute

+                                         {atName != "" ? ` - ${atName}` : ""}{" "}

+                                     </div>

+                                 )}

+                             </Modal.Title>

+                         </Modal.Header>

+                         <Modal.Body>

+                             <Form horizontal>

+                                 <FormGroup controlId="atName">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Name of the attribute">

+                                             Attribute Name

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             id="atName"

+                                             type="text"

+                                             value={atName}

+                                             onChange={handleFieldChange}

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup controlId="atDesc">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Describes what is the attribute's purpose">

+                                             Description

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             type="text"

+                                             value={atDesc}

+                                             onChange={handleFieldChange}

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup controlId="atOID">

+                                     <Col sm={4}>

+                                         <ControlLabel title="Object identifier">

+                                             OID (optional)

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <FormControl

+                                             type="text"

+                                             value={atOID}

+                                             onChange={handleFieldChange}

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atParent" controlId="atParent" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An attribute's parent">

+                                             Parent Attribute

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             allowNew

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atParent", values);

+                                             }}

+                                             selected={atParent}

+                                             newSelectionPrefix="Add a parent: "

+                                             options={attributes}

+                                             placeholder="Type a parent attribute..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atSyntax" controlId="atSyntax" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An attribute's syntax">

+                                             Syntax Name

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atSyntax", values);

+                                             }}

+                                             selected={atSyntax}

+                                             newSelectionPrefix="Add a syntax: "

+                                             options={syntaxes}

+                                             placeholder="Type a syntax name..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atUsage" controlId="atUsage" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An attribute usage purpose">

+                                             Attribute Usage

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <select

+                                             id="atUsage"

+                                             className="btn btn-default dropdown"

+                                             onChange={handleFieldChange}

+                                             value={atUsage}

+                                             disabled={atModalViewOnly}

+                                         >

+                                             <option>userApplications</option>

+                                             <option>directoryOperation</option>

+                                             <option>distributedOperation</option>

+                                             <option>dSAOperation</option>

+                                         </select>

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atMultivalued" controlId="atMultivalued">

+                                     <Col sm={4}>

+                                         <ControlLabel title="If attribute can have a multiple values">

+                                             Multivalued Attribute

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Checkbox

+                                             id="atMultivalued"

+                                             checked={atMultivalued}

+                                             title="If attribute can have a multiple values"

+                                             onChange={handleFieldChange}

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atNoUserMod" controlId="atNoUserMod">

+                                     <Col sm={4}>

+                                         <ControlLabel title="If attribute is not modifiable by a client application">

+                                             Not Modifiable By A User

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Checkbox

+                                             id="atNoUserMod"

+                                             checked={atNoUserMod}

+                                             title="If attribute is not modifiable by a client application"

+                                             onChange={handleFieldChange}

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atAlias" controlId="atAlias" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An alias name for the attribute">

+                                             Alias Names

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             allowNew

+                                             multiple

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atAlias", values);

+                                             }}

+                                             selected={atAlias}

+                                             options={[]}

+                                             newSelectionPrefix="Add an alias: "

+                                             placeholder="Type an alias name..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atEqMr" controlId="atEqMr" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An equality matching rule">

+                                             Equality Matching Rule

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atEqMr", values);

+                                             }}

+                                             selected={atEqMr}

+                                             newSelectionPrefix="Add an matching rule: "

+                                             options={matchingrules}

+                                             placeholder="Type an matching rule..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atOrder" controlId="atOrder" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="An order matching rule">

+                                             Order Matching Rule

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atOrder", values);

+                                             }}

+                                             selected={atOrder}

+                                             newSelectionPrefix="Add an matching rule: "

+                                             options={matchingrules}

+                                             placeholder="Type an matching rule..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                                 <FormGroup key="atSubMr" controlId="atSubMr" disabled={false}>

+                                     <Col sm={4}>

+                                         <ControlLabel title="A substring matching rule">

+                                             Substring Matching Rule

+                                         </ControlLabel>

+                                     </Col>

+                                     <Col sm={8}>

+                                         <Typeahead

+                                             onChange={values => {

+                                                 handleTypeaheadChange("atSubMr", values);

+                                             }}

+                                             selected={atSubMr}

+                                             newSelectionPrefix="Add an matching rule: "

+                                             options={matchingrules}

+                                             placeholder="Type an matching rule..."

+                                             disabled={atModalViewOnly}

+                                         />

+                                     </Col>

+                                 </FormGroup>

+                             </Form>

+                             {spinner}

+                         </Modal.Body>

+                         <Modal.Footer>

+                             {atModalViewOnly ? (

+                                 <Button

+                                     bsStyle="default"

+                                     className="btn-cancel"

+                                     onClick={closeModal}

+                                 >

+                                     Close

+                                 </Button>

+                             ) : (

+                                 <div>

+                                     <Button

+                                         bsStyle="default"

+                                         className="btn-cancel"

+                                         onClick={closeModal}

+                                     >

+                                         Cancel

+                                     </Button>

+                                     <Button

+                                         bsStyle="primary"

+                                         onClick={newAtEntry ? addHandler : editHandler}

+                                     >

+                                         {newAtEntry ? "Add" : "Save"}

+                                     </Button>

+                                 </div>

+                             )}

+                         </Modal.Footer>

+                     </div>

+                 </Modal>

+             </div>

+         );

+     }

+ }

+ 

+ AttributeTypeModal.propTypes = {

+     addHandler: PropTypes.func,

+     editHandler: PropTypes.func,

+     handleTypeaheadChange: PropTypes.func,

+     handleFieldChange: PropTypes.func,

+     attributes: PropTypes.array,

+     matchingrules: PropTypes.array,

+     syntaxes: PropTypes.array,

+     atName: PropTypes.string,

+     atDesc: PropTypes.string,

+     atOID: PropTypes.string,

+     atParent: PropTypes.array,

+     atSyntax: PropTypes.array,

+     atUsage: PropTypes.string,

+     atMultivalued: PropTypes.bool,

+     atNoUserMod: PropTypes.bool,

+     atAlias: PropTypes.array,

+     atEqMr: PropTypes.array,

+     atOrder: PropTypes.array,

+     atSubMr: PropTypes.array,

+     atModalViewOnly: PropTypes.bool,

+     attributeModalShow: PropTypes.bool,

+     newAtEntry: PropTypes.bool,

+     closeModal: PropTypes.func,

+     loading: PropTypes.bool

+ };

+ 

+ AttributeTypeModal.defaultProps = {

+     addHandler: noop,

+     editHandler: noop,

+     handleTypeaheadChange: noop,

+     handleFieldChange: noop,

+     attributes: [],

+     matchingrules: [],

+     syntaxes: [],

+     atName: "",

+     atDesc: "",

+     atOID: "",

+     atParent: [],

+     atSyntax: [],

+     atUsage: "userApplications",

+     atMultivalued: false,

+     atNoUserMod: false,

+     atAlias: [],

+     atEqMr: [],

+     atOrder: [],

+     atSubMr: [],

+     atModalViewOnly: false,

+     attributeModalShow: false,

+     newAtEntry: true,

+     closeModal: noop,

+     loading: false

+ };

+ 

+ export { ObjectClassModal, AttributeTypeModal };

@@ -0,0 +1,558 @@ 

+ import React from "react";

+ import {

+     Button,

+     DropdownButton,

+     MenuItem,

+     actionHeaderCellFormatter,

+     sortableHeaderCellFormatter,

+     tableCellFormatter,

+     noop

+ } from "patternfly-react";

+ import { DSTable } from "../dsTable.jsx";

+ import PropTypes from "prop-types";

+ import "../../css/ds.css";

+ 

+ class ObjectClassesTable extends React.Component {

+     constructor(props) {

+         super(props);

+ 

+         this.state = {

+             searchFilterValue: "",

+             fieldsToSearch: ["name", "oid"],

+             columns: [

+                 {

+                     property: "name",

+                     header: {

+                         label: "ObjectClass Name",

+                         props: {

+                             index: 0,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 0

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "oid",

+                     header: {

+                         label: "OID",

+                         props: {

+                             index: 1,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 1

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "must",

+                     header: {

+                         label: "Required Attributes",

+                         props: {

+                             index: 2,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 2

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [<td key={rowData.name[0]}>{value.join(" ")}</td>];

+                             }

+                         ]

+                     }

+                 },

+                 {

+                     property: "may",

+                     header: {

+                         label: "Allowed Attributes",

+                         props: {

+                             index: 3,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 3

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [<td key={rowData.name[0]}>{value.join(" ")}</td>];

+                             }

+                         ]

+                     }

+                 },

+                 {

+                     property: "actions",

+                     header: {

+                         label: "Actions",

+                         props: {

+                             index: 4,

+                             rowSpan: 1,

+                             colSpan: 1

+                         },

+                         formatters: [actionHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 4

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [

+                                     <td key={rowData.name[0]}>

+                                         {rowData.x_origin === null ||

+                                         rowData.x_origin === undefined ||

+                                         rowData.x_origin[0].toLowerCase() != "user defined" ? (

+                                             <Button

+                                                 onClick={() => {

+                                                     this.props.viewModalHandler(rowData);

+                                                 }}

+                                             >

+                                                 View Objectclass

+                                             </Button>

+                                         ) : (

+                                             <DropdownButton

+                                                 id={rowData.name[0]}

+                                                 bsStyle="default"

+                                                 title="Choose Action..."

+                                                 className="ds-schema-dropdown"

+                                             >

+                                                 <MenuItem

+                                                     eventKey="1"

+                                                     className="ds-schema-dropdown"

+                                                     onClick={() => {

+                                                         this.props.editModalHandler(rowData);

+                                                     }}

+                                                 >

+                                                     Edit ObjectClass

+                                                 </MenuItem>

+                                                 <MenuItem divider />

+                                                 <MenuItem

+                                                     eventKey="2"

+                                                     className="ds-schema-dropdown"

+                                                     onClick={() => {

+                                                         this.props.deleteHandler(rowData);

+                                                     }}

+                                                 >

+                                                     Delete ObjectClass

+                                                 </MenuItem>

+                                             </DropdownButton>

+                                         )}

+                                     </td>

+                                 ];

+                             }

+                         ]

+                     }

+                 }

+             ]

+         };

+         this.getColumns = this.getColumns.bind(this);

+     }

+ 

+     getColumns() {

+         return this.state.columns;

+     }

+ 

+     render() {

+         return (

+             <div>

+                 <DSTable

+                     getColumns={this.getColumns}

+                     fieldsToSearch={this.state.fieldsToSearch}

+                     rowKey="name"

+                     rows={this.props.rows}

+                     toolBarSearchField="ObjectClasses"

+                     toolBarLoading={this.props.loading}

+                 />

+             </div>

+         );

+     }

+ }

+ 

+ ObjectClassesTable.propTypes = {

+     rows: PropTypes.array,

+     editModalHandler: PropTypes.func,

+     deleteHandler: PropTypes.func,

+     viewModalHandler: PropTypes.func,

+     loading: PropTypes.bool

+ };

+ 

+ ObjectClassesTable.defaultProps = {

+     rows: [],

+     editModalHandler: noop,

+     deleteHandler: noop,

+     viewModalHandler: noop,

+     loading: false

+ };

+ 

+ class AttributesTable extends React.Component {

+     constructor(props) {

+         super(props);

+ 

+         this.state = {

+             searchFilterValue: "",

+             fieldsToSearch: ["name", "oid"],

+             columns: [

+                 {

+                     property: "name",

+                     header: {

+                         label: "Attribute Name",

+                         props: {

+                             index: 0,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 0

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "oid",

+                     header: {

+                         label: "OID",

+                         props: {

+                             index: 1,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 1

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "syntax",

+                     header: {

+                         label: "Syntax",

+                         props: {

+                             index: 2,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 2

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [

+                                     <td key={rowData.name[0]}>

+                                         {

+                                             this.props.syntaxes.filter(

+                                                 attr => attr.id === value[0]

+                                             )[0]["label"]

+                                         }

+                                     </td>

+                                 ];

+                             }

+                         ]

+                     }

+                 },

+                 {

+                     property: "multivalued",

+                     header: {

+                         label: "Multivalued",

+                         props: {

+                             index: 3,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 3

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [<td key={rowData.name[0]}>{value ? "yes" : "no"}</td>];

+                             }

+                         ]

+                     }

+                 },

+                 {

+                     property: "actions",

+                     header: {

+                         label: "Actions",

+                         props: {

+                             index: 4,

+                             rowSpan: 1,

+                             colSpan: 1

+                         },

+                         formatters: [actionHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 4

+                         },

+                         formatters: [

+                             (value, { rowData }) => {

+                                 return [

+                                     <td key={rowData.name[0]}>

+                                         {rowData.x_origin === null ||

+                                         rowData.x_origin === undefined ||

+                                         rowData.x_origin[0].toLowerCase() != "user defined" ? (

+                                             <Button

+                                                 onClick={() => {

+                                                     this.props.viewModalHandler(rowData);

+                                                 }}

+                                             >

+                                                 View Attribute

+                                             </Button>

+                                         ) : (

+                                             <DropdownButton

+                                                 id={rowData.name[0]}

+                                                 bsStyle="default"

+                                                 title="Choose Action..."

+                                                 className="ds-schema-dropdown"

+                                             >

+                                                 <MenuItem

+                                                     eventKey="1"

+                                                     className="ds-schema-dropdown"

+                                                     onClick={() => {

+                                                         this.props.editModalHandler(rowData);

+                                                     }}

+                                                 >

+                                                     Edit Attribute

+                                                 </MenuItem>

+                                                 <MenuItem divider />

+                                                 <MenuItem

+                                                     eventKey="2"

+                                                     className="ds-schema-dropdown"

+                                                     onClick={() => {

+                                                         this.props.deleteHandler(rowData);

+                                                     }}

+                                                 >

+                                                     Delete Attribute

+                                                 </MenuItem>

+                                             </DropdownButton>

+                                         )}

+                                     </td>

+                                 ];

+                             }

+                         ]

+                     }

+                 }

+             ]

+         };

+         this.getColumns = this.getColumns.bind(this);

+     }

+ 

+     getColumns() {

+         return this.state.columns;

+     }

+ 

+     render() {

+         return (

+             <div>

+                 <DSTable

+                     getColumns={this.getColumns}

+                     fieldsToSearch={this.state.fieldsToSearch}

+                     rowKey="name"

+                     rows={this.props.rows}

+                     toolBarSearchField="Attributes"

+                     toolBarLoading={this.props.loading}

+                 />

+             </div>

+         );

+     }

+ }

+ 

+ AttributesTable.propTypes = {

+     rows: PropTypes.array,

+     editModalHandler: PropTypes.func,

+     deleteHandler: PropTypes.func,

+     viewModalHandler: PropTypes.func,

+     syntaxes: PropTypes.array,

+     loading: PropTypes.bool

+ };

+ 

+ AttributesTable.defaultProps = {

+     rows: [],

+     editModalHandler: noop,

+     deleteHandler: noop,

+     viewModalHandler: noop,

+     syntaxes: [],

+     loading: false

+ };

+ 

+ class MatchingRulesTable extends React.Component {

+     constructor(props) {

+         super(props);

+ 

+         this.state = {

+             searchFilterValue: "",

+             fieldsToSearch: ["name", "oid"],

+             columns: [

+                 {

+                     property: "name",

+                     header: {

+                         label: "Matching Rule Name",

+                         props: {

+                             index: 0,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 0

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "oid",

+                     header: {

+                         label: "OID",

+                         props: {

+                             index: 1,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 1

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "syntax",

+                     header: {

+                         label: "Syntax",

+                         props: {

+                             index: 2,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 2

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 },

+                 {

+                     property: "desc",

+                     header: {

+                         label: "Description",

+                         props: {

+                             index: 3,

+                             rowSpan: 1,

+                             colSpan: 1,

+                             sort: true

+                         },

+                         transforms: [],

+                         formatters: [],

+                         customFormatters: [sortableHeaderCellFormatter]

+                     },

+                     cell: {

+                         props: {

+                             index: 3

+                         },

+                         formatters: [tableCellFormatter]

+                     }

+                 }

+             ]

+         };

+         this.getColumns = this.getColumns.bind(this);

+     }

+ 

+     getColumns() {

+         return this.state.columns;

+     }

+ 

+     render() {

+         return (

+             <div>

+                 <DSTable

+                     getColumns={this.getColumns}

+                     fieldsToSearch={this.state.fieldsToSearch}

+                     rowKey="oid"

+                     rows={this.props.rows}

+                     toolBarSearchField="Matching Rules"

+                     toolBarDisableLoadingSpinner

+                 />

+             </div>

+         );

+     }

+ }

+ 

+ MatchingRulesTable.propTypes = {

+     rows: PropTypes.array

+ };

+ 

+ MatchingRulesTable.defaultProps = {

+     rows: []

+ };

+ 

+ export { ObjectClassesTable, AttributesTable, MatchingRulesTable };

@@ -6,7 +6,9 @@ 

              if (columnsToSearch && columnsToSearch.length) {

                  columnsToSearch.forEach(column => {

                      if (column in row) {

-                         rowToSearch.push(row[column]);

+                         if (row[column] != null) {

+                             rowToSearch.push(row[column]);

+                         }

                      }

                  });

              } else {
@@ -53,22 +55,26 @@ 

                  cmd_list.push(cmd);

              }

          }

-         console.log(

-             "CMD: " + js_func + ": " + desc + " ==> " + cmd_list.join(" ")

-         );

+         console.log("CMD: " + js_func + ": " + desc + " ==> " + cmd_list.join(" "));

      }

  }

  

  // Convert DS timestamp to a friendly string: 20180921142257Z -> 10/21/2018, 2:22:57 PM

- export function get_date_string (timestamp) {

+ export function get_date_string(timestamp) {

      let year = timestamp.substr(0, 4);

      let month = timestamp.substr(4, 2);

      let day = timestamp.substr(6, 2);

      let hour = timestamp.substr(8, 2);

      let minute = timestamp.substr(10, 2);

      let sec = timestamp.substr(12, 2);

-     let date = new Date(parseInt(year), (parseInt(month) - 1), parseInt(day),

-                         parseInt(hour), parseInt(minute), parseInt(sec));

+     let date = new Date(

+         parseInt(year),

+         parseInt(month) - 1,

+         parseInt(day),

+         parseInt(hour),

+         parseInt(minute),

+         parseInt(sec)

+     );

      return date.toLocaleString();

  }

  
@@ -81,8 +87,14 @@ 

      let hour = start.substr(8, 2);

      let minute = start.substr(10, 2);

      let sec = start.substr(12, 2);

-     let startDate = new Date(parseInt(year), parseInt(month), parseInt(day),

-                              parseInt(hour), parseInt(minute), parseInt(sec));

+     let startDate = new Date(

+         parseInt(year),

+         parseInt(month),

+         parseInt(day),

+         parseInt(hour),

+         parseInt(minute),

+         parseInt(sec)

+     );

  

      // Get the servers current date

      year = end.substr(0, 4);
@@ -91,17 +103,23 @@ 

      hour = end.substr(8, 2);

      minute = end.substr(10, 2);

      sec = end.substr(12, 2);

-     let currDate = new Date(parseInt(year), parseInt(month), parseInt(day),

-                             parseInt(hour), parseInt(minute), parseInt(sec));

+     let currDate = new Date(

+         parseInt(year),

+         parseInt(month),

+         parseInt(day),

+         parseInt(hour),

+         parseInt(minute),

+         parseInt(sec)

+     );

  

      // Generate pretty elapsed time string

-     let seconds = Math.floor((currDate - (startDate)) / 1000);

+     let seconds = Math.floor((currDate - startDate) / 1000);

      let minutes = Math.floor(seconds / 60);

      let hours = Math.floor(minutes / 60);

      let days = Math.floor(hours / 24);

-     hours = hours - (days * 24);

-     minutes = minutes - (days * 24 * 60) - (hours * 60);

-     seconds = seconds - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60);

+     hours = hours - days * 24;

+     minutes = minutes - days * 24 * 60 - hours * 60;

+     seconds = seconds - days * 24 * 60 * 60 - hours * 60 * 60 - minutes * 60;

  

      return `${days} days, ${hours} hours, ${minutes} minutes, and ${seconds} seconds`;

  }
@@ -114,7 +132,7 @@ 

      return false;

  }

  

- export function valid_port (val) {

+ export function valid_port(val) {

      // Validate value is a number and between 1 and 65535

      let result = !isNaN(val);

      if (result) {
@@ -125,9 +143,9 @@ 

      return result;

  }

  

- export function valid_dn (dn) {

+ export function valid_dn(dn) {

      // Validate value is a valid DN (sanity validation)

-     if (dn.endsWith(',')) {

+     if (dn.endsWith(",")) {

          return false;

      }

      let dn_regex = new RegExp("^([A-Za-z]+=.*)");

@@ -1,377 +0,0 @@ 

- 

- <div id="schema-content">

-   <div id="objectclass-page" class="all-pages ds-margin-left" hidden>

-     <h3 class="ds-config-header">Objectclasses</h3>

-     <div>

-       <input type="checkbox" class="ds-config-checkbox" id="oc-user-defined"><label

-             for="oc-user-defined" class="ds-label">Only Non-standard Schema (objectClasses with X-ORIGIN: "user defined")</label>

-     </div>

-     <table id="oc-table" class="display ds-repl-table" cellspacing="0" width="100%">

-       <thead>

-         <tr class="ds-table-header">

-           <th class="ds-center">Objectclass Name</th>

-           <th class="ds-center">OID</th>

-           <th class="ds-center">Required Attributes</th>

-           <th class="ds-center">Allowed Attributes</th>

-           <th class="ds-center">Action</th>

-         </tr>

-       </thead>

-       <tbody>

-       </tbody>

-     </table>

-     <button id="add-oc-button" name="create-oc" data-toggle="modal" data-target="#add-edit-oc-form" class="btn btn-primary ds-button">Create Objectclass</button>

-   </div>

- 

-   <div id="attribute-page" class="all-pages ds-margin-left" hidden>

-     <h3 class="ds-config-header">Attributes</h3>

-     <div>

-       <input type="checkbox" class="ds-config-checkbox" id="attr-user-defined"><label

-             for="attr-user-defined" class="ds-label">Only Non-standard Schema (attributes with X-ORIGIN: "user defined")</label>

-     </div>

-     <table id="attr-table" class="display ds-repl-table" cellspacing="0" width="100%">

-       <thead>

-         <tr class="ds-table-header">

-           <th class="ds-center">Attribute Name</th>

-           <th class="ds-center">OID</th>

-           <th class="ds-center">Syntax</th>

-           <th class="ds-center">Multivalued</th>

-           <th class="ds-center">Action</th>

-         </tr>

-       </thead>

-       <tbody>

-       </tbody>

-     </table>

-     <button id="create-attr-button" data-toggle="modal" data-target="#add-edit-attr-form" class="btn btn-primary ds-button">Create Attribute</button>

-   </div>

- 

-   <div id="schema-mr" class="all-pages ds-margin-left" hidden>

-     <div class="">

-       <h3 class="ds-config-header">Matching Rules</h3>

-       <table id="schema-mr-table" class="display ds-table" cellspacing="0" width="100%">

-         <thead>

-           <tr class="ds-table-header">

-             <th>Matching Rule Name</th>

-             <th>OID</th>

-             <th>Syntax</th>

-             <th>Description</th>

-           </tr>

-         </thead>

-         <tbody id="standard-body">

-         </tbody>

-       </table>

-     </div>

-   </div>

- 

- 

-   <!-- Modals/Popups/Wizards -->

- 

-     <!-- View Attribute modal -->

-     <div class="modal fade" id="view-attr-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="view-attr-header" aria-hidden="true">

-         <div class="modal-dialog">

-             <div class="modal-content">

-                 <div class="modal-header">

-                     <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">

-                         <span class="pficon pficon-close"></span>

-                     </button>

-                     <h4 class="modal-title">View Attribute</h4>

-                 </div>

-                 <div class="modal-body">

-                     <div class="ds-inline">

-                         <div>

-                             <label for="attr-name-view" class="ds-config-label-lrg" title="The attribute name"><b

-                                 >Attribute Name</b></label><input class="ds-input" type="text" id="attr-name-view" size="40" disabled />

-                         </div>

-                         <div>

-                             <label for="attr-desc-view" class="ds-config-label-lrg" title="The attribute description"><b

-                                 >Description</b></label><input class="ds-input" type="text" id="attr-desc-view" size="40"  disabled />

-                         </div>

-                         <div>

-                             <label for="attr-oid-view" class="ds-config-label-lrg" title="The attribute name"><b

-                                 >OID</b></label><input class="ds-input" type="text" id="attr-oid-view" size="40" disabled />

-                         </div>

-                         <div>

-                             <label for="attr-parent-view" class="ds-config-label-lrg" title="The parent attribute"><b>Parent Attribute</b></label><input

-                                 class="ds-input" type="text" id="attr-parent-view" size="40" disabled />

-                         </div>

-                         <div>

-                             <label for="attr-syntax-view" class="ds-config-label-lrg" title="The attribute syntax"><b>Attribute Syntax</b></label><input

-                                 class="ds-input" type="text" id="attr-syntax-view" size="40" disabled />

-                         </div>

-                         <div>

-                             <label for="attr-usage-view" class="ds-config-label-lrg" title="The parent attribute"><b>Attribute Usage</b></label><input

-                                 class="ds-input" type="text" id="attr-usage-view" size="40" disabled />

-                         </div>

-                         <div>

-                             <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" disabled="disabled" /><label

-                                 for="attr-multivalued-view" class="ds-label"> Attribute Multi-Valued </label>

-                         </div>

-                         <div>

-                             <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" disabled="disabled" /><label

-                                 for="attr-no-user-mod-view" class="ds-label"> Read-only (NO-USER-MODIFICATION flag) </label>

-                         </div>

-                         <div>

-                             <label for="attr-alias-view" class="ds-config-label-lrg" title="The attribute alias list separated by space"><b

-                                 >Attribute Aliases</b></label><input class="ds-input" type="text" id="attr-alias-view" size="40" disabled />

-                         </div>

-                         <div class="panel panel-default ds-margin-top">

-                             <div class="panel-heading"><strong>Matching rules</strong></div>

-                                 <div class="panel-body">

-                                     <div>

-                                         <label for="attr-eq-mr-select-view" class="ds-config-label-lrg"><b>Equality</b></label><input

-                                             class="ds-input" type="text" id="attr-eq-mr-select-view" size="35" disabled />

-                                     </div>

-                                 <div>

-                                     <label for="attr-order-mr-select-view" class="ds-config-label-lrg"><b>Ordering</b></label><input

-                                         class="ds-input" type="text" id="attr-order-mr-select-view" size="35" disabled />

-                                 </div>

-                                 <div>

-                                     <label for="attr-sub-mr-select-view" class="ds-config-label-lrg"><b>Substring</b></label><input

-                                         class="ds-input" type="text" id="attr-sub-mr-select-view" size="35" disabled />

-                                 </div>

-                             </div>

-                         </div>

-                     </div>

-                     <div class="modal-footer">

-                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

-                     </div>

-                 </div>

-             </div>

-         </div>

-     </div>

- 

-   <!-- Add/edit Attribute modal -->

-   <div class="modal fade" id="add-edit-attr-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="add-edit-attr-header" aria-hidden="true">

-     <div class="modal-dialog">

-       <div class="modal-content">

-         <div class="modal-header">

-           <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">

-             <span class="pficon pficon-close"></span>

-           </button>

-           <h4 class="modal-title" id="add-edit-attr-header">Add Attribute</h4>

-         </div>

-         <div class="modal-body">

-           <div class="ds-inline">

-             <p class="ds-modal-error"></p>

-             <div>

-               <label for="attr-name" class="ds-config-label-lrg" title="The attribute name"><b

-                 >Attribute Name</b></label><input class="ds-input" type="text" id="attr-name" size="40"/>

-             </div>

-             <div>

-               <label for="attr-desc" class="ds-config-label-lrg" title="The attribute description"><b

-               >Description</b></label><input class="ds-input" type="text" id="attr-desc" size="40"/>

-             </div>

-             <div>

-               <label for="attr-oid" class="ds-config-label-lrg" title="The attribute name"><b

-               >OID</b></label><input class="ds-input" type="text" id="attr-oid" size="40"/>

-             </div>

-             <div>

-               <label for="attr-parent" class="ds-config-label-lrg" title="The parent attribute"><b>Parent Attribute</b></label><select

-                     class="btn btn-default dropdown ds-oc-dropdown" id="attr-parent">

-                 <option value=""></option>

-               </select>

-             </div>

-             <div>

-               <label for="attr-syntax" class="ds-config-label-lrg" title="The attribute syntax"><b>Attribute Syntax</b></label><select

-                 class="btn btn-default dropdown ds-oc-dropdown" id="attr-syntax">

-                 <option value="">Make a selection</option>

-               </select>

-             </div>

-             <div>

-               <label for="attr-usage" class="ds-config-label-lrg" title="The parent attribute"><b>Attribute Usage</b></label><select

-                     class="btn btn-default dropdown ds-oc-dropdown" id="attr-usage">

-               </select>

-             </div>

-             <div>

-               <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued"><label

-                 for="attr-multivalued" class="ds-label"> Attribute Multi-Valued </label>

-             </div>

-             <div>

-               <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod"><label

-                     for="attr-no-user-mod" class="ds-label"> Read-only (NO-USER-MODIFICATION flag) </label>

-             </div>

-             <div>

-               <label for="attr-alias" class="ds-config-label-lrg" title="The attribute alias list separated by space"><b

-                 >Attribute Aliases</b></label><input class="ds-input" type="text" id="attr-alias" size="40"/>

-             </div>

-             <div class="panel panel-default ds-margin-top">

-                 <div class="panel-heading"><strong>Matching rules</strong></div>

-                 <div class="panel-body">

-                   <div>

-                     <label for="attr-eq-mr-select" class="ds-config-label-lrg"><b>Equality</b></label><select

-                           class="btn btn-default dropdown ds-oc-dropdown" id="attr-eq-mr-select">

-                     <option></option>

-                   </select>

-                   </div>

-                   <div>

-                     <label for="attr-order-mr-select" class="ds-config-label-lrg"><b>Ordering</b></label><select

-                           class="btn btn-default dropdown ds-oc-dropdown" id="attr-order-mr-select">

-                     <option></option>

-                   </select>

-                   </div>

-                   <div>

-                     <label for="attr-sub-mr-select" class="ds-config-label-lrg"><b>Substring</b></label><select

-                           class="btn btn-default dropdown ds-oc-dropdown" id="attr-sub-mr-select">

-                     <option></option>

-                   </select>

-                   </div>

-                 </div>

-             </div>

-           </div>

-           <div id="save-attr-spinner" class="ds-center" hidden>

-             <p></p>

-             <p><span class="spinner spinner-xs spinner-inline"></span> Processing...<p>

-           </div>

-         </div>

-         <div class="modal-footer">

-           <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>

-           <button type="button" class="btn btn-primary" id="save-attr-button">Save</button>

-         </div>

-       </div>

-     </div>

-   </div>

- 

- 

-   <!-- View Objectclass -->

-     <div class="modal fade" id="view-objectclass-form" aria-labelledby="view-objectclass-form" data-backdrop="static" tabindex="-1" role="dialog" aria-hidden="true">

-         <div class="modal-dialog">

-             <div class="modal-content">

-                 <div class="modal-header">

-                     <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">

-                         <span class="pficon pficon-close"></span>

-                     </button>

-                     <h4 class="modal-title">View Objectclass</h4>

-                 </div>

-                 <div class="modal-body">

-                     <form class="form-horizontal">

-                         <div class="ds-inline">

-                             <div>

-                                 <label for="oc-name-view" class="ds-config-label-lrg" title="The objectclass name"><b

-                                     >Objectclass Name</b></label><input class="ds-input" type="text" id="oc-name-view" size="40" disabled />

-                             </div>

-                             <div>

-                                 <label for="oc-desc-view" class="ds-config-label-lrg" title="The objectClass description"><b

-                                     >Description</b></label><input class="ds-input" type="text" id="oc-desc-view" size="40" disabled/>

-                             </div>

-                             <div>

-                                 <label for="oc-oid-view" class="ds-config-label-lrg" title="Objectclass OID (optional)"><b

-                                     >OID (optional)</b></label><input class="ds-input" value="" type="text" id="oc-oid-view" size="40" disabled/>

-                             </div>

-                             <div>

-                                 <label for="oc-parent-view" class="ds-config-label-lrg" title="The parent objectclass"><b>Parent Objectclass</b></label><input

-                                     class="ds-input" value="" type="text" id="oc-parent-view" size="40" disabled />

-                             </div>

-                             <div>

-                                 <label for="oc-kind-view" class="ds-config-label-lrg" title="The parent objectclass"><b>Objectclass Kind</b></label><input

-                                     class="ds-input" value="" type="text" id="oc-kind-view"  size="40" disabled />

-                             </div>

-                             <hr>

-                             <div class="ds-container">

-                                 <div>

-                                     <label class="ds-config-label" for="oc-required-list-view" title=

-                                         "Attributes allowed by the objectclass"><b>Required Attributes</b></label>

-                                     <select id="oc-required-list-view" class="ds-may-must-list" multiple disabled>

-                                     </select>

-                                 </div>

-                                 <div class="ds-divider"></div>

-                                 <div>

-                                     <label class="ds-config-label" for="oc-allowed-list-view" title=

-                                         "Attributes allowed by the objectclass"><b>Allowed Attributes</b></label>

-                                     <select id="oc-allowed-list-view" class="ds-may-must-list" multiple disabled>

-                                     </select>

-                                 </div>

-                             </div>

-                         </div>

-                     </form>

-                     <div class="modal-footer">

-                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

-                     </div>

-                 </div>

-             </div>

-         </div>

-     </div>

- 

-   <!-- Add/Edit Objectclass -->

-   <div class="modal fade" id="add-edit-oc-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="add-edit-oc-header" aria-hidden="true">

-     <div class="modal-dialog">

-       <div class="modal-content">

-         <div class="modal-header">

-           <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">

-             <span class="pficon pficon-close"></span>

-           </button>

-           <h4 class="modal-title" id="add-edit-oc-header">Add Objectclass</h4>

-         </div>

-         <div class="modal-body">

-           <form class="form-horizontal">

-             <div class="ds-inline">

-               <p class="ds-modal-error"></p>

-               <div>

-                 <label for="oc-name" class="ds-config-label-lrg" title="The objectclass name"><b

-                   >Objectclass Name</b></label><input class="ds-input" type="text" id="oc-name" size="40" required />

-               </div>

-               <div>

-                 <label for="oc-desc" class="ds-config-label-lrg" title="The objectClass description"><b

-                 >Description</b></label><input class="ds-input" type="text" id="oc-desc" size="40"/>

-               </div>

-               <div>

-                 <label for="oc-oid" class="ds-config-label-lrg" title="Objectclass OID (optional)"><b

-                   >OID (optional)</b></label><input class="ds-input" value="" type="text" id="oc-oid" size="40"/>

-               </div>

-               <div>

-                 <label for="oc-parent" class="ds-config-label-lrg" title="The parent objectclass"><b>Parent Objectclass</b></label><select

-                       class="btn btn-default dropdown ds-oc-dropdown" id="oc-parent">

-                 </select>

-               </div>

-               <div>

-                 <label for="oc-kind" class="ds-config-label-lrg" title="The parent objectclass"><b>Objectclass Kind</b></label><select

-                       class="btn btn-default dropdown ds-oc-dropdown" id="oc-kind">

-                 <option value=""></option>

-                 </select>

-               </div>

-               <hr>

-               <div class="ds-container">

-                 <div name="available-attrs">

-                   <label for="schema-list" title="The available attributes to choose from."><b>Available Attributes</b></label>

-                   <select id="schema-list" class="ds-oc-form-list" name="availattrs" multiple>

-                   </select>

-                 </div>

- 

-                 <div name="add-remove-buttons">

-                   <div name="must buttons" class="btn-group ds-oc-must-buttons">

-                     <input type="button" class="ds-oc-add-del-btn" id="oc-must-add-button" value="Add &nbsp; &#9658; &#9658; &#9658; "/>

-                     <input type="button" class="ds-oc-add-del-btn" id="oc-must-remove-button" value="&#9668; &#9668; &#9668; &nbsp; Remove"/>

-                   </div>

-                   <p></p>

-                   <div name="may buttons" class="btn-group ds-oc-may-buttons">

-                     <input type="button" class="ds-oc-add-del-btn" id="oc-may-add-button" value="Add &nbsp; &#9658; &#9658; &#9658;"/>

-                     <input type="button" class="ds-oc-add-del-btn" id="oc-may-remove-button" value="&#9668; &#9668; &#9668; &nbsp; Remove"/>

-                   </div>

-                 </div>

- 

-                 <div name="may-must-lists">

-                   <label class="ds-config-label" for="oc-required-list" title=

-                     "Attributes required by the objectclass"><b>Required Attributes</b></label>

-                   <select id="oc-required-list" class="ds-may-must-list" name="availattrs" multiple>

-                   </select>

-                   <p></p>

-                   <label class="ds-config-label" for="oc-allowed-list" title=

-                     "Attributes allowed by the objectclass"><b>Allowed Attributes</b></label>

-                   <select id="oc-allowed-list" class="ds-may-must-list" name="availattrs" multiple>

-                   </select>

-                 </div>

-               </div>

-             </div>

-           </form>

-           <div id="save-oc-spinner" class="ds-center" hidden>

-             <p></p>

-             <p><span class="spinner spinner-xs spinner-inline"></span> Processing...<p>

-           </div>

-         </div>

-         <div class="modal-footer">

-           <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>

-           <button type="button" class="btn btn-primary" id="save-oc-button">Save</button>

-         </div>

-       </div>

-     </div>

-   </div>

- 

- </div>

@@ -1,925 +0,0 @@ 

- var attr_btn_html =

-   '<div class="dropdown">' +

-     '<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">' +

-       '  Choose Action...' +

-       '<span class="caret"></span>' +

-     '</button>' +

-     '<ul class="dropdown-menu ds-agmt-dropdown" role="menu" id="attr-action-btn" aria-labelledby="attr-action-btn">' +

-       '<li role=""><a role="menuitem" tabindex="0" class="attr-edit-btn" href="#schema-tab">Edit Attribute</a></li>' +

-       '<li role=""><a role="menuitem" tabindex="1" class="attr-del-btn" href="#schema-tab">Delete Attribute</a></li>' +

-      '</ul>' +

-   '</div>';

- 

- var attr_btn_html_only_view =

-   '<button class="btn btn-default attr-view-btn" type="button"' +

-   ' href="#schema-tab" title="Only user-defined attributes can be modified"> View Attribute' +

-   '</button>';

- 

- var oc_btn_html =

-   '<div class="dropdown">' +

-     '<button class="btn btn-default dropdown-toggle" type="button"data-toggle="dropdown">' +

-       ' Choose Action...' +

-       '<span class="caret"></span>' +

-     '</button>' +

-     '<ul class="dropdown-menu ds-agmt-dropdown" role="menu">' +

-       '<li role=""><a role="menuitem" tabindex="0" class="oc-edit-btn" href="#schema-tab">Edit Objectclass</a></li>' +

-       '<li role=""><a role="menuitem" tabindex="1" class="oc-del-btn" href="#schema-tab">Delete Objectclass</a></li>' +

-     '</ul>' +

-   '</div>';

- 

- var oc_btn_html_only_view =

-   '<button class="btn btn-default oc-view-btn" type="button"' +

-   ' href="#schema-tab" title="Only user-defined objectClasses can be modified"> View Objectclass' +

-   '</button>';

- 

- var schema_oc_table;

- var schema_at_table;

- var schema_mr_table;

- 

- var attr_usage_opts = ['userApplications', 'directoryOperation', 'distributedOperation', 'dSAOperation'];

- var oc_kind_opts = ['STRUCTURAL', 'ABSTRACT', 'AUXILIARY'];

- 

- function is_x_origin_user_defined(x_origin) {

-   if (typeof x_origin === 'string' && x_origin.toLowerCase() !== 'user defined' || x_origin == null) {

-     return false;

-   } else {

-     return true;

-   }

- }

- 

- // Leave only user defined attributes if the checkbox is crossed

- $.fn.dataTable.ext.search.push(

-   function(settings, searchData, index, rowData, counter) {

-     var x_origin;

-     if ( settings.sTableId == "attr-table" ) {

-         if ( $("#attr-user-defined").is(":checked") ) {

-           x_origin = rowData[7];

-           if (!is_x_origin_user_defined(x_origin)) {

-             return false;

-           }

-         }

-     } else {

-         if ( $("#oc-user-defined").is(":checked") ) {

-           x_origin = rowData[5];

-           if (!is_x_origin_user_defined(x_origin)) {

-             return false;

-           }

-         }

-     }

-     return true;

-   }

- );

- 

- function clear_oc_form() {

-   // Clear input fields and reset dropboxes

-   $("#add-edit-oc-header").html('Add Objectclass');

-   $(".ds-modal-error").hide();

-   $("#oc-name").attr('disabled', false);

-   $("#oc-name").val("");

-   $("#oc-oid").val("");

-   $("#oc-kind").prop('selectedIndex',0);

-   $("#oc-desc").val("");

-   $("#oc-parent").prop('selectedIndex',0);

-   $("#schema-list").prop('selectedIndex',-1);

-   $('#oc-required-list').find('option').remove();

-   $('#oc-allowed-list').find('option').remove();

-   $("#save-oc-button").attr('disabled', false);

- }

- 

- function clear_attr_form() {

-   // Clear input fields and reset dropboxes

-   $("#add-edit-attr-header").html('Add Attribute');

-   $(".ds-modal-error").hide();

-   $("#attr-name").attr('disabled', false);

-   $("#attr-name").val("");

-   $("#attr-syntax").val("");

-   $("#attr-desc").val("");

-   $("#attr-parent").prop('selectedIndex',0);

-   $("#attr-usage").prop('selectedIndex',0);

-   $("#attr-oid").val("");

-   $("#attr-alias").val("");

-   $('#attr-multivalued').prop('checked', false);

-   $('#attr-no-user-mod').prop('checked', false);

-   $("#attr-eq-mr-select").prop('selectedIndex',0);

-   $("#attr-order-mr-select").prop('selectedIndex',0);

-   $("#attr-sub-mr-select").prop('selectedIndex',0);

-   $("#save-attr-button").attr('disabled', false);

- }

- 

- function load_schema_objects_to_select(object, select_id, schema_json_select) {

-   var data = [];

-   for (var i = 0; i < schema_json_select[object].items.length; i++) {

-     item = schema_json_select[object].items[i];

-     if (item.name) {

-       data.push.apply(data, [item.name]);

-     } else {

-       data.push.apply(data, [item.oid]);

-     }

-   }

-   // Update html select

-   $.each(data, function (i, item) {

-       $("#" + select_id).append($('<option>', {

-           value: item,

-           text : item

-       }));

-   });

- }

- 

- function get_and_set_schema_tables() {

-   console.log("Loading schema...");

- 

-   // Set attribute usage select html in attribute's edit window

-   $.each(attr_usage_opts, function (i, item) {

-       $("#attr-usage").append($('<option>', {

-           value: item,

-           text : item,

-       }));

-   });

- 

-   // Set objectClass kind select html in objectClass's edit window

-   $.each(oc_kind_opts, function (i, item) {

-       $("#oc-kind").append($('<option>', {

-           value: item,

-           text : item,

-       }));

-   });

- 

-   var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'list'];

-   log_cmd('get_and_set_schema_tables', 'Get all schema objects', cmd);

-   cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(schema_data) {

-     var schema_json = JSON.parse(schema_data);

-     // Setup the tables: standard, custom, and Matching Rules

-     var data = [];

-     // If objectClass is user defined them the action button is enabled

-     for (var i = 0; i < schema_json.objectclasses.items.length; i++) {

-       var oc_btn = oc_btn_html_only_view;

-       item = schema_json.objectclasses.items[i];

-       if (is_x_origin_user_defined(item.x_origin)) {

-         oc_btn = oc_btn_html;

-       }

-       // Validate all params

-       if (item.oid === undefined) {

-          item.oid = "";

-       }

-       if (item.must === undefined) {

-          item.must = [];

-       }

-       if (item.may === undefined) {

-          item.may = [];

-       }

-       if (item.x_origin === undefined) {

-          item.x_origin = "";

-       }

-       if (item.kind === undefined) {

-          item.kind = "";

-       }

-       if (item.desc === undefined) {

-          item.desc = "";

-       }

-       if (item.sup === undefined) {

-           item.sup = "";

-       }

- 

-       data.push.apply(data, [[

-         item.name,

-         item.oid,

-         item.must.join(" "),

-         item.may.join(" "),

-         oc_btn,

-         item.x_origin,

-         oc_kind_opts[item.kind],

-         item.desc,

-         item.sup

-       ]]);

-     }

-     // Update html table

-     schema_oc_table = $('#oc-table').DataTable ({

-       "data": data,

-       "paging": true,

-       "bAutoWidth": false,

-       "dom": '<"pull-left"f><"pull-right"l>tip',

-       "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],

-       "language": {

-         "emptyTable": "No objectclasses defined",

-         "search": "Search Objectclasses"

-       },

-       "columnDefs": [ {

-         "targets": 4,

-         "orderable": false

-       }, {

-         "targets": 5,

-         "visible": false

-       }]

-     });

- 

-     // Get syntaxes and use the data to populate the attribute's table

-     cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', "attributetypes", 'get_syntaxes'];

-     cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(syntax_data) {

-       var obj = JSON.parse(syntax_data);

-       var syntax_list = [];

- 

-       load_schema_objects_to_select('matchingrules', 'attr-eq-mr-select', schema_json);

-       load_schema_objects_to_select('matchingrules', 'attr-order-mr-select', schema_json);

-       load_schema_objects_to_select('matchingrules', 'attr-sub-mr-select', schema_json);

-       load_schema_objects_to_select('attributetypes', 'schema-list', schema_json);

-       load_schema_objects_to_select('objectclasses', 'oc-parent', schema_json);

-       load_schema_objects_to_select('attributetypes', 'attr-parent', schema_json);

- 

-       for (var i = 0; i < obj.items.length; i++) {

-         item = obj.items[i];

-         syntax_list.push.apply(syntax_list, [item]);

-       }

-       // Update syntax select html in attribute's edit window

-       $.each(syntax_list, function (i, item) {

-           $("#attr-syntax").append($('<option>', {

-               value: item.id,

-               text : item.name + " (" + item.id + ")"

-           }));

-       });

- 

-       var data = [];

-       var syntax_name = "";

-       for (var i = 0; i < schema_json.attributetypes.items.length; i++) {

-         var attr_btn = attr_btn_html_only_view;

-         item = schema_json.attributetypes.items[i];

-         if (item.single_value) {

-             multivalued = 'no';

-         } else {

-             multivalued = 'yes';

-         }

-         $.each(syntax_list, function (i, syntax) {

-           if (syntax.id === item.syntax) {

-             syntax_name = '<div title="' + syntax.name + '">' + syntax.name + '</div>';

-           }

-         });

-         // If attribute is user defined them the action button is enabled

-         if (is_x_origin_user_defined(item.x_origin)) {

-           attr_btn = attr_btn_html;

-         }

-         // Validate all params

-         if (item.oid === undefined) {

-            item.oid = "";

-         }

-         if (item.sup === undefined) {

-            item.sup = "";

-         }

-         if (item.x_origin === undefined) {

-            item.x_origin = "";

-         }

-         if (item.no_user_mod === undefined) {

-            item.no_user_mod = "";

-         }

-         if (item.desc === undefined) {

-            item.desc = "";

-         }

-         if (item.usage === undefined) {

-            item.usage = "";

-         }

-         if (item.aliases === undefined) {

-            item.aliases = "";

-         }

-         if (item.equality === undefined) {

-            item.equality = "";

-         }

-         if (item.ordering === undefined) {

-            item.ordering = "";

-         }

-         if (item.substr === undefined) {

-            item.substr = "";

-         }

- 

-         data.push.apply(data, [[

-           item.name,

-           item.oid,

-           syntax_name,

-           multivalued,

-           attr_btn,

-           item.desc,

-           item.aliases,

-           item.x_origin,

-           attr_usage_opts[item.usage],

-           item.no_user_mod,

-           item.sup,

-           item.equality,

-           item.ordering,

-           item.substr,

-         ]]);

-       }

-       // Update html table

-       schema_at_table = $('#attr-table').DataTable({

-         "data": data,

-         "paging": true,

-         "bAutoWidth": false,

-         "dom": '<"pull-left"f><"pull-right"l>tip', // Moves the search box to the left

-         "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],

-         "language": {

-           "emptyTable": "No attributes defined",

-           "search": "Search Attributes"

-         },

-         "columnDefs": [ {

-           "targets": 4,

-           "orderable": false

-         }, {

-           "targets": 5,

-           "visible": false

-         }]

-       });

-       update_progress();

-     }).fail(function(syntax_data) {

-         console.log("Get syntaxes failed: " + syntax_data.message);

-         check_inst_alive(1);

-     });

- 

-     var data = [];

-     for (var i = 0; i < schema_json.matchingrules.items.length; i++) {

-       item = schema_json.matchingrules.items[i];

-       data.push.apply(data, [[

-         item.name,

-         item.oid,

-         item.syntax,

-         item.desc]]);

-     }

-     schema_mr_table = $('#schema-mr-table').DataTable({

-       "paging": true,

-       "data": data,

-       "bAutoWidth": false,

-       "dom": '<"pull-left"f><"pull-right"l>tip',

-       "language": {

-         "emptyTable": "No matching rules defined",

-         "search": "Search Matching Rules"

-       },

-       "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],

-     });

- 

-     console.log("Finished loading schema.");

-     update_progress();

-   }).fail(function(oc_data) {

-       console.log("Get all schema objects failed: " + oc_data.message);

-       check_inst_alive(1);

-   });

- }

- 

- $(document).ready( function() {

-   // Set an interval event to wait for all the pages to load, then load the config

-   $("#schema-content").load("schema.html", function (){

-     // Sort schema list awhile

-     sort_list( $("#schema-list") );

- 

-     $("#objectclass-btn").on("click", function() {

-       $(".all-pages").hide();

-       $("#schema-content").show();

-       $("#objectclass-page").show();

-     });

-     $("#attribute-btn").on("click", function() {

-       $(".all-pages").hide();

-       $("#schema-content").show();

-       $("#attribute-page").show();

-     });

-     $("#schema-mr-btn").on("click", function() {

-       $(".all-pages").hide();

-       $("#schema-content").show();

-       $("#schema-mr").show();

-     });

- 

-     $('#attr-user-defined').change(function() {

-       schema_at_table.draw();

-     });

-     $('#oc-user-defined').change(function() {

-       schema_oc_table.draw();

-     });

- 

-     //

-     // Modals/Forms

-     //

- 

-     /*

-      *

-      * Add Objectclass Form

-      *

-      */

-     $("#add-oc-button").on("click", function() {

-       clear_oc_form();

-       document.getElementById("oc-parent").value = 'top';

-     });

- 

-     $("#save-oc-button").on("click", function() {

-       var oc_name = $("#oc-name").val();

-       var oc_oid = $("#oc-oid").val();

-       var oc_parent = $("#oc-parent").val();

-       var oc_kind = $("#oc-kind").val();

-       var oc_desc = $("#oc-desc").val();

-       var oc_x_origin = "user defined";

-       var oc_required_list = $('#oc-required-list option').map(function() { return $(this).val(); }).get();

-       var oc_allowed_list = $('#oc-allowed-list option').map(function() { return $(this).val(); }).get();

- 

-       var action = 'add';

-       var edit = false;

-       if ( $("#add-edit-oc-header").text().indexOf("Edit Objectclass") != -1){

-         edit = true;

-         action = 'replace';

-       }

-       if (oc_name == '') {

-         report_err($("#oc-name"), 'You must provide an objectClass name');

-         return;

-       }

-       var cmd = [DSCONF, server_inst, 'schema', 'objectclasses', action, oc_name];

-       // Process and validate parameters

-       if (oc_oid != "") {

-           cmd.push.apply(cmd, ["--oid", oc_oid]);

-       }

-       if (oc_parent != "") {

-           cmd.push.apply(cmd, ["--sup", oc_parent]);

-       }

-       if (oc_kind != "") {

-           cmd.push.apply(cmd, ["--kind", oc_kind]);

-       }

-       if (oc_desc != "") {

-           cmd.push.apply(cmd, ["--desc", oc_desc]);

-       }

-       if (oc_x_origin != "") {

-           cmd.push.apply(cmd, ["--x-origin=\"" + oc_x_origin + "\""]);

-       }

-       if (oc_required_list.length !== 0) {

-         cmd.push.apply(cmd, ["--must"]);

-         cmd.push.apply(cmd, oc_required_list);

-       }

-       if (oc_allowed_list.length !== 0) {

-         cmd.push.apply(cmd, ["--may"]);

-         cmd.push.apply(cmd, oc_allowed_list);

-       }

- 

-       $("#save-oc-spinner").show();

-       log_cmd('#save-oc-button (click)', 'Save objectclasses', cmd);

-       cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).

-       done(function(data) {

-         $("#oc-name").attr('disabled', false);

- 

-         // Update html table (if edit: delete old then add new)

-         if ( edit ) {

-           var selector = $('tr:contains(' + oc_name + ')');

-           schema_oc_table.row(selector).remove().draw(false);

-         }

-         var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'objectclasses', 'query', oc_name];

-         log_cmd('#save-oc-button (click)', 'Search objectclasses', cmd);

-         cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).

-         done(function(oc_data) {

-           var obj = JSON.parse(oc_data);

-           var item = obj.oc;

-           schema_oc_table.row.add( [

-             item.name,

-             item.oid,

-             item.must.join(" "),

-             item.may.join(" "),

-             oc_btn_html,

-             item.x_origin,

-             oc_kind_opts[item.kind],

-             item.desc,

-             item.sup

-           ] ).draw( false );

-         }).

-         fail(function(oc_data) {

-           popup_err("err", oc_data.message);

-           console.log("Search objectclasses failed: " + oc_data.message);

-           check_inst_alive(1);

-         });

-         // Replace the option in 'Edit objectClass' window

-         if (!edit) {

-           var option = $('<option></option>').attr("value", oc_name).text(oc_name);

-           $("#oc-parent").append(option);

-         }

-         $("#save-oc-spinner").hide();

-         popup_success("The objectClass was saved in DS");

-         $("#add-edit-oc-form").modal('toggle');

-       }).

-       fail(function(data) {

-         $("#save-oc-spinner").hide();

-         popup_err("Error", "Failed to save the objectClass\n" + data.message);

-         $("#add-edit-oc-form").modal('toggle');

-       });

-     });

- 

-     // Required Attributes

-     $("#oc-must-add-button").on("click", function () {

-       var add_attrs = $("#schema-list").val();

-       if (add_attrs && add_attrs != '' && add_attrs.length > 0) {

-         for (var i = 0; i < add_attrs.length; i++) {

-           if ( $('#oc-required-list option[value="' + add_attrs[i] + '"]').val() === undefined) {

-             $('#oc-required-list').append($("<option/>").val(add_attrs[i]).text(add_attrs[i]));

-           }

-         }

-         $("#schema-list").find('option:selected').remove();

-       }

-     });

-     $("#oc-must-remove-button").on("click", function () {

-       var add_attrs = $("#oc-required-list").find('option:selected');

-       if (add_attrs && add_attrs != '' && add_attrs.length > 0) {

-         for (var i = 0; i < add_attrs.length; i++) {

-           if ( $('#schema-list option[value="' + add_attrs[i].text + '"]').val() === undefined) {

-             $('#schema-list').append($("<option/>").val(add_attrs[i].text).text(add_attrs[i].text));

-           }

-         }

-       }

-       $("#oc-required-list").find('option:selected').remove();

-       sort_list( $("#schema-list") );

-     });

- 

-     // Allowed Attributes

-     $("#oc-may-add-button").on("click", function () {

-       var add_attrs = $("#schema-list").val();

-       if (add_attrs && add_attrs != '' && add_attrs.length > 0) {

-         for (var i = 0; i < add_attrs.length; i++) {

-           if ( $('#oc-allowed-list option[value="' + add_attrs[i] + '"]').val() === undefined) {

-             $('#oc-allowed-list').append($("<option/>").val(add_attrs[i]).text(add_attrs[i]));

-           }

-         }

-         $("#schema-list").find('option:selected').remove();

-       }

-     });

-     $("#oc-may-remove-button").on("click", function () {

-       var add_attrs = $("#oc-allowed-list").find('option:selected');

-       if (add_attrs && add_attrs != '' && add_attrs.length > 0) {

-         for (var i = 0; i < add_attrs.length; i++) {

-           if ( $('#schema-list option[value="' + add_attrs[i].text + '"]').val() === undefined) {

-             $('#schema-list').append($("<option/>").val(add_attrs[i].text).text(add_attrs[i].text));

-           }

-         }

-       }

-       $("#oc-allowed-list").find('option:selected').remove();

-       sort_list( $("#schema-list") );

-     });

- 

-     /*

-      *

-      * Add Attribute Form

-      *

-      */

-     $("#create-attr-button").on("click", function() {

-       clear_attr_form();

-     });

- 

-     $("#save-attr-button").on("click", function() {

-       var attr_name = $("#attr-name").val();

-       var attr_oid = $("#attr-oid").val();

-       var attr_syntax = $("#attr-syntax").val();

-       var attr_syntax_text = $("#attr-syntax :selected").text();

-       var attr_usage = $('#attr-usage').val();

-       var attr_desc = $('#attr-desc').val();

-       var attr_x_origin = "user defined";

-       var attr_parent = $('#attr-parent').val();

-       var attr_aliases = $('#attr-alias').val().split(" ");

-       var eq_mr= $('#attr-eq-mr-select').val();

-       var order_mr = $('#attr-order-mr-select').val();

-       var sub_mr  = $('#attr-sub-mr-select').val();

-       var multiple = 'no';

-       if ( $("#attr-multivalued").is(":checked") ) {

-         multiple = 'yes';

-       }

-       var no_user_mod = false;

-       if ( $("#attr-no-user-mod").is(":checked") ) {

-         no_user_mod = true;

-       }

-       var action = 'add';

-       var edit = false;

-       if ( $("#add-edit-attr-header").text().indexOf("Edit Attribute") != -1){

-         edit = true;

-         action = 'replace';

-       }

- 

-       if (attr_name == '') {

-         report_err($("#attr-name"), 'You must provide an attribute name');

-         return;

-       }

-       if (attr_syntax == '') {

-         report_err($("#attr-syntax"), 'You must provide an attribute syntax');

-         return;

-       }

- 

-       var cmd = [DSCONF, server_inst, 'schema', 'attributetypes', action, attr_name];

-       // Process and validate parameters

-       if (attr_aliases) {

-         cmd.push.apply(cmd, ["--aliases"]);

-         cmd.push.apply(cmd, attr_aliases);

-       }

-       if (attr_syntax) {

-         cmd.push.apply(cmd, ["--syntax", attr_syntax]);

-       }

-       if (multiple == 'no') {

-         cmd.push.apply(cmd, ["--single-value"]);

-       } else {

-         cmd.push.apply(cmd, ["--multi-value"]);

-       }

-       if (no_user_mod) {

-         cmd.push.apply(cmd, ["--no-user-mod"]);

-       } else {

-         cmd.push.apply(cmd, ["--user-mod"]);

-       }

-       cmd.push.apply(cmd, ["--oid", attr_oid]);

-       cmd.push.apply(cmd, ["--usage", attr_usage]);

-       cmd.push.apply(cmd, ["--sup", attr_parent]);

-       cmd.push.apply(cmd, ["--desc", attr_desc]);

-       cmd.push.apply(cmd, ["--x-origin", attr_x_origin]);

-       cmd.push.apply(cmd, ["--equality"]);

-       if (eq_mr) {

-         cmd.push.apply(cmd, [eq_mr]);

-       } else {

-         cmd.push.apply(cmd, [""]);

-       }

-       cmd.push.apply(cmd, ["--substr"]);

-       if (sub_mr) {

-         cmd.push.apply(cmd, [sub_mr]);

-       } else {

-         cmd.push.apply(cmd, [""]);

-       }

-       cmd.push.apply(cmd, ["--ordering"]);

-       if (order_mr) {

-         cmd.push.apply(cmd, [order_mr]);

-       } else {

-         cmd.push.apply(cmd, [""]);

-       }

-       $("#save-attr-spinner").show();

-       log_cmd('#save-attr-button (click)', 'Save attribute', cmd);

-       cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).

-       done(function(data) {

-         var attr_syntax_name = '<div title="' + attr_syntax + '">' +

-                                attr_syntax_text.substr(0, attr_syntax_text.indexOf(" (")) + '</div>';

-         $("#attr-name").attr('disabled', false);

-         // Update html table (if edit: delete old then add new)

-         if ( edit ) {

-           var selector = $('tr:contains(' + attr_name + ')');

-           schema_at_table.row(selector).remove().draw(false);

-         }

-         var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'attributetypes', 'query', attr_name];

-         log_cmd('#save-oc-button (click)', 'Get attribute', cmd);

-         cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).

-         done(function(at_data) {

-           var obj = JSON.parse(at_data);

-           var item = obj.at;

-           schema_at_table.row.add( [

-             item.name,

-             item.oid,

-             attr_syntax_name,

-             multiple,

-             attr_btn_html,

-             item.desc,

-             item.aliases,

-             item.x_origin,

-             attr_usage_opts[item.usage],

-             item.no_user_mod,

-             item.sup,

-             item.equality,

-             item.ordering,

-             item.substr,

- 

-           ] ).draw( false );

-           $("#attr-name").attr('disabled', false);

-         }).

-         fail(function(at_data) {

-           popup_err("err", at_data.message);

-           console.log("Query attributes failed: " + at_data.message);

-           check_inst_alive(1);

-         });

-         if (!edit) {

-           var option = $('<option></option>').attr("value", attr_name).text(attr_name);

-           $("#schema-list").append(option);

-         }

-         $("#save-attr-spinner").hide();

-         popup_success("The attribute was saved in DS");

-         $("#add-edit-attr-form").modal('toggle');

-       }).

-       fail(function(data) {

-         $("#save-attr-spinner").hide();

-         popup_err("Error", "Failed to save the attribute: " + data.message);

-         $("#add-edit-attr-form").modal('toggle');

-      });

-     });

- 

-     function load_attr_form(element) {

-       clear_attr_form();

-       var data = schema_at_table.row(element.parents('tr') ).data();

-       var edit_attr_name = data[0];

-       var edit_attr_oid = data[1];

-       var edit_attr_syntax = $.parseHTML(data[2])[0].title;

-       var edit_attr_multivalued = data[3];

-       var edit_attr_desc = data[5];

-       var edit_attr_aliases = data[6];

-       var edit_attr_x_origin = data[7];

-       var edit_attr_usage = data[8];

-       var edit_attr_no_user_mod = data[9];

-       var edit_attr_parent = data[10];

-       var edit_attr_eq_mr = data[11];

-       var edit_attr_order_mr = data[12];

-       var edit_attr_sub_mr = data[13];

- 

-       $("#add-edit-attr-header").html('Edit Attribute: ' + edit_attr_name);

-       $("#attr-name").val(edit_attr_name);

-       $("#attr-name").attr('disabled', true);

-       $("#attr-oid").val(edit_attr_oid);

-       $("#attr-usage")[0].value = edit_attr_usage;

-       $("#attr-parent")[0].value = edit_attr_parent;

-       $("#attr-desc").val(edit_attr_desc);

-       if (edit_attr_aliases) {

-         $("#attr-alias").val(edit_attr_aliases.join(" "));

-       }

-       $("#attr-syntax").val(edit_attr_syntax);

-       $("#attr-multivalued").prop('checked', false);

-       if (edit_attr_multivalued == "yes") {

-         $("#attr-multivalued").prop('checked', true);

-       }

-       $("#attr-no-user-mod").prop('checked', false);

-       if (edit_attr_no_user_mod) {

-         $("#attr-no-user-mod").prop('checked', true);

-       }

-       $("#save-attr-spinner").show();

-       $("#attr-eq-mr-select")[0].value = edit_attr_eq_mr;

-       $("#attr-order-mr-select")[0].value = edit_attr_order_mr;

-       $("#attr-sub-mr-select")[0].value = edit_attr_sub_mr;

-       $("#save-attr-spinner").hide();

- 

-       $("#add-edit-attr-form").modal('toggle');

-     }

- 

-     function load_view_attr_form(element) {

-       clear_attr_form();

-       var data = schema_at_table.row(element.parents('tr') ).data();

-       var edit_attr_name = data[0];

-       var edit_attr_oid = data[1];

-       var edit_attr_syntax = $.parseHTML(data[2])[0].title;

-       var edit_attr_multivalued = data[3];

-       var edit_attr_desc = data[5];

-       var edit_attr_aliases = data[6];

-       var edit_attr_x_origin = data[7];

-       var edit_attr_usage = data[8];

-       var edit_attr_no_user_mod = data[9];

-       var edit_attr_parent = data[10];

-       var edit_attr_eq_mr = data[11];

-       var edit_attr_order_mr = data[12];

-       var edit_attr_sub_mr = data[13];

- 

-       $("#attr-name-view").val(edit_attr_name);

-       $("#attr-oid-view").val(edit_attr_oid);

-       $("#attr-usage-view")[0].value = edit_attr_usage;

-       $("#attr-parent-view")[0].value = edit_attr_parent;

-       $("#attr-desc-view").val(edit_attr_desc);

-       if (edit_attr_aliases) {

-         $("#attr-alias-view").val(edit_attr_aliases.join(" "));

-       }

-       $("#attr-syntax-view").val(edit_attr_syntax);

-       $("#attr-multivalued-view").prop('checked', false);

-       if (edit_attr_multivalued == "yes") {

-         $("#attr-multivalued-view").prop('checked', true);

-       }

-       $("#attr-no-user-mod-view").prop('checked', false);

-       if (edit_attr_no_user_mod) {

-         $("#attr-no-user-mod-view").prop('checked', true);

-       }

-       $("#attr-eq-mr-select-view").val(edit_attr_eq_mr);

-       $("#attr-order-mr-select-view").val(edit_attr_order_mr);

-       $("#attr-sub-mr-select-view").val(edit_attr_sub_mr);

- 

-       $("#view-attr-form").modal('toggle');

-     }

- 

-     $(document).on('click', '.attr-view-btn', function(e) {

-       e.preventDefault();

-       load_view_attr_form($(this));

-     });

- 

-     $(document).on('click', '.attr-edit-btn', function(e) {

-       e.preventDefault();

-       load_attr_form($(this));

-     });

- 

-     $(document).on('click', '.attr-del-btn', function(e) {

-       e.preventDefault();

-       var data = schema_at_table.row( $(this).parents('tr') ).data();

-       var del_attr_name = data[0];

-       var at_row = $(this);

-       popup_confirm("Are you sure you want to delete attribute: <b>" + del_attr_name + "</b>", "Confirmation", function (yes) {

-         if (yes) {

-           var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'attributetypes', 'remove', del_attr_name];

-           log_cmd('.attr-del-btn (click)', 'Remove attribute', cmd);

-           cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {

-             popup_success("Attribute was successfully removed!");

-             schema_at_table.row( at_row.parents('tr') ).remove().draw( false );

-             $("#schema-list option[value='" + del_attr_name + "']").remove();

-           }).fail(function(data) {

-             popup_err("Attribute removal error", del_attr_name + " removal has failed: " + data.message);

-           });

-         }

-       });

-     });

- 

-     function load_view_oc_form(element) {

-       clear_oc_form();

-       var data = schema_oc_table.row(element.parents('tr') ).data();

-       var edit_oc_name = data[0];

-       var edit_oc_oid = data[1];

-       var edit_oc_required = data[2].split(" ");

-       var edit_oc_allowed = data[3].split(" ");

-       var edit_oc_x_origin = data[5];

-       var edit_oc_kind = data[6];

-       var edit_oc_desc = data[7];

-       var edit_oc_parent = data[8];

- 

-       $("#oc-name-view").val(edit_oc_name);

-       $("#oc-oid-view").val(edit_oc_oid);

-       $("#oc-kind-view")[0].value = edit_oc_kind;

-       $("#oc-desc-view").val(edit_oc_desc);

-       $("#oc-parent-view")[0].value = edit_oc_parent;

-       $.each(edit_oc_required, function (i, item) {

-         if (item) {

-           $("#oc-required-list-view").append($('<option>', {

-             value: item,

-             text : item

-           }));

-         }

-       });

-       $.each(edit_oc_allowed, function (i, item) {

-         if (item) {

-           $("#oc-allowed-list-view").append($('<option>', {

-             value: item,

-             text : item

-           }));

-         }

-       });

- 

-       // Update modal html header and fields and show()

-       $("#view-objectclass-form").modal('toggle');

-     }

- 

-     function load_oc_form(element) {

-       clear_oc_form();

-       var data = schema_oc_table.row(element.parents('tr') ).data();

-       var edit_oc_name = data[0];

-       var edit_oc_oid = data[1];

-       var edit_oc_required = data[2].split(" ");

-       var edit_oc_allowed = data[3].split(" ");

-       var edit_oc_x_origin = data[5];

-       var edit_oc_kind = data[6];

-       var edit_oc_desc = data[7];

-       var edit_oc_parent = data[8];

- 

-       $("#save-oc-spinner").show();

-       $("#add-edit-oc-header").html('Edit Objectclass: ' + edit_oc_name);

-       $("#oc-name").attr('disabled', true);

-       $("#oc-name").val(edit_oc_name);

-       $("#oc-oid").val(edit_oc_oid);

-       $("#oc-kind").val(edit_oc_kind);

-       $("#oc-desc").val(edit_oc_desc);

-       $("#oc-parent").val(edit_oc_parent);

-       $.each(edit_oc_required, function (i, item) {

-         if (item) {

-           $("#oc-required-list").append($('<option>', {

-             value: item,

-             text : item

-           }));

-         }

-       });

-       $.each(edit_oc_allowed, function (i, item) {

-         if (item) {

-           $("#oc-allowed-list").append($('<option>', {

-             value: item,

-             text : item

-           }));

-         }

-       });

-       $("#save-oc-spinner").hide();

- 

-       // Update modal html header and fields and show()

-       $("#add-edit-oc-form").modal('toggle');

-     }

- 

-     $(document).on('click', '.oc-view-btn', function(e) {

-       e.preventDefault();

-       load_view_oc_form($(this));

-     });

- 

-     $(document).on('click', '.oc-edit-btn', function(e) {

-       e.preventDefault();

-       load_oc_form($(this));

-     });

- 

-     $(document).on('click', '.oc-del-btn', function(e) {

-       e.preventDefault();

-       var data = schema_oc_table.row( $(this).parents('tr') ).data();

-       var del_oc_name = data[0];

-       var oc_row = $(this);

- 

-       popup_confirm("Are you sure you want to delete objectclass: <b>" + del_oc_name + "</b>", "Confirmation", function (yes) {

-         if (yes) {

-           var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'objectclasses', 'remove', del_oc_name];

-           log_cmd('.oc-del-btn (click)', 'Remove objectclass', cmd);

-           cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {

-             popup_success("ObjectClass was successfully removed!");

-             schema_oc_table.row( oc_row.parents('tr') ).remove().draw( false );

-             $("#oc-parent option[value='" + del_oc_name + "']").remove();

-           }).fail(function(data) {

-             popup_err("Error", del_oc_name + " removal has failed: " + data.message);

-           });

-         }

-       });

-     });

-     // Page is loaded, mark it as so...

-     schema_page_loaded = 1;

-   });

- });

The added file is too large to be shown here, see it at: src/cockpit/389-console/src/schema.jsx
@@ -30,8 +30,6 @@ 

          "fonts",

          "images",

          "index.html",

-         "schema.html",

-         "schema.js",

          "servers.html",

          "servers.js",

          "static",

file modified
+8 -2
@@ -110,7 +110,7 @@ 

          if json:

              attr_syntaxes_list = []

              for id, name in ATTR_SYNTAXES.items():

-                 attr_syntaxes_list.append({'name': name, 'id': id})

+                 attr_syntaxes_list.append({'label': name, 'id': id})

              result = {'type': 'list', 'items': attr_syntaxes_list}

          else:

              result = ATTR_SYNTAXES
@@ -129,7 +129,7 @@ 

                  obj_i = vars(object_model(obj))

                  if len(obj_i["names"]) == 1:

                      obj_i['name'] = obj_i['names'][0].lower()

-                     obj_i['aliases'] = ""

+                     obj_i['aliases'] = None

                  elif len(obj_i["names"]) > 1:

                      obj_i['name'] = obj_i['names'][0].lower()

                      obj_i['aliases'] = obj_i['names'][1:]
@@ -153,6 +153,12 @@ 

                  object_insts.append(obj_i)

  

              object_insts = sorted(object_insts, key=itemgetter('name'))

+             # Ensure that the string values are in list so we can use React filter component with it

+             for obj_i in object_insts:

+                 for key, value in obj_i.items():

+                     if isinstance(value, str):

+                         obj_i[key] = (value, )

+ 

              return {'type': 'list', 'items': object_insts}

          else:

              object_insts = [object_model(obj_i) for obj_i in results]

Description: Port the schema UI tab to React and preserve all
existing features.

https://pagure.io/389-ds-base/issue/50836

Reviewed by: ?

Can we merge the two setState functions into this one?

I think you are missing a file from your PR, I can not build the server:

ERROR in ./src/schema.jsx
Module not found: Error: Can't resolve './lib/schema/schemaTables.jsx' in '/home/mareynol/source/ds389/389-ds-base/src/cockpit/389-console/src'

rebased onto 8d415b6564c963469b8e8fe27879632a155b1d23

4 years ago

I've put the files to PR. Please, check.

1 new commit added

  • Remove old code and fix couple of issues
4 years ago

Can we merge the two setState functions into this one?

Fixed.

This can be removed :)

Fixed.

Clicking on Schema tab crashes browser:

TypeError: rowData.x_origin is null
schemaTables.jsx:333:36
    formatters schemaTables.jsx:333
    evaluateFormatters evaluate-formatters.js:10
    reduce self-hosted:303
    evaluateFormatters evaluate-formatters.js:8
    render body-row.js:120
    map self-hosted:251
    render body-row.js:90
    React 13
    toggleLoading schema.jsx:113
    toggleLoading self-hosted:880
    loadSchemaData schema.jsx:214
    s cockpit.js:979
    f cockpit.js:991
    n cockpit.js:897
The above error occurred in the <BodyRow> component:
    in BodyRow (created by Body)
    in tbody (created by Body)
    in Body (created by DSTable)
    in table (created by Provider)
    in Provider (created by TablePfProvider)
    in TablePfProvider (created by DSTable)
    in div (created by DSTable)
    in DSTable (created by AttributesTable)
    in div (created by AttributesTable)
    in AttributesTable (created by Schema)
    in div (created by Schema)
    in div (created by TabPane)
    in Transition (created by Fade)
    in Fade (created by TabPane)
    in TabPane (created by Schema)
    in div (created by TabContent)
    in TabContent (created by Schema)
    in div (created by Schema)
    in TabContainer (created by Uncontrolled(TabContainer))
    in Uncontrolled(TabContainer) (created by Schema)
    in div (created by Schema)
    in div (created by Schema)
    in div (created by Schema)
    in Schema

1 new commit added

  • Fix the issue when x_origin is null
4 years ago

Hm, it doesn't crash the browser when I click on Schema but if I search for the attribute which has x_origin == null - it crashes.

This commit should fix it. Please check.

Better, but when I try to add a new attribute i get a usage error:

tools.jsx:58 CMD: cmdOperationAttribute: Do the add operation on Attribute ==> dsconf -j ldapi://%2fvar%2frun%2fslapd-localhost.socket schema attributetypes add mark --single-value --user-mod --oid  --usage userApplications --desc mark --sup  --equality  --substr  --ordering 

cockpit.js:606 usage: dsconf instance schema attributetypes add [-h] [--oid OID]
                                                 [--desc DESC]
                                                 [--x-origin X_ORIGIN]
                                                 [--aliases ALIASES [ALIASES ...]]
                                                 [--single-value]
                                                 [--multi-value]
                                                 [--no-user-mod] [--user-mod]
                                                 [--equality EQUALITY]
                                                 [--substr SUBSTR]
                                                 [--ordering ORDERING]
                                                 [--usage USAGE]
                                                 [--sup SUP [SUP ...]]
                                                 --syntax SYNTAX
                                                 name
dsconf instance schema attributetypes add: error: the following arguments are required: --syntax

We now need "--syntax "

1 new commit added

  • Add field validation
4 years ago

Yeah, I was about to add it but then I decided to create the PR sooner for the initial review.
Now it the field validation is added, please check.

On FF there is no space between the checkbox and the label for user-defined classes.

When adding an objectclass, the tab just starts reloading, but doesn't say its saving, just says that the page is reloading. This is confusing

When I click on "view objectclass" it also showing the loading page. It should just open the modal, not reload the entire tab every time I want to look at an objectclass. So there's some weird toggling going on for these tasks. Also viewing an objectclass does not show the allowed attributes.

Same issue when deleting an objectclass. When you choose delete the pages just says "Loading schema". Then a notification finally pops up saying the delete was successful.

On the objectclass table if I reset the page size the browser crashes (for the Attribute table it works correctly):

TypeError: rowData.x_origin is undefined
schemaTables.jsx:125:36
The above error occurred in the <BodyRow> component:
    in BodyRow (created by Body)
    in tbody (created by Body)
    in Body (created by DSTable)
    in table (created by Provider)
    in Provider (created by TablePfProvider)
    in TablePfProvider (created by DSTable)
    in div (created by DSTable)
    in DSTable (created by ObjectClassesTable)
    in div (created by ObjectClassesTable)
    in ObjectClassesTable (created by Schema)
    in div (created by Schema)
    in div (created by TabPane)
    in Transition (created by Fade)
    in Fade (created by TabPane)
    in TabPane (created by Schema)
    in div (created by TabContent)
    in TabContent (created by Schema)
    in div (created by Schema)
    in TabContainer (created by Uncontrolled(TabContainer))
    in Uncontrolled(TabContainer) (created by Schema)
    in div (created by Schema)
    in div (created by Schema)
    in div (created by Schema)
    in Schema

rebased onto 084799802b14b0fe7688d2d7a586fb59e4402470

4 years ago

On FF there is no space between the checkbox and the label for user-defined classes.

Fixed.

When adding an objectclass, the tab just starts reloading, but doesn't say its saving, just says that the page is reloading. This is confusing
When I click on "view objectclass" it also showing the loading page. It should just open the modal, not reload the entire tab every time I want to look at an objectclass. So there's some weird toggling going on for these tasks. Also viewing an objectclass does not show the allowed attributes.
Same issue when deleting an objectclass. When you choose delete the pages just says "Loading schema". Then a notification finally pops up saying the delete was successful.

I agree, it's a bit confusing. I've split the spinners to 3 kinds: global, table, modal.

On the objectclass table if I reset the page size the browser crashes (for the Attribute table it works correctly)

Works for me but I've added an additional precaution check.

Please, review.

For objectclasses and attributes I still don't see a space between the checkbox and the label Only Non-standard Schema (attributes with X-ORIGIN: "user defined")

Everything else is good!

rebased onto 2ebdd30

4 years ago

Pull-Request has been merged by spichugi

4 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/3891

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago