<commit_before>const ApplicationsData     = require('./authorised_apps.data');
const BinarySocket         = require('../../../../socket');
const showLocalTimeOnHover = require('../../../../../base/clock').showLocalTimeOnHover;
const localize             = require('../../../../../base/localize').localize;
const showLoadingImage     = require('../../../../../base/utility').showLoadingImage;
const State                = require('../../../../../base/storage').State;
const FlexTableUI          = require('../../../../../common_functions/attach_dom/flextable');
const toTitleCase          = require('../../../../../common_functions/string_util').toTitleCase;

const ApplicationsUI = (() => {
    'use strict';

    let can_revoke = false;

    const container_selector = '#applications-container';
    const messages = {
        no_apps       : 'You have not granted access to any applications.',
        revoke_confirm: 'Are you sure that you want to permanently revoke access to application',
        revoke_access : 'Revoke access',
    };

    const formatApp = (app) => {
        const last_used = app.last_used ? app.last_used.format('YYYY-MM-DD HH:mm:ss') : localize('Never');
        const scopes = app.scopes.map(scope => localize(toTitleCase(scope))).join(', ');
        const data = [app.name, scopes, last_used];
        if (can_revoke) {
            data.push(''); // for the "Revoke App" button
        }
        return data;
    };

    const createRevokeButton = (container, app) => {
        const $button = $('<button/>', { class: 'button', text: localize(messages.revoke_access) });
        $button.on('click', () => {
            if (window.confirm(`${localize(messages.revoke_confirm)}: '${app.name}'?`)) {
                BinarySocket.send({ revoke_oauth_app: app.id }).then((response) => {
                    if (response.error) {
                        displayError(response.error.message);
                    } else {
                        BinarySocket.send({ oauth_apps: 1 }).then((res) => {
                            update(res.oauth_apps.map(ApplicationsData.parse));
                        });
                    }
                });
                container.css({ opacity: 0.5 });
            }
        });
        return $button;
    };

    const createTable = (data) => {
        if ($('#applications-table').length) {
            return FlexTableUI.replace(data);
        }
        const headers = ['Name', 'Permissions', 'Last Used'];
        const columns = ['name', 'permissions', 'last_used'];
        can_revoke = /admin/.test((State.get(['response', 'authorize', 'authorize']) || {}).scopes);
        if (can_revoke) {
            headers.push('Action');
            columns.push('action');
        }
        FlexTableUI.init({
            container: container_selector,
            header   : headers.map(s => localize(s)),
            id       : 'applications-table',
            cols     : columns,
            data     : data,
            style    : ($row, app) => {
                if (can_revoke) {
                    $row.children('.action').first().append(createRevokeButton($row, app));
                }
            },
            formatter: formatApp,
        });
        return showLocalTimeOnHover('td.last_used');
    };

    const update = (apps) => {
        $('#loading').remove();
        createTable(apps);
        if (!apps.length) {
            FlexTableUI.displayError(localize(messages.no_apps), 7);
        }
    };

    const displayError = (message) => {
        $(container_selector).find('.error-msg').text(message);
    };<commit_msg>remove columns array and instead create it from headers<commit_after>const ApplicationsData     = require('./authorised_apps.data');
const BinarySocket         = require('../../../../socket');
const showLocalTimeOnHover = require('../../../../../base/clock').showLocalTimeOnHover;
const localize             = require('../../../../../base/localize').localize;
const showLoadingImage     = require('../../../../../base/utility').showLoadingImage;
const State                = require('../../../../../base/storage').State;
const FlexTableUI          = require('../../../../../common_functions/attach_dom/flextable');
const toTitleCase          = require('../../../../../common_functions/string_util').toTitleCase;

const ApplicationsUI = (() => {
    'use strict';

    let can_revoke = false;

    const container_selector = '#applications-container';
    const messages = {
        no_apps       : 'You have not granted access to any applications.',
        revoke_confirm: 'Are you sure that you want to permanently revoke access to application',
        revoke_access : 'Revoke access',
    };

    const formatApp = (app) => {
        const last_used = app.last_used ? app.last_used.format('YYYY-MM-DD HH:mm:ss') : localize('Never');
        const scopes = app.scopes.map(scope => localize(toTitleCase(scope))).join(', ');
        const data = [app.name, scopes, last_used];
        if (can_revoke) {
            data.push(''); // for the "Revoke App" button
        }
        return data;
    };

    const createRevokeButton = (container, app) => {
        const $button = $('<button/>', { class: 'button', text: localize(messages.revoke_access) });
        $button.on('click', () => {
            if (window.confirm(`${localize(messages.revoke_confirm)}: '${app.name}'?`)) {
                BinarySocket.send({ revoke_oauth_app: app.id }).then((response) => {
                    if (response.error) {
                        displayError(response.error.message);
                    } else {
                        BinarySocket.send({ oauth_apps: 1 }).then((res) => {
                            update(res.oauth_apps.map(ApplicationsData.parse));
                        });
                    }
                });
                container.css({ opacity: 0.5 });
            }
        });
        return $button;
    };

    const createTable = (data) => {
        if ($('#applications-table').length) {
            return FlexTableUI.replace(data);
        }
        const headers = ['Name', 'Permissions', 'Last Used'];
        can_revoke = /admin/.test((State.get(['response', 'authorize', 'authorize']) || {}).scopes);
        if (can_revoke) {
            headers.push('Action');
        }
        FlexTableUI.init({
            container: container_selector,
            header   : headers.map(localize),
            id       : 'applications-table',
            cols     : headers.map(title => title.toLowerCase().replace(/\s/g, '-')),
            data     : data,
            style    : ($row, app) => {
                if (can_revoke) {
                    $row.children('.action').first().append(createRevokeButton($row, app));
                }
            },
            formatter: formatApp,
        });
        return showLocalTimeOnHover('td.last_used');
    };

    const update = (apps) => {
        $('#loading').remove();
        createTable(apps);
        if (!apps.length) {
            FlexTableUI.displayError(localize(messages.no_apps), 7);
        }
    };

    const displayError = (message) => {
        $(container_selector).find('.error-msg').text(message);
    };
{'fraction_non_alphanumeric': 0.16985314491548906, 'fraction_numerical': 0.0011083402604599613, 'mean_word_length': 1.856747130985358, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4632659', 'n_tokens_mistral': 2002, 'n_tokens_neox': 1931, 'n_words': 372}