Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • 987FCF504483CBC8/toolkit
1 result
Select Git revision
Show changes
Commits on Source (139)
Showing
with 779 additions and 370 deletions
image: registry.gitlab.tugraz.at/dbp/web-components/toolkit/main:v1
image: registry.gitlab.tugraz.at/dbp/web-components/toolkit/main:v2
cache:
key: ${CI_PROJECT_PATH}
......@@ -51,8 +51,10 @@ publish:
- chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -t rsa "${DEPLOY_HOST}" >> ~/.ssh/known_hosts
# Deploy
- cd toolkit-showcase
- dep deploy --file ./../.gitlab-ci/deploy.php "${CI_ENVIRONMENT_NAME}"
- cd .gitlab-ci
- export DO_NOT_TRACK=1
- composer install
- composer exec -- deployer.phar deploy "stage=${CI_ENVIRONMENT_NAME}"
- echo "Deployed to ${CI_ENVIRONMENT_URL}"
# Simple health check
- curl --max-time 10 --retry 3 --output /dev/null --silent --show-error --fail --location "${CI_ENVIRONMENT_URL}"
......
vendor/
\ No newline at end of file
FROM debian:buster
FROM debian:bullseye
ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND noninteractive
......@@ -26,6 +26,7 @@ RUN apt-get update && apt-get install -y \
firefox-esr \
composer \
php-zip \
php-curl \
rsync \
sudo \
&& rm -rf /var/lib/apt/lists/*
......@@ -34,11 +35,3 @@ RUN useradd -u 1000 -ms /bin/bash user
RUN echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER user
WORKDIR /home/user
# Install deployer globally and add it to PATH
ENV COMPOSER_HOME="/home/user/.composer"
RUN mkdir -p "${COMPOSER_HOME}"
ADD composer.lock "${COMPOSER_HOME}"
ADD composer.json "${COMPOSER_HOME}"
RUN composer global install
ENV PATH "${COMPOSER_HOME}/vendor/bin:${PATH}"
\ No newline at end of file
#!/bin/bash
set -e
TAG="registry.gitlab.tugraz.at/dbp/web-components/toolkit/main:v1"
TAG="registry.gitlab.tugraz.at/dbp/web-components/toolkit/main:v2"
sudo docker build --tag "${TAG}" --file "Dockerfile" .
echo "Now run: sudo docker push '$TAG'"
{
"require": {
"symfony/process": " ^4.4",
"symfony/console": " ^4.4",
"symfony/yaml": " ^4.4",
"deployer/deployer": " ^6.4",
"deployer/recipes": " ^6.2"
"symfony/process": " ^5.0",
"symfony/console": " ^5.0",
"symfony/yaml": " ^5.0",
"deployer/deployer": "^7.0.0-rc.3"
},
"config": {
"platform": {
"php": "7.3"
}
}
}
This diff is collapsed.
<?php
declare(strict_types=1);
namespace Deployer;
require 'recipe/common.php';
require 'recipe/rsync.php';
import('recipe/common.php');
import('contrib/rsync.php');
// Global config
set('allow_anonymous_stats', false);
$PROJECT_ROOT = dirname(__DIR__).'/toolkit-showcase';
set('rsync',[
'exclude' => [
'.git',
'deploy.php',
],
$RSYNC_CONFIG = [
'exclude' => [],
'exclude-file' => false,
'include' => [],
'include' => [],
'include-file' => false,
'filter' => [],
'filter-file' => false,
'filter-perdir'=> false,
'flags' => 'rz',
'options' => ['delete'],
'timeout' => 60,
]);
set('rsync_src', __DIR__ . '/../toolkit-showcase/dist');
set('rsync_dest','{{release_path}}');
'filter' => [],
'filter-file' => false,
'filter-perdir' => false,
'flags' => 'rz',
'options' => ['delete', 'links'],
'timeout' => 60,
];
// Hosts
host('demo')
->stage('demo')
->hostname('mw@vpu01-demo.tugraz.at')
->set('labels', ['stage' => 'demo'])
->setHostname('mw@vpu01-demo.tugraz.at')
->set('rsync', $RSYNC_CONFIG)
->set('rsync_src', $PROJECT_ROOT.'/dist')
->set('deploy_path', '/home/mw/demo/deploy/apps/demo');
host('development')
->stage('development')
->hostname('mw@mw01-dev.tugraz.at')
->set('labels', ['stage' => 'development'])
->setHostname('mw@mw01-dev.tugraz.at')
->set('rsync', $RSYNC_CONFIG)
->set('rsync_src', $PROJECT_ROOT.'/dist')
->set('deploy_path', '/home/mw/dev/deploy/apps/demo');
task('build', function () {
$stage = get('stage');
runLocally("yarn install --frozen-lockfile");
runLocally("APP_ENV=$stage yarn run build");
task('build', function () use ($PROJECT_ROOT) {
$options = ['cwd' => $PROJECT_ROOT];
$stage = get('labels')['stage'];
runLocally("yarn install --frozen-lockfile", $options);
runLocally("APP_ENV=$stage yarn run build", $options);
});
// Deploy task
task('deploy', [
'deploy:info',
'build',
'deploy:prepare',
'deploy:setup',
'deploy:lock',
'deploy:release',
'rsync',
'deploy:shared',
'deploy:symlink',
'deploy:unlock',
'cleanup',
'success',
'deploy:cleanup',
'deploy:success',
]);
after('deploy:failed', 'deploy:unlock');
......@@ -35,6 +35,7 @@ the version number in its `package.json` is higher than the version number on np
| `unsubscribe` | Reserved for future use |
| `auth` | Authentication information, set by the authentication component |
| `lang` | Currently selected language, set by the language selector |
| `lang-dir` | Location of the i18n language file where all required i18n translations are |
| `entry-point-url` | Entry point url for all api requests |
| `requested-login-status` | Used by the login buttons to trigger a login in auth components |
| `initial-file-handling-state` | Used by the file-handling component to sync file source/sink at first time open |
......
{
"name": "dbp-toolkit",
"version": "0.1.1",
"version": "0.1.2",
"description": "",
"main": "index.js",
"private": true,
......@@ -24,7 +24,7 @@
"author": "",
"license": "LGPL-2.1-or-later",
"devDependencies": {
"lerna": "^4.0.0"
"lerna": "^5.0.0"
},
"dependencies": {}
}
{
"name": "@dbp-toolkit/app-shell",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/app-shell",
"version": "0.3.1",
"version": "0.3.3",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......@@ -15,18 +15,18 @@
},
"devDependencies": {
"@esm-bundle/chai": "^4.2.0",
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"eslint": "^8.0.0",
"eslint-plugin-jsdoc": "^39.0.0",
"glob": "^7.1.6",
"glob": "^8.0.0",
"i18next-parser": "^6.3.0",
"karma": "^6.0.0",
"karma-chrome-launcher": "^3.0.0",
"karma-firefox-launcher": "^2.1.0",
"karma-mocha": "^2.0.1",
"mocha": "^9.0.0",
"mocha": "^10.0.0",
"playwright-core": "^1.20.2",
"prettier": "^2.5.1",
"rollup": "^2.33.3",
......@@ -36,12 +36,13 @@
"rollup-plugin-serve": "^1.0.1"
},
"dependencies": {
"@dbp-toolkit/auth": "^0.3.0",
"@dbp-toolkit/common": "^0.3.0",
"@dbp-toolkit/language-select": "^0.3.0",
"@dbp-toolkit/matomo": "^0.2.2",
"@dbp-toolkit/notification": "^0.3.0",
"@dbp-toolkit/person-profile": "^0.2.2",
"@dbp-toolkit/auth": "^0.3.1",
"@dbp-toolkit/common": "^0.3.3",
"@dbp-toolkit/language-select": "^0.3.1",
"@dbp-toolkit/matomo": "^0.2.6",
"@dbp-toolkit/notification": "^0.3.1",
"@dbp-toolkit/person-profile": "^0.2.5",
"@dbp-toolkit/theme-switcher": "^0.0.4",
"@open-wc/scoped-elements": "^2.1.0",
"i18next": "^21.4.2",
"lit": "^2.0.0",
......
......@@ -62,6 +62,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
this._roles = [];
this._i18n = createInstance();
this.lang = this._i18n.language;
this._extra = [];
this.matomoUrl = '';
this.matomoSiteId = -1;
......@@ -73,6 +74,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
this.initateOpenMenu = false;
this.auth = {};
this.langDir = '';
}
static get scopedElements() {
......@@ -179,6 +181,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
return {
lang: this.lang,
component: '',
extra: [],
};
},
},
......@@ -191,18 +194,20 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
return {
lang: params.lang,
component: '',
extra: [],
};
},
},
{
name: 'mainRoute',
path: '/:component',
path: ['/:component', '/:component/(.*)'],
action: (context, params) => {
// remove the additional parameters added by Keycloak
let componentTag = params.component.toLowerCase().replace(/&.+/, '');
let componentTag = params.component.toLowerCase();
let extra = params[0] ? params[0].split('/') : [];
return {
lang: params.lang,
component: componentTag,
extra: extra,
};
},
},
......@@ -218,17 +223,20 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
let state = {
component: this.activeView,
lang: this.lang,
extra: this._extra,
};
return state;
},
setState: (state) => {
this.updateLangIfChanged(state.lang);
this.switchComponent(state.component);
this._extra = state.extra;
},
getDefaultState: () => {
return {
lang: 'de',
component: this.routes[0],
extra: [],
};
},
},
......@@ -264,14 +272,17 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
buildTime: {type: String, attribute: 'build-time'},
env: {type: String},
auth: {type: Object},
langDir: {type: String, attribute: 'lang-dir'},
};
}
connectedCallback() {
super.connectedCallback();
if (this.src) this.fetchMetadata(this.src);
this.initRouter();
if (this.src) {
this.fetchMetadata(this.src);
}
}
/**
......@@ -692,7 +703,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
background-position:center center;
margin: 0 0.5% 0 1.5%;
font-size:94%;
}
}
*/
.menu a {
......
......@@ -4,7 +4,7 @@ import {unsafeHTML} from 'lit/directives/unsafe-html.js';
import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {Icon} from '@dbp-toolkit/common';
import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element';
import {AdapterLitElement} from '@dbp-toolkit/common';
import {LoginStatus} from '@dbp-toolkit/auth/src/util';
export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) {
......
import {html, css} from 'lit';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element';
import {AdapterLitElement} from '@dbp-toolkit/common';
export class BuildInfo extends AdapterLitElement {
constructor() {
......
......@@ -61,7 +61,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) {
cursor: pointer;
text-decoration: none;
}
h2 a {
white-space: nowrap;
}
......@@ -80,7 +80,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) {
-webkit-mask-position: center center;
mask-position: center center;
margin: 0 2px 0 0px;
padding: 0 0 0.25% 0;
padding: 0;
-webkit-mask-size: 100%;
mask-size: 100%;
}
......
import UniversalRouter from 'universal-router';
import generateUrls from 'universal-router/generateUrls';
function stateMatches(a, b) {
return JSON.stringify(a, Object.keys(a).sort()) === JSON.stringify(b, Object.keys(b).sort());
}
/**
* A wrapper around UniversalRouter which adds history integration
*/
......@@ -31,28 +35,24 @@ export class Router {
window.addEventListener('popstate', (event) => {
this.setStateFromCurrentLocation();
this.dispatchLocationChanged();
this._dispatchLocationChanged();
});
}
async _getStateForPath(pathname) {
let isBasePath = pathname.replace(/\/$/, '') === this.router.baseUrl.replace(/\/$/, '');
if (isBasePath) {
return this.getDefaultState();
}
return this.router.resolve({pathname: pathname});
}
/**
* In case something else has changed the location, update the app state accordingly.
*/
setStateFromCurrentLocation() {
const oldPathName = location.pathname;
this.router
.resolve({pathname: oldPathName})
this._getStateForPath(location.pathname)
.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);
} else if (this.isBasePath(oldPathName)) {
page = this.getDefaultState();
}
this.setState(page);
})
.catch((e) => {
......@@ -61,10 +61,6 @@ export class Router {
});
}
isBasePath(pathname) {
return pathname.replace(/\/$/, '') === this.router.baseUrl.replace(/\/$/, '');
}
/**
* Update the router after some internal state change.
*/
......@@ -72,18 +68,21 @@ export class Router {
// 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 defaultPathname = this.getPathname(this.getDefaultState());
if (newPathname === defaultPathname && this.isBasePath(oldPathname)) {
return;
}
const referrerUrl = location.href;
window.history.pushState({}, '', newPathname);
this.dispatchLocationChanged(referrerUrl);
this._getStateForPath(location.pathname)
.then((page) => {
const newState = this.getState();
// if the state has changed we update
if (!stateMatches(newState, page)) {
const newPathname = this.getPathname();
const referrerUrl = location.href;
window.history.pushState({}, '', newPathname);
this._dispatchLocationChanged(referrerUrl);
}
})
.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.
});
});
}
......@@ -93,14 +92,15 @@ export class Router {
* @param {string} pathname
*/
updateFromPathname(pathname) {
this.router
.resolve({pathname: pathname})
this._getStateForPath(pathname)
.then((page) => {
if (location.pathname === pathname) return;
const referrerUrl = location.href;
window.history.pushState({}, '', pathname);
this.setState(page);
this.dispatchLocationChanged(referrerUrl);
const oldState = this.getState();
if (!stateMatches(oldState, page)) {
const referrerUrl = location.href;
window.history.pushState({}, '', pathname);
this.setState(page);
this._dispatchLocationChanged(referrerUrl);
}
})
.catch((err) => {
throw new Error(`Route not found: ${pathname}: ${err}`);
......@@ -117,7 +117,9 @@ export class Router {
*/
getPathname(partialState) {
const currentState = this.getState();
if (partialState === undefined) partialState = {};
if (partialState === undefined) {
partialState = {};
}
let combined = {...currentState, ...partialState};
try {
......@@ -128,7 +130,7 @@ export class Router {
}
}
dispatchLocationChanged(referrerUrl = '') {
_dispatchLocationChanged(referrerUrl = '') {
// fire a locationchanged event
window.dispatchEvent(
new CustomEvent('locationchanged', {
......
import {html, css} from 'lit';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {createInstance} from './i18n.js';
import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element';
import {AdapterLitElement} from '@dbp-toolkit/common';
export class TUGrazLogo extends AdapterLitElement {
constructor() {
......
packages/auth/assets/favicon.ico

2.49 KiB | W: 16px | H: 16px

packages/auth/assets/favicon.ico

1.12 KiB | W: 16px | H: 16px

packages/auth/assets/favicon.ico
packages/auth/assets/favicon.ico
packages/auth/assets/favicon.ico
packages/auth/assets/favicon.ico
  • 2-up
  • Swipe
  • Onion skin
{
"name": "@dbp-toolkit/auth",
"homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/auth",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.js",
"license": "LGPL-2.1-or-later",
"repository": {
......@@ -15,20 +15,20 @@
},
"devDependencies": {
"@esm-bundle/chai": "^4.2.0",
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-url": "^6.0.0",
"@rollup/plugin-url": "^7.0.0",
"eslint": "^8.0.0",
"eslint-plugin-jsdoc": "^39.0.0",
"glob": "^7.1.6",
"glob": "^8.0.0",
"i18next-parser": "^6.3.0",
"karma": "^6.0.0",
"karma-chrome-launcher": "^3.0.0",
"karma-firefox-launcher": "^2.1.0",
"karma-mocha": "^2.0.1",
"mocha": "^9.0.0",
"mocha": "^10.0.0",
"playwright-core": "^1.20.2",
"prettier": "^2.5.1",
"rollup": "^2.33.3",
......@@ -38,7 +38,7 @@
"rollup-plugin-terser": "^7.0.2"
},
"dependencies": {
"@dbp-toolkit/common": "^0.3.0",
"@dbp-toolkit/common": "^0.3.3",
"@open-wc/scoped-elements": "^2.1.0",
"event-target-shim": "^6.0.0",
"lit": "^2.0.0"
......
......@@ -2,7 +2,8 @@ import {createInstance} from './i18n.js';
import JSONLD from '@dbp-toolkit/common/jsonld';
import {KeycloakWrapper} from './keycloak.js';
import {LoginStatus} from './util.js';
import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element';
import {AdapterLitElement} from '@dbp-toolkit/common';
import {send} from '@dbp-toolkit/common/notification';
/**
* Keycloak auth web component
......@@ -219,17 +220,28 @@ export class AuthKeycloak extends AdapterLitElement {
this._kcwrapper.addEventListener('changed', this._onKCChanged);
const handleLogin = async () => {
if (this.forceLogin || this._kcwrapper.isLoggingIn()) {
this._setLoginStatus(LoginStatus.LOGGING_IN);
await this._kcwrapper.login({lang: this.lang, scope: this.scope || ''});
} else if (this.tryLogin) {
this._setLoginStatus(LoginStatus.LOGGING_IN);
await this._kcwrapper.tryLogin();
if (!this._authenticated) {
try {
if (this.forceLogin || this._kcwrapper.isLoggingIn()) {
this._setLoginStatus(LoginStatus.LOGGING_IN);
await this._kcwrapper.login({lang: this.lang, scope: this.scope || ''});
} else if (this.tryLogin) {
this._setLoginStatus(LoginStatus.LOGGING_IN);
await this._kcwrapper.tryLogin();
if (!this._authenticated) {
this._setLoginStatus(LoginStatus.LOGGED_OUT);
}
} else {
this._setLoginStatus(LoginStatus.LOGGED_OUT);
}
} else {
} catch (error) {
// In case the keycloak server is offline for example
this._setLoginStatus(LoginStatus.LOGGED_OUT);
send({
summary: this._i18n.t('login-failed'),
type: 'danger',
timeout: 5,
});
throw error;
}
};
......
{
"login": "Anmelden",
"login-failed": "Kommunikation mit dem Anmeldeserver fehlgeschlagen",
"logout": "Abmelden"
}