Skip to content
Snippets Groups Projects
Commit 583bfd2b authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Port to vpu-app-shell

parent 169ce8ec
No related branches found
No related tags found
No related merge requests found
Pipeline #9917 passed with warnings
......@@ -16,3 +16,6 @@
[submodule "vendor/file-upload"]
path = vendor/file-upload
url = git@gitlab.tugraz.at:VPU/WebComponents/FileUpload.git
[submodule "vendor/app-shell"]
path = vendor/app-shell
url = git@gitlab.tugraz.at:VPU/Apps/AppShell.git
......@@ -5173,6 +5173,15 @@
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
"dev": true
},
"vpu-app-shell": {
"version": "file:vendor/app-shell",
"requires": {
"i18next": "^19.1.0",
"lit-element": "^2.2.1",
"lit-html": "^1.1.2",
"universal-router": "^8.3.0"
}
},
"vpu-auth": {
"version": "file:vendor/auth",
"requires": {
......
import {html, LitElement, css} from 'lit-element';
import * as commonUtils from 'vpu-common/utils';
import * as commonStyles from 'vpu-common/styles';
import buildinfo from 'consts:buildinfo';
class VPUBuildInfo extends LitElement {
constructor() {
super();
}
static get styles() {
return css`
${commonStyles.getThemeCSS()}
${commonStyles.getGeneralCSS()}
${commonStyles.getTagCSS()}
:host {
display: inline-block;
}
`;
}
render() {
const date = new Date(buildinfo.time);
return html`
<a href="${buildinfo.url}" style="float: right">
<div class="tags has-addons" title="Build Time: ${date.toString()}">
<span class="tag is-light">build</span>
<span class="tag is-dark">${buildinfo.info} (${buildinfo.env})</span>
</div>
</a>
`;
}
}
commonUtils.defineCustomElement('vpu-build-info', VPUBuildInfo);
This diff is collapsed.
import UniversalRouter from 'universal-router';
import generateUrls from 'universal-router/generateUrls';
/**
* A wrapper around UniversalRouter which adds history integration
*/
export class Router {
/**
* @param {Array} routes The routes passed to UniversalRouter
* @param {object} options Options
* @param {string} options.routeName The main route name
* @param {Function} options.getState Function which should return the current state
* @param {Function} options.setState Function which gets passed the new state based on the route
* @param {object} unioptions options passed to UniversalRouter
*/
constructor(routes, options, unioptions) {
this.getState = options.getState;
this.setState = options.setState;
// XXX: We only have one route atm
// If we need more we need to pass the route name to each function
this.routeName = options.routeName;
console.assert(this.getState);
console.assert(this.setState);
console.assert(this.routeName);
// https://github.com/kriasoft/universal-router
this.router = new UniversalRouter(routes, unioptions);
window.addEventListener('popstate', (event) => {
this.setStateFromCurrentLocation();
this.dispatchLocationChanged();
});
}
/**
* In case something else has changed the location, update the app state accordingly.
*/
setStateFromCurrentLocation() {
const oldPathName = location.pathname;
this.router.resolve({pathname: oldPathName}).then(page => {
const newPathname = this.getPathname(page);
// In case of a router redirect, set the new location
if (newPathname !== oldPathName) {
const referrerUrl = location.href;
window.history.replaceState({}, '', newPathname);
this.dispatchLocationChanged(referrerUrl);
}
this.setState(page);
}).catch((e) => {
// In case we can't resolve the location, just leave things as is.
// This happens when a user enters a wrong URL or when testing with karma.
});
}
/**
* Update the router after some internal state change.
*/
update() {
// Queue updates so we can call this multiple times when changing state
// without it resulting in multiple location changes
setTimeout(() => {
const newPathname = this.getPathname();
const oldPathname = location.pathname;
if (newPathname === oldPathname)
return;
const referrerUrl = location.href;
window.history.pushState({}, '', newPathname);
this.dispatchLocationChanged(referrerUrl);
});
}
/**
* Given a new routing path set the location and the app state.
*
* @param {string} pathname
*/
updateFromPathname(pathname) {
this.router.resolve({pathname: pathname}).then(page => {
if (location.pathname === pathname)
return;
const referrerUrl = location.href;
window.history.pushState({}, '', pathname);
this.setState(page);
this.dispatchLocationChanged(referrerUrl);
}).catch((err) => {
throw new Error(`Route not found: ${pathname}: ${err}`);
});
}
/**
* Pass some new router state to get a new router path that can
* be passed to updateFromPathname() later on. If nothing is
* passed the current state is used.
*
* @param {object} [partialState] The optional partial new state
* @returns {string} The new path
*/
getPathname(partialState) {
const currentState = this.getState();
if (partialState === undefined)
partialState = {};
let combined = {...currentState, ...partialState};
return generateUrls(this.router)(this.routeName, combined);
}
dispatchLocationChanged(referrerUrl = "") {
// fire a locationchanged event
window.dispatchEvent(new CustomEvent('locationchanged', {
detail: {
referrerUrl: referrerUrl,
},
bubbles: true
}));
}
}
import {html, LitElement, css} from 'lit-element';
import * as commonUtils from 'vpu-common/utils';
import * as commonStyles from 'vpu-common/styles';
import {createI18nInstance} from '../i18n.js';
const i18n = createI18nInstance();
class VPUTUGrazLogo extends LitElement {
constructor() {
super();
this.lang = i18n.language;
}
static get properties() {
return {
lang: { type: String }
};
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
if (propName === "lang") {
i18n.changeLanguage(this.lang);
}
});
super.update(changedProperties);
}
static get styles() {
return css`
${commonStyles.getThemeCSS()}
${commonStyles.getGeneralCSS()}
:host {
display: inline-block;
}
#claim
{
font-size: 12px;
text-align: right;
padding: 0 17px 0 0;
line-height: 17px;
letter-spacing: 2px;
vertical-align: top;
text-transform: uppercase;
display: inline-block;
white-space: nowrap;
}
#img {
overflow: visible;
}
a:hover path, a:focus path {
fill:#000 !important;
transition:none;
}
* {
transition:fill 0.15s, stroke 0.15s;
}
`;
}
render() {
return html`
<a href="https://www.tugraz.at" title="TU Graz Home" target="_blank" rel="noopener">
<div id="claim">
<div class="int-header-logo-claim-single">${i18n.t('logo.word1')}</div>
<div class="int-header-logo-claim-single">${i18n.t('logo.word2')}</div>
<div class="int-header-logo-claim-single">${i18n.t('logo.word3')}</div>
</div>
<svg id="img" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="51.862" width="141.1" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 141.10001 51.862499"><g transform="matrix(1.25 0 0 -1.25 0 51.862)"><g transform="scale(.1)"><path style="fill:#e4154b" d="m0 103.73h207.45v207.46l-207.45 0.01v-207.47z"></path><path style="fill:#e4154b" d="m228.19 103.73h207.46v207.46h-207.46v-207.46z"></path><path style="fill:#e4154b" d="m456.41 103.73h207.44v207.46h-207.44v-207.46z"></path><path style="fill:#e4154b" d="m103.72 0h207.47v207.46h-207.47v-207.46z"></path><path style="fill:#e4154b" d="m352.68 207.46h207.44v207.46h-207.44v-207.46z"></path><path style="fill:#231f20" d="m751.04 277.91h-66.426v33.195h171.19v-33.195h-66.407v-173.73h-38.359v173.73"></path><path style="fill:#231f20" d="m1048.3 180.22c0-12.461-2.25-23.711-6.72-33.75-4.5-10.039-10.61-18.555-18.36-25.567-7.76-7.031-16.9-12.421-27.503-16.21-10.605-3.809-22.109-5.7036-34.551-5.7036-12.422 0-23.945 1.8946-34.551 5.7036-10.605 3.789-19.824 9.179-27.656 16.21-7.851 7.012-13.984 15.528-18.34 25.567-4.394 10.039-6.582 21.289-6.582 33.75v130.89h38.379v-129.59c0-5.039 0.801-10.351 2.442-15.898 1.64-5.547 4.336-10.664 8.125-15.332s8.789-8.516 15.039-11.523c6.211-3.008 13.926-4.512 23.144-4.512 9.199 0 16.914 1.504 23.145 4.512 6.23 3.007 11.25 6.855 15.039 11.523 3.77 4.668 6.48 9.785 8.12 15.332 1.63 5.547 2.45 10.859 2.45 15.898v129.59h38.38v-130.89"></path><path style="fill:#231f20" d="m832.56 75.664c-7.597 3.2812-17.46 4.8632-25.332 4.8632-22.929 0-35.605-14.434-35.605-33.184 0-18.613 12.383-32.637 33.34-32.637 5.351 0 9.59 0.5274 12.969 1.3086v23.867h-20.84v14.414h39.687v-49.297c-10.41-2.6172-21.25-4.707-31.816-4.707-31.797 0-53.906 14.805-53.906 45.742 0 31.348 20.566 48.906 53.906 48.906 11.406 0 20.41-1.4453 28.867-3.8086l-1.27-15.469"></path><path style="fill:#231f20" d="m856.2 69.375h16.758v-15.332h0.293c0.84 6.289 8.574 16.914 19.824 16.914 1.836 0 3.828 0 5.782-0.5273v-17.715c-1.68 0.918-5.059 1.4454-8.457 1.4454-15.333 0-15.333-17.832-15.333-27.52v-24.785h-18.867v67.52"></path><path style="fill:#231f20" d="m913.75 65.84c7.324 3.1446 17.187 5.1172 25.215 5.1172 22.09 0 31.23-8.5351 31.23-28.457v-8.6523c0-6.8165 0.156-11.934 0.293-16.914 0.137-5.1172 0.41-9.8242 0.84-15.078h-16.602c-0.703 3.5352-0.703 8.0078-0.839 10.098h-0.293c-4.36-7.4618-13.81-11.661-22.38-11.661-12.793 0-25.332 7.207-25.332 20.059 0 10.078 5.195 15.976 12.383 19.258 7.187 3.2812 16.464 3.9453 24.355 3.9453h10.41c0 10.879-5.195 14.551-16.328 14.551-8.008 0-16.035-2.8907-22.363-7.3438l-0.586 15.078zm22.11-52.715c5.782 0 10.274 2.3633 13.223 6.0352 3.105 3.8086 3.945 8.6523 3.945 13.906h-8.164c-8.437 0-20.957-1.3086-20.957-11.68 0-5.7617 5.195-8.2617 11.953-8.2617"></path><path style="fill:#231f20" d="m985.69 69.375h57.422v-14.414l-36.04-39.473h37.31v-13.633h-60.235v14.297l36.715 39.59h-35.172v13.633"></path><path style="fill:#e4154b" d="m1059.6 0h69.102v69.121h-69.102v-69.121z"></path></g></g></svg>
</a>
`;
}
}
commonUtils.defineCustomElement('vpu-tugraz-logo', VPUTUGrazLogo);
{
"logo": {
"word1": "Wissen",
"word2": "Technik",
"word3": "Leidenschaft"
},
"pdf-upload": {
"upload-field-label": "PDF Dateien zum Signieren hochladen",
"upload-area-text": "Sie können in diesem Bereich PDF Dateien per Drag & Drop oder per Direktauswahl hochladen",
......@@ -24,7 +19,5 @@
},
"error-summary": "Ein Fehler ist aufgetreten",
"error-permission-message": "Sie müssen das Recht auf Amtssignaturen besitzen um diese Funktion nutzen zu können!",
"error-login-message": "Sie müssen eingeloggt sein um diese Funktion nutzen zu können!",
"privacy-policy": "Datenschutz",
"page-updated-needs-reload": "Die Applikation wurde aktualisiert. Bitte laden Sie die Seite neu."
"error-login-message": "Sie müssen eingeloggt sein um diese Funktion nutzen zu können!"
}
{
"logo": {
"word1": "Science",
"word2": "Passion",
"word3": "Technology"
},
"pdf-upload": {
"upload-field-label": "Upload PDF files to sign",
"upload-area-text": "In this area you can upload PDF files via Drag & Drop or by selecting them directly",
......@@ -24,7 +19,5 @@
},
"error-summary": "An error occurred",
"error-permission-message": "You need have permissions to use the official signature to use this function!",
"error-login-message": "You need to be logged in to use this function!",
"privacy-policy": "Privacy Policy",
"page-updated-needs-reload": "The application has been updated. Please reload the page."
"error-login-message": "You need to be logged in to use this function!"
}
import './app';
import 'vpu-app-shell';
......@@ -2,7 +2,6 @@ import {assert} from 'chai';
import '../src/vpu-signature-pdf-upload';
import '../src/vpu-signature.js';
import {Router} from '../src/app/router.js';
suite('vpu-signature-pdf-upload basics', () => {
let node;
......@@ -40,28 +39,3 @@ suite('vpu-signature-app basics', () => {
});
});
suite('router', () => {
test('basics', () => {
const routes = [
{
name: 'foo',
path: '',
action: (context) => {
return {};
}
},
];
const router = new Router(routes, {
routeName: 'foo',
getState: () => { return {}; },
setState: (state) => { },
});
router.setStateFromCurrentLocation();
router.update();
router.updateFromPathname("/");
assert.equal(router.getPathname(), '/');
});
});
Subproject commit 0fdb2d6ba4f06ae9bc5bd45915698bd608e06fab
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment