Skip to content

Commit

Permalink
lamapi specifs integration + more detailed readme
Browse files Browse the repository at this point in the history
  • Loading branch information
benromdhane-w committed Feb 28, 2021
1 parent 320c8d6 commit fb9d8aa
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 20 deletions.
149 changes: 138 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,67 @@
# Dashboard for X5GON project
# Learning Analytics Machine Dashboard (LAM Dashboard)

This is an implementation of a dashboard for the X5GON project.
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![License][license-shield]][license-url]

It is released under the terms of the MIT license.
<!-- PROJECT LOGO -->
<p align="center">
<a href="https://platform.x5gon.org">
<img src="readme/logo.svg" alt="Logo" width="80" height="80">
</a>
<p align="center">
<a href="https://www.x5gon.org/wp-content/uploads/2020/04/D3.3_final.pdf"><strong>Explore the full documentation »</strong></a>
<br />
<br />
<a href="https://wp3.x5gon.org">View Demo</a>
·
<a href="https://gitlab.univ-nantes.fr/x5gon/lamdashboard/issues">Report Bug</a>
·
<a href="https://gitlab.univ-nantes.fr/x5gon/lamdashboard/issues">Request Feature</a>
</p>
</p>

## Implementation notes
<!-- TABLE OF CONTENTS -->
<details open="open">
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
<ul>
<li><a href="#built-with">Built With</a></li>
<li><a href="#architecture">Architecture</a></li>
</ul>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#installation">Installation</a></li>
<li><a href="#debugging">Debugging</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
</ol>
</details>

<!-- ABOUT THE PROJECT -->
## About The Project

<img src="readme/lamdashboard.png" width="60%" height="60%" style="height:60%; width:60%; max-width:60%" >

The X5GON project stands for easily implemented freely available innovative technology elements that will converge currently scattered Open Educational Resources (OER) available in various modalities across Europe and the globe.

X5GON's Learning Analytics Machine (LAM) is capable of dealing with multi-lingual collections of OER. We can give you insight into the usage of your resources across different languages, make your content seen across the world and see how your resources are being used in different cultures.

The X5GON LAM Dashboard (models dashboard) is a web dasboard based on the LAM API aiming to show a specific learning use case which is "Exploring in deep the OERs in order to construct a coherent course set of materials".


### Built With

The code is conceived to be build-less, directly usable from any
checkout of the code.
Expand All @@ -14,22 +71,92 @@ defined in .vue syntax and loaded through http-vue-loader. This
approach has one major drawback: since code is dynamically loaded and
interpreted, the devtools interaction is not as direct as it could be.

## Architecture
### Architecture

All application-wide state (search results, basket, sequence) is
stored in the Store component, especially interactions with the API.

## Hacking
## Getting Started

### Installation

It is advised to install vuejs devtools extensions to facilitate debugging.
Hacking: it is advised to install vuejs devtools extensions to facilitate debugging.

## Debugging
### Debugging

If you enter a query in the form d:NAME the application will fetch
data/NAME.json as debug data. It will use it to populate search
results, basket and sequence.

## Authors
## Usage

Once up and running, here is how it's looking the LAM Dashboard, the [Official X5GON LAM Dashboard](https://wp3.x5gon.org).
Some functionnalities:

1. The "OER neighborhood":

[![OER neighborhood][oer-neighborhood]](readme/oer_neighborhood.png)


2. "OREs in the Basket, ready to be exported":

[![OREs in the Basket][oers-inthebasket]](readme/oers_set_inthebasket.png)

<!-- ROADMAP -->
## Roadmap

See the [open issues](https://gitlab.univ-nantes.fr/x5gon/lamdashboard/issues) for a list of proposed features (and known issues).

<!-- CONTRIBUTING -->
## Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

<!-- LICENSE -->
## License

Distributed under the [MIT License](https://opensource.org/licenses/MIT) License. See [LICENSE](LICENSE.txt) for more information.

<!-- CONTACT -->
## Contact

### Authors

Architecture and implementation:
* Olivier Aubert - [@oaubert](https://github.com/oaubert) - <contact@olivieraubert.net>

Graphical design:
* Maxime Zoffoli - <mail@maximezoffoli.com>

### Contributers
Some miner contributions were done in order to fit with the LAM API specifications:
* Victor Connes - <Victor.Connes@univ-nantes.fr>
* Colin de la Higuera - <cdlh@univ-nantes.fr>
* Walid Ben Romdhane - [@walidbrw](https://github.com/walidbrw) - <walid_benromdhane@hotmail.fr>


<!-- MARKDOWN LINKS & IMAGES -->
[contributors-shield]: https://img.shields.io/github/contributors/X5GON/lamdashboard.svg?style=for-the-badge
[contributors-url]: https://gitlab.univ-nantes.fr/x5gon/lamdashboard/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/X5GON/lamdashboard.svg?style=for-the-badge
[forks-url]: https://gitlab.univ-nantes.fr/x5gon/lamdashboard/network/members
[stars-shield]: https://img.shields.io/github/stars/X5GON/lamdashboard.svg?style=for-the-badge
[stars-url]: https://gitlab.univ-nantes.fr/x5gon/lamdashboard/stargazers
[issues-shield]: https://img.shields.io/github/issues/X5GON/lamdashboard.svg?style=for-the-badge
[issues-url]: https://gitlab.univ-nantes.fr/x5gon/lamdashboard/issues
[license-shield]: https://img.shields.io/github/license/X5GON/lamdashboard.svg?style=for-the-badge
[license-url]: https://gitlab.univ-nantes.fr/x5gon/lamdashboard/blob/master/LICENSE
[license]: https://img.shields.io/badge/License-BSD%202--Clause-green.svg
[license-link]: https://opensource.org/licenses/BSD-2-Clause



Architecture and implementation: Olivier Aubert <contact@olivieraubert.net>
Graphical design: Maxime Zoffoli <mail@maximezoffoli.com>
[project-screenshot]: readme/lamdashboard.png
[oer-neighborhood]: readme/oer_neighborhood.png
[oers-inthebasket]: readme/oers_set_inthebasket.png
9 changes: 5 additions & 4 deletions js/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ export default {
concept_mapping_from_reference: false,
max_concepts: 5,
api: {
search: 'http://wp3dev.x5gon.org/others/modelsdsh/search',
neighbors: 'http://wp3dev.x5gon.org/others/modelsdsh/neighbors',
search: 'https://wp3.x5gon.org/others/modelsdsh/search',
neighbors: 'https://wp3.x5gon.org/others/modelsdsh/neighbors',

sequence_sort: 'http://wp3dev.x5gon.org/sequencing/sort',
sequence_insert: 'http://wp3dev.x5gon.org/sequencing/insert',
sequence_sort: 'https://wp3.x5gon.org/sequencing/sort',
sequence_insert: 'https://wp3.x5gon.org/sequencing/insert',
export_tombz: 'https://wp3.x5gon.org/others/moodle/playlist2mbz',

},
// For resource representation
Expand Down
22 changes: 17 additions & 5 deletions js/Sequence.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<ul class="sequence-menu-list">
<li @click="do_addition"><img alt="" src="img/icon_addition.svg">Automatic addition of resources</li>
<li @click="do_export"><img alt="" src="img/icon_export.svg">Export</li>
<li @click="do_export_tombz"><img alt="" src="img/icon_export.svg">Export to MBZ</li>
</ul>
</div>
<x5gon-toolbar></x5gon-toolbar>
Expand Down Expand Up @@ -89,7 +90,7 @@
}
},
computed: {
...Vuex.mapState([ "sequence", "insertions", "sequence_distances" ]),
...Vuex.mapState([ "sequence", "insertions", "sequence_distances", "mbzurl", "mbzinfos"]),
items: function () {
if (this.insertions.length == 0) {
return this.sequence.map(r => ({
Expand Down Expand Up @@ -149,6 +150,7 @@
},
methods: {
on_resource_mouseover: function (item) {
this.active_resource = item;
},
Expand All @@ -173,10 +175,10 @@
do_export: function () {
let resource_repr = (r) => `<li><a href="${r.url}">${r.title}</a></li>`;
const data = `<html><head><title>X5Gon document sequence</title></head><body>
<ol>
${this.sequence.map(resource_repr).join("\n")}
</ol>
</body></html>`;
<ol>
${this.sequence.map(resource_repr).join("\n")}
</ol>
</body></html>`;
const a = document.createElement('a');
document.body.appendChild(a);
const url = URL.createObjectURL(new Blob([data], {type: "octet/stream"}));
Expand All @@ -188,6 +190,15 @@
document.body.removeChild(a);
}, 0);
},
do_export_tombz: function () {
hola = this.$store.dispatch('export_tombz');
hola.finally(response => {
mbz_url = this.mbzurl;
document.body.appendChild(mbz_url);
mbz_url.click();
});
},
insert_item: function (item) {
if (! item.is_suggested) {
return;
Expand All @@ -196,6 +207,7 @@
},
},
mounted: function () {
}
}
</script>
Expand Down
102 changes: 102 additions & 0 deletions js/Store.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ const store = new Vuex.Store({
// Loading message. If not null, display loading spinner
loading_message: "",
show_help: false,
// Mbz infos (url and playlistinfos)
mbzurl : '',
mbzinfos : {},
},

// Mutation are synchronous. They should normally not be directly called, but instead through actions (see below)
Expand Down Expand Up @@ -146,6 +149,14 @@ const store = new Vuex.Store({
show_help(state, value) {
state.show_help = !!value;
},

mbz_url(state, mbzurl) {
state.mbzurl = mbzurl;
},

mbz_pst_infos(state, mbzinfos) {
state.mbzinfos = mbzinfos;
},
},

// Actions are asynchronous. They are called with the dispatch method (or through mapActions in components)
Expand Down Expand Up @@ -203,6 +214,56 @@ const store = new Vuex.Store({
});
},

async query_api_dwdfile({ commit }, query) {
let { url, params, message, debug } = query;
let _store = this;
this.dispatch("start_loading", message);
return new Promise(function (resolve, reject) {
try {
fetch(url, {
method: !debug ? 'POST' : 'GET',
//mode: 'cors',
cache: 'no-cache',
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: !debug ? JSON.stringify(params) : undefined
}).catch(error => {
_store.dispatch("stop_loading", "");
reject(error);
return;
}).then(response => {
if (response === undefined) {
_store.dispatch("stop_loading", "");
reject("Undefined result");
return;
}
response.blob()
.catch(error => {
_store.dispatch("stop_loading", "");
reject(error);
return;
})
.then(data => {
_store.dispatch("stop_loading", "");
if (!data) {
reject("No data");
return;
}
data.filename = (response.headers.get('content-disposition') || '').split('filename=')[1];
resolve(data);
})
})
} catch (error) {
_store.dispatch("stop_loading", "");
reject(error);
return;
}
});
},

async submit_search_query({ commit }, query) {
let url = constant.api.search;
if (query && query.startsWith('d:')) {
Expand Down Expand Up @@ -301,6 +362,42 @@ const store = new Vuex.Store({
});
},

async export_tombz({ commit }) {
if (this.state.sequence.length == 0) {
commit('mbz_url', '');
commit('mbz_pst_infos', {});
return;
}
return this.dispatch('query_api_dwdfile',
{ url: constant.api.export_tombz,
responseType: 'arraybuffer',
headers: {
Accept: "application/octet-stream",
},
params: {
playlist_general_infos: { pst_name: "Playlist from wp3.x5gon.org",
pst_id: Math.floor(Math.random() * 1001)+1,
pst_url: "wp3.x5gon.org",
pst_author: "Anonymous User",
pst_creation_date: (new Date()).toISOString().slice(0, 19).replace("T", " "),
pst_thumbnail_url: "",
pst_description: "This an auto-generated playlist built on wp3.x5gon.org site.",
pst_license: "CC-BY"},
playlist_items: this.state.sequence.map((item , index)=> ({material_id: item.id, x5gon_id: item.id})),
},
message: "Exporting basket to mbz Moodle file..."
}).then(data => {
let blob = new Blob([data], {type: data.type}),
mbzurl = document.createElement('a');
mbzurl.href = window.URL.createObjectURL(blob);
mbzurl.download = data.filename;
commit('mbz_url', mbzurl);
// commit('mbz_pst_infos', params);
}).catch(error => {
this.dispatch("show_error_notification", `Error when Exporting basket to mbz Moodle file: ${error}`);
});
},

async show_error_notification({ commit }, message) {
return this.dispatch('show_notification', { message: message,
type: 'error' });
Expand Down Expand Up @@ -350,6 +447,11 @@ const store = new Vuex.Store({
async hide_help({ commit }) {
commit("show_help", false);
},
},
getters: {
mbzUrl: state => {
return state.mbzurl;
}
}
});

Expand Down
Binary file added readme/lamdashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added readme/oer_neighborhood.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added readme/oers_set_inthebasket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit fb9d8aa

Please sign in to comment.