<commit_before>// Application class
// Requries a datamodel in the "Model" module
// Manages switching ui components which are views and associated viewmodels
// Views are HTML partial pages, ViewModels are the underlying databindings and behavior
// of the View. The ViewModel should take and return data to the Model object.
define(['knockout', 'underscore', 'jquery', 'guid'],
function (ko, _, $, Guid)
{
    // Page Composition Algorithm:
    // -----------------------------------
    // 1. Find all data-component nodes and insert into queue (processing the DOM breadth-first)
    // 2. Take a node off the queue, parse the nodes parameters if any
    // 3. Add events and fields to the node and loaded component
    // 4. Find the components parent, use Application if none, and add variable containers for that component
    // 5. Add visibility and context databindings to the root node
    // 6. Insert the expanded template into the components root as html
    // 7. Parse the components html children for data-component nodes and add them to the queue
    // 8. When the queue is empty, the page is finished loading

    // Application public interface
    var Application = {

        Model: ko.observable({}),

        Name: ko.observable(''),

        Components: ko.observableArray([]),

        Visible: ko.observable(true),

        Children: ko.observableArray(),

        // Composes the page and applies data bindings
        Compose: function (components)
        {
            this.Components(components);
            LoadComponents();

            // Apply initial component types
            TypeComponents($('body'));

            var topLevelComponents = $('[data-component]').toArray();
            var expandedModels = ExpandComponents(topLevelComponents);

            // trigger loaded event from bottom up
            expandedModels.reverse();
            _(expandedModels).each(function (comp) { $(comp).triggerHandler('Loaded'); });

            // Finally trigger that the application as a whole is loaded
            $(this).triggerHandler('Loaded');

            ko.applyBindings(this);
        },

        // Activate a component, attached to all child components ViewModels
        Activate: function ()
        {
            this.Visible(true);

            if (this.View && this.View().data('componentType') == 'collection')
            {
                var data = ko.dataFor(this.View().get(0));

                var params = [data].concat(arguments);
                $(this).triggerHandler('Activate', params);
            }
            else
            {
                $(this).triggerHandler('Activate', arguments);
            }
        },

        // Finishes a component, attached to all child components ViewModels
        Finish: function ()
        {
            this.Visible(false);
            $(this).triggerHandler('Finish', arguments);
        },

        // Find an component by id using a depth first search (recursive)
        Find: function (componentId)
        {
            var target = null;

            _(this.Children()).each(function (child)
            {
                var foundChild = null;
                if (child.Uid == componentId)
                {
                    foundChild = child;
                }
                else
                {
                    foundChild = child.Find(componentId);
                }

                if (foundChild != null)
                {
                    target = foundChild;
                }
            });

            return target;
        },

        // Inject a component dynamically
        InjectComponent: function (component)
        {
            // Expand the component into the DOM
            var viewModels = ExpandComponent(component);
            viewModels.reverse();

            // Trigger loaded handlers from the bottom up
            _(viewModels).each(function (vm) { $(vm).triggerHandler('Loaded'); });

            // Apply bindings to the root level injected node using its parent
            var parent = _(viewModels).last().Parent();
            ko.applyBindingsToNode(component, null, parent);

            // Return the root of the injected componentsQueue
            return _(viewModels).last();
        }
    }

    // Application private interface

    // Parses a javascript object from a string, NOT json
    function ParseJsObject(string)
    {
        // Use 'eval' to create a javascript object from the malformed JSON
        // NOTE: there are some security concerns with this method
        var parenString = '(' + string + ')'; // object literals must be enclosed in parenthesis for eval to work properly
        var obj = eval(parenString);

        return obj;
    }

    // Loads view templates and styles for each component
    function _LoadComponents()
    {
        // Put JQuery AJAX into synchronous mode for this algorithm to work, we will clear this flag once page loading is complete
        $.ajaxSetup({ async: false });

        // Preload styles and templates for each component
        _(this.Components()).each(function (comp)
        {
            // Append the style node to the pages head
            if ('Style' in comp)
            {
                var styleLink = $('<link rel="stylesheet" type="text/css" href="' + comp.Style + '"/>');
                $('head').append(styleLink);
            }

            // Load the view template and store it for later
            $.get(comp.View, {}, function (viewData)
            {
                comp.Template = viewData;
            });
        });

        // Put JQuery back into asynchronous mode for future ajax requests
        $.ajaxSetup({ async: true });
    }
    var LoadComponents = _.bind(_LoadComponents, Application);

    // Shorthand to expand a single component
    // returns a tree structure in an array of the expanded components
    function _ExpandComponent(component)
    {
        return ExpandComponents([component]);
    }
    var ExpandComponent = _.bind(_ExpandComponent, Application);

    // Expands a data-component element into its component, uses a breadth-first traversal
    // Returns a list of the constructed view models that were expanded
    function _ExpandComponents(components)
    {
        var componentsQueue = components;
        var viewModels = [];

        while (componentsQueue.length > 0)
        {
            var componentRoot = $(componentsQueue.shift()); // dequeue operation
            var componentName = componentRoot.data('component');

            // Check the component type to make sure it isnt a collection component
            var componentType = componentRoot.data('componentType');
            if (componentType != 'collection')
            {
                // Find the component description
                var component = _(this.Components()).findWhere({ Name: componentName });
                if (component)
                {
                    var viewModel = BuildComponent(componentRoot, component);

                    // Add the view model to the list of view models that were processed
                    viewModels.push(viewModel);

                    // Find any child data-component nodes and push them onto the queue
                    var childComponents = componentRoot.find('[data-component]').toArray();
                    _(childComponents).each(function (child)
                    {
                        componentsQueue.push(child);
                    });
                }
            }
        }

        return viewModels;
    }
    var ExpandComponents = _.bind(_ExpandComponents, Application);

    function _BuildComponent(componentRoot, component, type)
    {
        // Get the components view parameters
        var params = componentRoot.data('parameters');
        if (params)
        {
            params = ParseJsObject(params);
        }

        // Get the name to use as a field name
        var fieldName = componentRoot.data('name');

        // Create the view model and add standard fields
        var viewModel = new component.ViewModel();
        viewModel.Visible = ko.observable(false); // Hidden by default
        viewModel.Name = fieldName;
        viewModel.ViewParameters = params;
        viewModel.Children = ko.observableArray();
        viewModel.Find = this.Find;
        viewModel.Activate = this.Activate;
        viewModel.Finish = this.Finish;
        viewModel.Uid = Guid.NewGuid();
        viewModel.View = function () { return $('#' + this.Uid); };
        viewModel.Remove = function() { this.View.remove(); };

        // Find the parent of the view, using app when there is no parent
        var parentRoot = componentRoot.parent().closest('[data-component]');
        var parent = this;
        if (parentRoot.length > 0)
        {
            var parent = this.Find(parentRoot.attr('id'));
        }

        // Add the viewmodel to its parent and add a parent property to the viewmodel
        parent.Children.push(viewModel);
        viewModel.Parent = ko.observable(parent);

        if (type != 'collection')
        {
            parent[fieldName] = ko.observable(viewModel);

            // Add remove handler to clean up viewmodel when removed from parent
            viewModel.View.on('DOMNodeRemoved', function ()
            {
                delete parent[fieldName];

                var childIndex = parent.Children.indexOf(viewModel);
                if(childIndex > -1)
                {
                    parent.Children.splice(childIndex, 1);
                }

                $(viewModel).triggerHandler('Removed');
                $(parent).triggerHandler('ChildRemoved', viewModel);
            });

            // Add databinding for visibility and context to the component root node
            componentRoot.attr('data-bind', 'visible: ' + fieldName + '().Visible, with: ' + fieldName);
        }
        else
        {
            if (!(fieldName in parent))
            {
                parent[fieldName] = {};
            }

            parent[fieldName][viewModel.Uid] = ko.observable(viewModel);

            // Add remove handler to clean up viewmodel when removed from parent
            viewModel.View.on('DOMNodeRemoved', function ()
            {
                delete parent[fieldName][viewModel.Uid];

                if($.isEmptyObject(parent[fieldName]))
                {
                    delete parent[fieldName];
                }

                var childIndex = parent.Children.indexOf(viewModel);
                if(childIndex > -1)
                {
                    parent.Children.splice(childIndex, 1);
                }

                $(viewModel).triggerHandler('Removed');
                $(parent).triggerHandler('ChildRemoved', viewModel);
            });

            // Add databinding for visibility and context to the component root node
            componentRoot.attr('data-bind', 'visible: $parent.' + fieldName + '["' + viewModel.Uid + '"]().Visible, with: $parent.' + fieldName + '["' + viewModel.Uid + '"]');
        }

        componentRoot.attr('id', viewModel.Uid);
        componentRoot.hide();   // Hide by default so that the views don't flash on the screen before knockout kicks in

        // Compile the view using its parameters
        var compiledView = _.template(component.Template, params);

        // Insert the compiled view into the DOM
        componentRoot.html(compiledView);

        // Type any child components
        TypeComponents(componentRoot);

        return viewModel;
    }
    var BuildComponent = _.bind(_BuildComponent, Application);

    function TypeComponents(root)
    {
        // Select foreach data-binds and mark components inside as having type "collection"
        var collectionComponents = root.find('[data-bind*="foreach:"] [data-component]');
        collectionComponents.attr('data-component-type', 'collection');

        // Select if and ifnot data-binds and mark components inside as having type "conditional"
        var conditionalComponents = root.find('[data-bind*="if:"],[data-bind*="ifnot:"] [data-component]');
        conditionalComponents.attr('data-component-type', 'conditional');
    }

    // Updates the title element when the application name is set
    Application.Name.subscribe(function (value)
    {
        var titleElem = $('title');
        if (titleElem.length > 0)
        {
            titleElem.text(value);
        }
        else
        {
            titleElem = $('<title>' + value + '</title>');
            $('head').append(titleElem);
        }
    });

    // Add node processor for foreach bindings
    ko.bindingProvider.instance.preprocessNode = function (node)
    {
        var componentType = $(node).data('componentType');
        var componentName = $(node).data('component');

        if (componentType && componentType == 'collection')
        {
            // Find the component description
            var component = _(Application.Components()).findWhere({ Name: componentName });
            if (component)
            {
                var viewModel = BuildComponent($(node), component, componentType);

                var childComponents = viewModel.View().find('[data-component]').toArray();
                var expandedModels = ExpandComponents(childComponents);

                // trigger loaded event from bottom up
                expandedModels.reverse();
                _(expandedModels).each(function (comp) { $(comp).triggerHandler('Loaded'); });

                $(viewModel).triggerHandler('Loaded');
            }
        }
        else if (componentType && componentType == 'conditional')
        {
            Application.InjectComponent(node);
        }
    };

    return Application;
});
<commit_msg>Changed childremoved argument to array<commit_after>// Application class
// Requries a datamodel in the "Model" module
// Manages switching ui components which are views and associated viewmodels
// Views are HTML partial pages, ViewModels are the underlying databindings and behavior
// of the View. The ViewModel should take and return data to the Model object.
define(['knockout', 'underscore', 'jquery', 'guid'],
function (ko, _, $, Guid)
{
    // Page Composition Algorithm:
    // -----------------------------------
    // 1. Find all data-component nodes and insert into queue (processing the DOM breadth-first)
    // 2. Take a node off the queue, parse the nodes parameters if any
    // 3. Add events and fields to the node and loaded component
    // 4. Find the components parent, use Application if none, and add variable containers for that component
    // 5. Add visibility and context databindings to the root node
    // 6. Insert the expanded template into the components root as html
    // 7. Parse the components html children for data-component nodes and add them to the queue
    // 8. When the queue is empty, the page is finished loading

    // Application public interface
    var Application = {

        Model: ko.observable({}),

        Name: ko.observable(''),

        Components: ko.observableArray([]),

        Visible: ko.observable(true),

        Children: ko.observableArray(),

        // Composes the page and applies data bindings
        Compose: function (components)
        {
            this.Components(components);
            LoadComponents();

            // Apply initial component types
            TypeComponents($('body'));

            var topLevelComponents = $('[data-component]').toArray();
            var expandedModels = ExpandComponents(topLevelComponents);

            // trigger loaded event from bottom up
            expandedModels.reverse();
            _(expandedModels).each(function (comp) { $(comp).triggerHandler('Loaded'); });

            // Finally trigger that the application as a whole is loaded
            $(this).triggerHandler('Loaded');

            ko.applyBindings(this);
        },

        // Activate a component, attached to all child components ViewModels
        Activate: function ()
        {
            this.Visible(true);

            if (this.View && this.View().data('componentType') == 'collection')
            {
                var data = ko.dataFor(this.View().get(0));

                var params = [data].concat(arguments);
                $(this).triggerHandler('Activate', params);
            }
            else
            {
                $(this).triggerHandler('Activate', arguments);
            }
        },

        // Finishes a component, attached to all child components ViewModels
        Finish: function ()
        {
            this.Visible(false);
            $(this).triggerHandler('Finish', arguments);
        },

        // Find an component by id using a depth first search (recursive)
        Find: function (componentId)
        {
            var target = null;

            _(this.Children()).each(function (child)
            {
                var foundChild = null;
                if (child.Uid == componentId)
                {
                    foundChild = child;
                }
                else
                {
                    foundChild = child.Find(componentId);
                }

                if (foundChild != null)
                {
                    target = foundChild;
                }
            });

            return target;
        },

        // Inject a component dynamically
        InjectComponent: function (component)
        {
            // Expand the component into the DOM
            var viewModels = ExpandComponent(component);
            viewModels.reverse();

            // Trigger loaded handlers from the bottom up
            _(viewModels).each(function (vm) { $(vm).triggerHandler('Loaded'); });

            // Apply bindings to the root level injected node using its parent
            var parent = _(viewModels).last().Parent();
            ko.applyBindingsToNode(component, null, parent);

            // Return the root of the injected componentsQueue
            return _(viewModels).last();
        }
    }

    // Application private interface

    // Parses a javascript object from a string, NOT json
    function ParseJsObject(string)
    {
        // Use 'eval' to create a javascript object from the malformed JSON
        // NOTE: there are some security concerns with this method
        var parenString = '(' + string + ')'; // object literals must be enclosed in parenthesis for eval to work properly
        var obj = eval(parenString);

        return obj;
    }

    // Loads view templates and styles for each component
    function _LoadComponents()
    {
        // Put JQuery AJAX into synchronous mode for this algorithm to work, we will clear this flag once page loading is complete
        $.ajaxSetup({ async: false });

        // Preload styles and templates for each component
        _(this.Components()).each(function (comp)
        {
            // Append the style node to the pages head
            if ('Style' in comp)
            {
                var styleLink = $('<link rel="stylesheet" type="text/css" href="' + comp.Style + '"/>');
                $('head').append(styleLink);
            }

            // Load the view template and store it for later
            $.get(comp.View, {}, function (viewData)
            {
                comp.Template = viewData;
            });
        });

        // Put JQuery back into asynchronous mode for future ajax requests
        $.ajaxSetup({ async: true });
    }
    var LoadComponents = _.bind(_LoadComponents, Application);

    // Shorthand to expand a single component
    // returns a tree structure in an array of the expanded components
    function _ExpandComponent(component)
    {
        return ExpandComponents([component]);
    }
    var ExpandComponent = _.bind(_ExpandComponent, Application);

    // Expands a data-component element into its component, uses a breadth-first traversal
    // Returns a list of the constructed view models that were expanded
    function _ExpandComponents(components)
    {
        var componentsQueue = components;
        var viewModels = [];

        while (componentsQueue.length > 0)
        {
            var componentRoot = $(componentsQueue.shift()); // dequeue operation
            var componentName = componentRoot.data('component');

            // Check the component type to make sure it isnt a collection component
            var componentType = componentRoot.data('componentType');
            if (componentType != 'collection')
            {
                // Find the component description
                var component = _(this.Components()).findWhere({ Name: componentName });
                if (component)
                {
                    var viewModel = BuildComponent(componentRoot, component);

                    // Add the view model to the list of view models that were processed
                    viewModels.push(viewModel);

                    // Find any child data-component nodes and push them onto the queue
                    var childComponents = componentRoot.find('[data-component]').toArray();
                    _(childComponents).each(function (child)
                    {
                        componentsQueue.push(child);
                    });
                }
            }
        }

        return viewModels;
    }
    var ExpandComponents = _.bind(_ExpandComponents, Application);

    function _BuildComponent(componentRoot, component, type)
    {
        // Get the components view parameters
        var params = componentRoot.data('parameters');
        if (params)
        {
            params = ParseJsObject(params);
        }

        // Get the name to use as a field name
        var fieldName = componentRoot.data('name');

        // Create the view model and add standard fields
        var viewModel = new component.ViewModel();
        viewModel.Visible = ko.observable(false); // Hidden by default
        viewModel.Name = fieldName;
        viewModel.ViewParameters = params;
        viewModel.Children = ko.observableArray();
        viewModel.Find = this.Find;
        viewModel.Activate = this.Activate;
        viewModel.Finish = this.Finish;
        viewModel.Uid = Guid.NewGuid();
        viewModel.View = function () { return $('#' + this.Uid); };
        viewModel.Remove = function() { this.View.remove(); };

        // Find the parent of the view, using app when there is no parent
        var parentRoot = componentRoot.parent().closest('[data-component]');
        var parent = this;
        if (parentRoot.length > 0)
        {
            var parent = this.Find(parentRoot.attr('id'));
        }

        // Add the viewmodel to its parent and add a parent property to the viewmodel
        parent.Children.push(viewModel);
        viewModel.Parent = ko.observable(parent);

        if (type != 'collection')
        {
            parent[fieldName] = ko.observable(viewModel);

            // Add remove handler to clean up viewmodel when removed from parent
            viewModel.View.on('DOMNodeRemoved', function ()
            {
                delete parent[fieldName];

                var childIndex = parent.Children.indexOf(viewModel);
                if(childIndex > -1)
                {
                    parent.Children.splice(childIndex, 1);
                }

                $(viewModel).triggerHandler('Removed');
                $(parent).triggerHandler('ChildRemoved', [viewModel]);
            });

            // Add databinding for visibility and context to the component root node
            componentRoot.attr('data-bind', 'visible: ' + fieldName + '().Visible, with: ' + fieldName);
        }
        else
        {
            if (!(fieldName in parent))
            {
                parent[fieldName] = {};
            }

            parent[fieldName][viewModel.Uid] = ko.observable(viewModel);

            // Add remove handler to clean up viewmodel when removed from parent
            viewModel.View.on('DOMNodeRemoved', function ()
            {
                delete parent[fieldName][viewModel.Uid];

                if($.isEmptyObject(parent[fieldName]))
                {
                    delete parent[fieldName];
                }

                var childIndex = parent.Children.indexOf(viewModel);
                if(childIndex > -1)
                {
                    parent.Children.splice(childIndex, 1);
                }

                $(viewModel).triggerHandler('Removed');
                $(parent).triggerHandler('ChildRemoved', [viewModel]);
            });

            // Add databinding for visibility and context to the component root node
            componentRoot.attr('data-bind', 'visible: $parent.' + fieldName + '["' + viewModel.Uid + '"]().Visible, with: $parent.' + fieldName + '["' + viewModel.Uid + '"]');
        }

        componentRoot.attr('id', viewModel.Uid);
        componentRoot.hide();   // Hide by default so that the views don't flash on the screen before knockout kicks in

        // Compile the view using its parameters
        var compiledView = _.template(component.Template, params);

        // Insert the compiled view into the DOM
        componentRoot.html(compiledView);

        // Type any child components
        TypeComponents(componentRoot);

        return viewModel;
    }
    var BuildComponent = _.bind(_BuildComponent, Application);

    function TypeComponents(root)
    {
        // Select foreach data-binds and mark components inside as having type "collection"
        var collectionComponents = root.find('[data-bind*="foreach:"] [data-component]');
        collectionComponents.attr('data-component-type', 'collection');

        // Select if and ifnot data-binds and mark components inside as having type "conditional"
        var conditionalComponents = root.find('[data-bind*="if:"],[data-bind*="ifnot:"] [data-component]');
        conditionalComponents.attr('data-component-type', 'conditional');
    }

    // Updates the title element when the application name is set
    Application.Name.subscribe(function (value)
    {
        var titleElem = $('title');
        if (titleElem.length > 0)
        {
            titleElem.text(value);
        }
        else
        {
            titleElem = $('<title>' + value + '</title>');
            $('head').append(titleElem);
        }
    });

    // Add node processor for foreach bindings
    ko.bindingProvider.instance.preprocessNode = function (node)
    {
        var componentType = $(node).data('componentType');
        var componentName = $(node).data('component');

        if (componentType && componentType == 'collection')
        {
            // Find the component description
            var component = _(Application.Components()).findWhere({ Name: componentName });
            if (component)
            {
                var viewModel = BuildComponent($(node), component, componentType);

                var childComponents = viewModel.View().find('[data-component]').toArray();
                var expandedModels = ExpandComponents(childComponents);

                // trigger loaded event from bottom up
                expandedModels.reverse();
                _(expandedModels).each(function (comp) { $(comp).triggerHandler('Loaded'); });

                $(viewModel).triggerHandler('Loaded');
            }
        }
        else if (componentType && componentType == 'conditional')
        {
            Application.InjectComponent(node);
        }
    };

    return Application;
});
<|endoftext|>


<commit_before><commit_msg>Update project refluxjs to v0.4.0<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * Name: QuizziPedia::Front-End::QML::createJSON;
 * Description: questo file contiene le funzioni che permettono la generazione
 * del json a partire da un testo validato dal parser QML;
 * Creation data: 27-04-2016;
 * Author: Matteo Gnoato.
 ********************************************************************************
 * Updates history
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Ottimizzati i cicli for delle funzioni in modo da minimizzare
 * la computazione
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Risolto problemi di formazione valida del json finale
 * per la domanda custom
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Risolto problemi di formazione valida del json finale
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createCustom che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createCollegamentoelementi che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createSpaziVuoti che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createAreaCliccabile che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createOrdinamentoStringhe che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createOrdinamentoImmagini che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createRispostaMultipla che creea
 * la parte JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createVF che creea la parte JSON riguardante
 * la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione che crea la parte json dei campi comuni
 * a tutte le tipologie di domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 *******************************************************************************/

createJSON = function(corpo, res, tipologia, topic){
    var campiComuni = "{ \n " +
        "\"makeWith\" : \"qml\" , \n" +
        " \"language\" : " + "\"it\"" + ", \n";
    campiComuni = campiComuni + "\"topic\" : \"" + topic + "\" , \n " ;
    var jsonString = "\n \"question\" :[ \n { \n";
    var jsonKey = "";
    if(corpo.hasOwnProperty('keywords')){
        jsonKey = " , \n \"keywords\" : \n [ ";
        for(k = 0 ; k < corpo.keywords.length ; k++){
            if(k == corpo.keywords.length-1){
                jsonKey = jsonKey + "\"" + corpo.keywords[k] + "\"";
            }
            else{
                jsonKey = jsonKey + "\"" + corpo.keywords[k] + "\" ,";
            }
        }
        jsonKey = jsonKey + " \n ]";
    }
    var jsonStatistic = "\n }";

    if(tipologia == "veroFalso") {
         jsonString = jsonString + createJSONVF(corpo, res);
    }
    else if(tipologia ==  "rispostaMultipla"){
         jsonString = jsonString + createJSONrispostaMultipla(corpo, res);
    }
    else if(tipologia == "ordinamentoStringhe"){
         jsonString = jsonString + createJSONordinamentoStringhe(corpo, res);
    }
    else if(tipologia == "collegamentoElementi"){
         jsonString = jsonString + createJSONcollegamentoElementi(corpo, res);
    }
    else if(tipologia == "ordinamentoImmagini"){
         jsonString = jsonString + createJSONordinamentoImmagini(corpo, res);
    }
    else if(tipologia == "areaCliccabile"){
         jsonString = jsonString + createJSONareaCliccabile(corpo, res);
    }
    else if(tipologia == "riempimentoSpaziVuoti"){
        jsonString = jsonString + createJSONriepimentoSpaziVuoti(corpo, res);
    }
    else if(tipologia == "custom"){
        jsonString = jsonString + createJSONcustom(corpo, res);
    }

    jsonString = jsonString + "\n ]"; // questi dovrebbero chiudere il tag "question"
    jsonString = campiComuni + jsonString + jsonKey +  jsonStatistic;
    console.log(jsonString);
    var fine = JSON.parse(jsonString);
    return fine;
}

createJSONVF = function(corpo, res){
    var jsonString = " \"type\" : \"veroFalso\"" + ", \n ";
    if(corpo.hasOwnProperty('image')){
        jsonString =  jsonString + "\n \"image\" : \" " + corpo.image + "\" , \n";
    }
    jsonString = jsonString + " \n \"answers\" : [ \n { \n \"text\" : \"" + corpo.answer[0].text + "\" , \n";
    jsonString = jsonString + " \n \"isItRight\" : " + corpo.answer[0].isItRight + "\n" + "} \n] \n} \n";
    return jsonString;
}

createJSONrispostaMultipla = function(corpo){
    var jsonString = "\"type\" : \"rispostaMultipla\"" + ",";
    if(corpo.hasOwnProperty('image')){
        jsonString = jsonString + " \n \"image\" : " + "\"" + corpo.url + "\",";
    }
    if(corpo.hasOwnProperty('questionText')) {
        jsonString = jsonString + " \n \"questionText\" : " + "\"" +  corpo.questionText + "\",";
    }
    jsonString = jsonString + " \n \"answers\" : [{";
    for(var j = 0 ;j < corpo.answer.length ; j++){
        if(corpo.answer[j].hasOwnProperty('text')){
            jsonString = jsonString + " \n \"text\" : " + "\"" + corpo.answer[j].text + "\",";
        }
        if(corpo.answer[j].hasOwnProperty('url')){
            jsonString = jsonString + " \n \"url\" :" + "\"" + corpo.answer[j].url + "\",";
        }
        if(corpo.answer[j].hasOwnProperty('isItRight')){
            jsonString = jsonString + " \n \"isItRight\" : " +  corpo.answer[j].isItRight ;
        }
        if(j == corpo.answer.length -1) {
            jsonString = jsonString + "}";
        }
        else{
            jsonString = jsonString + "}, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONordinamentoStringhe = function(corpo){
    var jsonString = "\"type\" : \"ordinamentoStringhe\" ,";
    if(corpo.hasOwnProperty('questionText')){
        jsonString = jsonString + " \n \"questionText\" : " + "\"" +corpo.questionText + "\",";
    }
    if(corpo.hasOwnProperty('image')){
        jsonString = jsonString + " \n \"image\" : " + "\"" +corpo.image + "\",";
    }
    jsonString = jsonString + " \n \"answers\" : \n [ \n {";
    for(j = 0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + "\"text\" : " + "\"" + corpo.answer[j].text + "\",";
        jsonString = jsonString + "\"position\" : " + "\"" + corpo.answer[j].position + "\"";
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}";
        }
        else{
            jsonString = jsonString + "}, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONcollegamentoElementi = function(corpo){
    var jsonString = "\"type\" : \"collegamentoElementi\" ,";
    jsonString = jsonString + " \n \"questionText\" : " + "\"" + corpo.questionText + "\",";
    jsonString = jsonString + " \n \"answers\" : \n [ \n {";
    for(j=0 ; j < corpo.answer.length ; j++){
        if(corpo.answer[j].hasOwnProperty('text1')){
            jsonString = jsonString + " \n \"text1\" : \"" + corpo.answer[j].text1 + "\" ,";
        }
        if(corpo.answer[j].hasOwnProperty('text2')){
            jsonString = jsonString + " \n \"text2\" : \"" + corpo.answer[j].text2 + "\"";
        }
        if(corpo.answer[j].hasOwnProperty('url1')){
            jsonString = jsonString + " \n \"url1\" : \"" + corpo.answer[j].url1 + "\" ,";
        }
        if(corpo.answer[j].hasOwnProperty('url2')){
            jsonString = jsonString + " \n \"url2\" : \"" + corpo.answer[j].url2 + "\"";
        }
        if(j == corpo.answer.length -1){
            jsonString = jsonString + " \n }";
        }
        else{
            jsonString = jsonString + " \n }, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONordinamentoImmagini = function(corpo){
    var jsonString = "\"type\" : \"ordinamentoImmagini\" ,";
    jsonString = jsonString + "\"quesitonText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + "\"answers\" : [{";
    for(j = 0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + "\"url\" \"" + corpo.answer[j].url + "\" ,";
        jsonString = jsonString + "\"position\" \"" + corpo.answer[j].position + "\"";
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}]";
        }
        else {
            jsonString = jsonString + "}, \n {";
        }
    }
    return jsonString;

}

createJSONareaCliccabile = function(corpo){
    var jsonString = "\"type\" : \"areaCliccabile\" ,";
    jsonString = jsonString + "\n \"questionText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + " \n \"image\" : \"" + corpo.image + "\" ,";
    jsonString = jsonString + " \n \"resolution\" : { \n \"x\" : " + corpo.resolution.x + ", \n \"y\" : " + corpo.resolution.y + "\n }, \n";
    jsonString = jsonString + " \n \"answers\" : [ \n { ";
    for(j=0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + " \n \"x\" : \"" + corpo.answer[j].x + "\" ,";
        jsonString = jsonString + " \n  \"y\" : \"" + corpo.answer[j].y + "\"";
        if(corpo.answer[j].hasOwnProperty('text')){
            jsonString = jsonString + ", \n \"text\" : \" " + corpo.answer[j].text + "\"";
        }
        if(j == corpo.answer.length -1){
            jsonString = jsonString + " \n } \n ]";
        }
        else{
            jsonString = jsonString + " \n }, \n {";
        }
    }
    jsonString = jsonString + "}";
    return jsonString;
}

createJSONriepimentoSpaziVuoti = function(corpo){
    var jsonString = "\"type\" : \"spaziVuoti\" ,";
    jsonString = jsonString + " \n \"questionText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + " \n \"answers\" : [{";
    for(j=0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + " \n \"parolaNumero\" : " + corpo.answer[j].parolaNumero;
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}]";
        }
        else {
            jsonString = jsonString + " \n}, \n {";
        }
    }
    jsonString = jsonString + "}";

    return jsonString;
}

createJSONcustom = function(corpo){
    var jsonString = "";
    for(var i = 0 ; i < corpo.question.length ; i++){
        if(corpo.question[i].type == "veroFalso"){
            jsonString = jsonString + createJSONVF(corpo.question[i]);
        }
        else if(corpo.question[i].type == "rispostaMultipla"){
            jsonString = jsonString + createJSONrispostaMultipla(corpo.question[i]);
        }
        else if(corpo.question[i].type == "ordinamentoStringhe"){
            jsonString = jsonString + createJSONordinamentoStringhe(corpo.question[i]);
        }
        else if(corpo.question[i].type == "collegamentoElementi"){
            jsonString = jsonString + createJSONcollegamentoElementi(corpo.question[i]);
        }
        else if(corpo.question[i].type == "ordinamentoImmagini"){
            jsonString = jsonString + createJSONordinamentoImmagini(corpo.question[i]);
        }
        else if(corpo.question[i].type == "areaCliccabile"){
            jsonString = jsonString + createJSONareaCliccabile(corpo.question[i]);
        }
        else if(corpo.question[i].type == "riempimentoSpaziVuoti"){
            jsonString = jsonString + createJSONriepimentoSpaziVuoti(corpo.question[i]);
        }
        if(i == corpo.question.length -1){
           // jsonString = jsonString + "}]";   lasciare commentato
        }
        else{
            jsonString = jsonString + ", \n {";
        }
    }
    return jsonString;
}<commit_msg>update tag collegamento nel QML<commit_after>/*******************************************************************************
 * Name: QuizziPedia::Front-End::QML::createJSON;
 * Description: questo file contiene le funzioni che permettono la generazione
 * del json a partire da un testo validato dal parser QML;
 * Creation data: 27-04-2016;
 * Author: Matteo Gnoato.
 ********************************************************************************
 * Updates history
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Ottimizzati i cicli for delle funzioni in modo da minimizzare
 * la computazione
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Risolto problemi di formazione valida del json finale
 * per la domanda custom
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160513
 * Update data: 13-05-2016;
 * Description: Risolto problemi di formazione valida del json finale
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createCustom che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createCollegamentoelementi che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createSpaziVuoti che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createAreaCliccabile che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createOrdinamentoStringhe che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createOrdinamentoImmagini che creea la parte
 * JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createRispostaMultipla che creea
 * la parte JSON riguardante la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione createVF che creea la parte JSON riguardante
 * la tipologia specifica della domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 * Id: createJSON_20160527
 * Update data: 27-04-2016;
 * Description: Creata funzione che crea la parte json dei campi comuni
 * a tutte le tipologie di domanda;
 * Autore: Matteo Gnoato.
 *-------------------------------------------------------------------------------
 *******************************************************************************/

createJSON = function(corpo, res, tipologia, topic){
    var campiComuni = "{ \n " +
        "\"makeWith\" : \"qml\" , \n" +
        " \"language\" : " + "\"it\"" + ", \n";
    campiComuni = campiComuni + "\"topic\" : \"" + topic + "\" , \n " ;
    var jsonString = "\n \"question\" :[ \n { \n";
    var jsonKey = "";
    if(corpo.hasOwnProperty('keywords')){
        jsonKey = " , \n \"keywords\" : \n [ ";
        for(k = 0 ; k < corpo.keywords.length ; k++){
            if(k == corpo.keywords.length-1){
                jsonKey = jsonKey + "\"" + corpo.keywords[k] + "\"";
            }
            else{
                jsonKey = jsonKey + "\"" + corpo.keywords[k] + "\" ,";
            }
        }
        jsonKey = jsonKey + " \n ]";
    }
    var jsonStatistic = "\n }";

    if(tipologia == "veroFalso") {
         jsonString = jsonString + createJSONVF(corpo, res);
    }
    else if(tipologia ==  "rispostaMultipla"){
         jsonString = jsonString + createJSONrispostaMultipla(corpo, res);
    }
    else if(tipologia == "ordinamentoStringhe"){
         jsonString = jsonString + createJSONordinamentoStringhe(corpo, res);
    }
    else if(tipologia == "collegamentoElementi"){
         jsonString = jsonString + createJSONcollegamentoElementi(corpo, res);
    }
    else if(tipologia == "ordinamentoImmagini"){
         jsonString = jsonString + createJSONordinamentoImmagini(corpo, res);
    }
    else if(tipologia == "areaCliccabile"){
         jsonString = jsonString + createJSONareaCliccabile(corpo, res);
    }
    else if(tipologia == "riempimentoSpaziVuoti"){
        jsonString = jsonString + createJSONriepimentoSpaziVuoti(corpo, res);
    }
    else if(tipologia == "custom"){
        jsonString = jsonString + createJSONcustom(corpo, res);
    }

    jsonString = jsonString + "\n ]"; // questi dovrebbero chiudere il tag "question"
    jsonString = campiComuni + jsonString + jsonKey +  jsonStatistic;
    console.log(jsonString);
    var fine = JSON.parse(jsonString);
    return fine;
}

createJSONVF = function(corpo, res){
    var jsonString = " \"type\" : \"veroFalso\"" + ", \n ";
    if(corpo.hasOwnProperty('image')){
        jsonString =  jsonString + "\n \"image\" : \" " + corpo.image + "\" , \n";
    }
    jsonString = jsonString + " \n \"answers\" : [ \n { \n \"text\" : \"" + corpo.answer[0].text + "\" , \n";
    jsonString = jsonString + " \n \"isItRight\" : " + corpo.answer[0].isItRight + "\n" + "} \n] \n} \n";
    return jsonString;
}

createJSONrispostaMultipla = function(corpo){
    var jsonString = "\"type\" : \"rispostaMultipla\"" + ",";
    if(corpo.hasOwnProperty('image')){
        jsonString = jsonString + " \n \"image\" : " + "\"" + corpo.url + "\",";
    }
    if(corpo.hasOwnProperty('questionText')) {
        jsonString = jsonString + " \n \"questionText\" : " + "\"" +  corpo.questionText + "\",";
    }
    jsonString = jsonString + " \n \"answers\" : [{";
    for(var j = 0 ;j < corpo.answer.length ; j++){
        if(corpo.answer[j].hasOwnProperty('text')){
            jsonString = jsonString + " \n \"text\" : " + "\"" + corpo.answer[j].text + "\",";
        }
        if(corpo.answer[j].hasOwnProperty('url')){
            jsonString = jsonString + " \n \"url\" :" + "\"" + corpo.answer[j].url + "\",";
        }
        if(corpo.answer[j].hasOwnProperty('isItRight')){
            jsonString = jsonString + " \n \"isItRight\" : " +  corpo.answer[j].isItRight ;
        }
        if(j == corpo.answer.length -1) {
            jsonString = jsonString + "}";
        }
        else{
            jsonString = jsonString + "}, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONordinamentoStringhe = function(corpo){
    var jsonString = "\"type\" : \"ordinamentoStringhe\" ,";
    if(corpo.hasOwnProperty('questionText')){
        jsonString = jsonString + " \n \"questionText\" : " + "\"" +corpo.questionText + "\",";
    }
    if(corpo.hasOwnProperty('image')){
        jsonString = jsonString + " \n \"image\" : " + "\"" +corpo.image + "\",";
    }
    jsonString = jsonString + " \n \"answers\" : \n [ \n {";
    for(j = 0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + "\"text\" : " + "\"" + corpo.answer[j].text + "\",";
        jsonString = jsonString + "\"position\" : " + "\"" + corpo.answer[j].position + "\"";
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}";
        }
        else{
            jsonString = jsonString + "}, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONcollegamentoElementi = function(corpo){
    var jsonString = "\"type\" : \"collegamento\" ,";
    jsonString = jsonString + " \n \"questionText\" : " + "\"" + corpo.questionText + "\",";
    jsonString = jsonString + " \n \"answers\" : \n [ \n {";
    for(j=0 ; j < corpo.answer.length ; j++){
        if(corpo.answer[j].hasOwnProperty('text1')){
            jsonString = jsonString + " \n \"text1\" : \"" + corpo.answer[j].text1 + "\" ,";
        }
        if(corpo.answer[j].hasOwnProperty('text2')){
            jsonString = jsonString + " \n \"text2\" : \"" + corpo.answer[j].text2 + "\"";
        }
        if(corpo.answer[j].hasOwnProperty('url1')){
            jsonString = jsonString + " \n \"url1\" : \"" + corpo.answer[j].url1 + "\" ,";
        }
        if(corpo.answer[j].hasOwnProperty('url2')){
            jsonString = jsonString + " \n \"url2\" : \"" + corpo.answer[j].url2 + "\"";
        }
        if(j == corpo.answer.length -1){
            jsonString = jsonString + " \n }";
        }
        else{
            jsonString = jsonString + " \n }, \n {";
        }
    }
    jsonString = jsonString + "]}";
    return jsonString;
}

createJSONordinamentoImmagini = function(corpo){
    var jsonString = "\"type\" : \"ordinamentoImmagini\" ,";
    jsonString = jsonString + "\"quesitonText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + "\"answers\" : [{";
    for(j = 0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + "\"url\" \"" + corpo.answer[j].url + "\" ,";
        jsonString = jsonString + "\"position\" \"" + corpo.answer[j].position + "\"";
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}]";
        }
        else {
            jsonString = jsonString + "}, \n {";
        }
    }
    return jsonString;

}

createJSONareaCliccabile = function(corpo){
    var jsonString = "\"type\" : \"areaCliccabile\" ,";
    jsonString = jsonString + "\n \"questionText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + " \n \"image\" : \"" + corpo.image + "\" ,";
    jsonString = jsonString + " \n \"resolution\" : { \n \"x\" : " + corpo.resolution.x + ", \n \"y\" : " + corpo.resolution.y + "\n }, \n";
    jsonString = jsonString + " \n \"answers\" : [ \n { ";
    for(j=0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + " \n \"x\" : \"" + corpo.answer[j].x + "\" ,";
        jsonString = jsonString + " \n  \"y\" : \"" + corpo.answer[j].y + "\"";
        if(corpo.answer[j].hasOwnProperty('text')){
            jsonString = jsonString + ", \n \"text\" : \" " + corpo.answer[j].text + "\"";
        }
        if(j == corpo.answer.length -1){
            jsonString = jsonString + " \n } \n ]";
        }
        else{
            jsonString = jsonString + " \n }, \n {";
        }
    }
    jsonString = jsonString + "}";
    return jsonString;
}

createJSONriepimentoSpaziVuoti = function(corpo){
    var jsonString = "\"type\" : \"spaziVuoti\" ,";
    jsonString = jsonString + " \n \"questionText\" : \"" + corpo.questionText + "\" ,";
    jsonString = jsonString + " \n \"answers\" : [{";
    for(j=0 ; j < corpo.answer.length ; j++){
        jsonString = jsonString + " \n \"parolaNumero\" : " + corpo.answer[j].parolaNumero;
        if(j == corpo.answer.length -1){
            jsonString = jsonString + "}]";
        }
        else {
            jsonString = jsonString + " \n}, \n {";
        }
    }
    jsonString = jsonString + "}";

    return jsonString;
}

createJSONcustom = function(corpo){
    var jsonString = "";
    for(var i = 0 ; i < corpo.question.length ; i++){
        if(corpo.question[i].type == "veroFalso"){
            jsonString = jsonString + createJSONVF(corpo.question[i]);
        }
        else if(corpo.question[i].type == "rispostaMultipla"){
            jsonString = jsonString + createJSONrispostaMultipla(corpo.question[i]);
        }
        else if(corpo.question[i].type == "ordinamentoStringhe"){
            jsonString = jsonString + createJSONordinamentoStringhe(corpo.question[i]);
        }
        else if(corpo.question[i].type == "collegamentoElementi"){
            jsonString = jsonString + createJSONcollegamentoElementi(corpo.question[i]);
        }
        else if(corpo.question[i].type == "ordinamentoImmagini"){
            jsonString = jsonString + createJSONordinamentoImmagini(corpo.question[i]);
        }
        else if(corpo.question[i].type == "areaCliccabile"){
            jsonString = jsonString + createJSONareaCliccabile(corpo.question[i]);
        }
        else if(corpo.question[i].type == "riempimentoSpaziVuoti"){
            jsonString = jsonString + createJSONriepimentoSpaziVuoti(corpo.question[i]);
        }
        if(i == corpo.question.length -1){
           // jsonString = jsonString + "}]";   lasciare commentato
        }
        else{
            jsonString = jsonString + ", \n {";
        }
    }
    return jsonString;
}<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

/* eslint-disable no-console */
const fs = require('fs-extra');
const path = require('path');
const util = require('util');
const exec = require('child_process').exec;
const version = require('../../package.json').version;

const documentationPath = './docs/documentation';
const outputPath = '/tmp/documentation/';

function createTempDirectory() {
  return new Promise((resolve, reject) => {
    fs.emptyDir(outputPath, (error) => {
      if (error) {
        reject(error);
      }
      resolve();
    })
  });
}

function execute(command) {
  return new Promise((resolve, reject) => {
    exec(command, (error, stdout) => {
      if(error) {
        reject(error);
      }
      resolve(stdout.trim())
    });
  });
}

function gitClone(url, directory)  {
  return execute(util.format('git clone %s %s', url, directory));
}

function readFiles(directory, filelist) {
  if(directory[directory.length - 1] != '/') {
    directory = directory.concat('/');
  }

  const files = fs.readdirSync(directory);
  filelist = filelist || [];
  files.forEach((file) => {
    if (fs.statSync(directory + file).isDirectory()) {
      filelist = readFiles(directory + file + '/', filelist);
    } else {
      const originalPath = directory + file;
      const newPath = outputPath + originalPath
        .replace(documentationPath + '/', '')
        .replace('/', '-');
      filelist.push({
        originalPath,
        newPath
      });
    }
  });
  return filelist;
}

function copyFile(from, to, linksToReplace) {
  from = path.relative(process.cwd(), from);
  to = path.relative(process.cwd(), to);
  const replaceHyphen = new RegExp('-', 'gi');
  return new Promise((resolve, reject) => {
    fs.readFile(from, (error, data) => {
      if (error) {
        reject(error);
      }
      let fileData = data.toString();
      linksToReplace.forEach((link) => {
        const str = '\\(' + link.oldName.replace(replaceHyphen, '\\-') + '\\)';
        const r = new RegExp(str, 'gi');
        fileData = fileData.replace(r, link.newName);
      });
      fs.outputFile(to, fileData, (error2) => {
        if (error2) {
          reject(error2);
        }
        resolve();
      })
    })
  });
}

function createFiles() {
  const files = readFiles(documentationPath) || [];
  const linksToReplace = checkNameLinks(files);
  const copies = files.map(({ originalPath, newPath }) => copyFile(originalPath, newPath, linksToReplace));
  return Promise.all(copies);
}

function checkNameLinks(files) {
  return files.reduce((pValue, cValue) => {
    const oldName = cValue.originalPath.split('/').slice(-1).pop().replace('.md', '');
    const newName = '(' + cValue.newPath.split('/').slice(-1).pop().replace('.md', '') + ')';
    if (oldName !== newName) {
      pValue.push({
        oldName,
        newName
      });
    }
    return pValue;
  }, []);
}

(function() {
  Promise.resolve()
    .then(() => createTempDirectory())
    .then(() => gitClone('https://github.com/angular/angular-cli.wiki', outputPath))
    .then(() => createFiles())
    .then(() => process.chdir(outputPath))
    .then(() => execute('git add .'))
    .then(() => execute(`git commit -m ${version}`))
    .then(() => execute('git status'))
    .then((data) => {
      console.log(data);
    })
    .catch((error) => {
      console.log('error', error);
    })
})();<commit_msg>refactor: fix issues with docs scripts (#4893)<commit_after>#!/usr/bin/env node
'use strict';

/* eslint-disable no-console */
const exec = require('child_process').exec;
const fs = require('fs');
const path = require('path');
const temp = require('temp');
const util = require('util');
const version = require('../../package.json').version;

const documentationPath = path.join(__dirname, '../../docs/documentation');
const outputPath = temp.mkdirSync('angular-cli-docs');

function execute(command) {
  return new Promise((resolve, reject) => {
    exec(command, (error, stdout) => {
      if(error) {
        reject(error);
      }
      resolve(stdout.trim())
    });
  });
}

function readFiles(directory, filelist) {
  if(directory[directory.length - 1] != '/') {
    directory = directory.concat('/');
  }

  const files = fs.readdirSync(directory);
  filelist = filelist || [];
  files.forEach((file) => {
    if (fs.statSync(directory + file).isDirectory()) {
      filelist = readFiles(directory + file + '/', filelist);
    } else {
      const originalPath = directory + file;
      const newPath = outputPath + originalPath
        .replace(documentationPath + '/', '')
        .replace('/', '-');
      filelist.push({
        originalPath,
        newPath
      });
    }
  });
  return filelist;
}

function copyFile(from, to, linksToReplace) {
  from = path.relative(process.cwd(), from);
  to = path.relative(process.cwd(), to);
  const replaceHyphen = new RegExp('-', 'gi');
  return new Promise((resolve, reject) => {
    fs.readFile(from, (error, data) => {
      if (error) {
        reject(error);
      }
      let fileData = data.toString();
      linksToReplace.forEach((link) => {
        const str = '\\(' + link.oldName.replace(replaceHyphen, '\\-') + '\\)';
        const r = new RegExp(str, 'gi');
        fileData = fileData.replace(r, link.newName);
      });
      fs.writeFile(to, fileData, (error2) => {
        if (error2) {
          reject(error2);
        }
        resolve();
      })
    })
  });
}

function createFiles() {
  const files = readFiles(documentationPath) || [];
  const linksToReplace = checkNameLinks(files);
  const copies = files.map(({ originalPath, newPath }) => {
    return copyFile(originalPath, newPath, linksToReplace)
  });
  return Promise.all(copies);
}

function checkNameLinks(files) {
  return files.reduce((pValue, cValue) => {
    const oldName = cValue.originalPath.split('/').slice(-1).pop().replace('.md', '');
    const newName = '(' + cValue.newPath.split('/').slice(-1).pop().replace('.md', '') + ')';
    if (oldName !== newName) {
      pValue.push({
        oldName,
        newName
      });
    }
    return pValue;
  }, []);
}

Promise.resolve()
  .then(() => console.log(`Documentation Path: ${documentationPath}`))
  .then(() => console.log(`Wiki path: ${outputPath}`))
  .then(() => console.log('Cloning...'))
  .then(() => execute(`git clone "https://github.com/angular/angular-cli.wiki" ${outputPath}`))
  .then(() => console.log('Copying Files...'))
  .then(() => createFiles())
  .then(() => process.chdir(outputPath))
  .then(() => console.log('Committing...'))
  .then(() => execute('git add .'))
  .then(() => execute(`git commit -m "${version}"`))
  .then(() => execute('git push'))
  .then(() => console.log('Done...'))
  .catch(err => console.error(`Error:\n${err.message}`));
<|endoftext|>


<commit_before>var _ = require('underscore'),
    error = require('../error'),
    assets = require('../assets'),
    relations = require('../relations'),
    step = require('step');

exports.bundleRelations = function bundleRelations(siteGraph, relationsToBundle, cb) {
    assets[relationsToBundle[0].to.type].makeBundle(_.pluck(relationsToBundle, 'to'), error.passToFunction(cb, function (bundleAsset) {
        siteGraph.registerAsset(bundleAsset);
        var bundleRelation = new relations[relationsToBundle[0].type]({
            from: relationsToBundle[0].from,
            to: bundleAsset
        });
        siteGraph.attachAndRegisterRelation(bundleRelation, 'before', relationsToBundle[0]);
        relationsToBundle.forEach(function (relation) {
            siteGraph.detachAndUnregisterRelation(relation);
        });
        cb();
    }));
};
<commit_msg>transforms/bundleRelations: Re-register the relations of the bundled assets to the bundle.<commit_after>var _ = require('underscore'),
    error = require('../error'),
    assets = require('../assets'),
    relations = require('../relations'),
    step = require('step');

// Will break the existing assets pretty badly, be careful!

exports.bundleRelations = function bundleRelations(siteGraph, relationsToBundle, cb) {
    assets[relationsToBundle[0].to.type].makeBundle(_.pluck(relationsToBundle, 'to'), error.passToFunction(cb, function (bundleAsset) {
        bundleAsset.baseUrl = relationsToBundle[0].from.baseUrl;
        siteGraph.registerAsset(bundleAsset);
        var bundleRelation = new relations[relationsToBundle[0].type]({
            from: relationsToBundle[0].from,
            to: bundleAsset
        });
        siteGraph.attachAndRegisterRelation(bundleRelation, 'before', relationsToBundle[0]);
        relationsToBundle.forEach(function (relation) {
            siteGraph.detachAndUnregisterRelation(relation);
            siteGraph.findRelations('from', relation.to).forEach(function (relrel) {
                siteGraph.unregisterRelation(relrel);
                relrel.from = bundleAsset;
                siteGraph.registerRelation(relrel);
            });
        });
        cb();
    }));
};
<|endoftext|>


<commit_before>import React from 'react';
import Finalized from '../Sidebars/Finalized';
import Unfinalized from '../Sidebars/Unfinalized';
import AddItemButton from '../TravelObjectForms/AddItemButton'
import { Grid, Box } from '@material-ui/core'
import '../../styles/Trip.css'
import { FirebaseContext } from '../Firebase';
import MapComponent from "../Utilities/Map"
import { handleSuggestions } from "../../scripts/Suggestions"
import GetSuggestionButton from '../Utilities/GetSuggestionButton';

const config = {
    userCategories: ["bakery"],
    userBudget: 4,
    radius: "10000",
    timeRange: [new Date(2020, 7, 15, 2, 0), new Date(2020, 7, 15, 20, 0)],
    coordinates: { lat: 36.1699, lng: -115.1398 },
    items: new Set([])
}
//"ChIJmx1Uvc3FyIARdp6ftqC7Gd8","ChIJDRyBe_nEyIARH77JCHU27r8","ChIJVcuReVnbyIARXwAzHqxeAnk","ChIJ_YX8a9LGyIARrcojBX4AgtU"
export default class Trip extends React.Component {
    static contextType = FirebaseContext;
    constructor(props) {
        super(props);

        this.state = {
            reference: "/users/" + sessionStorage.getItem("userId") + "/trips/" + sessionStorage.getItem("tripId"),
            items: null,
            tripSetting: null,
            selectedObject: null,
            today: {
                events: [],
                date: null
            },
            map: null,
            service: null,
            queryResults: null
        }

        this.handleRemoveItem = this.handleRemoveItem.bind(this);
        this.handleEditItem = this.handleEditItem.bind(this);
        this.handleAddItem = this.handleAddItem.bind(this);
        this.handleEditTripSetting = this.handleEditTripSetting.bind(this);
        this.handleSelectedObject = this.handleSelectedObject.bind(this);
        this.handleChangeDisplayDate = this.handleChangeDisplayDate.bind(this);
        this.setMap = this.setMap.bind(this);
    }

    componentDidMount() {
        let travelObjectList = [];
        this.context.getTrip(this.state.reference)
            .then(data => {
                let trip = data.data();
                this.setState({
                    tripSetting: {
                        title: trip.title,
                        startDate: trip.startDate.toDate(),
                        endDate: trip.startDate.toDate(),
                        destination: trip.destination,
                        description: trip.description,
                        userPref: trip.userPref
                    }
                })

                trip.travelObjects.forEach(travelObject => {
                    travelObject.startDate = travelObject.startDate.toDate();
                    travelObject.endDate = travelObject.endDate.toDate();
                    travelObjectList.push(travelObject)
                });
                this.setState({ items: travelObjectList });
            })
            .catch(error => {
                console.log("Error retrieving trip data");
                console.error(error);
            });
    }

    handleRemoveItem(data) {
        this.context.deleteTravelObject(this.state.reference, data)
            .then(() => {
                this.setState({
                    items: this.state.items.filter((item) => item.id !== data.id)
                });
            })
            .catch(error => {
                console.log("Error Removing Item")
                console.error(error)
            });
    }

    handleEditItem(data) {
        let newItems = [];
        let itemToChange;
        this.state.items.forEach((item) => {
            if (item.id === data.id) {
                itemToChange = item;
                newItems.push(data);
            } else {
                newItems.push(item);
            }
        });
        this.context.editTravelObject(this.state.reference, itemToChange, data)
            .then(() => {
                this.setState({
                    items: newItems,
                    loaded: true
                });
            })
            .catch((error) => {
                console.log("Error Editing Item");
                console.log(error);
            });
        this.setState({ items: newItems });
    }

    handleAddItem(data) {
        // Add to database here
        data.id = Date.now();
        this.context.addTravelObject(this.state.reference, data)
            .then(() => {
                this.setState({ items: this.state.items.concat(data) });
                this.getFoodSuggestions(config).then(results => {
                    console.log(results)
                });
            })
            .catch(error => {
                console.log("Error Adding Item")
                console.error(error)
            });
    }

    async handleEditTripSetting(newSetting) {
        await this.context.editTripSetting(this.state.reference, this.state.tripSetting, newSetting);
        this.setState({
            tripSetting: newSetting
        });
    }

    handleSelectedObject(id) {
        this.setState({ selectedObject: id })
    }

    handleChangeDisplayDate(travelObjects, date) {
        if (this.state.today.date !== date) {
            this.setState({
                today: {
                    events: travelObjects,
                    date: date
                }
            })
        }
    }

    async getActivitySuggestions(config) {
        /**
         * param:
         * config: an object with six fields:
         *  1. userCategories: a  String array of categories
         *  2. userBudget: an integer for budget
         *  3. radius: a string integer radius object
         *  4. timeRange: free time range [startDate, endDate]
         *  5. coordinates: an object for coordinates
         *  6. items: set of all place ids of selected places
         * return the suggestions : an array of PlaceObject already sorted based on score
         */
        if (this.state.map) {
            let results = await handleSuggestions(this.state.service, config, "activities");
            return results;
        }
    }

    async getFoodSuggestions(config) {
        if (this.state.map) {

            let results = await handleSuggestions(this.state.service, config, "food");
            return results;
        }
    }

    setMap(map) {
        this.setState({
            map: map,
            service: new window.google.maps.places.PlacesService(map)
        })
    }

    render() {
        // if data hasn't been loaded yet, don't render the trip
        // prevents map from loading empty data
        if (!this.state.items || !this.state.tripSetting) {
            return null;
        }
        return (

                <Grid id="map-component">
                    <MapComponent
                        zoom={15}
                        defaultCenter={this.state.tripSetting.destination.coordinates}
                        finalized={this.state.items.filter((item) => item.finalized)}
                        unfinalized={this.state.items.filter((item) => !item.finalized && item.coordinates !== null)}
                        selected={this.state.selectedObject}
                        displayDate={this.state.today}
                        setMap={this.setMap}
                    />
                </Grid>
                <Grid container className="foreground" direction="row" justify="space-between">
                    <Grid item id="finalized-component">
                        <Finalized
                            list={this.state.items.filter((item) => item.finalized)}
                            startDate={this.state.tripSetting.startDate}
                            endDate={this.state.tripSetting.endDate}
                            onRemoveItem={this.handleRemoveItem}
                            onEditItem={this.handleEditItem}
                            onAddItem={this.handleAddItem}
                            onClickObject={this.handleSelectedObject}
                            setTodaysEvents={this.handleChangeDisplayDate}

                        />
                    </Grid>
                    <Grid item id="unfinalized-component">
                        <Unfinalized
                            list={this.state.items.filter((item) => !item.finalized)}
                            onRemoveItem={this.handleRemoveItem}
                            onEditItem={this.handleEditItem}
                            onAddItem={this.handleAddItem}
                            tripSetting={this.state.tripSetting}
                            onEditTripSetting={this.handleEditTripSetting}
                            onClickObject={this.handleSelectedObject}
                        />
                    </Grid>
                </Grid>
                <Grid id="button-group">
                    <Box mb={3}>
                        <GetSuggestionButton />
                    </Box>
                    <Box>
                        <AddItemButton
                            startDate={this.state.tripSetting.startDate}
                            onAddItem={this.handleAddItem}
                        />
                    </Box>
                </Grid>

        );
    }
}<commit_msg>Keep track of all existing placeIds<commit_after>import React from 'react';
import Finalized from '../Sidebars/Finalized';
import Unfinalized from '../Sidebars/Unfinalized';
import AddItemButton from '../TravelObjectForms/AddItemButton'
import { Grid, Box } from '@material-ui/core'
import '../../styles/Trip.css'
import { FirebaseContext } from '../Firebase';
import MapComponent from "../Utilities/Map"
import { handleSuggestions } from "../../scripts/Suggestions"
import GetSuggestionButton from '../Utilities/GetSuggestionButton';

const config = {
    userCategories: ["bakery"],
    userBudget: 4,
    radius: "10000",
    timeRange: [new Date(2020, 7, 15, 2, 0), new Date(2020, 7, 15, 20, 0)],
    coordinates: { lat: 36.1699, lng: -115.1398 },
    items: new Set([])
}
//"ChIJmx1Uvc3FyIARdp6ftqC7Gd8","ChIJDRyBe_nEyIARH77JCHU27r8","ChIJVcuReVnbyIARXwAzHqxeAnk","ChIJ_YX8a9LGyIARrcojBX4AgtU"
export default class Trip extends React.Component {
    static contextType = FirebaseContext;
    constructor(props) {
        super(props);

        this.state = {
            reference: "/users/" + sessionStorage.getItem("userId") + "/trips/" + sessionStorage.getItem("tripId"),
            items: null,
            tripSetting: null,
            selectedObject: null,
            today: {
                events: [],
                date: null
            },
            map: null,
            service: null,
            queryResults: null,
            palceIds: new Set()
        }

        this.handleRemoveItem = this.handleRemoveItem.bind(this);
        this.handleEditItem = this.handleEditItem.bind(this);
        this.handleAddItem = this.handleAddItem.bind(this);
        this.handleEditTripSetting = this.handleEditTripSetting.bind(this);
        this.handleSelectedObject = this.handleSelectedObject.bind(this);
        this.handleChangeDisplayDate = this.handleChangeDisplayDate.bind(this);
        this.setMap = this.setMap.bind(this);
    }

    componentDidMount() {
        let travelObjectList = [];
        let placeIds = new Set();
        this.context.getTrip(this.state.reference)
            .then(data => {
                let trip = data.data();
                this.setState({
                    tripSetting: {
                        title: trip.title,
                        startDate: trip.startDate.toDate(),
                        endDate: trip.startDate.toDate(),
                        destination: trip.destination,
                        description: trip.description,
                        userPref: trip.userPref
                    }
                })

                trip.travelObjects.forEach(travelObject => {
                    travelObject.startDate = travelObject.startDate.toDate();
                    travelObject.endDate = travelObject.endDate.toDate();
                    travelObjectList.push(travelObject)
                    placeIds.add(travelObject.palceId);
                });
                this.setState({ items: travelObjectList, placeIds: placeIds });
            })
            .catch(error => {
                console.log("Error retrieving trip data");
                console.error(error);
            });
    }

    handleRemoveItem(data) {
        this.context.deleteTravelObject(this.state.reference, data)
            .then(() => {
                var placeIdCopy = new Set(this.state.placeIds);
                placeIdCopy = placeIdCopy.delete(data.placeId);
                this.setState({
                    items: this.state.items.filter((item) => item.id !== data.id),
                    placeIds: placeIdCopy
                });
            })
            .catch(error => {
                console.log("Error Removing Item")
                console.error(error)
            });
    }

    handleEditItem(data) {
        let newItems = [];
        let itemToChange;
        let newPlaceIds = new Set(this.state.placeIds);
        this.state.items.forEach((item) => {
            if (item.id === data.id) {
                newPlaceIds.delete(item.placeId);
                newPlaceIds.add(data.placeId);
                itemToChange = item;
                newItems.push(data);
            } else {
                newItems.push(item);
            }
        });
        this.context.editTravelObject(this.state.reference, itemToChange, data)
            .then(() => {
                this.setState({
                    items: newItems,
                    placeIds: newPlaceIds
                });
            })
            .catch((error) => {
                console.log("Error Editing Item");
                console.log(error);
            });
        this.setState({ items: newItems });
    }

    handleAddItem(data) {
        // Add to database here
        var newPlaceIds = new Set(this.state.placeIds);
        newPlaceIds.add(data.placeId);

        data.id = Date.now();
        this.context.addTravelObject(this.state.reference, data)
            .then(() => {
                this.setState({ items: this.state.items.concat(data), placeIds: newPlaceIds });
                this.getFoodSuggestions(config).then(results => {
                    console.log(results)
                });
            })
            .catch(error => {
                console.log("Error Adding Item")
                console.error(error)
            });
    }

    async handleEditTripSetting(newSetting) {
        await this.context.editTripSetting(this.state.reference, this.state.tripSetting, newSetting);
        this.setState({
            tripSetting: newSetting
        });
    }

    handleSelectedObject(id) {
        this.setState({ selectedObject: id })
    }

    handleChangeDisplayDate(travelObjects, date) {
        if (this.state.today.date !== date) {
            this.setState({
                today: {
                    events: travelObjects,
                    date: date
                }
            })
        }
    }

    async getActivitySuggestions(config) {
        /**
         * param:
         * config: an object with six fields:
         *  1. userCategories: a  String array of categories
         *  2. userBudget: an integer for budget
         *  3. radius: a string integer radius object
         *  4. timeRange: free time range [startDate, endDate]
         *  5. coordinates: an object for coordinates
         *  6. items: set of all place ids of selected places
         * return the suggestions : an array of PlaceObject already sorted based on score
         */
        if (this.state.map) {
            let results = await handleSuggestions(this.state.service, config, "activities");
            return results;
        }
    }

    async getFoodSuggestions(config) {
        if (this.state.map) {

            let results = await handleSuggestions(this.state.service, config, "food");
            return results;
        }
    }

    setMap(map) {
        this.setState({
            map: map,
            service: new window.google.maps.places.PlacesService(map)
        })
    }

    render() {
        // if data hasn't been loaded yet, don't render the trip
        // prevents map from loading empty data
        if (!this.state.items || !this.state.tripSetting) {
            return null;
        }
        return (

                <Grid id="map-component">
                    <MapComponent
                        zoom={15}
                        defaultCenter={this.state.tripSetting.destination.coordinates}
                        finalized={this.state.items.filter((item) => item.finalized)}
                        unfinalized={this.state.items.filter((item) => !item.finalized && item.coordinates !== null)}
                        selected={this.state.selectedObject}
                        displayDate={this.state.today}
                        setMap={this.setMap}
                    />
                </Grid>
                <Grid container className="foreground" direction="row" justify="space-between">
                    <Grid item id="finalized-component">
                        <Finalized
                            list={this.state.items.filter((item) => item.finalized)}
                            startDate={this.state.tripSetting.startDate}
                            endDate={this.state.tripSetting.endDate}
                            onRemoveItem={this.handleRemoveItem}
                            onEditItem={this.handleEditItem}
                            onAddItem={this.handleAddItem}
                            onClickObject={this.handleSelectedObject}
                            setTodaysEvents={this.handleChangeDisplayDate}

                        />
                    </Grid>
                    <Grid item id="unfinalized-component">
                        <Unfinalized
                            list={this.state.items.filter((item) => !item.finalized)}
                            onRemoveItem={this.handleRemoveItem}
                            onEditItem={this.handleEditItem}
                            onAddItem={this.handleAddItem}
                            tripSetting={this.state.tripSetting}
                            onEditTripSetting={this.handleEditTripSetting}
                            onClickObject={this.handleSelectedObject}
                        />
                    </Grid>
                </Grid>
                <Grid id="button-group">
                    <Box mb={3}>
                        <GetSuggestionButton />
                    </Box>
                    <Box>
                        <AddItemButton
                            startDate={this.state.tripSetting.startDate}
                            onAddItem={this.handleAddItem}
                        />
                    </Box>
                </Grid>

        );
    }
}<|endoftext|>


<commit_before>import React from 'react';
import { keyBy } from 'lodash';
import { RestApiClient } from '@dosomething/gateway';
import { extractPostsFromSignups, extractSignupsFromPosts } from '../../helpers';

const reviewComponent = (Component, data) => {
  return class extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        loading: true,
      };

      this.api = new RestApiClient;
      this.updatePost = this.updatePost.bind(this);
      this.updateTag = this.updateTag.bind(this);
      this.updateQuantity = this.updateQuantity.bind(this);
      this.showHistory = this.showHistory.bind(this);
      this.hideHistory = this.hideHistory.bind(this);
      this.deletePost = this.deletePost.bind(this);
    }

    componentDidMount() {
      this.getPostsByStatus('pending', data.campaign.id);
    }

    // Make API call to GET /posts to get posts by filtered status.
    getPostsByStatus(status, campaignId) {
      this.api.get('api/v2/posts', {
        filter: {
          status: status,
          campaign_id: campaignId,
        },
        include: 'signup,siblings',
      })
      .then(json => this.setState({
        campaign: data.campaign,
        posts: keyBy(json.data, 'id'),
        signups: extractSignupsFromPosts(keyBy(json.data, 'id')),
        filter: status,
        postTotals: json.meta.pagination.total,
        displayHistoryModal: null,
        historyModalId: null,
        loading: false,
        nextPage: json.meta.pagination.links.next,
        prevPage: json.meta.pagination.links.previous,
      }));
    }

    // Open the history modal of the given post
    showHistory(postId, event) {
      event.preventDefault()

      this.setState({
        displayHistoryModal: true,
        historyModalId: postId,
      });
    }

    // Close the open history modal
    hideHistory(event) {
      if (event) {
        event.preventDefault();
      }

      this.setState({
        displayHistoryModal: false,
        historyModalId: null,
      });
    }

    // Updates a post status.
    updatePost(postId, fields) {
      fields.post_id = postId;

      let request = this.api.put('reviews', fields);

      request.then((result) => {
        this.setState((previousState) => {
          const newState = {...previousState};
          newState.posts[postId].status = fields.status;

          return newState;
        });
      });
    }

    // Tag a post.
    updateTag(postId, tag) {
      const fields = {
        post_id: postId,
        tag_name: tag,
      };

      let response = this.api.post('tags', fields);

      return response.then((result) => {
        this.setState((previousState) => {
          const newState = {...previousState};
          const user = newState.posts[postId].user;
          const signup = newState.posts[postId].signup.data;

          // Merge existing post with the newly updated values from API.
          newState.posts[postId] = {
            ...newState.posts[postId],
            ...result['data']
          };

          return newState;
        });
      });
    }

    // Update a signups quanity.
    updateQuantity(signup, newQuantity) {
      // Fields to send to /posts
      const fields = {
        northstar_id: signup.northstar_id,
        campaign_id: signup.campaign_id,
        campaign_run_id: signup.campaign_run_id,
        quantity: newQuantity,
      };

      // Make API request to Rogue to update the quantity on the backend
      let request = this.api.post('posts', fields);

      request.then((result) => {
        // Update the state
        this.setState((previousState) => {
          const newState = {...previousState};

          newState.signups[signup.id].quantity = result.quantity;

          return newState;
        });
      });

      // Close the modal
      this.hideHistory();
    }

    // Delete a post.
    deletePost(postId, event) {
      event.preventDefault();
      const confirmed = confirm('🚨🔥🚨Are you sure you want to delete this?🚨🔥🚨');

      if (confirmed) {
        // Make API request to Rogue to update the quantity on the backend
        let response = this.api.delete('posts/'.concat(postId));

        response.then((result) => {
          // Update the state
          this.setState((previousState) => {
            var newState = {...previousState};

            // Remove the deleted post from the state
            delete(newState.posts[postId]);

            // Return the new state
            return newState;
          });
        });
      }
    }

    render() {
      const methods = {
        updatePost: this.updatePost,
        updateTag: this.updateTag,
        updateQuantity: this.updateQuantity,
        showHistory: this.showHistory,
        hideHistory: this.hideHistory,
        deletePost: this.deletePost,
      };

      return <Component {...this.state} {...methods} />;
    }
  }
}

export default reviewComponent;

<commit_msg>Update withReviewing HoC to require some initial parameters<commit_after>import React from 'react';
import { keyBy } from 'lodash';
import { RestApiClient } from '@dosomething/gateway';
import { extractPostsFromSignups, extractSignupsFromPosts } from '../../helpers';

const reviewComponent = (Component, data) => {
  return class extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        loading: true,
      };

      this.api = new RestApiClient;
      this.updatePost = this.updatePost.bind(this);
      this.updateTag = this.updateTag.bind(this);
      this.updateQuantity = this.updateQuantity.bind(this);
      this.showHistory = this.showHistory.bind(this);
      this.hideHistory = this.hideHistory.bind(this);
      this.deletePost = this.deletePost.bind(this);
      this.setNewPosts = this.setNewPosts.bind(this);
    }

    // Loads initial posts into state.
    componentDidMount() {
      // Require initial_posts and campaign parameters.
      if (data.initial_posts && data.campaign) {
        this.getPostsByStatus(data.initial_posts, data.campaign.id);
      } else {
        // @TODO - handle error better.
        console.log("Error: need to know the initial posts to load and the campaign.");
      }
    }

    // Make API call to GET /posts to get posts by filtered status.
    getPostsByStatus(status, campaignId) {
      this.api.get('api/v2/posts', {
        filter: {
          status: status,
          campaign_id: campaignId,
        },
        include: 'signup,siblings',
      })
      .then(json => this.setState({
        campaign: data.campaign,
        posts: keyBy(json.data, 'id'),
        signups: extractSignupsFromPosts(keyBy(json.data, 'id')),
        filter: status,
        postTotals: json.meta.pagination.total,
        displayHistoryModal: null,
        historyModalId: null,
        loading: false,
        nextPage: json.meta.pagination.links.next,
        prevPage: json.meta.pagination.links.previous,
      }));
    }

    setNewPosts(posts) {
      this.setState({
        campaign: data.campaign,
        posts: posts,
        signups: extractSignupsFromPosts(posts),
        filter: status,
        // postTotals: json.meta.pagination.total,
        displayHistoryModal: null,
        historyModalId: null,
        loading: false,
      });
    }

    // Open the history modal of the given post
    showHistory(postId, event) {
      event.preventDefault()

      this.setState({
        displayHistoryModal: true,
        historyModalId: postId,
      });
    }

    // Close the open history modal
    hideHistory(event) {
      if (event) {
        event.preventDefault();
      }

      this.setState({
        displayHistoryModal: false,
        historyModalId: null,
      });
    }

    // Updates a post status.
    updatePost(postId, fields) {
      fields.post_id = postId;

      let request = this.api.put('reviews', fields);

      request.then((result) => {
        this.setState((previousState) => {
          const newState = {...previousState};
          newState.posts[postId].status = fields.status;

          return newState;
        });
      });
    }

    // Tag a post.
    updateTag(postId, tag) {
      const fields = {
        post_id: postId,
        tag_name: tag,
      };

      let response = this.api.post('tags', fields);

      return response.then((result) => {
        this.setState((previousState) => {
          const newState = {...previousState};
          const user = newState.posts[postId].user;
          const signup = newState.posts[postId].signup.data;

          // Merge existing post with the newly updated values from API.
          newState.posts[postId] = {
            ...newState.posts[postId],
            ...result['data']
          };

          return newState;
        });
      });
    }

    // Update a signups quanity.
    updateQuantity(signup, newQuantity) {
      // Fields to send to /posts
      const fields = {
        northstar_id: signup.northstar_id,
        campaign_id: signup.campaign_id,
        campaign_run_id: signup.campaign_run_id,
        quantity: newQuantity,
      };

      // Make API request to Rogue to update the quantity on the backend
      let request = this.api.post('posts', fields);

      request.then((result) => {
        // Update the state
        this.setState((previousState) => {
          const newState = {...previousState};

          newState.signups[signup.signup_id].quantity = result.quantity;

          return newState;
        });
      });

      // Close the modal
      this.hideHistory();
    }

    // Delete a post.
    deletePost(postId, event) {
      event.preventDefault();
      const confirmed = confirm('🚨🔥🚨Are you sure you want to delete this?🚨🔥🚨');

      if (confirmed) {
        // Make API request to Rogue to update the quantity on the backend
        let response = this.api.delete('posts/'.concat(postId));

        response.then((result) => {
          // Update the state
          this.setState((previousState) => {
            var newState = {...previousState};

            // Remove the deleted post from the state
            delete(newState.posts[postId]);

            // Return the new state
            return newState;
          });
        });
      }
    }

    render() {
      const methods = {
        updatePost: this.updatePost,
        updateTag: this.updateTag,
        updateQuantity: this.updateQuantity,
        showHistory: this.showHistory,
        hideHistory: this.hideHistory,
        deletePost: this.deletePost,
        setNewPosts: this.setNewPosts,
      };

      // Pass in the state from this HoC to trigger rendering down the DOM
      // Also pass in methods bound to this instance.
      // Also pass in original data pass to the HoC in case other components still need it down the line.
      return <Component {...this.state} {...methods} {...data} />;
    }
  }
}

export default reviewComponent;

<|endoftext|>


<commit_before>/**
 * Created by Tsiewing on 27/04/2016.
 */
// script.js

// create the adminCtrl controller and inject Angular's $scope
adminApp.controller('adminCtrl', function($scope) {
});

// create the skapaProvcontroller and inject Angular's $scope
adminApp.controller('skapaProvController', function($scope) {
    $scope.message1 = 'Ange namn på provet:';
    $scope.message2 = 'Välj typ av fråga:';
    $scope.message3 = 'Välj antal svarsalternativ:';
    $scope.message4 = 'Formulera din fråga:';
    $scope.provNamnet = [
        {provetsNamn:'IT-säkerhetsteknik'},
        {provetsNamn:'Java SE'},
        {provetsNamn:'Java EE'},
        {provetsNamn:'Kravanalys 1'},
        {provetsNamn:'.Net'}
    ];
    $scope.changedValue = function(item) {
        console(item);
    }
});

// Variable and function applied in SkapaProv to increment the Fråga Nr.
var addFraga = (function () {
    var counter = 1;
    return function () {return counter += 1;}
})();

function addFragaNr(){
    document.getElementById("fragaCounter").innerHTML = addFraga();
}

// Creating variables and functions to access the Admin's input in SkapaProv
var elProvtid = document.getElementById('inputProvtid');
var elFragaNr = document.getElementById('fragaCounter');

function checkRadio() {
    if (document.getElementById('svarEtt').checked) {
        return $('#svarEtt').val();
    } else if (document.getElementById('svarTva').checked) {
        return $('#svarTva').val();
    } else if (document.getElementById('svarTre').checked) {
        return $('#svarTre').val();
    } else if (document.getElementById('svarFyra').checked) {
        return $('#svarFyra').val();
    } else if (document.getElementById('svarFem').checked) {
        return $('#svarFem').val();
    }
}

<commit_msg>Working on SkapaProv<commit_after>/**
 * Created by Tsiewing on 27/04/2016.
 */
// script.js

// create the adminCtrl controller and inject Angular's $scope
adminApp.controller('adminCtrl', function($scope) {
});

// create the skapaProvcontroller and inject Angular's $scope
adminApp.controller('skapaProvController', function($scope) {
    $scope.message1 = 'Ange namn på provet:';
    $scope.message2 = 'Välj typ av fråga:';
    $scope.message3 = 'Välj antal svarsalternativ:';
    $scope.message4 = 'Formulera din fråga:';
    $scope.provNamnet = [
        {provetsNamn:'IT-säkerhetsteknik'},
        {provetsNamn:'Java SE'},
        {provetsNamn:'Java EE'},
        {provetsNamn:'Kravanalys 1'},
        {provetsNamn:'.Net'}
    ];
    $scope.changedValue = function(item) {
        console(item);
    }
});

// Variable and function applied in SkapaProv to increment the Fråga Nr.
var addFraga = (function () {
    var counter = 1;
    return function () {return counter += 1;}
})();

function addFragaNr(){
    document.getElementById("fragaCounter").innerHTML = addFraga();
}

// Creating variables and functions to access the Admin's input in SkapaProv
var elProvtid = document.getElementById('inputProvtid');
var elFragaNr = document.getElementById('fragaCounter');

function checkRadio() {
    if (document.getElementById('svarEtt').checked) {
        return $('#svarEtt').val();
    } else if (document.getElementById('svarTva').checked) {
        return $('#svarTva').val();
    } else if (document.getElementById('svarTre').checked) {
        return $('#svarTre').val();
    } else if (document.getElementById('svarFyra').checked) {
        return $('#svarFyra').val();
    } else if (document.getElementById('svarFem').checked) {
        return $('#svarFem').val();
    }
}

<|endoftext|>


<commit_before>// Note: You must restart bin/webpack-dev-server for changes to take effect

/* eslint global-require: 0 */

const webpack = require('webpack')
const merge = require('webpack-merge')
const CompressionPlugin = require('compression-webpack-plugin')
const sharedConfig = require('./shared.js')

module.exports = merge(sharedConfig, {
  output: { filename: '[name]-[chunkhash].js' },
  devtool: 'source-map',
  stats: 'normal',

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: 'production',
      },
    }),

    new webpack.optimize.OccurrenceOrderPlugin(),

    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      sourceMap: true,

      compress: {
        warnings: false
      },

      output: {
        comments: false
      }
    }),

    new CompressionPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
    })
  ]
})
<commit_msg>Removed duplicate process.env export.<commit_after>// Note: You must restart bin/webpack-dev-server for changes to take effect

/* eslint global-require: 0 */

const webpack = require('webpack')
const merge = require('webpack-merge')
const CompressionPlugin = require('compression-webpack-plugin')
const sharedConfig = require('./shared.js')

module.exports = merge(sharedConfig, {
  output: { filename: '[name]-[chunkhash].js' },
  devtool: 'source-map',
  stats: 'normal',

  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),

    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      sourceMap: true,

      compress: {
        warnings: false
      },

      output: {
        comments: false
      }
    }),

    new CompressionPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
    })
  ]
})
<|endoftext|>