<commit_before>/**
* Controls the actions in the project header (make public/private, watch button,
* forking, etc.)
*/
'use strict';

var $ = require('jquery');
var bootbox = require('bootbox');
require('bootstrap-editable');
var ko = require('knockout');
var Raven = require('raven-js');

var $osf = require('js/osfHelpers');

var iconmap = require('js/iconmap');
var NodeActions = require('js/project.js');
var NodesPrivacy = require('js/nodesPrivacy').NodesPrivacy;


// List of node categories
var NODE_CATEGORIES = window.contextVars.nodeCategories;


/**
 * The ProjectViewModel, scoped to the project header.
 * @param {Object} data The parsed project data returned from the project's API url.
 */
var ProjectViewModel = function(data) {
    var self = this;
    self._id = data.node.id;
    self.apiUrl = data.node.api_url;
    self.dateCreated = new $osf.FormattableDate(data.node.date_created);
    self.dateModified = new $osf.FormattableDate(data.node.date_modified);
    self.dateForked = new $osf.FormattableDate(data.node.forked_date);
    self.parent = data.parent_node;
    self.doi = ko.observable(data.node.identifiers.doi);
    self.ark = ko.observable(data.node.identifiers.ark);
    self.idCreationInProgress = ko.observable(false);
    self.watchedCount = ko.observable(data.node.watched_count);
    self.userIsWatching = ko.observable(data.user.is_watching);
    self.dateRegistered = new $osf.FormattableDate(data.node.registered_date);
    self.inDashboard = ko.observable(data.node.in_dashboard);
    self.dashboard = data.user.dashboard_id;
    self.userCanEdit = data.user.can_edit;
    self.userPermissions = data.user.permissions;
    self.node = data.node;
    self.description = ko.observable(data.node.description);
    self.title = data.node.title;
    self.category = ko.observable(data.node.category);
    self.isRegistration = data.node.is_registration;
    self.user = data.user;
    self.nodeIsPublic = data.node.is_public;
    self.nodeType = data.node.node_type;

    self.nodeIsPendingEmbargoTermination = ko.observable(data.node.is_pending_embargo_termination);
    self.makePublicTooltip = ko.computed(function() {
        if(self.nodeIsPendingEmbargoTermination()) {
            return 'A request to make this registration public is pending';
        }
        return null;
    });

    // WATCH button is removed, functionality is still here in case of future implementation -- CU
    // The button text to display (e.g. "Watch" if not watching)
    self.watchButtonDisplay = ko.pureComputed(function() {
        return self.watchedCount().toString();
    });
    self.watchButtonAction = ko.pureComputed(function() {
        return self.userIsWatching() ? 'Unwatch' : 'Watch';
    });

    self.canBeOrganized = ko.pureComputed(function() {
        return !!(self.user.username && (self.nodeIsPublic || self.user.has_read_permissions));
    });


    // Add icon to title
    self.icon = ''; // TODO Dynamically update icon
    var category = data.node.category_short;
    if (Object.keys(iconmap.componentIcons).indexOf(category) >=0 ){
        self.icon = iconmap.componentIcons[category];
    }
    else {
        self.icon = iconmap.projectIcons[category];
    }

    // Editable Title and Description
    if (self.userCanEdit) {
        var editableOptions = {
            type: 'text',
            pk: self._id,
            url: self.apiUrl + 'edit/',
            ajaxOptions: {
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json'
            },
            params: function (params) {
                // Send JSON data
                return JSON.stringify(params);
            },
            success: function () {
                document.location.reload(true);
            },
            error: $osf.handleEditableError,
            placement: 'bottom'
        };

        // TODO: Remove hardcoded selectors.
        $.fn.editable.defaults.mode = 'inline';
        $('#nodeTitleEditable').editable($.extend({}, editableOptions, {
            name: 'title',
            title: 'Edit Title',
            tpl: '<input type="text" maxlength="200">',
            validate: function (value) {
                if ($.trim(value) === '') {
                    return 'Title cannot be blank.';
                }
                else if(value.length > 200){
                    return 'Title cannot exceed 200 characters.';
                }
            }
        }));

        $('#nodeDescriptionEditable').editable($.extend({}, editableOptions, {
            name: 'description',
            title: 'Edit Description',
            emptytext: 'No description',
            emptyclass: 'text-muted',
            value: self.description(),
            success: function(response, newValue) {
                newValue = response.newValue; // Update display to reflect changes, eg by sanitizer
                self.description(newValue);
                return {newValue: newValue};
            }

        }));
        
        // Front end is passed the display category, which must be mapped to the matching dropdown box value
        var categoryOptions = $.map(NODE_CATEGORIES, function(display, value) {
            return {value: value, text: display}
        });
        var initCategory = categoryOptions.find(function(element /*, index, array*/) {
            return element.text === self.category();
        });

        $('#nodeCategoryEditable').editable($.extend({}, editableOptions, {
            type: 'select',
            name: 'category',
            title: 'Select a category',
            value: initCategory.value,
            source: categoryOptions,
            success: function(response, newValue) {
                newValue = response.newValue;
                self.category(newValue);
                return {newValue: newValue};
            }
        }));
    }

    /**
     * Add project to the Project Organizer.
     */
    self.addToDashboard = function() {
        $('#addDashboardFolder').tooltip('hide');
        self.inDashboard(true);
        var jsonData = {
            'toNodeID': self.dashboard,
            'pointerID': self._id
        };
        $osf.postJSON('/api/v1/pointer/', jsonData)
            .fail(function(data) {<commit_msg>Set icon for category and simplify value logic<commit_after>/**
* Controls the actions in the project header (make public/private, watch button,
* forking, etc.)
*/
'use strict';

var $ = require('jquery');
var bootbox = require('bootbox');
require('bootstrap-editable');
var ko = require('knockout');
var Raven = require('raven-js');

var $osf = require('js/osfHelpers');

var iconmap = require('js/iconmap');
var NodeActions = require('js/project.js');
var NodesPrivacy = require('js/nodesPrivacy').NodesPrivacy;


// List of node categories
var NODE_CATEGORIES = window.contextVars.nodeCategories;


/**
 * The ProjectViewModel, scoped to the project header.
 * @param {Object} data The parsed project data returned from the project's API url.
 */
var ProjectViewModel = function(data) {
    var self = this;
    self._id = data.node.id;
    self.apiUrl = data.node.api_url;
    self.dateCreated = new $osf.FormattableDate(data.node.date_created);
    self.dateModified = new $osf.FormattableDate(data.node.date_modified);
    self.dateForked = new $osf.FormattableDate(data.node.forked_date);
    self.parent = data.parent_node;
    self.doi = ko.observable(data.node.identifiers.doi);
    self.ark = ko.observable(data.node.identifiers.ark);
    self.idCreationInProgress = ko.observable(false);
    self.watchedCount = ko.observable(data.node.watched_count);
    self.userIsWatching = ko.observable(data.user.is_watching);
    self.dateRegistered = new $osf.FormattableDate(data.node.registered_date);
    self.inDashboard = ko.observable(data.node.in_dashboard);
    self.dashboard = data.user.dashboard_id;
    self.userCanEdit = data.user.can_edit;
    self.userPermissions = data.user.permissions;
    self.node = data.node;
    self.description = ko.observable(data.node.description);
    self.title = data.node.title;
    self.categoryValue = ko.observable(data.node.category_short);
    self.isRegistration = data.node.is_registration;
    self.user = data.user;
    self.nodeIsPublic = data.node.is_public;
    self.nodeType = data.node.node_type;

    self.nodeIsPendingEmbargoTermination = ko.observable(data.node.is_pending_embargo_termination);
    self.makePublicTooltip = ko.computed(function() {
        if(self.nodeIsPendingEmbargoTermination()) {
            return 'A request to make this registration public is pending';
        }
        return null;
    });

    // WATCH button is removed, functionality is still here in case of future implementation -- CU
    // The button text to display (e.g. "Watch" if not watching)
    self.watchButtonDisplay = ko.pureComputed(function() {
        return self.watchedCount().toString();
    });
    self.watchButtonAction = ko.pureComputed(function() {
        return self.userIsWatching() ? 'Unwatch' : 'Watch';
    });

    self.canBeOrganized = ko.pureComputed(function() {
        return !!(self.user.username && (self.nodeIsPublic || self.user.has_read_permissions));
    });

    // Add icon to title
    self.icon = ko.pureComputed(function() {
        var category = self.categoryValue();
        if (Object.keys(iconmap.componentIcons).indexOf(category) >=0 ){
            return iconmap.componentIcons[category];
        } else {
            return iconmap.projectIcons[category];
        }
    });

    // Editable Title and Description
    if (self.userCanEdit) {
        var editableOptions = {
            type: 'text',
            pk: self._id,
            url: self.apiUrl + 'edit/',
            ajaxOptions: {
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json'
            },
            params: function (params) {
                // Send JSON data
                return JSON.stringify(params);
            },
            success: function () {
                document.location.reload(true);
            },
            error: $osf.handleEditableError,
            placement: 'bottom'
        };

        // TODO: Remove hardcoded selectors.
        $.fn.editable.defaults.mode = 'inline';
        $('#nodeTitleEditable').editable($.extend({}, editableOptions, {
            name: 'title',
            title: 'Edit Title',
            tpl: '<input type="text" maxlength="200">',
            validate: function (value) {
                if ($.trim(value) === '') {
                    return 'Title cannot be blank.';
                }
                else if(value.length > 200){
                    return 'Title cannot exceed 200 characters.';
                }
            }
        }));

        $('#nodeDescriptionEditable').editable($.extend({}, editableOptions, {
            name: 'description',
            title: 'Edit Description',
            emptytext: 'No description',
            emptyclass: 'text-muted',
            value: self.description(),
            success: function(response, newValue) {
                newValue = response.newValue; // Update display to reflect changes, eg by sanitizer
                self.description(newValue);
                return {newValue: newValue};
            }
        }));

        var categoryOptions = $.map(NODE_CATEGORIES, function(display, value) {
            return {value: value, text: display};
        });
        $('#nodeCategoryEditable').editable($.extend({}, editableOptions, {
            type: 'select',
            name: 'category',
            title: 'Select a category',
            value: self.categoryValue(),
            source: categoryOptions,
            success: function(response, newValue) {
                newValue = response.newValue;
                self.categoryValue(newValue);
                return {newValue: newValue};
            }
        }));
    }

    /**
     * Add project to the Project Organizer.
     */
    self.addToDashboard = function() {
        $('#addDashboardFolder').tooltip('hide');
        self.inDashboard(true);
        var jsonData = {
            'toNodeID': self.dashboard,
            'pointerID': self._id
        };
        $osf.postJSON('/api/v1/pointer/', jsonData)
            .fail(function(data) {
{'fraction_non_alphanumeric': 0.12482808834236712, 'fraction_numerical': 0.0017797912790227328, 'mean_word_length': 2.2982924226254, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2209940', 'n_tokens_mistral': 3533, 'n_tokens_neox': 3452, 'n_words': 749}