---
# System prepended metadata

title: P1935 UI

---

# P1935 UI
## Code Structure
* efo
    * static
      * network_topology.js
	    有call到listServices()
      - request.js
	    listServices() call /api/services
    * efo
      * api.py
	    call efo.get_service_status()
      * efo.py
	    get_service_status(cluster, namespace)
	    call adapter2.py裡的get_service_status


Problem
* Service function chain: check if only show default cluster?

## Tasks
![](https://i.imgur.com/6LNUQVQ.png)

![](https://i.imgur.com/vvTJO29.png)


1. operator/operator.html字改成Service Topology
![](https://i.imgur.com/kW1kvZm.png)

2. 在api.py裡把list_services()多加registry_svcs
    ```javacript=
    # list services (network topology)
    @bp.route('/services', methods=["GET"])
    @login_required
    def list_services():
        svcs, status_code = efo.get_service_status(current_user.id)
        return make_response(jsonify(svcs), status_code)
    ```

3. 在/static/request.js 連結list_appstores, list_branchstores
    ```javascript=
    // new function
    function listStores() {

    const branch_httpRequest = new XMLHttpRequest();
    var branchs = [];
    branch_httpRequest.onreadystatechange = function() {
            if (this.readyState === XMLHttpRequest.DONE) {
                branch_resp = JSON.parse(this.response);
            for (var i = 0; i < branch_resp.length; i++){
               branchs.push(branch_resp[i]["name"]);
               branchs.push(branch_resp[i]["machine_name"]);
               branchs.push(branch_resp[i]["cluster_name"]);
               branchs.push(branch_resp[i]["role"]);
               branchs.push(branch_resp[i]["ip"]);
               branchs.push(branch_resp[i]["port"]);
               branchs.push(branch_resp[i]["image_list"]);
               branchs.push(branch_resp[i]["total_package_size"]);
               branchs.push(branch_resp[i]["available_size"]);
            }
            }
    }
        branch_httpRequest.open('GET', `/api/branchstores`, false);
        branch_httpRequest.send();

        
        const httpRequest = new XMLHttpRequest();
        var apps = [];
        app_httpRequest.onreadystatechange = function() {
            if (this.readyState === XMLHttpRequest.DONE) {
                app_resp = JSON.parse(this.response);
            for (var i = 0; i < app_resp.length; i++){
               apps.push(app_resp[i]["name"]);
               apps.push(app_resp[i]["machine_name"]);
               apps.push(app_resp[i]["cluster_name"]);
               apps.push(app_resp[i]["role"]);
               apps.push(app_resp[i]["ip"]);
               apps.push(app_resp[i]["port"]);
               apps.push(app_resp[i]["image_list"]);
               apps.push(app_resp[i]["total_package_size"]);
               apps.push(app_resp[i]["available_size"]);
            }
            }
    }     
        httpRequest.open('GET', `/api/appstores`, false);
        httpRequest.send();

        const merge = [...httpRequest.response, ...branch_httpRequest.response]
        if ( branch_httpRequest.status === 200 && httpRequest.status === 200){
            return merge;
          
            /*    
            return:
            [{
                 'name': ,
                 'machine_name': ,
                 'cluster_name': ,
                 'role:' ,
                 'image_list': ,
                 'total_package_size': ,
                 'available_size':
             }, {}]
            */
            }
    }
    ```


4. 在draw_network_topology():
    * 確保其他有用到listServices()的都有改到
    * services -> app_svcs
    * add registry_svcs
    
    ```javascript=
    function draw_network_topology(){
    response = listServices();
    var services = JSON.parse(response);
    store_response = listStores();
    var nodes = [];
    var edges = [];
    prefixes = [];
    var branchs = [];
       
    for ( var i = 0; i < services.length; i++){
        // check ip prefix
        prefix = services[i].ip.split('.')[0];
        if (!( prefixes.includes(prefix) )){
            prefixes.push(prefix);
            nodes.push({
                id: prefix+".",
                label: prefix+".",
                image: "https://i.ibb.co/WB3M1Cc/Edgemaster.png",
                shape: "image"
            });
        }
        // add service to topology
        nodes.push({
            id: services[i].ip,
            label: services[i].ip,
            image: "https://i.ibb.co/zszT32D/node.png",
            shape: "image"
        });
        edges.push({
            from: prefix+".",
            to: services[i].ip
        });
    }
    for ( i = 0 ; i < store_response.length ; i++){
        prefix = services[i].ip.split('.')[0];
        if ( store_response[i] == branch_resp[i] ) {
            branchs.push({
                id: store_response[i].ip,
                label: store_response[i].ip,
                image: "https://i.ibb.co/9WCtqkd/branch.png",
                shape: "image"
            });
            edges.push({
                from: prefix+".",
                to: store_response[i].ip
            });
        }
    }

    var data = {
        nodes: nodes,
        edges: edges,
        branchs: branchs,
    };
    var options = {};
    var container = document.querySelector('.network');
    network = new vis.Network(container, data, options);
    network.on('click',(obj)=>{
        document.querySelector('.report').innerHTML = obj.nodes[0];
        selectnode=obj.nodes[0];
        var list=""
        var listbranch=""
        for(i = 0; i < services.length; i++){
            if(selectnode==services[i].ip){
                list=services[i];
                break;
            }else{
                list=""
            }   
        }
        for(i = 0; i < store_response.length; i++){
            if(selectnode==store_response[i].ip){
                listbranch=store_response[i];
                break;
            }else{
                listbranch=""
            }   
        }
        const manis = getManifest(list.name);
        console.log(manis);
        list.description = "";
        manis.forEach(mani => {
            data = JSON.parse(mani.data);
            if ("annotations" in data.metadata) {
                list.description = data.metadata.annotations.description;
            }
        })
        const manis_b = getManifest(listbranch.name);
        console.log(manis_b);
        listbranch.description = "";
        manis_b.forEach(mani => {
            data = JSON.parse(mani.data);
            if ("annotations" in data.metadata) {
                listbranch.description = data.metadata.annotations.description;
            }
        })

    if (list==services[i]){
        var content='<img src="https://i.ibb.co/zszT32D/node.png" width="100">'
        content+=['<center><table class=topo_table>',
        '<tr>',
            '<td colspan="2" height="60"><span style="border-bottom: 2px #6C6C6C solid;font-size: x-large;">'+list.name+'</td>',
        '</tr>',
        '<tr>',
            '<td>IP</td>',
            '<td>'+list.ip+'</td>',
        '</tr>',
        '<tr>',
            '<td>port</td>',
            '<td>'+list.port+'</td>',
        '</tr>',
        '<tr>',
            '<td colspan="2" height="50"><span style="border-bottom: 2px #6C6C6C solid;">description</td>',
        '</tr>',
        '<tr>',
            '<td colspan="2">'+list.description+'</td>',
        '</tr>'
        ].join("\n");
    }else{
        var content = "";
    }
        
    if (listbranch==store_response[i]){
        var content='<img src="https://i.ibb.co/9WCtqkd/branch.png" width="100">'
        content+=['<center><table class=topo_table>',
        '<tr>',
            '<td colspan="2" height="60"><span style="border-bottom: 2px #6C6C6C solid;font-size: x-large;">'+list.name+'</td>',
        '</tr>',
        '<tr>',
            '<td>IP</td>',
            '<td>'+listbranch.ip+'</td>',
        '</tr>',
        '<tr>',
            '<td>port</td>',
            '<td>'+listbranch.port+'</td>',
        '</tr>',
        '<tr>',
            '<td colspan="2" height="50"><span style="border-bottom: 2px #6C6C6C solid;">description</td>',
        '</tr>',
        '<tr>',
            '<td colspan="2">'+listbranch.description+'</td>',
        '</tr>',
        '<button onclick="showpopup();" class=learn_more>more</button>'
        ].join("\n");
    }else{
        var content = "";
    }
    document.querySelector('.report').innerHTML = content;
        
    document.querySelector('.branch_name').innerHTML = listbranch.name;
    document.querySelector('.branch_ip').innerHTML = listbranch.ip;
    document.querySelector('.branch_port').innerHTML = listbranch.port;
    document.querySelector('.branch_image_list').innerHTML = listbranch.image_list;
    document.querySelector('.branch_total').innerHTML = listbranch.total_package_size;
    document.querySelector('.branch_available').innerHTML = listbranch.available_size;

    
    });
    }
    ````
* 參考node_topology.js

5. operator/simple.html
    ```javacript=
    <div class="report"></div>
      <div id=popup_box class=popup_box>
        <a onclick="closepopup();" class="popup_close" href="#">x</a>
        <h1 style="border-bottom:1px solid lightgray;display: flex;align-items: flex-end;margin-left: 10px;">Owner Node</h1>
        <div class="node_content">
          <img src="https://i.ibb.co/9WCtqkd/branch.png" width="250">
          <center><div class="node_name"></div></center>
        </div>
        <div class="node_list">
          <table class="node_table" text-align="center">
            <h2>Basic Information :</h2>
            <tr>
              <td>IP</td>
              <td><div class="branch_ip"></div></td>
            </tr>
            <tr>
              <td>Port</td>
              <td><div class="branch_port"></div></td>
            </tr>
	          <tr>
              <td>Image list</td>
              <td><div class="branch_image_list"></div></td>
            </tr>
            <tr>
              <td>Total package size</td>
              <td><div class="branch_total"></div></td>
            </tr>
	          <tr>
              <td>Available size</td>
              <td><div class="branch_available"></div></td>
            </tr>
          </table>
        </div>
      </div>
    </div>
    ```
6. UI介面
    * description部分印出private registry: role
        e.g. private registry: branchstore
    * Branchstore/Appstore圖示用不同顏色
    * 加more botton
        * Basic Information:
            表格:
            * ip
            * port
            * image_list
            * total_package_size
            * available_size
# Git操作
* 複製到自己的directory
複製到自己的/home/sherrylee
git clone https://github.com/dingyiyi0226/standard-p1935.git
* 若要用branch:
開branch並切到branch: git checkout -b sherrylee
每次改時確認一下是否在branch: git status
* 有人更新: git pull
* 改完想要push到github
git config --global user.name "xxxxx"
git config --global user.email xxxxx@example.com
git add .
git commit -m "xxxxx"
到branch: git push origin sherrylee
到master: git push origin master


