var OBS_URL = obs_url(); var FETCH_CONFIG = { method: 'GET', mode: 'cors', credentials: 'include', }; var FETCH_JSON_CONFIG = Object.assign({}, FETCH_CONFIG, { headers: { 'Accept': 'application/json', }, }); var POST_CONFIG = Object.assign({}, FETCH_CONFIG, { method: 'POST', }); function origin_project(origin) { return origin.replace(/[+~]$/, '') } function param_lookup_package(cell) { return { urlPrefix: OBS_URL + '/package/show/' + project_get() + '/', target: '_blank', }; } function param_lookup_origin(cell) { var origin = cell.getValue(); if (origin == 'None') { return { url: '#' }; } var params = { labelField: 'origin', urlField: 'package', urlPrefix: OBS_URL + '/package/show/' + origin_project(origin) + '/', target: '_blank', }; if (cell.getTable().package) { params['url'] = params['urlPrefix'] + cell.getTable().package; params['urlPrefix'] = null; } return params; } function param_lookup_request(cell) { if (cell.getValue() == null) { return { label: ' ', url: '#' } } return { urlPrefix: OBS_URL + '/request/show/', target: '_blank', }; } function formatter_tristate(cell, formatterParams, onRendered) { onRendered(function() { $(cell.getElement()).sparkline(cell.getValue(), { type: 'tristate', width: '100%', barWidth: 14, disableTooltips: true, }); }); } function sorter_tristate(a, b, aRow, bRow, column, dir, sorterParams) { return sorter_tristate_distance(a) - sorter_tristate_distance(b); } function sorter_request(a, b, aRow, bRow, column, dir, sorterParams) { if (a == b) return 0; if (a == null) return (dir == 'asc' ? 1 : -1) * Number.MAX_SAFE_INTEGER; if (b == null) return (dir == 'asc' ? -1 : 1) * Number.MAX_SAFE_INTEGER; return a - b; } function sorter_tristate_distance(revisions) { var distance = 0; for (var i = revisions.length - 1; i >= 0; i--) { if (revisions[i] === -1) distance += 10; else if (revisions[i] === 0) distance += 1; else break } return distance } function table_selection_get(table) { if (table.getSelectedRows().length > 0) { return table.getSelectedRows()[0].getIndex(); } return null; } function table_selection_set(table, value) { if (typeof table === 'undefined') return; if (table.getSelectedRows().length > 0) { if (table.getSelectedRows()[0].getIndex() != value) { table.getSelectedRows()[0].deselect(); table.selectRow(value); setTimeout(function(){ table.scrollToRow(value, 'middle', false) }, 500); } } else { table.selectRow(value); setTimeout(function(){ table.scrollToRow(value, 'middle', false) }, 500); } } var project_table; function project_table_init(selector) { project_table = new Tabulator(selector, { columns: [ { title: 'Package', field: 'package', headerFilter: 'input', width: 200, formatter: 'link', formatterParams: param_lookup_package, }, { title: 'Origin', field: 'origin', headerFilter: 'input', width: 200, formatter: 'link', formatterParams: param_lookup_origin, }, { title: 'Revisions', field: 'revisions', width: 170, formatter: formatter_tristate, sorter: sorter_tristate, }, { title: 'Request', field: 'request', headerFilter: 'input', width: 100, formatter: 'link', formatterParams: param_lookup_request, sorter: sorter_request, }, ], dataLoaded: package_select_set, index: 'package', initialSort: [ { column: 'package', dir: 'asc' }, ], rowClick: package_select_hash, selectable: 1, tooltips: true, }); } var potential_table; function potential_table_init(selector) { potential_table = new Tabulator(selector, { columns: [ { title: 'Origin', field: 'origin', headerFilter: 'input', width: 200, formatter: 'link', formatterParams: param_lookup_origin, }, { title: 'Version', field: 'version', headerFilter: 'input', width: 100, }, { title: '', formatter: function(cell, formatterParams, onRendered) { return ""; }, width: 20, headerSort: false, tooltip: 'diff', cellClick: potential_external, }, { title: '', formatter: function(cell, formatterParams, onRendered) { return ""; }, width: 20, headerSort: false, tooltip: 'submit', cellClick: potential_submit_prompt, }, ], dataLoaded: potential_select_set, index: 'origin', initialSort: [ { column: 'origin', dir: 'asc' }, ], rowClick: potential_select_hash, selectable: 1, tooltips: true, }); } var history_table; function history_table_init(selector) { history_table = new Tabulator(selector, { columns: [ { title: 'Origin', field: 'origin', headerFilter: 'input', width: 200, formatter: 'link', formatterParams: param_lookup_origin, }, { title: 'Request', field: 'request', headerFilter: 'input', width: 100, formatter: 'link', formatterParams: param_lookup_request, sorter: sorter_request, }, { title: 'State', field: 'state', headerFilter: 'input', width: 100, }, ], dataLoaded: history_select_set, index: 'request', initialSort: [ { column: 'request', dir: 'desc' }, ], pagination: 'local', paginationSize: 15, rowClick: history_select_hash, selectable: 1, tooltips: true, }); } function project_prompt() { const request = new Request(operator_url() + '/origin/projects/all', FETCH_JSON_CONFIG); fetch(request) .then(response => response.json()) .then(projects => { var options = []; for (var i = 0; i < projects.length; i++) { options[i] = {text: projects[i], value: projects[i]}; } bootbox.prompt({ title: 'Project', inputType: 'select', inputOptions: options, closeButton: false, callback: function(project) { if (project) { hash_set([project]); } } }); }); } function project_get() { if ('project' in project_table) { return project_table.project; } return null; } function project_set(project) { if (project == project_get()) { return; } project_table.project = project; project_table.clearData(); project_table.setData(operator_url() + '/origin/list/' + project, {}, FETCH_JSON_CONFIG); project_table.setHeaderFilterFocus('package'); } function package_get() { if (typeof potential_table !== 'undefined' && 'package' in potential_table) { return potential_table.package; } return null; } function package_set(project, package) { if (package == package_get()) { return; } $('aside').toggle(package != null); potential_table.package = package; history_table.package = package; if (package == null) return; potential_table.clearData(); potential_table.setData( operator_url() + '/origin/potentials/' + project + '/' + package, {}, FETCH_JSON_CONFIG); history_table.clearData(); history_table.setData( operator_url() + '/origin/history/' + project + '/' + package, {}, FETCH_JSON_CONFIG); package_select_set(); } function package_select_set() { var package = package_get(); if (package) { table_selection_set(project_table, package); } } function package_select_hash() { if (table_selection_get(project_table)) { hash_set([project_get(), table_selection_get(project_table), origin_project(project_table.getSelectedRows()[0].getData()['origin'])]); } else { hash_set([project_get()]); } } function potential_get() { return hash_get(2); } function potential_set(project, package, origin, request) { if (project == $('#details').data('project') && package == $('#details').data('package') && origin == $('#details').data('origin') && request == $('#details').data('request')) return; var path; if (request != null) { // Unlike a diff between origin and target project a diff between // a request and an origin requires the request source project and // package which are provided along with the history data. As such the // history table must be loaded before the diff can be requested. if (!history_table.getSelectedRows().length) return; var request_data = history_table.getSelectedRows()[0].getData(); path = [ origin, package, request_data['source_project'], request_data['source_package'], 'latest', request_data['source_revision'], ].join('/'); } else { path = [project, package, origin].join('/'); } $('#details').toggle(origin != null); $('#details').data('project', project); $('#details').data('package', package); $('#details').data('origin', origin); $('#details').data('request', request); // At minimum an origin is required, but be sure to toggle element and set // data attributes to handle the next call properly. if (origin == null) return; $('#details').html('

Loading...

'); fetch(operator_url() + '/package/diff/' + path, FETCH_CONFIG) .then(response => response.text()) .then(text => { if (text == '') { $('#details').html('

No difference

'); return; } else if (text.startsWith('# diff failed')) { $('#details').html('

Failed to generate diff

');
                $('#details pre').text(text);
                return;
            }
            $('#details').html(Diff2Html.getPrettyHtml(text));
        });

    potential_select_set();
}

function potential_select_set() {
    var origin = potential_get();
    if (origin) {
        table_selection_set(potential_table, origin);
    }
}

function potential_select_hash() {
    hash_set([project_get(), package_get(), table_selection_get(potential_table),
             table_selection_get(history_table)]);
}

function potential_external(e, cell) {
    window.open(OBS_URL + '/package/rdiff/' + cell.getData()['origin'] + '/' + package_get() +
      '?oproject=' + project_get(), '_blank');
}

function potential_submit_prompt(e, cell) {
    bootbox.prompt({
        title: 'Submit ' + cell.getData()['origin'] + '/' + package_get() + ' to ' + project_get() + '?',
        size: 'large',
        inputType: 'textarea',
        closeButton: false,
        callback: function(message) {
            if (message === null) return;
            potential_submit(project_get(), package_get(), cell.getData()['origin'], message);
        }
    });
}

function potential_submit(project, package, origin, message) {
    fetch(operator_url() + '/request/submit/' + origin + '/' + package + '/' + project +
            '?message=' + encodeURIComponent(message), POST_CONFIG)
        .then(response => response.text())
        .then(log => {
            log = log.trim()
            console.log(log);
            var words = log.split(/\s+/);
            var request = words[words.length - 1];
            if (request == 'failed') {
                bootbox.alert({
                    title: 'Failed to submit ' + origin + '/' + package + ' to ' + project,
                    message: '
' + log.substr(0, log.length - 7) + '
', size: 'large', closeButton: false, }); return; } project_table.updateData([{'package': package, 'request': request}]); }); } function history_get() { return hash_get(3); } function history_select_set() { var request = history_get(); if (request) { table_selection_set(history_table, request); // Trigger appropriate potential_set() call since waiting for history // data to be available for request diff. hash_changed(); } } function history_select_hash() { potential_select_hash(); } var title_suffix; function hash_init() { title_suffix = document.title; window.onhashchange = hash_changed; hash_changed(); } function hash_parts() { return window.location.hash.substr(1).replace(/\/+$/, '').split('/'); } function hash_get(index) { var parts = hash_parts(); if (parts.length > index) { return parts[index]; } return null; } function hash_set(parts) { // Shorten the parts array to before the first null. for (var i = 0; i < parts.length; i++) { if (parts[i] == null) { parts.length = i; break } } window.location.hash = parts.join('/'); } function hash_changed() { // Wait until all tables have been initialized before proceeding. if (typeof history_table === 'undefined') return; var parts = hash_parts(); var project = null; var package = null; var origin = null; var request = null; // route: /* if (parts[0] == '') { project_prompt(); return; } // route: /:project project = parts[0]; project_set(project); // route: /:project/:package if (parts.length >= 2) { package = parts[1]; } package_set(project, package); // route: /:project/:package/:origin if (parts.length >= 3) { origin = parts[2]; } // route: /:project/:package/:origin/:request if (parts.length >= 4) { request = parts[3]; } potential_set(project, package, origin, request); title_update(project, package, origin, request); } function title_update(project, package, origin, request) { var parts = hash_parts(); var title = ''; if (project) { title += project; } if (package) { title += '/' + package; } if (request) { title += ' request ' + request; } if (origin) { title += ' diff against ' + origin; } if (title) { document.title = title + ' - ' + title_suffix; } else { document.title = title_suffix; } }