<commit_before>////////////////////////////////////////////////////////////
//  This file was authored by A. Leah Zulas             ////
//  It heavily utilizes D3 js                           ////
//  If retreives data using Ajax, from an express server////
//  Any questions about the below code should be sent to:///
//  alzulas@alzulas.com                                 ////
////////////////////////////////////////////////////////////

//Create CSV array and retreive cookie
var outPutCSV = [];
var myid = getCookie("userName");
//Use cookie to request data from the server, so long as cookie exists.
if (myid != ""){
    var dataPassed;
    $.ajax({
        type: "GET",
        url: "/RSSMresult/" + myid,
        async: false,
        success: function(dataPassed){
            outPutCSV = calculateScores(dataPassed); //collect data and put them into the CSV
            console.log(outPutCSV); //Correctly calculated data print to console so we can see it worked
            console.log("Get request complete");//verification that the data was retreieved.
        },
    });
}

    //d3.getElementById("myDiv").style.margin = "50px 10px 20px 30px";
    //This html just explains what the participant just did.
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("The measure you completed was designed to assess how you experience yourself when you are interacting with different significant others in your life or engaged in different roles.  More specifically, this questionnaire measures to what extent you experience satisfaction of 3 psychological needs in these different interactions.");
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("According to self-determination theory (Ryan & Deci, 2000), humans have three essential needs that if satisfied promote psychological well-being. These 3 needs are:");
    d3.select("body").append("li")
        .style("margin", "30px 50px 0px 50px")
        .text("Relatedness-which is the experience of intimacy and genuine connection with others.");
    d3.select("body").append("li")
        .style("margin", "10px 50px 0px 50px")
        .text("Competence-which is the experience of feeling effective and capable of achieving desired outcomes.");
    d3.select("body").append("li")
        .style("margin", "10px 50px 0px 50px")
        .text("Autonomy-which is the experience of self-determination, full willingness, and volition when carrying out an activity.");
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("");

//begins the process of printing scores.
//Common was to write JS, because any variables not wrapped in a function is available in the entire namespace of the website.
printScores();

function printScores(){
    //creat array of possible relationships
    //THIS IS ONE OF THE VARIABLES TO CHANGE IF YOU WANT TO ADD NEW RELATIONSHIPS.
    var relationship = ["Mother", "Father", "Romantic Partner", "Ex-Romantic Partner", "Sibling", "Close Friend", "Overall"];
    i = 0;//counter
    for (relation in relationship){ //Go through each relationship above and...
        standardResults(outPutCSV[i], outPutCSV[i+1], outPutCSV[i+2], relationship[relation]); //calculate info about it.
        //The above hands the next part of this the comp score, auto score, relation score, and the relationship name
        i = i+3;
        //it then progresses the counter to the next relationship in the CSV
    }
}

function getCookie(cname) { //This function retreives the participant ID, stored as a cookie
    var name = cname + "=";
    var ca = document.cookie.split(';'); //Ask for cookie, split by ;
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) { //looking for ID in cookie called "cname"
            return c.substring(name.length, c.length); //Return ID
        }
    }
    return ""; //No ID found, return empty string
}

function calculateScores(dataPassed){
    //Takes data from CSV off the server, calculates relavant scores, returns array
    var results = [];
    //Will be in the order of mother comp-auto-related then
    //father comp-auto-related then
    //romantic partner comp-auto-related then
    //ex comp-auto-related then
    //sibling comp-auto-related then
    //close friend
    //Below are necessary variables
    var currentComp = 0;
    var currentAuto = 0;
    var currentRelated = 0;
    var overallComp = 0;
    var overallAuto = 0;
    var overallRelated = 0;
    var compDenominator = 4*6;
    var autoDenominator = 4*6;
    var relatedDenominator = 4*6;
    var dataArray = dataPassed.split(","); //Takes CSV from the server, creates array
    //round counter. Because every 4th time through the data, scores are calculated
    var round = 0;
    //Relevant data beings at position 8 in the array from the server
    for (var i = 8; i < 95; i++){
        currentComp = currentComp + Number(dataArray[i]);//take current score for this relationship, add to previous
        overallComp = overallComp + Number(dataArray[i]);//Do for an overall score as well
        if(Number(dataArray[i])==0){
            //If there is nothing in this relationship, because they don't have one or never think of that person,
            //Then the overall score must have a different number to divide from
            compDenominator--;
        }
        //Go to next item in the array and repeat
        i++;
        currentAuto = currentAuto + Number(dataArray[i]);
        overallAuto = overallAuto + Number(dataArray[i]);
        if(Number(dataArray[i])==0){
            autoDenominator--;
        }
        //Go to next item in the array and repeat
        i++;
        currentRelated = currentRelated + Number(dataArray[i]);
        overallRelated = overallRelated + Number(dataArray[i]);
        if(Number(dataArray[i])==0){
            relatedDenominator--;
        }
        //Move forward round
        round++;
        if (round > 3){
            //If we have all relevant scores for this relationship, then calculate averages
            currentComp = currentComp/4;
            currentAuto = currentAuto/4;
            currentRelated = currentRelated/4;
            //Push these scores onto the results array
            results.push(currentComp);
            results.push(currentAuto);
            results.push(currentRelated);
            //Reset variables for next relationship
            currentAuto = 0;
            currentComp = 0;
            currentRelated = 0;
            round = 0;
            //Move forward past questions like "relationship type", "closeness" and a filler question
            i = i+3;
        }
    }
    //Once all relationship scores are calculated, an overall must be calculated
    overallComp = overallComp/compDenominator;
    overallAuto = overallAuto/autoDenominator;
    overallRelated = overallRelated/relatedDenominator;
    //Push these onto the results array
    results.push(overallComp);
    results.push(overallAuto);
    results.push(overallRelated);

    //return results to the ajax call
    return results;
}

function standardResults(compScore, autoScore, relateScore, relation){
    //Printing scores to the screen.
    if(relation == "Overall"){//Print overall scores last
        d3.select("body").append("H1")
            .style("margin", "30px 50px 0px 50px")
            .text("Your Overall RSSM Scores are: ");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your competence score is " + compScore);
        //These include the actal mean and SD for the population,
        //they go to a function to calculate where the participants score lies
        standardDeviationPrint(compScore, 3.97, .74, "competancy");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your autonomy score is " + autoScore);
        standardDeviationPrint(autoScore, 3.85, .73, "autonomy");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your relatedness score is " + relateScore);
        standardDeviationPrint(compScore, 4.22, .69, "relatedness");
        createBargraph(outPutCSV);
    }
    else if(compScore != 0 && autoScore != 0 && relateScore != 0){//Print each relationship, so long as it exists
        d3.select("body").append("H1")
            .style("margin", "30px 50px 0px 50px")
            .text("RSSM Score for you with your " + relation);
        d3.select("body").append("li")
            .style("margin", "15px 50px 0px 50px")
            .text("Your competence score is " + compScore);
        d3.select("body").append("li")
            .style("margin", "10px 50px 0px 50px")
            .text("Your autonomy score is " + autoScore);
        d3.select("body").append("li")
            .style("margin", "10px 50px 0px 50px")
            .text("Your relatedness score is " + relateScore);
    }
}

function standardDeviationPrint(Score, Mean, SD, type){ //participants score, popMean, popSD, score type
    //Find how many deviations from the mean they are, and print the accompanying text with it.
    if (Score > Mean-SD && Score < Mean+SD){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is average");
    }
    else if (Score > Mean-(SD*2) && Score < Mean-SD){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is on the low side of average");
    }
    else if (Score > Mean-(SD*3) && Score < Mean-(SD*2)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is low");
    }
    else if (Score > 0 && Score < Mean-(SD*3)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is very low");
    }
    else if (Score > Mean+(SD) && Score < Mean+(SD*2)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is on the high side of average");
    }
    else if (Score > Mean+(SD*2) && Score < Mean+(SD*3)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is high");
    }
    else if (Score > Mean+(SD*3) && Score < 5){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is very high");
    }
    else{
        //Something in the code failed most likely. But also, they could have not answered for any relationship.
        d3.select("body").append("p")
            .style("margin", "15px 50px 0px 50px")
            .text("Test was inconclusive or there is an error in the survey. Please contact the web developer.");
    }

}

function createBargraph(dataset){ //This was a test of D3
    //It creates a little BISBAS graph
    //It's not super useful
    //But I kept the code just in case.
    //If you'd like to see it, uncomment out the call to this function above.
     console.log("graphing17");

//			d3.select("body")//.selectAll("div")
//				.data(dataset)
//				.enter()
//				.append("div")
//				.attr("class", "bar")
//				.style("height", function(d) {
//					var barHeight = d * 5;
//					return barHeight + "px";
//				});

    var w = 1000;
    var h = 500;
    var barPadding = 1;

    //Create SVG element
    var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h)
                .style("height", function(d) {
					var barHeight = d * 5;
					return barHeight + "px";
				});

    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x", function(d, i) {
            return i * (w / dataset.length);
        })
        .attr("y", function(d) {
            return h - (d * 4);
        })
        .attr("width", w / dataset.length - barPadding)
        .attr("height", function(d) {
            return d * 4;
        })
        .attr("fill", function(d) {
            return "rgb(0, 0, " + Math.round(d * 10) + ")";
        });
}<commit_msg>graph test18<commit_after>////////////////////////////////////////////////////////////
//  This file was authored by A. Leah Zulas             ////
//  It heavily utilizes D3 js                           ////
//  If retreives data using Ajax, from an express server////
//  Any questions about the below code should be sent to:///
//  alzulas@alzulas.com                                 ////
////////////////////////////////////////////////////////////

//Create CSV array and retreive cookie
var outPutCSV = [];
var myid = getCookie("userName");
//Use cookie to request data from the server, so long as cookie exists.
if (myid != ""){
    var dataPassed;
    $.ajax({
        type: "GET",
        url: "/RSSMresult/" + myid,
        async: false,
        success: function(dataPassed){
            outPutCSV = calculateScores(dataPassed); //collect data and put them into the CSV
            console.log(outPutCSV); //Correctly calculated data print to console so we can see it worked
            console.log("Get request complete");//verification that the data was retreieved.
        },
    });
}

    //d3.getElementById("myDiv").style.margin = "50px 10px 20px 30px";
    //This html just explains what the participant just did.
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("The measure you completed was designed to assess how you experience yourself when you are interacting with different significant others in your life or engaged in different roles.  More specifically, this questionnaire measures to what extent you experience satisfaction of 3 psychological needs in these different interactions.");
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("According to self-determination theory (Ryan & Deci, 2000), humans have three essential needs that if satisfied promote psychological well-being. These 3 needs are:");
    d3.select("body").append("li")
        .style("margin", "30px 50px 0px 50px")
        .text("Relatedness-which is the experience of intimacy and genuine connection with others.");
    d3.select("body").append("li")
        .style("margin", "10px 50px 0px 50px")
        .text("Competence-which is the experience of feeling effective and capable of achieving desired outcomes.");
    d3.select("body").append("li")
        .style("margin", "10px 50px 0px 50px")
        .text("Autonomy-which is the experience of self-determination, full willingness, and volition when carrying out an activity.");
    d3.select("body").append("p")
        .style("margin", "30px 50px 0px 50px")
        .text("");

//begins the process of printing scores.
//Common was to write JS, because any variables not wrapped in a function is available in the entire namespace of the website.
printScores();

function printScores(){
    //creat array of possible relationships
    //THIS IS ONE OF THE VARIABLES TO CHANGE IF YOU WANT TO ADD NEW RELATIONSHIPS.
    var relationship = ["Mother", "Father", "Romantic Partner", "Ex-Romantic Partner", "Sibling", "Close Friend", "Overall"];
    i = 0;//counter
    for (relation in relationship){ //Go through each relationship above and...
        standardResults(outPutCSV[i], outPutCSV[i+1], outPutCSV[i+2], relationship[relation]); //calculate info about it.
        //The above hands the next part of this the comp score, auto score, relation score, and the relationship name
        i = i+3;
        //it then progresses the counter to the next relationship in the CSV
    }
}

function getCookie(cname) { //This function retreives the participant ID, stored as a cookie
    var name = cname + "=";
    var ca = document.cookie.split(';'); //Ask for cookie, split by ;
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) { //looking for ID in cookie called "cname"
            return c.substring(name.length, c.length); //Return ID
        }
    }
    return ""; //No ID found, return empty string
}

function calculateScores(dataPassed){
    //Takes data from CSV off the server, calculates relavant scores, returns array
    var results = [];
    //Will be in the order of mother comp-auto-related then
    //father comp-auto-related then
    //romantic partner comp-auto-related then
    //ex comp-auto-related then
    //sibling comp-auto-related then
    //close friend
    //Below are necessary variables
    var currentComp = 0;
    var currentAuto = 0;
    var currentRelated = 0;
    var overallComp = 0;
    var overallAuto = 0;
    var overallRelated = 0;
    var compDenominator = 4*6;
    var autoDenominator = 4*6;
    var relatedDenominator = 4*6;
    var dataArray = dataPassed.split(","); //Takes CSV from the server, creates array
    //round counter. Because every 4th time through the data, scores are calculated
    var round = 0;
    //Relevant data beings at position 8 in the array from the server
    for (var i = 8; i < 95; i++){
        currentComp = currentComp + Number(dataArray[i]);//take current score for this relationship, add to previous
        overallComp = overallComp + Number(dataArray[i]);//Do for an overall score as well
        if(Number(dataArray[i])==0){
            //If there is nothing in this relationship, because they don't have one or never think of that person,
            //Then the overall score must have a different number to divide from
            compDenominator--;
        }
        //Go to next item in the array and repeat
        i++;
        currentAuto = currentAuto + Number(dataArray[i]);
        overallAuto = overallAuto + Number(dataArray[i]);
        if(Number(dataArray[i])==0){
            autoDenominator--;
        }
        //Go to next item in the array and repeat
        i++;
        currentRelated = currentRelated + Number(dataArray[i]);
        overallRelated = overallRelated + Number(dataArray[i]);
        if(Number(dataArray[i])==0){
            relatedDenominator--;
        }
        //Move forward round
        round++;
        if (round > 3){
            //If we have all relevant scores for this relationship, then calculate averages
            currentComp = currentComp/4;
            currentAuto = currentAuto/4;
            currentRelated = currentRelated/4;
            //Push these scores onto the results array
            results.push(currentComp);
            results.push(currentAuto);
            results.push(currentRelated);
            //Reset variables for next relationship
            currentAuto = 0;
            currentComp = 0;
            currentRelated = 0;
            round = 0;
            //Move forward past questions like "relationship type", "closeness" and a filler question
            i = i+3;
        }
    }
    //Once all relationship scores are calculated, an overall must be calculated
    overallComp = overallComp/compDenominator;
    overallAuto = overallAuto/autoDenominator;
    overallRelated = overallRelated/relatedDenominator;
    //Push these onto the results array
    results.push(overallComp);
    results.push(overallAuto);
    results.push(overallRelated);

    //return results to the ajax call
    return results;
}

function standardResults(compScore, autoScore, relateScore, relation){
    //Printing scores to the screen.
    if(relation == "Overall"){//Print overall scores last
        d3.select("body").append("H1")
            .style("margin", "30px 50px 0px 50px")
            .text("Your Overall RSSM Scores are: ");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your competence score is " + compScore);
        //These include the actal mean and SD for the population,
        //they go to a function to calculate where the participants score lies
        standardDeviationPrint(compScore, 3.97, .74, "competancy");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your autonomy score is " + autoScore);
        standardDeviationPrint(autoScore, 3.85, .73, "autonomy");
        d3.select("body").append("li")
            .style("margin", "30px 50px 0px 50px")
            .text("Your relatedness score is " + relateScore);
        standardDeviationPrint(compScore, 4.22, .69, "relatedness");
        createBargraph(outPutCSV);
    }
    else if(compScore != 0 && autoScore != 0 && relateScore != 0){//Print each relationship, so long as it exists
        d3.select("body").append("H1")
            .style("margin", "30px 50px 0px 50px")
            .text("RSSM Score for you with your " + relation);
        d3.select("body").append("li")
            .style("margin", "15px 50px 0px 50px")
            .text("Your competence score is " + compScore);
        d3.select("body").append("li")
            .style("margin", "10px 50px 0px 50px")
            .text("Your autonomy score is " + autoScore);
        d3.select("body").append("li")
            .style("margin", "10px 50px 0px 50px")
            .text("Your relatedness score is " + relateScore);
    }
}

function standardDeviationPrint(Score, Mean, SD, type){ //participants score, popMean, popSD, score type
    //Find how many deviations from the mean they are, and print the accompanying text with it.
    if (Score > Mean-SD && Score < Mean+SD){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is average");
    }
    else if (Score > Mean-(SD*2) && Score < Mean-SD){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is on the low side of average");
    }
    else if (Score > Mean-(SD*3) && Score < Mean-(SD*2)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is low");
    }
    else if (Score > 0 && Score < Mean-(SD*3)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is very low");
    }
    else if (Score > Mean+(SD) && Score < Mean+(SD*2)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is on the high side of average");
    }
    else if (Score > Mean+(SD*2) && Score < Mean+(SD*3)){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is high");
    }
    else if (Score > Mean+(SD*3) && Score < 5){
        d3.select("body").append("ul")
            .style("margin", "15px 50px 0px 50px")
            .text("Your " + type + " score is very high");
    }
    else{
        //Something in the code failed most likely. But also, they could have not answered for any relationship.
        d3.select("body").append("p")
            .style("margin", "15px 50px 0px 50px")
            .text("Test was inconclusive or there is an error in the survey. Please contact the web developer.");
    }

}

function createBargraph(dataset){ //This was a test of D3
    //It creates a little BISBAS graph
    //It's not super useful
    //But I kept the code just in case.
    //If you'd like to see it, uncomment out the call to this function above.
     console.log("graphing18");

//			d3.select("body")//.selectAll("div")
//				.data(dataset)
//				.enter()
//				.append("div")
//				.attr("class", "bar")
//				.style("height", function(d) {
//					var barHeight = d * 5;
//					return barHeight + "px";
//				});

    var w = 1000;
    var h = 500;
    var barPadding = 1;

    //Create SVG element
    var svg = d3.select("body")
                .style("margin", "30px 50px 0px 50px")
                .style("height", function(d) {
					var barHeight = d * 5;
					return barHeight + "px";
				})
                .append("svg")
                .attr("width", w)
                .attr("height", h);

    svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("x", function(d, i) {
            return i * (w / dataset.length);
        })
        .attr("y", function(d) {
            return h - (d * 4);
        })
        .attr("width", w / dataset.length - barPadding)
        .attr("height", function(d) {
            return d * 4;
        })
        .attr("fill", function(d) {
            return "rgb(0, 0, " + Math.round(d * 10) + ")";
        });
}<|endoftext|>


<commit_before><commit_msg>fix(h5): improve page id<commit_after><|endoftext|>


<commit_before>define(['jquery',
    'underscore',
    'underscore.string',
    'text!todo/sean/page-template.html',
    'text!todo/sean/item-template.html'], function ($, _, _s, pageTemplate, itemTemplate) {
    'use strict';
    function createPrototypeTodoApplication(jsonOverHttp) {
        var dom, addButtonPressed, keyPressed, addButton, userInput, list, appendItemToView, respondToTodoAdded, respondToRefreshItems;
        dom = $(pageTemplate);
        addButton = dom.find('.add-todo-item-button');
        userInput = dom.find('.user-input');
        list = dom.find('.todo-items-list');
        keyPressed = function (event) {
            if (event.which === 13) {
                addButtonPressed();
            }
        };
        addButtonPressed = function () {
            var toAdd, todo;
            toAdd = userInput.val();
            if (!_s.isBlank(_s.trim(toAdd))) {
                userInput.val('');
                todo = { name: toAdd, done: false };
                jsonOverHttp({uri: 'todo', method: 'POST', body: todo}).then(respondToTodoAdded);
                userInput.focus();
            }
        };
        appendItemToView = function (todo) {
            var todoElement;
            todoElement = $(itemTemplate);
            todoElement.find('.todo-id').val(todo.id);
            todoElement.find('.todo-name').text(todo.name);
            if (todo.done) {
                todoElement.find('.todo-done').attr('checked', 'checked');
            } else {
                todoElement.find('.todo-done').removeAttr('checked');
            }
            list.append(todoElement);
        };
        respondToTodoAdded = function (response) {
            appendItemToView(response.body);
        };
        respondToRefreshItems = function (response) {
            _.each(response.body, appendItemToView);
        };
        addButton.on('click', addButtonPressed);
        userInput.on('keyup', keyPressed);
        jsonOverHttp({uri: 'todo', method: 'GET'}).then(respondToRefreshItems);
        return dom;
    }

    return createPrototypeTodoApplication;
});
<commit_msg>trim names before sending<commit_after>define(['jquery',
    'underscore',
    'underscore.string',
    'text!todo/sean/page-template.html',
    'text!todo/sean/item-template.html'], function ($, _, _s, pageTemplate, itemTemplate) {
    'use strict';
    function createPrototypeTodoApplication(jsonOverHttp) {
        var dom, addButtonPressed, keyPressed, addButton, userInput, list, appendItemToView, respondToTodoAdded, respondToRefreshItems;
        dom = $(pageTemplate);
        addButton = dom.find('.add-todo-item-button');
        userInput = dom.find('.user-input');
        list = dom.find('.todo-items-list');
        keyPressed = function (event) {
            if (event.which === 13) {
                addButtonPressed();
            }
        };
        addButtonPressed = function () {
            var toAdd, todo;
            toAdd = _s.trim(userInput.val());
            if (!_s.isBlank(toAdd)) {
                userInput.val('');
                userInput.focus();
                todo = { name: toAdd, done: false };
                jsonOverHttp({uri: 'todo', method: 'POST', body: todo}).then(respondToTodoAdded);
            }
        };
        appendItemToView = function (todo) {
            var todoElement;
            todoElement = $(itemTemplate);
            todoElement.find('.todo-id').val(todo.id);
            todoElement.find('.todo-name').text(todo.name);
            if (todo.done) {
                todoElement.find('.todo-done').attr('checked', 'checked');
            } else {
                todoElement.find('.todo-done').removeAttr('checked');
            }
            list.append(todoElement);
        };
        respondToTodoAdded = function (response) {
            appendItemToView(response.body);
        };
        respondToRefreshItems = function (response) {
            _.each(response.body, appendItemToView);
        };
        addButton.on('click', addButtonPressed);
        userInput.on('keyup', keyPressed);
        jsonOverHttp({uri: 'todo', method: 'GET'}).then(respondToRefreshItems);
        return dom;
    }

    return createPrototypeTodoApplication;
});
<|endoftext|>


<commit_before>var _ = require('underscore');
var CategoryOptionModel = require('./category/category-option-model');
var CategoryOptionsView = require('./category/category-options-view');
var HistogramOptionModel = require('./histogram/histogram-option-model');
var HistogramOptionsView = require('./histogram/histogram-options-view');
var FormulaOptionModel = require('./formula/formula-option-model');
var FormulaOptionsView = require('./formula/formula-options-view');
var TimeSeriesOptionModel = require('./time-series/time-series-option-model');
var TimeSeriesNoneOptionModel = require('./time-series/time-series-none-option-model');
var TimeSeriesOptionsView = require('./time-series/time-series-options-view');

// Order is the same in how things will be presented in the UI
module.exports = [
  {
    type: 'category',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        var type = columnModel.get('type');
        var m;
        if (type === 'string' || type === 'boolean') {
          m = new CategoryOptionModel({
            tuples: tuples,
            title: _t('editor.widgets.widgets-types.category') + ' ' + columnModel.get('name'),
            name: columnModel.get('name'),
            aggregation: 'count' // or sum
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.category-label'),
        name: 'category',
        createContentView: function () {
          return new CategoryOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'histogram',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        if (columnModel.get('type') === 'number') {
          var m = new HistogramOptionModel({
            tuples: tuples,
            title: _t('editor.widgets.widgets-types.histogram') + ' ' + columnModel.get('name'),
            name: columnModel.get('name'),
            bins: 10
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.histogram-label'),
        name: 'histogram',
        createContentView: function () {
          return new HistogramOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'formula',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        if (columnModel.get('type') === 'number') {
          var m = new FormulaOptionModel({
            tuples: tuples,
            title: _t('editor.widgets.widgets-types.formula') + ' ' + columnModel.get('name'),
            operation: 'avg',
            name: columnModel.get('name')
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.formula-label'),
        name: 'formula',
        createContentView: function () {
          return new FormulaOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'time-series',
    createOptionModels: function (tuplesItems, widgetDefinitionsCollection) {
      var existingDefModel = widgetDefinitionsCollection.find(function (m) {
        return m.get('type') === 'time-series';
      });

      var models = _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        var columnName = columnModel.get('name');
        if (columnModel.get('type') === 'date') {
          var attrs = {
            tuples: tuples,
            title: _t('editor.widgets.widgets-types.time-series') + ' ' + columnName,
            bins: 256
          };

          // Preselect the correct tuple, if there already exists a widget definition
          if (existingDefModel && existingDefModel.get('column') === columnName) {
            _.find(tuples, function (d, i) {
              if (d.layerDefinitionModel.id === existingDefModel.get('layer_id')) {
                attrs.selected = true;
                attrs.layer_index = i;
                return true;
              }
            });
          }

          var m = new TimeSeriesOptionModel(attrs);
          memo.push(m);
        }

        return memo;
      }, []);

      // Special-case; preprend the none-model since it should appear first
      var noneOptionModel = new TimeSeriesNoneOptionModel();
      return [noneOptionModel].concat(models);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.time-series-label'),
        name: 'time-series',
        createContentView: function () {
          return new TimeSeriesOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  }
];
<commit_msg>Removed widget type from the title, closes #8114<commit_after>var _ = require('underscore');
var CategoryOptionModel = require('./category/category-option-model');
var CategoryOptionsView = require('./category/category-options-view');
var HistogramOptionModel = require('./histogram/histogram-option-model');
var HistogramOptionsView = require('./histogram/histogram-options-view');
var FormulaOptionModel = require('./formula/formula-option-model');
var FormulaOptionsView = require('./formula/formula-options-view');
var TimeSeriesOptionModel = require('./time-series/time-series-option-model');
var TimeSeriesNoneOptionModel = require('./time-series/time-series-none-option-model');
var TimeSeriesOptionsView = require('./time-series/time-series-options-view');

// Order is the same in how things will be presented in the UI
module.exports = [
  {
    type: 'category',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        var type = columnModel.get('type');
        var m;
        if (type === 'string' || type === 'boolean') {
          m = new CategoryOptionModel({
            tuples: tuples,
            title: columnModel.get('name'),
            name: columnModel.get('name'),
            aggregation: 'count' // or sum
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.category-label'),
        name: 'category',
        createContentView: function () {
          return new CategoryOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'histogram',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        if (columnModel.get('type') === 'number') {
          var m = new HistogramOptionModel({
            tuples: tuples,
            title: columnModel.get('name'),
            name: columnModel.get('name'),
            bins: 10
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.histogram-label'),
        name: 'histogram',
        createContentView: function () {
          return new HistogramOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'formula',
    createOptionModels: function (tuplesItems) {
      return _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        if (columnModel.get('type') === 'number') {
          var m = new FormulaOptionModel({
            tuples: tuples,
            title: columnModel.get('name'),
            operation: 'avg',
            name: columnModel.get('name')
          });
          memo.push(m);
        }
        return memo;
      }, []);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.formula-label'),
        name: 'formula',
        createContentView: function () {
          return new FormulaOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  },
  {
    type: 'time-series',
    createOptionModels: function (tuplesItems, widgetDefinitionsCollection) {
      var existingDefModel = widgetDefinitionsCollection.find(function (m) {
        return m.get('type') === 'time-series';
      });

      var models = _.reduce(tuplesItems, function (memo, tuples) {
        var columnModel = tuples[0].columnModel;
        var columnName = columnModel.get('name');
        if (columnModel.get('type') === 'date') {
          var attrs = {
            tuples: tuples,
            title: columnName,
            bins: 256
          };

          // Preselect the correct tuple, if there already exists a widget definition
          if (existingDefModel && existingDefModel.get('column') === columnName) {
            _.find(tuples, function (d, i) {
              if (d.layerDefinitionModel.id === existingDefModel.get('layer_id')) {
                attrs.selected = true;
                attrs.layer_index = i;
                return true;
              }
            });
          }

          var m = new TimeSeriesOptionModel(attrs);
          memo.push(m);
        }

        return memo;
      }, []);

      // Special-case; preprend the none-model since it should appear first
      var noneOptionModel = new TimeSeriesNoneOptionModel();
      return [noneOptionModel].concat(models);
    },
    createTabPaneItem: function (optionsCollection) {
      return {
        label: _t('components.modals.add-widgets.tab-pane.time-series-label'),
        name: 'time-series',
        createContentView: function () {
          return new TimeSeriesOptionsView({
            collection: optionsCollection
          });
        }
      };
    }
  }
];
<|endoftext|>


<commit_before>define([
    'uijet_dir/uijet',
    'resources',
    'api'
], function (uijet, resources, api) {

    function sortByPeriod (a, b) { return a.period - b.period; }
    function addFloats (a, b) {
        var res = a + b;
        return +(res).toPrecision((res | 0).toString().length + 2);
    }

    var TimeSeriesModel = uijet.Model({
        url : function () {
            return api.getTimelineRoute(this.attributes.muni_id, this.attributes.nodes);
        },
        parse   : function (response) {
            var periods = [],
                series = {};
            response.forEach(function (item) {
                var period = +item.period;
                if ( !~ periods.indexOf(period) ) {
                    periods.push(period);
                }
                if ( ! (period in series) ) {
                    series[period] = {
                        budget  : +item.budget,
                        actual  : +item.actual
                    };
                }
                else {
                    series[period].budget = addFloats(series[period].budget, +item.budget);
                    series[period].actual = addFloats(series[period].actual, +item.actual);
                }
            });
            return {
                periods : periods.sort(),
                series  : series
            };
        },
        toSeries: function () {
            var series = this.get('series'),
                actuals = [],
                budgets = [],
                period;
            for ( period in series ) {
                actuals.push({
                    period  : period,
                    amount  : series[period].actual
                });
                budgets.push({
                    period  : period,
                    amount  : series[period].budget
                });
            }
            return [actuals.sort(sortByPeriod), budgets.sort(sortByPeriod)];
        }
    });

    uijet.Resource('TimeSeries', uijet.Collection({
        model           : TimeSeriesModel,
        fetch           : function () {
            return uijet.whenAll(this.models.map(function (model) {
                return model.fetch();
            }));
        },
        periods         : function () {
            return this.pluck('periods').reduce(function (prev, current) {
                current.forEach(function (item) {
                    if ( !~ this.indexOf(item) )
                        this.push(item);
                }, prev);
                return prev;
            }).sort();
        },
        extractLegend   : function () {
            return this.models.map(function (model) {
                var attrs = model.attributes;
                return {
                    title   : attrs.title,
                    nodes   : attrs.nodes,
                    muni    : new resources.Muni({
                        id  : attrs.muni_id,
                        name: attrs.muni
                    })
                };
            });
        }
    }));

    uijet.Adapter('TimelineChart', {
        set : function (legend_item_models) {
            var updated_models = legend_item_models.map(function (legend_item) {
                var muni = legend_item.get('muni'),
                    muni_id = muni.id,
                    nodes = legend_item.get('nodes'),
                    title = legend_item.get('title'),
                    type = legend_item.get('amount_type'),
                    muni_name = muni.get('name'),
                    model = this.resource.get(legend_item.cid),
                    now = Date.now();

                if ( model ) {
                    model.set({
                        muni_id     : muni_id,
                        nodes       : nodes,
                        title       : title,
                        muni        : muni_name,
                        amount_type : type
                    });
                    if ( model.hasChanged() ) {
                        model.set({ updated : now });
                    }
                }
                else {
                    model = new TimeSeriesModel({
                        id          : legend_item.id,
                        muni_id     : muni_id,
                        nodes       : nodes,
                        title       : title,
                        muni        : muni_name,
                        amount_type : type,
                        updated     : now
                    });
                }
                return model;
            }, this);

            return this.resource.set(updated_models).fetch();
        }
    });

});
<commit_msg>Fixed legend items extraction to include amount_type<commit_after>define([
    'uijet_dir/uijet',
    'resources',
    'api'
], function (uijet, resources, api) {

    function sortByPeriod (a, b) { return a.period - b.period; }
    function addFloats (a, b) {
        var res = a + b;
        return +(res).toPrecision((res | 0).toString().length + 2);
    }

    var TimeSeriesModel = uijet.Model({
        url : function () {
            return api.getTimelineRoute(this.attributes.muni_id, this.attributes.nodes);
        },
        parse   : function (response) {
            var periods = [],
                series = {};
            response.forEach(function (item) {
                var period = +item.period;
                if ( !~ periods.indexOf(period) ) {
                    periods.push(period);
                }
                if ( ! (period in series) ) {
                    series[period] = {
                        budget  : +item.budget,
                        actual  : +item.actual
                    };
                }
                else {
                    series[period].budget = addFloats(series[period].budget, +item.budget);
                    series[period].actual = addFloats(series[period].actual, +item.actual);
                }
            });
            return {
                periods : periods.sort(),
                series  : series
            };
        },
        toSeries: function () {
            var series = this.get('series'),
                actuals = [],
                budgets = [],
                period;
            for ( period in series ) {
                actuals.push({
                    period  : period,
                    amount  : series[period].actual
                });
                budgets.push({
                    period  : period,
                    amount  : series[period].budget
                });
            }
            return [actuals.sort(sortByPeriod), budgets.sort(sortByPeriod)];
        }
    });

    uijet.Resource('TimeSeries', uijet.Collection({
        model           : TimeSeriesModel,
        fetch           : function () {
            return uijet.whenAll(this.models.map(function (model) {
                return model.fetch();
            }));
        },
        periods         : function () {
            return this.pluck('periods').reduce(function (prev, current) {
                current.forEach(function (item) {
                    if ( !~ this.indexOf(item) )
                        this.push(item);
                }, prev);
                return prev;
            }).sort();
        },
        extractLegend   : function () {
            return this.models.map(function (model) {
                var attrs = model.attributes;
                return {
                    title       : attrs.title,
                    nodes       : attrs.nodes,
                    muni        : new resources.Muni({
                        id  : attrs.muni_id,
                        name: attrs.muni
                    }),
                    amount_type : attrs.amount_type
                };
            });
        }
    }));

    uijet.Adapter('TimelineChart', {
        set : function (legend_item_models) {
            var updated_models = legend_item_models.map(function (legend_item) {
                var muni = legend_item.get('muni'),
                    muni_id = muni.id,
                    nodes = legend_item.get('nodes'),
                    title = legend_item.get('title'),
                    type = legend_item.get('amount_type'),
                    muni_name = muni.get('name'),
                    model = this.resource.get(legend_item.cid),
                    now = Date.now();

                if ( model ) {
                    model.set({
                        muni_id     : muni_id,
                        nodes       : nodes,
                        title       : title,
                        muni        : muni_name,
                        amount_type : type
                    });
                    if ( model.hasChanged() ) {
                        model.set({ updated : now });
                    }
                }
                else {
                    model = new TimeSeriesModel({
                        id          : legend_item.id,
                        muni_id     : muni_id,
                        nodes       : nodes,
                        title       : title,
                        muni        : muni_name,
                        amount_type : type,
                        updated     : now
                    });
                }
                return model;
            }, this);

            return this.resource.set(updated_models).fetch();
        }
    });

});
<|endoftext|>


<commit_before>import React, { useCallback, useState } from 'react';
import matchSorter from 'match-sorter';
import {
  SettingsPageTitle,
  useQuery,
  useTracking,
  useFocusWhenNavigate,
} from '@strapi/helper-plugin';
import Plus from '@strapi/icons/Plus';
import Trash from '@strapi/icons/Trash';
import Pencil from '@strapi/icons/Pencil';
import Duplicate from '@strapi/icons/Duplicate';
import { Button } from '@strapi/design-system/Button';
import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
import { Table, Tbody, Th, Thead, Tr, TFooter } from '@strapi/design-system/Table';
import { Typography } from '@strapi/design-system/Typography';
import { Main } from '@strapi/design-system/Main';
import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import RoleRow from './components/RoleRow';
import EmptyRole from './components/EmptyRole';
import UpgradePlanModal from '../../../../../components/UpgradePlanModal ';
import { useRolesList } from '../../../../../hooks';

const useSortedRoles = () => {
  const { roles, isLoading } = useRolesList();

  const query = useQuery();
  const _q = decodeURIComponent(query.get('_q') || '');
  const sortedRoles = matchSorter(roles, _q, { keys: ['name', 'description'] });

  return { isLoading, sortedRoles };
};

const useRoleActions = () => {
  const { formatMessage } = useIntl();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { trackUsage } = useTracking();
  const { push } = useHistory();

  const handleGoTo = useCallback(
    id => {
      push(`/settings/roles/${id}`);
    },
    [push]
  );

  const handleToggle = useCallback(() => {
    setIsModalOpen(prev => !prev);
  }, []);

  const handleToggleModalForCreatingRole = useCallback(() => {
    trackUsage('didShowRBACUpgradeModal');
    setIsModalOpen(true);
  }, [trackUsage]);

  const getIcons = useCallback(
    role => [
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
        icon: <Duplicate />,
      },
      {
        onClick: () => handleGoTo(role.id),
        label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
        icon: <Pencil />,
      },
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.delete', defaultMessage: 'Delete' }),
        icon: <Trash />,
      },
    ],
    [formatMessage, handleToggle, handleGoTo]
  );

  return {
    isModalOpen,
    handleToggleModalForCreatingRole,
    handleToggle,
    getIcons,
  };
};

const RoleListPage = () => {
  const { formatMessage } = useIntl();
  useFocusWhenNavigate();

  const { sortedRoles, isLoading } = useSortedRoles();
  const {
    isModalOpen,
    handleToggle,
    handleToggleModalForCreatingRole,
    getIcons,
  } = useRoleActions();

  const rowCount = sortedRoles.length + 1;
  const colCount = 5;

  // ! TODO - Add the search input

  return (

      <SettingsPageTitle name="Roles" />
      <HeaderLayout
        primaryAction={
          <Button onClick={handleToggleModalForCreatingRole} startIcon={<Plus />} size="L">
            {formatMessage({
              id: 'Settings.roles.list.button.add',
              defaultMessage: 'Add new role',
            })}
          </Button>
        }
        title={formatMessage({
          id: 'Settings.roles.title',
          defaultMessage: 'roles',
        })}
        subtitle={formatMessage({
          id: 'Settings.roles.list.description',
          defaultMessage: 'List of roles',
        })}
      />
      <ContentLayout>
        <Table
          colCount={colCount}
          rowCount={rowCount}
          footer={
            <TFooter onClick={handleToggleModalForCreatingRole} icon={<Plus />}>
              {formatMessage({
                id: 'Settings.roles.list.button.add',
                defaultMessage: 'Add new role',
              })}
            </TFooter>
          }
        >

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.name',
                    defaultMessage: 'Name',
                  })}
                </Typography>

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.description',
                    defaultMessage: 'Description',
                  })}
                </Typography>

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.users',
                    defaultMessage: 'Users',
                  })}
                </Typography>

                <VisuallyHidden>
                  {formatMessage({
                    id: 'Settings.roles.list.header.actions',
                    defaultMessage: 'Actions',
                  })}
                </VisuallyHidden>

            {sortedRoles?.map(role => (
              <RoleRow
                key={role.id}
                id={role.id}
                name={role.name}
                description={role.description}
                usersCount={role.usersCount}
                icons={getIcons(role)}
              />
            ))}

        {!rowCount && !isLoading && <EmptyRole />}
      </ContentLayout>
      <UpgradePlanModal isOpen={isModalOpen} onClose={handleToggle} />

  );
};

export default RoleListPage;
<commit_msg>fix: admin import<commit_after>import React, { useCallback, useState } from 'react';
import matchSorter from 'match-sorter';
import {
  SettingsPageTitle,
  useQuery,
  useTracking,
  useFocusWhenNavigate,
} from '@strapi/helper-plugin';
import Plus from '@strapi/icons/Plus';
import Trash from '@strapi/icons/Trash';
import Pencil from '@strapi/icons/Pencil';
import Duplicate from '@strapi/icons/Duplicate';
import { Button } from '@strapi/design-system/Button';
import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
import { Table, Tbody, Th, Thead, Tr, TFooter } from '@strapi/design-system/Table';
import { Typography } from '@strapi/design-system/Typography';
import { Main } from '@strapi/design-system/Main';
import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import RoleRow from './components/RoleRow';
import EmptyRole from './components/EmptyRole';
import UpgradePlanModal from '../../../../../components/UpgradePlanModal';
import { useRolesList } from '../../../../../hooks';

const useSortedRoles = () => {
  const { roles, isLoading } = useRolesList();

  const query = useQuery();
  const _q = decodeURIComponent(query.get('_q') || '');
  const sortedRoles = matchSorter(roles, _q, { keys: ['name', 'description'] });

  return { isLoading, sortedRoles };
};

const useRoleActions = () => {
  const { formatMessage } = useIntl();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const { trackUsage } = useTracking();
  const { push } = useHistory();

  const handleGoTo = useCallback(
    id => {
      push(`/settings/roles/${id}`);
    },
    [push]
  );

  const handleToggle = useCallback(() => {
    setIsModalOpen(prev => !prev);
  }, []);

  const handleToggleModalForCreatingRole = useCallback(() => {
    trackUsage('didShowRBACUpgradeModal');
    setIsModalOpen(true);
  }, [trackUsage]);

  const getIcons = useCallback(
    role => [
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.duplicate', defaultMessage: 'Duplicate' }),
        icon: <Duplicate />,
      },
      {
        onClick: () => handleGoTo(role.id),
        label: formatMessage({ id: 'app.utils.edit', defaultMessage: 'Edit' }),
        icon: <Pencil />,
      },
      {
        onClick: handleToggle,
        label: formatMessage({ id: 'app.utils.delete', defaultMessage: 'Delete' }),
        icon: <Trash />,
      },
    ],
    [formatMessage, handleToggle, handleGoTo]
  );

  return {
    isModalOpen,
    handleToggleModalForCreatingRole,
    handleToggle,
    getIcons,
  };
};

const RoleListPage = () => {
  const { formatMessage } = useIntl();
  useFocusWhenNavigate();

  const { sortedRoles, isLoading } = useSortedRoles();
  const {
    isModalOpen,
    handleToggle,
    handleToggleModalForCreatingRole,
    getIcons,
  } = useRoleActions();

  const rowCount = sortedRoles.length + 1;
  const colCount = 5;

  // ! TODO - Add the search input

  return (

      <SettingsPageTitle name="Roles" />
      <HeaderLayout
        primaryAction={
          <Button onClick={handleToggleModalForCreatingRole} startIcon={<Plus />} size="L">
            {formatMessage({
              id: 'Settings.roles.list.button.add',
              defaultMessage: 'Add new role',
            })}
          </Button>
        }
        title={formatMessage({
          id: 'Settings.roles.title',
          defaultMessage: 'roles',
        })}
        subtitle={formatMessage({
          id: 'Settings.roles.list.description',
          defaultMessage: 'List of roles',
        })}
      />
      <ContentLayout>
        <Table
          colCount={colCount}
          rowCount={rowCount}
          footer={
            <TFooter onClick={handleToggleModalForCreatingRole} icon={<Plus />}>
              {formatMessage({
                id: 'Settings.roles.list.button.add',
                defaultMessage: 'Add new role',
              })}
            </TFooter>
          }
        >

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.name',
                    defaultMessage: 'Name',
                  })}
                </Typography>

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.description',
                    defaultMessage: 'Description',
                  })}
                </Typography>

                <Typography variant="sigma" textColor="neutral600">
                  {formatMessage({
                    id: 'Settings.roles.list.header.users',
                    defaultMessage: 'Users',
                  })}
                </Typography>

                <VisuallyHidden>
                  {formatMessage({
                    id: 'Settings.roles.list.header.actions',
                    defaultMessage: 'Actions',
                  })}
                </VisuallyHidden>

            {sortedRoles?.map(role => (
              <RoleRow
                key={role.id}
                id={role.id}
                name={role.name}
                description={role.description}
                usersCount={role.usersCount}
                icons={getIcons(role)}
              />
            ))}

        {!rowCount && !isLoading && <EmptyRole />}
      </ContentLayout>
      <UpgradePlanModal isOpen={isModalOpen} onClose={handleToggle} />

  );
};

export default RoleListPage;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { DatePicker } from '@strapi/design-system/DatePicker';
import { Field, FieldInput } from '@strapi/design-system/Field';
import { NumberInput } from '@strapi/design-system/NumberInput';
import { TimePicker } from '@strapi/design-system/TimePicker';
import { Select, Option } from '@strapi/design-system/Select';
import { useIntl } from 'react-intl';
import DateTimePicker from '../DateTimePicker';

const Inputs = ({ label, onChange, options, type, value }) => {
  const { formatMessage } = useIntl();

  if (type === 'boolean') {
    return (
      <Select
        // FIXME: stop errors in the console
        aria-label={label}
        onChange={onChange}
        value={value}
      >
        <Option value="true">true</Option>
        <Option value="false">false</Option>
      </Select>
    );
  }

  if (type === 'date') {
    return (
      <DatePicker
        clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
        ariaLabel={label}
        name="datepicker"
        onChange={date => onChange(date.toISOString())}
        onClear={() => onChange(null)}
        selectedDate={value ? new Date(value) : null}
        selectedDateLabel={formattedDate => `Date picker, current is ${formattedDate}`}
      />
    );
  }

  if (type === 'datetime') {
    return (
      <DateTimePicker
        clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
        ariaLabel={label}
        name="datetimepicker"
        onChange={date => onChange(date.toISOString())}
        onClear={() => onChange(null)}
        value={value ? new Date(value) : null}
        selectedDateLabel={formattedDate => `Date picker, current is ${formattedDate}`}
      />
    );
  }

  if (type === 'enumeration') {
    return (
      <Select
        // FIXME: stop errors in the console
        aria-label={label}
        onChange={onChange}
        value={value}
      >
        {options.map(optionValue => {
          return (
            <Option key={optionValue} value={optionValue}>
              {optionValue}
            </Option>
          );
        })}
      </Select>
    );
  }

  if (['float', 'integer', 'biginteger', 'decimal'].includes(type)) {
    return (
      <NumberInput
        aria-label={label}
        name="filter-value"
        onValueChange={onChange}
        value={value || 0}
      />
    );
  }

  if (type === 'time') {
    return (
      <TimePicker
        aria-label={label}
        onClear={() => onChange('')}
        onChange={onChange}
        value={value}
        clearLabel="Clear the selected time picker value"
      />
    );
  }

  return (
    <Field>
      <FieldInput // FIXME: stop errors in the console
        aria-label={formatMessage({ id: 'app.utils.filter-value', defaultMessage: 'Filter value' })}
        onChange={({ target: { value } }) => onChange(value)}
        value={value}
        size="M"
      />
    </Field>
  );
};

Inputs.defaultProps = {
  label: '',
  options: [],
  value: '',
};

Inputs.propTypes = {
  label: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  options: PropTypes.arrayOf(PropTypes.string),
  type: PropTypes.string.isRequired,
  value: PropTypes.any,
};

export default Inputs;
<commit_msg>FilterPopoverURLQuery: Remove all time-releated information from date filter<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import parseISO from 'date-fns/parseISO';
import formatISO from 'date-fns/formatISO';
import { DatePicker } from '@strapi/design-system/DatePicker';
import { Field, FieldInput } from '@strapi/design-system/Field';
import { NumberInput } from '@strapi/design-system/NumberInput';
import { TimePicker } from '@strapi/design-system/TimePicker';
import { Select, Option } from '@strapi/design-system/Select';
import { useIntl } from 'react-intl';
import DateTimePicker from '../DateTimePicker';

const Inputs = ({ label, onChange, options, type, value }) => {
  const { formatMessage } = useIntl();

  if (type === 'boolean') {
    return (
      <Select
        // FIXME: stop errors in the console
        aria-label={label}
        onChange={onChange}
        value={value}
      >
        <Option value="true">true</Option>
        <Option value="false">false</Option>
      </Select>
    );
  }

  if (type === 'date') {
    return (
      <DatePicker
        clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
        ariaLabel={label}
        name="datepicker"
        onChange={date => onChange(formatISO(date, { representation: 'date' }))}
        onClear={() => onChange(null)}
        selectedDate={value ? parseISO(value) : null}
        selectedDateLabel={formattedDate => `Date picker, current is ${formattedDate}`}
      />
    );
  }

  if (type === 'datetime') {
    return (
      <DateTimePicker
        clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}
        ariaLabel={label}
        name="datetimepicker"
        onChange={date => onChange(date.toISOString())}
        onClear={() => onChange(null)}
        value={value ? new Date(value) : null}
        selectedDateLabel={formattedDate => `Date picker, current is ${formattedDate}`}
      />
    );
  }

  if (type === 'enumeration') {
    return (
      <Select
        // FIXME: stop errors in the console
        aria-label={label}
        onChange={onChange}
        value={value}
      >
        {options.map(optionValue => {
          return (
            <Option key={optionValue} value={optionValue}>
              {optionValue}
            </Option>
          );
        })}
      </Select>
    );
  }

  if (['float', 'integer', 'biginteger', 'decimal'].includes(type)) {
    return (
      <NumberInput
        aria-label={label}
        name="filter-value"
        onValueChange={onChange}
        value={value || 0}
      />
    );
  }

  if (type === 'time') {
    return (
      <TimePicker
        aria-label={label}
        onClear={() => onChange('')}
        onChange={onChange}
        value={value}
        clearLabel="Clear the selected time picker value"
      />
    );
  }

  return (
    <Field>
      <FieldInput // FIXME: stop errors in the console
        aria-label={formatMessage({ id: 'app.utils.filter-value', defaultMessage: 'Filter value' })}
        onChange={({ target: { value } }) => onChange(value)}
        value={value}
        size="M"
      />
    </Field>
  );
};

Inputs.defaultProps = {
  label: '',
  options: [],
  value: '',
};

Inputs.propTypes = {
  label: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  options: PropTypes.arrayOf(PropTypes.string),
  type: PropTypes.string.isRequired,
  value: PropTypes.any,
};

export default Inputs;
<|endoftext|>


<commit_before>import express from 'express';
import session from 'express-session';
import bodyParser from 'body-parser';
import config from '../src/config';
import * as actions from './actions/index';
import { mapUrl } from 'utils/url.js';
import PrettyError from 'pretty-error';
import http from 'http';

const pretty = new PrettyError();
const app = express();

const server = new http.Server(app);

app.use(session({
    secret: 'react and redux rule!!!!',
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 60000 },
}));
app.use(bodyParser.json());

app.use((req, res) => {
    const splittedUrlPath = req.url.split('?')[0].split('/').slice(1);

    const { action, params } = mapUrl(actions, splittedUrlPath);

    if (action) {
        action(req, params).then((result) => {
            if (result instanceof Function) {
                result(res);
            } else {
                res.json(result);
            }
        }, (reason) => {
            if (reason && reason.redirect) {
                res.redirect(reason.redirect);
            } else {
                console.error('API ERROR:', pretty.render(reason));
                res.status(reason.status || 500).json(reason);
            }
        });
    } else {
        res.status(404).end('NOT FOUND');
    }
});

if (config.apiPort) {
    const runnable = app.listen(config.apiPort, (err) => {
        if (err) {
            console.error(err);
        }
        console.log('================|  API Ready  |================='.dim);
        console.log('==>'.dim, `🔮  API is running on port ${config.apiPort}`.blue);
        console.log('==>'.dim, '💦  Send requests to'.blue, `http://${config.apiHost}:${config.apiPort}`.yellow);
        console.log('================================================'.dim);
    });
} else {
    console.error('==>     ERROR: No PORT environment variable has been specified');
}
<commit_msg>log API requests<commit_after>import express from 'express';
import session from 'express-session';
import bodyParser from 'body-parser';
import config from '../src/config';
import * as actions from './actions/index';
import { mapUrl } from 'utils/url.js';
import PrettyError from 'pretty-error';
import http from 'http';

const pretty = new PrettyError();
const app = express();

const server = new http.Server(app);

app.use(session({
    secret: 'react and redux rule!!!!',
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 60000 },
}));
app.use(bodyParser.json());

app.use((req, res) => {
    const splittedUrlPath = req.url.split('?')[0].split('/').slice(1);

    const { action, params } = mapUrl(actions, splittedUrlPath);

    if (action) {
        console.log('Request made to the API at', req.url.yellow, 'Responded with', res.statusCode.toString().blue);
        action(req, params).then((result) => {
            if (result instanceof Function) {
                result(res);
            } else {
                res.json(result);
            }
        }, (reason) => {
            if (reason && reason.redirect) {
                res.redirect(reason.redirect);
            } else {
                console.error('API ERROR:', pretty.render(reason));
                res.status(reason.status || 500).json(reason);
            }
        });
    } else {
        res.status(404).end('NOT FOUND');
    }
});

if (config.apiPort) {
    const runnable = app.listen(config.apiPort, (err) => {
        if (err) {
            console.error(err);
        }
        console.log('================|  API Ready  |================='.dim);
        console.log('==>'.dim, `🔮  API is running on port ${config.apiPort}`.blue);
        console.log('==>'.dim, '💦  Send requests to'.blue, `http://${config.apiHost}:${config.apiPort}`.yellow);
        console.log('================================================'.dim);
    });
} else {
    console.error('==>     ERROR: No PORT environment variable has been specified');
}
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var argv = require('minimist')(process.argv.slice(2));
var swagger = require("swagger-node-express");
const passport = require('passport');
var Strategy = require('passport-http-bearer').Strategy;
var db = require('./db');

let Firewalla = require('../net2/Firewalla.js');
let firewalla = new Firewalla();

passport.use(new Strategy(
  function(token, cb) {
    db.users.findByToken(token, function(err, user) {
      if (err) { return cb(err); }
      if (!user) { return cb(null, false); }
      return cb(null, user);
    });
  }));

var system = require('./routes/system');
var message = require('./routes/message');
var shadowsocks = require('./routes/shadowsocks');
var encipher = require('./routes/fastencipher2');
let dnsmasq = require('./routes/dnsmasq');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

var subpath_v1 = express();
app.use("/v1", subpath_v1);
subpath_v1.use(passport.initialize());
subpath_v1.use(passport.session());
subpath_v1.use(bodyParser.json());
subpath_v1.use(bodyParser.urlencoded({ extended: false }));

subpath_v1.use('/encipher', encipher);

if(!firewalla.isProduction()) {
  // apis for development purpose only, do NOT enable them in production
  subpath_v1.use('/sys', system);
  subpath_v1.use('/message', message);
  subpath_v1.use('/ss', shadowsocks);
  subpath_v1.use('/dns', dnsmasq);

  let subpath_docs = express();
  app.use("/docs", subpath_docs);
  subpath_docs.use("/", express.static('dist'));

  swagger.setAppHandler(subpath_docs);

  subpath_docs.get('/', function (req, res) {
    res.sendfile(__dirname + '/dist/index.html');
  });

  swagger.configureSwaggerPaths('', '/docs/api-docs', '');
}

if(require('fs').existsSync("/.dockerenv")) {
  // enable direct pairing in docker environment, since iphone simulator and docker can't be in same subnet
  // DO NOT ENABLE THIS IN PRODUCTION -- SECURITY RISK
  let devicePairing = require('./routes/devicePairing');
  subpath_v1.use('/device', devicePairing)
}

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;

swagger.setApiInfo({
    title: "Firewalla API",
    description: "API to do something, manage something...",
    termsOfServiceUrl: "",
    contact: "tt@firewalla.com",
    license: "",
    licenseUrl: ""
});

var domain = 'localhost';
if(argv.domain !== undefined)
    domain = argv.domain;
else
    console.log('No --domain=xxx specified, taking default hostname "localhost".');
var applicationUrl = 'http://' + domain;
swagger.configure(applicationUrl, '1.0.0');

<commit_msg>bug fix<commit_after>'use strict';

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var argv = require('minimist')(process.argv.slice(2));
var swagger = require("swagger-node-express");
const passport = require('passport');
var Strategy = require('passport-http-bearer').Strategy;
var db = require('./db');

let Firewalla = require('../net2/Firewalla.js');
let firewalla = new Firewalla();

passport.use(new Strategy(
  function(token, cb) {
    db.users.findByToken(token, function(err, user) {
      if (err) { return cb(err); }
      if (!user) { return cb(null, false); }
      return cb(null, user);
    });
  }));

var system = require('./routes/system');
var message = require('./routes/message');
var shadowsocks = require('./routes/shadowsocks');
var encipher = require('./routes/fastencipher2');
let dnsmasq = require('./routes/dnsmasq');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

var subpath_v1 = express();
app.use("/v1", subpath_v1);
subpath_v1.use(passport.initialize());
subpath_v1.use(passport.session());
subpath_v1.use(bodyParser.json());
subpath_v1.use(bodyParser.urlencoded({ extended: false }));

subpath_v1.use('/encipher', encipher);

if(!firewalla.isProduction()) {
  // apis for development purpose only, do NOT enable them in production
  subpath_v1.use('/sys', system);
  subpath_v1.use('/message', message);
  subpath_v1.use('/ss', shadowsocks);
  subpath_v1.use('/dns', dnsmasq);

  let subpath_docs = express();
  app.use("/docs", subpath_docs);
  subpath_docs.use("/", express.static('dist'));

  swagger.setAppHandler(subpath_docs);

  subpath_docs.get('/', function (req, res) {
    res.sendfile(__dirname + '/dist/index.html');
  });

  swagger.configureSwaggerPaths('', '/docs/api-docs', '');
  swagger.configure(applicationUrl, '1.0.0');

  swagger.setApiInfo({
    title: "Firewalla API",
    description: "API to do something, manage something...",
    termsOfServiceUrl: "",
    contact: "tt@firewalla.com",
    license: "",
    licenseUrl: ""
  });

}

if(require('fs').existsSync("/.dockerenv")) {
  // enable direct pairing in docker environment, since iphone simulator and docker can't be in same subnet
  // DO NOT ENABLE THIS IN PRODUCTION -- SECURITY RISK
  let devicePairing = require('./routes/devicePairing');
  subpath_v1.use('/device', devicePairing)
}

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;

var domain = 'localhost';
if(argv.domain !== undefined)
    domain = argv.domain;
else
    console.log('No --domain=xxx specified, taking default hostname "localhost".');
var applicationUrl = 'http://' + domain;

<|endoftext|>


<commit_before>var jest = require('jest')
    ,common = require('./common')
    ,models = require('../models')
    ,og_action = require('../og/og').doAction
    ,_ = require('underscore')
    ,mail = require('../lib/mail');

var SendMailResource = module.exports = jest.Resource.extend({
    init:function() {
        this._super();
        this.allowed_methods = ['post'];
        this.authentication = new common.SessionAuthentication();
        this.fields = {};
        this.update_fields = {
            body : null
        };
    },

    create_obj: function(req,fields,callback) {
        var user = req.user;
        var to = req.body.mail_config.to || 'info@uru.org.il';
        var subject = req.body.mail_config.subject || 'NO MORE MAILS FOR ' + user.email;
        var explanation = (req.body.mail_config.explanation ?  req.body.mail_config.explanation + " " + user.email : 'The reason is:' + '
' + req.body.mail_config.body;
        mail.sendMail(to, explanation, subject, function(err){
            callback(err);
        });
    }
});

<commit_msg>add )<commit_after>var jest = require('jest')
    ,common = require('./common')
    ,models = require('../models')
    ,og_action = require('../og/og').doAction
    ,_ = require('underscore')
    ,mail = require('../lib/mail');

var SendMailResource = module.exports = jest.Resource.extend({
    init:function() {
        this._super();
        this.allowed_methods = ['post'];
        this.authentication = new common.SessionAuthentication();
        this.fields = {};
        this.update_fields = {
            body : null
        };
    },

    create_obj: function(req,fields,callback) {
        var user = req.user;
        var to = req.body.mail_config.to || 'info@uru.org.il';
        var subject = req.body.mail_config.subject || 'NO MORE MAILS FOR ' + user.email;
        var explanation = (req.body.mail_config.explanation ?  req.body.mail_config.explanation + " " + user.email : 'The reason is:' + '
' + req.body.mail_config.body);
        mail.sendMail(to, explanation, subject, function(err){
            callback(err);
        });
    }
});

<|endoftext|>


<commit_before>import mongoose from 'mongoose';

import config from '../../config';
import logger from '../logger';

mongoose.Promise = global.Promise;

const connection = mongoose.connect(config.database.uri, {
	autoIndex: true,
	reconnectTries: Number.MAX_VALUE,
	reconnectInterval: 500,
	poolSize: 50,
	bufferMaxEntries: 0,
	keepAlive: 120,
});

connection
	.then((db) => {
		logger.info(
			`Successfully connected to ${config.database.uri} MongoDB cluster in ${
				config.env
			} mode.`,
		);
		return db;
	})
	.catch((err) => {
		if (err.message.code === 'ETIMEDOUT') {
			logger.info('Attempting to re-establish database connection.');
			mongoose.connect(config.database.uri);
		} else {
			logger.error('Error while attempting to connect to database:', { err });
		}
	});

export default connection;
<commit_msg>mongo useNewUrlParser<commit_after>import mongoose from 'mongoose';

import config from '../../config';
import logger from '../logger';

mongoose.Promise = global.Promise;

const connection = mongoose.connect(config.database.uri, {
	autoIndex: true,
	reconnectTries: Number.MAX_VALUE,
	reconnectInterval: 500,
	poolSize: 50,
	bufferMaxEntries: 0,
	keepAlive: 120,
	useNewUrlParser: true,
});

connection
	.then((db) => {
		logger.info(
			`Successfully connected to ${config.database.uri} MongoDB cluster in ${
				config.env
			} mode.`,
		);
		return db;
	})
	.catch((err) => {
		if (err.message.code === 'ETIMEDOUT') {
			logger.info('Attempting to re-establish database connection.');
			mongoose.connect(config.database.uri);
		} else {
			logger.error('Error while attempting to connect to database:', { err });
		}
	});

export default connection;
<|endoftext|>