<commit_before>function SettingsAssistant() {
    /* this is the creator function for your scene assistant object. It will be passed all the
       additional parameters (after the scene name) that were passed to pushScene. The reference
       to the scene controller (this.controller) has not be established yet, so any initialization
       that needs the scene controller should be done in the setup function below. */
}

SettingsAssistant.prototype.setup = function() {
    /* this function is for setup tasks that have to happen when the scene is first created */

    /* use Mojo.View.render to render view templates and add them to the scene, if needed */

    /* setup widgets here */
    this.controller.setupWidget('enabled-spinner', {}, { spinning: false });
    this.controller.setupWidget('enabled', {modelProperty:'value'}, this.enabledModel = {});

    /* add event handlers to listen to events from widgets */
    Mojo.Event.listen(this.controller.get('enabled'), Mojo.Event.propertyChange,
        this.handleEnable.bind(this));
};

SettingsAssistant.prototype.enabled = function (obj) {
    this.controller.get('enabled-spinner').mojo.stop(); //addClassName('hidden');
    Mojo.Log.info("Enabled paper swapping");
};

SettingsAssistant.prototype.errorEnabling = function (oops) {
    this.controller.get('enabled-spinner').mojo.stop(); //addClassName('hidden');
    this.enabledModel.value = false;
    Mojo.Log.error("Couldn't enable paper swapping: " + oops.errorText);
    this.controller.showAlertDialog({
        title: $L("Oops, couldn't enable"),
        message: oops.errorText,
        choices: [{label:$L('Dismiss'), value:'dismiss', type:'secondary'}]
    });
};

SettingsAssistant.prototype.disabled = function (obj) {
    this.controller.get('enabled-spinner').addClassName('hidden');
    Mojo.Log.info("Disabled paper swapping");
};

SettingsAssistant.prototype.errorDisabling = function (oops) {
    this.controller.get('enabled-spinner').addClassName('hidden');
    this.enabledModel.value = true;
    Mojo.Log.error("Couldn't disable paper swapping: " + oops.errorText);
    this.controller.showAlertDialog({
        title: $L("Oops, couldn't disable"),
        message: oops.errorText,
        choices: [{label:$L('Dismiss'), value:'dismiss', type:'secondary'}]
    });
};

SettingsAssistant.prototype.handleEnable = function(event) {
    if (event.property != 'value') {
        return;
    }

    this.controller.get('enabled-spinner').mojo.start(); //removeClassName('hidden');

    if (event.value) {
        // Set up the timer subscription?
        Mojo.Log.info("Trying to schedule paper swapping");
        this.controller.serviceRequest("palm://com.palm.power/timeout", {
            method: "set",
            parameters: {
                wakeup: false,
                key: "org.markpasc.paperplain.activate",
                uri: "palm://com.palm.applicationManager/launch",
                params: '{id:"org.markpasc.paperplain", params:{"action":"swappaper"}}',
                'in': "00:05:00"
            },
            onSuccess: this.enabled.bind(this),
            onFailure: this.errorEnabling.bind(this),
        });
    }
    else {
        // Delete the timer subscription.
        Mojo.Log.info("Trying to unschedule paper swapping");
        this.controller.serviceRequest("palm://com.palm.power/timeout", {
            method: "clear",
            parameters: {
                key: "org.markpasc.paperplain.activate",
            },
            onSuccess: this.disabled.bind(this),
            onFailure: this.errorDisabling.bind(this),
        });
    }
};

SettingsAssistant.prototype.activate = function(event) {
    /* put in event handlers here that should only be in effect when this scene is active. For
       example, key handlers that are observing the document */
};

SettingsAssistant.prototype.deactivate = function(event) {
    /* remove any event handlers you added in activate and do any other cleanup that should happen before
       this scene is popped or another scene is pushed on top */
};

SettingsAssistant.prototype.cleanup = function(event) {
    /* this function should do any cleanup needed before the scene is destroyed as
       a result of being popped off the scene stack */
};
<commit_msg>Try scheduling the alarm for 10 seconds from now instead of 5 minutes (since we can't 'in' any less than 5 minutes)<commit_after>function SettingsAssistant() {
    /* this is the creator function for your scene assistant object. It will be passed all the
       additional parameters (after the scene name) that were passed to pushScene. The reference
       to the scene controller (this.controller) has not be established yet, so any initialization
       that needs the scene controller should be done in the setup function below. */
}

SettingsAssistant.prototype.setup = function() {
    /* this function is for setup tasks that have to happen when the scene is first created */

    /* use Mojo.View.render to render view templates and add them to the scene, if needed */

    /* setup widgets here */
    this.controller.setupWidget('enabled-spinner', {}, { spinning: false });
    this.controller.setupWidget('enabled', {modelProperty:'value'}, this.enabledModel = {});

    /* add event handlers to listen to events from widgets */
    Mojo.Event.listen(this.controller.get('enabled'), Mojo.Event.propertyChange,
        this.handleEnable.bind(this));
};

SettingsAssistant.prototype.enabled = function (obj) {
    this.controller.get('enabled-spinner').mojo.stop(); //addClassName('hidden');
    Mojo.Log.info("Enabled paper swapping");
};

SettingsAssistant.prototype.errorEnabling = function (oops) {
    this.controller.get('enabled-spinner').mojo.stop(); //addClassName('hidden');
    this.enabledModel.value = false;
    Mojo.Log.error("Couldn't enable paper swapping: " + oops.errorText);
    this.controller.showAlertDialog({
        title: $L("Oops, couldn't enable"),
        message: oops.errorText,
        choices: [{label:$L('Dismiss'), value:'dismiss', type:'secondary'}]
    });
};

SettingsAssistant.prototype.disabled = function (obj) {
    this.controller.get('enabled-spinner').addClassName('hidden');
    Mojo.Log.info("Disabled paper swapping");
};

SettingsAssistant.prototype.errorDisabling = function (oops) {
    this.controller.get('enabled-spinner').addClassName('hidden');
    this.enabledModel.value = true;
    Mojo.Log.error("Couldn't disable paper swapping: " + oops.errorText);
    this.controller.showAlertDialog({
        title: $L("Oops, couldn't disable"),
        message: oops.errorText,
        choices: [{label:$L('Dismiss'), value:'dismiss', type:'secondary'}]
    });
};

SettingsAssistant.prototype.handleEnable = function(event) {
    if (event.property != 'value') {
        return;
    }

    this.controller.get('enabled-spinner').mojo.start(); //removeClassName('hidden');

    if (event.value) {
        // Set up the timer subscription?
        Mojo.Log.info("Trying to schedule paper swapping");

        var now = new Date();
        var then = now.getTime() + 10 * 1000;  // 10 seconds
        var alarmTime = new Date(then);
        var alarmAt = [alarmTime.getUTCMonth()+1, alarmTime.getUTCDate(), alarmTime.getUTCFullYear()].join('/')
            + ' ' + [alarmTime.getUTCHours(), alarmTime.getUTCMinutes(), alarmTime.getUTCSeconds()].join(':')

        this.controller.serviceRequest("palm://com.palm.power/timeout", {
            method: "set",
            parameters: {
                wakeup: false,
                key: "org.markpasc.paperplain.activate",
                uri: "palm://com.palm.applicationManager/launch",
                params: '{id:"org.markpasc.paperplain", params:{"action":"swappaper"}}',
                at: alarmAt,
            },
            onSuccess: this.enabled.bind(this),
            onFailure: this.errorEnabling.bind(this),
        });
    }
    else {
        // Delete the timer subscription.
        Mojo.Log.info("Trying to unschedule paper swapping");
        this.controller.serviceRequest("palm://com.palm.power/timeout", {
            method: "clear",
            parameters: {
                key: "org.markpasc.paperplain.activate",
            },
            onSuccess: this.disabled.bind(this),
            onFailure: this.errorDisabling.bind(this),
        });
    }
};

SettingsAssistant.prototype.activate = function(event) {
    /* put in event handlers here that should only be in effect when this scene is active. For
       example, key handlers that are observing the document */
};

SettingsAssistant.prototype.deactivate = function(event) {
    /* remove any event handlers you added in activate and do any other cleanup that should happen before
       this scene is popped or another scene is pushed on top */
};

SettingsAssistant.prototype.cleanup = function(event) {
    /* this function should do any cleanup needed before the scene is destroyed as
       a result of being popped off the scene stack */
};
<|endoftext|>


<commit_before>import _ from "lodash";
import {termSearch, perhaps} from "../../common";

const BINDINGS = {
    softwareCatalog: '=',
    servers: '=',
    databases: '='
};

const FIELDS_TO_SEARCH = {
    SOFTWARE: [
        'vendor',
        'name',
        'version',
        'maturityStatus'
    ]
};

const EOL_CELL_TEMPLATE = '
 <waltz-icon ng-if="COL_FIELD" name="power-off"></waltz-icon>
';

const LIFECYCLE_STATUS_CELL_TEMPLATE = `<div class="ui-grid-cell-contents"><span ng-bind="COL_FIELD | toDisplayName:'lifecycleStatus'"></span></div>`;

function mkBooleanColumnFilter(uiGridConstants) {
    return {
        type: uiGridConstants.filter.SELECT,
        selectOptions: [
            {value: 'true', label: 'Yes'},
            {value: 'false', label: 'No'}
        ]
    };
}

function isEndOfLife(endOfLifeStatus) {
    return endOfLifeStatus === 'END_OF_LIFE';
}

function createDefaultTableOptions($animate, uiGridConstants, exportFileName = "export.csv") {
    return {
        columnDefs: [],
        data: [],
        enableGridMenu: true,
        enableFiltering: true,
        enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
        enableSorting: true,
        exporterCsvFilename: exportFileName,
        exporterMenuPdf: false,
        onRegisterApi: (gridApi) => {
            $animate.enabled(gridApi.grid.element, false);
        }
    };
}

function prepareServerGridOptions($animate, uiGridConstants) {

    const columnDefs = [
        { field: 'hostname', displayName: 'Host' },
        { field: 'environment' },
        {
            field: 'virtual',
            displayName: 'Virtual',
            width: "5%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: '
 <waltz-icon ng-if="COL_FIELD" name="check"></waltz-icon>
'
        },
        { field: 'operatingSystem', displayName: 'OS' },
        { field: 'operatingSystemVersion', displayName: 'Version' },
        { field: 'location' },
        { field: 'country' },
        {
            field: 'isHwEndOfLife',
            displayName: 'h/w EOL',
            width: "6%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'hardwareEndOfLifeDate', displayName: 'h/w EOL On' },
        {
            field: 'isOperatingSystemEndOfLife',
            displayName: 'OS EOL',
            width: "6%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'operatingSystemEndOfLifeDate', displayName: 'OS EOL On' },
        {
            field: 'lifecycleStatus',
            displayName: 'Lifecycle',
            cellTemplate: LIFECYCLE_STATUS_CELL_TEMPLATE
        }
    ];

    const baseTable = createDefaultTableOptions($animate, uiGridConstants, "server.csv");
    return _.extend(baseTable, {
        columnDefs,
        rowTemplate: '

'
    });
}

function prepareDatabaseGridOptions($animate, uiGridConstants) {

    const columnDefs = [
        { field: 'instanceName', displayName: 'Instance' },
        { field: 'databaseName', displayName: 'Database' },
        { field: 'environment' },
        { field: 'dbmsVendor', displayName: 'Vendor' },
        { field: 'dbmsName', displayName: 'Product Name' },
        { field: 'dbmsVersion', displayName: 'Version' },
        {
            field: 'isEndOfLife',
            displayName: 'EOL',
            width: "5%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'endOfLifeDate', displayName: 'EOL On' },
        {
            field: 'lifecycleStatus',
            displayName: 'Lifecycle',
            cellTemplate: LIFECYCLE_STATUS_CELL_TEMPLATE
        }
    ];

    const baseTable = createDefaultTableOptions($animate, uiGridConstants, "database.csv");
    return _.extend(baseTable, {
        columnDefs,
        rowTemplate: '

'
    });
}

function controller($animate, $scope, uiGridConstants) {

    const vm = this;

    const watchExpressionForQueries = [
        'ctrl.qry',
        'ctrl.softwareCatalog.packages',
        'ctrl.servers',
        'ctrl.databases'
    ];

    $scope.$watchGroup(
        watchExpressionForQueries,
        ([qry, packages = [], servers = [], databases = []]) => {
            if (qry) {
                vm.filteredSoftwareCatalog = {
                    usages: vm.softwareCatalog.usages,
                    packages: termSearch(packages, qry, FIELDS_TO_SEARCH.SOFTWARE)
                };
                vm.filteredServers = termSearch(servers, qry);
                vm.filteredDatabases = termSearch(databases, qry);
            } else {
                vm.filteredSoftwareCatalog = vm.softwareCatalog;
                vm.filteredServers = servers;
                vm.filteredDatabases = databases;
            }
        }
    );

    $scope.$watch(
        'ctrl.softwareCatalog.usages',
        (usages = []) => {
            vm.softwareUsages = _.chain(usages)
                .groupBy('provenance')
                .value();
        }
    );

    $scope.$watch(
        'ctrl.servers',
        servers => {
            _.forEach(servers,
                (svr) => Object.assign(svr, {
                    "isHwEndOfLife": isEndOfLife(svr.hardwareEndOfLifeStatus),
                    "isOperatingSystemEndOfLife": isEndOfLife(svr.operatingSystemEndOfLifeStatus)
                })
            );
            vm.serverGridOptions.data = servers;
        }
    );

    $scope.$watch(
        'ctrl.databases',
        databases => {
            _.forEach(databases,
                (db) => Object.assign(db, {
                    "isEndOfLife": isEndOfLife(db.endOfLifeStatus)
                })
            );
            vm.databaseGridOptions.data = databases;
        }
    );

    vm.serverGridOptions = prepareServerGridOptions($animate, uiGridConstants);
    vm.databaseGridOptions = prepareDatabaseGridOptions($animate, uiGridConstants);

    vm.hasAnyData = () => {
        const hasSoftware = perhaps(() => vm.softwareCatalog.packages.length > 0, false);
        const hasServers = perhaps(() => vm.servers.length > 0, false);
        const hasDatabases = false;

        return hasSoftware || hasServers || hasDatabases;
    }

}

controller.$inject = [
    '$animate',
    '$scope',
    'uiGridConstants'
];

const directive = {
    restrict: 'E',
    replace: true,
    scope: {},
    template: require('./technology-section.html'),
    bindToController: BINDINGS,
    controllerAs: 'ctrl',
    controller
};

export default () => directive;
<commit_msg>Use cellFilter instead of cellTemplate<commit_after>import _ from "lodash";
import {termSearch, perhaps} from "../../common";

const BINDINGS = {
    softwareCatalog: '=',
    servers: '=',
    databases: '='
};

const FIELDS_TO_SEARCH = {
    SOFTWARE: [
        'vendor',
        'name',
        'version',
        'maturityStatus'
    ]
};

const EOL_CELL_TEMPLATE = '
 <waltz-icon ng-if="COL_FIELD" name="power-off"></waltz-icon>
';

function mkBooleanColumnFilter(uiGridConstants) {
    return {
        type: uiGridConstants.filter.SELECT,
        selectOptions: [
            {value: 'true', label: 'Yes'},
            {value: 'false', label: 'No'}
        ]
    };
}

function isEndOfLife(endOfLifeStatus) {
    return endOfLifeStatus === 'END_OF_LIFE';
}

function createDefaultTableOptions($animate, uiGridConstants, exportFileName = "export.csv") {
    return {
        columnDefs: [],
        data: [],
        enableGridMenu: true,
        enableFiltering: true,
        enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
        enableSorting: true,
        exporterCsvFilename: exportFileName,
        exporterMenuPdf: false,
        onRegisterApi: (gridApi) => {
            $animate.enabled(gridApi.grid.element, false);
        }
    };
}

function prepareServerGridOptions($animate, uiGridConstants) {

    const columnDefs = [
        { field: 'hostname', displayName: 'Host' },
        { field: 'environment' },
        {
            field: 'virtual',
            displayName: 'Virtual',
            width: "5%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: '
 <waltz-icon ng-if="COL_FIELD" name="check"></waltz-icon>
'
        },
        { field: 'operatingSystem', displayName: 'OS' },
        { field: 'operatingSystemVersion', displayName: 'Version' },
        { field: 'location' },
        { field: 'country' },
        {
            field: 'isHwEndOfLife',
            displayName: 'h/w EOL',
            width: "6%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'hardwareEndOfLifeDate', displayName: 'h/w EOL On' },
        {
            field: 'isOperatingSystemEndOfLife',
            displayName: 'OS EOL',
            width: "6%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'operatingSystemEndOfLifeDate', displayName: 'OS EOL On' },
        {
            field: 'lifecycleStatus',
            displayName: 'Lifecycle',
            cellFilter: "toDisplayName:'lifecycleStatus'"
        }
    ];

    const baseTable = createDefaultTableOptions($animate, uiGridConstants, "server.csv");
    return _.extend(baseTable, {
        columnDefs,
        rowTemplate: '

'
    });
}

function prepareDatabaseGridOptions($animate, uiGridConstants) {

    const columnDefs = [
        { field: 'instanceName', displayName: 'Instance' },
        { field: 'databaseName', displayName: 'Database' },
        { field: 'environment' },
        { field: 'dbmsVendor', displayName: 'Vendor' },
        { field: 'dbmsName', displayName: 'Product Name' },
        { field: 'dbmsVersion', displayName: 'Version' },
        {
            field: 'isEndOfLife',
            displayName: 'EOL',
            width: "5%",
            filter: mkBooleanColumnFilter(uiGridConstants),
            cellTemplate: EOL_CELL_TEMPLATE
        },
        { field: 'endOfLifeDate', displayName: 'EOL On' },
        {
            field: 'lifecycleStatus',
            displayName: 'Lifecycle',
            cellFilter: "toDisplayName:'lifecycleStatus'"
        }
    ];

    const baseTable = createDefaultTableOptions($animate, uiGridConstants, "database.csv");
    return _.extend(baseTable, {
        columnDefs,
        rowTemplate: '

'
    });
}

function controller($animate, $scope, uiGridConstants) {

    const vm = this;

    const watchExpressionForQueries = [
        'ctrl.qry',
        'ctrl.softwareCatalog.packages',
        'ctrl.servers',
        'ctrl.databases'
    ];

    $scope.$watchGroup(
        watchExpressionForQueries,
        ([qry, packages = [], servers = [], databases = []]) => {
            if (qry) {
                vm.filteredSoftwareCatalog = {
                    usages: vm.softwareCatalog.usages,
                    packages: termSearch(packages, qry, FIELDS_TO_SEARCH.SOFTWARE)
                };
                vm.filteredServers = termSearch(servers, qry);
                vm.filteredDatabases = termSearch(databases, qry);
            } else {
                vm.filteredSoftwareCatalog = vm.softwareCatalog;
                vm.filteredServers = servers;
                vm.filteredDatabases = databases;
            }
        }
    );

    $scope.$watch(
        'ctrl.softwareCatalog.usages',
        (usages = []) => {
            vm.softwareUsages = _.chain(usages)
                .groupBy('provenance')
                .value();
        }
    );

    $scope.$watch(
        'ctrl.servers',
        servers => {
            _.forEach(servers,
                (svr) => Object.assign(svr, {
                    "isHwEndOfLife": isEndOfLife(svr.hardwareEndOfLifeStatus),
                    "isOperatingSystemEndOfLife": isEndOfLife(svr.operatingSystemEndOfLifeStatus)
                })
            );
            vm.serverGridOptions.data = servers;
        }
    );

    $scope.$watch(
        'ctrl.databases',
        databases => {
            _.forEach(databases,
                (db) => Object.assign(db, {
                    "isEndOfLife": isEndOfLife(db.endOfLifeStatus)
                })
            );
            vm.databaseGridOptions.data = databases;
        }
    );

    vm.serverGridOptions = prepareServerGridOptions($animate, uiGridConstants);
    vm.databaseGridOptions = prepareDatabaseGridOptions($animate, uiGridConstants);

    vm.hasAnyData = () => {
        const hasSoftware = perhaps(() => vm.softwareCatalog.packages.length > 0, false);
        const hasServers = perhaps(() => vm.servers.length > 0, false);
        const hasDatabases = false;

        return hasSoftware || hasServers || hasDatabases;
    }

}

controller.$inject = [
    '$animate',
    '$scope',
    'uiGridConstants'
];

const directive = {
    restrict: 'E',
    replace: true,
    scope: {},
    template: require('./technology-section.html'),
    bindToController: BINDINGS,
    controllerAs: 'ctrl',
    controller
};

export default () => directive;
<|endoftext|>


<commit_before>// twister_directmsg.js
// 2013 Miguel Freitas
//
// Handle direct messages modal

function requestDMsnippetList(dmThreadList) {
    var followList = [];
    for (var i = 0; i < followingUsers.length; i++)
        followList.push({username:followingUsers[i]});
    for (var i = 0; i < groupChatAliases.length; i++)
        followList.push({username:groupChatAliases[i]});

    twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList],
        function(req, ret) {processDMsnippet(ret, dmThreadList);}, dmThreadList,
        function(req, ret) {console.log('ajax error:' + ret);}, null
    );
}

function processDMsnippet(dmUsers, dmThreadList) {
    dmThreadList.empty();

    for (var u in dmUsers) {
        // convert snipped to html and add it to date-sorted list
        var dmItem = dmDataToSnippetItem(dmUsers[u][0], u);
        var timeDmItem = parseInt(dmItem.attr('data-time'));
        var existingItems = dmThreadList.children();
        for (var j = 0; j < existingItems.length; j++) {
            var streamItem = existingItems.eq(j);
            var timeExisting = streamItem.attr('data-time');
            if (typeof timeExisting === 'undefined' || timeDmItem > parseInt(timeExisting)) {
                // this post in stream is older, so post must be inserted above
                streamItem.before(dmItem);
                break;
            }
        }
        if (j === existingItems.length)
            dmThreadList.append(dmItem);
    }
    $.MAL.dmThreadListLoaded();
}

function requestDmConversationModal(postboard, dm_screenname) {
    if (postboard.is('html *')) {
        requestDmConversation(postboard, dm_screenname);
        setTimeout(requestDmConversationModal, 1000, postboard, dm_screenname);
    }
}

function requestDmConversation(postboard, dm_screenname) {
    var since_id = undefined;

    var oldItems = postboard.children();
    if (oldItems.length)
        since_id = parseInt(oldItems.eq(oldItems.length - 1).attr('data-id'));

    var userDmReq = [{username: dm_screenname}];
    if (typeof since_id !== 'undefined')
        userDmReq[0].since_id = since_id;

    var count = 100;
    twisterRpc('getdirectmsgs', [defaultScreenName, count, userDmReq],
        function(args, ret) {processDmConversation(args.postboard, args.dm_screenname, ret);},
            {postboard: postboard, dm_screenname: dm_screenname},
        function(arg, ret) {
            var msg = (ret.message) ? ret.message : ret;
            alert(polyglot.t('ajax_error', {error: msg}));
        }, null
    );
}

function processDmConversation(postboard, dm_screenname, dmData) {
    var lastId = undefined;

    if (dmData[dm_screenname]) {
        var dmList = dmData[dm_screenname];
        if (dmList.length) {
            for (var i = 0; i < dmList.length; i++) {
                var dmItem = dmDataToConversationItem(dmList[i], defaultScreenName, dm_screenname)
                    .attr('data-id', dmList[i].id)
                    .appendTo(postboard)
                ;
                lastId = dmList[i].id;
            }
            $.MAL.dmChatListLoaded(postboard);
        }
    }
    if (typeof lastId !== 'undefined')
        resetNewDMsCountForUser(dm_screenname, lastId);
}

function directMsgSubmit(e) {
    e.stopPropagation();
    e.preventDefault();

    var replyText = $(this).closest('.post-area-new').find('textarea');

    newDirectMsg(replyText.val(), $('.directMessages').attr('data-dm-screen-name'));

    replyText.val('');
}

function newDirectMsg(msg,  dm_screenname) {
    if (typeof lastPostId !== 'undefined') {
        var paramsOrig = [defaultScreenName, lastPostId + 1, dm_screenname, msg];
        var paramsOpt = paramsOrig;
        var copySelf = $.Options.dmCopySelf.val === 'enable';
        if (copySelf && dm_screenname[0] !== '*')
            paramsOpt = paramsOrig.concat(true)

        twisterRpc('newdirectmsg', paramsOpt,
            function(arg, ret) {
                incLastPostId();
                if (arg.copySelf)
                    incLastPostId();
            }, {copySelf: copySelf},
            function(arg, ret) {
                // fallback for older twisterd (error: no copy_self parameter)
                twisterRpc('newdirectmsg', arg.paramsOrig,
                    function(arg, ret) {incLastPostId();}, null,
                    function(arg, ret) {
                        var msg = (ret.message) ? ret.message : ret;
                        alert('Ajax error: ' + msg);
                    }, null
                );
            }, {paramsOrig: paramsOrig}
        );
    } else
        alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)'));
}

// dispara o modal de direct messages
function directMessagesPopup() {
    if (!defaultScreenName) {
      alert(polyglot.t('You have to log in to use direct messages.'));
      return;
    }

    modal = openModal({
        classAdd: 'directMessages',
        content: $('.direct-messages-template').children().clone(true),
        title: polyglot.t('Direct Messages')
    });

    requestDMsnippetList(modal.content.find('.direct-messages-list'));

    modal.self.find('.mark-all-as-read')
        .css('display', 'inline')
        .attr('title', polyglot.t('Mark all as read'))
        .on('click', function() {
            for (var user in _newDMsPerUser) {
                _newDMsPerUser[user] = 0;
            }
            saveDMsToStorage();
            $.MAL.updateNewDMsUI(getNewDMsCount());
        })
    ;
}

function openDmWithUserModal(dm_screenname) {
    if (!defaultScreenName) {
        alert(polyglot.t('You have to log in to use direct messages.'));
        return;
    }

    modal = openModal({
        classAdd: 'directMessages',
        content: $('.messages-thread-template').children().clone(true),
        title: polyglot.t('direct_messages_with', {username: '' + dm_screenname + ''})
    });

    modal.self.attr('data-dm-screen-name', dm_screenname);

    if (dm_screenname.length && dm_screenname[0] === '*')
        getGroupChatName(dm_screenname, modal.self.find('.modal-header h3 span'));
    else
        getFullname(dm_screenname, modal.self.find('.modal-header h3 span'));

    requestDmConversationModal(modal.self.find('.direct-messages-thread').empty(), dm_screenname);

    $('.dm-form-template').children().clone(true)
        .addClass('open').appendTo(modal.content).fadeIn('fast');
}

function initInterfaceDirectMsg() {
    $('.direct-messages').attr('href','#directmessages');
    $('.userMenu-messages a').attr('href','#directmessages');

    $('#dm-snippet-template').on('click', function() {
        window.location.hash = '#directmessages?user=' + $(this).attr('data-dm-screen-name');
    });

    $('.dm-submit').on('click', directMsgSubmit);
    $('.direct-messages-with-user').on('click', function() {
        window.location.hash = '#directmessages?user=' +
            $(this).closest('[data-screen-name]').attr('data-screen-name');
    });
}

<commit_msg>add hide post preview in directMsgSubmit() too<commit_after>// twister_directmsg.js
// 2013 Miguel Freitas
//
// Handle direct messages modal

function requestDMsnippetList(dmThreadList) {
    var followList = [];
    for (var i = 0; i < followingUsers.length; i++)
        followList.push({username:followingUsers[i]});
    for (var i = 0; i < groupChatAliases.length; i++)
        followList.push({username:groupChatAliases[i]});

    twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList],
        function(req, ret) {processDMsnippet(ret, dmThreadList);}, dmThreadList,
        function(req, ret) {console.log('ajax error:' + ret);}, null
    );
}

function processDMsnippet(dmUsers, dmThreadList) {
    dmThreadList.empty();

    for (var u in dmUsers) {
        // convert snipped to html and add it to date-sorted list
        var dmItem = dmDataToSnippetItem(dmUsers[u][0], u);
        var timeDmItem = parseInt(dmItem.attr('data-time'));
        var existingItems = dmThreadList.children();
        for (var j = 0; j < existingItems.length; j++) {
            var streamItem = existingItems.eq(j);
            var timeExisting = streamItem.attr('data-time');
            if (typeof timeExisting === 'undefined' || timeDmItem > parseInt(timeExisting)) {
                // this post in stream is older, so post must be inserted above
                streamItem.before(dmItem);
                break;
            }
        }
        if (j === existingItems.length)
            dmThreadList.append(dmItem);
    }
    $.MAL.dmThreadListLoaded();
}

function requestDmConversationModal(postboard, dm_screenname) {
    if (postboard.is('html *')) {
        requestDmConversation(postboard, dm_screenname);
        setTimeout(requestDmConversationModal, 1000, postboard, dm_screenname);
    }
}

function requestDmConversation(postboard, dm_screenname) {
    var since_id = undefined;

    var oldItems = postboard.children();
    if (oldItems.length)
        since_id = parseInt(oldItems.eq(oldItems.length - 1).attr('data-id'));

    var userDmReq = [{username: dm_screenname}];
    if (typeof since_id !== 'undefined')
        userDmReq[0].since_id = since_id;

    var count = 100;
    twisterRpc('getdirectmsgs', [defaultScreenName, count, userDmReq],
        function(args, ret) {processDmConversation(args.postboard, args.dm_screenname, ret);},
            {postboard: postboard, dm_screenname: dm_screenname},
        function(arg, ret) {
            var msg = (ret.message) ? ret.message : ret;
            alert(polyglot.t('ajax_error', {error: msg}));
        }, null
    );
}

function processDmConversation(postboard, dm_screenname, dmData) {
    var lastId = undefined;

    if (dmData[dm_screenname]) {
        var dmList = dmData[dm_screenname];
        if (dmList.length) {
            for (var i = 0; i < dmList.length; i++) {
                var dmItem = dmDataToConversationItem(dmList[i], defaultScreenName, dm_screenname)
                    .attr('data-id', dmList[i].id)
                    .appendTo(postboard)
                ;
                lastId = dmList[i].id;
            }
            $.MAL.dmChatListLoaded(postboard);
        }
    }
    if (typeof lastId !== 'undefined')
        resetNewDMsCountForUser(dm_screenname, lastId);
}

function directMsgSubmit(e) {
    e.stopPropagation();
    e.preventDefault();

    var replyText = $(this).closest('.post-area-new').find('textarea');

    replyText.siblings('#post-preview').hide();

    newDirectMsg(replyText.val(), $('.directMessages').attr('data-dm-screen-name'));

    replyText.val('');
}

function newDirectMsg(msg,  dm_screenname) {
    if (typeof lastPostId !== 'undefined') {
        var paramsOrig = [defaultScreenName, lastPostId + 1, dm_screenname, msg];
        var paramsOpt = paramsOrig;
        var copySelf = $.Options.dmCopySelf.val === 'enable';
        if (copySelf && dm_screenname[0] !== '*')
            paramsOpt = paramsOrig.concat(true)

        twisterRpc('newdirectmsg', paramsOpt,
            function(arg, ret) {
                incLastPostId();
                if (arg.copySelf)
                    incLastPostId();
            }, {copySelf: copySelf},
            function(arg, ret) {
                // fallback for older twisterd (error: no copy_self parameter)
                twisterRpc('newdirectmsg', arg.paramsOrig,
                    function(arg, ret) {incLastPostId();}, null,
                    function(arg, ret) {
                        var msg = (ret.message) ? ret.message : ret;
                        alert('Ajax error: ' + msg);
                    }, null
                );
            }, {paramsOrig: paramsOrig}
        );
    } else
        alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)'));
}

// dispara o modal de direct messages
function directMessagesPopup() {
    if (!defaultScreenName) {
      alert(polyglot.t('You have to log in to use direct messages.'));
      return;
    }

    modal = openModal({
        classAdd: 'directMessages',
        content: $('.direct-messages-template').children().clone(true),
        title: polyglot.t('Direct Messages')
    });

    requestDMsnippetList(modal.content.find('.direct-messages-list'));

    modal.self.find('.mark-all-as-read')
        .css('display', 'inline')
        .attr('title', polyglot.t('Mark all as read'))
        .on('click', function() {
            for (var user in _newDMsPerUser) {
                _newDMsPerUser[user] = 0;
            }
            saveDMsToStorage();
            $.MAL.updateNewDMsUI(getNewDMsCount());
        })
    ;
}

function openDmWithUserModal(dm_screenname) {
    if (!defaultScreenName) {
        alert(polyglot.t('You have to log in to use direct messages.'));
        return;
    }

    modal = openModal({
        classAdd: 'directMessages',
        content: $('.messages-thread-template').children().clone(true),
        title: polyglot.t('direct_messages_with', {username: '' + dm_screenname + ''})
    });

    modal.self.attr('data-dm-screen-name', dm_screenname);

    if (dm_screenname.length && dm_screenname[0] === '*')
        getGroupChatName(dm_screenname, modal.self.find('.modal-header h3 span'));
    else
        getFullname(dm_screenname, modal.self.find('.modal-header h3 span'));

    requestDmConversationModal(modal.self.find('.direct-messages-thread').empty(), dm_screenname);

    $('.dm-form-template').children().clone(true)
        .addClass('open').appendTo(modal.content).fadeIn('fast');
}

function initInterfaceDirectMsg() {
    $('.direct-messages').attr('href','#directmessages');
    $('.userMenu-messages a').attr('href','#directmessages');

    $('#dm-snippet-template').on('click', function() {
        window.location.hash = '#directmessages?user=' + $(this).attr('data-dm-screen-name');
    });

    $('.dm-submit').on('click', directMsgSubmit);
    $('.direct-messages-with-user').on('click', function() {
        window.location.hash = '#directmessages?user=' +
            $(this).closest('[data-screen-name]').attr('data-screen-name');
    });
}

<|endoftext|>


<commit_before>/**
 * FCViz
 * Payload script for loan auction pages
 */

window.fcViz = function (e) {
  targetUrl = $(e.target).attr('href');
  switch(targetUrl) {
    case "#bids-summary":
      if ($("#bids_summary_chart_control").length == 0) {
        renderBidSummaryCharts();
      }
      break;
    case "#bids-all":

      break;
    default:
      break;
  }
}

$('.tabs').tabs().bind('change', window.fcViz);

//Observe mutations made to #bids-summary, so that we can reapply window.fcViz
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if(mutation.addedNodes.length > 0) {
      var el = jQuery(document.createElement("a"));
      switch(mutation.addedNodes[0].id) {
        case "bids_summary":
          window.fcViz({ target: el.attr("href", "#bids-summary") });
          break;
        case "loan_offers":
          window.fcViz({ target: el.attr("href", "#bids-all") });
          break;
        default:
          break;
      }
    }
  })
});

observer.observe(document, { childList: true, subtree: true });

var activeId = $("div.active").filter("div.tab-pane").attr("id");
var el = jQuery(document.createElement("a")).attr("href", "#"+activeId);
window.fcViz({target: el});

function renderBidSummaryCharts() {
  var table = $("#bids_summary").find("table");
  var chartControlDiv = document.createElement("div");
  chartControlDiv.id = "bids_summary_chart_control";
  table.before(chartControlDiv);

  var data = makeDataFrom(table);
  var cumData = makeCumulative(data);
  var bidGroups = findBidGroups(table);

  makeBidSummaryChart(data, cumData, bidGroups);
}

function findBidGroups(table) {
  var bidGroups = {};

  table.find("tr.accepted[data-my-bids=1]").each(function(){
    var key = $(this).attr("data-annualised_rate");
    var bidGroup = $(this).nextUntil(":not(.sub-accepted, .sub-group)").clone();
    bidGroup.each(function(){
      $(this).children().last().detach();
      $(this).children().attr("class","tooltip").first().attr("style", null);
    });
    bidGroups[key] = bidGroup;
  });
  return bidGroups;
}

function makeCumulative(data) {
  var cumData = [];
  cumData.push({ name: data[0].name, value: data[0].name === "Rej"? 0 : data[0].value});
  for (i=1;i<data.length;++i) {
    cumData.push({ name: data[i].name, value: data[i].value + cumData[i-1].value});
  }

  var total = +document.getElementById("amount").innerHTML.replace("£","").replace(",","");
  cumData.forEach(function(d){ d.value = d.value/total * 100; });
  return cumData;
}

function makeDataFrom(table) {
  var rows = table.find("tbody");
  var data = [];

  rows.children().filter(":not(.sub-accepted, .sub-group)").each(function(){
    data.push({
      name: +$(this).attr("data-annualised_rate"),
      value: +$(this).attr("data-amount")
    });
  });

  if (data.length > 1 && data[0].name === data[1].name) {
    data[0].name = "Rej";
  }
  return data;
}

function makeBidSummaryChart(data, cumData, bidGroups) {
  var margin = {top: 20, right: 30, bottom: 30, left: 30},
  width = $("#bids-summary").width() * 0.95 - margin.left - margin.right,
  height = 250 - margin.top - margin.bottom;

  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1);

  var y = d3.scale.linear()
      .range([height, 0]);

  var cumY = d3.scale.linear()
      .range([height, 0]);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");

  if (data.length > 30) {
    //Hide every other tick on the x-axis.
    //Do this by inspecting the 3rd element,
    //inferring if it is even or odd, and
    //hiding the tick if it is the other.
    var labelInterval = $("#bid_form").length > 0? 4 : 2;
    var labels = [];
    data.forEach(function(d){ labels.push(d.name)});
    xAxis.tickFormat(function(d){ return labels.indexOf(d) % labelInterval? "" : d; });
  }

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .tickFormat(function(d){ return d3.formatPrefix(d, 3).scale(d); });

  var cumYAxis = d3.svg.axis()
      .scale(cumY)
      .orient("right");

  var chart = d3.select("#bids_summary_chart_control").append("svg")
      .attr("id", "bids_summary_viz")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  x.domain(data.map(function(d) { return d.name; }));
  y.domain([0, d3.max(data, function(d) { return d.value; })]);
  cumY.domain([0, 100]);

  chart.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

  chart.append("g")
    .attr("class", "y axis")
    .call(yAxis)
  .append("text")
    .attr("transform", "translate(10,-20)")
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("(£'000)");

  chart.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + width + ",0)")
    .call(cumYAxis)
  .append("text")
    .attr("transform", "translate(15,-20)")
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("%");

  var div = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

  var commaSeparator = d3.format(",d");

  chart.selectAll("rect")
    .data(data)
  .enter().append("rect")
    .attr("class", "fcviz")
    .attr("x", function(d) { return x(d.name+""); })
    .attr("y", function(d) { return y(d.value); })
    .attr("height", function(d) { return height - y(d.value); })
    .attr("width", x.rangeBand())
    .on("mouseover", function(d){
      div.transition()
        .duration(200)
        .style("opacity", .9);
      var bidGroupSuffix = "";
      if (bidGroups[d.name]) {
        bidGroupSuffix += "
";
        bidGroups[d.name].each(function(){ bidGroupSuffix += "
"+$(this).html()+"
"; });
        bidGroupSuffix += "
";
      }
      div.html("£"+commaSeparator(d.value)+" @ "+d.name+"%"+bidGroupSuffix)
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY - 28) + "px");
    })
    .on("mouseout", function(d){
      div.transition()
        .duration(500)
        .style("opacity", 0);
    });

  var line = d3.svg.line()
    .x(function(d) { return x(d.name); })
    .y(function(d) { return cumY(d.value); });

  chart.append("path")
    .datum(cumData)
    .attr("class", "cum")
    .attr("transform", "translate(" + x.rangeBand()/2 + ",0)")
    .attr("d", line)
    .attr("opacity", 0.5)
    .on("mouseover", function(d){ this.setAttribute("opacity", 1.0); })
    .on("mouseout", function(d){ this.setAttribute("opacity", 0.5); });

  //Render the first bar in the chart semi-transparent if the rate is rejected
  if (data[0].name === "Rej") {
    chart.select("rect").style("opacity", 0.5);
  }
}<commit_msg>Code rework for reusability<commit_after>/**
 * FCViz
 * Payload script for loan auction pages
 */

window.renderBidSummaryCharts = function (table, id) {
  var data = makeSummaryDataFrom(table);
  var cumData = makeSummaryCumulative(data);
  var bidGroups = findBidGroups(table);

  makeBidSummaryChart(id, data, cumData, bidGroups);
}

window.renderAllBidCharts = function (table, id) {

}

window.fcViz = function (e) {
  var targetUrl = $(e.target).attr('href');
  var id = null;
  var renderer = null;
  switch(targetUrl) {
    case "#bids-summary":
      id = "bids_summary_chart_control";
      renderer = renderBidSummaryCharts;
      break;
    case "#bids-all":

      break;
    default:
      break;
  }
  if (id != null && renderer != null) {
    render(targetUrl, id, renderer);
  }
}

$('.tabs').tabs().bind('change', window.fcViz);

//Observe mutations made to #bids-summary, so that we can reapply window.fcViz
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if(mutation.addedNodes.length > 0) {
      var el = jQuery(document.createElement("a"));
      switch(mutation.addedNodes[0].id) {
        case "bids_summary":
          window.fcViz({ target: el.attr("href", "#bids-summary") });
          break;
        case "loan_offers":
          window.fcViz({ target: el.attr("href", "#bids-all") });
          break;
        default:
          break;
      }
    }
  })
});

observer.observe(document, { childList: true, subtree: true });

var activeId = $("div.active").filter("div.tab-pane").attr("id");
var el = jQuery(document.createElement("a")).attr("href", "#"+activeId);
window.fcViz({target: el});

function render(targetUrl, id, renderer) {
  if ($("#"+id).length == 0) {
    var table = $(targetUrl).find("table");
    placeChartDivBeforeTable(table, id);
    renderer(table, id);
  }
}

function placeChartDivBeforeTable(table, chart) {
  var chartControlDiv = document.createElement("div");
  chartControlDiv.id = chart;
  table.before(chartControlDiv);
}

function findBidGroups(table) {
  var bidGroups = {};

  table.find("tr.accepted[data-my-bids=1]").each(function(){
    var key = $(this).attr("data-annualised_rate");
    var bidGroup = $(this).nextUntil(":not(.sub-accepted, .sub-group)").clone();
    bidGroup.each(function(){
      $(this).children().last().detach();
      $(this).children().attr("class","tooltip").first().attr("style", null);
    });
    bidGroups[key] = bidGroup;
  });
  return bidGroups;
}

function makeSummaryCumulative(data) {
  var cumData = [];
  cumData.push({ name: data[0].name, value: data[0].name === "Rej"? 0 : data[0].value});
  for (i=1;i<data.length;++i) {
    cumData.push({ name: data[i].name, value: data[i].value + cumData[i-1].value});
  }

  var total = +document.getElementById("amount").innerHTML.replace("£","").replace(",","");
  cumData.forEach(function(d){ d.value = d.value/total * 100; });
  return cumData;
}

function makeSummaryDataFrom(table) {
  var rows = table.find("tbody");
  var data = [];

  rows.children().filter(":not(.sub-accepted, .sub-group)").each(function(){
    data.push({
      name: +$(this).attr("data-annualised_rate"),
      value: +$(this).attr("data-amount")
    });
  });

  if (data.length > 1 && data[0].name === data[1].name) {
    data[0].name = "Rej";
  }
  return data;
}

function makeBidSummaryChart(id, data, cumData, bidGroups) {
  var margin = {top: 20, right: 30, bottom: 30, left: 30},
  width = $("#bids-summary").width() * 0.95 - margin.left - margin.right,
  height = 250 - margin.top - margin.bottom;

  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1);

  var y = d3.scale.linear()
      .range([height, 0]);

  var cumY = d3.scale.linear()
      .range([height, 0]);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");

  if (data.length > 30) {
    //Hide every other tick on the x-axis.
    //Do this by inspecting the 3rd element,
    //inferring if it is even or odd, and
    //hiding the tick if it is the other.
    var labelInterval = $("#bid_form").length > 0? 4 : 2;
    var labels = [];
    data.forEach(function(d){ labels.push(d.name)});
    xAxis.tickFormat(function(d){ return labels.indexOf(d) % labelInterval? "" : d; });
  }

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .tickFormat(function(d){ return d3.formatPrefix(d, 3).scale(d); });

  var cumYAxis = d3.svg.axis()
      .scale(cumY)
      .orient("right");

  var chart = d3.select("#"+id).append("svg")
      .attr("id", "bids_summary_viz")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  x.domain(data.map(function(d) { return d.name; }));
  y.domain([0, d3.max(data, function(d) { return d.value; })]);
  cumY.domain([0, 100]);

  chart.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

  chart.append("g")
    .attr("class", "y axis")
    .call(yAxis)
  .append("text")
    .attr("transform", "translate(10,-20)")
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("(£'000)");

  chart.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + width + ",0)")
    .call(cumYAxis)
  .append("text")
    .attr("transform", "translate(15,-20)")
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("%");

  var div = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

  var commaSeparator = d3.format(",d");

  chart.selectAll("rect")
    .data(data)
  .enter().append("rect")
    .attr("class", "fcviz")
    .attr("x", function(d) { return x(d.name+""); })
    .attr("y", function(d) { return y(d.value); })
    .attr("height", function(d) { return height - y(d.value); })
    .attr("width", x.rangeBand())
    .on("mouseover", function(d){
      div.transition()
        .duration(200)
        .style("opacity", .9);
      var bidGroupSuffix = "";
      if (bidGroups[d.name]) {
        bidGroupSuffix += "
";
        bidGroups[d.name].each(function(){ bidGroupSuffix += "
"+$(this).html()+"
"; });
        bidGroupSuffix += "
";
      }
      div.html("£"+commaSeparator(d.value)+" @ "+d.name+"%"+bidGroupSuffix)
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY - 28) + "px");
    })
    .on("mouseout", function(d){
      div.transition()
        .duration(500)
        .style("opacity", 0);
    });

  var line = d3.svg.line()
    .x(function(d) { return x(d.name); })
    .y(function(d) { return cumY(d.value); });

  chart.append("path")
    .datum(cumData)
    .attr("class", "cum")
    .attr("transform", "translate(" + x.rangeBand()/2 + ",0)")
    .attr("d", line)
    .attr("opacity", 0.5)
    .on("mouseover", function(d){ this.setAttribute("opacity", 1.0); })
    .on("mouseout", function(d){ this.setAttribute("opacity", 0.5); });

  //Render the first bar in the chart semi-transparent if the rate is rejected
  if (data[0].name === "Rej") {
    chart.select("rect").style("opacity", 0.5);
  }
}
<|endoftext|>


<commit_before>mol.modules.map.menu = function(mol) {

    mol.map.menu = {};

    mol.map.menu.MenuEngine = mol.mvp.Engine.extend({
        init: function(proxy, bus) {
            this.proxy = proxy;
            this.bus = bus;
        },

        /**
         * Starts the MenuEngine. Note that the container parameter is
         * ignored.
         */
        start: function() {

            this.display = new mol.map.menu.BottomMenuDisplay();
            this.display.toggle(true);

            this.addEventHandlers();
            this.fireEvents();
        },

        /**
         * Adds a handler for the 'search-display-toggle' event which
         * controls display visibility. Also adds UI event handlers for the
         * display.
         */
        addEventHandlers: function() {
            var self = this;

            this.display.about.click(
                function(Event) {
                    window.open('/about/');
                }
            );

            this.display.help.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('help-display-dialog')
                    );
                }
            );

            this.display.status.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('status-display-dialog')
                    );
                }
            );

            this.display.feedback.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('feedback-display-toggle')
                    );
                }
            );

            this.bus.addHandler(
                'add-dashboard-toggle-button',
                function(event) {
                    $(self.display).prepend(event.button);
                    self.display.dashboardItem =
                        $(self.display).find('#dashboard');

                    self.display.dashboardItem.click(
                        function(event) {
                            self.bus.fireEvent(
                                new mol.bus.Event('taxonomy-dashboard-toggle'));
                        }
                    );
                }
            );

            this.bus.addHandler(
                'menu-display-toggle',
                function(event) {
                    var params = null,
                    e = null;

                    if (event.visible === undefined) {
                        self.display.toggle();
                        params = {visible: self.display.is(':visible')};
                    } else {
                        self.display.toggle(event.visible);
                    }
                }
            );
        },

        /**
         * Fires the 'add-map-control' event. The mol.map.MapEngine handles
         * this event and adds the display to the map.
         */
        fireEvents: function() {
            var params = {
                    display: this.display,
                    slot: mol.map.ControlDisplay.Slot.BOTTOM,
                    position: google.maps.ControlPosition.RIGHT_BOTTOM
            };
            this.bus.fireEvent(new mol.bus.Event('add-map-control', params));
        }
    });

    mol.map.menu.BottomMenuDisplay = mol.mvp.View.extend({
        init: function() {
            var html = '' +
                '
' +
                    '
Status
' +
                    '
About' +
                '
' +
                    '
Feedback
' +
                    '
Help
' +
                '
';

            this._super(html);
            this.about = $(this).find('.about');
            this.help = $(this).find('.help');
            this.feedback = $(this).find('.feedback');
            this.status = $(this).find('.status');
        }
    });
};

<commit_msg>First pass Start Over button.<commit_after>mol.modules.map.menu = function(mol) {

    mol.map.menu = {};

    mol.map.menu.MenuEngine = mol.mvp.Engine.extend({
        init: function(proxy, bus) {
            this.proxy = proxy;
            this.bus = bus;
        },

        /**
         * Starts the MenuEngine. Note that the container parameter is
         * ignored.
         */
        start: function() {

            this.display = new mol.map.menu.BottomMenuDisplay();
            this.display.toggle(true);

            this.addEventHandlers();
            this.fireEvents();
        },

        /**
         * Adds a handler for the 'search-display-toggle' event which
         * controls display visibility. Also adds UI event handlers for the
         * display.
         */
        addEventHandlers: function() {
            var self = this;

            this.display.start.click(
                function(Event) {
                   self.bus.fireEvent(
                        new mol.bus.Event('toggle-splash')
                    );
                }
            );
            this.display.about.click(
                function(Event) {
                    window.open('/about/');
                }
            );

            this.display.help.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('help-display-dialog')
                    );
                }
            );

            this.display.status.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('status-display-dialog')
                    );
                }
            );

            this.display.feedback.click(
                function(Event) {
                    self.bus.fireEvent(
                        new mol.bus.Event('feedback-display-toggle')
                    );
                }
            );

            this.bus.addHandler(
                'add-dashboard-toggle-button',
                function(event) {
                    $(self.display).prepend(event.button);
                    self.display.dashboardItem =
                        $(self.display).find('#dashboard');

                    self.display.dashboardItem.click(
                        function(event) {
                            self.bus.fireEvent(
                                new mol.bus.Event('taxonomy-dashboard-toggle'));
                        }
                    );
                }
            );

            this.bus.addHandler(
                'menu-display-toggle',
                function(event) {
                    var params = null,
                    e = null;

                    if (event.visible === undefined) {
                        self.display.toggle();
                        params = {visible: self.display.is(':visible')};
                    } else {
                        self.display.toggle(event.visible);
                    }
                }
            );
        },

        /**
         * Fires the 'add-map-control' event. The mol.map.MapEngine handles
         * this event and adds the display to the map.
         */
        fireEvents: function() {
            var params = {
                    display: this.display,
                    slot: mol.map.ControlDisplay.Slot.BOTTOM,
                    position: google.maps.ControlPosition.RIGHT_BOTTOM
            };
            this.bus.fireEvent(new mol.bus.Event('add-map-control', params));
        }
    });

    mol.map.menu.BottomMenuDisplay = mol.mvp.View.extend({
        init: function() {
            var html = '' +
                '
' +
                    '
Start Over
' +
                    '
Status
' +
                    '
About' +
                '
' +
                    '
Feedback
' +
                    '
Help
' +
                '
';

            this._super(html);
            this.start = $(this).find('.start');
            this.about = $(this).find('.about');
            this.help = $(this).find('.help');
            this.feedback = $(this).find('.feedback');
            this.status = $(this).find('.status');
        }
    });
};

<|endoftext|>


<commit_before><commit_msg>more logging<commit_after><|endoftext|>


<commit_before>/**
 * Created with JetBrains WebStorm.
 * User: Abdelkrim
 * Date: 2013/08/21
 * Time: 00:00
 * Copyright (c) 2013 ALT-F1, We believe in the projects we work on™
 */
/*
 * GET home page.
 */

var express = require('express')
, _ = require('lodash')
, jade = require('jade')
, fs = require('fs')
, webshot = require('webshot')
, marked = require('marked')
, dotenv = require('dotenv').config({silent:true})
, request = require('request')
, MarkedMetaData = require('marked-metadata')
, hljs = require('highlight.js')

// , redis = require('redis')
, requestProxy = require('express-request-proxy')
, seneca = require('seneca')();

// require('redis-streams')(redis);

marked.setOptions({
    renderer: new marked.Renderer(),
    header: false,
    gfm: true,
    tables: true,
    // breaks: false,
    // pedantic: false,
    // sanitize: true,
    // smartLists: true,
    // smartypants: false
    highlight: function (code) {
        console.log('CODE:', code);
        return hljs.highlightAuto(code).value;
    }
});

module.exports = (function () {
    'use strict';
    var router = express.Router();

    router.get('/', function (req, res) {
        res.render('index',{
            'pathToAssets': '/bootstrap-3.3.1',
            'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/' + 'carousel',
            'carousel': jade.renderFile('app/views/carousel.jade')
        });
    });
    router.get('/:id', function (req, res) {
        var id = req.params.id;
        res.render(id,{
            'pathToAssets': '/bootstrap-3.3.1',
            // FIXME: when remove carousel design gets smashed. Fix
            'carousel': jade.renderFile('app/views/carousel.jade')
        });
    });

    router.get('/about', function (req, res) {
        res.redirect('http://www.alt-f1.be');
    });
    router.get('/contact', function (req, res) {
        res.redirect('http://www.alt-f1.be/contact-us.html');
    });
    router.get('/template/:selectedTemplate', function (req, res) {
        res.render('bootstrap3-templates/' + req.params.selectedTemplate, {
            'pathToAssets': '/bootstrap-3.3.1',
            'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/' + req.params.selectedTemplate
        });
    });

    router.get('/security/report/:id', function (req, res) {
        // seneca.act({role:'web', cmd:'list', name:'ww', 'q.id':req.params.id}, function (err, msg){
        //     res.render('bootstrap3-templates/dashboard', _.extend({
        //      'pathToAssets': '/bootstrap-3.3.1',
        //      'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/dashboard'
        //     }, msg));
        // });
    });

    var access_object = {};
    var updateSendPulseAccessToken = () => {
        const data = {
            grant_type:'client_credentials',
            client_id:process.env.SENDPULSE_CLIENT_ID,
            client_secret:process.env.SENDPULSE_CLIENT_SECRET
        };

        console.log('Sending', data);
        request.post({url:'https://api.sendpulse.com/oauth/access_token', form: data}, (err, response, body) => {
            access_object = JSON.parse(body);
            setTimeout(updateSendPulseAccessToken, 3600 * 1000);
            console.log(err, access_object);
        });
    };

    updateSendPulseAccessToken()

    router.all('/sendpulse/*', requestProxy({
        //cache: redis.createClient(),
        //cacheMaxAge: 3600,
        url: 'https://api.sendpulse.com/*',
        headers: {
            Authorization: `${access_object.token_type} ${access_object.access_token}`
        }
    }));

    router.get('/ws/:url', (req, res, next) => {
        var url = req.params.url;
        var fname = `${url}.png`;
        var webshot = require('webshot');
        var userAgent = req.headers['user-agent'];
        console.log(userAgent, req.query.options);
        var options = _.extend({
            // screenSize: {
            //  width: '800'
            //  , height: '600'
            // },
            // shotSize: {
            //  width: '300'
            //  , height: 'all'
            // },
             userAgent: userAgent
        }, req.query.options?JSON.parse(req.query.options):{});

        console.log('Capturing screenshot:', url, options);
        //res.writeHead(200, {'Content-Type': 'image/png' });
        // stream the file
        var renderStream = webshot(url, options)
        , screenshot = '';

        // Capture the streaming output from the screenshot
        renderStream.on('data', function(data) {
            screenshot += data.toString('binary');
        });

        // Once the image capture is completed, write it out to the browser
        renderStream.on('end', function() {
            res.set('Content-Type', 'image/png');
            res.end(screenshot, 'binary');
        });

//        renderStream.on('data', res.write.bind(res));
//        renderStream.on('end', res.end.bind(res));

    });

    // Generic section
    router.get('/:section/:id', (req, res, next) => {
        var id = req.params.id
        , section = req.params.section;

        if(['css','img','media', 'js'].indexOf(section) > -1){
            next();
            return;
        }

        var mkmd = new MarkedMetaData(`app/views/${section}/${id}.md`);
        var md = {};
        try {
            md = mkmd.metadata();
        }catch(e){
            console.log('No metadata found');
        }

        res.render(md.layout || 'section',{
            title: md.title,
            pathToAssets: '/bootstrap-3.3.1',
            pathToSelectedTemplateWithinBootstrap : '/bootstrap-3.3.1/docs/examples/' + 'carousel',
            carousel: jade.renderFile('app/views/carousel.jade'),
            body: fs.existsSync(`app/views/${section}/${id}.jade`)?
                jade.renderFile(`app/views/${section}/${id}.jade`):mkmd.markdown()
        });
    });

    return router;
})();
<commit_msg>cleaned up<commit_after>/**
 * Created with JetBrains WebStorm.
 * User: Abdelkrim
 * Date: 2013/08/21
 * Time: 00:00
 * Copyright (c) 2013 ALT-F1, We believe in the projects we work on™
 */
/*
 * GET home page.
 */

var express = require('express')
, _ = require('lodash')
, jade = require('jade')
, fs = require('fs')
, webshot = require('webshot')
, marked = require('marked')
, dotenv = require('dotenv').config({silent:true})
, request = require('request')
, MarkedMetaData = require('marked-metadata')
, hljs = require('highlight.js')

// , redis = require('redis')
, requestProxy = require('express-request-proxy')
, seneca = require('seneca')();

// require('redis-streams')(redis);

marked.setOptions({
    renderer: new marked.Renderer(),
    header: false,
    gfm: true,
    tables: true,
    // breaks: false,
    // pedantic: false,
    // sanitize: true,
    // smartLists: true,
    // smartypants: false
    highlight: function (code) {
        console.log('CODE:', code);
        return hljs.highlightAuto(code).value;
    }
});

module.exports = (function () {
    'use strict';
    var router = express.Router();

    router.get('/', function (req, res) {
        res.render('index',{
            'pathToAssets': '/bootstrap-3.3.1',
            'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/' + 'carousel',
            'carousel': jade.renderFile('app/views/carousel.jade')
        });
    });
    router.get('/:id', function (req, res) {
        var id = req.params.id;
        res.render(id,{
            'pathToAssets': '/bootstrap-3.3.1',
            // FIXME: when remove carousel design gets smashed. Fix
            'carousel': jade.renderFile('app/views/carousel.jade')
        });
    });

    router.get('/about', function (req, res) {
        res.redirect('http://www.alt-f1.be');
    });
    router.get('/contact', function (req, res) {
        res.redirect('http://www.alt-f1.be/contact-us.html');
    });
    router.get('/template/:selectedTemplate', function (req, res) {
        res.render('bootstrap3-templates/' + req.params.selectedTemplate, {
            'pathToAssets': '/bootstrap-3.3.1',
            'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/' + req.params.selectedTemplate
        });
    });

    router.get('/security/report/:id', function (req, res) {
        // seneca.act({role:'web', cmd:'list', name:'ww', 'q.id':req.params.id}, function (err, msg){
        //     res.render('bootstrap3-templates/dashboard', _.extend({
        //      'pathToAssets': '/bootstrap-3.3.1',
        //      'pathToSelectedTemplateWithinBootstrap' : '/bootstrap-3.3.1/docs/examples/dashboard'
        //     }, msg));
        // });
    });

    var access_object = {};
    var updateSendPulseAccessToken = () => {
        const data = {
            grant_type:'client_credentials',
            client_id:process.env.SENDPULSE_CLIENT_ID,
            client_secret:process.env.SENDPULSE_CLIENT_SECRET
        };

        console.log('Sending', data);
        request.post({url:'https://api.sendpulse.com/oauth/access_token', form: data}, (err, response, body) => {
            access_object = JSON.parse(body);
            setTimeout(updateSendPulseAccessToken, 3600 * 1000);
            console.log(err, access_object);
        });
    };

    updateSendPulseAccessToken()

    router.all('/sendpulse/*', requestProxy({
        //cache: redis.createClient(),
        //cacheMaxAge: 3600,
        url: 'https://api.sendpulse.com/*',
        headers: {
            Authorization: `${access_object.token_type} ${access_object.access_token}`
        }
    }));

    router.get('/ws/:url', (req, res, next) => {
        var url = req.params.url;
        var fname = `${url}.png`;
        var webshot = require('webshot');
        var userAgent = req.headers['user-agent'];
        console.log(userAgent, req.query.options);
        var options = _.extend({
             userAgent: userAgent
        }, req.query.options?JSON.parse(req.query.options):{});

        console.log('Capturing screenshot:', url, options);
        // stream the file
        var renderStream = webshot(url, options)
        , screenshot = '';

        // Capture the streaming output from the screenshot
        renderStream.on('data', function(data) {
            screenshot += data.toString('binary');
        });

        // Once the image capture is completed, write it out to the browser
        renderStream.on('end', function() {
            res.set('Content-Type', 'image/png');
            res.end(screenshot, 'binary');
        });
    });

    // Generic section
    router.get('/:section/:id', (req, res, next) => {
        var id = req.params.id
        , section = req.params.section;

        if(['css','img','media', 'js'].indexOf(section) > -1){
            next();
            return;
        }

        var mkmd = new MarkedMetaData(`app/views/${section}/${id}.md`);
        var md = {};
        try {
            md = mkmd.metadata();
        }catch(e){
            console.log('No metadata found');
        }

        res.render(md.layout || 'section',{
            title: md.title,
            pathToAssets: '/bootstrap-3.3.1',
            pathToSelectedTemplateWithinBootstrap : '/bootstrap-3.3.1/docs/examples/' + 'carousel',
            carousel: jade.renderFile('app/views/carousel.jade'),
            body: fs.existsSync(`app/views/${section}/${id}.jade`)?
                jade.renderFile(`app/views/${section}/${id}.jade`):mkmd.markdown()
        });
    });

    return router;
})();
<|endoftext|>


<commit_before>Question.obligatory = ["q", "as"];

function Question(div, options, finishedCallback) {
    this.name = "Question";

    this.finishedCallback = finishedCallback;

    div.className = "question";

    this.question = options.get("q");
    this.answers = options.get("as");
    this.hasCorrect = options.dget("hasCorrect", false);
    this.showNumbers = options.dget("showNumbers", true);
    this.randomOrder = options.dget("randomOrder", true);

    if (this.randomOrder) {
        this.orderedAnswers = new Array(this.answers.length);
        for (var i = 0; i < this.answers.length; ++i)
            this.orderedAnswers[i] = this.answers[i];
        fisherYates(this.orderedAnswers);
    }
    else {
        this.orderedAnswers = this.answers;
    }

    this.qp = document.createElement("p");
    this.qp.appendChild(document.createTextNode(this.question));
    this.xl = document.createElement(this.showNumbers ? "ol" : "ul");
    for (var i = 0; i < this.orderedAnswers.length; ++i) {
        var li = document.createElement("li")
        if (typeof(this.orderedAnswers[i]) == "string") {
            li.appendChild(document.createTextNode(this.orderedAnswers[i]));
        }
        else if (this.orderedAnswers[i].length == 2) {
            li.appendChild(document.createTextNode(this.orderedAnswers[i][1]));
        }
        else {
            assert(false, "Badly formatted 'as' array");
        }
        this.xl.appendChild(li);
    }
    div.appendChild(this.qp);
    div.appendChild(this.xl);

    this.handleKey = function(code, time) {
        if (this.showNumbers &&
            ((code >= 48 && code <= 57) || (code >= 96 && code <= 105))) {
            // Convert numeric keypad codes to ordinary keypad codes.
            var n = code >= 96 ? code - 96 : code - 48;
            if (n > 0 && n <= this.orderedAnswers.length) {
                var ans = typeof(this.orderedAnswers[n-1]) == "string" ? this.orderedAnswers[n-1] : this.orderedAnswers[n-1][1];
                var correct = "NULL";
                if (this.hasCorrect) {
                    var correct_ans = typeof(this.answers[0]) == "string" ? this.answers[0] : this.answers[0][1];
                    correct = correct_ans == ans ? 1 : 0;
                }
                this.finishedCallback([[htmlencode(ans), correct]]);
            }
        }
    }
}
<commit_msg>Add support for answering questions using letter keys.<commit_after>Question.obligatory = ["q", "as"];

function Question(div, options, finishedCallback) {
    this.name = "Question";

    this.finishedCallback = finishedCallback;

    div.className = "question";

    this.question = options.get("q");
    this.answers = options.get("as");
    this.hasCorrect = options.dget("hasCorrect", false);
    this.showNumbers = options.dget("showNumbers", true);
    this.randomOrder = options.dget("randomOrder", true);

    if (this.randomOrder) {
        this.orderedAnswers = new Array(this.answers.length);
        for (var i = 0; i < this.answers.length; ++i)
            this.orderedAnswers[i] = this.answers[i];
        fisherYates(this.orderedAnswers);
    }
    else {
        this.orderedAnswers = this.answers;
    }

    this.qp = document.createElement("p");
    this.qp.appendChild(document.createTextNode(this.question));
    this.xl = document.createElement(this.showNumbers ? "ol" : "ul");
    for (var i = 0; i < this.orderedAnswers.length; ++i) {
        var li = document.createElement("li")
        if (typeof(this.orderedAnswers[i]) == "string") {
            li.appendChild(document.createTextNode(this.orderedAnswers[i]));
        }
        else if (this.orderedAnswers[i].length == 2) {
            li.appendChild(document.createTextNode(this.orderedAnswers[i][1]));
        }
        else {
            assert(false, "Badly formatted 'as' array");
        }
        this.xl.appendChild(li);
    }
    div.appendChild(this.qp);
    div.appendChild(this.xl);

    // TODO: A bit of code duplication in this function.
    this.handleKey = function(code, time) {
        if (this.showNumbers &&
            ((code >= 48 && code <= 57) || (code >= 96 && code <= 105))) {
            // Convert numeric keypad codes to ordinary keypad codes.
            var n = code >= 96 ? code - 96 : code - 48;
            if (n > 0 && n <= this.orderedAnswers.length) {
                var ans = typeof(this.orderedAnswers[n-1]) == "string" ? this.orderedAnswers[n-1] : this.orderedAnswers[n-1][1];
                var correct = "NULL";
                if (this.hasCorrect) {
                    var correct_ans = typeof(this.answers[0]) == "string" ? this.answers[0] : this.answers[0][1];
                    correct = correct_ans == ans ? 1 : 0;
                }
                this.finishedCallback([[htmlencode(ans), correct]]);
            }
        }
        // Letters.
        else if ((code >= 97 && code <= 120) || (code >= 65 && code <= 90)) {
            if (code >= 97)
                code -= (97 - 65);
            for (var i = 0; i < this.answers.length; ++i) {
                var ans = null;
                if (typeof(this.answers[i]) == "string") {
                    if (code == this.answers[i].toUpperCase().charCodeAt(0))
                        ans = this.answers[i];
                }
                else {
                    if (code == this.answers[i][0].toUpperCase().charCodeAt(0))
                        ans = this.answers[i][1];
                }

                if (ans) {
                    var correct = "NULL";
                    if (this.hasCorrect) {
                        var correct_ans = typeof(this.answers[0]) == "string" ? this.answers[0] : this.answers[0][1];
                        correct = correct_ans == ans ? 1 : 0;
                    }
                    this.finishedCallback([[htmlencode(ans), correct]]);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>/* global TrelloPowerUp */

var t = TrelloPowerUp.iframe();

// you can access arguments passed to your iframe like so
var settingsOk = t.arg('settingsOk');
var mapUrl = t.arg('map-url');
var inOverlayMode = t.arg('overlayMode');

var resizeOverlayMap = function() {
    var mapFrameElement = document.getElementById('map-frame');
    var overlayContentElement = document.getElementById('map-overlay-content');
    var overlayContentHeight = overlayContentElement.offsetHeight;
    var mapOffsetTop = mapFrameElement.offsetTop;
    var mapHeight = overlayContentHeight - mapOffsetTop;
    mapFrameElement.height = mapHeight;
};

var handleWindowResize = function(event) {
    resizeOverlayMap();
};

t.render(function () {
    // make sure your rendering logic lives here, since we will
    // recall this method as the user adds and removes attachments
    // from your section
    var mapFrameElement = document.getElementById('map-frame');
    var noSettingsSectionElement = document.getElementById('no-settings-section');
    if (settingsOk) {
        mapFrameElement.src = mapUrl;
        mapFrameElement.style.display='block';
        noSettingsSectionElement.style.display='none';
    } else {
        mapFrameElement.style.display='none';
        noSettingsSectionElement.style.display='block';
    }
    if (inOverlayMode) {
        resizeOverlayMap();

        optimizedResize.addWindowResizeListener(handleWindowResize);

        // close overlay if user clicks outside our content
        document.addEventListener('click', function(event) {
            var eventtarget = event.target;
            if (eventtarget.tagName == 'BODY' || eventtarget.id == 'close-map-overlay' || eventtarget.id == 'close-map-overlay-button') {
                t.closeOverlay().done();
            }
        });

        // close overlay if user presses escape key
        document.addEventListener('keyup', function(event) {
            if (event.keyCode == 27) {
                t.closeOverlay().done();
            }
        });
    } else {
        t.card('attachments')
        .get('attachments')
        .filter(function (attachment) {
            return attachment.url.indexOf('https://www.maprosoft.com/app/map') == 0;
        })
        .then(function (attachments) {
            //var urls = attachments.map(function(a){
            //  return a.url;
            //});
            //document.getElementById('urls').textContent = urls.join(', ');

            mapFrameElement.src = mapUrl;

            //var mapUrlDebugElement = document.getElementById('map-url-debug');
            //if (mapUrlDebugElement) {
            //    mapUrlDebugElement.innerHTML = mapUrl;
            //}
        });
    }
});
<commit_msg>update<commit_after>/* global TrelloPowerUp */

var t = TrelloPowerUp.iframe();

// you can access arguments passed to your iframe like so
//var settingsOk = t.arg('settingsOk');
//var mapUrl = t.arg('map-url');
//var inOverlayMode = t.arg('overlayMode');

var resizeOverlayMap = function() {
    var mapFrameElement = document.getElementById('map-frame');
    var overlayContentElement = document.getElementById('map-overlay-content');
    var overlayContentHeight = overlayContentElement.offsetHeight;
    var mapOffsetTop = mapFrameElement.offsetTop;
    var mapHeight = overlayContentHeight - mapOffsetTop;
    mapFrameElement.height = mapHeight;
};

var handleWindowResize = function(event) {
    resizeOverlayMap();
};

t.render(function () {

    // you can access arguments passed to your iframe like so
    var settingsOk = t.arg('settingsOk');
    var mapUrl = t.arg('map-url');
    var inOverlayMode = t.arg('overlayMode');

    // make sure your rendering logic lives here, since we will
    // recall this method as the user adds and removes attachments
    // from your section
    var mapFrameElement = document.getElementById('map-frame');
    var noSettingsSectionElement = document.getElementById('no-settings-section');
    if (settingsOk) {
        mapFrameElement.src = mapUrl;
        mapFrameElement.style.display='block';
        noSettingsSectionElement.style.display='none';
    } else {
        mapFrameElement.style.display='none';
        noSettingsSectionElement.style.display='block';
    }
    if (inOverlayMode) {
        resizeOverlayMap();

        optimizedResize.addWindowResizeListener(handleWindowResize);

        // close overlay if user clicks outside our content
        document.addEventListener('click', function(event) {
            var eventtarget = event.target;
            if (eventtarget.tagName == 'BODY' || eventtarget.id == 'close-map-overlay' || eventtarget.id == 'close-map-overlay-button') {
                t.closeOverlay().done();
            }
        });

        // close overlay if user presses escape key
        document.addEventListener('keyup', function(event) {
            if (event.keyCode == 27) {
                t.closeOverlay().done();
            }
        });
    } else {
        t.card('attachments')
        .get('attachments')
        .filter(function (attachment) {
            return attachment.url.indexOf('https://www.maprosoft.com/app/map') == 0;
        })
        .then(function (attachments) {
            //var urls = attachments.map(function(a){
            //  return a.url;
            //});
            //document.getElementById('urls').textContent = urls.join(', ');

            mapFrameElement.src = mapUrl;

            //var mapUrlDebugElement = document.getElementById('map-url-debug');
            //if (mapUrlDebugElement) {
            //    mapUrlDebugElement.innerHTML = mapUrl;
            //}
        });
    }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

import ClickOutsideComponent from '../mixins/click-outside-component';
import Filterable from '../mixins/filterable';

export default Ember.Component.extend(Filterable, ClickOutsideComponent, {

    /** Bind conditional classes. */
    classNameBindings: ['hasSelected:has-success', 'isInvalid:has-error', '!removeCreate:input-group'],

    /** Setup component css classes. */
    classNames: [
        'autocomplete-input', 'dropdown-group'
    ],

    /** Update when item being updated from outside. */
    didUpdateAttrs() {
        this._super(...arguments);
        const item = this.get('item');

        if (item && item !== this.get('hasSelected')) {
            this.set('hasSelected', item);
        }
    },

    /** Enable multi select.
     *
     * When multi select is enabled the textfield will not be
     * set with the selected value.
     *
     */
    multiSelect: false,

    /** Setting to disable create button. */
    disableCreate: true,

    /** Setting to hide the create button. */
    removeCreate: true,

    /** Injected services. */
    store: Ember.inject.service('store'),

    /** Name of the store to fetch data from. */
    storeName: null,

    /** Value of the input field */
    value: '',

    /** Limit number of responses. */
    limit: 40,

    /** Has valid selection. */
    hasSelected: false,

    /** Highligted index in dropdown. */
    highlightedIndex: -1,

    /** Update dropdown list when index change. */
    onHighlightedIndexChange: function () {
        if (this.get('hasFocus')) {
            let listItem = this.$('li[data-index='+ this.get('highlightedIndex') +']');

            if (listItem) {
                listItem.addClass('active').siblings().removeClass('active');
            }
        }
    }.observes('highlightedIndex', 'hasFocus'),

    /** Handle item select. */
    onSelected: function () {
        if (this.get('hasSelected')) {
            this.set(
                'value', this.get('hasSelected').get(this.get('displayField', 'name'))
            );

            this.set('hasFocus', false);
        }
    }.observes('hasSelected'),

    /** Return if input is invalid. */
    isInvalid: Ember.computed('hasSelected', 'hasFocus', 'value', function () {
        const isInvalid = (
            (this.get('value') && this.get('value').length > 0 && !this.get('multiSelect')) &&
            !this.get('hasFocus') && !this.get('hasSelected')
        );

        return isInvalid;
    }),

    /** Data to display in preview dropdown. */
    previewData: [],

    /** Does the input field have focus. */
    hasFocus: false,

    /** Field to use in autocomplete search */
    filterField: null,

    /** Timeout between keyup events. */
    keyupTimeout: 150,

    /** Return if preview dropdown is visible. */
    isDropdownVisible: Ember.computed('previewData', 'hasFocus', function () {
        const visible = (this.get('previewData').length || this.get('value.length')) && this.get('hasFocus');

        Ember.run.scheduleOnce('afterRender', this, ()=>{
            if (visible) {
                let element = this.$('')[0];
                if (element && element.scrollIntoView) {
                    element.scrollIntoView({block: "end", behavior: "smooth"});
                }
            }
        });

        return visible;
    }),

    /** Override init. */
    init () {

        /** If using local data decrease the timeout. */
        if (this.localData) {
            this.keyupTimeout = 10;
        }

        return this._super(...arguments);
    },

    /** Fetch data stored in client store with out request.
     *
     * Using this method it's up to the application to keep the data up to date.
     *
     */
    _fetchLocalData (filterField, filterValue, limit) {
        var result = this.get('store').peekAll(this.storeName).filter((item) => {
            let fieldValue = item.get(filterField).toLowerCase();

            return fieldValue.indexOf(filterValue.toLowerCase()) !== -1;
        }).sortBy(filterField).slice(0, limit + 1);

        this.set('previewData', result);
    },

    /** Fetch data from remote server. */
    _fetchRemoteData (filterField, filterValue, limit) {
        var queryParams = {
            search: true,
            limit: limit,
            orderby: filterField
        };

        queryParams[filterField] = filterValue;

        Ember.$.extend(queryParams, this.get('filters'));

        this.get('store').query(this.storeName, queryParams).then((response) => {
            this.set('previewData', response);
        }).catch((reason) => {
            this.set('previewData', []);

            console.warn('Invalid response from server: ', reason);
        });
    },

    /**
     * Fetch data based on search value and update store.
     */
    fetchData () {
        if (this.localData) {
            this._fetchLocalData(
                this.get('filterField'), this.get('value'), this.get('limit')
            );
        } else {
            this._fetchRemoteData(
                this.get('filterField'), this.get('value'), this.get('limit')
            );
        }
    },

    /** Handle event when user clicks outside of component. */
    onOutsideClick () {
        this.set('hasFocus', false);
    },

    /**
     * Handle keyup events in input field.
     */
    _onKeyup () {
        if (!this.get('value').length) {
            this.set('previewData', []);
        } else {
            this.fetchData();
        }

        // Set item as undefined.
        if (!this.get('multiSelect')) {
            this.get('itemSelected')();
            this.set('hasSelected', false);
        }

        this.set('highlightedIndex', -1);
    },

    actions: {

        /**
        * Handle Keydown events in input field.
        *
        * Triggers private method to be able to delay execution.
        *
        */
        onKeyDown (value, event) {
            this.set('hasFocus', true);

            if ([38, 40, 13, 27, 9].indexOf(event.keyCode) !== -1) {
                let index = this.get('highlightedIndex');

                // Arrow key up.
                if (event.keyCode === 38) {
                    index -= 1;
                // Arrow key down
                } else if (event.keyCode === 40) {
                    index += 1;

                // Enter key
                } else if (event.keyCode === 13) {
                    this.send(
                        'onItemClick', this.get('previewData').objectAt(index)
                    );

                    return;

                // ESC and TAB key should remove focus.
                } else if ([27, 9].indexOf(event.keyCode) !== -1) {
                    this.set('hasFocus', false);
                }

                if (index < 0) {
                    index = 0;
                } else if (index > this.get('previewData').length - 1) {
                    index = this.get('previewData').length - 1;
                }

                this.set('highlightedIndex', index);

                return false;
            }

            // Debounce keyup event if user types fast.
            Ember.run.debounce(this, this._onKeyup, this.keyupTimeout);
        },

        /**
         * Handle focus events from input field.
         */
        onFocus () {
            this.set('hasFocus', true);
        },

        /**
         * Handle click event in dropdown list.
         */
        onItemClick (item) {
            // Should be set from parent.
            this.attrs.itemSelected(item);

            if (!this.get('multiSelect')) {
                this.set('hasSelected', item);

            // If multi select clear the value, close the dropdown and give focus to
            // input field.
            } else {
                this.set('value', '');
                this.set('previewData', []);
                this.$('input').focus();
            }
        }
    }
});
<commit_msg>Remove auto focus autocomplete input<commit_after>import Ember from 'ember';

import ClickOutsideComponent from '../mixins/click-outside-component';
import Filterable from '../mixins/filterable';

export default Ember.Component.extend(Filterable, ClickOutsideComponent, {

    /** Bind conditional classes. */
    classNameBindings: ['hasSelected:has-success', 'isInvalid:has-error', '!removeCreate:input-group'],

    /** Setup component css classes. */
    classNames: [
        'autocomplete-input', 'dropdown-group'
    ],

    /** Update when item being updated from outside. */
    didUpdateAttrs() {
        this._super(...arguments);
        const item = this.get('item');

        if (item && item !== this.get('hasSelected')) {
            this.set('hasSelected', item);
        }
    },

    /** Enable multi select.
     *
     * When multi select is enabled the textfield will not be
     * set with the selected value.
     *
     */
    multiSelect: false,

    /** Setting to disable create button. */
    disableCreate: true,

    /** Setting to hide the create button. */
    removeCreate: true,

    /** Injected services. */
    store: Ember.inject.service('store'),

    /** Name of the store to fetch data from. */
    storeName: null,

    /** Value of the input field */
    value: '',

    /** Limit number of responses. */
    limit: 40,

    /** Has valid selection. */
    hasSelected: false,

    /** Highligted index in dropdown. */
    highlightedIndex: -1,

    /** Update dropdown list when index change. */
    onHighlightedIndexChange: function () {
        if (this.get('hasFocus')) {
            let listItem = this.$('li[data-index='+ this.get('highlightedIndex') +']');

            if (listItem) {
                listItem.addClass('active').siblings().removeClass('active');
            }
        }
    }.observes('highlightedIndex', 'hasFocus'),

    /** Handle item select. */
    onSelected: function () {
        if (this.get('hasSelected')) {
            this.set(
                'value', this.get('hasSelected').get(this.get('displayField', 'name'))
            );

            this.set('hasFocus', false);
        }
    }.observes('hasSelected'),

    /** Return if input is invalid. */
    isInvalid: Ember.computed('hasSelected', 'hasFocus', 'value', function () {
        const isInvalid = (
            (this.get('value') && this.get('value').length > 0 && !this.get('multiSelect')) &&
            !this.get('hasFocus') && !this.get('hasSelected')
        );

        return isInvalid;
    }),

    /** Data to display in preview dropdown. */
    previewData: [],

    /** Does the input field have focus. */
    hasFocus: false,

    /** Field to use in autocomplete search */
    filterField: null,

    /** Timeout between keyup events. */
    keyupTimeout: 150,

    /** Return if preview dropdown is visible. */
    isDropdownVisible: Ember.computed('previewData', 'hasFocus', function () {
        const visible = (this.get('previewData').length || this.get('value.length')) && this.get('hasFocus');
        return visible;
    }),

    /** Override init. */
    init () {

        /** If using local data decrease the timeout. */
        if (this.localData) {
            this.keyupTimeout = 10;
        }

        return this._super(...arguments);
    },

    /** Fetch data stored in client store with out request.
     *
     * Using this method it's up to the application to keep the data up to date.
     *
     */
    _fetchLocalData (filterField, filterValue, limit) {
        var result = this.get('store').peekAll(this.storeName).filter((item) => {
            let fieldValue = item.get(filterField).toLowerCase();

            return fieldValue.indexOf(filterValue.toLowerCase()) !== -1;
        }).sortBy(filterField).slice(0, limit + 1);

        this.set('previewData', result);
    },

    /** Fetch data from remote server. */
    _fetchRemoteData (filterField, filterValue, limit) {
        var queryParams = {
            search: true,
            limit: limit,
            orderby: filterField
        };

        queryParams[filterField] = filterValue;

        Ember.$.extend(queryParams, this.get('filters'));

        this.get('store').query(this.storeName, queryParams).then((response) => {
            this.set('previewData', response);
        }).catch((reason) => {
            this.set('previewData', []);

            console.warn('Invalid response from server: ', reason);
        });
    },

    /**
     * Fetch data based on search value and update store.
     */
    fetchData () {
        if (this.localData) {
            this._fetchLocalData(
                this.get('filterField'), this.get('value'), this.get('limit')
            );
        } else {
            this._fetchRemoteData(
                this.get('filterField'), this.get('value'), this.get('limit')
            );
        }
    },

    /** Handle event when user clicks outside of component. */
    onOutsideClick () {
        this.set('hasFocus', false);
    },

    /**
     * Handle keyup events in input field.
     */
    _onKeyup () {
        if (!this.get('value').length) {
            this.set('previewData', []);
        } else {
            this.fetchData();
        }

        // Set item as undefined.
        if (!this.get('multiSelect')) {
            this.get('itemSelected')();
            this.set('hasSelected', false);
        }

        this.set('highlightedIndex', -1);
    },

    actions: {

        /**
        * Handle Keydown events in input field.
        *
        * Triggers private method to be able to delay execution.
        *
        */
        onKeyDown (value, event) {
            this.set('hasFocus', true);

            if ([38, 40, 13, 27, 9].indexOf(event.keyCode) !== -1) {
                let index = this.get('highlightedIndex');

                // Arrow key up.
                if (event.keyCode === 38) {
                    index -= 1;
                // Arrow key down
                } else if (event.keyCode === 40) {
                    index += 1;

                // Enter key
                } else if (event.keyCode === 13) {
                    this.send(
                        'onItemClick', this.get('previewData').objectAt(index)
                    );

                    return;

                // ESC and TAB key should remove focus.
                } else if ([27, 9].indexOf(event.keyCode) !== -1) {
                    this.set('hasFocus', false);
                }

                if (index < 0) {
                    index = 0;
                } else if (index > this.get('previewData').length - 1) {
                    index = this.get('previewData').length - 1;
                }

                this.set('highlightedIndex', index);

                return false;
            }

            // Debounce keyup event if user types fast.
            Ember.run.debounce(this, this._onKeyup, this.keyupTimeout);
        },

        /**
         * Handle focus events from input field.
         */
        onFocus () {
            this.set('hasFocus', true);
        },

        /**
         * Handle click event in dropdown list.
         */
        onItemClick (item) {
            // Should be set from parent.
            this.attrs.itemSelected(item);

            if (!this.get('multiSelect')) {
                this.set('hasSelected', item);

            // If multi select clear the value, close the dropdown and give focus to
            // input field.
            } else {
                this.set('value', '');
                this.set('previewData', []);
                this.$('input').focus();
            }
        }
    }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Route.extend({
  // model(params) {
  //   return this.store.findRecord('post', params.post_id);
  // }
});
<commit_msg>implicit model is better!<commit_after>import Ember from 'ember';

export default Ember.Route.extend({

});
<|endoftext|>