Group Details Private

administrators

  • RE: Client und Contact über eine API Abfrage erstellen

    :pepehi: @konstantin

    es gibt dazu 2 Möglichkeiten.

    category.create

    {
        "jsonrpc": "2.0",
        "method": "cmdb.category.save",
        "params": {
            "apikey": "apikey",
            "language": "en",
            "category": "C__CATG__CONTACT",
            "object": 1122704399,
            "data": {
                "contact": 14,
                "role": 1
            }
        },
        "id": 1
    }
    

    object.create with categories

    {
      "id": 1,
      "version": "2.0",
      "method": "cmdb.object.create",
      "params": {
        "type": "C__OBJTYPE__SERVER",
        "title": "MyLittleServer",
        "categories": {
          "C__CATG__CONTACT": [
            {
                "contact": 14,
                "role": 1
            }
          ],
          "C__CATG__MODEL": [
            {
              "serial": "1337"
            }
          ]
        },
        "apikey": "h3md6u3y",
        "language": "en"
      }
    }
    
    posted in Entwicklung
  • RE: Switch Ports Sortierung

    Hey @StefanP74

    ich war ein wenig fleißig und habe etwas erarbeitet 😉 Dieses mal betrifft es aber ein paar mehr Zeilen - ich glaube es ist einfacher die komplette Datei zu tauschen. Leider ist es im Forum nicht möglich die ganze Datei hochzuladen...

    /**
     * i-doit cabling visualization javascript base class.
     *
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    window.Cabling = Class.create({
        $element:      null,
        data:          null,
        cache:         null,
        svg:           null,
        vis:           null,
        zoom:          null,
        options:       {},
        indexMapping:  [],
        rootContainer: {
            height:   0,
            matching: []
        },
    
        getOptions: function () {
            return this.options;
        },
    
        getOption: function (option) {
            return this.options[option];
        },
    
        setOption: function (option, value) {
            this.options[option] = value;
    
            return this;
        },
    
        getSelectedElements: function () {
            // This method should be used to get all selected cable paths.
            // this.svg.selectAll('.selected');
        },
    
        initialize: function ($el, data, options) {
            var that = this;
    
            that.$element = $el;
            that.data = data || [];
            that.options = {
                authEdit:               false, // Defines if the cabling view will allow any editing.
                minZoomLevel:           0.1,   // Defines the minimal zoom level.
                maxZoomLevel:           1.5,   // Defines the maximal zoom level.
                objectTypeData:         {},    // JSON with all necessary object type data (name, color, ...).
                connectorTypeData:      {},    // JSON with all necessary connector type data (name, color, ...).
                objectTypeFilter:       [],    // Array pf object types, that shall not be displayed.
                onAfterProcess:         null,  // 'Complete' event for when the rendering has finished.
                onObjSelect:            null,  // Click event for a object node.
                onObjUnselect:          null,  // Event for when a object gets unselected.
                onCableSelect:          null,  // Click event for a cable.
                onConnectorSelect:      null,  // Click event for a connector.
                onConnectorUnselect:    null,  // Event for when a connector gets unselected.
                onObjAcceptDrag:        null,  // Event for when a object gets unselected.
                onObjAbortDrag:         null,  // Event for when a object gets unselected.
                width:                  null,  // This can be used to change the viewpoints width. The SVG element will always remain 100%x100%.
                height:                 null,  // This can be used to change the viewpoints height. The SVG element will always remain 100%x100%.
                undefinedConnectorType: {
                    color: '#fff',
                    title: '-'
                },                             // Default 'connector type' object.
                undefinedObjectType:    {
                    color: '#fff',
                    title: '-'
                },                             // Default 'object type' object.
                nodeWidth:              150,   // Define the node width.
                nodeHeight:             20,    // Define the node heigt.
                nodeMarginX:            25,    // Define the horizontal margin between nodes.
                nodeMarginY:            25,    // Define the vertical margin between nodes.
                displayWiring:          false, // Define if the internal wiring shall be displayed (object boxes will get transparent).
                showCableLabels:        false, // Define if cables shall be displayed.
                clickableConnectors:    false  // Define if connectors shall be clickable.
            };
    
            that.rootContainer = {
                height:   0,
                matching: []
            };
    
            // Setting the default width and height.
            that.options.width = that.$element.getWidth();
            that.options.height = that.$element.getHeight() + 16;
    
            Object.extend(that.options, options || {});
    
            that.svg = d3.select($el).append('svg')
                         .attr('width', that.options.width)
                         .attr('height', that.options.height);
    
            that
                .svg.append('rect')
                .attr('width', that.options.width)
                .attr('height', that.options.height)
                .style('fill', 'none')
                .style('pointer-events', 'all');
    
            // Here we set the <g> after the <rect>, this is necessary for dragging and zooming but still clicking elements inside <g>.
            that.vis = this.svg.append("g");
    
            that.zoom = d3.zoom()
                .scaleExtent([
                    that.options.minZoomLevel,
                    that.options.maxZoomLevel
                ])
                .on('zoom', function () {
                    that.vis.attr('transform', d3.event.transform);
                });
    
            that.svg
                .call(that.zoom)
                .call(that.zoom.transform, d3.zoomIdentity.translate(that.options.width / 2, that.options.height / 2));
    
            this.appendStyle();
    
            return this;
        },
    
        appendStyle: function () {
            // This method is necessary to include the SVG styles - this will be used in the SVG export.
            var defs   = this.svg.select('defs'),
                isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
    
            if (defs.node() === null) {
                defs = this.svg.append('defs');
    
                defs.append('style').attr('type', 'text/css').text(
                    ".cabling-object { \
                        fill: none;\
                        stroke: #444;\
                        stroke-width: 1px;\
                    }\
                    text {\
                        font-family: \"Helvetica Neue\", \"Lucida Grande\", \"Tahoma\", Arial, serif;\
                        font-size: 11px;\
                        paint-order: stroke;\
                        stroke: transparent;\
                        stroke-width: 0;\
                        fill: #000;\
                    }\
                    text.connector-left-title,\
                    text.connector-right-title {\
                        stroke-width: 5px;\
                        stroke: transparent;\
                    }\
                    text.connector-left-title.stroked,\
                    text.connector-right-title.stroked {\
                        " + (isIE11 ? "stroke-width: 0;" : "stroke-width: 5px;") + "\
                        stroke: #fff;\
                    }\
                    text.title,\
                    .linkname text,\
                    .linkname.clicked rect,\
                    .clicked rect.title {\
                        fill: #fff;\
                    }\
                    text.title {\
                        font-weight: bold;\
                    }\
                    .linkname rect,\
                    .linkname.clicked text {\
                        fill: #000;\
                    }\
                    rect.title,\
                    .clicked text.title {\
                        fill: #222;\
                    }\
                    circle.connector {\
                        stroke: rgba(0, 0, 0, 0.75);\
                        stroke-width: 1;\
                    }\
                    circle.connector-inner {\
                        fill: rgba(0, 0, 0, 0.75);\
                        stroke: none;\
                    }\
                    path {\
                        fill: none;\
                        stroke: #555;\
                        stroke-width: 2;\
                    }"
                );
            }
        },
    
        textFormat: function (text, width) {
            var result = text;
    
            if (width <= 0) {
                return '';
            }
    
            d3.select(this).text(result);
    
            while (this.getComputedTextLength() > width) {
                result = result.substring(0, (result.length - 2));
                d3.select(this).text(result);
            }
    
            if (result !== text && width > 2) {
                result += '..';
            }
    
            return result;
        },
    
        clearCanvas: function () {
            this.vis.selectAll('*').remove();
    
            this.rootContainer = {
                height:   0,
                matching: []
            };
        },
    
        responsive: function () {
            this.options.width = this.$element.getWidth();
            this.options.height = this.$element.getHeight() + 16;
    
            return this;
        },
    
        preProcess: function () {
            return this;
        },
    
        process: function () {
            this.indexMapping = [];
    
            return this.preProcess().processSide('left').processSide('right').postProcess();
        },
    
        processSide: function (dir) {
            var that    = this,
                invertX = (dir === 'right'),
                cache = this.data[dir];
    
            // @see CABLING-49 Implement proper calculation for 'separation'.
            var tree = d3.tree()
                .separation((a, b) => Math.max(1, (a.children || []).length, (b.children || []).length))
                .nodeSize([
                    (that.options.nodeHeight + that.options.nodeMarginY),
                    (that.options.nodeWidth + that.options.nodeMarginX)
                ]);
    
            var root = d3.stratify()(cache)
                .sort(function (a, b) {
                    // First sort by 'connected-index' to keep internally wired connectors near by each other.
                    if (dir === 'right' && a.data.siblingId && b.data.siblingId && a.data.siblingId !== b.data.siblingId) {
                        // @see CABLING-58 Use the newly created indexMapping to find the proper index.
                        return this.indexMapping.findIndex((d) => d == a.data.siblingId) - this.indexMapping.findIndex((d) => d == b.data.siblingId);
                    }
    
                    // @see  CABLING-36  Any "unconnected" connector will be moved down, so that no wires cross each other.
                    if (a.data.siblingId && !b.data.siblingId) {
                        return -1;
                    }
    
                    if (!a.data.siblingId && b.data.siblingId) {
                        return 1;
                    }
    
                    // @see CABLING-19 Following code will try to sort the connectors in a more natural way!
    
                    // First we split by "non-word" characters (like dots, slashes etc.).
                    var aParts = a.data.title.split(/\W/),
                        bParts = b.data.title.split(/\W/),
                        minParts = Math.min(aParts.length, bParts.length), comparison, i;
    
                    for (i = 0; i < minParts; i++) {
                        if (isNumeric(aParts[i]) && isNumeric(bParts[i])) {
                            comparison = aParts[i] - bParts[i];
                        } else {
                            comparison = aParts[i].localeCompare(bParts[i]);
                        }
    
                        if (comparison !== 0) {
                            return comparison;
                        }
                    }
    
                    // If nothing worked out, use the default:
                    return a.data.title.localeCompare(b.data.title);
                }.bind(this));
    
            if (dir === 'left') {
                this.indexMapping = root.children.map((d) => d.data.id);
            }
    
            var connectorTranslate = function (d) {
                if (that.options.clickableConnectors) {
                    if (d.parent === null || d.parent && d.parent.id === 'root') {
                        return 'translate(' + (invertX ? 5 : -5) + ',0)';
                    }
    
                    if (d.data.inner) {
                        return 'translate(' + (invertX ? -5 : that.options.nodeWidth+5) + ',0)';
                    } else {
                        return 'translate(' + (invertX ? that.options.nodeWidth+5 : -(that.options.nodeWidth+5)) + ',0)';
                    }
                } else {
                    if (d.parent === null || d.parent && d.parent.id === 'root') {
                        return 'translate(0,0)';
                    }
    
                    if (d.data.inner) {
                        return 'translate(' + (invertX ? 0 : that.options.nodeWidth) + ',0)';
                    } else {
                        return 'translate(' + (invertX ? that.options.nodeWidth : -that.options.nodeWidth) + ',0)';
                    }
                }
            };
    
            var linkData = tree(root).links();
    
            var cable = that.vis
                .selectAll(".cable.cable-" + dir)
                .data(linkData);
    
            cable
                .enter().append("path")
                .style("opacity", 0)
                .attr("class", "cable cable-" + dir);
    
            // After the link data is assigned, we reduce the data to only hold cable information.
            linkData = linkData.filter(function (d) {
                return d.source.id !== 'root' && d.source.data.outer;
            });
    
            // @see  CABLING-35  Show internal cabling
            that.vis
                .selectAll('.internal-link.internal-link-' + dir)
                .data((root.children || []).filter((d) => d.data.wiredToItself))
                .enter()
                .append("path")
                .style("opacity", 0)
                .attr('class', 'internal-link internal-link-' + dir)
                .attr('d', function (d) {
                    const connection = (root.children || []).find(function (conn) { return conn.id == d.data.connectorId});
    
                    if (!connection) {
                        return '';
                    }
    
                    d.y -= 20;
                    var xBetween = d.y + 30;
                    const yBetween = ((d.x + connection.x) / 2);
    
                    // Mirror the coordinates for the left side.
                    if (dir === 'left') {
                        d.y *= -1;
                        xBetween *= -1;
                    }
    
    
                    return 'M' + d.y + ',' + d.x +
                           ' C' + xBetween + ',' + d.x + ' ' + xBetween + ',' + yBetween + ' ' + xBetween + ',' + yBetween;
                })
                .interrupt()
                .transition().duration(500)
                .transition().duration(250)
                .style("opacity", 1);
    
            var cableLabel = that.vis
                .selectAll(".linkname.linkname-" + dir)
                .data(linkData)
                .enter()
                .append("g")
                .style("opacity", 0)
                .attr("class", "linkname linkname-" + dir)
                .attr('data-id', function (d) {
                    return d.source.data.cableId;
                });
    
            that.vis
                .selectAll(".cable.cable-" + dir)
                .classed('cable-root', function (d) {
                    return (d.source.id === 'root');
                })
                .interrupt().transition().duration(500)
                .attr("d", function (d) {
                    var fromX  = (d.source.y + (that.options.showCableLabels ? 50 : 125)),
                        fromX2 = (fromX+20),
                        fromX3 = (fromX+40),
                        fromY  = d.source.x,
                        toX    = (d.target.y + (that.options.showCableLabels ? 50 : 125)),
                        toY    = d.target.x;
    
                    if (d.target.data.doubling) {
                        toX += 20;
                    }
    
                    if (!invertX) {
                        fromX *= -1;
                        fromX2 *= -1;
                        fromX3 *= -1;
                        toX *= -1;
                    }
    
                    return "M" + fromX + "," + fromY +
                           "C" + fromX2 + "," + fromY + " " + fromX2 + "," + toY + " " + fromX3 + "," + toY +
                           "L" + toX + "," + toY;
                })
                .transition().duration(250)
                .style("opacity", 1)
                .style('stroke-dasharray', function (d) {
                    if (d.target.data.doubling) {
                        return '2,2';
                    }
    
                    return null;
                });
    
            cable
                .exit()
                .interrupt().transition().duration(500)
                .style("opacity", 0)
                .remove();
    
            cableLabel
                .append('rect')
                .attr('class', 'mouse-pointer')
                .attr('height', 14)
                .attr('width', 125)
                .attr('data-id', function (d) {
                    return d.source.cableId
                })
                .on('click', that.selectCableObject.bind(this));
    
            cableLabel
                .append('text')
                .attr('class', 'mouse-pointer')
                .attr('dy', 10)
                .attr('x', 62.5)
                .style('text-anchor', 'middle')
                .text(function (d) {
                    return d.source.data.cableTitle;
                })
                .on('click', that.selectCableObject.bind(this));
    
            that.vis
                .selectAll(".linkname.linkname-" + dir)
                .classed('hide', !that.options.showCableLabels)
                .interrupt().transition().duration(550)
                .style('opacity', (that.options.showCableLabels ? 1 : 0))
                .attr('transform', function (d) {
                    var translateX = d.source.y,
                        translateY = d.source.x;
    
                    if (invertX) {
                        translateX = translateX + 85;
                    } else {
                        translateX = translateX + that.options.nodeWidth + 65;
                    }
    
                    if (d.source.parent.id === 'root') {
                        translateX = translateX - 65;
                    }
    
                    return 'translate(' + (invertX ? '' : '-') + translateX + ',' + translateY + ')';
                });
    
            var node = that.vis
                .selectAll(".node.node-" + dir)
                .data(root.descendants());
    
            var nodeEnter = node
                .enter().append("g")
                .style("opacity", 0)
                .attr("class", "node node-" + dir)
                .classed('root', function (d) {
                    return d.parent === null;
                })
                .attr('data-id', function (d) {
                    return d.id;
                });
    
            // This will append newly created and already existing nodes.
            this.vis
                .selectAll('.node.node-' + dir)
                .transition().duration(500)
                .style("opacity", 1)
                .attr("transform", function (d) {
                    var translateX = d.y,
                        translateY = d.x;
    
                    if (d.parent === null) {
                        return "translate(" + (invertX ? 0 : -that.options.nodeWidth) + "," + translateY + ")";
                    }
    
                    if (d.parent && d.parent.id === 'root') {
                        return "translate(" + (invertX ? that.options.nodeWidth : -that.options.nodeWidth) + "," + translateY + ")";
                    }
    
                    if (d.data.inner) {
                        if (!invertX) {
                            translateX = -(translateX + that.options.nodeWidth);
                        }
                    } else {
                        if (!invertX) {
                            translateX = -(translateX + that.options.nodeWidth) + (that.options.nodeWidth + that.options.nodeMarginX);
                        } else {
                            translateX -= that.options.nodeMarginX;
                        }
                    }
    
                    return "translate(" + translateX + "," + translateY + ")";
                });
    
            node.exit()
                .interrupt().transition().duration(500)
                .style("opacity", 0)
                .remove();
    
            var container = nodeEnter
                .filter(function (d) {
                    // Only draw boxes for the "root" element and "left" connectors.
                    return d.parent === null || d.data.inner;
                })
                .each(function (d) {
                    // Prepare some data for each node.
                    d.childNum = (d.children ? d.children.length : 1);
    
                    d.minX = d.y;
                    d.maxX = d.y + (that.options.nodeWidth * 2);
    
                    if (d.children) {
                        d.minY = d.children.first().x;
                        d.maxY = d.children.last().x + that.options.nodeHeight;
                    } else {
                        d.minY = d.x;
                        d.maxY = d.x + that.options.nodeHeight;
                    }
    
                    d.width = d.maxX - d.minX;
                    d.height = d.maxY - d.minY;
                    d.translateX = 0;
                    d.translateY = -(d.height / 2);
    
                    if (d.parent === null) {
                        if (that.rootContainer.height < d.height) {
                            that.rootContainer.height = d.height;
                            that.rootContainer.translateX = d.translateX;
                            that.rootContainer.translateY = d.translateY;
                        }
    
                        d.width = that.options.nodeWidth;
                    }
                });
    
            container
                .append('rect')
                .attr('class', 'title mouse-pointer')
                .attr('width', function (d) {
                    return d.width;
                })
                .attr('height', function (d) {
                    return 20;
                })
                .attr('data-object-id', function (d) {
                    return d.data.objectId;
                })
                .attr('transform', function (d) {
                    var translateX = d.translateX,
                        translateY = d.translateY;
    
                    if (d.parent && d.parent !== 'root') {
                        if (!invertX) {
                            translateX = -that.options.nodeWidth;
                        }
                    }
    
                    return 'translate(' + translateX + ',' + (translateY - 20) + ')';
                })
                .on('click', that.selectObject.bind(this));
    
            container
                .append('rect')
                .attr('class', 'body')
                .attr('width', function (d) {
                    return d.width;
                })
                .attr('height', function (d) {
                    return d.height;
                })
                .attr('data-conn', function (d) {
                    return d.data.title;
                })
                .attr('transform', function (d) {
                    var translateX = d.translateX,
                        translateY = d.translateY;
    
                    if (d.parent && d.parent !== 'root') {
                        if (!invertX) {
                            translateX = -that.options.nodeWidth;
                        }
                    }
    
                    return 'translate(' + translateX + ',' + translateY + ')';
                })
                .attr('fill', function (d) {
                    if (!that.options.objectTypeData.hasOwnProperty(d.data.objectTypeId)) {
                        return that.options.undefinedObjectType.color;
                    }
    
                    return that.options.objectTypeData[d.data.objectTypeId].color || that.options.undefinedObjectType.color
                });
    
            nodeEnter
                .filter(function (d) {
                    return d.parent !== null;
                })
                .append('circle')
                .attr('data-connector-id', function (d) {
                    return d.data.id;
                })
                .attr('class', 'connector connector-' + dir)
                .attr('transform', connectorTranslate)
                .on('click', that.selectConnector.bind(this));
    
            nodeEnter
                .filter(function (d) {
                    return d.parent !== null;
                })
                .append('circle')
                .attr('data-connector-id', function (d) {
                    return d.data.id;
                })
                .style('opacity', 0)
                .attr('class', 'connector-inner hide connector-inner-' + dir)
                .attr('r', 4)
                .attr('transform', connectorTranslate)
                .on('click', that.selectConnector.bind(this));
    
            that.vis
                .selectAll('circle.connector.connector-' + dir)
                .classed('mouse-pointer', that.options.clickableConnectors)
                .interrupt().transition().duration(500)
                .attr('r', (that.options.clickableConnectors ? 10: 5))
                .attr('fill', function (d) {
                    var connectorType = that.options.connectorTypeData[d.data.connectorType];
    
                    return connectorType ? connectorType.color : that.options.undefinedConnectorType.color;
                })
                .attr('transform', connectorTranslate)
                .style('stroke-width', (that.options.clickableConnectors ? 3 : 1));
    
            that.vis
                .selectAll('circle.connector-inner.connector-inner-' + dir)
                .classed('mouse-pointer', that.options.clickableConnectors)
                .interrupt().transition().duration(500)
                .attr('transform', connectorTranslate)
                .style('opacity', (that.options.clickableConnectors ? 1 : 0));
    
            container
                .filter(function (d) {
                    return (d.parent !== null || invertX);
                })
                .append('text')
                .attr('class', 'title mouse-pointer')
                .attr("dy", function (d) {
                    if (d.id === 'root') {
                        return -((that.rootContainer.height / 2) + 7);
                    }
    
                    return -((d.height / 2) + 7);
                })
                .attr("x", function (d) {
                    if (d.parent === null) {
                        return 0
                    }
    
                    return invertX ? that.options.nodeWidth : 0;
                })
                .style("text-anchor", 'middle')
                .text(function (d) {
                    return d.data.objectTitle;
                })
                .on('click', that.selectObject.bind(this));
    
            nodeEnter
                .append("text")
                .attr('class', 'connector-' + dir + '-title')
                .attr("dy", 3)
                .attr("x", function (d) {
                    if (d.parent !== null && d.parent.id === 'root') {
                        return invertX ? -25 : 25;
                    }
    
                    if (d.data.outer) {
                        return invertX ? that.options.nodeWidth-10 : -(that.options.nodeWidth-10);
                    }
    
                    return invertX ? 10 : (that.options.nodeWidth-10);
                })
                .style("text-anchor", function (d) {
                    if (d.parent !== null && d.parent.id === 'root' || d.data.outer) {
                        return invertX ? 'end' : 'start';
                    }
    
                    return invertX ? "start" : "end";
                })
                .text(function (d) {
                    return that.textFormat.call(this, d.data.title, (that.options.nodeWidth - 15));
                });
    
            // @see CABLING-56 Show the full title when hovering connector.
            nodeEnter.append('title').text(d => d.data.title);
    
            // After all calculations have been done, we set the root height.
            this.vis.selectAll('g.root rect.title')
                .attr('transform', function (d) {
                    return 'translate(' + that.rootContainer.translateX + ',' + (that.rootContainer.translateY - 20) + ')';
                });
    
            this.vis.selectAll('g.root rect.body')
                .attr('height', function () {
                    return that.rootContainer.height;
                })
                .attr('transform', function (d) {
                    return 'translate(' + that.rootContainer.translateX + ',' + that.rootContainer.translateY + ')';
                });
    
            this.vis.selectAll('rect.body')
                .transition().duration(250)
                .style('opacity', (this.options.displayWiring ? 0.5 : 1));
    
            this.vis
                .selectAll(".cable.cable-root.cable-" + dir)
                .each(function (d) {
                    d.fromX = (invertX ? '' : '-') + 100;
                    d.fromY = d.target.x;
                    d.toX = (invertX ? '' : '-') + (d.target.y + (that.options.showCableLabels ? 50 : 125));
                    d.toY = d.target.x;
    
                    // If a connector is internally wired, we draw the line to the middle (to visually "connect" them).
                    if (d.target.data.wired) {
                        d.fromX = 0; // -25;
                    }
    
                    // If a root connector is not connected, only show a small "stump".
                    if (!d.target.children) {
                        d.toX = parseInt((invertX ? '' : '-') + 200);
                    }
                })
                .attr('data-index', (d, i) => i)
                .interrupt().transition().delay(500).duration(250)
                .style('opacity', 1)
                .attr('d', function (d) {
                    // @see  CABLING-35  Cut the 'self wired' connectors more short
                    if (d.target.data.wiredToItself || false) {
                        if (dir === 'right') {
                            d.toX -= 45;
                        } else {
                            d.toX += 45;
                        }
                    }
    
                    if (invertX && d.target.data.wired) {
                        const index = this.indexMapping.findIndex((i) => i == d.target.data.siblingId);
                        const $selection = this.vis.select('[data-index="' + index + '"]');
    
                        if (index >= 0 && $selection.size()) {
                            d.fromY = $selection.data()[0].fromY;
    
                            return "M" + d.fromX + "," + d.fromY +
                                   "C" + (d.fromX+20) + "," + d.fromY + " " + (d.fromX+20) + "," + d.toY + " " + (d.fromX+40) + "," + d.toY +
                                   "L" + d.toX + "," + d.toY;
                        }
                    }
    
                    return "M" + d.fromX + "," + d.fromY +
                           "L" + d.toX + "," + d.toY;
                }.bind(this));
    
            this.vis.selectAll('.connector-' + dir + '-title')
                .classed('stroked', this.options.displayWiring);
    
            return this;
        },
    
        postProcess: function () {
            if (Object.isFunction(this.options.onAfterProcess)) {
                this.options.onAfterProcess.call(this);
            }
    
            return this;
        },
    
        setData: function (data) {
            this.data = data;
    
            return this;
        },
    
        selectObject: function (d) {
            var $object = this.vis.selectAll('[data-id="' + d.id + '"]');
    
            if (!$object.classed('clicked')) {
                this.vis.selectAll('.clicked').classed('clicked', false);
    
                $object.classed('clicked', true);
    
                if (Object.isFunction(this.options.onObjSelect)) {
                    this.options.onObjSelect.call(this, d);
                }
            }
    
            return this;
        },
    
        selectCableObject: function (d) {
            var $object = this.vis.selectAll('[data-id="' + d.source.data.cableId + '"]');
    
            if (!$object.classed('clicked')) {
                this.vis.selectAll('.clicked').classed('clicked', false);
    
                $object.classed('clicked', true);
    
                if (Object.isFunction(this.options.onCableSelect)) {
                    this.options.onCableSelect.call(this, d);
                }
            }
    
            return this;
        },
    
        selectConnector: function (d) {
            var $connector = this.vis.select('circle.connector-inner[data-connector-id="' + d.data.id + '"]');
    
            if (! this.options.clickableConnectors) {
                return;
            }
    
            $connector.classed('hide', !$connector.classed('hide'));
    
            if (Object.isFunction(this.options.onConnectorSelect)) {
                this.options.onConnectorSelect.call(this, d);
            }
    
            return this;
        },
    
        unselectConnectors: function (d) {
            var data = this.vis.selectAll('.connector-inner:not(.hide)').classed('hide', true).data();
    
            if (Object.isFunction(this.options.onConnectorUnselect)) {
                this.options.onConnectorUnselect.call(this, data);
            }
    
            return this;
        },
    
        unselectObject: function (data) {
            if (Object.isFunction(this.options.onObjUnselect)) {
                this.options.onObjUnselect.call(this, data);
            }
    
            return this;
        },
    
        center: function () {
            var translateX = (this.options.width / 2),
                translateY = (this.options.height / 2);
    
            this.vis.attr('transform', "translate(" + translateX + "," + translateY + ")");
    
            this.svg.select('rect').call(this.zoom.transform, d3.zoomIdentity.translate(translateX, translateY));
    
            return this;
        }
    });
    

    Die Datei müsste mit diesem neuen Inhalt überschrieben werden 😄

    Das dürfte weiterhelfen!

    4b3a1091-f515-4bae-bfc1-f35baeca93b8-image.png

    VG Leo

    posted in Betrieb
  • RE: Switch Ports Sortierung

    Hey @StefanP74

    freut mich das ich dir damit weiterhelfen konnte 😄 Bzgl. dem "Chaotische Verkabelung" Problem - ist das erst durch den Fix geschehen? Denn genau den zuständigen Code habe ich angepasst...

    Wäre natürlich schön wenn der Fix nur Probleme löst anstatt auch neue zu schaffen 😞

    Ich schaue mal ob ich auch dieses Problem nachvollziehen (und ggf. fixen) kann

    VG Leo

    edit

    3479e8b6-ff8a-4e86-b34a-497faf203a50-image.png

    Okay, ich kann es nachstellen... Mal sehen ob ich das auch noch hinbekomme 😄

    edit 2

    Ich glaube auch hier habe ich das Problem gefunden... Es ist aber etwa schwieriger zu lösen 😕 Es ist nämlich so dass die toIndex Werte vom Backend vorbereitet werden... Die Sortierung passiert dann aber im Frontend und ändert die Indexe, sodass diese dann nicht mehr korrekt sind.
    Mal sehen wie ich das löse 😄

    posted in Betrieb
  • RE: Switch Ports Sortierung

    Hey @StefanP74

    ich glaube ich habe etwas gefunden - könntest du das vielleicht kurz bei dir ausprobieren und schauen ob es ggf. zu unerwünschten Seiteneffekten kommt? Ich habe das mit der Add-on Version 1.4 geprüft.

    Dazu bitte in die folgende Datei navigieren (ausgehend vom i-doit Verzeichnis) src/classes/modules/cabling/assets/js/cabling.js

    Hier auf Zeile 254 steht folgendes:

    // Then sort by "toIndex" to keep internally wired connectors near by each other.
    if (a.data.toIndex && b.data.toIndex) {
        return a.data.toIndex - b.data.toIndex
    }
    

    Das bitte mal mit folgender kleinen Änderung anpassen:

    // Then sort by "toIndex" to keep internally wired connectors near by each other.
    if (a.data.toIndex && b.data.toIndex && a.data.toIndex !== b.data.toIndex) {
        return a.data.toIndex - b.data.toIndex
    }
    

    Das Problem ist nämlich das die Ausgänge alle auf den gleichen Eingang zeigen - bedeutet hier das der a.data.toIndex und b.data.toIndex den identischen Wert beinhalten. Das Ergebnis der Sortierung ist in diesem Fall 0 was so viel heißt wie: "Bleib wo du bist".

    In diesem Fall soll aber die Sortierung nach Namen übernehmen. Aus diesem Grund ergänzen wir die Bedingung um a.data.toIndex ist ungleich b.data.toIndex.

    Wenn das soweit passt würde ich das im Code übernehmen sodass diese Anpassung in der nächsten Version landet 🙂

    Viele Grüße
    Leo

    posted in Betrieb
  • RE: Duplizieren bei einzigartigen Attribut

    :pepehi: @StefanP74

    du kannst in der Verwaltung unter Import konfigurieren, ob die Kategorie oder nur der Wert bei Fehlern nicht importiert werden.
    5d624f03-5aec-4341-bc98-95a3e9c95da6-image.png

    posted in Betrieb
  • RE: SNMP Community hinzufügen

    :pepehi: @GeoItsm

    hier muss unterschieden werden. Es gibt den JDisc import der Daten, die via JDisc erfasst werden, in i-doit importiert.
    Außerdem gibt es in i-doit noch die SNMP Kategorie die eigenständig Daten erfassen kann.

    Für die JDisc konfig hab ich diesen "alten" Link gefunden. Ggf. hilft dieser -> https://jdisc.com/2021/01/03/snmp-custom-data-collection/

    Für i-doit schau mal hier -> http://localhost:8001/de/automatisierung-und-integration/snmp.html

    posted in Allgemein
  • RE: i-diary unter Linux ausführen (z.B. über Wine)

    :pepehi: @RAG

    ich habe dazu bisher nichts gelesen oder gehört.

    posted in Betrieb
  • RE: Umgang mit Protokollen bei Wartungen

    Hallo @StefanS

    Vielen dank für deinen Use-Case, würdest du uns das bitte noch mal offiziell als Feature Feedback an https://help.i-doit.com/ schicken?

    Viele Grüße
    Leo

    posted in Betrieb
  • RE: Switch Ports Sortierung

    Hallo @StefanP74

    ich glaube genau dieser Fall wird aktuell nicht berücksichtigt 🤔

    Hat ein Eingang mehrere Ausgänge, dann werden zusätzlich die Ausgänge mit Abhängigkeit zum jeweiligen Eingang, ebenso sortiert.

    Ich werde mir das aber noch mal lokal nachbauen und anschauen. Vielleicht lässt es sich ja doch noch irgendwie einbauen ohne etwas anderes kaputt zu machen 😉

    Viele Grüße
    Leo

    posted in Betrieb