Skip to content
Snippets Groups Projects
Commit 4d8fae51 authored by jackie / Andrea Ida Malkah Klaura's avatar jackie / Andrea Ida Malkah Klaura
Browse files

Merge branch 'develop'

parents 63d48323 531b6ccb
No related branches found
No related tags found
No related merge requests found
Showing
with 4527 additions and 1519 deletions
......@@ -2,9 +2,8 @@
node_modules
/dist
# local env files
.env.local
.env.*.local
# all dev/prod specific env files; we have sample.env.* as templates
.env.*
# Log files
npm-debug.log*
......
......@@ -2,13 +2,15 @@
> The Web-UI component of the AUTOradio framework
# Setup
## Prerequisites
This version is an early development prototype, only the interface to the [steering/pv module](https://gitlab.servus.at/autoradio/pv) is implemented partly yet.
This version is an early development prototype.
## Build Setup
Detailed setup infos will follow, as soon as we reach something between alpha and beta stage.
For the current early dev prototype you only need the first two steps here:
## Running it locally (dev environment)
``` bash
## Project setup
......@@ -16,18 +18,19 @@ npm install
### Compiles and hot-reloads for development
npm run serve
```
### Compiles and minifies for production
npm run build
Before you can actually run it, you have to copy the `sample.env.development` file to `.env.development` and change the values to reflect your local setup.
### Run your tests
npm run test
For customizing the whole vue cli development environment, see [Configuration Reference](https://cli.vuejs.org/config/).
### Lints and fixes files
npm run lint
```
## Setting it up on a server (production environment)
For customizing the whole vue cli development environment, see [Configuration Reference](https://cli.vuejs.org/config/).
To build the production code, use `npm run build`. This compiles and minifies the code for production. Then you just have to put it on some static website.
Before building you have to copy the `sample.env.production` file to `.env.production` and change the values to your final setup.
> TODO: provide an example setup
## Configuration
......@@ -52,7 +55,7 @@ CORS_ORIGIN_WHITELIST = (
This assumes of course that you have the dashboard running on its standard localhost port 8080. If you want to change this to e.g. port `9090`, add a line `PORT: 9090,` to the `.env.development` file of the dashboard package.
## Detailed infos on build environment
# Infos on build environment
This project is built with [Vue.js 2](https://vuejs.org). Take a look at their [Guide](https://vuejs.org/v2/guide/) or the [API docs](https://vuejs.org/v2/api/) to find out more about the core framework. As template we are using the _webpack template_. For a detailed explanation on how things work with this, check out the [webpack guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). For the whole einvornment setup we started out with Vue CLI 2 but now work with [Vue CLI 3](https://cli.vuejs.org).
......
This diff is collapsed.
......@@ -9,20 +9,22 @@
},
"dependencies": {
"axios": "^0.18.0",
"bootstrap-vue": "^2.0.0-rc.11",
"oidc-client": "^1.6.1",
"vue": "^2.5.22",
"vue-router": "^3.0.1"
"bootstrap-vue": "^2.0.0-rc.19",
"dompurify": "^1.0.10",
"filesize": "^4.1.2",
"oidc-client": "^1.7.1",
"vue": "^2.6.10",
"vue-router": "^3.0.6"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0",
"@vue/cli-plugin-eslint": "^3.4.0",
"@vue/cli-service": "^3.4.0",
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.7.0",
"@vue/cli-service": "^3.7.0",
"babel-eslint": "^10.0.1",
"copy-webpack-plugin": "^4.6.0",
"eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.5.21"
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.2.2",
"vue-template-compiler": "^2.6.10"
},
"eslintConfig": {
"root": true,
......@@ -30,10 +32,15 @@
"node": true
},
"extends": [
"plugin:vue/essential",
"plugin:vue/recommended",
"eslint:recommended"
],
"rules": {},
"rules": {
"no-console": "off",
"curly": "error",
"block-spacing": "error",
"keyword-spacing": "error"
},
"parserOptions": {
"parser": "babel-eslint"
}
......
# For detailed comments take a look at the sample.env.production
# Here we filled in some common defaults for local development
# API URLs for the other AuRa modules
# ===================================
VUE_APP_API_STEERING = http://127.0.0.1:8000/api/v1/
VUE_APP_API_STEERING_SHOWS = http://127.0.0.1:8000/api/v1/shows/
VUE_APP_OIDC_CLIENT_ID = 078036
VUE_APP_API_TANK = http://127.0.0.1:8040/api/v1/
# OIDC settings
# =============
# The client ID will most certainly differ for every local dev environment:
VUE_APP_OIDC_CLIENT_ID = 575513
VUE_APP_API_STEERING_OIDC_URI = http://localhost:8000/openid
VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION = 120
VUE_APP_API_STEERING_OIDC_REDIRECT_URI = http://localhost:8080/oidc_callback.html
VUE_APP_API_STEERING_OIDC_REDIRECT_URI_SILENT = http://localhost:8080/oidc_callback_silentRenew.html
VUE_APP_API_STEERING_OIDC_REDIRECT_URI_POSTLOGOUT = http://localhost:8080
# Dashboard UI defaults
# =====================
# How many timeslots should be shown by default? (has to be a string)
VUE_APP_TIMESLOT_FILTER_DEFAULT_NUMSLOTS = 10
# For how many days from now should timeslots be fetched by default? (has to be an int)
VUE_APP_TIMESLOT_FILTER_DEFAULT_DAYS = 60
......@@ -5,6 +5,10 @@
VUE_APP_API_STEERING = http://YOUR.STEERING.DOMAIN/api/v1/
VUE_APP_API_STEERING_SHOWS = http://YOUR.STEERING.DOMAIN/api/v1/shows/
# aura/tank REST API settings
# ===========================
VUE_APP_API_TANK = http://YOUR.TANK.DOMAIN/api/v1/
# Open ID Connect settings
# ========================
......
<template>
<div id="app">
<app-header v-bind:modules="modules" v-bind:user="user"></app-header>
<router-view/>
<app-footer></app-footer>
<app-header
:modules="modules"
:user="user"
/>
<router-view />
<app-footer />
</div>
</template>
......@@ -15,7 +18,7 @@ import footer from './components/Footer.vue'
import axios from 'axios'
export default {
name: 'app',
name: 'App',
components: {
'app-header': header,
'app-footer': footer
......@@ -62,10 +65,31 @@ export default {
},
computed: {
modules: function () {
if (this.user.logged_in === true) return this.modules_logged_in
else return this.modules_logged_out
if (this.user.logged_in === true) { return this.modules_logged_in }
else { return this.modules_logged_out }
}
},
mounted () {
// TODO: remove oidc logging after thorough testing
oidc.Log.logger = console
let self = this
this.oidcmgr.events.addAccessTokenExpiring(function () {
console.log('starting silent access_token renewal')
self.oidcmgr.signinSilent().then(function (user) {
self.user.access_token = user.access_token
console.log(self.user.access_token)
}).catch(function (err) {
console.log(err)
alert('Your OpenID access token could not be renewed automatically.\n' +
'You will be logged out in ' + process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION + ' seconds.')
})
})
this.oidcmgr.events.addAccessTokenExpired(function () {
console.log('expired!')
self.signOut()
})
this.getOIDCUser()
},
methods: {
signIn () {
this.oidcmgr.signinRedirect().catch(function (err) {
......@@ -133,27 +157,6 @@ export default {
console.log(new Date(user.expires_at * 1000).toUTCString())
console.log(user.access_token)
}
},
mounted () {
// TODO: remove oidc logging after thorough testing
oidc.Log.logger = console
let self = this
this.oidcmgr.events.addAccessTokenExpiring(function () {
console.log('starting silent access_token renewal')
self.oidcmgr.signinSilent().then(function (user) {
self.user.access_token = user.access_token
console.log(self.user.access_token)
}).catch(function (err) {
console.log(err)
alert('Your OpenID access token could not be renewed automatically.\n' +
'You will be logged out in ' + process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION + ' seconds.')
})
})
this.oidcmgr.events.addAccessTokenExpired(function () {
console.log('expired!')
self.signOut()
})
this.getOIDCUser()
}
}
</script>
......
......@@ -2,15 +2,15 @@
<b-container>
<h1>Credits</h1>
<p>
autoradio/<b>dashboard</b><br />
... developed under the GNU General Public License, by<br />
autoradio/<b>dashboard</b><br>
... developed under the GNU General Public License, by<br>
<ul>
<li>Andrea Ida Malkah Klaura <a href="mailto:jackie@o94.at">jackie@o94.at</a></li>
<li>...</li>
</ul>
</p>
<p>
<b>Graphics &amp; Icons</b><br />
<b>Graphics &amp; Icons</b><br>
<ul>
<li>animated loading icon: <a href="https://loading.io/spinner">spinner by loading.io</a>, CC-BY License</li>
<li>all other Icons: <a href="http://tango.freedesktop.org/">Tango Project</a>, Public Domain</li>
......
......@@ -6,13 +6,19 @@
a productive version.
</p>
<p>
Here we go: <b-button size="lg" variant="warning" @click="debug()">Debug now!</b-button>
Here we go: <b-button
size="lg"
variant="warning"
@click="debug()"
>
Debug now!
</b-button>
</p>
Response headers: <br />
Response headers: <br>
<div style="border: 1px dotted #aaa">
{{ response.headers }}
</div>
Response data: <br />
Response data: <br>
<div style="border: 1px dotted #aaa">
{{ response.data }}
</div>
......
This diff is collapsed.
......@@ -5,7 +5,10 @@
<b-col sm="8">
autoradio/<b>dashboard v0.0.23</b>
</b-col>
<b-col sm="4" align="right">
<b-col
sm="4"
align="right"
>
... bla ... bla ... hear the music?
</b-col>
</b-row>
......
......@@ -6,40 +6,95 @@
<b-col md="10">
<span class="header-title"><router-link to="home"><span class="d-none d-sm-inline">autoradio/</span><b>dashboard</b></router-link></span>
</b-col>
<b-col md="2" class="d-none d-sm-none d-md-block" align="right">
<a href="http://o94.at" target="new"><img class="header-logo" src="../assets/logo.jpg" /></a>
<b-col
md="2"
class="d-none d-sm-none d-md-block"
align="right"
>
<a
href="http://o94.at"
target="new"
><img
class="header-logo"
src="../assets/logo.jpg"
></a>
</b-col>
</b-row>
</b-container>
</div>
<div>
<b-container>
<b-navbar toggleable="lg" type="dark" variant="dark">
<b-navbar
toggleable="lg"
type="dark"
variant="dark"
>
<span class="d-none d-sm-inline d-lg-none menu-context-info">For more options tap the menu button on the right:</span>
<span class="d-sm-none menu-context-info">Hit menu button for more:</span>
<b-navbar-toggle target="nav_collapse"></b-navbar-toggle>
<b-collapse is-nav id="nav_collapse">
<b-navbar-toggle target="nav_collapse" />
<b-collapse
id="nav_collapse"
is-nav
>
<b-navbar-nav>
<b-nav-item v-for="mod in modules" :key="mod.slug" :to="mod.slug">{{ mod.title }}</b-nav-item>
<b-nav-item
v-for="mod in modules"
:key="mod.slug"
:to="mod.slug"
>
{{ mod.title }}
</b-nav-item>
</b-navbar-nav>
<b-navbar-nav class="ml-auto">
<b-nav-item-dropdown text="EN" right>
<b-dropdown-item href="#">EN</b-dropdown-item>
<b-dropdown-item href="#">DE</b-dropdown-item>
<b-nav-item-dropdown
text="EN"
right
>
<b-dropdown-item href="#">
EN
</b-dropdown-item>
<b-dropdown-item href="#">
DE
</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item-dropdown v-if="user.logged_in" right>
<b-nav-item-dropdown
v-if="user.logged_in"
right
>
<!-- Using button-content slot -->
<template slot="button-content">
<em>{{ user.name }}</em>
</template>
<b-dropdown-item href="#">Settings</b-dropdown-item>
<b-dropdown-item href="#">Profile</b-dropdown-item>
<b-dropdown-item @click='$parent.signOut'>Signout</b-dropdown-item>
<b-dropdown-item href="#">
Settings
</b-dropdown-item>
<b-dropdown-item href="#">
Profile
</b-dropdown-item>
<b-dropdown-item @click="$parent.signOut">
Signout
</b-dropdown-item>
</b-nav-item-dropdown>
<b-nav-item v-if="! user.logged_in" to="home"><img src="../assets/16x16/system-users.png" alt="log-in symbol" title="Log in"></b-nav-item>
<b-nav-item
v-if="! user.logged_in"
to="home"
>
<img
src="../assets/16x16/system-users.png"
alt="log-in symbol"
title="Log in"
>
</b-nav-item>
<div class="help-image-container">
<b-nav-item>
<router-link to="help"><img class="help-image" src="../assets/help-browser-32x32.png" alt="Help symbol" title="Go to help pages"></router-link>
<router-link to="help">
<img
class="help-image"
src="../assets/help-browser-32x32.png"
alt="Help symbol"
title="Go to help pages"
>
</router-link>
</b-nav-item>
</div>
</b-navbar-nav>
......
<template>
<b-container>
<h1>Help pages</h1>
<br /><br />
<br><br>
<div style="border: 5px dotted #5c3566;">
<br /><br />
<br><br>
<p><b>By the mighty witchcraftry of the mother of time!</b></p>
<p>This feature is not implemented yet.</p>
<br /><br />
<br><br>
</div>
</b-container>
</template>
......
......@@ -4,7 +4,7 @@
<div align="center">
<h1>Welcome to the Dashboard!</h1>
<p>Here are some infos for you on how to use this interface...</p>
<br />
<br>
</div>
<b-row align="center">
<b-col sm="3">
......@@ -33,9 +33,18 @@
</b-col>
</b-row>
</div>
<div v-else align="center">
<div
v-else
align="center"
>
<p>You are not logged in yet.</p>
<b-button size="lg" variant="outline-secondary" @click="$parent.signIn">Log in</b-button>
<b-button
size="lg"
variant="outline-secondary"
@click="$parent.signIn"
>
Log in
</b-button>
</div>
</b-container>
<!--
......
<template>
<b-container align="center">
<h1>Dashboard Settings</h1>
<br /><br />
<br><br>
<div style="border: 5px dotted #5c3566;">
<br /><br />
<br><br>
<p><b>By the mighty witchcraftry of the mother of time!</b></p>
<p>This feature is not implemented yet.</p>
<br /><br />
<br><br>
</div>
</b-container>
</template>
......
This diff is collapsed.
<template>
<div>
<b-modal ref="modalNote" title="Editing a note" size="lg" @ok="saveNote">
<b-modal
ref="modalNote"
title="Editing a note"
size="lg"
@ok="saveNote"
>
<b-container fluid>
<p v-if="typeof note.start !== 'undefined'">This is the note for the timeslot on {{prettyDateTime(note.start) }}.</p>
<p v-else>You are creating a new note.</p>
<p v-if="typeof note.start !== 'undefined'">
This is the note for the timeslot on {{ prettyDateTime(note.start) }}.
</p>
<p v-else>
You are creating a new note.
</p>
<b-row>
<b-col cols="2">Title:</b-col>
<b-col cols="10"><b-form-input v-model="title" type="text" placeholder="Enter a title"></b-form-input></b-col>
<b-col cols="2"></b-col>
<b-col cols="10"><small class="slug">Slug: {{ slug }}</small></b-col>
<b-col cols="2">
Title:
</b-col>
<b-col cols="10">
<b-form-input
v-model="title"
type="text"
placeholder="Enter a title"
/>
</b-col>
<b-col cols="2" />
<b-col cols="10">
<small class="slug">Slug: {{ slug }}</small>
</b-col>
</b-row>
<br />
<br>
<b-row>
<b-col cols="2">Summary:</b-col>
<b-col cols="10"><b-form-textarea v-model="summary" :rows="4" placeholder="Enter a summary"></b-form-textarea></b-col>
<b-col cols="2">
Summary:
</b-col>
<b-col cols="10">
<b-form-textarea
v-model="summary"
:rows="4"
placeholder="Enter a summary"
/>
</b-col>
</b-row>
<br />
<br>
<b-row>
<b-col cols="2">Content:</b-col>
<b-col cols="10"><b-form-textarea v-model="content" :rows="8" placeholder="Enter a text describing this timeslot"></b-form-textarea></b-col>
<b-col cols="2">
Content:
</b-col>
<b-col cols="10">
<b-form-textarea
v-model="content"
:rows="8"
placeholder="Enter a text describing this timeslot"
/>
</b-col>
</b-row>
<br />
<br>
<b-row>
<b-col cols="2">Host:</b-col>
<b-col cols="10"><b-form-select v-model="host_selected" :options="hosts" class="mb-3" /></b-col>
<b-col cols="2">
Host:
</b-col>
<b-col cols="10">
<b-form-select
v-model="host_selected"
:options="hosts"
class="mb-3"
/>
</b-col>
</b-row>
</b-container>
</b-modal>
......@@ -44,6 +87,7 @@ function debugErrorResponse (data) {
*/
export default {
mixins: [ prettyDate ],
props: {
show: { type: Object, required: true },
showAggregate: { type: Object, required: true }
......@@ -86,7 +130,6 @@ export default {
return hosts
}
},
mixins: [ prettyDate ],
methods: {
update (event) {
// only try to save if anything has changed
......@@ -113,7 +156,7 @@ export default {
axios.put(uri, this.note, {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
}).then(response => {
}).then(() => {
// everything was fine, we can close the modal now
this.$refs.modalNote.hide()
}).catch(error => {
......
This diff is collapsed.
function leadingZero (num) {
if (num < 10) return '0' + num
else return num.toString()
if (num < 10) { return '0' + num }
else { return num.toString() }
}
var day = [
......@@ -68,6 +68,13 @@ export default {
duration += 'sec'
}
return duration
},
prettyNanoseconds: function(ns) {
var sec_total = ns / 1000 / 1000 / 1000
var hours = Math.floor(sec_total / 3600)
var minutes = Math.floor((sec_total - (hours * 3600)) / 60)
var seconds = Math.floor((sec_total - (hours * 3600) - (minutes * 60)) * 10) / 10
return hours + ':' + leadingZero(minutes) + ':' + leadingZero(seconds)
}
}
}
function compareEpisodesByDate (a, b) {
var dateA = new Date(a.start)
var dateB = new Date(b.start)
if (dateA < dateB) return -1
else if (dateA > dateB) return 1
else return 0
if (dateA < dateB) { return -1 }
else if (dateA > dateB) { return 1 }
else { return 0 }
}
export default {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment