MediaWiki:Shared.js

From Linjauskone
Revision as of 12:23, 1 December 2023 by Admin (talk | contribs)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
API_URL = mw.util.wikiScript( 'api' );
var actions = [];
var progressItems = {};
var progressItemList = [];
var orgs = {}

class_map = {
    'Tutkimusjulkaisut': 'field-border-1',
    'Toimintakulttuuri': 'field-border-2',
    'Oppiminen' : 'field-border-3',
    'Data' : 'field-border-4'
}
color_map = {
    'Tutkimusjulkaisut': '#007ECA',
    'Toimintakulttuuri': '#53BD9D',
    'Oppiminen' : '#93A0FF',
    'Data' : '#003EAD'
}

function getSortedKeys(dictonary) {
    var sorted = [];
    for(var key in dictonary) {
        sorted[sorted.length] = key;
    }
    sorted.sort();    
    return sorted
}

function intersection(setA, setB) {
    const _intersection = new Set();
    for (const elem of setB) {
        if (setA.has(elem)) {
            _intersection.add(elem);
        }
    }
    return _intersection;
}

const observer = new IntersectionObserver( 
    ([e]) => e.target.classList.toggle('stuck', e.intersectionRatio < 1),
    {threshold: [1]}
)
function renderActionHeader(org_actors) {    
    org_actors.forEach(org_actor => {
        var col = $('<div>', {class:'col'}).html('<h1>' + org_actor.name + '</h1>')
        $('#selected-orgs-row').append(col)
    })   
}

function getSelectedCheckboxes(selector) {
    var selected = new Set()
    $(selector + ' input:checked').each(function () {
        selected.add($(this).val());
    });
    return selected
}

function getSelectedRadio(selector) {
    return $(selector + ' input:checked').val()
}

function getSelectedOptions(selector) {
    var selected = new Set();
    $(selector + ' option:selected').each(function () {
        selected.add($(this).val());
    });
    return selected
}

function getActionYear(action) {
    if(action.action_deadline) {
        return ''+action.action_deadline
    }
    if(action.section_deadline) {
        return ''+action.section_deadline
    }
    return ''+action.policy_endyear
}

function getProgressYear(progress) {
    var d = new Date(progress.date)
    return ''+ d.getFullYear()
}

function group_actions_by_year(actions) {    
    return actions.reduce((groups, item) => {
        year = getActionYear(item)
        const group = (groups[year] || []);
        group.push(item);
        groups[year] = group;
        return groups;
      }, {});
}

function renderAction(obj) {
    var policy_page = obj['action_id_raw'].substring(0, obj['action_id_raw'].indexOf('/'))    
    var policy_doc_link = '/' + policy_page + '#' + obj['section_type_name'] + '_' + obj['section_ordinal'] + ':_' + obj['section_name'].replace(' ', '_')
    var action_card = $('<div>', {class: 'card mb-4 ' + class_map[obj.action_field]})
    var action_header = $('<div>', {class: 'card-header', style:'color: #ffffff;  background-color:' + color_map[obj.action_field]}).html(obj.action_field + ' - ' + obj['section_type_name'] + '  ' + obj.section_ordinal + '<a style="color:white" data-toggle="collapse" href="#collapse' + obj.action_id +'"><i  class="bi bi-chevron-down float-right"></i></a>')
    var action_body = $('<div>', {class: 'card-body'})
    var field_badge = $('<span>', {class: 'badge float-right', style:'background-color:' + color_map[obj.action_field]}).text(obj.action_field)
    var action_section = $('<div>', {class:'collapse', id: 'collapse' + obj.action_id }).html(
        '<h5 style="margin-top: 1em">'+ obj.section_name + '<a style="color: white" href="' + policy_doc_link + '"><i title="Avaa linjausteksti" style="margin-left: 1em;" class="bi bi-box-arrow-up-right"></i></a></h5><p> ' + obj.section_desc + '</p>'
    )
    var action_title = $('<h5>', {class: 'card-title'}).text(obj.action_name)
    //var action_title = $('<h5>', {class: 'card-title'}).html(obj.action_name+'<i class="bi bi-question-octagon-fill float-right" style="font-size: 2rem; color:'+ color_map[obj.action_field] +'" data-trigger"focus" data-container="body" data-toggle="popover" data-placement="top" data-content="' + obj.section_desc + ' "></i>')
    var action_text = $('<p>', {class: 'card-text'}).text(obj.action_description)


    var action_footer = $('<div>', {class: 'card-footer', style:'background-color: ' + color_map[obj.action_field]})

    var progressCount = 0
    if(obj.action_id in progressItems) {
        var p_items = progressItems[obj.action_id]
        var progressCount = p_items.length
    }
    if(progressCount > 0) {
        console.log(progressCount)
        var progress_button = $('<button>', {class: 'btn btn-secondary float-right', type:'button', onclick:'$("#' + obj.action_id + '").modal("show")'}).html('Edistysaskeleita<span style="margin-left: 5px" class="badge badge-dark">' + progressCount +'</span>')
        action_body.append(progress_button)
        console.log(obj)
    }
    var progress_add = $('<a>', {class:'new-progress btn btn-outline-primary float-right', style: 'color: white; border-color: white;', href:'/index.php/Special:FormEdit/Progress?Progress[Action]='+encodeURIComponent(obj.action_id_raw)  }).text('Add new')         

    action_card.append(action_header)
    action_card.append(action_body)
    
    action_header.append(action_section)

    action_body.append(action_title)
    action_body.append(action_text)
    //action_body.append(action_link)
    addProgressModal(obj)

    return action_card
}

function addProgressModal(action) {    
    if(action.action_id in progressItems) {
        console.log(action)
        var _progressItems = progressItems[action.action_id]

        var $modalContainer = $('<div>', {class:'modal', tabindex:'-1', role:'dialog', id:action.action_id})
        var $modal = $('<div>', {class:'modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable', role:'document'})
        var $modalContent = $('<div>', {class:'modal-content'})
        var $modalHeader = $('<div>', {class:'modal-header'})
        var $title = $('<h5>', {class:'modal-title'}).text(action.section_type_name)
        var $titleClose = $('<button>', {type:'button', class:'close', 'data-dismiss':'modal'})
        var $close = $('<span>').html('&times;')
        $titleClose.append($close)

        var $actionText = $('<p>', {class:'card-text'}).text((action.action_name != '' ? action.action_name + '. ' : '') + action.action_description)
        var $actionRole = $('<h6>', {class:'card-subtitle mb-2 text-muted'}).text(action.action_responsible_actor.join(','))
        var $objectiveName = $('<h5>', {class:'card-title'}).text(action.section_name)
        var $policyLink = $('<a>', {href:'#', class:'card-link'}).text(action.policy_name)
        var $modalBody = $('<div>', {class:'modal-body'})
        var $sectionType = $('<p>').text(action.section_type_name)
        //$modalBody.append($sectionType)
        $modalBody.append($objectiveName)
        //$modalBody.append($actionRole)
        //$modalBody.append($actionText)

        _progressItems.forEach(function(progressItem) {
            $modalBody.append(createProgressCard(progressItem))
        })
        $modalHeader.append($title)
        $modalHeader.append($titleClose)

        $modalContent.append($modalHeader)
        $modalContent.append($modalBody)

        $modal.append($modalContent)

        $modalContainer.append($modal)

        $('#modals').append($modalContainer)
    }
}

function createProgressCard(data) {
    var $card = $('<div>', {class:'card', style: 'margin-bottom: 1em;'})
    var $cardBody = $('<div>', {class:'card-body'})
    var $cardTitle = $('<h5>', {class: 'card-title'}).text(data.name)
    var $cardSubTitle = $('<h6>', {class:'card-subtitle mb-2 text-muted'}).text(data.date)
    var $cardSubTitle2 = $('<h6>', {class:'card-subtitle mb-2 text-muted'}).text(data.org)
    $cardText = $('<p>', {class: 'card-text'}).text(data.desc)

    $cardBody.append($cardTitle)
    $cardBody.append($cardSubTitle)
    $cardBody.append($cardSubTitle2)
    $cardBody.append($cardText)
    $card.append($cardBody)

    return $card
}

async function updateProgressData(data) {
    console.log(data)
    items = {}
    data.forEach(function (r) {
        progressID = Object.keys(r)[0]
        obj = r[progressID]
        console.log(obj)
        date = ''
        if (obj.printouts['Date'].length > 0 && obj.printouts['Date'][0].timestamp) {
            date = new Date(parseInt(obj.printouts['Date'][0].timestamp) * 1000)
        }

        actionID = obj.printouts.Action[0].fulltext.replace('#', '').replace(/\s/g, '').replace(':', '').replace('/', '')
        progressUrl = obj.printouts.Action[0].fullurl
        name = obj.printouts.Name || ''
        desc = obj.printouts.Description || ''
        orgName = obj.printouts.OrgName || ''
        orgBusinessID = obj.printouts.BusinessID[0] || ''

        var section_desc = obj.printouts['sectionDesc'][0] || '' // footnotes!
        section_desc = section_desc.replace(/\[\[.*\]\]/g, "");

        if (!(actionID in items)) {
            items[actionID] = []
        }
        var item = {
            url: obj.fullurl,
            fulltext: obj.fulltext,
            actionID: actionID,
            url: progressUrl,
            date: date,
            name: name,
            desc: desc,
            org: orgName,
            businessID: orgBusinessID,
            'policy_name': obj.printouts['policyName'][0] || '',
            'section_ordinal': obj.printouts['sectionOrdinal'][0] || null,
            'section_name': obj.printouts['sectionName'][0] || '',
            'section_desc': section_desc,
            'section_type_name': obj.printouts['sectionTypeName'][0] || '',
            'action_domain': obj.printouts['Domain'][0].fulltext || '',
            'action_field': obj.printouts['Field'][0] || '',

        }
        items[actionID].push(item)
        progressItemList.push(item)
    })
    progressItems = items
}

function updateActions(data) {
    console.log(data)
    actions = []
    data.forEach(function (r) {
        progressID = Object.keys(r)[0]
        obj = r[progressID]
        

        var section_desc = obj.printouts['sectionDesc'][0] || '' // footnotes!
        section_desc = section_desc.replace(/\[\[.*\]\]/g, "");
        var action_description = obj.printouts['Description'][0] || ''
        //action_description = action_description.replace(/<\/?[^>]+(>|$)/g, "")
        actions.push(
            {
                'policy_name': obj.printouts['policyName'][0] || '',
                'policy_endyear': obj.printouts['policyEndYear'][0] || null,
                'section_name': obj.printouts['sectionName'][0] || '',
                'section_desc': section_desc,
                'section_deadline': obj.printouts['Section deadline'][0] || null,
                'section_ordinal': obj.printouts['sectionOrdinal'][0] || null,
                'section_type': obj.printouts['sectionType'][0].fulltext || '',
                'section_type_name': obj.printouts['sectionTypeName'][0] || '',
                'action_deadline': obj.printouts['Action deadline'][0] || null,
                'action_description': action_description,
                'action_field': obj.printouts['Field'][0] || '',
                'action_domain': obj.printouts['Domain'][0].fulltext || '',
                'action_name': obj.printouts['Name'][0] || '',
                'action_responsible_actor': obj.printouts['Responsible actor'],
                'action_id': obj.fulltext.replace('#', '').replace(/\s/g, '').replace(':', '').replace('/', ''),
                'action_id_raw': obj.fulltext

            }
        )
    })
}

function updateOrgs(data) {
    console.log(data)
    actions = []
    data.forEach(function (r) {
        progressID = Object.keys(r)[0]
        obj = r[progressID]
        console.log(obj)
        var businessID = obj.printouts['BusinessID'][0] || ''
        // handle localized string queries and separate properties -  todo refactor this out
        var actors = []
        var actor_ids = obj.printouts['Responsible actor']
        var actors_fi = obj.printouts['actors_fi']
        var actors_sv = obj.printouts['actors_sv']
        var actors_en = obj.printouts['actors_en']

        for (let i = 0; i < actor_ids.length; i++) {
            actors.push({
                id: actor_ids[i].fulltext,
                fi: actors_fi[i],
                sv: actors_sv[i],
                en: actors_en[i]
            })
        }
        var name = obj.printouts['Name'][0] || ''
        orgs[businessID] = {
            'name': name,
            'businessID': businessID,
            'responsible_actors': actors,
        }
        if($('#orgs').length) {
            $('#orgs').append('<option value="'+businessID+'">'+name+'</option>')    
        }

    })
    console.log(orgs)
}

function updateActors(data) {
    console.log(data)
    data.forEach(function (r) {
        id = Object.keys(r)[0]
        
        var name = r[id].printouts['Name'][0]
        $('#actors').append('<option value="'+id+'">'+name+'</option>')    
        console.log('test')
    })  
    
}

async function fetch_data(lang) {
    // get all Actions
console.log(lang)
    const actionQuery = '[[Category:Action]]|?Part of document.Name ' + lang + '=sectionName|?Part of document.Type=sectionType|?Part of document.Type.Name ' + lang + '=sectionTypeName|?Part of document.Description ' + lang + '=sectionDesc|?Part of document.Ordinal=sectionOrdinal|?Part of document.Document.Name ' + lang + '=policyName|?Part of document.Document.Validity end=policyEndYear|?Part of document.Document.Field.Name ' + lang + '=Field|?Part of document.Document.Field=Domain|?Name ' + lang + '=Name|?Description ' + lang + '=Description|?Responsible actor|?Deadline year=Action deadline|?Part of document.Name ' + lang + '=Section name|?Part of document.Deadline year=Section deadline|limit=50'

    const progressQuery = '[[Category:Progress]]|?Name|?Description|?Date|?Action|?Organization.Name=OrgName|?Organization.BusinessID=BusinessID|?Action.Part of document.Name ' + lang + '=sectionName|?Action.Part of document.Type.Name ' + lang + '=sectionTypeName|?Action.Part of document.Description ' + lang + '=sectionDesc|?Action.Part of document.Ordinal=sectionOrdinal|?Action.Part of document.Document.Name ' + lang + '=policyName|?Action.Part of document.Document.Field=Domain|?Action.Part of document.Document.Field.Name ' + lang + '=Field|sort=Date|order=desc'

    const orgQuery = '[[Category:Organization]]|?Name|?BusinessID|?Responsible actor|?Responsible actor.Name fi=actors_fi|?Responsible actor.Name sv=actors_sv|?Responsible actor.Name en=actors_en|limit=500'

    const actorQuery = '[[Category:Actor]]|?Name ' + lang + '=Name|limit=500'

    $('#spinner').show()
    $('#error').hide()


    return Promise.all([
        executeAsk(progressQuery)
            .then(updateProgressData),
        executeAsk(actionQuery)
            .then(updateActions),
        executeAsk(actorQuery)
            .then(updateActors),
        executeAsk(orgQuery)
            .then(updateOrgs)
    ])
        .then(() => {
            console.log('data loaded')
            $('#spinner').hide()
            if(glang === 'fi') {
              var countSelectedText = '{0}/{1} valittu'
              var deselectAllText = 'poista valinnat'
              var noneSelectedText = 'ei valintoja'
              var selectAllText = 'valitse kaikki' 
            }
            $('#orgs').selectpicker({
                actionsBox: true,
                selectedTextFormat: 'count',
                liveSearch: true,
                multiple: true,
                maxOptions: ORGS_MAX_OPTIONS,
                countSelectedText: countSelectedText,         
                deselectAllText: deselectAllText,         
                noneSelectedText: noneSelectedText,         
                selectAllText: selectAllText         
            })
            $('#actors').selectpicker({
                actionsBox: true,
                selectedTextFormat: 'count',
                liveSearch: true,
                multiple: true,
                countSelectedText: countSelectedText,         
                deselectAllText: deselectAllText,         
                noneSelectedText: noneSelectedText,         
                selectAllText: selectAllText  
            })
            const queryString = window.location.search;
            const urlParams = new URLSearchParams(queryString);
            if(urlParams.has('actors')) {
                 $('#actors').selectpicker('selectAll');
            }
            $('#filters').collapse('show')
        })

}


async function executeAsk(query) {

    var results = [];
    var res = null;
    var offset = 0
    try {
        while (res == null || res.query.results.length == 50) {

            _query = query + '|offset=' + offset
            console.log(_query)
            res = await $.ajax({
                url: API_URL,
                data: {
                    action: 'ask',
                    format: 'json',
                    api_version: 3,
                    query: _query
                    
                },
                xhrFields: {
                    withCredentials: false
                },
                dataType: 'json'
            })
            offset = offset + 50
            results = results.concat(res.query.results)
        }
        return results
    } catch (error) {
        $('#spinner').hide()
        $('#error').text(error)
        $('#error').show()
        console.log(error)
    }

}

Sivustoa ylläpitää Avoimen tieteen ja tutkimuksen (AVOTT) kansallisen koordinaation sihteeristö, joka toimii Tieteellisten seurain valtuuskunnassa (TSV) Opetus- ja kulttuuriministeriön (OKM) rahoituksella. Avoimen tieteen ja tutkimuksen koordinaatio edistää avoimen tieteen ja tutkimuksen toteutumista sekä keskustelua sen mahdollisuuksista, haasteista sekä niiden ratkaisuista Suomessa.

Webbplatsen upprätthålls av Sekretariatet för den nationella samordningen av öppen vetenskap och forskning. Sekretariatet verkar vid Vetenskapliga samfundens delegation med finansiering från undervisnings- och kulturministeriet. Samordningen främjar öppen vetenskap och forskning samt diskussion kring dess möjligheter, utmaningar och lösningar i Finland.

This website is maintained by the Secretariat of the National Coordination for Open Science and Research in Finland (AVOTT), which operates in the Federation of Finnish Learned Societies (TSV) with funding from the Ministry of Education and Culture (OKM). The Open Science and Research Coordination promotes open science and research, as well as discussion on its opportunities, challenges and their solutions in Finland.