Integrated Ionic framework
This commit is contained in:
parent
fcfa54cc4e
commit
87869ce604
|
@ -8,6 +8,7 @@
|
|||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
last 2 ChromeAndroid versions
|
||||
last 2 Chrome versions
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
|
@ -27,7 +27,7 @@ steps:
|
|||
commands:
|
||||
- npm install
|
||||
- npm run build:production
|
||||
- cp /drone/src/.htaccess /drone/src/dist/tsw-timetable-frontend/
|
||||
- cp /drone/src/.htaccess /drone/src/dist/www/
|
||||
- name: rebuild-cache
|
||||
privileged: true
|
||||
image: 2martens/drone-volume-cache
|
||||
|
@ -44,7 +44,7 @@ steps:
|
|||
settings:
|
||||
hosts: [ "gienah.uberspace.de" ]
|
||||
user: wahlfron
|
||||
source: /drone/src/dist/tsw-timetable-frontend/.
|
||||
source: /drone/src/dist/www/.
|
||||
target: ~/tmp/build
|
||||
recursive: true
|
||||
delete: true
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"root": true,
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"tsconfig.json"
|
||||
],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/recommended",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/component-class-suffix": [
|
||||
"error",
|
||||
{
|
||||
"suffixes": [
|
||||
"Page",
|
||||
"Component"
|
||||
]
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": "app",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": "app",
|
||||
"style": "camelCase"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.html"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/template/recommended"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +1,27 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
# Specifies intentionally untracked files to ignore when using Git
|
||||
# http://git-scm.com/docs/gitignore
|
||||
|
||||
*~
|
||||
*.sw[mnpcod]
|
||||
.tmp
|
||||
*.tmp
|
||||
*.tmp.*
|
||||
UserInterfaceState.xcuserstate
|
||||
$RECYCLE.BIN/
|
||||
|
||||
*.log
|
||||
log.txt
|
||||
|
||||
|
||||
/.sourcemaps
|
||||
/.versions
|
||||
/coverage
|
||||
|
||||
# Ionic
|
||||
/.ionic
|
||||
/www
|
||||
/platforms
|
||||
/plugins
|
||||
|
||||
# Compiled output
|
||||
/dist
|
||||
|
@ -18,6 +41,7 @@ yarn-error.log
|
|||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Visual Studio Code
|
||||
|
@ -29,6 +53,7 @@ yarn-error.log
|
|||
.history/*
|
||||
|
||||
# Miscellaneous
|
||||
/.angular
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
|
|
107
angular.json
107
angular.json
|
@ -3,11 +3,12 @@
|
|||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"tsw-timetable-frontend": {
|
||||
"app": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
"@ionic/angular-toolkit:page": {
|
||||
"styleext": "scss",
|
||||
"standalone": true
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
|
@ -25,26 +26,29 @@
|
|||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/tsw-timetable-frontend",
|
||||
"outputPath": "www",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": [
|
||||
"zone.js"
|
||||
],
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets",
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "assets"
|
||||
},
|
||||
"src/manifest.webmanifest"
|
||||
],
|
||||
"styles": [
|
||||
"@angular/material/prebuilt-themes/deeppurple-amber.css",
|
||||
"src/sass/styles.scss"
|
||||
"src/theme/variables.scss",
|
||||
"src/global.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"src/sass"
|
||||
"src/sass",
|
||||
"src/theme",
|
||||
"src"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
|
@ -61,8 +65,8 @@
|
|||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
|
@ -76,8 +80,8 @@
|
|||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
|
@ -112,6 +116,9 @@
|
|||
"sourceMap": true,
|
||||
"namedChunks": true,
|
||||
"localize": ["de"]
|
||||
},
|
||||
"ci": {
|
||||
"progress": false
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
|
@ -120,16 +127,19 @@
|
|||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "tsw-timetable-frontend:build:production"
|
||||
"browserTarget": "app:build:production"
|
||||
},
|
||||
"productionDebug": {
|
||||
"browserTarget": "tsw-timetable-frontend:build:productionDebug"
|
||||
"browserTarget": "app:build:productionDebug"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "tsw-timetable-frontend:build:development"
|
||||
"browserTarget": "app:build:development"
|
||||
},
|
||||
"developmentRemote": {
|
||||
"browserTarget": "tsw-timetable-frontend:build:developmentRemote"
|
||||
"browserTarget": "app:build:developmentRemote"
|
||||
},
|
||||
"ci": {
|
||||
"progress": false
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
|
@ -137,36 +147,71 @@
|
|||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "tsw-timetable-frontend:build"
|
||||
"browserTarget": "app:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"polyfills": [
|
||||
"zone.js",
|
||||
"zone.js/testing"
|
||||
],
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets",
|
||||
"src/manifest.webmanifest"
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "src/assets",
|
||||
"output": "assets"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"@angular/material/prebuilt-themes/deeppurple-amber.css",
|
||||
"src/sass/styles.scss"
|
||||
"src/theme/variables.scss",
|
||||
"src/global.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"src/sass"
|
||||
"src/theme"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"progress": false,
|
||||
"watch": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"schematicCollections": [
|
||||
"@ionic/angular-toolkit"
|
||||
]
|
||||
},
|
||||
"schematics": {
|
||||
"@ionic/angular-toolkit:component": {
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@ionic/angular-toolkit:page": {
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@angular-eslint/schematics:application": {
|
||||
"setParserOptionsProject": true
|
||||
},
|
||||
"@angular-eslint/schematics:library": {
|
||||
"setParserOptionsProject": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import {CapacitorConfig} from '@capacitor/cli';
|
||||
|
||||
const config: CapacitorConfig = {
|
||||
appId: 'io.ionic.starter',
|
||||
appName: 'tsw-timetable-frontend',
|
||||
webDir: 'www',
|
||||
server: {
|
||||
androidScheme: 'https'
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "tsw-timetable-frontend",
|
||||
"integrations": {
|
||||
"capacitor": {}
|
||||
},
|
||||
"type": "angular-standalone"
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/app'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{type: 'html'},
|
||||
{type: 'text-summary'}
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load Diff
58
package.json
58
package.json
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"name": "tsw-timetable-frontend",
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"author": "Ionic Framework",
|
||||
"homepage": "https://ionicframework.com/",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
|
@ -11,45 +13,69 @@
|
|||
"build:production": "ng build -c production",
|
||||
"build:production:sourcemap": "ng build -c productionDebug",
|
||||
"build:production:stats": "ng build -c production --stats-json",
|
||||
"analyze": "webpack-bundle-analyzer dist/tsw-timetable-frontend/de/stats.json",
|
||||
"analyze": "webpack-bundle-analyzer www/de/stats.json",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test",
|
||||
"extract-i18n": "ng extract-i18n --output-path src/locale"
|
||||
"extract-i18n": "ng extract-i18n --output-path src/locale",
|
||||
"lint": "ng lint"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^16.2.1",
|
||||
"@angular/cdk": "^16.2.1",
|
||||
"@angular/common": "^16.2.1",
|
||||
"@angular/compiler": "^16.2.1",
|
||||
"@angular/core": "^16.2.1",
|
||||
"@angular/forms": "^16.2.1",
|
||||
"@angular/material": "^16.2.1",
|
||||
"@angular/platform-browser": "^16.2.1",
|
||||
"@angular/platform-browser-dynamic": "^16.2.1",
|
||||
"@angular/router": "^16.2.1",
|
||||
"@angular/service-worker": "^16.2.1",
|
||||
"@capacitor/app": "5.0.6",
|
||||
"@capacitor/core": "5.5.1",
|
||||
"@capacitor/haptics": "5.0.6",
|
||||
"@capacitor/keyboard": "5.0.6",
|
||||
"@capacitor/status-bar": "5.0.6",
|
||||
"@ionic/angular": "^7.5.0",
|
||||
"@ngrx/effects": "^16.2.0",
|
||||
"@ngrx/store": "^16.2.0",
|
||||
"ionicons": "^7.2.1",
|
||||
"keycloak-angular": "^14.0.0",
|
||||
"rxjs": "~7.8.1",
|
||||
"tslib": "^2.6.2",
|
||||
"zone.js": "~0.13.1"
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^16.2.0",
|
||||
"@angular/cli": "~16.2.0",
|
||||
"@angular-devkit/build-angular": "^16.2.1",
|
||||
"@angular-eslint/builder": "^16.2.0",
|
||||
"@angular-eslint/eslint-plugin": "^16.2.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^16.2.0",
|
||||
"@angular-eslint/schematics": "^16.2.0",
|
||||
"@angular-eslint/template-parser": "^16.2.0",
|
||||
"@angular/cli": "^16.2.1",
|
||||
"@angular/compiler-cli": "^16.2.1",
|
||||
"@angular/localize": "^16.2.1",
|
||||
"@angular/language-service": "^16.2.1",
|
||||
"@angular/localize": "^16.2.11",
|
||||
"@capacitor/cli": "5.5.1",
|
||||
"@ionic/angular-toolkit": "^9.0.0",
|
||||
"@types/jasmine": "~4.3.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.3.0",
|
||||
"@typescript-eslint/parser": "5.3.0",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsdoc": "30.7.6",
|
||||
"eslint-plugin-prefer-arrow": "1.2.2",
|
||||
"jasmine-core": "~4.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~6.4.0",
|
||||
"karma-chrome-launcher": "~3.2.0",
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.1.0",
|
||||
"typescript": "~5.1.6",
|
||||
"webpack-bundle-analyzer": "^4.9.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
"karma-jasmine-html-reporter": "~2.0.0",
|
||||
"ts-node": "^8.3.0",
|
||||
"typescript": "~5.0.2",
|
||||
"webpack-bundle-analyzer": "^4.9.0"
|
||||
},
|
||||
"description": "An Ionic project"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
<app-navigation>
|
||||
<router-outlet></router-outlet>
|
||||
</app-navigation>
|
||||
<ion-app>
|
||||
<ion-split-pane contentId="main-content">
|
||||
<ion-menu contentId="main-content" type="overlay">
|
||||
<ion-content>
|
||||
<ion-list id="inbox-list">
|
||||
<ion-list-header>Inbox</ion-list-header>
|
||||
<ion-note>hi@ionicframework.com</ion-note>
|
||||
|
||||
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
|
||||
<ion-item routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false"
|
||||
routerLinkActive="selected">
|
||||
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
|
||||
<ion-label>{{ p.title }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-menu-toggle>
|
||||
</ion-list>
|
||||
|
||||
<ion-list id="labels-list" *ngIf="labels.length > 0">
|
||||
<ion-list-header>Labels</ion-list-header>
|
||||
|
||||
<ion-item *ngFor="let label of labels" lines="none">
|
||||
<ion-icon aria-hidden="true" slot="start" ios="bookmark-outline" md="bookmark-sharp"></ion-icon>
|
||||
<ion-label>{{ label }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
<ion-router-outlet id="main-content"></ion-router-outlet>
|
||||
</ion-split-pane>
|
||||
</ion-app>
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
ion-menu ion-content {
|
||||
--background: var(--ion-item-background, var(--ion-background-color, #fff));
|
||||
}
|
||||
|
||||
ion-menu.md ion-content {
|
||||
--padding-start: 8px;
|
||||
--padding-end: 8px;
|
||||
--padding-top: 20px;
|
||||
--padding-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
ion-menu.md ion-note {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list-header,
|
||||
ion-menu.md ion-note {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#inbox-list {
|
||||
border-bottom: 1px solid var(--ion-color-step-150, #d7d8da);
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#inbox-list ion-list-header {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#labels-list ion-list-header {
|
||||
font-size: 16px;
|
||||
|
||||
margin-bottom: 18px;
|
||||
|
||||
color: #757575;
|
||||
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item {
|
||||
--padding-start: 10px;
|
||||
--padding-end: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item.selected {
|
||||
--background: rgba(var(--ion-color-primary-rgb), 0.14);
|
||||
}
|
||||
|
||||
ion-menu.md ion-item.selected ion-icon {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
ion-menu.md ion-item ion-icon {
|
||||
color: #616e7e;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item ion-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-content {
|
||||
--padding-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list {
|
||||
padding: 20px 0 0 0;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-note {
|
||||
line-height: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item {
|
||||
--padding-start: 16px;
|
||||
--padding-end: 16px;
|
||||
--min-height: 50px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item.selected ion-icon {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item ion-icon {
|
||||
font-size: 24px;
|
||||
color: #73849a;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list#labels-list ion-list-header {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list-header,
|
||||
ion-menu.ios ion-note {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-note {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ion-note {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
|
||||
color: var(--ion-color-medium-shade);
|
||||
}
|
||||
|
||||
ion-item.selected {
|
||||
--color: var(--ion-color-primary);
|
||||
}
|
|
@ -1,24 +1,44 @@
|
|||
import {TestBed} from '@angular/core/testing';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
|
||||
import {AppComponent} from './app.component';
|
||||
import {NavigationComponent} from "./navigation/navigation.component";
|
||||
import {KeycloakAngularModule} from "keycloak-angular";
|
||||
import {MatSidenavModule} from "@angular/material/sidenav";
|
||||
import {NoopAnimationsModule} from "@angular/platform-browser/animations";
|
||||
import {MatToolbarModule} from "@angular/material/toolbar";
|
||||
import {MatListModule} from "@angular/material/list";
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule, KeycloakAngularModule, MatSidenavModule, NoopAnimationsModule,
|
||||
MatToolbarModule, MatListModule, MatIconModule],
|
||||
declarations: [AppComponent, NavigationComponent]
|
||||
}));
|
||||
beforeEach(async () => {
|
||||
TestBed.overrideComponent(AppComponent, {
|
||||
add: {
|
||||
imports: [RouterTestingModule]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have menu labels', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const app = fixture.nativeElement;
|
||||
const menuItems = app.querySelectorAll('ion-label');
|
||||
expect(menuItems.length).toEqual(12);
|
||||
expect(menuItems[0].textContent).toContain('Inbox');
|
||||
expect(menuItems[1].textContent).toContain('Outbox');
|
||||
});
|
||||
|
||||
it('should have urls', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const app = fixture.nativeElement;
|
||||
const menuItems = app.querySelectorAll('ion-item');
|
||||
expect(menuItems.length).toEqual(12);
|
||||
expect(menuItems[0].getAttribute('ng-reflect-router-link')).toEqual(
|
||||
'/folder/inbox'
|
||||
);
|
||||
expect(menuItems[1].getAttribute('ng-reflect-router-link')).toEqual(
|
||||
'/folder/outbox'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,73 @@
|
|||
import {CommonModule} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
import {NavigationComponent} from "./navigation/navigation.component";
|
||||
import {RouterOutlet} from "@angular/router";
|
||||
import {RouterLink, RouterLinkActive} from '@angular/router';
|
||||
import {
|
||||
IonApp,
|
||||
IonContent,
|
||||
IonIcon,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonListHeader,
|
||||
IonMenu,
|
||||
IonMenuToggle,
|
||||
IonNote,
|
||||
IonRouterOutlet,
|
||||
IonSplitPane
|
||||
} from '@ionic/angular/standalone';
|
||||
import {addIcons} from 'ionicons';
|
||||
import {
|
||||
archiveOutline,
|
||||
archiveSharp,
|
||||
bookmarkOutline,
|
||||
bookmarkSharp,
|
||||
heartOutline,
|
||||
heartSharp,
|
||||
mailOutline,
|
||||
mailSharp,
|
||||
paperPlaneOutline,
|
||||
paperPlaneSharp,
|
||||
trashOutline,
|
||||
trashSharp,
|
||||
warningOutline,
|
||||
warningSharp
|
||||
} from 'ionicons/icons';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.scss'],
|
||||
standalone: true,
|
||||
imports: [NavigationComponent, RouterOutlet]
|
||||
imports: [RouterLink, RouterLinkActive, CommonModule, IonApp, IonSplitPane, IonMenu, IonContent, IonList,
|
||||
IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet],
|
||||
})
|
||||
export class AppComponent {
|
||||
public appPages = [
|
||||
{title: 'Inbox', url: '/folder/inbox', icon: 'mail'},
|
||||
{title: 'Outbox', url: '/folder/outbox', icon: 'paper-plane'},
|
||||
{title: 'Favorites', url: '/folder/favorites', icon: 'heart'},
|
||||
{title: 'Archived', url: '/folder/archived', icon: 'archive'},
|
||||
{title: 'Trash', url: '/folder/trash', icon: 'trash'},
|
||||
{title: 'Spam', url: '/folder/spam', icon: 'warning'},
|
||||
];
|
||||
public labels = [];
|
||||
|
||||
constructor() {
|
||||
addIcons({
|
||||
mailOutline,
|
||||
mailSharp,
|
||||
paperPlaneOutline,
|
||||
paperPlaneSharp,
|
||||
heartOutline,
|
||||
heartSharp,
|
||||
archiveOutline,
|
||||
archiveSharp,
|
||||
trashOutline,
|
||||
trashSharp,
|
||||
warningOutline,
|
||||
warningSharp,
|
||||
bookmarkOutline,
|
||||
bookmarkSharp
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {APP_INITIALIZER, ApplicationConfig, isDevMode} from "@angular/core";
|
||||
import {KeycloakBearerInterceptor, KeycloakService} from "keycloak-angular";
|
||||
import {Location} from "@angular/common";
|
||||
import {provideRouter, withComponentInputBinding} from "@angular/router";
|
||||
import {provideRouter, RouteReuseStrategy, withComponentInputBinding} from "@angular/router";
|
||||
import {ROOT_ROUTES} from "./app.routes";
|
||||
import {provideStore} from "@ngrx/store";
|
||||
import {provideEffects} from "@ngrx/effects";
|
||||
|
@ -9,6 +9,7 @@ import {provideAnimations} from "@angular/platform-browser/animations";
|
|||
import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from "@angular/common/http";
|
||||
import {provideServiceWorker} from "@angular/service-worker";
|
||||
import {environment} from "../environments/environment";
|
||||
import {IonicRouteStrategy, provideIonicAngular} from "@ionic/angular/standalone";
|
||||
|
||||
function initializeKeycloak(keycloak: KeycloakService, locationService: Location) {
|
||||
return () =>
|
||||
|
@ -39,6 +40,8 @@ export const appConfig: ApplicationConfig = {
|
|||
multi: true,
|
||||
deps: [KeycloakService, Location],
|
||||
},
|
||||
{provide: RouteReuseStrategy, useClass: IonicRouteStrategy},
|
||||
provideIonicAngular(),
|
||||
provideRouter(ROOT_ROUTES, withComponentInputBinding()),
|
||||
provideStore(),
|
||||
provideEffects(),
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import {Route} from "@angular/router";
|
||||
import {Routes} from '@angular/router';
|
||||
|
||||
export const ROOT_ROUTES: Route[] = [
|
||||
export const ROOT_ROUTES: Routes = [
|
||||
{
|
||||
path: '',
|
||||
loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent),
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'permission-denied',
|
||||
loadComponent: () => import("./permission-denied/permission-denied.component")
|
||||
|
@ -14,9 +19,4 @@ export const ROOT_ROUTES: Route[] = [
|
|||
path: 'privacy-policy',
|
||||
loadComponent: () => import("./privacy-policy/privacy-policy.component").then(mod => mod.PrivacyPolicyComponent)
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
loadComponent: () => import("./dashboard/dashboard.component").then(mod => mod.DashboardComponent),
|
||||
pathMatch: 'full'
|
||||
}
|
||||
];
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
<div class="row">
|
||||
<h1 class="mat-headline-5 mainContentColumn" i18n="page title">Timetable</h1>
|
||||
</div>
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title i18n="page title">Timetable</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="mainContentColumn">
|
||||
<p class="mat-body-1" i18n="welcome text|A welcome to users">
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large" i18n="page title">Timetable</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<div id="container">
|
||||
<p i18n="welcome text|A welcome to users">
|
||||
TODO
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {IonButtons, IonContent, IonHeader, IonMenuButton, IonTitle, IonToolbar} from "@ionic/angular/standalone";
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrls: ['./dashboard.component.scss'],
|
||||
standalone: true,
|
||||
imports: [
|
||||
IonButtons,
|
||||
IonHeader,
|
||||
IonMenuButton,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonContent
|
||||
]
|
||||
})
|
||||
export class DashboardComponent {
|
||||
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
<div class="row">
|
||||
<div class="mainContentColumn">
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title i18n="page title">Legal Notice</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large" i18n="page title">Legal Notice</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-grid id="container">
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2 i18n>Information provided according to Sec. 5 German Telemedia Act (TMG):</h2>
|
||||
<p i18n>Jim Richard Martens<br/>
|
||||
Flaßheide 45<br/>
|
||||
|
@ -15,28 +32,48 @@
|
|||
22525 Hamburg</p>
|
||||
|
||||
<h2 i18n>Liability for Contents</h2>
|
||||
<p i18n>As service providers, we are liable for own contents of these websites according to Sec. 7, paragraph 1 German
|
||||
<p i18n>As service providers, we are liable for own contents of these websites according to Sec. 7, paragraph 1
|
||||
German
|
||||
Telemedia Act (TMG). However, according to Sec. 8 to 10 German Telemedia Act (TMG), service providers are not
|
||||
obligated to permanently monitor submitted or stored information or to search for evidences that indicate illegal
|
||||
activities.</p> <p i18n>Legal obligations to removing information or to blocking the use of information remain unchallenged.
|
||||
In this case, liability is only possible at the time of knowledge about a specific violation of law. Illegal contents
|
||||
obligated to permanently monitor submitted or stored information or to search for evidences that indicate
|
||||
illegal
|
||||
activities.</p>
|
||||
<p i18n>Legal obligations to removing information or to blocking the use of information remain unchallenged.
|
||||
In this case, liability is only possible at the time of knowledge about a specific violation of law. Illegal
|
||||
contents
|
||||
will be removed immediately at the time we get knowledge of them.</p>
|
||||
<h2 i18n>Liability for Links</h2>
|
||||
<p i18n>Our offer includes links to external third party websites. We have no influence on the contents of those websites,
|
||||
therefore we cannot guarantee for those contents. Providers or administrators of linked websites are always responsible
|
||||
<p i18n>Our offer includes links to external third party websites. We have no influence on the contents of those
|
||||
websites,
|
||||
therefore we cannot guarantee for those contents. Providers or administrators of linked websites are always
|
||||
responsible
|
||||
for their own contents.</p>
|
||||
<p i18n>The linked websites had been checked for possible violations of law at the time of the establishment of the link.
|
||||
Illegal contents were not detected at the time of the linking. A permanent monitoring of the contents of linked
|
||||
websites cannot be imposed without reasonable indications that there has been a violation of law. Illegal links
|
||||
<p i18n>The linked websites had been checked for possible violations of law at the time of the establishment of
|
||||
the
|
||||
link.
|
||||
Illegal contents were not detected at the time of the linking. A permanent monitoring of the contents of
|
||||
linked
|
||||
websites cannot be imposed without reasonable indications that there has been a violation of law. Illegal
|
||||
links
|
||||
will be removed immediately at the time we get knowledge of them.</p>
|
||||
<h2 i18n>Copyright</h2>
|
||||
<p i18n>Contents and compilations published on these websites by the providers are subject to German copyright laws.
|
||||
Reproduction, editing, distribution as well as the use of any kind outside the scope of the copyright law require a
|
||||
written permission of the author or originator. Downloads and copies of these websites are permitted for private use
|
||||
<p i18n>Contents and compilations published on these websites by the providers are subject to German copyright
|
||||
laws.
|
||||
Reproduction, editing, distribution as well as the use of any kind outside the scope of the copyright law
|
||||
require
|
||||
a
|
||||
written permission of the author or originator. Downloads and copies of these websites are permitted for
|
||||
private
|
||||
use
|
||||
only.<br/> The commercial use of our contents without permission of the originator is prohibited.</p>
|
||||
<p i18n>Copyright laws of third parties are respected as long as the contents on these websites do not originate from the
|
||||
provider. Contributions of third parties on this site are indicated as such. However, if you notice any violations of
|
||||
<p i18n>Copyright laws of third parties are respected as long as the contents on these websites do not originate
|
||||
from the
|
||||
provider. Contributions of third parties on this site are indicated as such. However, if you notice any
|
||||
violations
|
||||
of
|
||||
copyright law, please inform us. Such contents will be removed immediately.</p>
|
||||
<p></p>
|
||||
</div>
|
||||
</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
@use 'mixins';
|
||||
|
||||
@include mixins.centralColumnLayout();
|
||||
|
||||
p {
|
||||
@include mixins.justifiedText();
|
||||
}
|
||||
|
|
|
@ -1,9 +1,29 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {
|
||||
IonButtons, IonCol,
|
||||
IonContent,
|
||||
IonGrid,
|
||||
IonHeader,
|
||||
IonMenuButton, IonRow,
|
||||
IonTitle,
|
||||
IonToolbar
|
||||
} from "@ionic/angular/standalone";
|
||||
|
||||
@Component({
|
||||
selector: 'app-legal-notice',
|
||||
standalone: true,
|
||||
templateUrl: './legal-notice.component.html',
|
||||
imports: [
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonMenuButton,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonGrid,
|
||||
IonRow,
|
||||
IonCol
|
||||
],
|
||||
styleUrls: ['./legal-notice.component.scss']
|
||||
})
|
||||
export class LegalNoticeComponent {
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<mat-sidenav-container class="sidenav-container">
|
||||
<mat-sidenav #drawer class="sidenav"
|
||||
[attr.role]="'dialog'"
|
||||
[mode]="'side'">
|
||||
<mat-toolbar i18n="title|Title of the sidebar menu">Menu</mat-toolbar>
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="legal-notice" i18n="link name|The name of the legal notice page">Legal Notice</a>
|
||||
<a mat-list-item routerLink="privacy-policy" i18n="link name|The name of the privacy policy page">Privacy
|
||||
Policy</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
<mat-sidenav-content>
|
||||
<mat-toolbar color="primary">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Toggle sidenav"
|
||||
mat-icon-button
|
||||
(click)="drawer.toggle()">
|
||||
<mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
mat-icon-button
|
||||
[routerLink]="''">
|
||||
<mat-icon>home</mat-icon>
|
||||
</button>
|
||||
<span i18n="application title|The application title in the toolbar">Timetable</span>
|
||||
<span class="spacer"></span>
|
||||
<ng-container *ngIf="isLoggedIn$ | async; else loginButton">
|
||||
<span class="logged-user" i18n>Logged in as {{loggedUserName$ | async}}</span>
|
||||
<button mat-raised-button class="app-nav-icon" (click)="logout()" i18n>Logout</button>
|
||||
</ng-container>
|
||||
<ng-template #loginButton>
|
||||
<button mat-raised-button class="app-nav-icon" (click)="login()" i18n>Login</button>
|
||||
</ng-template>
|
||||
</mat-toolbar>
|
||||
<ng-content></ng-content>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
|
@ -1,25 +0,0 @@
|
|||
.sidenav-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.sidenav .mat-toolbar {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
.mat-toolbar.mat-primary {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.logged-user {
|
||||
margin-right: 1em;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatListModule} from '@angular/material/list';
|
||||
import {MatSidenavModule} from '@angular/material/sidenav';
|
||||
import {MatToolbarModule} from '@angular/material/toolbar';
|
||||
|
||||
import {NavigationComponent} from './navigation.component';
|
||||
import {KeycloakAngularModule} from "keycloak-angular";
|
||||
import {RouterTestingModule} from "@angular/router/testing";
|
||||
|
||||
describe('NavigationComponent', () => {
|
||||
let component: NavigationComponent;
|
||||
let fixture: ComponentFixture<NavigationComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [NavigationComponent],
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatListModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
KeycloakAngularModule,
|
||||
RouterTestingModule
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NavigationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should compile', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,57 +0,0 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {KeycloakService} from "keycloak-angular";
|
||||
import {from, of, switchMap} from "rxjs";
|
||||
import {ActivatedRoute, RouterLink} from "@angular/router";
|
||||
import {MatSidenavModule} from "@angular/material/sidenav";
|
||||
import {MatToolbarModule} from "@angular/material/toolbar";
|
||||
import {MatListModule} from "@angular/material/list";
|
||||
import {MatButtonModule} from "@angular/material/button";
|
||||
import {MatIconModule} from "@angular/material/icon";
|
||||
import {AsyncPipe, NgIf} from "@angular/common";
|
||||
|
||||
@Component({
|
||||
selector: 'app-navigation',
|
||||
templateUrl: './navigation.component.html',
|
||||
styleUrls: ['./navigation.component.scss'],
|
||||
imports: [
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
MatListModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
NgIf,
|
||||
AsyncPipe,
|
||||
RouterLink
|
||||
],
|
||||
standalone: true
|
||||
})
|
||||
export class NavigationComponent {
|
||||
loggedUserName$;
|
||||
isLoggedIn$;
|
||||
url: string;
|
||||
|
||||
constructor(private keycloakService: KeycloakService,
|
||||
route: ActivatedRoute) {
|
||||
this.url = route.snapshot.url.join('');
|
||||
this.isLoggedIn$ = from(this.keycloakService.isLoggedIn());
|
||||
this.loggedUserName$ = this.isLoggedIn$.pipe(
|
||||
switchMap(loggedIn => {
|
||||
if (loggedIn) {
|
||||
return of(this.keycloakService.getUsername());
|
||||
} else {
|
||||
return of('');
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
login(): void {
|
||||
this.keycloakService.login({
|
||||
redirectUri: window.location.origin + this.url,
|
||||
});
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
this.keycloakService.logout(window.location.origin);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
<div class="container">
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h1>Permission Denied to Access this Page!!!!</h1>
|
||||
</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {IonCol, IonGrid, IonRow} from "@ionic/angular/standalone";
|
||||
|
||||
@Component({
|
||||
selector: 'app-permission-denied',
|
||||
templateUrl: './permission-denied.component.html',
|
||||
styleUrls: ['./permission-denied.component.scss'],
|
||||
standalone: true
|
||||
standalone: true,
|
||||
imports: [IonGrid, IonRow, IonCol]
|
||||
})
|
||||
export class PermissionDeniedComponent {
|
||||
|
||||
|
|
|
@ -1,35 +1,74 @@
|
|||
<div class="row">
|
||||
<div class="mainContentColumn">
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title i18n="page title">Privacy Policy</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large" i18n="page title">Privacy Policy</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2 i18n>1. An overview of data protection</h2>
|
||||
<h3 i18n>General</h3>
|
||||
<p i18n>The following gives a simple overview of what happens to your personal information when you visit our website.
|
||||
Personal information is any data with which you could be personally identified. Detailed information on the subject
|
||||
<p i18n>The following gives a simple overview of what happens to your personal information when you visit our
|
||||
website.
|
||||
Personal information is any data with which you could be personally identified. Detailed information on the
|
||||
subject
|
||||
of data protection can be found in our privacy policy found below.</p>
|
||||
<h3 i18n>Data collection on our website</h3>
|
||||
<p><strong i18n>Who is responsible for the data collection on this website?</strong></p>
|
||||
<p i18n>The data collected on this website are processed by the website operator. The operator's contact details can be found
|
||||
<p i18n>The data collected on this website are processed by the website operator. The operator's contact details
|
||||
can
|
||||
be found
|
||||
in the website's required legal notice.</p>
|
||||
<p><strong i18n>How do we collect your data?</strong></p>
|
||||
<p i18n>Some data are collected when you provide it to us. This could, for example, be data you enter on a contact form.</p>
|
||||
<p i18n>Other data are collected automatically by our IT systems when you visit the website. These data are primarily technical
|
||||
data such as the browser and operating system you are using or when you accessed the page. These data are collected
|
||||
<p i18n>Some data are collected when you provide it to us. This could, for example, be data you enter on a
|
||||
contact
|
||||
form.</p>
|
||||
<p i18n>Other data are collected automatically by our IT systems when you visit the website. These data are
|
||||
primarily technical
|
||||
data such as the browser and operating system you are using or when you accessed the page. These data are
|
||||
collected
|
||||
automatically as soon as you enter our website.</p>
|
||||
<p><strong i18n>What do we use your data for?</strong></p>
|
||||
<p i18n>Part of the data is collected to ensure the proper functioning of the website. Other data can be used to analyze how
|
||||
<p i18n>Part of the data is collected to ensure the proper functioning of the website. Other data can be used to
|
||||
analyze how
|
||||
visitors use the site.</p>
|
||||
<p><strong i18n>What rights do you have regarding your data?</strong></p>
|
||||
<p i18n>You always have the right to request information about your stored data, its origin, its recipients, and the purpose
|
||||
of its collection at no charge. You also have the right to request that it be corrected, blocked, or deleted. You can
|
||||
contact us at any time using the address given in the legal notice if you have further questions about the issue of
|
||||
privacy and data protection. You may also, of course, file a complaint with the competent regulatory authorities.</p>
|
||||
<p i18n>You always have the right to request information about your stored data, its origin, its recipients, and
|
||||
the
|
||||
purpose
|
||||
of its collection at no charge. You also have the right to request that it be corrected, blocked, or deleted.
|
||||
You
|
||||
can
|
||||
contact us at any time using the address given in the legal notice if you have further questions about the
|
||||
issue
|
||||
of
|
||||
privacy and data protection. You may also, of course, file a complaint with the competent regulatory
|
||||
authorities.</p>
|
||||
<h2 i18n>2. General information and mandatory information</h2>
|
||||
<h3 i18n>Data protection</h3>
|
||||
<p i18n>The operators of this website take the protection of your personal data very seriously. We treat your personal data as
|
||||
<p i18n>The operators of this website take the protection of your personal data very seriously. We treat your
|
||||
personal data as
|
||||
confidential and in accordance with the statutory data protection regulations and this privacy policy.</p>
|
||||
<p i18n>If you use this website, various pieces of personal data will be collected. Personal information is any data with which
|
||||
you could be personally identified. This privacy policy explains what information we collect and what we use it for.
|
||||
<p i18n>If you use this website, various pieces of personal data will be collected. Personal information is any
|
||||
data
|
||||
with which
|
||||
you could be personally identified. This privacy policy explains what information we collect and what we use
|
||||
it
|
||||
for.
|
||||
It also explains how and for what purpose this happens.</p>
|
||||
<p i18n>Please note that data transmitted via the internet (e.g. via email communication) may be subject to security breaches.
|
||||
<p i18n>Please note that data transmitted via the internet (e.g. via email communication) may be subject to
|
||||
security
|
||||
breaches.
|
||||
Complete protection of your data from third-party access is not possible.</p>
|
||||
<h3 i18n>Notice concerning the party responsible for this website</h3>
|
||||
<p i18n>The party responsible for processing data on this website is:</p>
|
||||
|
@ -39,22 +78,31 @@
|
|||
|
||||
<p i18n>Telephone: 04021082122<br/>
|
||||
Email: admin@2martens.de</p>
|
||||
<p i18n>The responsible party is the natural or legal person who alone or jointly with others decides on the purposes and means
|
||||
<p i18n>The responsible party is the natural or legal person who alone or jointly with others decides on the
|
||||
purposes and means
|
||||
of processing personal data (names, email addresses, etc.).</p>
|
||||
<h3 i18n>SSL or TLS encryption</h3>
|
||||
<p i18n>This site uses SSL or TLS encryption for security reasons and for the protection of the
|
||||
transmission of confidential content, such as the inquiries you send to us as the site operator. You can recognize an
|
||||
encrypted connection in your browser's address line when it changes from "http://" to "https://" and the lock icon is
|
||||
transmission of confidential content, such as the inquiries you send to us as the site operator. You can
|
||||
recognize
|
||||
an
|
||||
encrypted connection in your browser's address line when it changes from "http://" to "https://" and the lock
|
||||
icon
|
||||
is
|
||||
displayed in your browser's address bar.</p>
|
||||
<p i18n>If SSL or TLS encryption is activated, the data you transfer to us cannot be read by third parties.</p>
|
||||
<h3 i18n>Opposition to promotional emails</h3>
|
||||
<p i18n>We hereby expressly prohibit the use of contact data published in the context
|
||||
of website legal notice requirements with regard to sending promotional and informational materials not expressly
|
||||
requested. The website operator reserves the right to take specific legal action if unsolicited advertising material,
|
||||
of website legal notice requirements with regard to sending promotional and informational materials not
|
||||
expressly
|
||||
requested. The website operator reserves the right to take specific legal action if unsolicited advertising
|
||||
material,
|
||||
such as email spam, is received.</p>
|
||||
<h2 i18n>3. Data collection on our website</h2>
|
||||
<h3 i18n>Server log files</h3>
|
||||
<p i18n>The website provider automatically collects and stores information that your browser automatically transmits to us in
|
||||
<p i18n>The website provider automatically collects and stores information that your browser automatically
|
||||
transmits
|
||||
to us in
|
||||
"server log files". These are:</p>
|
||||
<ul>
|
||||
<li i18n>Browser type and browser version</li>
|
||||
|
@ -65,7 +113,10 @@
|
|||
<li i18n>IP address</li>
|
||||
</ul>
|
||||
<p i18n>These data will not be combined with data from other sources.</p>
|
||||
<p i18n>The basis for data processing is Art. 6 (1) (b) DSGVO, which allows the processing of data to fulfill a contract or
|
||||
<p i18n>The basis for data processing is Art. 6 (1) (b) DSGVO, which allows the processing of data to fulfill a
|
||||
contract or
|
||||
for measures preliminary to a contract.</p>
|
||||
</div>
|
||||
</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
@use 'mixins';
|
||||
|
||||
@include mixins.centralColumnLayout();
|
||||
|
||||
p {
|
||||
@include mixins.justifiedText();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,30 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {
|
||||
IonButtons, IonCol,
|
||||
IonContent,
|
||||
IonGrid,
|
||||
IonHeader,
|
||||
IonMenuButton, IonRow,
|
||||
IonTitle,
|
||||
IonToolbar
|
||||
} from "@ionic/angular/standalone";
|
||||
|
||||
@Component({
|
||||
selector: 'app-privacy-policy',
|
||||
standalone: true,
|
||||
templateUrl: './privacy-policy.component.html',
|
||||
styleUrls: ['./privacy-policy.component.scss']
|
||||
styleUrls: ['./privacy-policy.component.scss'],
|
||||
imports: [
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonMenuButton,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonGrid,
|
||||
IonRow,
|
||||
IonCol
|
||||
],
|
||||
})
|
||||
export class PrivacyPolicyComponent {
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 930 B |
|
@ -0,0 +1,16 @@
|
|||
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/>
|
||||
<circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/>
|
||||
<path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/>
|
||||
<path fill="#FFCE00" style="mix-blend-mode:multiply"
|
||||
d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/>
|
||||
<circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/>
|
||||
<rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056"
|
||||
width="10.196" height="89.884" rx="5.098"/>
|
||||
<path
|
||||
d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z"
|
||||
fill="#7044FF" style="mix-blend-mode:multiply"/>
|
||||
<circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -1,4 +1,5 @@
|
|||
export const environment = {
|
||||
production: false,
|
||||
backendURL: "http://localhost:12000/timetable/v1",
|
||||
keycloakURL: "https://id.2martens.de",
|
||||
realm: "2martens",
|
||||
|
|
|
@ -4,3 +4,12 @@ export const environment = {
|
|||
realm: "2martens",
|
||||
clientId: "tsw-timetable-frontend"
|
||||
};
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||
*
|
||||
* This import should be commented out in production mode because it will have a negative impact
|
||||
* on performance if an error is thrown.
|
||||
*/
|
||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||
|
|
BIN
src/favicon.ico
BIN
src/favicon.ico
Binary file not shown.
Before Width: | Height: | Size: 948 B |
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* App Global CSS
|
||||
* ----------------------------------------------------------------------------
|
||||
* Put style rules here that you want to apply globally. These styles are for
|
||||
* the entire app and not just one component. Additionally, this file can be
|
||||
* used as an entry point to import other CSS/Sass files to be included in the
|
||||
* output CSS.
|
||||
* For more information on global stylesheets, visit the documentation:
|
||||
* https://ionicframework.com/docs/layout/global-stylesheets
|
||||
*/
|
||||
|
||||
/* Core CSS required for Ionic components to work properly */
|
||||
@import "@ionic/angular/css/core.css";
|
||||
|
||||
/* Basic CSS for apps built with Ionic */
|
||||
@import "@ionic/angular/css/normalize.css";
|
||||
@import "@ionic/angular/css/structure.css";
|
||||
@import "@ionic/angular/css/typography.css";
|
||||
@import "@ionic/angular/css/display.css";
|
||||
|
||||
/* Optional CSS utils that can be commented out */
|
||||
@import "@ionic/angular/css/padding.css";
|
||||
@import "@ionic/angular/css/float-elements.css";
|
||||
@import "@ionic/angular/css/text-alignment.css";
|
||||
@import "@ionic/angular/css/text-transformation.css";
|
||||
@import "@ionic/angular/css/flex-utils.css";
|
|
@ -1,18 +1,21 @@
|
|||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8"/>
|
||||
<title i18n="application title|Title of browser tab">Timetable</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<base href="/"/>
|
||||
<meta name="color-scheme" content="light dark"/>
|
||||
<meta name="viewport"
|
||||
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<meta name="format-detection" content="telephone=no"/>
|
||||
<meta name="msapplication-tap-highlight" content="no"/>
|
||||
<link rel="icon" type="image/png" href="assets/icon/favicon.png"/>
|
||||
<!-- add to homescreen for ios -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
<meta name="theme-color" content="#1976d2">
|
||||
</head>
|
||||
<body class="mat-typography">
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
||||
</body>
|
||||
|
|
|
@ -210,73 +210,6 @@
|
|||
<context context-type="linenumber">37,39</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4330763172337088682" datatype="html">
|
||||
<source>Menu</source>
|
||||
<target>Menü</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Title of the sidebar menu</note>
|
||||
<note priority="1" from="meaning">title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="1213249934851573317" datatype="html">
|
||||
<source>Legal Notice</source>
|
||||
<target>Impressum</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The name of the legal notice page</note>
|
||||
<note priority="1" from="meaning">link name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="6132019390784336883" datatype="html">
|
||||
<source>Privacy Policy</source>
|
||||
<target>Datenschutzerklärung</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">8,9</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The name of the privacy policy page</note>
|
||||
<note priority="1" from="meaning">link name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="8837138757935170328" datatype="html">
|
||||
<source>Timetable</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The application title in the toolbar</note>
|
||||
<note priority="1" from="meaning">application title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="2448391510242468907" datatype="html">
|
||||
<source>Logged in as
|
||||
<x id="INTERPOLATION" equiv-text="{{loggedUserName$ | async}}"/>
|
||||
</source>
|
||||
<target>Eingeloggt als
|
||||
<x id="INTERPOLATION" equiv-text="{{loggedUserName$ | async}}"/>
|
||||
</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">30,31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3797778920049399855" datatype="html">
|
||||
<source>Logout</source>
|
||||
<target>Ausloggen</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2454050363478003966" datatype="html">
|
||||
<source>Login</source>
|
||||
<target>Login</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">34</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7094009074606381897" datatype="html">
|
||||
<source>1. An overview of data protection</source>
|
||||
<target>1. Datenschutz auf einen Blick</target>
|
||||
|
|
|
@ -161,65 +161,6 @@
|
|||
<context context-type="linenumber">37,39</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4330763172337088682" datatype="html">
|
||||
<source>Menu</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Title of the sidebar menu</note>
|
||||
<note priority="1" from="meaning">title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="1213249934851573317" datatype="html">
|
||||
<source>Legal Notice</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The name of the legal notice page</note>
|
||||
<note priority="1" from="meaning">link name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="6132019390784336883" datatype="html">
|
||||
<source>Privacy Policy</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">8,9</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The name of the privacy policy page</note>
|
||||
<note priority="1" from="meaning">link name</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="8837138757935170328" datatype="html">
|
||||
<source>Timetable</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">27</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">The application title in the toolbar</note>
|
||||
<note priority="1" from="meaning">application title</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="2448391510242468907" datatype="html">
|
||||
<source>Logged in as
|
||||
<x id="INTERPOLATION" equiv-text="{{loggedUserName$ | async}}"/>
|
||||
</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">30,31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3797778920049399855" datatype="html">
|
||||
<source>Logout</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">31</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2454050363478003966" datatype="html">
|
||||
<source>Login</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/navigation/navigation.component.html</context>
|
||||
<context context-type="linenumber">34</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7094009074606381897" datatype="html">
|
||||
<source>1. An overview of data protection</source>
|
||||
<context-group purpose="location">
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/// <reference types="@angular/localize" />
|
||||
|
||||
import {bootstrapApplication} from "@angular/platform-browser";
|
||||
import {AppComponent} from "./app/app.component";
|
||||
import "@angular/localize/init";
|
||||
import {bootstrapApplication} from '@angular/platform-browser';
|
||||
import {AppComponent} from './app/app.component';
|
||||
import {appConfig} from "./app/app.config";
|
||||
|
||||
bootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||
* will put import in the top of bundle, so user need to create a separate file
|
||||
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||
* into that file, and then add the following code before importing zone.js.
|
||||
* import './zone-flags';
|
||||
*
|
||||
* The flags allowed in zone-flags.ts are listed here.
|
||||
*
|
||||
* The following flags will work for all browsers.
|
||||
*
|
||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
*
|
||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||
*
|
||||
* (window as any).__Zone_enable_cross_context_check = true;
|
||||
*
|
||||
*/
|
||||
|
||||
import './zone-flags';
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
|
@ -1,57 +0,0 @@
|
|||
@mixin container() {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@mixin flexDirection($value: row) {
|
||||
flex-direction: $value;
|
||||
}
|
||||
|
||||
@mixin flexWrap($value: nowrap) {
|
||||
flex-wrap: $value;
|
||||
}
|
||||
|
||||
@mixin justifyContent($value) {
|
||||
justify-content: $value;
|
||||
}
|
||||
|
||||
@mixin alignItems($value) {
|
||||
align-items: $value;
|
||||
}
|
||||
|
||||
@mixin order($order: 0) {
|
||||
order: $order;
|
||||
}
|
||||
|
||||
@mixin flex($grow: 0, $shrink: 1, $basis: auto) {
|
||||
flex: $grow $shrink $basis;
|
||||
}
|
||||
|
||||
.row {
|
||||
@include container();
|
||||
@include flexDirection(row);
|
||||
@include justifyContent(center);
|
||||
@include alignItems(stretch)
|
||||
}
|
||||
|
||||
// Two-column layout with one main column and one sidebar column (left or right)
|
||||
@mixin twoColumnLayout() {
|
||||
.mainContentColumn {
|
||||
@include flex(9, 0);
|
||||
}
|
||||
.sidebarColumn {
|
||||
@include flex(3, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// One column that does not grow but takes up 60% of the space
|
||||
@mixin centralColumnLayout() {
|
||||
.mainContentColumn {
|
||||
@include flex(0, 1, 60%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@mixin justifiedText() {
|
||||
text-align: justify;
|
||||
text-justify: inter-word;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
||||
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
|
@ -0,0 +1,11 @@
|
|||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/testing';
|
||||
import {getTestBed} from '@angular/core/testing';
|
||||
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
);
|
|
@ -0,0 +1,28 @@
|
|||
@mixin flexDirection($value: row) {
|
||||
flex-direction: $value;
|
||||
}
|
||||
|
||||
@mixin flexWrap($value: nowrap) {
|
||||
flex-wrap: $value;
|
||||
}
|
||||
|
||||
@mixin justifyContent($value) {
|
||||
justify-content: $value;
|
||||
}
|
||||
|
||||
@mixin alignItems($value) {
|
||||
align-items: $value;
|
||||
}
|
||||
|
||||
@mixin order($order: 0) {
|
||||
order: $order;
|
||||
}
|
||||
|
||||
@mixin flex($grow: 0, $shrink: 1, $basis: auto) {
|
||||
flex: $grow $shrink $basis;
|
||||
}
|
||||
|
||||
@mixin justifiedText() {
|
||||
text-align: justify;
|
||||
text-justify: inter-word;
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
// Ionic Variables and Theming. For more info, please see:
|
||||
// http://ionicframework.com/docs/theming/
|
||||
|
||||
/** Ionic CSS Variables **/
|
||||
:root {
|
||||
/** primary **/
|
||||
--ion-color-primary: #3880ff;
|
||||
--ion-color-primary-rgb: 56, 128, 255;
|
||||
--ion-color-primary-contrast: #ffffff;
|
||||
--ion-color-primary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-primary-shade: #3171e0;
|
||||
--ion-color-primary-tint: #4c8dff;
|
||||
|
||||
/** secondary **/
|
||||
--ion-color-secondary: #3dc2ff;
|
||||
--ion-color-secondary-rgb: 61, 194, 255;
|
||||
--ion-color-secondary-contrast: #ffffff;
|
||||
--ion-color-secondary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-secondary-shade: #36abe0;
|
||||
--ion-color-secondary-tint: #50c8ff;
|
||||
|
||||
/** tertiary **/
|
||||
--ion-color-tertiary: #5260ff;
|
||||
--ion-color-tertiary-rgb: 82, 96, 255;
|
||||
--ion-color-tertiary-contrast: #ffffff;
|
||||
--ion-color-tertiary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-tertiary-shade: #4854e0;
|
||||
--ion-color-tertiary-tint: #6370ff;
|
||||
|
||||
/** success **/
|
||||
--ion-color-success: #2dd36f;
|
||||
--ion-color-success-rgb: 45, 211, 111;
|
||||
--ion-color-success-contrast: #ffffff;
|
||||
--ion-color-success-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-success-shade: #28ba62;
|
||||
--ion-color-success-tint: #42d77d;
|
||||
|
||||
/** warning **/
|
||||
--ion-color-warning: #ffc409;
|
||||
--ion-color-warning-rgb: 255, 196, 9;
|
||||
--ion-color-warning-contrast: #000000;
|
||||
--ion-color-warning-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-warning-shade: #e0ac08;
|
||||
--ion-color-warning-tint: #ffca22;
|
||||
|
||||
/** danger **/
|
||||
--ion-color-danger: #eb445a;
|
||||
--ion-color-danger-rgb: 235, 68, 90;
|
||||
--ion-color-danger-contrast: #ffffff;
|
||||
--ion-color-danger-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-danger-shade: #cf3c4f;
|
||||
--ion-color-danger-tint: #ed576b;
|
||||
|
||||
/** dark **/
|
||||
--ion-color-dark: #222428;
|
||||
--ion-color-dark-rgb: 34, 36, 40;
|
||||
--ion-color-dark-contrast: #ffffff;
|
||||
--ion-color-dark-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-dark-shade: #1e2023;
|
||||
--ion-color-dark-tint: #383a3e;
|
||||
|
||||
/** medium **/
|
||||
--ion-color-medium: #92949c;
|
||||
--ion-color-medium-rgb: 146, 148, 156;
|
||||
--ion-color-medium-contrast: #ffffff;
|
||||
--ion-color-medium-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-medium-shade: #808289;
|
||||
--ion-color-medium-tint: #9d9fa6;
|
||||
|
||||
/** light **/
|
||||
--ion-color-light: #f4f5f8;
|
||||
--ion-color-light-rgb: 244, 245, 248;
|
||||
--ion-color-light-contrast: #000000;
|
||||
--ion-color-light-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-light-shade: #d7d8da;
|
||||
--ion-color-light-tint: #f5f6f9;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
/*
|
||||
* Dark Colors
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
body {
|
||||
--ion-color-primary: #428cff;
|
||||
--ion-color-primary-rgb: 66, 140, 255;
|
||||
--ion-color-primary-contrast: #ffffff;
|
||||
--ion-color-primary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-primary-shade: #3a7be0;
|
||||
--ion-color-primary-tint: #5598ff;
|
||||
|
||||
--ion-color-secondary: #50c8ff;
|
||||
--ion-color-secondary-rgb: 80, 200, 255;
|
||||
--ion-color-secondary-contrast: #ffffff;
|
||||
--ion-color-secondary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-secondary-shade: #46b0e0;
|
||||
--ion-color-secondary-tint: #62ceff;
|
||||
|
||||
--ion-color-tertiary: #6a64ff;
|
||||
--ion-color-tertiary-rgb: 106, 100, 255;
|
||||
--ion-color-tertiary-contrast: #ffffff;
|
||||
--ion-color-tertiary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-tertiary-shade: #5d58e0;
|
||||
--ion-color-tertiary-tint: #7974ff;
|
||||
|
||||
--ion-color-success: #2fdf75;
|
||||
--ion-color-success-rgb: 47, 223, 117;
|
||||
--ion-color-success-contrast: #000000;
|
||||
--ion-color-success-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-success-shade: #29c467;
|
||||
--ion-color-success-tint: #44e283;
|
||||
|
||||
--ion-color-warning: #ffd534;
|
||||
--ion-color-warning-rgb: 255, 213, 52;
|
||||
--ion-color-warning-contrast: #000000;
|
||||
--ion-color-warning-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-warning-shade: #e0bb2e;
|
||||
--ion-color-warning-tint: #ffd948;
|
||||
|
||||
--ion-color-danger: #ff4961;
|
||||
--ion-color-danger-rgb: 255, 73, 97;
|
||||
--ion-color-danger-contrast: #ffffff;
|
||||
--ion-color-danger-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-danger-shade: #e04055;
|
||||
--ion-color-danger-tint: #ff5b71;
|
||||
|
||||
--ion-color-dark: #f4f5f8;
|
||||
--ion-color-dark-rgb: 244, 245, 248;
|
||||
--ion-color-dark-contrast: #000000;
|
||||
--ion-color-dark-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-dark-shade: #d7d8da;
|
||||
--ion-color-dark-tint: #f5f6f9;
|
||||
|
||||
--ion-color-medium: #989aa2;
|
||||
--ion-color-medium-rgb: 152, 154, 162;
|
||||
--ion-color-medium-contrast: #000000;
|
||||
--ion-color-medium-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-medium-shade: #86888f;
|
||||
--ion-color-medium-tint: #a2a4ab;
|
||||
|
||||
--ion-color-light: #222428;
|
||||
--ion-color-light-rgb: 34, 36, 40;
|
||||
--ion-color-light-contrast: #ffffff;
|
||||
--ion-color-light-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-light-shade: #1e2023;
|
||||
--ion-color-light-tint: #383a3e;
|
||||
}
|
||||
|
||||
/*
|
||||
* iOS Dark Theme
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
.ios body {
|
||||
--ion-background-color: #000000;
|
||||
--ion-background-color-rgb: 0, 0, 0;
|
||||
|
||||
--ion-text-color: #ffffff;
|
||||
--ion-text-color-rgb: 255, 255, 255;
|
||||
|
||||
--ion-color-step-50: #0d0d0d;
|
||||
--ion-color-step-100: #1a1a1a;
|
||||
--ion-color-step-150: #262626;
|
||||
--ion-color-step-200: #333333;
|
||||
--ion-color-step-250: #404040;
|
||||
--ion-color-step-300: #4d4d4d;
|
||||
--ion-color-step-350: #595959;
|
||||
--ion-color-step-400: #666666;
|
||||
--ion-color-step-450: #737373;
|
||||
--ion-color-step-500: #808080;
|
||||
--ion-color-step-550: #8c8c8c;
|
||||
--ion-color-step-600: #999999;
|
||||
--ion-color-step-650: #a6a6a6;
|
||||
--ion-color-step-700: #b3b3b3;
|
||||
--ion-color-step-750: #bfbfbf;
|
||||
--ion-color-step-800: #cccccc;
|
||||
--ion-color-step-850: #d9d9d9;
|
||||
--ion-color-step-900: #e6e6e6;
|
||||
--ion-color-step-950: #f2f2f2;
|
||||
|
||||
--ion-item-background: #000000;
|
||||
|
||||
--ion-card-background: #1c1c1d;
|
||||
}
|
||||
|
||||
.ios ion-modal {
|
||||
--ion-background-color: var(--ion-color-step-100);
|
||||
--ion-toolbar-background: var(--ion-color-step-150);
|
||||
--ion-toolbar-border-color: var(--ion-color-step-250);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Material Design Dark Theme
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
.md body {
|
||||
--ion-background-color: #121212;
|
||||
--ion-background-color-rgb: 18, 18, 18;
|
||||
|
||||
--ion-text-color: #ffffff;
|
||||
--ion-text-color-rgb: 255, 255, 255;
|
||||
|
||||
--ion-border-color: #222222;
|
||||
|
||||
--ion-color-step-50: #1e1e1e;
|
||||
--ion-color-step-100: #2a2a2a;
|
||||
--ion-color-step-150: #363636;
|
||||
--ion-color-step-200: #414141;
|
||||
--ion-color-step-250: #4d4d4d;
|
||||
--ion-color-step-300: #595959;
|
||||
--ion-color-step-350: #656565;
|
||||
--ion-color-step-400: #717171;
|
||||
--ion-color-step-450: #7d7d7d;
|
||||
--ion-color-step-500: #898989;
|
||||
--ion-color-step-550: #949494;
|
||||
--ion-color-step-600: #a0a0a0;
|
||||
--ion-color-step-650: #acacac;
|
||||
--ion-color-step-700: #b8b8b8;
|
||||
--ion-color-step-750: #c4c4c4;
|
||||
--ion-color-step-800: #d0d0d0;
|
||||
--ion-color-step-850: #dbdbdb;
|
||||
--ion-color-step-900: #e7e7e7;
|
||||
--ion-color-step-950: #f3f3f3;
|
||||
|
||||
--ion-item-background: #1e1e1e;
|
||||
|
||||
--ion-toolbar-background: #1f1f1f;
|
||||
|
||||
--ion-tab-bar-background: #1f1f1f;
|
||||
|
||||
--ion-card-background: #1e1e1e;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
/*
|
||||
* For more information on dynamic font scaling, visit the documentation:
|
||||
* https://ionicframework.com/docs/layout/dynamic-font-scaling
|
||||
*/
|
||||
--ion-dynamic-font: var(--ion-default-dynamic-font);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Prevents Angular change detection from
|
||||
* running with certain Web Component callbacks
|
||||
*/
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
(window as any).__Zone_disable_customElements = true;
|
|
@ -8,7 +8,8 @@
|
|||
]
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts"
|
||||
"src/main.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.d.ts"
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"target": "es2022",
|
||||
"module": "es2022",
|
||||
"esModuleInterop": true,
|
||||
"useDefineForClassFields": true,
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"es2022",
|
||||
"dom"
|
||||
]
|
||||
],
|
||||
"useDefineForClassFields": true
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
"@angular/localize"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
|
|
Loading…
Reference in New Issue