Merge branch 'master' into nutzungsbedingungen
This commit is contained in:
commit
36b7106c26
@ -1,4 +0,0 @@
|
||||
((haskell-mode . ((haskell-indent-spaces . 4)
|
||||
(haskell-process-use-ghci . t)))
|
||||
(hamlet-mode . ((hamlet/basic-offset . 4)
|
||||
(haskell-process-use-ghci . t))))
|
||||
@ -33,6 +33,10 @@ npm install:
|
||||
- n stable
|
||||
- npm install -g npm
|
||||
- hash -r
|
||||
- apt-get install openssh-client -y
|
||||
- install -m 0700 -d ~/.ssh
|
||||
- install -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
|
||||
- for keyVar in ${!SSH_PRIVATE_KEY_NPM_*}; do install -T -m 0400 ${!keyVar} ~/.ssh/${keyVar}; echo "IdentityFile ~/.ssh/${keyVar}" >> ~/.ssh/config; done
|
||||
artifacts:
|
||||
paths:
|
||||
- node_modules/
|
||||
@ -78,6 +82,10 @@ yesod:build:dev:
|
||||
- apt-get update -y
|
||||
- apt-get install -y --no-install-recommends locales-all
|
||||
- ln -s $(which g++-7) $(dirname $(which g++-7))/g++
|
||||
- 'which ssh-agent || apt-get install openssh-client -y'
|
||||
- install -m 0700 -d ~/.ssh
|
||||
- install -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
|
||||
- for keyVar in ${!SSH_PRIVATE_KEY_STACK_*}; do install -T -m 0400 ${!keyVar} ~/.ssh/${keyVar}; echo "IdentityFile ~/.ssh/${keyVar}" >> ~/.ssh/config; done
|
||||
artifacts:
|
||||
paths:
|
||||
- bin/
|
||||
@ -101,6 +109,10 @@ yesod:build:
|
||||
- apt-get update -y
|
||||
- apt-get install -y --no-install-recommends locales-all
|
||||
- ln -s $(which g++-7) $(dirname $(which g++-7))/g++
|
||||
- apt-get install -y --no-install-recommends openssh-client
|
||||
- install -m 0700 -d ~/.ssh
|
||||
- install -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
|
||||
- for keyVar in ${!SSH_PRIVATE_KEY_STACK_*}; do install -T -m 0400 ${!keyVar} ~/.ssh/${keyVar}; echo "IdentityFile ~/.ssh/${keyVar}" >> ~/.ssh/config; done
|
||||
artifacts:
|
||||
paths:
|
||||
- bin/
|
||||
@ -226,8 +238,8 @@ deploy:uniworx3:
|
||||
- apt-get update -y
|
||||
- apt-get install -y --no-install-recommends openssh-client
|
||||
- install -m 0700 -d ~/.ssh
|
||||
- install -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
|
||||
- install -m 0400 ${SSH_PRIVATE_KEY_UNIWORX3} ~/.ssh/id
|
||||
- install -T -m 0644 ${SSH_KNOWN_HOSTS} ~/.ssh/known_hosts
|
||||
- install -T -m 0400 ${SSH_PRIVATE_KEY_UNIWORX3} ~/.ssh/SSH_PRIVATE_KEY_UNIWORX3; echo "IdentityFile ~/.ssh/SSH_PRIVATE_KEY_UNIWORX3" >> ~/.ssh/config;
|
||||
dependencies:
|
||||
- yesod:build
|
||||
|
||||
|
||||
9
frontend/src/_common.sass
Normal file
9
frontend/src/_common.sass
Normal file
@ -0,0 +1,9 @@
|
||||
@use "~@fortawesome/fontawesome-pro/scss/fontawesome" with ( $fa-font-path: "~@fortawesome/fontawesome-pro/webfonts" )
|
||||
|
||||
@forward "~@fortawesome/fontawesome-pro/scss/fontawesome"
|
||||
|
||||
@use "~@fortawesome/fontawesome-pro/scss/solid"
|
||||
|
||||
@use "~typeface-roboto" as roboto
|
||||
|
||||
@use "~typeface-source-sans-pro" as source-sans-pro
|
||||
@ -4,13 +4,7 @@ import { I18n } from './services/i18n/i18n';
|
||||
import { UtilRegistry } from './services/util-registry/util-registry';
|
||||
import { isValidUtility } from './core/utility';
|
||||
|
||||
// load window.fetch polyfill
|
||||
import 'whatwg-fetch';
|
||||
|
||||
import '@fortawesome/fontawesome-pro/css/all.css';
|
||||
|
||||
import 'typeface-roboto/index.css';
|
||||
import 'typeface-source-sans-pro/index.css';
|
||||
import './app.sass';
|
||||
|
||||
export class App {
|
||||
httpClient = new HttpClient();
|
||||
|
||||
1191
frontend/src/app.sass
Normal file
1191
frontend/src/app.sass
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
||||
/* eslint-env node */
|
||||
|
||||
import { App } from './app';
|
||||
import { Utility } from './core/utility';
|
||||
|
||||
@ -13,52 +15,50 @@ const TEST_UTILS = [
|
||||
];
|
||||
|
||||
describe('App', () => {
|
||||
let app;
|
||||
|
||||
beforeEach(() => {
|
||||
app = new App();
|
||||
global.App = new App();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(app).toBeTruthy();
|
||||
expect(global.App).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should setup all utlites when page is done loading', () => {
|
||||
spyOn(app.utilRegistry, 'setupAll');
|
||||
spyOn(global.App.utilRegistry, 'setupAll');
|
||||
document.dispatchEvent(new Event('DOMContentLoaded'));
|
||||
expect(app.utilRegistry.setupAll).toHaveBeenCalled();
|
||||
expect(global.App.utilRegistry.setupAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('provides services', () => {
|
||||
it('HttpClient as httpClient', () => {
|
||||
expect(app.httpClient).toBeTruthy();
|
||||
expect(global.App.httpClient).toBeTruthy();
|
||||
});
|
||||
|
||||
it('HtmlHelpers as htmlHelpers', () => {
|
||||
expect(app.htmlHelpers).toBeTruthy();
|
||||
expect(global.App.htmlHelpers).toBeTruthy();
|
||||
});
|
||||
|
||||
it('I18n as i18n', () => {
|
||||
expect(app.i18n).toBeTruthy();
|
||||
expect(global.App.i18n).toBeTruthy();
|
||||
});
|
||||
|
||||
it('UtilRegistry as utilRegistry', () => {
|
||||
expect(app.utilRegistry).toBeTruthy();
|
||||
expect(global.App.utilRegistry).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('registerUtilities()', () => {
|
||||
it('should register the given utilities', () => {
|
||||
spyOn(app.utilRegistry, 'register');
|
||||
app.registerUtilities(TEST_UTILS);
|
||||
expect(app.utilRegistry.register.calls.count()).toBe(TEST_UTILS.length);
|
||||
expect(app.utilRegistry.register.calls.argsFor(0)).toEqual([TEST_UTILS[0]]);
|
||||
expect(app.utilRegistry.register.calls.argsFor(1)).toEqual([TEST_UTILS[1]]);
|
||||
spyOn(global.App.utilRegistry, 'register');
|
||||
global.App.registerUtilities(TEST_UTILS);
|
||||
expect(global.App.utilRegistry.register.calls.count()).toBe(TEST_UTILS.length);
|
||||
expect(global.App.utilRegistry.register.calls.argsFor(0)).toEqual([TEST_UTILS[0]]);
|
||||
expect(global.App.utilRegistry.register.calls.argsFor(1)).toEqual([TEST_UTILS[1]]);
|
||||
});
|
||||
|
||||
it('should throw an error if not passed an array of utilities', () => {
|
||||
expect(() => {
|
||||
app.registerUtilities({});
|
||||
global.App.registerUtilities({});
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
223
frontend/src/lib/storage-manager/storage-manager.js
Normal file
223
frontend/src/lib/storage-manager/storage-manager.js
Normal file
@ -0,0 +1,223 @@
|
||||
/* global global:writable */
|
||||
|
||||
import * as semver from 'semver';
|
||||
|
||||
export const LOCATION = {
|
||||
LOCAL: 'local',
|
||||
WINDOW: 'window',
|
||||
};
|
||||
|
||||
const LOCATION_SHADOWING = [ LOCATION.WINDOW, LOCATION.LOCAL ];
|
||||
|
||||
export class StorageManager {
|
||||
|
||||
namespace;
|
||||
version;
|
||||
_options;
|
||||
_global;
|
||||
|
||||
constructor(namespace, version, options) {
|
||||
this.namespace = namespace;
|
||||
this.version = semver.valid(version);
|
||||
|
||||
if (!namespace) {
|
||||
throw new Error('Cannot setup StorageManager without namespace');
|
||||
}
|
||||
if (!this.version) {
|
||||
throw new Error('Cannot setup StorageManager without valid semver version');
|
||||
}
|
||||
|
||||
if (options !== undefined) {
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
if (global !== undefined)
|
||||
this._global = global;
|
||||
else if (window !== undefined)
|
||||
this._global = window;
|
||||
else
|
||||
throw new Error('Cannot setup StorageManager without window or global');
|
||||
}
|
||||
|
||||
save(key, value, options=this._options) {
|
||||
if (!key) {
|
||||
throw new Error('StorageManager.save called with invalid key');
|
||||
}
|
||||
|
||||
if (options && options.location !== undefined && !Object.values(LOCATION).includes(options.location)) {
|
||||
throw new Error('StorageManager.save called with unsupported location option');
|
||||
}
|
||||
|
||||
const location = options && options.location !== undefined ? options.location : LOCATION_SHADOWING[0];
|
||||
|
||||
switch (location) {
|
||||
case LOCATION.LOCAL: {
|
||||
this._saveToLocalStorage({ ...this._getFromLocalStorage(), [key]: value });
|
||||
break;
|
||||
}
|
||||
case LOCATION.WINDOW: {
|
||||
this._saveToWindow({ ...this._getFromLocalStorage(), [key]: value });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.error('StorageManager.save cannot save item with unsupported location');
|
||||
}
|
||||
}
|
||||
|
||||
load(key, options=this._options) {
|
||||
if (options && options.location !== undefined && !Object.values(LOCATION).includes(options.location)) {
|
||||
throw new Error('StorageManager.load called with unsupported location option');
|
||||
}
|
||||
|
||||
let locations = options && options.location !== undefined ? [options.location] : LOCATION_SHADOWING;
|
||||
|
||||
while (locations.length > 0) {
|
||||
const location = locations.shift();
|
||||
let val;
|
||||
|
||||
switch (location) {
|
||||
case LOCATION.LOCAL: {
|
||||
val = this._getFromLocalStorage()[key];
|
||||
break;
|
||||
}
|
||||
case LOCATION.WINDOW: {
|
||||
val = this._getFromWindow()[key];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.error('StorageManager.load cannot load item with unsupported location');
|
||||
}
|
||||
|
||||
if (val !== undefined || locations.length === 0) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remove(key, options=this._options) {
|
||||
if (options && options.location !== undefined && !Object.values(LOCATION).includes(options.location)) {
|
||||
throw new Error('StorageManager.load called with unsupported location option');
|
||||
}
|
||||
|
||||
const locations = options && options.location !== undefined ? [options.location] : LOCATION_SHADOWING;
|
||||
|
||||
for (const location of locations) {
|
||||
switch (location) {
|
||||
case LOCATION.LOCAL: {
|
||||
let val = this._getFromLocalStorage();
|
||||
|
||||
delete val[key];
|
||||
|
||||
return this._saveToLocalStorage(val);
|
||||
}
|
||||
case LOCATION.WINDOW: {
|
||||
let val = this._getFromWindow();
|
||||
|
||||
delete val[key];
|
||||
|
||||
return this._saveToWindow(val);
|
||||
}
|
||||
default:
|
||||
console.error('StorageManager.load cannot load item with unsupported location');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear(options) {
|
||||
if (options && options.location !== undefined && !Object.values(LOCATION).includes(options.location)) {
|
||||
throw new Error('StorageManager.clear called with unsupported location option');
|
||||
}
|
||||
|
||||
const locations = options && options.location !== undefined ? [options.location] : LOCATION_SHADOWING;
|
||||
|
||||
for (const location of locations) {
|
||||
switch (location) {
|
||||
case LOCATION.LOCAL:
|
||||
return this._clearLocalStorage();
|
||||
case LOCATION.WINDOW:
|
||||
return this._clearWindow();
|
||||
default:
|
||||
console.error('StorageManager.clear cannot clear with unsupported location');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
_getFromLocalStorage() {
|
||||
let state;
|
||||
|
||||
try {
|
||||
state = JSON.parse(window.localStorage.getItem(this.namespace));
|
||||
} catch {
|
||||
state = null;
|
||||
}
|
||||
|
||||
if (state === null || !state.version || !semver.satisfies(this.version, `^${state.version}`)) {
|
||||
// remove item from localStorage if it stores an invalid state
|
||||
this._clearLocalStorage();
|
||||
return {};
|
||||
}
|
||||
|
||||
if ('state' in state)
|
||||
return state.state;
|
||||
else {
|
||||
delete state.version;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
_saveToLocalStorage(state) {
|
||||
if (!state)
|
||||
return this._clearLocalStorage();
|
||||
|
||||
let versionedState;
|
||||
|
||||
if ('version' in state || 'state' in state) {
|
||||
versionedState = { version: this.version, state: state };
|
||||
} else {
|
||||
versionedState = { version: this.version, ...state };
|
||||
}
|
||||
|
||||
window.localStorage.setItem(this.namespace, JSON.stringify(versionedState));
|
||||
}
|
||||
|
||||
_clearLocalStorage() {
|
||||
window.localStorage.removeItem(this.namespace);
|
||||
}
|
||||
|
||||
|
||||
_getFromWindow() {
|
||||
if (!this._global || !this._global.App)
|
||||
return {};
|
||||
|
||||
if (!this._global.App.Storage)
|
||||
this._global.App.Storage = {};
|
||||
|
||||
return this._global.App.Storage[this.namespace] || {};
|
||||
}
|
||||
|
||||
_saveToWindow(value) {
|
||||
if (!this._global || !this._global.App) {
|
||||
throw new Error('StorageManager._saveToWindow called when window.App is not available');
|
||||
}
|
||||
|
||||
if (!value)
|
||||
return this._clearWindow();
|
||||
|
||||
if (!this._global.App.Storage)
|
||||
this._global.App.Storage = {};
|
||||
|
||||
this._global.App.Storage[this.namespace] = value;
|
||||
}
|
||||
|
||||
_clearWindow() {
|
||||
if (!this._global || !this._global.App) {
|
||||
throw new Error('StorageManager._saveToWindow called when window.App is not available');
|
||||
}
|
||||
|
||||
if (this._global.App.Storage) {
|
||||
delete this._global.App.Storage[this.namespace];
|
||||
}
|
||||
}
|
||||
}
|
||||
4
frontend/src/polyfill.js
Normal file
4
frontend/src/polyfill.js
Normal file
@ -0,0 +1,4 @@
|
||||
import 'whatwg-fetch';
|
||||
|
||||
import { ResizeObserver as Polyfill } from '@juggle/resize-observer';
|
||||
window.ResizeObserver = window.ResizeObserver || Polyfill;
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './alerts.scss';
|
||||
import './alerts.sass';
|
||||
|
||||
const ALERTS_INITIALIZED_CLASS = 'alerts--initialized';
|
||||
const ALERTS_ELEVATED_CLASS = 'alerts--elevated';
|
||||
|
||||
186
frontend/src/utils/alerts/alerts.sass
Normal file
186
frontend/src/utils/alerts/alerts.sass
Normal file
@ -0,0 +1,186 @@
|
||||
@use "../../common" as *
|
||||
|
||||
.alerts
|
||||
position: fixed
|
||||
bottom: 0
|
||||
right: 5%
|
||||
z-index: 20
|
||||
text-align: right
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
.alerts__toggler
|
||||
width: 40px
|
||||
height: 40px
|
||||
position: absolute
|
||||
top: 400px
|
||||
left: 50%
|
||||
transform: translateX(-50%)
|
||||
cursor: pointer
|
||||
|
||||
&::before
|
||||
@extend .fas
|
||||
|
||||
content: fa-content($fa-var-chevron-up)
|
||||
position: absolute
|
||||
left: 50%
|
||||
top: 0
|
||||
height: 30px
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 30px
|
||||
color: var(--color-grey)
|
||||
font-size: 30px
|
||||
transform: translateX(-50%)
|
||||
|
||||
&:hover::before
|
||||
color: var(--color-grey-medium)
|
||||
|
||||
.alerts--elevated
|
||||
z-index: 1000
|
||||
|
||||
.alerts__toggler--visible
|
||||
top: -40px
|
||||
opacity: 1
|
||||
transition: top 0.5s cubic-bezier(0.73, 1.25, 0.61, 1), opacity 0.5s cubic-bezier(0.73, 1.25, 0.61, 1)
|
||||
|
||||
@media (max-width: 425px)
|
||||
.alerts
|
||||
left: 5%
|
||||
|
||||
.alert
|
||||
position: relative
|
||||
display: block
|
||||
background-color: var(--color-lightblack)
|
||||
font-size: 1rem
|
||||
color: var(--color-lightwhite)
|
||||
z-index: 0
|
||||
padding: 0 50px
|
||||
padding-right: 60px
|
||||
animation: slide-in-alert .2s ease-out forwards
|
||||
margin-bottom: 10px
|
||||
transition: margin-bottom .2s ease-out
|
||||
|
||||
.alert a
|
||||
color: var(--color-lightwhite)
|
||||
|
||||
&:hover
|
||||
color: var(--color-grey)
|
||||
|
||||
@keyframes slide-in-alert
|
||||
from
|
||||
transform: translateY(120%)
|
||||
|
||||
to
|
||||
transform: translateY(0)
|
||||
|
||||
@keyframes slide-out-alert
|
||||
from
|
||||
transform: translateY(0)
|
||||
max-height: 200px
|
||||
|
||||
to
|
||||
transform: translateY(250%)
|
||||
opacity: 0
|
||||
max-height: 0
|
||||
overflow: hidden
|
||||
|
||||
@media (min-width: 425px)
|
||||
.alert
|
||||
max-width: 400px
|
||||
|
||||
.alert--invisible
|
||||
animation: slide-out-alert .2s ease-out forwards
|
||||
margin-bottom: 0
|
||||
|
||||
.alert__content
|
||||
padding: 8px 0
|
||||
min-height: 40px
|
||||
position: relative
|
||||
display: flex
|
||||
font-weight: 600
|
||||
align-items: center
|
||||
text-align: left
|
||||
|
||||
.alert__icon
|
||||
text-align: right
|
||||
position: absolute
|
||||
left: 0px
|
||||
top: 0
|
||||
width: 50px
|
||||
height: 100%
|
||||
z-index: 40
|
||||
|
||||
&::before
|
||||
position: absolute
|
||||
font-size: 24px
|
||||
top: 50%
|
||||
left: 50%
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
transform: translate(-50%, -50%)
|
||||
border-radius: 50%
|
||||
width: 30px
|
||||
height: 30px
|
||||
|
||||
.alert__closer
|
||||
cursor: pointer
|
||||
text-align: right
|
||||
position: absolute
|
||||
right: 0px
|
||||
top: 0
|
||||
width: 60px
|
||||
height: 100%
|
||||
transition: all .3s ease
|
||||
z-index: 40
|
||||
|
||||
&:hover
|
||||
transform: scale(1.05, 1.05)
|
||||
|
||||
&::before
|
||||
box-shadow: 0 0 4px white
|
||||
background-color: rgba(255, 255, 255, 0.1)
|
||||
color: white
|
||||
|
||||
&::before
|
||||
@extend .fas
|
||||
|
||||
content: fa-content($fa-var-times)
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
transform: translate(-50%, -50%)
|
||||
border-radius: 50%
|
||||
width: 30px
|
||||
height: 30px
|
||||
transition: all .15s ease
|
||||
|
||||
@media (max-width: 768px)
|
||||
.alert__closer
|
||||
width: 40px
|
||||
|
||||
.alert-success
|
||||
background-color: var(--color-success)
|
||||
|
||||
// .alert__icon::before {
|
||||
// --alert-icon-default: '\f058';
|
||||
// }
|
||||
|
||||
.alert-warning
|
||||
background-color: var(--color-warning)
|
||||
|
||||
// .alert__icon::before {
|
||||
// --alert-icon-default: '\f06a';
|
||||
// }
|
||||
|
||||
.alert-error
|
||||
background-color: var(--color-error)
|
||||
|
||||
// .alert__icon::before {
|
||||
// --alert-icon-default: '\f071';
|
||||
// }
|
||||
@ -1,221 +0,0 @@
|
||||
.alerts {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 5%;
|
||||
z-index: 20;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.alerts__toggler {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
top: 400px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
cursor: pointer;
|
||||
|
||||
&::before {
|
||||
content: '\f077';
|
||||
position: absolute;
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
left: 50%;
|
||||
top: 0;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
color: var(--color-grey);
|
||||
font-size: 30px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
color: var(--color-grey-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.alerts--elevated {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.alerts__toggler--visible {
|
||||
top: -40px;
|
||||
opacity: 1;
|
||||
transition: top .5s cubic-bezier(0.73, 1.25, 0.61, 1),
|
||||
opacity .5s cubic-bezier(0.73, 1.25, 0.61, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
|
||||
.alerts {
|
||||
left: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: var(--color-lightblack);
|
||||
font-size: 1rem;
|
||||
color: var(--color-lightwhite);
|
||||
z-index: 0;
|
||||
padding: 0 50px;
|
||||
padding-right: 60px;
|
||||
animation: slide-in-alert .2s ease-out forwards;
|
||||
margin-bottom: 10px;
|
||||
transition: margin-bottom .2s ease-out;
|
||||
}
|
||||
|
||||
.alert a {
|
||||
color: var(--color-lightwhite);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-grey);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-in-alert {
|
||||
from {
|
||||
transform: translateY(120%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-out-alert {
|
||||
from {
|
||||
transform: translateY(0);
|
||||
max-height: 200px;
|
||||
}
|
||||
to {
|
||||
transform: translateY(250%);
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 425px) {
|
||||
|
||||
.alert {
|
||||
max-width: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert--invisible {
|
||||
animation: slide-out-alert .2s ease-out forwards;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.alert__content {
|
||||
padding: 8px 0;
|
||||
min-height: 40px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
font-weight: 600;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.alert__icon {
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0;
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
z-index: 40;
|
||||
|
||||
&::before {
|
||||
/* content: var(--alert-icon, var(--alert-icon-default, '\f05a')); */
|
||||
position: absolute;
|
||||
/* font-family: 'Font Awesome 5 Free'; */
|
||||
font-size: 24px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert__closer {
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0;
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
transition: all .3s ease;
|
||||
z-index: 40;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05, 1.05);
|
||||
|
||||
&::before {
|
||||
box-shadow: 0 0 4px white;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '\f00d';
|
||||
position: absolute;
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
transition: all .15s ease;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.alert__closer {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: var(--color-success);
|
||||
|
||||
/* .alert__icon::before {
|
||||
* --alert-icon-default: '\f058';
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background-color: var(--color-warning);
|
||||
|
||||
/* .alert__icon::before {
|
||||
* --alert-icon-default: '\f06a';
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background-color: var(--color-error);
|
||||
|
||||
/* .alert__icon::before {
|
||||
* --alert-icon-default: '\f071';
|
||||
* }
|
||||
*/
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './asidenav.scss';
|
||||
import './asidenav.sass';
|
||||
|
||||
const FAVORITES_BTN_CLASS = 'navbar__list-item--favorite';
|
||||
const FAVORITES_BTN_ACTIVE_CLASS = 'navbar__list-item--active';
|
||||
|
||||
330
frontend/src/utils/asidenav/asidenav.sass
Normal file
330
frontend/src/utils/asidenav/asidenav.sass
Normal file
@ -0,0 +1,330 @@
|
||||
.main__aside
|
||||
position: fixed
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3)
|
||||
z-index: 1
|
||||
top: 0
|
||||
left: 0
|
||||
width: var(--asidenav-width-lg, 20%)
|
||||
height: 100%
|
||||
flex: 0 0 0
|
||||
flex-basis: var(--asidenav-width-lg, 20%)
|
||||
transition: all .2s ease-out
|
||||
|
||||
&::before
|
||||
position: absolute
|
||||
z-index: -1
|
||||
left: 0
|
||||
top: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: var(--color-dark)
|
||||
opacity: 0.05
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
position: absolute
|
||||
z-index: -2
|
||||
left: 0
|
||||
top: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
@media (max-width: 425px)
|
||||
.main__aside
|
||||
position: fixed
|
||||
top: var(--header-height-collapsed)
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
height: 100% !important
|
||||
width: 100%
|
||||
z-index: 5
|
||||
overflow: hidden
|
||||
transform: translateX(-110%)
|
||||
transition: transform .2s ease-out
|
||||
|
||||
&.main__aside--expanded
|
||||
transform: translateX(0%)
|
||||
|
||||
.asidenav__box-subtitle
|
||||
display: inherit
|
||||
|
||||
.asidenav__box-title
|
||||
font-size: 18px
|
||||
padding-left: 10px
|
||||
|
||||
.asidenav__box-subtitle
|
||||
display: none
|
||||
|
||||
@media (min-width: 1200px)
|
||||
.main__aside
|
||||
width: var(--asidenav-width-xl, 250px)
|
||||
|
||||
.asidenav
|
||||
color: var(--color-font)
|
||||
min-height: calc(100% - var(--header-height))
|
||||
height: 400px
|
||||
overflow-y: auto
|
||||
overflow-x: hidden
|
||||
|
||||
&::-webkit-scrollbar
|
||||
width: 0
|
||||
|
||||
.asidenav__box
|
||||
transition: opacity .2s ease
|
||||
|
||||
+ .asidenav__box
|
||||
margin-top: 10px
|
||||
|
||||
.asidenav__box-title
|
||||
padding: 7px 13px
|
||||
margin-top: 30px
|
||||
background-color: transparent
|
||||
transition: all .2s ease
|
||||
padding: 10px 13px
|
||||
margin: 0
|
||||
border-bottom: 1px solid var(--color-grey)
|
||||
|
||||
.asidenav-term-identifier--long
|
||||
display: inherit
|
||||
|
||||
.asidenav-term-identifier--short
|
||||
display: none
|
||||
|
||||
.asidenav__box-subtitle
|
||||
color: var(--color-fontsec)
|
||||
font-size: 0.9rem
|
||||
font-weight: 600
|
||||
padding: 0 13px
|
||||
margin: 3px 0
|
||||
|
||||
// LOGO
|
||||
|
||||
.asidenav__logo
|
||||
height: var(--header-height)
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
@media (max-width: 768px)
|
||||
.asidenav__logo
|
||||
display: none
|
||||
|
||||
.asidenav__logo-link
|
||||
flex: 1
|
||||
top: 10px
|
||||
left: 20px
|
||||
height: 80px
|
||||
padding: 0 20px
|
||||
display: flex
|
||||
flex-basis: var(--asidenav-width-xl, 250px)
|
||||
font-size: 16px
|
||||
align-items: center
|
||||
color: var(--color-dark)
|
||||
transform-origin: left
|
||||
|
||||
&:hover
|
||||
color: var(--color-primary)
|
||||
|
||||
.asidenav__logo-lmu
|
||||
width: 80px
|
||||
height: 100%
|
||||
|
||||
.asidenav__logo-uni2work
|
||||
display: flex
|
||||
align-items: flex-end
|
||||
min-width: 70px
|
||||
margin-left: 12px
|
||||
text-transform: uppercase
|
||||
width: 100%
|
||||
height: 100%
|
||||
padding: 2px 4px
|
||||
border: 1px solid currentColor
|
||||
letter-spacing: 2px
|
||||
background-color: white
|
||||
transition: background-color .3s ease
|
||||
|
||||
@media (max-width: 1199px)
|
||||
.asidenav__logo-link
|
||||
flex-basis: var(--asidenav-width-lg, 20%)
|
||||
font-size: 16px
|
||||
|
||||
.asidenav__logo-lmu
|
||||
display: none
|
||||
|
||||
.asidenav__logo-uni2work
|
||||
margin-left: 0
|
||||
|
||||
// SEAL
|
||||
|
||||
.asidenav__sigillum
|
||||
position: absolute
|
||||
bottom: -40px
|
||||
right: 25px
|
||||
opacity: 0.1
|
||||
|
||||
> img
|
||||
width: 350px
|
||||
|
||||
@media (max-width: 768px)
|
||||
.asidenav__sigillum
|
||||
right: auto
|
||||
left: 50%
|
||||
transform: translateX(-50%)
|
||||
|
||||
// LIST-ITEM
|
||||
|
||||
.asidenav__list-item
|
||||
color: var(--color-font)
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: flex-start
|
||||
align-items: center
|
||||
|
||||
&:not(.asidenav__list-item--active):hover
|
||||
background-color: var(--color-lightwhite)
|
||||
|
||||
> .asidenav__link-wrapper
|
||||
color: var(--color-font)
|
||||
|
||||
&:hover
|
||||
.asidenav__link-shorthand
|
||||
// transform: scale(1.05, 1.0);
|
||||
// transform-origin: right;
|
||||
text-shadow: none
|
||||
|
||||
.asidenav__nested-list-wrapper
|
||||
display: block
|
||||
|
||||
// small list-item-padding for medium to large screens
|
||||
@media (min-width: 769px)
|
||||
.asidenav__list-item
|
||||
padding-left: 10px
|
||||
|
||||
.asidenav__list-item--active
|
||||
background-color: var(--color-lightwhite)
|
||||
|
||||
.asidenav__link-wrapper
|
||||
color: var(--color-link)
|
||||
|
||||
.asidenav__link-shorthand
|
||||
transform: scale(1.05, 1)
|
||||
transform-origin: right
|
||||
text-shadow: none
|
||||
|
||||
.asidenav__link-wrapper
|
||||
position: relative
|
||||
display: flex
|
||||
flex: 1
|
||||
align-items: center
|
||||
padding: 8px 3px
|
||||
justify-content: flex-start
|
||||
color: var(--color-font)
|
||||
width: 100%
|
||||
z-index: 1
|
||||
|
||||
.asidenav__link-shorthand
|
||||
display: none
|
||||
|
||||
.asidenav__link-label
|
||||
line-height: 1
|
||||
|
||||
// hover sub-menus
|
||||
.asidenav__nested-list-wrapper
|
||||
position: absolute
|
||||
z-index: 10
|
||||
display: none
|
||||
color: var(--color-font)
|
||||
background-color: var(--color-grey-light)
|
||||
box-shadow: 1px 1px 1px 0px var(--color-grey)
|
||||
|
||||
.asidenav__nested-list
|
||||
min-width: 200px
|
||||
|
||||
@media (max-width: 425px)
|
||||
.asidenav__list-item
|
||||
padding-left: 10px
|
||||
|
||||
.asidenav__nested-list
|
||||
display: none
|
||||
|
||||
.asidenav__nested-list-item
|
||||
position: relative
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-lightwhite)
|
||||
|
||||
.asidenav__link-wrapper
|
||||
padding-left: 13px
|
||||
padding-right: 13px
|
||||
transition: all .2s ease
|
||||
color: var(--color-font)
|
||||
|
||||
// TABLET
|
||||
@media (min-width: 426px) and (max-width: 768px)
|
||||
.main__aside
|
||||
width: var(--asidenav-width-md, 50px)
|
||||
flex-basis: var(--asidenav-width-md, 50px)
|
||||
overflow: hidden
|
||||
min-height: calc(100% - var(--header-height-collapsed))
|
||||
top: var(--header-height-collapsed)
|
||||
|
||||
.asidenav__box-title
|
||||
width: var(--asidenav-width-md, 50px)
|
||||
font-size: 18px
|
||||
text-align: center
|
||||
padding: 10px 1px
|
||||
word-break: break-all
|
||||
background-color: var(--color-dark)
|
||||
color: var(--color-lightwhite)
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-darker)
|
||||
|
||||
&::before
|
||||
display: none
|
||||
|
||||
.asidenav-term-identifier--long
|
||||
display: none
|
||||
|
||||
.asidenav-term-identifier--short
|
||||
display: inherit
|
||||
|
||||
.asidenav__box-subtitle
|
||||
padding: 0 3px
|
||||
font-size: 0.85rem
|
||||
|
||||
.asidenav__link-shorthand
|
||||
display: flex
|
||||
position: static
|
||||
height: 50px
|
||||
width: var(--asidenav-width-md, 50px)
|
||||
text-align: center
|
||||
opacity: 1
|
||||
font-size: 15px
|
||||
line-height: 1em
|
||||
margin-right: 13px
|
||||
flex-shrink: 0
|
||||
padding: 1px
|
||||
outline: 1px solid white
|
||||
word-break: break-all
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.asidenav__list-item
|
||||
padding-left: 0
|
||||
|
||||
+ .asidenav__list-item
|
||||
margin: 0
|
||||
|
||||
.asidenav__link-wrapper
|
||||
color: var(--color-font)
|
||||
padding: 0
|
||||
|
||||
.asidenav__nested-list,
|
||||
.asidenav__link-label
|
||||
display: none
|
||||
|
||||
.asidenav__list-item--active
|
||||
.asidenav__link-wrapper
|
||||
background-color: var(--color-lightwhite)
|
||||
@ -1,406 +0,0 @@
|
||||
.main__aside {
|
||||
position: fixed;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: var(--asidenav-width-lg, 20%);
|
||||
height: 100%;
|
||||
flex: 0 0 0;
|
||||
flex-basis: var(--asidenav-width-lg, 20%);
|
||||
transition: all .2s ease-out;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-dark);
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: -2;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-grey-light);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
|
||||
.main__aside {
|
||||
position: fixed;
|
||||
top: var(--header-height-collapsed);
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100% !important;
|
||||
width: 100%;
|
||||
z-index: 5;
|
||||
overflow: hidden;
|
||||
transform: translateX(-110%);
|
||||
transition: transform .2s ease-out;
|
||||
|
||||
&.main__aside--expanded {
|
||||
transform: translateX(0%);
|
||||
|
||||
.asidenav__box-subtitle {
|
||||
display: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__box-title {
|
||||
font-size: 18px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.asidenav__box-subtitle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.main__aside {
|
||||
width: var(--asidenav-width-xl, 250px)
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav {
|
||||
color: var(--color-font);
|
||||
min-height: calc(100% - var(--header-height));
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__box {
|
||||
transition: opacity .2s ease;
|
||||
|
||||
+ .asidenav__box {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__box-title {
|
||||
padding: 7px 13px;
|
||||
margin-top: 30px;
|
||||
background-color: transparent;
|
||||
transition: all .2s ease;
|
||||
padding: 10px 13px;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid var(--color-grey);
|
||||
|
||||
.asidenav-term-identifier--long {
|
||||
display: inherit;
|
||||
}
|
||||
.asidenav-term-identifier--short {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__box-subtitle {
|
||||
color: var(--color-fontsec);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
padding: 0 13px;
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
/* LOGO */
|
||||
|
||||
.asidenav__logo {
|
||||
height: var(--header-height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.asidenav__logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__logo-link {
|
||||
flex: 1;
|
||||
top: 10px;
|
||||
left: 20px;
|
||||
height: 80px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
flex-basis: var(--asidenav-width-xl, 250px);
|
||||
font-size: 16px;
|
||||
align-items: center;
|
||||
color: var(--color-dark);
|
||||
transform-origin: left;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__logo-lmu {
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.asidenav__logo-uni2work {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
min-width: 70px;
|
||||
margin-left: 12px;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 2px 4px;
|
||||
border: 1px solid currentColor;
|
||||
letter-spacing: 2px;
|
||||
background-color: white;
|
||||
transition: background-color .3s ease;
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
|
||||
.asidenav__logo-link {
|
||||
flex-basis: var(--asidenav-width-lg, 20%);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.asidenav__logo-lmu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.asidenav__logo-uni2work {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* SEAL */
|
||||
|
||||
.asidenav__sigillum {
|
||||
position: absolute;
|
||||
bottom: -40px;
|
||||
right: 25px;
|
||||
opacity: 0.1;
|
||||
|
||||
> img {
|
||||
width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.asidenav__sigillum {
|
||||
right: auto;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
/* LIST-ITEM */
|
||||
|
||||
.asidenav__list-item {
|
||||
color: var(--color-font);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
&:not(.asidenav__list-item--active):hover {
|
||||
background-color: var(--color-lightwhite);
|
||||
|
||||
> .asidenav__link-wrapper {
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
.asidenav__link-shorthand {
|
||||
/* transform: scale(1.05, 1.0);
|
||||
* transform-origin: right;
|
||||
*/
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.asidenav__nested-list-wrapper {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* small list-item-padding for medium to large screens */
|
||||
@media (min-width: 769px) {
|
||||
.asidenav__list-item {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__list-item--active {
|
||||
background-color: var(--color-lightwhite);
|
||||
|
||||
.asidenav__link-wrapper {
|
||||
color: var(--color-link);
|
||||
}
|
||||
|
||||
.asidenav__link-shorthand {
|
||||
transform: scale(1.05, 1.0);
|
||||
transform-origin: right;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__link-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
padding: 8px 3px;
|
||||
justify-content: flex-start;
|
||||
color: var(--color-font);
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.asidenav__link-shorthand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.asidenav__link-label {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* hover sub-menus */
|
||||
.asidenav__nested-list-wrapper {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
color: var(--color-font);
|
||||
background-color: var(--color-grey-light);
|
||||
box-shadow: 1px 1px 1px 0px var(--color-grey);
|
||||
}
|
||||
|
||||
.asidenav__nested-list {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
.asidenav__list-item {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.asidenav__nested-list {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__nested-list-item {
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-lightwhite);
|
||||
}
|
||||
|
||||
.asidenav__link-wrapper {
|
||||
padding-left: 13px;
|
||||
padding-right: 13px;
|
||||
transition: all .2s ease;
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
|
||||
/* TABLET */
|
||||
@media (min-width: 426px) and (max-width: 768px) {
|
||||
|
||||
.main__aside {
|
||||
width: var(--asidenav-width-md, 50px);
|
||||
flex-basis: var(--asidenav-width-md, 50px);
|
||||
overflow: hidden;
|
||||
min-height: calc(100% - var(--header-height-collapsed));
|
||||
top: var(--header-height-collapsed);
|
||||
|
||||
.asidenav__box-title {
|
||||
width: var(--asidenav-width-md, 50px);
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
padding: 10px 1px;
|
||||
word-break: break-all;
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-lightwhite);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-darker);
|
||||
}
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.asidenav-term-identifier--long {
|
||||
display: none;
|
||||
}
|
||||
.asidenav-term-identifier--short {
|
||||
display: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__box-subtitle {
|
||||
padding: 0 3px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.asidenav__link-shorthand {
|
||||
display: flex;
|
||||
position: static;
|
||||
height: 50px;
|
||||
width: var(--asidenav-width-md, 50px);
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
font-size: 15px;
|
||||
line-height: 1em;
|
||||
margin-right: 13px;
|
||||
flex-shrink: 0;
|
||||
padding: 1px;
|
||||
outline: 1px solid white;
|
||||
word-break: break-all;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.asidenav__list-item {
|
||||
padding-left: 0;
|
||||
|
||||
+ .asidenav__list-item {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__link-wrapper {
|
||||
color: var(--color-font);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.asidenav__nested-list,
|
||||
.asidenav__link-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.asidenav__list-item--active {
|
||||
|
||||
.asidenav__link-wrapper {
|
||||
background-color: var(--color-lightwhite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import './async-form.scss';
|
||||
import './async-form.sass';
|
||||
|
||||
const ASYNC_FORM_INITIALIZED_CLASS = 'check-all--initialized';
|
||||
const ASYNC_FORM_RESPONSE_CLASS = 'async-form__response';
|
||||
|
||||
71
frontend/src/utils/async-form/async-form.sass
Normal file
71
frontend/src/utils/async-form/async-form.sass
Normal file
@ -0,0 +1,71 @@
|
||||
.async-form__response
|
||||
margin: 20px 0
|
||||
position: relative
|
||||
width: 100%
|
||||
font-size: 18px
|
||||
text-align: center
|
||||
padding-top: 60px
|
||||
|
||||
.async-form__response::before,
|
||||
.async-form__response::after
|
||||
position: absolute
|
||||
top: 0px
|
||||
left: 50%
|
||||
display: block
|
||||
|
||||
.async-form__response--success::before
|
||||
content: ''
|
||||
width: 17px
|
||||
height: 28px
|
||||
border: solid #069e04
|
||||
border-width: 0 5px 5px 0
|
||||
transform: translateX(-50%) rotate(45deg)
|
||||
|
||||
.async-form__response--info::before
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 30px
|
||||
top: 10px
|
||||
background-color: #777
|
||||
transform: translateX(-50%)
|
||||
|
||||
.async-form__response--info::after
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 5px
|
||||
background-color: #777
|
||||
transform: translateX(-50%)
|
||||
|
||||
.async-form__response--warning::before
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 30px
|
||||
background-color: rgb(255, 187, 0)
|
||||
transform: translateX(-50%)
|
||||
|
||||
.async-form__response--warning::after
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 5px
|
||||
top: 35px
|
||||
background-color: rgb(255, 187, 0)
|
||||
transform: translateX(-50%)
|
||||
|
||||
.async-form__response--error::before
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 40px
|
||||
background-color: #940d0d
|
||||
transform: translateX(-50%) rotate(-45deg)
|
||||
|
||||
.async-form__response--error::after
|
||||
content: ''
|
||||
width: 5px
|
||||
height: 40px
|
||||
background-color: #940d0d
|
||||
transform: translateX(-50%) rotate(45deg)
|
||||
|
||||
.async-form--loading
|
||||
opacity: 0.1
|
||||
transition: opacity 800ms ease-out
|
||||
pointer-events: none
|
||||
@ -1,78 +0,0 @@
|
||||
.async-form__response {
|
||||
margin: 20px 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.async-form__response::before,
|
||||
.async-form__response::after {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 50%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.async-form__response--success::before {
|
||||
content: '';
|
||||
width: 17px;
|
||||
height: 28px;
|
||||
border: solid #069e04;
|
||||
border-width: 0 5px 5px 0;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.async-form__response--info::before {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 30px;
|
||||
top: 10px;
|
||||
background-color: #777;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.async-form__response--info::after {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #777;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.async-form__response--warning::before {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 30px;
|
||||
background-color: rgb(255, 187, 0);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.async-form__response--warning::after {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
top: 35px;
|
||||
background-color: rgb(255, 187, 0);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.async-form__response--error::before {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 40px;
|
||||
background-color: #940d0d;
|
||||
transform: translateX(-50%) rotate(-45deg);
|
||||
}
|
||||
.async-form__response--error::after {
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 40px;
|
||||
background-color: #940d0d;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.async-form--loading {
|
||||
opacity: 0.1;
|
||||
transition: opacity 800ms ease-out;
|
||||
pointer-events: none;
|
||||
}
|
||||
4
frontend/src/utils/async-table/async-table-filter.sass
Normal file
4
frontend/src/utils/async-table/async-table-filter.sass
Normal file
@ -0,0 +1,4 @@
|
||||
.async-table-filter--loading
|
||||
opacity: 0.7
|
||||
pointer-events: none
|
||||
transition: opacity 400ms ease-out
|
||||
@ -1,5 +0,0 @@
|
||||
.async-table-filter--loading {
|
||||
opacity: 0.7;
|
||||
pointer-events: none;
|
||||
transition: opacity 400ms ease-out;
|
||||
}
|
||||
@ -1,9 +1,10 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import { HttpClient } from '../../services/http-client/http-client';
|
||||
import * as debounce from 'lodash.debounce';
|
||||
import './async-table-filter.scss';
|
||||
import './async-table.scss';
|
||||
import './async-table-filter.sass';
|
||||
import './async-table.sass';
|
||||
|
||||
const INPUT_DEBOUNCE = 600;
|
||||
const HEADER_HEIGHT = 80;
|
||||
@ -40,6 +41,8 @@ export class AsyncTable {
|
||||
};
|
||||
_ignoreRequest = false;
|
||||
|
||||
_storageManager = new StorageManager(ASYNC_TABLE_LOCAL_STORAGE_KEY, '1.0.0', { location: LOCATION.WINDOW });
|
||||
|
||||
constructor(element, app) {
|
||||
if (!element) {
|
||||
throw new Error('Async Table utility cannot be setup without an element!');
|
||||
@ -81,10 +84,10 @@ export class AsyncTable {
|
||||
this._setupPageSizeSelect();
|
||||
this._setupTableFilter();
|
||||
|
||||
this._processLocalStorage();
|
||||
this._processStorage();
|
||||
|
||||
// clear currentTableUrl from previous requests
|
||||
setLocalStorageParameter('currentTableUrl', null);
|
||||
this._storageManager.remove('currentTableUrl');
|
||||
|
||||
// mark initialized
|
||||
this._element.classList.add(ASYNC_TABLE_INITIALIZED_CLASS);
|
||||
@ -100,7 +103,7 @@ export class AsyncTable {
|
||||
|
||||
this._ths.forEach((th) => {
|
||||
th.clickHandler = (event) => {
|
||||
setLocalStorageParameter('horizPos', (this._scrollTable || {}).scrollLeft);
|
||||
this._storageManager.save('horizPos', (this._scrollTable || {}).scrollLeft);
|
||||
this._linkClickHandler(event);
|
||||
};
|
||||
th.element.addEventListener('click', th.clickHandler);
|
||||
@ -122,7 +125,7 @@ export class AsyncTable {
|
||||
left: this._scrollTable.offsetLeft || 0,
|
||||
behavior: 'smooth',
|
||||
};
|
||||
setLocalStorageParameter('scrollTo', scrollTo);
|
||||
this._storageManager.save('scrollTo', scrollTo);
|
||||
}
|
||||
this._linkClickHandler(event);
|
||||
};
|
||||
@ -225,7 +228,7 @@ export class AsyncTable {
|
||||
const prefix = findCssIdPrefix(focusedInput.id);
|
||||
const focusId = focusedInput.id.replace(prefix, '');
|
||||
callback = function(wrapper) {
|
||||
const idPrefix = getLocalStorageParameter('cssIdPrefix');
|
||||
const idPrefix = this._storageManager.load('cssIdPrefix');
|
||||
const toBeFocused = wrapper.querySelector('#' + idPrefix + focusId);
|
||||
if (toBeFocused) {
|
||||
toBeFocused.focus();
|
||||
@ -238,7 +241,7 @@ export class AsyncTable {
|
||||
}
|
||||
|
||||
_serializeTableFilterToURL(tableFilterForm) {
|
||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||
const url = new URL(this._storageManager.load('currentTableUrl') || window.location.href);
|
||||
|
||||
// create new FormData and format any date values
|
||||
const formData = Datepicker.unformatAll(this._massInputForm, new FormData(tableFilterForm));
|
||||
@ -254,18 +257,18 @@ export class AsyncTable {
|
||||
return url;
|
||||
}
|
||||
|
||||
_processLocalStorage() {
|
||||
const scrollTo = getLocalStorageParameter('scrollTo');
|
||||
_processStorage() {
|
||||
const scrollTo = this._storageManager.load('scrollTo');
|
||||
if (scrollTo && this._scrollTable) {
|
||||
window.scrollTo(scrollTo);
|
||||
}
|
||||
setLocalStorageParameter('scrollTo', null);
|
||||
this._storageManager.remove('scrollTo');
|
||||
|
||||
const horizPos = getLocalStorageParameter('horizPos');
|
||||
const horizPos = this._storageManager.load('horizPos');
|
||||
if (horizPos && this._scrollTable) {
|
||||
this._scrollTable.scrollLeft = horizPos;
|
||||
}
|
||||
setLocalStorageParameter('horizPos', null);
|
||||
this._storageManager.remove('horizPos');
|
||||
}
|
||||
|
||||
_removeListeners() {
|
||||
@ -300,7 +303,7 @@ export class AsyncTable {
|
||||
}
|
||||
|
||||
_changePagesizeHandler = () => {
|
||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||
const url = new URL(this._storageManager.load('currentTableUrl') || window.location.href);
|
||||
|
||||
// create new FormData and format any date values
|
||||
const formData = Datepicker.unformatAll(this._pagesizeForm, new FormData(this._pagesizeForm));
|
||||
@ -336,7 +339,7 @@ export class AsyncTable {
|
||||
return false;
|
||||
}
|
||||
|
||||
setLocalStorageParameter('currentTableUrl', url.href);
|
||||
this._storageManager.save('currentTableUrl', url.href);
|
||||
// reset table
|
||||
this._removeListeners();
|
||||
this._element.classList.remove(ASYNC_TABLE_INITIALIZED_CLASS);
|
||||
@ -346,9 +349,9 @@ export class AsyncTable {
|
||||
this._app.utilRegistry.setupAll(this._element);
|
||||
|
||||
if (callback && typeof callback === 'function') {
|
||||
setLocalStorageParameter('cssIdPrefix', response.idPrefix);
|
||||
this._storageManager.save('cssIdPrefix', response.idPrefix);
|
||||
callback(this._element);
|
||||
setLocalStorageParameter('cssIdPrefix', '');
|
||||
this._storageManager.remove('cssIdPrefix');
|
||||
}
|
||||
}).catch((err) => console.error(err)
|
||||
).finally(() => this._element.classList.remove(ASYNC_TABLE_LOADING_CLASS));
|
||||
@ -365,17 +368,3 @@ function findCssIdPrefix(id) {
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function setLocalStorageParameter(key, value) {
|
||||
const currentLSState = JSON.parse(window.localStorage.getItem(ASYNC_TABLE_LOCAL_STORAGE_KEY)) || {};
|
||||
if (value !== null) {
|
||||
currentLSState[key] = value;
|
||||
} else {
|
||||
delete currentLSState[key];
|
||||
}
|
||||
window.localStorage.setItem(ASYNC_TABLE_LOCAL_STORAGE_KEY, JSON.stringify(currentLSState));
|
||||
}
|
||||
function getLocalStorageParameter(key) {
|
||||
const currentLSState = JSON.parse(window.localStorage.getItem(ASYNC_TABLE_LOCAL_STORAGE_KEY)) || {};
|
||||
return currentLSState[key];
|
||||
}
|
||||
|
||||
4
frontend/src/utils/async-table/async-table.sass
Normal file
4
frontend/src/utils/async-table/async-table.sass
Normal file
@ -0,0 +1,4 @@
|
||||
.async-table--loading
|
||||
opacity: 0.7
|
||||
pointer-events: none
|
||||
transition: opacity 400ms ease-out
|
||||
@ -1,5 +0,0 @@
|
||||
.async-table--loading {
|
||||
opacity: 0.7;
|
||||
pointer-events: none;
|
||||
transition: opacity 400ms ease-out;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './course-teaser.scss';
|
||||
import './course-teaser.sass';
|
||||
|
||||
var COURSE_TEASER_INITIALIZED_CLASS = 'course-teaser--initialized';
|
||||
|
||||
|
||||
246
frontend/src/utils/course-teaser/course-teaser.sass
Normal file
246
frontend/src/utils/course-teaser/course-teaser.sass
Normal file
@ -0,0 +1,246 @@
|
||||
[uw-course-teaser]
|
||||
--course-border-color: var(--color-grey)
|
||||
--course-padding-hori: 10px
|
||||
--course-padding-vert: 12px
|
||||
display: grid
|
||||
position: relative
|
||||
grid-gap: 5px 7px
|
||||
grid-template-columns: 130px 30px 1fr 60px
|
||||
grid-template-areas: 'shrthnd . title chevron' 'shrthnd smstr school chevron' '. . rgstrd . ' 'tutor tutor name . ' 'duedate duedate date . ' 'dscrptn dscrptn dscrptn dscrptn'
|
||||
padding: var(--course-padding-vert) var(--course-padding-hori)
|
||||
transition: background-color .1s ease-out
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: var(--course-bg-color)
|
||||
|
||||
+ [uw-course-teaser]
|
||||
border-top: 1px solid var(--course-border-color)
|
||||
|
||||
@media (max-width: 768px)
|
||||
grid-template-columns: 140px 1fr 30px
|
||||
grid-template-areas: 'shrthnd title chevron' 'shrthnd title . ' 'smstr school school ' '. rgstrd rgstrd ' 'tutor name name ' 'duedate date date ' 'dscrptn dscrptn dscrptn'
|
||||
|
||||
@media (max-width: 426px)
|
||||
grid-template-columns: 1fr
|
||||
grid-template-areas: 'shrthnd' 'title' 'smstr' 'school' 'rgstrd' 'tutor' 'name' 'duedate' 'date' 'dscrptnlbl' 'dscrptn' 'chevron'
|
||||
|
||||
.course-teaser__not-expandable
|
||||
cursor: initial
|
||||
|
||||
// chevron
|
||||
.course-teaser__chevron
|
||||
position: relative
|
||||
padding: 10px
|
||||
grid-area: chevron
|
||||
justify-self: center
|
||||
align-self: center
|
||||
width: 100%
|
||||
height: 100%
|
||||
cursor: pointer
|
||||
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
display: block
|
||||
margin-top: -7.35px
|
||||
margin-left: -7.35px
|
||||
|
||||
// visually centered
|
||||
border-width: 0 3px 3px 0
|
||||
width: 8px
|
||||
height: 8px
|
||||
top: 50%
|
||||
left: 50%
|
||||
border-color: var(--color-fontsec)
|
||||
border-style: solid
|
||||
transform: rotate(135deg)
|
||||
transform-origin: 7.25px 7.25px
|
||||
|
||||
// rotate about visual center
|
||||
transition: all .2s ease-out
|
||||
|
||||
&:hover::before
|
||||
transform: scale(1.4) rotate(45deg)
|
||||
|
||||
@media (max-width: 768px)
|
||||
justify-self: end
|
||||
width: auto
|
||||
|
||||
&::before
|
||||
position: initial
|
||||
|
||||
@media (max-width: 426px)
|
||||
&::before
|
||||
transform: rotate(45deg)
|
||||
margin-left: -7.35px
|
||||
|
||||
&:hover::before
|
||||
transform: scale(1.4) rotate(45deg)
|
||||
|
||||
// semester
|
||||
.course-teaser__semester
|
||||
grid-area: smstr
|
||||
justify-self: end
|
||||
|
||||
a
|
||||
color: var(--color-fontsec)
|
||||
|
||||
@media (max-width: 768px)
|
||||
justify-self: initial
|
||||
|
||||
// shorthand
|
||||
.course-teaser__shorthand
|
||||
position: relative
|
||||
grid-area: shrthnd
|
||||
font-size: 2rem
|
||||
line-height: 1.25
|
||||
min-height: calc(2rem * 1.25)
|
||||
|
||||
> a
|
||||
position: absolute
|
||||
height: 100%
|
||||
width: 100%
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
word-break: break-any
|
||||
text-decoration: none !important
|
||||
|
||||
// sry.
|
||||
font-weight: 600
|
||||
color: var(--color-grey-medium)
|
||||
|
||||
// @media (max-width: 768px) {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
// title
|
||||
.course-teaser__title
|
||||
grid-area: title
|
||||
font-size: 1.2rem
|
||||
align-self: baseline
|
||||
|
||||
// registration
|
||||
.course-teaser__registration
|
||||
grid-area: rgstrd
|
||||
color: var(--color-fontsec)
|
||||
font-weight: bold
|
||||
|
||||
// school
|
||||
.course-teaser__school
|
||||
grid-area: school
|
||||
|
||||
a
|
||||
color: var(--color-fontsec)
|
||||
|
||||
// duedate
|
||||
.course-teaser__duedate
|
||||
grid-area: date
|
||||
|
||||
// lecturer
|
||||
.course-teaser__lecturer
|
||||
grid-area: name
|
||||
|
||||
// description
|
||||
.course-teaser__description
|
||||
grid-area: dscrptn
|
||||
max-height: 75vh
|
||||
overflow: auto
|
||||
|
||||
// show description only as dots (overflow text-overflow) and only show when expanded. No "hidden fiddling"
|
||||
|
||||
// labels
|
||||
.course-teaser__lecturer-label
|
||||
grid-area: tutor
|
||||
|
||||
.course-teaser__duedate-label
|
||||
grid-area: duedate
|
||||
|
||||
.course-teaser__description-label
|
||||
grid-area: dscrptnlbl
|
||||
|
||||
.course-teaser__lecturer-label,
|
||||
.course-teaser__description-label,
|
||||
.course-teaser__duedate-label
|
||||
justify-self: end
|
||||
color: var(--color-fontsec)
|
||||
font-style: italic
|
||||
|
||||
@media (max-width: 768px)
|
||||
justify-self: initial
|
||||
|
||||
@media (max-width: 426px)
|
||||
margin-top: 7px
|
||||
font-weight: bold
|
||||
font-style: initial
|
||||
|
||||
// hidden in closed state
|
||||
.course-teaser__description,
|
||||
.course-teaser__description-label
|
||||
display: none
|
||||
|
||||
// expanded courses
|
||||
.course-teaser__expanded
|
||||
cursor: initial
|
||||
|
||||
.course-teaser__chevron
|
||||
&::before
|
||||
transform: rotate(45deg)
|
||||
|
||||
&:hover::before
|
||||
transform: scale(1.4) rotate(135deg)
|
||||
|
||||
@media (max-width: 426px)
|
||||
&::before
|
||||
transform: rotate(225deg)
|
||||
|
||||
&:hover::before
|
||||
transform: scale(1.4) rotate(225deg)
|
||||
|
||||
.course-teaser__school-label,
|
||||
.course-teaser__school,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate,
|
||||
.course-teaser__description
|
||||
display: block
|
||||
|
||||
@media (max-width: 426px)
|
||||
.course-teaser__description-label
|
||||
display: block
|
||||
|
||||
// course teaser: header styling
|
||||
.course-teaser-header
|
||||
padding-top: 10px
|
||||
padding-bottom: 20px
|
||||
line-height: 1.4
|
||||
max-width: 85vw
|
||||
|
||||
.course-header
|
||||
float: left
|
||||
background-color: var(--color-dark)
|
||||
position: relative
|
||||
font-size: 16px
|
||||
color: #fff
|
||||
padding-top: 10px
|
||||
padding-bottom: 10px
|
||||
padding-left: 10px
|
||||
padding-right: 35px
|
||||
margin-bottom: 10px
|
||||
font-weight: bold
|
||||
text-align: left
|
||||
border-radius: 20px 20px 20px 20px / 50% 50% 50% 50%
|
||||
margin-right: 30px
|
||||
|
||||
.course-header-link
|
||||
color: white
|
||||
font-weight: bold
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
color: inherit
|
||||
|
||||
.course-teaser-header:after
|
||||
content: ""
|
||||
display: table
|
||||
clear: both
|
||||
@ -1,317 +0,0 @@
|
||||
[uw-course-teaser] {
|
||||
--course-border-color: var(--color-grey);
|
||||
--course-padding-hori: 10px;
|
||||
--course-padding-vert: 12px;
|
||||
|
||||
display: grid;
|
||||
position: relative;
|
||||
grid-gap: 5px 7px;
|
||||
grid-template-columns: 130px 30px 1fr 60px;
|
||||
grid-template-areas:
|
||||
'shrthnd . title chevron'
|
||||
'shrthnd smstr school chevron'
|
||||
'. . rgstrd . '
|
||||
'tutor tutor name . '
|
||||
'duedate duedate date . '
|
||||
'dscrptn dscrptn dscrptn dscrptn';
|
||||
padding: var(--course-padding-vert) var(--course-padding-hori);
|
||||
transition: background-color .1s ease-out;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--course-bg-color);
|
||||
}
|
||||
|
||||
+ [uw-course-teaser] {
|
||||
border-top: 1px solid var(--course-border-color);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: 140px 1fr 30px;
|
||||
grid-template-areas:
|
||||
'shrthnd title chevron'
|
||||
'shrthnd title . '
|
||||
'smstr school school '
|
||||
'. rgstrd rgstrd '
|
||||
'tutor name name '
|
||||
'duedate date date '
|
||||
'dscrptn dscrptn dscrptn';
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
'shrthnd'
|
||||
'title'
|
||||
'smstr'
|
||||
'school'
|
||||
'rgstrd'
|
||||
'tutor'
|
||||
'name'
|
||||
'duedate'
|
||||
'date'
|
||||
'dscrptnlbl'
|
||||
'dscrptn'
|
||||
'chevron';
|
||||
}
|
||||
}
|
||||
|
||||
.course-teaser__not-expandable {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
/* chevron */
|
||||
.course-teaser__chevron {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
grid-area: chevron;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
margin-top: -7.35px;
|
||||
margin-left: -7.35px; /* visually centered */
|
||||
border-width: 0 3px 3px 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
border-color: var(--color-fontsec);
|
||||
border-style: solid;
|
||||
transform: rotate(135deg);
|
||||
transform-origin: 7.25px 7.25px; /* rotate about visual center */
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
transform: scale(1.4) rotate(45deg);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
justify-self: end;
|
||||
width: auto;
|
||||
|
||||
&::before {
|
||||
position: initial;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
&::before {
|
||||
transform: rotate(45deg);
|
||||
margin-left: -7.35px;
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
transform: scale(1.4) rotate(45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* semester */
|
||||
.course-teaser__semester {
|
||||
grid-area: smstr;
|
||||
justify-self: end;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
justify-self: initial;
|
||||
}
|
||||
}
|
||||
|
||||
/* shorthand */
|
||||
.course-teaser__shorthand {
|
||||
position: relative;
|
||||
grid-area: shrthnd;
|
||||
font-size: 2rem;
|
||||
line-height: 1.25;
|
||||
min-height: calc(2rem * 1.25);
|
||||
|
||||
> a {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break: break-any;
|
||||
|
||||
text-decoration: none !important; /* sry. */
|
||||
font-weight: 600;
|
||||
color: var(--color-grey-medium);
|
||||
}
|
||||
|
||||
/* @media (max-width: 768px) {
|
||||
* position: initial;
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
/* title */
|
||||
.course-teaser__title {
|
||||
grid-area: title;
|
||||
font-size: 1.2rem;
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
/* registration */
|
||||
.course-teaser__registration {
|
||||
grid-area: rgstrd;
|
||||
color: var(--color-fontsec);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* school */
|
||||
.course-teaser__school {
|
||||
grid-area: school;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* duedate */
|
||||
.course-teaser__duedate {
|
||||
grid-area: date;
|
||||
}
|
||||
|
||||
/* lecturer */
|
||||
.course-teaser__lecturer {
|
||||
grid-area: name;
|
||||
}
|
||||
|
||||
/* description */
|
||||
.course-teaser__description {
|
||||
grid-area: dscrptn;
|
||||
max-height: 75vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* show description only as dots (overflow text-overflow) and only show when expanded. No "hidden fiddling" */
|
||||
|
||||
/* labels */
|
||||
.course-teaser__lecturer-label {
|
||||
grid-area: tutor;
|
||||
}
|
||||
|
||||
.course-teaser__duedate-label {
|
||||
grid-area: duedate;
|
||||
}
|
||||
|
||||
.course-teaser__description-label {
|
||||
grid-area: dscrptnlbl;
|
||||
}
|
||||
|
||||
.course-teaser__lecturer-label,
|
||||
.course-teaser__description-label,
|
||||
.course-teaser__duedate-label {
|
||||
justify-self: end;
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
justify-self: initial;
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
margin-top: 7px;
|
||||
font-weight: bold;
|
||||
font-style: initial;
|
||||
}
|
||||
}
|
||||
|
||||
/* hidden in closed state */
|
||||
.course-teaser__description,
|
||||
.course-teaser__description-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* expanded courses */
|
||||
.course-teaser__expanded {
|
||||
cursor: initial;
|
||||
|
||||
.course-teaser__chevron {
|
||||
&::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
transform: scale(1.4) rotate(135deg);
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
&::before {
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
transform: scale(1.4) rotate(225deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-teaser__school-label,
|
||||
.course-teaser__school,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate,
|
||||
.course-teaser__description {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
.course-teaser__description-label {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
course teaser: header styling
|
||||
*/
|
||||
.course-teaser-header {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 20px;
|
||||
line-height: 1.4;
|
||||
max-width: 85vw;
|
||||
|
||||
.course-header {
|
||||
float: left;
|
||||
background-color: var(--color-dark);
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 35px;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
border-radius: 20px 20px 20px 20px / 50% 50% 50% 50%;
|
||||
margin-right: 30px;
|
||||
|
||||
.course-header-link {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-teaser-header:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import './form.scss';
|
||||
import './form.sass';
|
||||
import { AutoSubmitButton } from './auto-submit-button';
|
||||
import { AutoSubmitInput } from './auto-submit-input';
|
||||
import { Datepicker } from './datepicker';
|
||||
|
||||
35
frontend/src/utils/form/form.sass
Normal file
35
frontend/src/utils/form/form.sass
Normal file
@ -0,0 +1,35 @@
|
||||
fieldset
|
||||
border: 0
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
legend
|
||||
display: none
|
||||
|
||||
@media (min-width: 769px)
|
||||
.form-group__input
|
||||
grid-column: 2
|
||||
|
||||
[uw-auto-submit-button][type='submit']
|
||||
animation: fade-in 500ms ease-in-out backwards
|
||||
animation-delay: 500ms
|
||||
|
||||
@keyframes fade-in
|
||||
from
|
||||
opacity: 0
|
||||
|
||||
.hidden
|
||||
visibility: hidden !important
|
||||
height: 0 !important
|
||||
width: 0 !important
|
||||
opacity: 0 !important
|
||||
margin: 0 !important
|
||||
padding: 0 !important
|
||||
min-width: 0 !important
|
||||
|
||||
.select--pagesize
|
||||
width: 5em
|
||||
min-width: 75px
|
||||
|
||||
.label-pagesize
|
||||
margin-right: 13px
|
||||
@ -1,45 +0,0 @@
|
||||
fieldset {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
legend {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.form-group__input {
|
||||
grid-column: 2;
|
||||
}
|
||||
}
|
||||
|
||||
[uw-auto-submit-button][type='submit'] {
|
||||
animation: fade-in 500ms ease-in-out backwards;
|
||||
animation-delay: 500ms;
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
visibility: hidden !important;
|
||||
height: 0 !important;
|
||||
width: 0 !important;
|
||||
opacity: 0 !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.select--pagesize {
|
||||
width: 5em;
|
||||
min-width: 75px;
|
||||
}
|
||||
|
||||
.label-pagesize {
|
||||
margin-right: 13px;
|
||||
}
|
||||
312
frontend/src/utils/hide-columns/hide-columns.js
Normal file
312
frontend/src/utils/hide-columns/hide-columns.js
Normal file
@ -0,0 +1,312 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager';
|
||||
import './hide-columns.sass';
|
||||
|
||||
const HIDE_COLUMNS_CONTAINER_IDENT = 'uw-hide-columns';
|
||||
const TABLE_HEADER_IDENT = 'uw-hide-column-header';
|
||||
|
||||
const TABLE_UTILS_ATTR = 'table-utils';
|
||||
const TABLE_UTILS_CONTAINER_SELECTOR = `[${TABLE_UTILS_ATTR}]`;
|
||||
|
||||
const TABLE_HIDER_CLASS = 'table-hider';
|
||||
const TABLE_HIDER_VISIBLE_CLASS = 'table-hider--visible';
|
||||
|
||||
const TABLE_PILL_CLASS = 'table-pill';
|
||||
|
||||
const CELL_HIDDEN_CLASS = 'hide-columns--hidden-cell';
|
||||
const CELL_ORIGINAL_COLSPAN = 'uw-hide-column-original-colspan';
|
||||
|
||||
@Utility({
|
||||
selector: `[${HIDE_COLUMNS_CONTAINER_IDENT}] table`,
|
||||
})
|
||||
export class HideColumns {
|
||||
|
||||
_storageManager = new StorageManager('HIDE_COLUMNS', '1.0.0', { location: LOCATION.LOCAL });
|
||||
|
||||
_element;
|
||||
_elementWrapper;
|
||||
_tableUtilContainer;
|
||||
|
||||
_autoHide;
|
||||
|
||||
headerToHider = new Map();
|
||||
hiderToHeader = new Map();
|
||||
|
||||
addHeaderHider(th, hider) {
|
||||
this.headerToHider.set(th, hider);
|
||||
this.hiderToHeader.set(hider, th);
|
||||
}
|
||||
|
||||
constructor(element) {
|
||||
this._autoHide = this._storageManager.load('autoHide', {}) || false;
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Hide Columns utility cannot be setup without an element!');
|
||||
}
|
||||
|
||||
// do not provide hide-column ability in tables inside modals or async forms with response
|
||||
if (element.closest('[uw-modal], .async-form__response')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._element = element;
|
||||
|
||||
const hideColumnsContainer = this._element.closest(`[${HIDE_COLUMNS_CONTAINER_IDENT}]`);
|
||||
if (!hideColumnsContainer) {
|
||||
throw new Error('Hide Columns utility needs to be setup on a table inside a hide columns container!');
|
||||
}
|
||||
this._elementWrapper = hideColumnsContainer;
|
||||
|
||||
// get or create table utils container
|
||||
this._tableUtilContainer = hideColumnsContainer.querySelector(TABLE_UTILS_CONTAINER_SELECTOR);
|
||||
if (!this._tableUtilContainer) {
|
||||
this._tableUtilContainer = document.createElement('div');
|
||||
this._tableUtilContainer.setAttribute(TABLE_UTILS_ATTR, '');
|
||||
const tableContainer = this._element.closest(`[${HIDE_COLUMNS_CONTAINER_IDENT}] > *`);
|
||||
hideColumnsContainer.insertBefore(this._tableUtilContainer, tableContainer);
|
||||
}
|
||||
|
||||
this._element.querySelectorAll('th').forEach(th => this.setupHideButton(th));
|
||||
}
|
||||
|
||||
setupHideButton(th) {
|
||||
const preHidden = this.isHiddenColumn(th);
|
||||
|
||||
const hider = document.createElement('span');
|
||||
|
||||
const hiderIcon = document.createElement('i');
|
||||
hiderIcon.classList.add('fas', 'fa-fw');
|
||||
hider.appendChild(hiderIcon);
|
||||
|
||||
const hiderContent = document.createElement('span');
|
||||
hiderContent.classList.add('table-hider__label');
|
||||
hiderContent.innerHTML = th.innerText;
|
||||
hider.appendChild(hiderContent);
|
||||
|
||||
this.addHeaderHider(th, hider);
|
||||
|
||||
th.addEventListener('mouseover', () => {
|
||||
hider.classList.add(TABLE_HIDER_VISIBLE_CLASS);
|
||||
});
|
||||
th.addEventListener('mouseout', () => {
|
||||
if (hider.classList.contains(TABLE_HIDER_CLASS)) {
|
||||
hider.classList.remove(TABLE_HIDER_VISIBLE_CLASS);
|
||||
}
|
||||
});
|
||||
|
||||
hider.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.switchColumnDisplay(th, hider);
|
||||
// this._tableHiderContainer.getElementsByClassName(TABLE_HIDER_CLASS).forEach(hider => this.hideHiderBehindHeader(hider));
|
||||
});
|
||||
|
||||
hider.addEventListener('mouseover', () => {
|
||||
hider.classList.add(TABLE_HIDER_VISIBLE_CLASS);
|
||||
const currentlyHidden = this.isHiddenColumn(th);
|
||||
this.updateHiderIcon(hider, !currentlyHidden);
|
||||
});
|
||||
hider.addEventListener('mouseout', () => {
|
||||
if (hider.classList.contains(TABLE_HIDER_CLASS)) {
|
||||
hider.classList.remove(TABLE_HIDER_VISIBLE_CLASS);
|
||||
}
|
||||
const currentlyHidden = this.isHiddenColumn(th);
|
||||
this.updateHiderIcon(hider, currentlyHidden);
|
||||
});
|
||||
|
||||
new ResizeObserver(() => { this.repositionHider(hider); }).observe(th);
|
||||
|
||||
// reposition hider on each window resize event
|
||||
// window.addEventListener('resize', () => this.repositionHider(hider));
|
||||
|
||||
this.updateColumnDisplay(this.colIndex(th), preHidden);
|
||||
this.updateHider(hider, preHidden);
|
||||
|
||||
if (preHidden) {
|
||||
this._tableUtilContainer.appendChild(hider);
|
||||
} else {
|
||||
this.hideHiderBehindHeader(hider);
|
||||
}
|
||||
}
|
||||
|
||||
switchColumnDisplay(th, hider) {
|
||||
const hidden = !this.isHiddenColumn(th);
|
||||
const originalColspan = Math.max(1, th.getAttribute(CELL_ORIGINAL_COLSPAN)) || 1;
|
||||
const colspan = Math.max(1, th.colSpan) || 1;
|
||||
const columnIndex = this.colIndex(th);
|
||||
|
||||
for (var i = 0; i < Math.max(colspan, originalColspan); i++) {
|
||||
this.updateColumnDisplay(columnIndex + i, hidden);
|
||||
}
|
||||
this.updateHider(hider, hidden);
|
||||
|
||||
// persist new hidden setting for column
|
||||
if ((hidden && this.isEmptyColumn(columnIndex) && this._autoHide) || (!hidden && (!this.isEmptyColumn(columnIndex) || !this._autoHide))) {
|
||||
this._storageManager.remove(this.getStorageKey(th));
|
||||
} else {
|
||||
this._storageManager.save(this.getStorageKey(th), hidden);
|
||||
}
|
||||
}
|
||||
|
||||
updateColumnDisplay(columnIndex, hidden) {
|
||||
this._element.getElementsByTagName('tr').forEach(row => {
|
||||
const cell = this.getCol(row, columnIndex);
|
||||
|
||||
if (cell) {
|
||||
const originalColspan = cell.getAttribute(CELL_ORIGINAL_COLSPAN);
|
||||
const colspan = Math.max(1, cell.colSpan) || 1;
|
||||
|
||||
if (hidden) {
|
||||
if (colspan > 1) {
|
||||
if (!originalColspan) {
|
||||
cell.setAttribute(CELL_ORIGINAL_COLSPAN, colspan);
|
||||
}
|
||||
cell.colSpan--;
|
||||
} else {
|
||||
cell.classList.add(CELL_HIDDEN_CLASS);
|
||||
}
|
||||
} else {
|
||||
if (cell.classList.contains(CELL_HIDDEN_CLASS)) {
|
||||
cell.classList.remove(CELL_HIDDEN_CLASS);
|
||||
} else if (originalColspan && colspan < originalColspan) {
|
||||
cell.colSpan++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateHider(hider, hidden) {
|
||||
if (hidden) {
|
||||
hider.classList.remove(TABLE_HIDER_CLASS);
|
||||
hider.classList.add(TABLE_PILL_CLASS);
|
||||
this._tableUtilContainer.appendChild(hider);
|
||||
} else {
|
||||
hider.classList.remove(TABLE_PILL_CLASS);
|
||||
hider.classList.add(TABLE_HIDER_CLASS);
|
||||
this.hideHiderBehindHeader(hider);
|
||||
}
|
||||
this.updateHiderIcon(hider, hidden);
|
||||
}
|
||||
|
||||
updateHiderIcon(hider, hidden) {
|
||||
hider.getElementsByClassName('fas').forEach(hiderIcon => {
|
||||
hiderIcon.classList.remove(hidden ? 'fa-eye' : 'fa-eye-slash');
|
||||
hiderIcon.classList.add(hidden ? 'fa-eye-slash' : 'fa-eye');
|
||||
});
|
||||
}
|
||||
|
||||
hideHiderBehindHeader(hider) {
|
||||
if (!this.hiderToHeader.get(hider).contains(hider)) {
|
||||
this.hiderToHeader.get(hider).appendChild(hider);
|
||||
}
|
||||
|
||||
this.repositionHider(hider);
|
||||
|
||||
// remove visible class if necessary
|
||||
hider.classList.remove(TABLE_HIDER_VISIBLE_CLASS);
|
||||
}
|
||||
|
||||
repositionHider(hider) {
|
||||
const thR = this.hiderToHeader.get(hider).getBoundingClientRect(),
|
||||
hR = hider.getBoundingClientRect();
|
||||
|
||||
hider.style.left = (thR.width/2 - hR.width/2) + 'px';
|
||||
hider.style.top = thR.height + 'px';
|
||||
}
|
||||
|
||||
getStorageKey(th) {
|
||||
// get handler name
|
||||
const handlerIdent = document.querySelector('[uw-handler]').getAttribute('uw-handler');
|
||||
|
||||
// get hide-columns container ident (if not present, use table index in document as fallback)
|
||||
let tIdent = this._elementWrapper.getAttribute(HIDE_COLUMNS_CONTAINER_IDENT);
|
||||
if (!tIdent) {
|
||||
const tablesInDocument = document.getElementsByTagName('TABLE');
|
||||
for (let i = 0; i < tablesInDocument.length; i++) {
|
||||
if (tablesInDocument[i] === this._element) {
|
||||
tIdent = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for unique table header ident from backend (if not present, use cell index as fallback)
|
||||
let thIdent = th.getAttribute(TABLE_HEADER_IDENT);
|
||||
if (!thIdent) {
|
||||
thIdent = this.colIndex(th);
|
||||
}
|
||||
|
||||
return `${handlerIdent}__${tIdent}__${thIdent}`;
|
||||
}
|
||||
|
||||
isEmptyColumn(columnIndex) {
|
||||
for (let row of this._element.getElementsByTagName('tr')) {
|
||||
const cell = this.getCol(row, columnIndex);
|
||||
if (cell.matches('th'))
|
||||
continue;
|
||||
if (cell.querySelector('.table__td-content')) {
|
||||
for (let child of cell.children) {
|
||||
if (!isEmptyElement(child))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return isEmptyElement(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isHiddenColumn(th) {
|
||||
const hidden = this._storageManager.load(this.getStorageKey(th)),
|
||||
emptyColumn = this.isEmptyColumn(this.colIndex(th));
|
||||
return hidden === true || hidden === undefined && emptyColumn && this._autoHide;
|
||||
}
|
||||
|
||||
colSpan(cell) {
|
||||
if (!cell)
|
||||
return 1;
|
||||
|
||||
const originalColspan = cell.getAttribute(CELL_ORIGINAL_COLSPAN);
|
||||
const colspan = Math.max(1, cell.colSpan) || 1;
|
||||
|
||||
return originalColspan ? Math.max(colspan, originalColspan) : colspan;
|
||||
}
|
||||
|
||||
colIndex(cell) {
|
||||
if (!cell)
|
||||
return 0;
|
||||
|
||||
const rowParent = cell.closest('tr');
|
||||
|
||||
if (!rowParent)
|
||||
return 0;
|
||||
|
||||
var i = 0;
|
||||
for (const sibling of Array.from(rowParent.cells).slice(0, cell.cellIndex)) {
|
||||
i += this.colSpan(sibling);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
getCol(row, columnIndex) {
|
||||
var c = 0;
|
||||
|
||||
for (const cell of row.cells) {
|
||||
c += cell ? this.colSpan(cell) : 1;
|
||||
|
||||
if (columnIndex < c)
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isEmptyElement(element) {
|
||||
for (let child of element.childNodes) {
|
||||
if (child.nodeName !== '#comment')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
61
frontend/src/utils/hide-columns/hide-columns.sass
Normal file
61
frontend/src/utils/hide-columns/hide-columns.sass
Normal file
@ -0,0 +1,61 @@
|
||||
.table-hider
|
||||
background-color: #fff
|
||||
color: var(--color-link)
|
||||
padding: 10px
|
||||
cursor: pointer
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
position: absolute
|
||||
overflow: hidden
|
||||
transition: transform .2s ease
|
||||
transform: scaleY(0)
|
||||
transform-origin: top
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
.table-hider__label
|
||||
display: none
|
||||
|
||||
&.table-hider--visible
|
||||
transform: scaleY(0.4)
|
||||
transition: none
|
||||
|
||||
// TODO find better way to prevent transition on icons
|
||||
|
||||
.fas
|
||||
transform: scaleY(2.5)
|
||||
|
||||
&:hover
|
||||
transform: scaleY(1)
|
||||
|
||||
.fas
|
||||
transform: scaleY(1)
|
||||
|
||||
[table-utils]
|
||||
max-width: 85vw
|
||||
margin-bottom: 10px
|
||||
min-height: 0
|
||||
line-height: 1.4
|
||||
|
||||
.table-pill
|
||||
background-color: var(--color-dark)
|
||||
float: left
|
||||
color: #fff
|
||||
padding: 10px
|
||||
border-radius: 20px / 50%
|
||||
margin-right: 20px
|
||||
margin-bottom: 10px
|
||||
cursor: pointer
|
||||
|
||||
.table-hider__label
|
||||
font-size: 16px
|
||||
font-weight: bold
|
||||
margin-left: 5px
|
||||
|
||||
&:after
|
||||
content: ""
|
||||
display: block
|
||||
clear: both
|
||||
|
||||
.hide-columns--hidden-cell
|
||||
display: none
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './checkbox.scss';
|
||||
import './checkbox.sass';
|
||||
|
||||
var CHECKBOX_CLASS = 'checkbox';
|
||||
var CHECKBOX_INITIALIZED_CLASS = 'checkbox--initialized';
|
||||
|
||||
71
frontend/src/utils/inputs/checkbox.sass
Normal file
71
frontend/src/utils/inputs/checkbox.sass
Normal file
@ -0,0 +1,71 @@
|
||||
// CUSTOM CHECKBOXES
|
||||
// Completely replaces legacy checkbox
|
||||
.checkbox [type='checkbox'], #lang-checkbox
|
||||
position: fixed
|
||||
top: -1px
|
||||
left: -1px
|
||||
width: 1px
|
||||
height: 1px
|
||||
overflow: hidden
|
||||
display: none
|
||||
|
||||
.checkbox
|
||||
position: relative
|
||||
display: inline-block
|
||||
|
||||
label
|
||||
display: block
|
||||
height: 20px
|
||||
width: 20px
|
||||
background-color: #f3f3f3
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05)
|
||||
border: 2px solid var(--color-primary)
|
||||
border-radius: 4px
|
||||
color: white
|
||||
cursor: pointer
|
||||
|
||||
label::before,
|
||||
label::after
|
||||
position: absolute
|
||||
display: block
|
||||
top: 12px
|
||||
left: 8px
|
||||
height: 2px
|
||||
width: 8px
|
||||
background-color: var(--color-font)
|
||||
|
||||
\:checked + label
|
||||
background-color: var(--color-primary)
|
||||
|
||||
[type='checkbox']:focus + label
|
||||
border-color: #3273dc
|
||||
box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25)
|
||||
outline: 0
|
||||
|
||||
\:checked + label::before,
|
||||
:checked + label::after
|
||||
content: ''
|
||||
|
||||
\:checked + label::before
|
||||
background-color: white
|
||||
transform: rotate(45deg)
|
||||
left: 2px
|
||||
top: 11px
|
||||
|
||||
\:checked + label::after
|
||||
background-color: white
|
||||
transform: rotate(-45deg)
|
||||
top: 9px
|
||||
width: 12px
|
||||
left: 7px
|
||||
|
||||
[disabled] + label
|
||||
pointer-events: none
|
||||
border: none
|
||||
opacity: 0.6
|
||||
filter: grayscale(1)
|
||||
|
||||
// special treatment for checkboxes in table headers
|
||||
th .checkbox
|
||||
margin-right: 7px
|
||||
vertical-align: bottom
|
||||
@ -1,83 +0,0 @@
|
||||
|
||||
/* CUSTOM CHECKBOXES */
|
||||
/* Completely replaces legacy checkbox */
|
||||
.checkbox [type='checkbox'], #lang-checkbox {
|
||||
position: fixed;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05);
|
||||
border: 2px solid var(--color-primary);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label::before,
|
||||
label::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 12px;
|
||||
left: 8px;
|
||||
height: 2px;
|
||||
width: 8px;
|
||||
background-color: var(--color-font);
|
||||
}
|
||||
|
||||
:checked + label {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
[type='checkbox']:focus + label {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0 0.125em rgba(50,115,220,.25);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
:checked + label::before,
|
||||
:checked + label::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
:checked + label::before {
|
||||
background-color: white;
|
||||
transform: rotate(45deg);
|
||||
left: 2px;
|
||||
top: 11px;
|
||||
}
|
||||
|
||||
:checked + label::after {
|
||||
background-color: white;
|
||||
transform: rotate(-45deg);
|
||||
top: 9px;
|
||||
width: 12px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
[disabled] + label {
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
opacity: 0.6;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* special treatment for checkboxes in table headers */
|
||||
th .checkbox {
|
||||
margin-right: 7px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './file-input.scss';
|
||||
import './file-input.sass';
|
||||
|
||||
const FILE_INPUT_CLASS = 'file-input';
|
||||
const FILE_INPUT_INITIALIZED_CLASS = 'file-input--initialized';
|
||||
|
||||
2
frontend/src/utils/inputs/file-input.sass
Normal file
2
frontend/src/utils/inputs/file-input.sass
Normal file
@ -0,0 +1,2 @@
|
||||
.file-input__list:empty
|
||||
display: none
|
||||
@ -1,3 +0,0 @@
|
||||
.file-input__list:empty {
|
||||
display: none;
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
import { Checkbox } from './checkbox';
|
||||
import { FileInput } from './file-input';
|
||||
|
||||
import './inputs.scss';
|
||||
import './radio.scss';
|
||||
import './inputs.sass';
|
||||
import './radio.sass';
|
||||
|
||||
export const InputUtils = [
|
||||
Checkbox,
|
||||
|
||||
211
frontend/src/utils/inputs/inputs.sass
Normal file
211
frontend/src/utils/inputs/inputs.sass
Normal file
@ -0,0 +1,211 @@
|
||||
// GENERAL STYLES FOR FORMS
|
||||
|
||||
// FORM GROUPS
|
||||
.form-section-title
|
||||
color: var(--color-fontsec)
|
||||
margin: 0
|
||||
|
||||
+ .form-group
|
||||
margin-top: 11px
|
||||
|
||||
.form-group
|
||||
position: relative
|
||||
display: flex
|
||||
display: grid
|
||||
grid-template-columns: 1fr 3fr
|
||||
grid-gap: 5px
|
||||
justify-content: flex-start
|
||||
align-items: flex-start
|
||||
|
||||
+ .form-group, + .form-section-legend, + .form-section-notification
|
||||
margin-top: 11px
|
||||
|
||||
+ .form-section-title
|
||||
margin-top: 40px
|
||||
|
||||
.form-section-legend
|
||||
color: var(--color-fontsec)
|
||||
margin: 7px 0
|
||||
|
||||
.form-group__hint, .form-section-title__hint
|
||||
color: var(--color-fontsec)
|
||||
font-size: 0.9rem
|
||||
font-weight: 600
|
||||
|
||||
.form-section-title__hint
|
||||
margin-top: 7px
|
||||
|
||||
+ .form-group
|
||||
margin-top: 11px
|
||||
|
||||
.form-group-label
|
||||
font-weight: 600
|
||||
padding-top: 6px
|
||||
|
||||
.form-group-label__hint
|
||||
margin-top: 7px
|
||||
color: var(--color-fontsec)
|
||||
font-size: 0.9rem
|
||||
|
||||
.form-group--required .form-group-label__caption::after, .form-group__required-marker::before
|
||||
content: ' *'
|
||||
color: var(--color-error)
|
||||
font-weight: 600
|
||||
|
||||
.form-group--submit .form-group__input
|
||||
grid-column: 2
|
||||
|
||||
@media (max-width: 768px)
|
||||
.form-group--submit .form-group__input
|
||||
grid-column: 1
|
||||
|
||||
.form-group--has-error
|
||||
background-color: rgba(255, 0, 0, 0.1)
|
||||
|
||||
input, textarea
|
||||
border-color: var(--color-error) !important
|
||||
|
||||
.form-error
|
||||
display: block
|
||||
|
||||
.form-error
|
||||
display: none
|
||||
|
||||
@media (max-width: 768px)
|
||||
.form-group
|
||||
grid-template-columns: 1fr
|
||||
align-items: baseline
|
||||
margin-top: 17px
|
||||
flex-direction: column
|
||||
|
||||
// TEXT INPUTS
|
||||
input[type='text'],
|
||||
input[type='search'],
|
||||
input[type='password'],
|
||||
input[type='url'],
|
||||
input[type='number'],
|
||||
input[type='email'],
|
||||
input[type*='date'],
|
||||
input[type*='time'],
|
||||
select
|
||||
// from bulma.css
|
||||
color: #363636
|
||||
border-color: #dbdbdb
|
||||
background-color: #f3f3f3
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05)
|
||||
width: 100%
|
||||
max-width: 600px
|
||||
align-items: center
|
||||
border: 1px solid transparent
|
||||
border-radius: 4px
|
||||
font-size: 1rem
|
||||
font-family: var(--font-base)
|
||||
line-height: 1.5
|
||||
padding: 4px 13px
|
||||
|
||||
input[type='number']
|
||||
width: 100px
|
||||
|
||||
input[type*='date'],
|
||||
input[type*='time'],
|
||||
.flatpickr-input[type='text']
|
||||
width: 50%
|
||||
width: 250px
|
||||
|
||||
// BUTTON STYLE SEE default-layout.lucius
|
||||
|
||||
// TEXTAREAS
|
||||
textarea
|
||||
width: 100%
|
||||
height: 170px
|
||||
max-width: 600px
|
||||
line-height: 1.5
|
||||
color: #363636
|
||||
background-color: #f3f3f3
|
||||
padding: 4px 13px
|
||||
font-size: 1rem
|
||||
font-family: var(--font-base)
|
||||
appearance: none
|
||||
border: 1px solid #dbdbdb
|
||||
border-radius: 2px
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05)
|
||||
vertical-align: top
|
||||
|
||||
// SHARED STATE RELATED STYLES
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea
|
||||
&:focus
|
||||
border-color: #3273dc
|
||||
box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25)
|
||||
outline: 0
|
||||
|
||||
&[disabled]
|
||||
background-color: #f3f3f3
|
||||
color: #7a7a7a
|
||||
box-shadow: none
|
||||
border-color: #dbdbdb
|
||||
|
||||
&[readonly]
|
||||
background-color: #f5f5f5
|
||||
border-color: #dbdbdb
|
||||
|
||||
// OPTIONS
|
||||
|
||||
select[size="1"], select:not([size])
|
||||
appearance: menulist
|
||||
|
||||
select,
|
||||
option
|
||||
font-size: 1rem
|
||||
line-height: 1.5
|
||||
padding: 4px 13px
|
||||
border: 1px solid #dbdbdb
|
||||
border-radius: 2px
|
||||
outline: 0
|
||||
color: #363636
|
||||
min-width: 250px
|
||||
width: auto
|
||||
background-color: #f3f3f3
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05)
|
||||
|
||||
@media (max-width: 425px)
|
||||
select, option
|
||||
width: 100%
|
||||
|
||||
// FILE INPUT
|
||||
.file-input
|
||||
display: none
|
||||
|
||||
.file-input__label
|
||||
cursor: pointer
|
||||
display: inline-block
|
||||
background-color: var(--color-primary)
|
||||
color: white
|
||||
padding: 10px 17px
|
||||
border-radius: 3px
|
||||
|
||||
.file-input__info
|
||||
font-size: .9rem
|
||||
font-style: italic
|
||||
margin: 10px 0
|
||||
color: var(--color-fontsec)
|
||||
|
||||
.file-input__list
|
||||
margin-left: 40px
|
||||
margin-top: 10px
|
||||
font-weight: 600
|
||||
|
||||
// PREVIOUSLY UPLOADED FILES
|
||||
|
||||
.file-uploads-label
|
||||
margin-bottom: 10px
|
||||
|
||||
.file-container
|
||||
display: flex
|
||||
align-items: center
|
||||
margin-bottom: 10px
|
||||
|
||||
.checkbox
|
||||
margin-left: 12px
|
||||
@ -1,253 +0,0 @@
|
||||
/* GENERAL STYLES FOR FORMS */
|
||||
|
||||
/* FORM GROUPS */
|
||||
.form-section-title {
|
||||
color: var(--color-fontsec);
|
||||
margin: 0;
|
||||
|
||||
+ .form-group {
|
||||
margin-top: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-gap: 5px;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
|
||||
+ .form-group, + .form-section-legend, + .form-section-notification {
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
||||
+ .form-section-title {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-section-legend {
|
||||
color: var(--color-fontsec);
|
||||
margin: 7px 0;
|
||||
}
|
||||
|
||||
.form-group__hint, .form-section-title__hint {
|
||||
color: var(--color-fontsec);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-section-title__hint {
|
||||
margin-top: 7px;
|
||||
|
||||
+ .form-group {
|
||||
margin-top: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group-label {
|
||||
font-weight: 600;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.form-group-label__hint {
|
||||
margin-top: 7px;
|
||||
color: var(--color-fontsec);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.form-group--required .form-group-label__caption::after, .form-group__required-marker::before {
|
||||
content: ' *';
|
||||
color: var(--color-error);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-group--submit .form-group__input {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-group--submit .form-group__input {
|
||||
grid-column: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group--has-error {
|
||||
background-color: rgba(255, 0, 0, 0.1);
|
||||
|
||||
input, textarea {
|
||||
border-color: var(--color-error) !important;
|
||||
}
|
||||
|
||||
.form-error {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.form-error {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-group {
|
||||
grid-template-columns: 1fr;
|
||||
align-items: baseline;
|
||||
margin-top: 17px;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
/* TEXT INPUTS */
|
||||
input[type='text'],
|
||||
input[type='search'],
|
||||
input[type='password'],
|
||||
input[type='url'],
|
||||
input[type='number'],
|
||||
input[type='email'],
|
||||
input[type*='date'],
|
||||
input[type*='time'],
|
||||
select {
|
||||
/* from bulma.css */
|
||||
color: #363636;
|
||||
border-color: #dbdbdb;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50,50,50,.05);
|
||||
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
align-items: center;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
font-size: 1rem;
|
||||
font-family: var(--font-base);
|
||||
line-height: 1.5;
|
||||
padding: 4px 13px;
|
||||
}
|
||||
|
||||
input[type='number'] {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
input[type*='date'],
|
||||
input[type*='time'],
|
||||
.flatpickr-input[type='text'] {
|
||||
width: 50%;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
/* BUTTON STYLE SEE default-layout.lucius */
|
||||
|
||||
/* TEXTAREAS */
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 170px;
|
||||
max-width: 600px;
|
||||
line-height: 1.5;
|
||||
color: #363636;
|
||||
background-color: #f3f3f3;
|
||||
padding: 4px 13px;
|
||||
font-size: 1rem;
|
||||
font-family: var(--font-base);
|
||||
appearance: none;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50,50,50,.05);
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* SHARED STATE RELATED STYLES */
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
&:focus {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0 0.125em rgba(50,115,220,.25);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
background-color: #f3f3f3;
|
||||
color: #7a7a7a;
|
||||
box-shadow: none;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
|
||||
&[readonly] {
|
||||
background-color: #f5f5f5;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
}
|
||||
|
||||
/* OPTIONS */
|
||||
|
||||
select[size = "1"], select:not([size]) {
|
||||
appearance: menulist;
|
||||
}
|
||||
|
||||
select,
|
||||
option {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
padding: 4px 13px;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 2px;
|
||||
outline: 0;
|
||||
color: #363636;
|
||||
min-width: 250px;
|
||||
width: auto;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50,50,50,.05);
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
|
||||
select, option {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* FILE INPUT */
|
||||
.file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-input__label {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background-color: var(--color-primary);
|
||||
color: white;
|
||||
padding: 10px 17px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.file-input__info {
|
||||
font-size: .9rem;
|
||||
font-style: italic;
|
||||
margin: 10px 0;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
.file-input__list {
|
||||
margin-left: 40px;
|
||||
margin-top: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* PREVIOUSLY UPLOADED FILES */
|
||||
|
||||
.file-uploads-label {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.file-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.checkbox {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
55
frontend/src/utils/inputs/radio.sass
Normal file
55
frontend/src/utils/inputs/radio.sass
Normal file
@ -0,0 +1,55 @@
|
||||
// CUSTOM RADIO BOXES
|
||||
// Completely replaces native radiobox
|
||||
|
||||
.radio-group
|
||||
display: flex
|
||||
|
||||
.radio
|
||||
position: relative
|
||||
display: inline-block
|
||||
|
||||
[type='radio']
|
||||
position: fixed
|
||||
top: -1px
|
||||
left: -1px
|
||||
width: 1px
|
||||
height: 1px
|
||||
overflow: hidden
|
||||
|
||||
label
|
||||
display: block
|
||||
height: 34px
|
||||
min-width: 42px
|
||||
line-height: 34px
|
||||
text-align: center
|
||||
padding: 0 13px
|
||||
background-color: #f3f3f3
|
||||
box-shadow: inset 2px 1px 2px 1px rgba(50, 50, 50, 0.05)
|
||||
color: var(--color-font)
|
||||
cursor: pointer
|
||||
|
||||
\:checked + label
|
||||
background-color: var(--color-primary)
|
||||
color: var(--color-lightwhite)
|
||||
box-shadow: inset -2px -1px 2px 1px rgba(255, 255, 255, 0.15)
|
||||
|
||||
\:focus + label
|
||||
border-color: #3273dc
|
||||
box-shadow: 0 0 0.125em 0 rgba(50, 115, 220, 0.8)
|
||||
outline: 0
|
||||
|
||||
[disabled] + label
|
||||
pointer-events: none
|
||||
border: none
|
||||
opacity: 0.6
|
||||
filter: grayscale(1)
|
||||
|
||||
.radio:first-child
|
||||
label
|
||||
border-top-left-radius: 4px
|
||||
border-bottom-left-radius: 4px
|
||||
|
||||
.radio:last-child
|
||||
label
|
||||
border-top-right-radius: 4px
|
||||
border-bottom-right-radius: 4px
|
||||
@ -1,66 +0,0 @@
|
||||
/* CUSTOM RADIO BOXES */
|
||||
/* Completely replaces native radiobox */
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.radio {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
[type='radio'] {
|
||||
position: fixed;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
height: 34px;
|
||||
min-width: 42px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
padding: 0 13px;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 2px 1px 2px 1px rgba(50, 50, 50, 0.05);
|
||||
color: var(--color-font);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:checked + label {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-lightwhite);
|
||||
box-shadow: inset -2px -1px 2px 1px rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
:focus + label {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0.125em 0 rgba(50,115,220,0.8);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
[disabled] + label {
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
opacity: 0.6;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.radio:first-child {
|
||||
label {
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.radio:last-child {
|
||||
label {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import './mass-input.scss';
|
||||
import './mass-input.sass';
|
||||
|
||||
const MASS_INPUT_CELL_SELECTOR = '.massinput__cell';
|
||||
const MASS_INPUT_ADD_CELL_SELECTOR = '.massinput__cell--add';
|
||||
|
||||
14
frontend/src/utils/mass-input/mass-input.sass
Normal file
14
frontend/src/utils/mass-input/mass-input.sass
Normal file
@ -0,0 +1,14 @@
|
||||
.massinput-list__wrapper, .massinput-list__cell
|
||||
display: grid
|
||||
grid: auto / auto 50px
|
||||
max-width: 600px
|
||||
grid-gap: 7px
|
||||
|
||||
.massinput-list__field
|
||||
grid-column: 1
|
||||
|
||||
.massinput-list__add, .massinput-list__delete
|
||||
grid-column: 2
|
||||
|
||||
.massinput-list__cell
|
||||
grid-column: 1 / 3
|
||||
@ -1,18 +0,0 @@
|
||||
.massinput-list__wrapper, .massinput-list__cell {
|
||||
display: grid;
|
||||
grid: auto / auto 50px;
|
||||
max-width: 600px;
|
||||
grid-gap: 7px;
|
||||
}
|
||||
|
||||
.massinput-list__field {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.massinput-list__add, .massinput-list__delete {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.massinput-list__cell {
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './modal.scss';
|
||||
import './modal.sass';
|
||||
|
||||
const MODAL_HEADERS = {
|
||||
'Is-Modal': 'True',
|
||||
|
||||
103
frontend/src/utils/modal/modal.sass
Normal file
103
frontend/src/utils/modal/modal.sass
Normal file
@ -0,0 +1,103 @@
|
||||
@use "../../common" as *
|
||||
|
||||
.modals-wrapper
|
||||
position: fixed
|
||||
left: 0
|
||||
top: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
z-index: -1
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
&.modals-wrapper--open
|
||||
z-index: 200
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.modal
|
||||
position: relative
|
||||
display: none
|
||||
background-color: rgba(255, 255, 255, 1)
|
||||
min-width: 60vw
|
||||
max-width: 70vw
|
||||
min-height: 100px
|
||||
max-height: calc(100vh - 30px)
|
||||
border-radius: 2px
|
||||
z-index: -1
|
||||
color: var(--color-font)
|
||||
overflow: auto
|
||||
overscroll-behavior: contain
|
||||
pointer-events: none
|
||||
opacity: 0
|
||||
|
||||
&.modal--open
|
||||
display: flex
|
||||
opacity: 1
|
||||
pointer-events: auto
|
||||
z-index: 200
|
||||
transition: opacity .2s .1s ease-in-out, transform .3s ease-in-out
|
||||
|
||||
@media (max-width: 1024px)
|
||||
.modal
|
||||
min-width: 80vw
|
||||
|
||||
@media (max-width: 768px)
|
||||
.modal
|
||||
min-width: 90vw
|
||||
|
||||
@media (max-width: 425px)
|
||||
.modal
|
||||
min-width: calc(100vw - 20px)
|
||||
|
||||
.modal__overlay
|
||||
position: fixed
|
||||
left: 0
|
||||
top: 0
|
||||
height: 100%
|
||||
width: 100%
|
||||
background-color: transparent
|
||||
z-index: -1
|
||||
transition: all .2s ease
|
||||
display: none
|
||||
|
||||
&.modal__overlay--open
|
||||
display: block
|
||||
z-index: 199
|
||||
opacity: 1
|
||||
background-color: rgba(0, 0, 0, 0.4)
|
||||
|
||||
.modal__trigger
|
||||
cursor: pointer
|
||||
|
||||
div.modal__trigger
|
||||
display: inline-block
|
||||
|
||||
.modal__trigger-label
|
||||
font-style: italic
|
||||
text-decoration: underline
|
||||
|
||||
.modal__closer
|
||||
position: absolute
|
||||
top: 20px
|
||||
right: 20px
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 30px
|
||||
height: 30px
|
||||
background-color: var(--color-darker)
|
||||
border-radius: 2px
|
||||
cursor: pointer
|
||||
z-index: 20
|
||||
|
||||
&::before
|
||||
@extend .fas
|
||||
|
||||
content: fa-content($fa-var-times)
|
||||
color: white
|
||||
|
||||
.modal__content
|
||||
margin: 20px 40px
|
||||
width: 100%
|
||||
@ -1,118 +0,0 @@
|
||||
.modals-wrapper {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.modals-wrapper--open {
|
||||
z-index: 200;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: relative;
|
||||
display: none;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
min-width: 60vw;
|
||||
max-width: 70vw;
|
||||
min-height: 100px;
|
||||
max-height: calc(100vh - 30px);
|
||||
border-radius: 2px;
|
||||
z-index: -1;
|
||||
color: var(--color-font);
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
|
||||
&.modal--open {
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
z-index: 200;
|
||||
transition:
|
||||
opacity .2s .1s ease-in-out,
|
||||
transform .3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.modal {
|
||||
min-width: 80vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.modal {
|
||||
min-width: 90vw;
|
||||
}
|
||||
}
|
||||
@media (max-width: 425px) {
|
||||
.modal {
|
||||
min-width: calc(100vw - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
.modal__overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
z-index: -1;
|
||||
transition: all .2s ease;
|
||||
display: none;
|
||||
|
||||
&.modal__overlay--open {
|
||||
display: block;
|
||||
z-index: 199;
|
||||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.modal__trigger {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modal__trigger {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.modal__trigger-label {
|
||||
font-style: italic;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.modal__closer {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: var(--color-darker);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
z-index: 20;
|
||||
|
||||
&::before {
|
||||
content: '\f00d';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.modal__content {
|
||||
margin: 20px 40px;
|
||||
width: 100%;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './navbar.scss';
|
||||
import './navbar.sass';
|
||||
|
||||
|
||||
export const LANGUAGE_SELECT_UTIL_SELECTOR = '[uw-language-select]';
|
||||
|
||||
228
frontend/src/utils/navbar/navbar.sass
Normal file
228
frontend/src/utils/navbar/navbar.sass
Normal file
@ -0,0 +1,228 @@
|
||||
.navbar-container
|
||||
position: relative
|
||||
|
||||
.navbar-shadow
|
||||
position: fixed
|
||||
right: 0
|
||||
top: 0
|
||||
height: var(--header-height-collapsed)
|
||||
width: 20px
|
||||
z-index: 50
|
||||
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.4), transparent)
|
||||
transition: height 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
|
||||
@media (min-width: 768px)
|
||||
.navbar-shadow
|
||||
height: var(--header-height)
|
||||
|
||||
@media (min-width: 1025px)
|
||||
.navbar-shadow
|
||||
display: none
|
||||
|
||||
.navbar
|
||||
position: fixed
|
||||
display: flex
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
justify-content: flex-start
|
||||
right: 0
|
||||
top: 0
|
||||
left: var(--asidenav-width-xl)
|
||||
height: var(--header-height)
|
||||
background-color: var(--color-primary)
|
||||
color: white
|
||||
z-index: 20
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2)
|
||||
overflow: auto
|
||||
transition: all 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
|
||||
@media (max-width: 1199px)
|
||||
.navbar
|
||||
left: var(--asidenav-width-lg)
|
||||
|
||||
@media (max-width: 768px)
|
||||
.navbar
|
||||
left: 0
|
||||
|
||||
// links
|
||||
.navbar__link-wrapper
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
align-items: center
|
||||
height: 80px
|
||||
min-width: 90px
|
||||
color: var(--color-lightwhite)
|
||||
transition: height 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
overflow: hidden
|
||||
cursor: pointer
|
||||
|
||||
.navbar__link-icon
|
||||
opacity: 0.7
|
||||
transition: opacity 0.2s ease
|
||||
margin-bottom: 7px
|
||||
|
||||
.navbar__link-label
|
||||
transition: opacity .2s ease
|
||||
padding: 2px 4px
|
||||
text-transform: uppercase
|
||||
font-weight: 600
|
||||
|
||||
@media (min-width: 769px)
|
||||
.navbar__link-wrapper
|
||||
border: 1px solid rgba(255, 255, 255, 0.7)
|
||||
|
||||
@media (max-width: 768px)
|
||||
.navbar__link-wrapper
|
||||
box-shadow: none
|
||||
min-width: 0
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.navbar__link-label
|
||||
padding: 0 7px
|
||||
|
||||
.navbar__link-icon
|
||||
transform: scale(0.65)
|
||||
margin-bottom: 0
|
||||
|
||||
// navbar list
|
||||
.navbar__list
|
||||
white-space: nowrap
|
||||
|
||||
+ .navbar__list
|
||||
margin-left: 12px
|
||||
|
||||
@media (min-width: 769px)
|
||||
.navbar__list:last-of-type
|
||||
padding-right: 40px
|
||||
|
||||
@media (max-width: 768px)
|
||||
.navbar__list
|
||||
+ .navbar__list
|
||||
margin-left: 0
|
||||
padding-right: 40px
|
||||
|
||||
// list item
|
||||
.navbar__list-item
|
||||
position: relative
|
||||
transition: background-color .1s ease
|
||||
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item--lang-wrapper
|
||||
margin-left: 12px
|
||||
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item
|
||||
margin-left: 12px
|
||||
|
||||
@media (max-width: 500px)
|
||||
.navbar__list-item
|
||||
min-width: 60px
|
||||
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item
|
||||
margin-left: 0
|
||||
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item--lang-wrapper
|
||||
margin-left: 0
|
||||
|
||||
.navbar__list-left
|
||||
flex: 5
|
||||
padding-left: 40px
|
||||
|
||||
@media (max-width: 768px)
|
||||
.navbar__list-left
|
||||
padding-left: 0
|
||||
|
||||
// "Favorites" list item, only visible on small screens and logged in
|
||||
.navbar__list-item
|
||||
&.navbar__list-item--favorite
|
||||
display: none
|
||||
|
||||
.navbar__list-item--favorite
|
||||
display: none
|
||||
background-color: var(--color-primary)
|
||||
|
||||
.logged-in
|
||||
.navbar__list
|
||||
li.navbar__list-item--favorite,
|
||||
.navbar__list-item--favorite
|
||||
display: inline-block
|
||||
|
||||
@media (min-width: 426px)
|
||||
.logged-in
|
||||
.navbar__list
|
||||
.navbar__list-item--favorite
|
||||
display: none !important
|
||||
|
||||
.navbar__list-item--active
|
||||
background-color: var(--color-lightwhite)
|
||||
color: var(--color-dark)
|
||||
|
||||
.navbar__link-wrapper
|
||||
color: var(--color-dark)
|
||||
|
||||
.navbar__list-item--active .navbar__link-wrapper
|
||||
color: var(--color-dark)
|
||||
|
||||
.navbar .navbar__list-item:not(.navbar__list-item--active):not(.navbar__list-item--favorite):hover .navbar__link-wrapper, #lang-checkbox:checked ~ * .navbar__link-wrapper
|
||||
background-color: var(--color-dark)
|
||||
color: var(--color-lightwhite)
|
||||
|
||||
.navbar__link-icon
|
||||
opacity: 1
|
||||
|
||||
// sticky state
|
||||
.navbar--sticky
|
||||
height: var(--header-height-collapsed)
|
||||
z-index: 100
|
||||
|
||||
.navbar__link-wrapper
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
.navbar__pushdown
|
||||
height: var(--header-height)
|
||||
transition: height 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
|
||||
.navbar--sticky + .navbar__pushdown
|
||||
display: block
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
@media (max-width: 768px)
|
||||
.navbar,
|
||||
.navbar__pushdown
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
.navbar__link-wrapper
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
@media (max-height: 500px)
|
||||
.navbar,
|
||||
.navbar__pushdown
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
.navbar__link-wrapper
|
||||
height: var(--header-height-collapsed)
|
||||
|
||||
#lang-dropdown
|
||||
display: none
|
||||
position: fixed
|
||||
top: var(--header-height)
|
||||
right: 0
|
||||
min-width: 200px
|
||||
z-index: 10
|
||||
background-color: white
|
||||
border-radius: 2px
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3)
|
||||
|
||||
select
|
||||
display: block
|
||||
|
||||
button
|
||||
display: block
|
||||
width: 100%
|
||||
|
||||
#lang-checkbox:checked ~ #lang-dropdown
|
||||
display: block
|
||||
|
||||
@media (max-width: 768px)
|
||||
#lang-dropdown
|
||||
top: var(--header-height-collapsed)
|
||||
@ -1,305 +0,0 @@
|
||||
.navbar-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navbar-shadow {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: var(--header-height-collapsed);
|
||||
width: 20px;
|
||||
z-index: 50;
|
||||
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.4), transparent);
|
||||
transition: height .2s cubic-bezier(0.03, 0.43, 0.58, 1);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.navbar-shadow {
|
||||
height: var(--header-height);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1025px) {
|
||||
|
||||
.navbar-shadow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
right: 0;
|
||||
top: 0;
|
||||
left: var(--asidenav-width-xl);
|
||||
height: var(--header-height);
|
||||
background-color: var(--color-primary);
|
||||
color: white;
|
||||
z-index: 20;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
|
||||
overflow: auto;
|
||||
transition: all .2s cubic-bezier(0.03, 0.43, 0.58, 1);
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
.navbar {
|
||||
left: var(--asidenav-width-lg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.navbar {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* links */
|
||||
.navbar__link-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 80px;
|
||||
min-width: 90px;
|
||||
color: var(--color-lightwhite);
|
||||
transition: height .2s cubic-bezier(0.03, 0.43, 0.58, 1);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navbar__link-icon {
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s ease;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.navbar__link-label {
|
||||
transition: opacity .2s ease;
|
||||
padding: 2px 4px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
|
||||
.navbar__link-wrapper {
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.navbar__link-wrapper {
|
||||
box-shadow: none;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.navbar__link-label {
|
||||
padding: 0 7px;
|
||||
}
|
||||
|
||||
.navbar__link-icon {
|
||||
transform: scale(0.65);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* navbar list */
|
||||
.navbar__list {
|
||||
white-space: nowrap;
|
||||
|
||||
+ .navbar__list {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
|
||||
.navbar__list:last-of-type {
|
||||
padding-right: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.navbar__list {
|
||||
+ .navbar__list {
|
||||
margin-left: 0;
|
||||
padding-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* list item */
|
||||
.navbar__list-item {
|
||||
position: relative;
|
||||
transition: background-color .1s ease;
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item--lang-wrapper {
|
||||
margin-left: 12px;
|
||||
}
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
|
||||
.navbar__list-item {
|
||||
min-width: 60px;
|
||||
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item {
|
||||
margin-left: 0;
|
||||
}
|
||||
&:not(.navbar__list-item--favorite) + .navbar__list-item--lang-wrapper {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar__list-left {
|
||||
flex: 5;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.navbar__list-left {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* "Favorites" list item, only visible on small screens and logged in */
|
||||
.navbar__list-item {
|
||||
&.navbar__list-item--favorite {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.navbar__list-item--favorite {
|
||||
display: none;
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.logged-in {
|
||||
.navbar__list {
|
||||
li.navbar__list-item--favorite,
|
||||
.navbar__list-item--favorite {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 426px) {
|
||||
|
||||
.logged-in {
|
||||
.navbar__list {
|
||||
.navbar__list-item--favorite {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar__list-item--active {
|
||||
background-color: var(--color-lightwhite);
|
||||
color: var(--color-dark);
|
||||
|
||||
.navbar__link-wrapper {
|
||||
color: var(--color-dark);
|
||||
}
|
||||
}
|
||||
|
||||
.navbar__list-item--active .navbar__link-wrapper {
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
.navbar .navbar__list-item:not(.navbar__list-item--active):not(.navbar__list-item--favorite):hover .navbar__link-wrapper, #lang-checkbox:checked ~ * .navbar__link-wrapper {
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-lightwhite);
|
||||
|
||||
.navbar__link-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* sticky state */
|
||||
.navbar--sticky {
|
||||
height: var(--header-height-collapsed);
|
||||
z-index: 100;
|
||||
|
||||
.navbar__link-wrapper {
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
.navbar__pushdown {
|
||||
height: var(--header-height);
|
||||
transition: height .2s cubic-bezier(0.03, 0.43, 0.58, 1);
|
||||
}
|
||||
|
||||
.navbar--sticky + .navbar__pushdown {
|
||||
display: block;
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.navbar,
|
||||
.navbar__pushdown {
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
|
||||
.navbar__link-wrapper {
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 500px) {
|
||||
|
||||
.navbar,
|
||||
.navbar__pushdown {
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
|
||||
.navbar__link-wrapper {
|
||||
height: var(--header-height-collapsed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#lang-dropdown {
|
||||
display: none;
|
||||
|
||||
position: fixed;
|
||||
top: var(--header-height);
|
||||
right: 0;
|
||||
min-width: 200px;
|
||||
z-index: 10;
|
||||
background-color: white;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.3);
|
||||
|
||||
select {
|
||||
display: block;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#lang-checkbox:checked ~ #lang-dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#lang-dropdown {
|
||||
top: var(--header-height-collapsed);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './show-hide.scss';
|
||||
import { StorageManager, LOCATION } from '../../lib/storage-manager/storage-manager';
|
||||
import './show-hide.sass';
|
||||
|
||||
const SHOW_HIDE_LOCAL_STORAGE_KEY = 'SHOW_HIDE';
|
||||
const SHOW_HIDE_INITIALIZED_CLASS = 'show-hide--initialized';
|
||||
@ -15,6 +16,8 @@ export class ShowHide {
|
||||
_showHideId;
|
||||
_element;
|
||||
|
||||
_storageManager = new StorageManager(SHOW_HIDE_LOCAL_STORAGE_KEY, '1.0.0', { location: LOCATION.LOCAL });
|
||||
|
||||
constructor(element) {
|
||||
if (!element) {
|
||||
throw new Error('ShowHide utility cannot be setup without an element!');
|
||||
@ -41,9 +44,9 @@ export class ShowHide {
|
||||
}
|
||||
|
||||
if (this._showHideId) {
|
||||
let localStorageCollapsed = this._getLocalStorage()[this._showHideId];
|
||||
if (typeof localStorageCollapsed !== 'undefined') {
|
||||
collapsed = localStorageCollapsed;
|
||||
let storageCollapsed = this._storageManager.load(this._showHideId);
|
||||
if (typeof storageCollapsed !== 'undefined') {
|
||||
collapsed = storageCollapsed;
|
||||
}
|
||||
}
|
||||
this._element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, collapsed);
|
||||
@ -70,18 +73,7 @@ export class ShowHide {
|
||||
const newState = this._element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS);
|
||||
|
||||
if (this._showHideId) {
|
||||
this._setLocalStorage(this._showHideId, newState);
|
||||
this._storageManager.save(this._showHideId, newState);
|
||||
}
|
||||
}
|
||||
|
||||
// maybe move these to a LocalStorageHelper?
|
||||
_setLocalStorage(id, state) {
|
||||
const lsData = this._getLocalStorage();
|
||||
lsData[id] = state;
|
||||
window.localStorage.setItem(SHOW_HIDE_LOCAL_STORAGE_KEY, JSON.stringify(lsData));
|
||||
}
|
||||
|
||||
_getLocalStorage() {
|
||||
return JSON.parse(window.localStorage.getItem(SHOW_HIDE_LOCAL_STORAGE_KEY)) || {};
|
||||
}
|
||||
}
|
||||
|
||||
44
frontend/src/utils/show-hide/show-hide.sass
Normal file
44
frontend/src/utils/show-hide/show-hide.sass
Normal file
@ -0,0 +1,44 @@
|
||||
$show-hide-toggle-size: 6px
|
||||
|
||||
.show-hide__toggle
|
||||
position: relative
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-lighter)
|
||||
cursor: pointer
|
||||
|
||||
.show-hide__toggle::before
|
||||
content: ''
|
||||
position: absolute
|
||||
width: $show-hide-toggle-size
|
||||
height: $show-hide-toggle-size
|
||||
left: -15px
|
||||
top: 50%
|
||||
color: var(--color-primary)
|
||||
border-right: 2px solid currentColor
|
||||
border-top: 2px solid currentColor
|
||||
transition: transform .2s ease
|
||||
transform: translateY(-50%) rotate(-45deg)
|
||||
|
||||
@media (max-width: 768px)
|
||||
left: auto
|
||||
right: 20px
|
||||
color: var(--color-font)
|
||||
|
||||
.show-hide__toggle--right::before
|
||||
left: auto
|
||||
right: 20px
|
||||
color: var(--color-font)
|
||||
|
||||
.show-hide--collapsed
|
||||
.show-hide__toggle::before
|
||||
transform: translateY(-50%) rotate(135deg)
|
||||
|
||||
& > :not(.show-hide__toggle)
|
||||
display: block
|
||||
height: 0
|
||||
margin: 0
|
||||
padding: 0
|
||||
max-height: 0
|
||||
overflow-y: hidden
|
||||
@ -1,54 +0,0 @@
|
||||
$show-hide-toggle-size: 6px;
|
||||
|
||||
.show-hide__toggle {
|
||||
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-grey-lighter);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.show-hide__toggle::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: $show-hide-toggle-size;
|
||||
height: $show-hide-toggle-size;
|
||||
left: -15px;
|
||||
top: 50%;
|
||||
color: var(--color-primary);
|
||||
border-right: 2px solid currentColor;
|
||||
border-top: 2px solid currentColor;
|
||||
transition: transform .2s ease;
|
||||
transform: translateY(-50%) rotate(-45deg);
|
||||
|
||||
@media (max-width: 768px) {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
|
||||
.show-hide__toggle--right::before {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
||||
.show-hide--collapsed {
|
||||
|
||||
.show-hide__toggle::before {
|
||||
transform: translateY(-50%) rotate(135deg);
|
||||
}
|
||||
|
||||
:not(.show-hide__toggle) {
|
||||
display: block;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-height: 0;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import './tabber.scss';
|
||||
import './tabber.sass';
|
||||
|
||||
(function($) {
|
||||
|
||||
|
||||
35
frontend/src/utils/tabber/tabber.sass
Normal file
35
frontend/src/utils/tabber/tabber.sass
Normal file
@ -0,0 +1,35 @@
|
||||
.tab-group
|
||||
border-top: 2px solid #dcdcdc
|
||||
padding-top: 30px
|
||||
|
||||
.tab-group-openers
|
||||
display: flex
|
||||
justify-content: stretch
|
||||
line-height: 40px
|
||||
font-size: 14px
|
||||
margin-bottom: 40px
|
||||
|
||||
.tab-opener
|
||||
display: inline-block
|
||||
flex: 1
|
||||
text-align: center
|
||||
padding: 0 13px
|
||||
margin: 0 2px
|
||||
background-color: var(--color-dark)
|
||||
color: white
|
||||
font-size: 16px
|
||||
text-transform: uppercase
|
||||
font-weight: 600
|
||||
transition: all .1s ease
|
||||
border-bottom: 5px solid rgba(100, 100, 100, 0.2)
|
||||
|
||||
.tab-opener:not(.tab-visible):hover
|
||||
cursor: pointer
|
||||
background-color: transparent
|
||||
color: rgb(52, 48, 58)
|
||||
border-bottom-color: grey
|
||||
|
||||
.tab-opener.tab-visible
|
||||
background-color: transparent
|
||||
color: rgb(52, 48, 58)
|
||||
border-bottom-color: var(--color-primary)
|
||||
@ -1,39 +0,0 @@
|
||||
.tab-group {
|
||||
border-top: 2px solid #dcdcdc;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.tab-group-openers {
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.tab-opener {
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 0 13px;
|
||||
margin: 0 2px;
|
||||
background-color: var(--color-dark);
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
transition: all .1s ease;
|
||||
border-bottom: 5px solid rgba(100, 100, 100, 0.2);
|
||||
}
|
||||
.tab-opener:not(.tab-visible):hover {
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
color: rgb(52, 48, 58);
|
||||
border-bottom-color: grey;
|
||||
}
|
||||
|
||||
.tab-opener.tab-visible {
|
||||
background-color: transparent;
|
||||
color: rgb(52, 48, 58);
|
||||
border-bottom-color: var(--color-primary);
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './tooltips.scss';
|
||||
import './tooltips.sass';
|
||||
|
||||
// empty 'shell' to be able to load styles
|
||||
@Utility({
|
||||
|
||||
92
frontend/src/utils/tooltips/tooltips.sass
Normal file
92
frontend/src/utils/tooltips/tooltips.sass
Normal file
@ -0,0 +1,92 @@
|
||||
.tooltip
|
||||
position: relative
|
||||
display: inline-block
|
||||
vertical-align: middle
|
||||
|
||||
&:hover .tooltip__content
|
||||
display: inline-block
|
||||
|
||||
.tooltip__handle
|
||||
color: var(--color-light)
|
||||
height: 1.5rem
|
||||
line-height: 1.5rem
|
||||
font-size: 1.2rem
|
||||
display: inline-block
|
||||
text-align: center
|
||||
margin: 0 10px
|
||||
cursor: default
|
||||
position: relative
|
||||
|
||||
&::before
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
top: 50%
|
||||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
font-size: 15px
|
||||
|
||||
&.tooltip__handle.urgency__success
|
||||
color: var(--color-success)
|
||||
|
||||
&.tooltip__handle.urgency__warning
|
||||
color: var(--color-warning)
|
||||
|
||||
&.tooltip__handle.urgency__error
|
||||
color: var(--color-error)
|
||||
|
||||
&:hover
|
||||
color: var(--color-dark)
|
||||
|
||||
&.tooltip__handle.urgency__success
|
||||
color: var(--color-success-dark)
|
||||
|
||||
&.tooltip__handle.urgency__warning
|
||||
color: var(--color-warning-dark)
|
||||
|
||||
&.tooltip__handle.urgency__error
|
||||
color: var(--color-error-dark)
|
||||
|
||||
.tooltip.tooltip__inline
|
||||
.tooltip__handle
|
||||
height: 1.0rem
|
||||
line-height: 1.0rem
|
||||
font-size: 1.0rem
|
||||
|
||||
.tooltip__content
|
||||
position: absolute
|
||||
display: none
|
||||
top: -10px
|
||||
transform: translateY(-100%)
|
||||
left: 3px
|
||||
width: 275px
|
||||
z-index: 10
|
||||
background-color: #fafafa
|
||||
border-radius: 4px
|
||||
padding: 13px 17px
|
||||
box-shadow: 0 0 20px 4px rgba(0, 0, 0, 0.1)
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
width: 16px
|
||||
height: 16px
|
||||
background-color: #fafafa
|
||||
transform: rotate(45deg)
|
||||
position: absolute
|
||||
left: 10px
|
||||
bottom: -8px
|
||||
|
||||
@media (max-width: 768px)
|
||||
.tooltip
|
||||
display: block
|
||||
margin-top: 10px
|
||||
|
||||
.tooltip__content
|
||||
left: 3px
|
||||
right: 3px
|
||||
width: auto
|
||||
|
||||
// fix font color when used in tableheaders
|
||||
th .tooltip__content
|
||||
color: var(--color-font)
|
||||
font-weight: normal
|
||||
@ -1,109 +0,0 @@
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
&:hover .tooltip__content {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip__handle {
|
||||
color: var(--color-light);
|
||||
height: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
font-size: 1.2rem;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
margin: 0 10px;
|
||||
cursor: default;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
&.tooltip__handle.urgency__success {
|
||||
color: var(--color-success);
|
||||
}
|
||||
&.tooltip__handle.urgency__warning {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
&.tooltip__handle.urgency__error {
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--color-dark);
|
||||
|
||||
&.tooltip__handle.urgency__success {
|
||||
color: var(--color-success-dark);
|
||||
}
|
||||
&.tooltip__handle.urgency__warning {
|
||||
color: var(--color-warning-dark);
|
||||
}
|
||||
&.tooltip__handle.urgency__error {
|
||||
color: var(--color-error-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip.tooltip__inline {
|
||||
.tooltip__handle {
|
||||
height: 1.0rem;
|
||||
line-height: 1.0rem;
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip__content {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: -10px;
|
||||
transform: translateY(-100%);
|
||||
left: 3px;
|
||||
width: 275px;
|
||||
z-index: 10;
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
padding: 13px 17px;
|
||||
box-shadow: 0 0 20px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #fafafa;
|
||||
transform: rotate(45deg);
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
bottom: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.tooltip {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
|
||||
.tooltip__content {
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* fix font color when used in tableheaders */
|
||||
th .tooltip__content {
|
||||
color: var(--color-font);
|
||||
font-weight: normal;
|
||||
}
|
||||
@ -11,6 +11,7 @@ import { Modal } from './modal/modal';
|
||||
import { Tooltip } from './tooltips/tooltips';
|
||||
import { CourseTeaser } from './course-teaser/course-teaser';
|
||||
import { NavbarUtils } from './navbar/navbar';
|
||||
import { HideColumns } from './hide-columns/hide-columns';
|
||||
|
||||
export const Utils = [
|
||||
Alerts,
|
||||
@ -27,4 +28,5 @@ export const Utils = [
|
||||
Tooltip,
|
||||
CourseTeaser,
|
||||
...NavbarUtils,
|
||||
HideColumns,
|
||||
];
|
||||
|
||||
2584
package-lock.json
generated
2584
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -6,7 +6,7 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"start": "run-p frontend:build:watch yesod:start",
|
||||
"start": "npm-run-all frontend:build --parallel \"frontend:build:watch\" \"yesod:start\"",
|
||||
"test": "run-s frontend:test yesod:test",
|
||||
"lint": "run-s frontend:lint yesod:lint",
|
||||
"build": "run-s frontend:build yesod:build",
|
||||
@ -85,11 +85,15 @@
|
||||
"lint-staged": "^8.2.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"mini-css-extract-plugin": "^0.8.0",
|
||||
"node-sass": "^4.13.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"null-loader": "^2.0.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"resolve-url-loader": "^3.1.1",
|
||||
"sass": "^1.23.7",
|
||||
"sass-loader": "^7.3.1",
|
||||
"semver": "^6.3.0",
|
||||
"standard-version": "^6.0.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"terser-webpack-plugin": "^2.2.3",
|
||||
@ -97,14 +101,16 @@
|
||||
"typeface-source-sans-pro": "0.0.75",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-manifest-plugin": "^2.2.0"
|
||||
"webpack-manifest-plugin": "^2.2.0",
|
||||
"webpack-plugin-hash-output": "^3.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"@juggle/resize-observer": "^2.5.0",
|
||||
"core-js": "^3.4.8",
|
||||
"moment": "^2.24.0",
|
||||
"npm": "^6.13.3",
|
||||
"tail.datetime": "git+https://github.com/uni2work/tail.DateTime.git#master",
|
||||
"npm": "^6.13.4",
|
||||
"tail.datetime": "git+ssh://git@gitlab2.rz.ifi.lmu.de/uni2work/tail.DateTime.git#master",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
892
records.json
892
records.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/typeface-roboto/index.css": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/app.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -12,7 +12,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/typeface-source-sans-pro/index.css": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/alerts/alerts.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -25,276 +25,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/@fortawesome/fontawesome-pro/css/all.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/async-form/async-form.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/asidenav/asidenav.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/show-hide/show-hide.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/inputs/inputs.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/inputs/radio.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/form/form.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/alerts/alerts.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/tooltips/tooltips.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/course-teaser/course-teaser.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/modal/modal.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/navbar/navbar.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/async-table/async-table.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/async-table/async-table-filter.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/mass-input/mass-input.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/inputs/file-input.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!node_modules/sass-loader/dist/cjs.js!frontend/src/utils/inputs/checkbox.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js!node_modules/postcss-loader/src/index.js!frontend/src/utils/form/datepicker.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
},
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/typeface-source-sans-pro/index.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/typeface-roboto/index.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/@fortawesome/fontawesome-pro/css/all.css": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-form/async-form.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -320,7 +51,20 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-form/async-form.scss": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-table/async-table-filter.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-table/async-table.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -385,71 +129,6 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/tooltips/tooltips.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/course-teaser/course-teaser.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/modal/modal.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-table/async-table.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/async-table/async-table-filter.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/mass-input/mass-input.scss": [
|
||||
{
|
||||
"modules": {
|
||||
@ -463,7 +142,7 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/alerts/alerts.scss": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/hide-columns/hide-columns.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -489,7 +168,33 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!frontend/src/utils/form/datepicker.css": [
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/course-teaser/course-teaser.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/tooltips/tooltips.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/sass-loader/dist/cjs.js??ref--6-3!frontend/src/utils/modal/modal.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
@ -527,5 +232,512 @@
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!frontend/src/utils/form/datepicker.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"modules": {
|
||||
"byIdentifier": {
|
||||
"multi frontend/src/polyfill.js frontend/src/main.js": 0
|
||||
},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
},
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/app.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/alerts/alerts.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/asidenav/asidenav.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/show-hide/show-hide.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-form/async-form.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-table/async-table-filter.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-table/async-table.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/form/form.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/inputs.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/radio.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/mass-input/mass-input.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/hide-columns/hide-columns.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/navbar/navbar.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/tooltips/tooltips.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/course-teaser/course-teaser.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/modal/modal.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/file-input.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/checkbox.scss": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--5-1!node_modules/postcss-loader/src/index.js??ref--5-2!node_modules/resolve-url-loader/index.js??ref--5-3!frontend/src/utils/form/datepicker.css": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/app.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-form/async-form.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/alerts/alerts.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/asidenav/asidenav.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/form/form.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/hide-columns/hide-columns.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/navbar/navbar.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/course-teaser/course-teaser.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/modal/modal.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/tooltips/tooltips.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/mass-input/mass-input.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/radio.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/inputs.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/show-hide/show-hide.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-table/async-table.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/async-table/async-table-filter.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/file-input.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/inputs/checkbox.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -19,10 +19,12 @@ let
|
||||
'';
|
||||
|
||||
override = oldAttrs: {
|
||||
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ (with pkgs; [ nodejs-12_x postgresql openldap ]) ++ (with haskellPackages; [ stack yesod-bin hlint cabal-install ]);
|
||||
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ (with pkgs; [ nodejs-12_x postgresql openldap google-chrome ]) ++ (with haskellPackages; [ stack yesod-bin hlint cabal-install ]);
|
||||
shellHook = ''
|
||||
export PROMPT_INFO="${oldAttrs.name}"
|
||||
|
||||
export CHROME_BIN=$(which google-chrome-stable)
|
||||
|
||||
if [[ -z "$PGHOST" ]]; then
|
||||
set -xe
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ import Handler.Utils.SchoolLdap
|
||||
import Handler.Utils.ExamOffice.Exam
|
||||
import Handler.Utils.ExamOffice.Course
|
||||
import Handler.Utils.Profile
|
||||
import Handler.Utils.Routes
|
||||
import Utils.Form
|
||||
import Utils.Sheet
|
||||
import Utils.SystemMessage
|
||||
@ -96,86 +97,12 @@ import qualified Ldap.Client as Ldap
|
||||
|
||||
import UnliftIO.Pool
|
||||
|
||||
|
||||
-- This is where we define all of the routes in our application. For a full
|
||||
-- explanation of the syntax, please see:
|
||||
-- http://www.yesodweb.com/book/routing-and-handlers
|
||||
--
|
||||
-- Note that this is really half the story; in Application.hs, mkYesodDispatch
|
||||
-- generates the rest of the code. Please see the following documentation
|
||||
-- for an explanation for this split:
|
||||
-- http://www.yesodweb.com/book/scaffolding-and-the-site-template#scaffolding-and-the-site-template_foundation_and_application_modules
|
||||
--
|
||||
-- This function also generates the following type synonyms:
|
||||
-- type Handler x = HandlerT UniWorX IO x
|
||||
-- type Widget = WidgetT UniWorX IO ()
|
||||
mkYesodData "UniWorX" uniworxRoutes
|
||||
|
||||
deriving instance Generic CourseR
|
||||
deriving instance Generic SheetR
|
||||
deriving instance Generic SubmissionR
|
||||
deriving instance Generic MaterialR
|
||||
deriving instance Generic TutorialR
|
||||
deriving instance Generic ExamR
|
||||
deriving instance Generic CourseApplicationR
|
||||
deriving instance Generic AllocationR
|
||||
deriving instance Generic SchoolR
|
||||
deriving instance Generic ExamOfficeR
|
||||
deriving instance Generic CourseNewsR
|
||||
deriving instance Generic CourseEventR
|
||||
deriving instance Generic (Route UniWorX)
|
||||
|
||||
data RouteChildren
|
||||
type instance Children RouteChildren a = ChildrenRouteChildren a
|
||||
type family ChildrenRouteChildren a where
|
||||
ChildrenRouteChildren (Route EmbeddedStatic) = '[]
|
||||
ChildrenRouteChildren (Route Auth) = '[]
|
||||
ChildrenRouteChildren UUID = '[]
|
||||
ChildrenRouteChildren (Key a) = '[]
|
||||
ChildrenRouteChildren (CI a) = '[]
|
||||
|
||||
ChildrenRouteChildren a = Children ChGeneric a
|
||||
|
||||
-- | Convenient Type Synonyms:
|
||||
type DB = YesodDB UniWorX
|
||||
type Form x = Html -> MForm (HandlerFor UniWorX) (FormResult x, Widget)
|
||||
type MsgRenderer = MsgRendererS UniWorX -- see Utils
|
||||
type MailM a = MailT (HandlerFor UniWorX) a
|
||||
|
||||
-- Pattern Synonyms for convenience
|
||||
pattern CSheetR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> SheetR -> Route UniWorX
|
||||
pattern CSheetR tid ssh csh shn ptn
|
||||
= CourseR tid ssh csh (SheetR shn ptn)
|
||||
|
||||
pattern CMaterialR :: TermId -> SchoolId -> CourseShorthand -> MaterialName -> MaterialR -> Route UniWorX
|
||||
pattern CMaterialR tid ssh csh mnm ptn
|
||||
= CourseR tid ssh csh (MaterialR mnm ptn)
|
||||
|
||||
pattern CTutorialR :: TermId -> SchoolId -> CourseShorthand -> TutorialName -> TutorialR -> Route UniWorX
|
||||
pattern CTutorialR tid ssh csh tnm ptn
|
||||
= CourseR tid ssh csh (TutorialR tnm ptn)
|
||||
|
||||
pattern CExamR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> ExamR -> Route UniWorX
|
||||
pattern CExamR tid ssh csh tnm ptn
|
||||
= CourseR tid ssh csh (ExamR tnm ptn)
|
||||
|
||||
pattern CSubmissionR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> CryptoFileNameSubmission -> SubmissionR -> Route UniWorX
|
||||
pattern CSubmissionR tid ssh csh shn cid ptn
|
||||
= CSheetR tid ssh csh shn (SubmissionR cid ptn)
|
||||
|
||||
pattern CApplicationR :: TermId -> SchoolId -> CourseShorthand -> CryptoFileNameCourseApplication -> CourseApplicationR -> Route UniWorX
|
||||
pattern CApplicationR tid ssh csh appId ptn
|
||||
= CourseR tid ssh csh (CourseApplicationR appId ptn)
|
||||
|
||||
pattern CNewsR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> CourseNewsR -> Route UniWorX
|
||||
pattern CNewsR tid ssh csh nId ptn
|
||||
= CourseR tid ssh csh (CourseNewsR nId ptn)
|
||||
|
||||
pattern CEventR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseEvent -> CourseEventR -> Route UniWorX
|
||||
pattern CEventR tid ssh csh nId ptn
|
||||
= CourseR tid ssh csh (CourseEventR nId ptn)
|
||||
|
||||
|
||||
-- Requires `rendeRoute`, thus cannot currently be moved to Foundation.I18n
|
||||
instance RenderMessage UniWorX (UnsupportedAuthPredicate AuthTag (Route UniWorX)) where
|
||||
renderMessage f ls (UnsupportedAuthPredicate tag route) = mr . MsgUnsupportedAuthPredicate (mr tag) $ Text.intercalate "/" pieces
|
||||
@ -1486,6 +1413,7 @@ siteLayout' headingOverride widget = do
|
||||
primaryLanguage <- unsafeHead . Text.splitOn "-" <$> selectLanguage appLanguages
|
||||
|
||||
mcurrentRoute <- getCurrentRoute
|
||||
let currentHandler = classifyHandler <$> mcurrentRoute
|
||||
|
||||
-- Get the breadcrumbs, as defined in the YesodBreadcrumbs instance.
|
||||
let
|
||||
|
||||
@ -1,10 +1,84 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||
|
||||
module Foundation.Routes
|
||||
( uniworxRoutes
|
||||
( module Foundation.Routes.Definitions
|
||||
, module Foundation.Routes
|
||||
) where
|
||||
|
||||
import ClassyPrelude.Yesod
|
||||
import Yesod.Routes.TH.Types (ResourceTree)
|
||||
import Import.NoFoundation
|
||||
import Foundation.Type
|
||||
|
||||
import Foundation.Routes.Definitions
|
||||
|
||||
uniworxRoutes :: [ResourceTree String]
|
||||
uniworxRoutes = $(parseRoutesFile "routes")
|
||||
-- This is where we define all of the routes in our application. For a full
|
||||
-- explanation of the syntax, please see:
|
||||
-- http://www.yesodweb.com/book/routing-and-handlers
|
||||
--
|
||||
-- Note that this is really half the story; in Application.hs, mkYesodDispatch
|
||||
-- generates the rest of the code. Please see the following documentation
|
||||
-- for an explanation for this split:
|
||||
-- http://www.yesodweb.com/book/scaffolding-and-the-site-template#scaffolding-and-the-site-template_foundation_and_application_modules
|
||||
--
|
||||
-- This function also generates the following type synonyms:
|
||||
-- type Handler x = HandlerT UniWorX IO x
|
||||
-- type Widget = WidgetT UniWorX IO ()
|
||||
mkYesodData "UniWorX" uniworxRoutes
|
||||
|
||||
deriving instance Generic CourseR
|
||||
deriving instance Generic SheetR
|
||||
deriving instance Generic SubmissionR
|
||||
deriving instance Generic MaterialR
|
||||
deriving instance Generic TutorialR
|
||||
deriving instance Generic ExamR
|
||||
deriving instance Generic CourseApplicationR
|
||||
deriving instance Generic AllocationR
|
||||
deriving instance Generic SchoolR
|
||||
deriving instance Generic ExamOfficeR
|
||||
deriving instance Generic CourseNewsR
|
||||
deriving instance Generic CourseEventR
|
||||
deriving instance Generic (Route UniWorX)
|
||||
|
||||
data RouteChildren
|
||||
type instance Children RouteChildren a = ChildrenRouteChildren a
|
||||
type family ChildrenRouteChildren a where
|
||||
ChildrenRouteChildren (Route EmbeddedStatic) = '[]
|
||||
ChildrenRouteChildren (Route Auth) = '[]
|
||||
ChildrenRouteChildren UUID = '[]
|
||||
ChildrenRouteChildren (Key a) = '[]
|
||||
ChildrenRouteChildren (CI a) = '[]
|
||||
|
||||
ChildrenRouteChildren a = Children ChGeneric a
|
||||
|
||||
-- Pattern Synonyms for convenience
|
||||
pattern CSheetR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> SheetR -> Route UniWorX
|
||||
pattern CSheetR tid ssh csh shn ptn
|
||||
= CourseR tid ssh csh (SheetR shn ptn)
|
||||
|
||||
pattern CMaterialR :: TermId -> SchoolId -> CourseShorthand -> MaterialName -> MaterialR -> Route UniWorX
|
||||
pattern CMaterialR tid ssh csh mnm ptn
|
||||
= CourseR tid ssh csh (MaterialR mnm ptn)
|
||||
|
||||
pattern CTutorialR :: TermId -> SchoolId -> CourseShorthand -> TutorialName -> TutorialR -> Route UniWorX
|
||||
pattern CTutorialR tid ssh csh tnm ptn
|
||||
= CourseR tid ssh csh (TutorialR tnm ptn)
|
||||
|
||||
pattern CExamR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> ExamR -> Route UniWorX
|
||||
pattern CExamR tid ssh csh tnm ptn
|
||||
= CourseR tid ssh csh (ExamR tnm ptn)
|
||||
|
||||
pattern CSubmissionR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> CryptoFileNameSubmission -> SubmissionR -> Route UniWorX
|
||||
pattern CSubmissionR tid ssh csh shn cid ptn
|
||||
= CSheetR tid ssh csh shn (SubmissionR cid ptn)
|
||||
|
||||
pattern CApplicationR :: TermId -> SchoolId -> CourseShorthand -> CryptoFileNameCourseApplication -> CourseApplicationR -> Route UniWorX
|
||||
pattern CApplicationR tid ssh csh appId ptn
|
||||
= CourseR tid ssh csh (CourseApplicationR appId ptn)
|
||||
|
||||
pattern CNewsR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> CourseNewsR -> Route UniWorX
|
||||
pattern CNewsR tid ssh csh nId ptn
|
||||
= CourseR tid ssh csh (CourseNewsR nId ptn)
|
||||
|
||||
pattern CEventR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseEvent -> CourseEventR -> Route UniWorX
|
||||
pattern CEventR tid ssh csh nId ptn
|
||||
= CourseR tid ssh csh (CourseEventR nId ptn)
|
||||
|
||||
10
src/Foundation/Routes/Definitions.hs
Normal file
10
src/Foundation/Routes/Definitions.hs
Normal file
@ -0,0 +1,10 @@
|
||||
module Foundation.Routes.Definitions
|
||||
( uniworxRoutes
|
||||
) where
|
||||
|
||||
import ClassyPrelude.Yesod
|
||||
import Yesod.Routes.TH.Types (ResourceTree)
|
||||
|
||||
|
||||
uniworxRoutes :: [ResourceTree String]
|
||||
uniworxRoutes = $(parseRoutesFile "routes")
|
||||
@ -89,7 +89,7 @@ getAllocationListR = do
|
||||
|
||||
dbtSorting = mconcat
|
||||
[ sortTerm $ queryAllocation . to (E.^. AllocationTerm)
|
||||
, sortSchool $ queryAllocation . to (E.^. AllocationSchool)
|
||||
, sortSchoolShort $ queryAllocation . to (E.^. AllocationSchool)
|
||||
, sortAllocationName $ queryAllocation . to (E.^. AllocationName)
|
||||
, singletonMap "available" . SortColumn $ view queryAvailable
|
||||
, if
|
||||
@ -124,7 +124,7 @@ getAllocationListR = do
|
||||
|
||||
psValidator :: PSValidator _ _
|
||||
psValidator = def
|
||||
& defaultSorting [SortDescBy "term", SortAscBy "school", SortAscBy "allocation"]
|
||||
& defaultSorting [SortDescBy "term", SortAscBy "school-short", SortAscBy "allocation"]
|
||||
|
||||
table <- runDB $ dbTableWidget' psValidator DBTable{..}
|
||||
|
||||
|
||||
@ -2,7 +2,9 @@ module Handler.Utils.Routes
|
||||
( classifyHandler
|
||||
) where
|
||||
|
||||
import Import
|
||||
import Import.NoFoundation
|
||||
import Foundation.Routes
|
||||
import Foundation.Type
|
||||
|
||||
import Utils.TH.Routes
|
||||
|
||||
|
||||
@ -11,11 +11,11 @@ packages:
|
||||
- .
|
||||
|
||||
extra-deps:
|
||||
- git: https://github.com/uni2work/encoding.git
|
||||
- git: git@gitlab2.rz.ifi.lmu.de:uni2work/encoding.git
|
||||
commit: 67bb87ceff53f0178c988dd4e15eeb2daee92b84
|
||||
- git: https://github.com/uni2work/memcached-binary.git
|
||||
- git: git@gitlab2.rz.ifi.lmu.de:uni2work/memcached-binary.git
|
||||
commit: b5461747e7be226d3b67daebc3c9aefe8a4490ad
|
||||
- git: https://github.com/uni2work/conduit-resumablesink.git
|
||||
- git: git@gitlab2.rz.ifi.lmu.de:uni2work/conduit-resumablesink.git
|
||||
commit: cbea6159c2975d42f948525e03e12fc390da53c5
|
||||
|
||||
- zip-stream-0.2.0.1
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#admin-studyterms
|
||||
select, option, input
|
||||
min-width: 50px
|
||||
@ -1,104 +0,0 @@
|
||||
.allocation__label, .allocation__explanation {
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.allocation__state {
|
||||
color: var(--color-font);
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.allocation__courses {
|
||||
margin: 20px 0 0 40px;
|
||||
}
|
||||
|
||||
.allocation-course {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(105px, 1fr) 9fr;
|
||||
grid-template-areas:
|
||||
'name name '
|
||||
'. registered '
|
||||
'prio-label prio '
|
||||
'instr-label instr '
|
||||
'form-label form ';
|
||||
|
||||
grid-gap: 5px 7px;
|
||||
margin: 12px 0;
|
||||
padding: 0 10px 12px 7px;
|
||||
|
||||
border-left: 1px solid var(--color-grey);
|
||||
|
||||
/* &:last-child {
|
||||
* padding: 12px 10px 0 10px;
|
||||
* }
|
||||
*
|
||||
* & + .allocation-course {
|
||||
* border-top: 1px solid var(--color-grey);
|
||||
* }
|
||||
*/
|
||||
|
||||
&:nth-child(2n) {
|
||||
background-color: rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
.allocation-course__registered {
|
||||
grid-area: registered;
|
||||
}
|
||||
|
||||
.allocation-course__priority {
|
||||
grid-area: prio;
|
||||
}
|
||||
.allocation-course__priority-label {
|
||||
grid-area: prio-label;
|
||||
justify-self: end;
|
||||
align-self: center;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.allocation-course__name {
|
||||
grid-area: name;
|
||||
|
||||
align-self: center;
|
||||
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.allocation-course__instructions {
|
||||
grid-area: instr;
|
||||
}
|
||||
.allocation-course__instructions-label {
|
||||
grid-area: instr-label;
|
||||
justify-self: end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.allocation-course__application {
|
||||
grid-area: form;
|
||||
}
|
||||
.allocation-course__application-label {
|
||||
grid-area: form-label;
|
||||
justify-self: end;
|
||||
text-align: right;
|
||||
padding-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 426px) {
|
||||
.allocation-course {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
'name '
|
||||
'registered '
|
||||
'prio-label '
|
||||
'prio '
|
||||
'instr-label'
|
||||
'instr '
|
||||
'form-label '
|
||||
'form ';
|
||||
}
|
||||
|
||||
.allocation-course__application-label {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
.comment
|
||||
white-space: pre-wrap
|
||||
font-family: monospace
|
||||
@ -4,4 +4,4 @@ $#
|
||||
$# participantTable : widget table
|
||||
|
||||
^{participantTable}
|
||||
_{MsgCourseMembersCountOf (fromIntegral numParticipants) (courseCapacity course)}.
|
||||
_{MsgCourseMembersCountOf (fromIntegral numParticipants) (courseCapacity course)}.
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
th {
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
.course-news {
|
||||
max-height: 50vh;
|
||||
overflow: auto;
|
||||
|
||||
.course-news-item {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.course-news-item__last-edit {
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.course-news-item__title .modal__trigger-label {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.course-news-item__summary .modal__trigger-label {
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
.bound_explanation {
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
.action {
|
||||
max-width: 800px;
|
||||
padding: 3px 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.action__options {
|
||||
max-height: 450px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.action__option {
|
||||
display: flex;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.action__label,
|
||||
.action__option-label {
|
||||
margin-left: 15px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.action__fieldset {
|
||||
margin: 7px 0 5px 9px;
|
||||
padding: 5px 0 10px;
|
||||
border-left: 1px solid #bcbcbc;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.action__toggle-all {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #bcbcbc;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.action__checked-counter {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
@ -11,7 +11,7 @@ $if not isModal
|
||||
|
||||
<div .main>
|
||||
|
||||
<div .main__content uw-poc>
|
||||
<div .main__content uw-poc :isJust currentHandler:uw-handler=#{fromMaybe "" currentHandler}>
|
||||
|
||||
$if not isModal
|
||||
<!-- breadcrumbs -->
|
||||
|
||||
@ -1,786 +0,0 @@
|
||||
:root {
|
||||
/* THEME INDEPENDENT COLORS */
|
||||
--color-error: #8c0707;
|
||||
--color-error-dark: #500303;
|
||||
--color-warning: #fc9900;
|
||||
--color-warning-dark: #c27400;
|
||||
--color-success: #23d160;
|
||||
--color-success-dark: #1ca64c;
|
||||
--color-info: #c4c4c4;
|
||||
--color-info-dark: #919191;
|
||||
--color-lightblack: #1A2A36;
|
||||
--color-lightwhite: #fcfffa;
|
||||
--color-grey: #B1B5C0;
|
||||
--color-grey-light: #efefef;
|
||||
--color-grey-lighter: #f5f5f5;
|
||||
--color-grey-medium: #9A989E;
|
||||
--color-font: #34303a;
|
||||
--color-fontsec: #5b5861;
|
||||
|
||||
|
||||
/* FONTS */
|
||||
--font-base: "Source Sans Pro", "Trebuchet MS", sans-serif;
|
||||
--font-logo: "Roboto", var(--font-base);
|
||||
|
||||
/* DIMENSIONS */
|
||||
--header-height: 100px;
|
||||
--header-height-collapsed: 60px;
|
||||
|
||||
--asidenav-width-xl: 250px;
|
||||
--asidenav-width-lg: 20%;
|
||||
--asidenav-width-md: 60px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
color: var(--color-font);
|
||||
font-family: var(--font-base);
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
/* THEMES */
|
||||
|
||||
body {
|
||||
/* DEFAULT LMU THEME */
|
||||
--color-lmu-green: #0a9342;
|
||||
--color-primary: var(--color-lmu-green);
|
||||
--color-light: #31cc72;
|
||||
--color-lighter: #35db7a;
|
||||
--color-dark: #087536;
|
||||
--color-darker: #075728;
|
||||
--color-link: var(--color-font);
|
||||
--color-link-hover: var(--color-font);
|
||||
--color-lmu-box-border: var(--color-lightwhite);
|
||||
|
||||
&.theme--lavender {
|
||||
--color-primary: #584c9c;
|
||||
--color-light: #5969b5;
|
||||
--color-lighter: #5f7dc2;
|
||||
--color-dark: #4c4279;
|
||||
--color-darker: #3c2765;
|
||||
--color-link: var(--color-dark);
|
||||
--color-link-hover: var(--color-darker);
|
||||
}
|
||||
|
||||
&.theme--neutral-blue {
|
||||
--color-primary: #3E606F;
|
||||
--color-light: rgb(189, 201, 219);
|
||||
--color-lighter: rgb(145, 159, 170);
|
||||
--color-dark: rgb(42, 74, 88);
|
||||
--color-darker: #193441;
|
||||
}
|
||||
|
||||
&.theme--aberdeen-reds {
|
||||
--color-primary: #820333;
|
||||
--color-light: #C9283E;
|
||||
--color-lighter: #F0433A;
|
||||
--color-dark: #540032;
|
||||
--color-darker: #2E112D;
|
||||
}
|
||||
|
||||
&.theme--moss-green {
|
||||
--color-primary: #5C996B;
|
||||
--color-light: #7ACC8F;
|
||||
--color-lighter: #99FFB2;
|
||||
--color-dark: #3D6647;
|
||||
--color-darker: #1F3324;
|
||||
}
|
||||
|
||||
&.theme--sky-love {
|
||||
--color-primary: #87ABE5;
|
||||
--color-light: #A0C6F2;
|
||||
--color-lighter: #BAE2FF;
|
||||
--color-dark: #7A95DE;
|
||||
--color-darker: #6B7BC9;
|
||||
--color-link: var(--color-lightblack);
|
||||
--color-link-hover: var(--color-darker);
|
||||
}
|
||||
}
|
||||
|
||||
/* END THEMES */
|
||||
|
||||
.emph {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: color .2s ease, background-color .2s ease;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
}
|
||||
|
||||
|
||||
ul {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
h1, h2, h3, .div-h3 , h4, h5 {
|
||||
font-weight: 600;
|
||||
}
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin: 10px 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
h3, .div-h3 {
|
||||
font-size: 20px;
|
||||
margin: 10px 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h3, .div-h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* LAYOUT */
|
||||
.main {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main__content {
|
||||
position: relative;
|
||||
background-color: white;
|
||||
transition: padding-left .2s ease-out;
|
||||
margin-top: var(--header-height-collapsed);
|
||||
margin-left: 0;
|
||||
|
||||
> .container {
|
||||
margin: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.main__content, .modal__content {
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p, form, .div-p {
|
||||
margin: 0.5rem 0;
|
||||
|
||||
&:last-child {
|
||||
margin: 0.5rem 0 0;
|
||||
|
||||
&:first-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 426px) {
|
||||
.main__content {
|
||||
margin-left: var(--asidenav-width-md, 50px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.main__content {
|
||||
margin-left: var(--asidenav-width-lg, 20%);
|
||||
margin-top: var(--header-height);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.main__content {
|
||||
margin-left: var(--asidenav-width-xl, 250px);
|
||||
}
|
||||
}
|
||||
|
||||
.main__content-body {
|
||||
padding: 13px;
|
||||
}
|
||||
|
||||
@media (min-width: 426px) {
|
||||
.main__content-body {
|
||||
padding: 13px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.main__content-body {
|
||||
padding: 20px 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.pseudo-focus {
|
||||
outline: 5px auto var(--color-light);
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
/* CONTAINER */
|
||||
.container {
|
||||
|
||||
+ .container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* GENERAL BUTTON STYLES */
|
||||
input[type="submit"],
|
||||
input[type="button"],
|
||||
button,
|
||||
.btn {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
box-shadow: 0;
|
||||
background-color: var(--color-dark);
|
||||
color: white;
|
||||
padding: 10px 17px;
|
||||
min-width: 100px;
|
||||
transition: all .1s;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
|
||||
a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0 0.25rem rgba(50,115,220,.25);
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="submit"][disabled],
|
||||
input[type="button"][disabled],
|
||||
button[disabled],
|
||||
.btn[disabled] {
|
||||
opacity: 0.3;
|
||||
background-color: var(--color-grey);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
input[type="submit"]:not([disabled]):hover,
|
||||
input[type="button"]:not([disabled]):hover,
|
||||
button:not([disabled]):hover,
|
||||
.btn:not([disabled]):hover {
|
||||
background-color: var(--color-light);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
background-color: var(--color-info)
|
||||
}
|
||||
|
||||
.btn--small {
|
||||
padding: 4px 7px;
|
||||
background-color: var(--color-darker);
|
||||
}
|
||||
|
||||
input[type="submit"].btn-info:hover,
|
||||
input[type="button"].btn-info:hover,
|
||||
.btn-info:hover {
|
||||
background-color: var(--color-grey)
|
||||
}
|
||||
|
||||
/* GENERAL TABLE STYLES */
|
||||
.table {
|
||||
margin: 21px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table:only-child {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.table--striped {
|
||||
|
||||
.table__row:not(.no-stripe):not(.table__row--sum):nth-child(even) {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
}
|
||||
|
||||
.table--hover {
|
||||
|
||||
.table__row:not(.no-hover):not(.table__row--sum):not(.table__row--head):not(.table__row--foot):hover {
|
||||
background-color: rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
}
|
||||
|
||||
.table__row--sum td.table__td::before {
|
||||
content: 'Σ';
|
||||
font-weight: bold;
|
||||
margin-right: .25em;
|
||||
}
|
||||
|
||||
/* SCROLLTABLE */
|
||||
.scrolltable {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scrolltable--bordered {
|
||||
box-shadow: 0 0 1px 1px var(--color-grey-light);
|
||||
}
|
||||
|
||||
@media (max-width: 425px) {
|
||||
|
||||
.scrolltable {
|
||||
margin-left: -10px;
|
||||
padding-left: 10px;
|
||||
margin-right: -10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* TABLE DESIGN */
|
||||
.table__td, .table__th {
|
||||
padding-top: 14px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.table__td {
|
||||
font-size: 16px;
|
||||
color: var(--color-font);
|
||||
line-height: 1.4;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.table__td--automatic {
|
||||
font-style: oblique;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
.table__td--overriden {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table__th {
|
||||
background-color: var(--color-dark);
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
line-height: 1.4;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "\f0c1";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
|
||||
.table th {
|
||||
padding: 4px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.table__td-content {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.table__th-link {
|
||||
font-weight: bold;
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.table--vertical {
|
||||
|
||||
th {
|
||||
background-color: transparent;
|
||||
color: var(--color-font);
|
||||
width: 170px;
|
||||
text-align: right;
|
||||
padding-right: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
td {
|
||||
font-weight: 600;
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
|
||||
.table--condensed {
|
||||
margin: 0;
|
||||
|
||||
.table__th,
|
||||
.table__td {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* UNORDERED LIST */
|
||||
.list-ul__item {
|
||||
// padding: 4px 0;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
/* LIST MODIFIERS */
|
||||
.list--iconless {
|
||||
list-style-type: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.list--inline {
|
||||
ul {
|
||||
display: inline-block;
|
||||
margin-left: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.list--inline {
|
||||
|
||||
display: inline-block;
|
||||
margin-left: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.list--comma-separated li {
|
||||
&::after {
|
||||
content: ', ';
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
&:last-of-type::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list--space-separated li {
|
||||
&::after {
|
||||
content: ' ';
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
&:last-of-type::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list--icon-width li {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
/* DEFINITION LIST */
|
||||
.deflist {
|
||||
display: grid;
|
||||
grid-template-columns: 100%;
|
||||
}
|
||||
.deflist__dt,
|
||||
.deflist__dd {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.deflist__dt {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.deflist__dd {
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> p, > .div-p {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.deflist {
|
||||
grid-template-columns: fit-content(25vw) 1fr;
|
||||
|
||||
.deflist {
|
||||
margin-top: -10px;
|
||||
margin-right: -15px;
|
||||
|
||||
.deflist__dd {
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deflist__dt,
|
||||
.deflist__dd {
|
||||
padding: 12px 0;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
|
||||
&:last-of-type {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.deflist__dt {
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
.deflist__dd {
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
|
||||
+ section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.pseudonym {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.headline-one {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Notification style used as requested by @hamanf in #298, but class was not globally available. Copied from dead-code. For @hamanf to clean up: */
|
||||
|
||||
.notification {
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
padding: 10px 20px 20px;
|
||||
margin: 40px auto;
|
||||
box-shadow: 0 0 4px 2px inset currentColor;
|
||||
padding-left: 100px;
|
||||
min-height: 100px;
|
||||
max-width: 700px;
|
||||
font-weight: 600;
|
||||
vertical-align: center;
|
||||
display: grid;
|
||||
grid-column: 2;
|
||||
|
||||
&::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 600;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100px;
|
||||
font-size: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.notification__content {
|
||||
grid-column: 1;
|
||||
align-self: center;
|
||||
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
||||
&.notification--broad {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
.form-section-notification {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-gap: 5px;
|
||||
|
||||
fieldset {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-gap: 5px;
|
||||
grid-column: 1/3;
|
||||
}
|
||||
|
||||
.notification {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
+ .form-group, + .form-section-legend, + .form-section-notification {
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
||||
+ .form-section-title {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.form-section-notification {
|
||||
grid-template-columns: 1fr;
|
||||
margin-top: 17px;
|
||||
|
||||
fieldset {
|
||||
grid-template-columns: 1fr;
|
||||
grid-column: 1/2;
|
||||
}
|
||||
}
|
||||
|
||||
.notification {
|
||||
grid-column: 1;
|
||||
|
||||
max-width: none;
|
||||
|
||||
padding-left: 40px;
|
||||
|
||||
&::before {
|
||||
height: auto;
|
||||
width: 45px;
|
||||
font-size: 40px;
|
||||
top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notification-error {
|
||||
color: var(--color-error) ;
|
||||
}
|
||||
|
||||
.notification-warning {
|
||||
color: var(--color-warning) ;
|
||||
}
|
||||
|
||||
.notification-info {
|
||||
color: var(--color-lightblack) ;
|
||||
}
|
||||
|
||||
.notification-success {
|
||||
color: var(--color-warning) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
"Heated" element.
|
||||
Set custom property "--hotness" to a value from 0 to 1 to turn
|
||||
the element's background to a color on a gradient from green to red.
|
||||
|
||||
TBD:
|
||||
- move to a proper place
|
||||
- think about font-weight...
|
||||
|
||||
Example:
|
||||
<div .heated style="--hotness: 0.2">Lorem ipsum
|
||||
*/
|
||||
|
||||
.heated {
|
||||
--hotness: 0;
|
||||
--red: calc(var(--hotness) * 200);
|
||||
--green: calc(255 - calc(var(--hotness) * 255));
|
||||
--opacity: calc(calc(var(--red) / 600) + 0.1);
|
||||
|
||||
font-weight: var(--weight, 600);
|
||||
background-color: rgba(var(--red), var(--green), 0, var(--opacity));
|
||||
}
|
||||
|
||||
|
||||
.uuid {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
||||
.form--inline {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
.ribbon {
|
||||
position: fixed;
|
||||
top: calc(40px + var(--header-height));
|
||||
transition: all .2s cubic-bezier(0.03, 0.43, 0.58, 1);
|
||||
right: -63px;
|
||||
transform: rotate(45deg);
|
||||
width: 250px;
|
||||
background: var(--color-error);
|
||||
text-align: center;
|
||||
color: var(--color-lightwhite);
|
||||
font-weight: 600;
|
||||
font-size: 1.25rem;
|
||||
line-height: 2em;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.4);
|
||||
z-index: 19;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.ribbon {
|
||||
top: calc(20px + var(--header-height-collapsed));
|
||||
right: -83px;
|
||||
transform: rotate(45deg) scale(0.6);
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
.occurrence--not-registered, .no-bonus
|
||||
text-decoration: line-through
|
||||
|
||||
.result
|
||||
font-size: 3rem
|
||||
margin: 30px 30px 0 !important
|
||||
@ -1,14 +0,0 @@
|
||||
.glossary
|
||||
dt, .dt
|
||||
font-weight: 600
|
||||
|
||||
&.sec
|
||||
font-style: italic
|
||||
font-size: 0.9rem
|
||||
font-weight: 600
|
||||
color: var(--color-fontsec)
|
||||
dd, .dd
|
||||
margin-left: 12px
|
||||
|
||||
dd + dt, .dd + dt, dd + .dt, .dd + .dt
|
||||
margin-top: 17px
|
||||
@ -1,5 +1,5 @@
|
||||
$newline never
|
||||
<th .table__th *{attrs} :isSortable:.sortable :isSorted SortAsc:.sorted-asc :isSorted SortDesc:.sorted-desc>
|
||||
<th .table__th *{attrs} :isSortable:.sortable :isSorted SortAsc:.sorted-asc :isSorted SortDesc:.sorted-desc uw-hide-column-header=#{maybe "" toPathPiece sortableKey}>
|
||||
$maybe flag <- sortableKey
|
||||
$case directions
|
||||
$of [SortAsc]
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
$newline never
|
||||
<div table-utils>
|
||||
<div .scrolltable .scrolltable--bordered>
|
||||
<table *{dbsAttrs'}>
|
||||
$maybe wHeaders' <- wHeaders
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
/* SORTABLE TABLE-HEADERS*/
|
||||
.table__th.sortable {
|
||||
position: relative;
|
||||
padding-right: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table__th.sortable::after,
|
||||
.table__th.sortable::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 4px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-bottom: 8px solid rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.table__th.sortable::before {
|
||||
/* magic numbers to move arrow back in the right position after flipping it.
|
||||
this allows us to use the same border for the up and the down arrow */
|
||||
transform: translateY(150%) scale(1, -1);
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
.table__th.sortable::after {
|
||||
transform: translateY(-150%);
|
||||
}
|
||||
|
||||
.table__th.sortable:hover::before,
|
||||
.table__th.sortable:hover::after {
|
||||
border-bottom-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.table__th.sorted-asc::before,
|
||||
.table__th.sorted-desc::after {
|
||||
border-bottom-color: white !important;
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
:root {
|
||||
--color-grey-light: #efefef;
|
||||
--color-grey-lighter: #f5f5f5;
|
||||
--color-fontsec: #5b5861;
|
||||
--course-bg-color: var(--color-grey-lighter);
|
||||
--course-expanded-bg-color: var(--color-grey-light);
|
||||
}
|
||||
|
||||
.scrolltable {
|
||||
box-shadow: none!important;
|
||||
}
|
||||
|
||||
.course-header::after,
|
||||
.course-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 20px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-bottom: 8px solid rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.course-header::before {
|
||||
/* magic numbers to move arrow back in the right position after flipping it.
|
||||
this allows us to use the same border for the up and the down arrow */
|
||||
transform: translateY(150%) scale(1, -1);
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
.course-header::after {
|
||||
transform: translateY(-150%);
|
||||
}
|
||||
|
||||
.course-header:hover::before,
|
||||
.course-header:hover::after {
|
||||
border-bottom-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.sorted-asc::before,
|
||||
.sorted-desc::after {
|
||||
border-bottom-color: white !important;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
.csv-export {
|
||||
margin-bottom: 13px;
|
||||
|
||||
}
|
||||
|
||||
.csv-import {
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
.table-filter {
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
.table-filter__toggle {
|
||||
padding: 3px 7px;
|
||||
}
|
||||
@ -1,3 +1,3 @@
|
||||
$newline never
|
||||
<div ##{wIdent "table-wrapper"} :not (null rows && (dbsEmptyStyle == DBESNoHeading)):uw-async-table data-async-table-db-header=#{toPathPiece HeaderDBTableShortcircuit}>
|
||||
<div ##{wIdent "table-wrapper"} :not (null rows && (dbsEmptyStyle == DBESNoHeading)):uw-async-table uw-hide-columns=#{dbtIdent} data-async-table-db-header=#{toPathPiece HeaderDBTableShortcircuit}>
|
||||
^{table}
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
/* TABLE HEADER */
|
||||
.table-header {
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* TABLE FOOTER */
|
||||
.table-footer {
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
justify-content: space-between;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* PAGINATION */
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
overflow: auto;
|
||||
|
||||
.pages {
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
|
||||
.page-link {
|
||||
margin-top: 7px;
|
||||
display: inline-block;
|
||||
background-color: var(--color-grey-medium);
|
||||
|
||||
+ .page-link {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-lightwhite);
|
||||
padding: 7px 13px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:not(.current):hover {
|
||||
background-color: var(--color-primary);
|
||||
|
||||
a {
|
||||
color: var(--color-lightwhite);
|
||||
}
|
||||
}
|
||||
|
||||
&.current {
|
||||
pointer-events: none;
|
||||
background-color: var(--color-dark);
|
||||
|
||||
a {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
#changelog {
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#gitrev {
|
||||
font-size: 12px;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
.breadcrumbs__container {
|
||||
position: relative;
|
||||
color: var(--color-lightwhite);
|
||||
padding: 4px 13px;
|
||||
background-color: var(--color-dark);
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
@media (min-width: 426px) {
|
||||
.breadcrumbs__container {
|
||||
padding: 7px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.breadcrumbs__container {
|
||||
padding: 7px 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumbs__link {
|
||||
color: var(--color-lightwhite);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-white);
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumbs__item {
|
||||
padding-right: 14px;
|
||||
position: relative;
|
||||
line-height: 28px;
|
||||
opacity: 0.8;
|
||||
z-index: 1;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
right: 0;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-color: var(--color-white);
|
||||
transform: rotate(-45deg);
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumbs__last-item {
|
||||
line-height: 28px;
|
||||
vertical-align: bottom;
|
||||
font-weight: 600;
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
.recipient-category {
|
||||
max-width: 400px;
|
||||
padding: 3px 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
.recipient-category__options {
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.recipient-category__option {
|
||||
display: flex;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.recipient-category__label,
|
||||
.recipient-category__option-label {
|
||||
margin-left: 15px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.recipient-category__fieldset {
|
||||
margin: 7px 0 5px 9px;
|
||||
padding: 5px 0 10px;
|
||||
border-left: 1px solid #bcbcbc;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.recipient-category__option-add {
|
||||
display: flex;
|
||||
|
||||
.btn-mass-input-add {
|
||||
margin-left: 10px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.recipient-category__options + .recipient-category__option-add {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.recipient-category__toggle-all {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #bcbcbc;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.recipient-category__checked-counter {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
.table__td--csv, .table__th--csv {
|
||||
font-family: monospace;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
.confirmationText {
|
||||
white-space: pre-wrap;
|
||||
font-size: 14px;
|
||||
font-family: monospace;
|
||||
}
|
||||
@ -1,3 +1,3 @@
|
||||
$newline never
|
||||
<div ##{fvId <> "-wrapper"}>
|
||||
<div .func-field__wrapper>
|
||||
^{formView}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
##{fvId <> "-wrapper"} {
|
||||
max-height: 75vh;
|
||||
overflow: auto;
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
margin: 40px 0;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 10%;
|
||||
width: 80%;
|
||||
height: 2px;
|
||||
background-color: var(--color-grey-light);
|
||||
}
|
||||
}
|
||||
|
||||
.footer-links * {
|
||||
margin-right: 0.5em;
|
||||
|
||||
&:last {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
.table--grading-key
|
||||
th, td
|
||||
padding: 3px;
|
||||
@ -1,8 +0,0 @@
|
||||
.btn.btn-mass-input-delete,
|
||||
.btn.btn-mass-input-add {
|
||||
background-color: #999;
|
||||
min-width: 50px;
|
||||
padding: 5px 15px;
|
||||
font-weight: 700;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
.file-input__unpack {
|
||||
font-size: .9rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
|
||||
.checkbox {
|
||||
display: inline-block;
|
||||
margin-left: 7px;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user