Skip to content

Commit

Permalink
Merge pull request #178 from LS-LEDA/dev
Browse files Browse the repository at this point in the history
MLA v1.2.0
  • Loading branch information
JiahuiChen99 committed Aug 19, 2022
2 parents 5258d19 + a07936b commit 36f4c11
Show file tree
Hide file tree
Showing 41 changed files with 1,814 additions and 159 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mla",
"version": "1.1.0",
"version": "1.2.0",
"license": "GPL-3.0",
"description": "Moodle Learning Analytics",
"homepage": "https://ls-leda.github.io/Moodle-Learning-Analytics/",
Expand Down Expand Up @@ -57,14 +57,17 @@
"@nlpjs/language": "^4.21.1",
"@nlpjs/nlp": "^4.22.0",
"@nlpjs/sentiment": "^4.22.0",
"@tensorflow/tfjs": "^3.19.0",
"chart.js": "^3.6.0",
"chartjs-plugin-zoom": "^1.2.0",
"core-js": "^3.6.5",
"echarts": "^5.3.1",
"electron-store": "^8.0.1",
"node-nlp": "^4.22.1",
"v8-compile-cache": "^2.3.0",
"vue": "^3.0.0",
"vue-router": "^4.0.12",
"vue-showdown": "^3.3.0",
"vuex": "^4.0.2"
},
"devDependencies": {
Expand All @@ -81,6 +84,7 @@
"post-loader": "^2.0.0",
"postcss": "^8.3.11",
"postcss-cli": "^9.0.1",
"raw-loader": "^4.0.2",
"tailwindcss": "^3.0.15",
"vue-cli-plugin-electron-builder": "~2.1.1"
},
Expand Down
62 changes: 62 additions & 0 deletions src/assets/weeklyInteractionsMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const hours = [
'00', '01', '02', '03', '04', '05', '06',
'07', '08', '09', '10', '11',
'12', '13', '14', '15', '16', '17',
'18', '19', '20', '21', '22', '23'
];

const days = [
'Sunday','Saturday', 'Friday', 'Thursday',
'Wednesday', 'Tuesday', 'Monday'
];

const weeklyInteractionConfig = {
tooltip: {
position: 'top'
},
grid: {
height: '60%',
top: 'center',
},
xAxis: {
type: 'category',
data: hours,
splitArea: {
show: true
}
},
yAxis: {
type: 'category',
data: days,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 500,
calculable: true,
orient: 'vertical',
top: 'center',
right: '3%',
},
series: [
{
name: 'Weekly Interactions',
type: 'heatmap',
coordinateSystem: 'cartesian2d',
data: null,
label: {
show: true
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};

export default weeklyInteractionConfig;
13 changes: 10 additions & 3 deletions src/background.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

import { app, protocol, BrowserWindow, webContents, shell, ipcMain, Tray, Menu } from 'electron'
import { app, protocol, BrowserWindow, webContents, shell, ipcMain, Tray, Menu, nativeImage } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'
const path = require('path')
Expand Down Expand Up @@ -72,7 +72,8 @@ ipcMain.on('read_settings', (event, args) => {
*/
ipcMain.on('write_settings', (event, args) => {
try {
config.set(args.key, args.value)
let setting = JSON.parse(args);
config.set(setting.key, setting.value);
applySettings(args.key, args.value);
} catch (err) {
event.reply('write_settings', err);
Expand Down Expand Up @@ -153,12 +154,18 @@ async function createWindow() {
}
}

// TODO: OS dependant icon
/**
* Fired after createWindow
* Creates MLA's tray with its icon & menu
*/
function createTray() {
tray = new Tray(iconPath);
let trayImage = nativeImage.createFromPath(iconPath);
trayImage.resize({
width: 32,
height: 32
})
tray = new Tray(trayImage);
const contextMenu = Menu.buildFromTemplate([
{ id: 0, label: 'MLA webpage', click: trayMenuAction },
{ type: 'separator' },
Expand Down
2 changes: 1 addition & 1 deletion src/components/InformationPanel/InformationPanel.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="h-full w-96 overflow-y-hidden pb-4">
<div class="flex flex-col bg-secondary dark:bg-dark_secondary h-full rounded-lg mx-2 my-2">
<Item :title="log_name"/>
<Item v-if="log_name" :title="log_name"/>
<Calendar @dateSelect="selectDate" calendarID="1"/>
<Calendar @dateSelect="selectDate" calendarID="2"/>
</div>
Expand Down
35 changes: 35 additions & 0 deletions src/components/Settings/AI/EmotionCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<div class="flex w-auto h-auto place-items-center">
<div class="flex w-full h-fit">
{{ emotion }}
</div>
<IconButton :icon="remove_icon" :type="false" :status="true" @click="this.$emit('removeEmotion')"/>
</div>
</template>

<script>
import IconButton from "@/components/UI/IconButton";
import {mdiClose} from "@mdi/js";
/**
* EmotionCard is a component for the list of imported
* emotions in the AI settings tab.
*/
export default {
name: "EmotionCard",
props: ['emotion'],
components: {
IconButton
},
data() {
return {
remove_icon: mdiClose
}
}
}
</script>

<style scoped>
</style>
34 changes: 34 additions & 0 deletions src/components/Students/DedicationCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div class="flex w-full h-fit bg-primary dark:bg-dark_primary rounded-lg p-5">
<div class="flex w-1/12 font-bold justify-center"> {{ id }}. </div>
<div class="flex w-5/12"> {{ name }} </div>
<div class="flex w-2/12"> {{ Math.round(student.total) }} </div>
<div class="flex w-4/12"> {{ this.time_spent() }} </div>
</div>
</template>

<script>
/**
* DedicationCard component used in Student Dedication list
*/
export default {
name: "DedicationCard",
props: ['id', 'name', 'student'],
methods: {
/**
* Convert student total time spent to days, hours, minutes format
* @returns {`${number} days ${number} hours ${number} minutes`}
*/
time_spent: function () {
let days = Math.round(this.student.total / 24 / 60);
let hours = Math.floor(this.student.total / 60);
let minutes = Math.round(this.student.total % 60);
return `${days} days ${hours} hours ${minutes} minutes`;
}
}
}
</script>

<style scoped>
</style>
26 changes: 26 additions & 0 deletions src/components/Students/ParticipationCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<div class="flex w-full h-fit bg-primary dark:bg-dark_primary rounded-lg p-5">
<div class="flex w-1/12 font-bold justify-center"> {{ id }}. </div>
<div class="flex w-8/12"> {{ name }} </div>
<div class="flex-none w-2/12"> {{ student.count }} </div>
<div class="flex w-2/12"> {{ student.percent.toFixed(2) }} % </div>
</div>
</template>

<script>
/**
* ParticipationCard is a component for the student
* participation table in the students' dashboard page.
* It provides information about the amount of tasks
* that a student has done in Moodle course
* Student Name - Participation % - Amount of tasks
*/
export default {
name: "ParticipationCard",
props: ['id', 'name', 'student']
}
</script>

<style scoped>
</style>
56 changes: 56 additions & 0 deletions src/components/Students/StudentCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<div class="flex w-full rounded-lg h-fit bg-primary dark:bg-dark_primary place-items-center p-5 gap-x-3">
<!-- List view Student Card -->
<div v-if="!grid" class="flex flex-col w-4/12">
<!-- Student Name -->
<span class="font-bold"> {{ name }} </span>
<span class="text-slate-800"> {{ student.last_resource }} </span>
</div>

<!-- Last Connection -->
<span v-if="!grid" class="flex w-4/12"> {{ time_conversion() }} </span>

<!-- Grid view Student Card -->
<div v-if="grid" class="flex flex-col w-full">
<span class="truncate text-ellipsis whitespace-nowrap font-bold"> {{ name }} </span>
<!-- Student Name -->
<span class="flex"> {{ time_conversion() }} </span>
</div>
</div>
</template>

<script>
/**
* Student Card is a component for students list section
* in Dashboard > Students > Students List
* The layout changes according to the selected view
* List View / Grid view
*/
export default {
name: "StudentCard",
props: ['student', 'name', 'grid'],
methods: {
/**
* Converts UNIX timestamp back to human-readable format
* @returns {`${string}
${string},
${string}
${string}
`}
*/
time_conversion: function () {
let date = new Date(this.student.timestamp * 1000);
return `${date.toLocaleString('default', {month: 'short'}).toUpperCase()}
${date.toLocaleString('default', {day: '2-digit'})},
${date.toLocaleString('default', {year: 'numeric'})}
${date.toLocaleString('default', {hour: '2-digit', minute: '2-digit'})}
`
}
}
}
</script>

<style scoped>
</style>
69 changes: 69 additions & 0 deletions src/components/Students/StudentDedication.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<div class="flex flex-col w-4/6 h-1/2 bg-secondary dark:bg-dark_secondary rounded-xl p-3 gap-y-3">
<div class="flex w-full justify-between">
<span class="flex font-bold text-xl">
Student Dedication
</span>
<button type="button" class="items-end place-self-end text-gray-500 rounded-lg hover:bg-gray-300"
@click.stop="this.sd_info = !this.sd_info">
<SvgIcon class="hover:cursor-pointer" type="mdi" :path="sd_info ? close_icon : info_icon"/>
</button>
</div>
<!-- Student participation list -->
<div class="flex flex-col w-full h-full overflow-y-auto">
<div v-if="!sd_info" class="flex flex-col w-full h-96 gap-y-5 pr-1">
<!-- List header -->
<div class="flex w-full h-auto px-5 font-bold">
<div class="flex w-1/12 justify-center"> ID </div>
<div class="flex w-5/12"> Student Name </div>
<div class="flex w-2/12"> Minutes </div>
<div class="flex w-4/12"> Time spent </div>
</div>
<DedicationCard v-for="(student, name, index) in students_dedication"
:key="index"
:id="index"
:name="name"
:student="student"
/>
</div>
<!-- Information -->
<p v-else>
Total time that each member has dedicated to the course.
</p>
</div>
</div>
</template>

<script>
/**
* Student Dedication list in students section
* TODO: Merge this component with StudentParticipation list
*/
import {mdiClose, mdiHelpCircleOutline} from "@mdi/js";
import SvgIcon from "@jamescoyle/vue-icon";
import DedicationCard from "@/components/Students/DedicationCard";
export default {
name: "StudentDedication",
components: {
DedicationCard,
SvgIcon
},
computed: {
students_dedication: function () {
return this.$store.state.students;
}
},
data() {
return {
info_icon: mdiHelpCircleOutline,
close_icon: mdiClose,
sd_info: false
}
}
}
</script>

<style scoped>
</style>
Loading

0 comments on commit 36f4c11

Please sign in to comment.