Merge branch 'device-page' of selene repository into tartarus-overhaul branch
|
@ -0,0 +1,2 @@
|
|||
dist
|
||||
node_modules
|
|
@ -0,0 +1,13 @@
|
|||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
|
@ -0,0 +1,39 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
|
@ -0,0 +1,16 @@
|
|||
# Multistage Dockerfile to build the marketplace UI and a web server to run it
|
||||
|
||||
# STAGE ONE: build the marketplace angular application
|
||||
FROM node:latest as build
|
||||
WORKDIR /usr/src/app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
ARG selene_env
|
||||
ARG application_name
|
||||
RUN npm run build -- --project=globalnav
|
||||
RUN npm run build-${selene_env} -- --project=${application_name}
|
||||
|
||||
# STAGE TWO: build the web server and copy the compiled angular app to it.
|
||||
FROM nginx:latest
|
||||
COPY --from=build /usr/src/app/dist/${application_name} /usr/share/nginx/html
|
|
@ -0,0 +1,739 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"internet": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"styleext": "scss"
|
||||
}
|
||||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/internet",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "internet:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "internet:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "internet:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"internet-e2e": {
|
||||
"root": "e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "internet:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "internet:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"market": {
|
||||
"root": "projects/market/",
|
||||
"sourceRoot": "projects/market/src",
|
||||
"projectType": "application",
|
||||
"prefix": "market",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"styleext": "scss",
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:class": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:guard": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:module": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:pipe": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:service": {
|
||||
"spec": false
|
||||
}
|
||||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/market",
|
||||
"index": "projects/market/src/index.html",
|
||||
"main": "projects/market/src/main.ts",
|
||||
"polyfills": "projects/market/src/polyfills.ts",
|
||||
"tsConfig": "projects/market/tsconfig.app.json",
|
||||
"assets": [
|
||||
"projects/market/src/favicon.ico",
|
||||
"projects/market/src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/market/src/environments/environment.ts",
|
||||
"with": "projects/market/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/market/src/environments/environment.ts",
|
||||
"with": "projects/market/src/environments/environment.test.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"development": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/market/src/environments/environment.ts",
|
||||
"with": "projects/market/src/environments/environment.dev.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "market:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "market:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "market:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/market/src/test.ts",
|
||||
"polyfills": "projects/market/src/polyfills.ts",
|
||||
"tsConfig": "projects/market/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/market/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"projects/market/src/favicon.ico",
|
||||
"projects/market/src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/market/tsconfig.app.json",
|
||||
"projects/market/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"market-e2e": {
|
||||
"root": "projects/market-e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "projects/market-e2e/protractor.conf.js",
|
||||
"devServerTarget": "market:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "market:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "projects/market-e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sso": {
|
||||
"root": "projects/sso/",
|
||||
"sourceRoot": "projects/sso/src",
|
||||
"projectType": "application",
|
||||
"prefix": "sso",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"styleext": "scss",
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:class": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:guard": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:module": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:pipe": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:service": {
|
||||
"spec": false
|
||||
}
|
||||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/sso",
|
||||
"index": "projects/sso/src/index.html",
|
||||
"main": "projects/sso/src/main.ts",
|
||||
"polyfills": "projects/sso/src/polyfills.ts",
|
||||
"tsConfig": "projects/sso/tsconfig.app.json",
|
||||
"assets": [
|
||||
"projects/sso/src/favicon.ico",
|
||||
"projects/sso/src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/sso/src/environments/environment.ts",
|
||||
"with": "projects/sso/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/market/src/environments/environment.ts",
|
||||
"with": "projects/market/src/environments/environment.test.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"development": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/market/src/environments/environment.ts",
|
||||
"with": "projects/market/src/environments/environment.dev.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "sso:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "sso:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "sso:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/sso/src/test.ts",
|
||||
"polyfills": "projects/sso/src/polyfills.ts",
|
||||
"tsConfig": "projects/sso/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/sso/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"projects/sso/src/favicon.ico",
|
||||
"projects/sso/src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/sso/tsconfig.app.json",
|
||||
"projects/sso/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sso-e2e": {
|
||||
"root": "projects/sso-e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "projects/sso-e2e/protractor.conf.js",
|
||||
"devServerTarget": "sso:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "sso:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "projects/sso-e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalnav": {
|
||||
"root": "projects/globalnav",
|
||||
"sourceRoot": "projects/globalnav/src",
|
||||
"projectType": "library",
|
||||
"prefix": "globalnav",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/globalnav/tsconfig.lib.json",
|
||||
"project": "projects/globalnav/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/globalnav/src/test.ts",
|
||||
"tsConfig": "projects/globalnav/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/globalnav/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/globalnav/tsconfig.lib.json",
|
||||
"projects/globalnav/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account": {
|
||||
"root": "projects/account/",
|
||||
"sourceRoot": "projects/account/src",
|
||||
"projectType": "application",
|
||||
"prefix": "account",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"styleext": "scss",
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:class": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:guard": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:module": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:pipe": {
|
||||
"spec": false
|
||||
},
|
||||
"@schematics/angular:service": {
|
||||
"spec": false
|
||||
}
|
||||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/account",
|
||||
"index": "projects/account/src/index.html",
|
||||
"main": "projects/account/src/main.ts",
|
||||
"polyfills": "projects/account/src/polyfills.ts",
|
||||
"tsConfig": "projects/account/tsconfig.app.json",
|
||||
"assets": [
|
||||
"projects/account/src/favicon.ico",
|
||||
"projects/account/src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "projects/account/src/environments/environment.ts",
|
||||
"with": "projects/account/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "account:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "account:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "account:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/account/src/test.ts",
|
||||
"polyfills": "projects/account/src/polyfills.ts",
|
||||
"tsConfig": "projects/account/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/account/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"./src/stylesheets"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"projects/account/src/favicon.ico",
|
||||
"projects/account/src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/account/tsconfig.app.json",
|
||||
"projects/account/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"account-e2e": {
|
||||
"root": "projects/account-e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "projects/account-e2e/protractor.conf.js",
|
||||
"devServerTarget": "account:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "account:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "projects/account-e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"page-not-found": {
|
||||
"root": "projects/page-not-found",
|
||||
"sourceRoot": "projects/page-not-found/src",
|
||||
"projectType": "library",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/page-not-found/tsconfig.lib.json",
|
||||
"project": "projects/page-not-found/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/page-not-found/src/test.ts",
|
||||
"tsConfig": "projects/page-not-found/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/page-not-found/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/page-not-found/tsconfig.lib.json",
|
||||
"projects/page-not-found/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "internet"
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./src/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: require('path').join(__dirname, './tsconfig.e2e.json')
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
import { AppPage } from './app.po';
|
||||
|
||||
describe('workspace-project App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to internet!');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name": "internet",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"build-dev": "ng build --configuration=development",
|
||||
"build-test": "ng build --configuration=test",
|
||||
"build-prod": "ng build --prod",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~7.0.0",
|
||||
"@angular/cdk": "^7.0.1",
|
||||
"@angular/common": "~7.0.0",
|
||||
"@angular/compiler": "~7.0.0",
|
||||
"@angular/core": "~7.0.0",
|
||||
"@angular/flex-layout": "^7.0.0-beta.19",
|
||||
"@angular/forms": "~7.0.0",
|
||||
"@angular/http": "~7.0.0",
|
||||
"@angular/material": "^7.0.1",
|
||||
"@angular/platform-browser": "~7.0.0",
|
||||
"@angular/platform-browser-dynamic": "~7.0.0",
|
||||
"@angular/router": "~7.0.0",
|
||||
"@fortawesome/angular-fontawesome": "^0.3.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.7",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.4.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.4.2",
|
||||
"angular-font-awesome": "^3.1.2",
|
||||
"core-js": "^2.5.4",
|
||||
"font-awesome": "^4.7.0",
|
||||
"rxjs": "~6.3.3",
|
||||
"zone.js": "~0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.10.0",
|
||||
"@angular-devkit/build-ng-packagr": "~0.10.0",
|
||||
"@angular/cli": "~7.0.3",
|
||||
"@angular/compiler-cli": "~7.0.0",
|
||||
"@angular/language-service": "~7.0.0",
|
||||
"@types/node": "~8.9.4",
|
||||
"@types/jasmine": "~2.8.8",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"codelyzer": "~4.5.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~3.0.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
||||
"karma-jasmine": "~1.1.2",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"ng-packagr": "^4.2.0",
|
||||
"protractor": "~5.4.0",
|
||||
"ts-node": "~7.0.0",
|
||||
"tsickle": ">=0.29.0",
|
||||
"tslib": "^1.9.0",
|
||||
"tslint": "~5.11.0",
|
||||
"typescript": "~3.1.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
#
|
||||
# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
|
||||
|
||||
> 0.5%
|
||||
last 2 versions
|
||||
Firefox ESR
|
||||
not dead
|
||||
not IE 9-11
|
|
@ -0,0 +1,31 @@
|
|||
// 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-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage'),
|
||||
reports: ['html', 'lcovonly'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
});
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"/api/*": {
|
||||
"target": "http://localhost:5003",
|
||||
"secure": false,
|
||||
"logLevel": "debug",
|
||||
"changeOrigin": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { DeviceComponent } from './device/device.component';
|
||||
import { PageNotFoundComponent } from 'page-not-found';
|
||||
import { ProfileComponent } from './profile/profile.component';
|
||||
// import { SkillComponent } from './skill/skill.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'device', component: DeviceComponent },
|
||||
{ path: 'profile', component: ProfileComponent },
|
||||
// { path: 'skill', component: ProfileComponent },
|
||||
{ path: '', redirectTo: '/profile', pathMatch: 'full' },
|
||||
{ path: '**', component: PageNotFoundComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<globalnav-sidenav
|
||||
[mycroftUrls]="environment.mycroftUrls"
|
||||
[user$]="user$"
|
||||
>
|
||||
<!--
|
||||
Inject the marketplace app into the <mat-sidenav-content> component
|
||||
of the global navigation menu library.
|
||||
-->
|
||||
<div appBody id="account-body">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</globalnav-sidenav>
|
|
@ -0,0 +1,14 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { environment } from '../environments/environment';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'account-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent {
|
||||
public environment = environment;
|
||||
title = 'account';
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { GlobalnavModule } from 'globalnav';
|
||||
import { PageNotFoundModule } from 'page-not-found';
|
||||
import { DeviceModule } from './device/device.module';
|
||||
import { ProfileModule } from './profile/profile.module';
|
||||
|
||||
@NgModule(
|
||||
{
|
||||
// declarations: [ AppComponent, PageNotFoundComponent ],
|
||||
declarations: [ AppComponent ],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
GlobalnavModule,
|
||||
HttpClientModule,
|
||||
DeviceModule,
|
||||
PageNotFoundModule,
|
||||
ProfileModule,
|
||||
AppRoutingModule
|
||||
],
|
||||
providers: [ ],
|
||||
bootstrap: [ AppComponent ]
|
||||
}
|
||||
)
|
||||
export class AppModule { }
|
|
@ -0,0 +1,39 @@
|
|||
<div mat-dialog-title class="mat-h2-primary">{{dialogTitle}}</div>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<div class="mat-body">{{dialogInstructions}}</div>
|
||||
<mat-radio-group fxLayout="column" [(ngModel)]="dialogData">
|
||||
<ng-container *ngFor="let possibleValue of possibleValues">
|
||||
|
||||
<!-- Radio buttons for pre-defined placements -->
|
||||
<mat-radio-button *ngIf="possibleValue.preDefined" class="predefined-group" [value]="possibleValue.name">
|
||||
{{possibleValue.name}}
|
||||
</mat-radio-button>
|
||||
|
||||
<!-- Radio buttons for user-defined placements -->
|
||||
<div *ngIf="!possibleValue.preDefined" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<mat-radio-button [value]="possibleValue.name">
|
||||
<mat-form-field [floatLabel]="'never'">
|
||||
<input matInput class="user-defined-group" value="{{possibleValue.name}}">
|
||||
</mat-form-field>
|
||||
</mat-radio-button>
|
||||
<button mat-icon-button [disableRipple]="true">
|
||||
<fa-icon [icon]="deleteIcon"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<!-- Radio button to add a new user-defined group -->
|
||||
<mat-radio-button>
|
||||
<mat-form-field [floatLabel]="'never'">
|
||||
<input matInput placeholder="Add {{dialogTitle}}">
|
||||
</mat-form-field>
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions align="end">
|
||||
<button mat-button (click)="onCancelClick()">CANCEL</button>
|
||||
<button mat-button class="attribute-save-button" [mat-dialog-close]="dialogData">SAVE</button>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
@import '~@angular/material/theming';
|
||||
@import '~src/stylesheets/mycroft-colors';
|
||||
@import '~src/stylesheets/components/buttons';
|
||||
|
||||
.predefined-group {
|
||||
margin-bottom: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.mat-body{
|
||||
margin-bottom: 16px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
color: mat-color($mycroft-warn);
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.attribute-save-button {
|
||||
@include action-button-primary;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
|
||||
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { DeviceAttribute } from '../device.service';
|
||||
import { GeographyEditComponent } from './geography/geography-edit.component';
|
||||
import { GroupEditComponent } from './group/group-edit.component';
|
||||
import { PlacementEditComponent } from './placement/placement-edit.component';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-attribute-edit',
|
||||
templateUrl: './attr-edit.component.html',
|
||||
styleUrls: ['./attr-edit.component.scss']
|
||||
})
|
||||
export class AttrEditComponent implements OnInit {
|
||||
@Input() dialogData: string;
|
||||
@Input() dialogInstructions: string;
|
||||
@Input() dialogRef: MatDialogRef<GeographyEditComponent | GroupEditComponent | PlacementEditComponent>;
|
||||
@Input() dialogTitle: string;
|
||||
@Input() possibleValues: DeviceAttribute[];
|
||||
public deleteIcon = faTrashAlt;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onCancelClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<mat-form-field [appearance]="'outline'" (click)="onClick()">
|
||||
<mat-label>{{label}}</mat-label>
|
||||
<div fxLayout="row" fxLayoutAlign="none center">
|
||||
<input
|
||||
matInput
|
||||
[readonly]="true"
|
||||
type="text"
|
||||
value="{{value.name}}"
|
||||
>
|
||||
<fa-icon matSuffix [icon]="editIcon" style="font-size: 16px;"></fa-icon>
|
||||
</div>
|
||||
<mat-hint>{{hint}}</mat-hint>
|
||||
</mat-form-field>
|
|
@ -0,0 +1,9 @@
|
|||
mat-form-field {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
padding-right: 10px
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
|
||||
import { faCaretRight } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-attribute-view',
|
||||
templateUrl: './attr-view.component.html',
|
||||
styleUrls: ['./attr-view.component.scss']
|
||||
})
|
||||
export class AttrViewComponent implements OnInit {
|
||||
@Input() editDialog: any;
|
||||
@Input() hint: string;
|
||||
@Input() label: string;
|
||||
@Input() possibleValues: any[];
|
||||
@Input() value: any;
|
||||
public editIcon = faCaretRight;
|
||||
|
||||
constructor(private dialog: MatDialog) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onClick() {
|
||||
const dialogRef = this.dialog.open(this.editDialog, { data: this.value.name });
|
||||
dialogRef.afterClosed().subscribe(
|
||||
(result) => { this.updateDevice(result); }
|
||||
);
|
||||
}
|
||||
|
||||
updateDevice(newValue: string) {
|
||||
if (newValue) {
|
||||
this.possibleValues.forEach(
|
||||
(value) => {
|
||||
if (value.name === newValue) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<account-device-attribute-edit
|
||||
[dialogData]="data"
|
||||
[dialogInstructions]="dialogInstructions"
|
||||
[dialogRef]="dialogRef"
|
||||
[dialogTitle]="'Geography'"
|
||||
[possibleValues]="deviceGeographies"
|
||||
>
|
||||
</account-device-attribute-edit>
|
||||
<!--<div mat-dialog-title class="mat-h2-primary">Geography</div>-->
|
||||
|
||||
<!--<div mat-dialog-content>-->
|
||||
<!--<div class="mat-body">-->
|
||||
<!--Groups are useful to organize multiple devices. You can reuse device names if they are in different groups.-->
|
||||
<!--</div>-->
|
||||
<!--<mat-radio-group fxLayout="column" [(ngModel)]="data">-->
|
||||
<!--<ng-container *ngFor="let geo of deviceGeographies">-->
|
||||
<!--<!– Radio buttons for user-defined groups –>-->
|
||||
<!--<div fxLayout="row" fxLayoutAlign="space-between center">-->
|
||||
<!--<mat-radio-button [value]="geo.name">-->
|
||||
<!--<mat-form-field [floatLabel]="'never'">-->
|
||||
<!--<input matInput value="{{geo.name}}">-->
|
||||
<!--</mat-form-field>-->
|
||||
<!--</mat-radio-button>-->
|
||||
<!--<button mat-icon-button [disableRipple]="true">-->
|
||||
<!--<fa-icon class="danger-icon" [icon]="deleteIcon"></fa-icon>-->
|
||||
<!--</button>-->
|
||||
<!--</div>-->
|
||||
|
||||
<!--</ng-container>-->
|
||||
|
||||
<!--<!– Radio button to add a new user-defined group –>-->
|
||||
<!--<mat-radio-button>-->
|
||||
<!--<mat-form-field [floatLabel]="'never'">-->
|
||||
<!--<input matInput placeholder="Add Geographic Location">-->
|
||||
<!--</mat-form-field>-->
|
||||
<!--</mat-radio-button>-->
|
||||
<!--</mat-radio-group>-->
|
||||
<!--</div>-->
|
||||
|
||||
<!--<div mat-dialog-actions align="end">-->
|
||||
<!--<button mat-button (click)="onCancelClick()">CANCEL</button>-->
|
||||
<!--<button mat-button [mat-dialog-close]="data" class="action-button">SAVE</button>-->
|
||||
<!--</div>-->
|
|
@ -0,0 +1,25 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
import { DeviceAttribute, DeviceService} from '../../device.service';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-geography-edit',
|
||||
templateUrl: './geography-edit.component.html',
|
||||
styleUrls: ['./geography-edit.component.scss']
|
||||
})
|
||||
export class GeographyEditComponent implements OnInit {
|
||||
public deviceGeographies: DeviceAttribute[];
|
||||
public dialogInstructions = '';
|
||||
|
||||
constructor(
|
||||
private deviceService: DeviceService,
|
||||
public dialogRef: MatDialogRef<GeographyEditComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: string) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.deviceGeographies = this.deviceService.deviceGeographies;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<account-device-attribute-view
|
||||
[editDialog]="dialog"
|
||||
[hint]="'Country, postal code, time zone'"
|
||||
[label]="'Geography'"
|
||||
[possibleValues]="deviceGeographies"
|
||||
[value]="device.location"
|
||||
>
|
||||
</account-device-attribute-view>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { Device, DeviceAttribute, DeviceService } from '../../device.service';
|
||||
import { GeographyEditComponent } from './geography-edit.component';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-geography-view',
|
||||
templateUrl: './geography-view.component.html',
|
||||
styleUrls: ['./geography-view.component.scss']
|
||||
})
|
||||
export class GeographyViewComponent implements OnInit {
|
||||
@Input() device: Device;
|
||||
public deviceGeographies: DeviceAttribute[];
|
||||
public dialog = GeographyEditComponent;
|
||||
|
||||
constructor( private service: DeviceService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.deviceGeographies = this.service.deviceGeographies;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<account-device-attribute-edit
|
||||
[dialogData]="data"
|
||||
[dialogInstructions]="dialogInstructions"
|
||||
[dialogRef]="dialogRef"
|
||||
[dialogTitle]="'Group'"
|
||||
[possibleValues]="deviceGroups"
|
||||
>
|
||||
</account-device-attribute-edit>
|
|
@ -0,0 +1,25 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
import { DeviceAttribute, DeviceService} from '../../device.service';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-group-edit',
|
||||
templateUrl: './group-edit.component.html',
|
||||
styleUrls: ['./group-edit.component.scss']
|
||||
})
|
||||
export class GroupEditComponent implements OnInit {
|
||||
public deviceGroups: DeviceAttribute[];
|
||||
public dialogInstructions = 'Groups are useful to organize multiple ' +
|
||||
'devices. You can reuse device names if they are in different groups.';
|
||||
|
||||
constructor(
|
||||
private deviceService: DeviceService,
|
||||
public dialogRef: MatDialogRef<GroupEditComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: DeviceAttribute) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.deviceGroups = this.deviceService.deviceGroups;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<account-device-attribute-view
|
||||
[editDialog]="dialog"
|
||||
[hint]="'Mechanism to categorize devices'"
|
||||
[label]="'Group'"
|
||||
[possibleValues]="deviceGroups"
|
||||
[value]="device.group"
|
||||
>
|
||||
</account-device-attribute-view>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { Device, DeviceAttribute, DeviceService } from '../../device.service';
|
||||
import { GroupEditComponent } from './group-edit.component';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-group-view',
|
||||
templateUrl: './group-view.component.html',
|
||||
styleUrls: ['./group-view.component.scss']
|
||||
})
|
||||
export class GroupViewComponent implements OnInit {
|
||||
@Input() device: Device;
|
||||
public deviceGroups: DeviceAttribute[];
|
||||
public dialog = GroupEditComponent;
|
||||
|
||||
constructor( private service: DeviceService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.deviceGroups = this.service.deviceGroups;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<account-device-attribute-edit
|
||||
[dialogData]="data"
|
||||
[dialogInstructions]="dialogInstructions"
|
||||
[dialogRef]="dialogRef"
|
||||
[dialogTitle]="'Placement'"
|
||||
[possibleValues]="devicePlacements"
|
||||
>
|
||||
</account-device-attribute-edit>
|
|
@ -0,0 +1,26 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
import { DeviceAttribute, DeviceService} from '../../device.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-placement-edit',
|
||||
templateUrl: './placement-edit.component.html',
|
||||
styleUrls: ['./placement-edit.component.scss']
|
||||
})
|
||||
export class PlacementEditComponent implements OnInit {
|
||||
public devicePlacements: DeviceAttribute[];
|
||||
public dialogInstructions = 'You can optionally indicate where a device is ' +
|
||||
'placed within a location. Field is informational only.';
|
||||
|
||||
constructor(
|
||||
private deviceService: DeviceService,
|
||||
public dialogRef: MatDialogRef<PlacementEditComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: string) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.devicePlacements = this.deviceService.devicePlacements;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<account-device-attribute-view
|
||||
[editDialog]="dialog"
|
||||
[hint]="'Where a device is placed within a location'"
|
||||
[label]="'Placement'"
|
||||
[possibleValues]="devicePlacements"
|
||||
[value]="device.placement"
|
||||
>
|
||||
</account-device-attribute-view>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import {Device, DeviceAttribute, DeviceService} from '../../device.service';
|
||||
import { PlacementEditComponent } from './placement-edit.component';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-placement-view',
|
||||
templateUrl: './placement-view.component.html',
|
||||
styleUrls: ['./placement-view.component.scss']
|
||||
})
|
||||
export class PlacementViewComponent implements OnInit {
|
||||
@Input() device: Device;
|
||||
public devicePlacements: DeviceAttribute[];
|
||||
public dialog = PlacementEditComponent;
|
||||
|
||||
constructor( private service: DeviceService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.devicePlacements = this.service.devicePlacements;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<div class="app-body">
|
||||
|
||||
<!-- Button for adding a new device centered at top of page-->
|
||||
<div fxLayout="row" fxLayoutAlign="center">
|
||||
<button fxFlex mat-flat-button class="action-button">
|
||||
<div fxLayout="row" fxLayoutAlign="space-between">
|
||||
<span class="mat-h2">ADD DEVICE</span>
|
||||
<fa-icon [icon]="addIcon"></fa-icon>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Device listing - show summary in expansion panel header and editable fields in expansion panel detail -->
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start start">
|
||||
<mat-expansion-panel *ngFor="let device of devices">
|
||||
|
||||
<!-- Put the platform icon, device name and device placement in the panel header -->
|
||||
<mat-expansion-panel-header fxLayout="row" fxLayoutAlign="start center" [expandedHeight]="'100px'" [collapsedHeight]="'100px'">
|
||||
<img [src]="getDeviceIcon(device)"/>
|
||||
<div>
|
||||
<div class="mat-h2-primary">{{device.name}}</div>
|
||||
<div class="mat-subheader">{{device.placement.name}}</div>
|
||||
</div>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<!-- Navigation to skill settings for this device. -->
|
||||
<button mat-flat-button color="primary" class="settings-button">
|
||||
<fa-icon [icon]="settingsIcon"></fa-icon>
|
||||
SKILL SETTINGS
|
||||
</button>
|
||||
|
||||
<mat-form-field [appearance]="'outline'">
|
||||
<mat-label>Name</mat-label>
|
||||
<input
|
||||
id="deviceName"
|
||||
matInput
|
||||
name="deviceName"
|
||||
required
|
||||
type="text"
|
||||
value="{{device.name}}"
|
||||
>
|
||||
<mat-hint>Must be unique within a device group (if defined)</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<account-device-group-view [device]="device"></account-device-group-view>
|
||||
<account-device-geography-view [device]="device"></account-device-geography-view>
|
||||
<account-device-placement-view [device]="device"></account-device-placement-view>
|
||||
|
||||
<!-- Static fields that display platform, software version and hardware version -->
|
||||
<div *ngFor="let staticData of defineStaticDeviceFields(device)">
|
||||
<span class="mat-body">{{staticData.name}}: </span>
|
||||
<span class="mat-body-primary">{{staticData.value}}</span>
|
||||
</div>
|
||||
|
||||
<!-- Last but not least, the delete device button -->
|
||||
<button mat-flat-button color="warn" class="delete-button" (click)="onRemovalClick(device)">
|
||||
<fa-icon [icon]="deleteIcon"></fa-icon>
|
||||
REMOVE DEVICE
|
||||
</button>
|
||||
</mat-expansion-panel>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,61 @@
|
|||
.action-button {
|
||||
border-radius: 12px;
|
||||
height: 100px;
|
||||
margin-bottom: 20px;
|
||||
max-width: 350px;
|
||||
min-width: 250px;
|
||||
|
||||
.mat-h2 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
color: yellow;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
mat-expansion-panel {
|
||||
border-radius: 12px;
|
||||
margin: 10px;
|
||||
max-width: 350px;
|
||||
min-width: 250px;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
padding-right: 10px
|
||||
}
|
||||
|
||||
img {
|
||||
height: 60px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mat-body-primary {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mat-h2-primary {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mat-subheader {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.settings-button {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
|
||||
import { faCogs, faPlusCircle, faTrash } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { DeviceService, Device } from './device.service';
|
||||
import { RemoveComponent } from './remove/remove.component';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device',
|
||||
templateUrl: './device.component.html',
|
||||
styleUrls: ['./device.component.scss']
|
||||
})
|
||||
export class DeviceComponent implements OnInit {
|
||||
public addIcon = faPlusCircle;
|
||||
public deleteIcon = faTrash;
|
||||
public devices: Device[];
|
||||
public platforms = {
|
||||
'mark-one': {icon: '../assets/mark-1-icon.svg', displayName: 'Mark I'},
|
||||
'mark-two': {icon: '../assets/mark-2-icon.svg', displayName: 'Mark II'},
|
||||
'picroft': {icon: '../assets/picroft-icon.svg', displayName: 'Picroft'},
|
||||
'kde': {icon: '../assets/kde-icon.svg', displayName: 'KDE'}
|
||||
};
|
||||
public settingsIcon = faCogs;
|
||||
private selectedDevice: Device;
|
||||
|
||||
constructor(public dialog: MatDialog, private deviceService: DeviceService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.devices = this.deviceService.devices;
|
||||
}
|
||||
|
||||
onRemovalClick (device: Device) {
|
||||
const removalDialogRef = this.dialog.open(RemoveComponent, {data: false});
|
||||
this.selectedDevice = device;
|
||||
removalDialogRef.afterClosed().subscribe(
|
||||
(result) => {
|
||||
if (result) { this.deviceService.deleteDevice(device); }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
defineStaticDeviceFields(device: Device) {
|
||||
const knownPlatform = this.platforms[device.platform];
|
||||
return [
|
||||
{name: 'Platform', value: knownPlatform ? knownPlatform.displayName : device.platform},
|
||||
{name: 'Core Version', value: device.coreVersion},
|
||||
{name: 'Enclosure Version', value: device.enclosureVersion}
|
||||
];
|
||||
}
|
||||
|
||||
getDeviceIcon(device: Device) {
|
||||
const knownPlatform = this.platforms[device.platform];
|
||||
// TODO: get unknown product icon from design team.
|
||||
return knownPlatform ? knownPlatform.icon : '../assets/mark-1-icon.svg';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import {
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatDialogModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatRadioModule,
|
||||
MatSelectModule,
|
||||
} from '@angular/material';
|
||||
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
|
||||
import { AttrEditComponent } from './attribute/attr-edit.component';
|
||||
import { AttrViewComponent } from './attribute/attr-view.component';
|
||||
import { DeviceComponent } from './device.component';
|
||||
import { DeviceService } from './device.service';
|
||||
import { GeographyEditComponent } from './attribute/geography/geography-edit.component';
|
||||
import { GeographyViewComponent } from './attribute/geography/geography-view.component';
|
||||
import { GroupEditComponent } from './attribute/group/group-edit.component';
|
||||
import { GroupViewComponent } from './attribute/group/group-view.component';
|
||||
import { PlacementEditComponent } from './attribute/placement/placement-edit.component';
|
||||
import { PlacementViewComponent } from './attribute/placement/placement-view.component';
|
||||
import { RemoveComponent } from './remove/remove.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AttrEditComponent,
|
||||
AttrViewComponent,
|
||||
DeviceComponent,
|
||||
GeographyEditComponent,
|
||||
GeographyViewComponent,
|
||||
GroupEditComponent,
|
||||
GroupViewComponent,
|
||||
PlacementEditComponent,
|
||||
PlacementViewComponent,
|
||||
RemoveComponent
|
||||
],
|
||||
entryComponents: [
|
||||
GeographyEditComponent,
|
||||
GroupEditComponent,
|
||||
PlacementEditComponent,
|
||||
RemoveComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
DragDropModule,
|
||||
FlexLayoutModule,
|
||||
FontAwesomeModule,
|
||||
FormsModule,
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatDialogModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatRadioModule,
|
||||
MatSelectModule,
|
||||
],
|
||||
providers: [
|
||||
DeviceService
|
||||
]
|
||||
})
|
||||
export class DeviceModule { }
|
|
@ -0,0 +1,91 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface DeviceAttribute {
|
||||
id?: string;
|
||||
name: string;
|
||||
preDefined: boolean;
|
||||
}
|
||||
|
||||
export interface Device {
|
||||
coreVersion: string;
|
||||
enclosureVersion: string;
|
||||
group: DeviceAttribute;
|
||||
id: string;
|
||||
location: DeviceAttribute;
|
||||
name: string;
|
||||
placement: DeviceAttribute;
|
||||
platform: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DeviceService {
|
||||
public devices: Device[] = [
|
||||
{
|
||||
coreVersion: '18.08',
|
||||
enclosureVersion: '1.2.3',
|
||||
group: {id: '1', name: 'None', preDefined: true},
|
||||
id: 'abc-def-ghi',
|
||||
location: {id: '1a2b-3c4d-5e6f', name: 'United States, 64101, CST', preDefined: false},
|
||||
name: 'Mark',
|
||||
placement: {id: 'bbb-bbb-bbb', name: 'Living Room', preDefined: false},
|
||||
platform: 'mark-one'
|
||||
},
|
||||
{
|
||||
coreVersion: '18.08',
|
||||
enclosureVersion: '1.2.3',
|
||||
group: {id: '1', name: 'None', preDefined: true},
|
||||
id: 'bcd-efg-hij',
|
||||
location: {id: '1a2b-3c4d-5e6f', name: 'United States, 64101, CST', preDefined: false},
|
||||
name: 'Marky Mark',
|
||||
placement: {id: 'bbb-bbb-bbb', name: 'Kitchen', preDefined: true},
|
||||
platform: 'mark-two'
|
||||
},
|
||||
{
|
||||
coreVersion: '18.08',
|
||||
enclosureVersion: '1.2.3',
|
||||
group: {id: '2', name: 'Parent House', preDefined: false},
|
||||
id: 'cde-fgh-ijk',
|
||||
location: {id: '1a2b-3c4d-5e6f', name: 'United States, 64101, CST', preDefined: false},
|
||||
name: 'American Pie',
|
||||
placement: {id: 'ddd-ddd-ddd', name: 'Bedroom', preDefined: true},
|
||||
platform: 'picroft'
|
||||
},
|
||||
{
|
||||
coreVersion: '18.08',
|
||||
enclosureVersion: '1.2.3',
|
||||
group: {id: '2', name: 'Parent House', preDefined: false},
|
||||
id: 'def-ghi-jkl',
|
||||
location: {id: '1a2b-3c4d-5e6f', name: 'United States, 64101, CST', preDefined: false},
|
||||
name: 'Kappa Delta Epsilon',
|
||||
placement: {id: 'fff-fff-fff', name: 'Kitchen', preDefined: true},
|
||||
platform: 'kde'
|
||||
}
|
||||
];
|
||||
|
||||
public deviceGroups: DeviceAttribute[] = [
|
||||
{ id: '1', name: 'None', preDefined: true},
|
||||
{ id: null, name: 'Home', preDefined: true},
|
||||
{ id: null, name: 'Office', preDefined: true},
|
||||
{ id: '2', name: 'Parent House', preDefined: false}
|
||||
];
|
||||
|
||||
public devicePlacements: DeviceAttribute[] = [
|
||||
{ id: '1', name: 'None', preDefined: true},
|
||||
{ id: null, name: 'Bedroom', preDefined: true},
|
||||
{ id: null, name: 'Kitchen', preDefined: true},
|
||||
{ id: '2', name: 'Living Room', preDefined: false}
|
||||
];
|
||||
|
||||
public deviceGeographies: DeviceAttribute[] = [
|
||||
{id: '1a2b-3c4d-5e6f', name: 'United States, 64101, CST', preDefined: false},
|
||||
{id: 'a1b2-c3d4-e5f6', name: 'United Kingdom, ABCDE, BST', preDefined: false}
|
||||
];
|
||||
|
||||
constructor() { }
|
||||
|
||||
deleteDevice(device: Device): void {
|
||||
console.log('deleting device... ');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<div mat-dialog-title class="mat-h2-primary">Remove Device</div>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<div class="mat-body">
|
||||
Just double checking. Device removal cannot be undone.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions align="end">
|
||||
<button id="device-remove-cancel-button" mat-button (click)="onCancelClick()">CANCEL</button>
|
||||
<button id="device-remove-button" mat-button [mat-dialog-close]="true">REMOVE</button>
|
||||
</div>
|
|
@ -0,0 +1,10 @@
|
|||
@import '~src/stylesheets/components/buttons';
|
||||
|
||||
.mat-body{
|
||||
margin-bottom: 16px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
#device-remove-button {
|
||||
@include action-button-warn;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import {Component, Inject, OnInit} from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector: 'account-device-remove',
|
||||
templateUrl: './remove.component.html',
|
||||
styleUrls: ['./remove.component.scss']
|
||||
})
|
||||
export class RemoveComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<RemoveComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: boolean) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
onCancelClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<mat-card class="section-card">
|
||||
<mat-toolbar class="section-card-title-bar">
|
||||
<div class="section-card-title">Agreements</div>
|
||||
</mat-toolbar>
|
||||
<div id="agreement-panels">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Terms of Use
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Accepted July 10, 2018
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
Terms of Use goes here.
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Privacy Policy
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Accepted July 10, 2018
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
Privacy Policy goes here.
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Open Data Set
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Opted In July 10, 2018
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
Open Data Set agreement goes here.
|
||||
<mat-action-row>
|
||||
<button mat-button>OPT OUT</button>
|
||||
</mat-action-row>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
</mat-card>
|
|
@ -0,0 +1,3 @@
|
|||
#agreement-panels {
|
||||
margin: 8px;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'account-agreements',
|
||||
templateUrl: './agreements.component.html',
|
||||
styleUrls: ['./agreements.component.scss']
|
||||
})
|
||||
export class AgreementsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<mat-card class="section-card">
|
||||
<mat-toolbar class="section-card-title-bar">
|
||||
<div class="section-card-title">Delete Account</div>
|
||||
</mat-toolbar>
|
||||
<div fxLayout="column">
|
||||
<span class="mat-h3">CAUTION</span>
|
||||
<div id="delete-warning">
|
||||
<div *ngFor="let paragraph of deleteWarning" class="mat-body-2">{{paragraph}}</div>
|
||||
</div>
|
||||
<button mat-raised-button color="warn">DELETE ACCOUNT</button>
|
||||
</div>
|
||||
</mat-card>
|
|
@ -0,0 +1,21 @@
|
|||
mat-card {
|
||||
button {
|
||||
color: white;
|
||||
margin-bottom: 10px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#delete-warning {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.mat-body-2 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-h3 {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'account-delete',
|
||||
templateUrl: './delete.component.html',
|
||||
styleUrls: ['./delete.component.scss']
|
||||
})
|
||||
export class DeleteComponent implements OnInit {
|
||||
public deleteWarning: string[];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
this.deleteWarning = [
|
||||
'Pressing the button below will delete your account and all data related to it from Mycroft servers.',
|
||||
'It cannot be undone.'
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<mat-card class="section-card">
|
||||
<mat-toolbar class="section-card-title-bar">
|
||||
<div class="section-card-title">Login</div>
|
||||
</mat-toolbar>
|
||||
<div fxLayout="row wrap" fxLayoutAlign="space-around">
|
||||
<div id="antisocial-login" fxFlex fxLayout="column" fxLayoutAlign="start stretch">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Email Address</mat-label>
|
||||
<input
|
||||
id="emailAddress"
|
||||
matInput
|
||||
name="emailAddress"
|
||||
placeholder="Enter Email Address"
|
||||
required
|
||||
type="email"
|
||||
>
|
||||
<mat-hint>Uniquely identifies your account</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Password</mat-label>
|
||||
<input
|
||||
id="password"
|
||||
matInput
|
||||
name="password"
|
||||
placeholder="Enter a Secure Password"
|
||||
type="password"
|
||||
>
|
||||
<mat-hint>Required when no external account is linked</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div id="social-login" fxFlex fxLayout="column">
|
||||
<div class="mat-subheading-2">Social Login</div>
|
||||
<div class="mat-body">Connect to a platform for faster login.</div>
|
||||
<div id="social-platform" *ngFor="let platform of socialPlatforms" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<img *ngIf="platform.image" [src]="platform.image"/>
|
||||
<fa-icon *ngIf="platform.icon" [icon]="platform.icon"></fa-icon>
|
||||
<mat-label>{{platform.label}}</mat-label>
|
||||
</div>
|
||||
<button mat-flat-button class="action-button">CONNECT</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
|
@ -0,0 +1,40 @@
|
|||
#antisocial-login {
|
||||
margin: 16px;
|
||||
|
||||
mat-form-field {
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#social-login {
|
||||
margin: 16px;
|
||||
|
||||
.mat-subheading-2 {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#social-platform {
|
||||
margin: 8px;
|
||||
|
||||
fa-icon {
|
||||
font-size: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
mat-label {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { faGithub, IconDefinition } from '@fortawesome/free-brands-svg-icons';
|
||||
|
||||
export interface ToggleLabel {
|
||||
label: string;
|
||||
image?: string;
|
||||
icon?: IconDefinition;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'account-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.scss']
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
public socialPlatforms: ToggleLabel[];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
const githubLabel: ToggleLabel = {
|
||||
label: 'GitHub',
|
||||
icon: faGithub
|
||||
};
|
||||
const googleLabel: ToggleLabel = {
|
||||
label: 'Google',
|
||||
image: '../../assets/google-logo.png'
|
||||
};
|
||||
const facebookLabel: ToggleLabel = {
|
||||
label: 'Facebook',
|
||||
image: '../../assets/facebook_logo.png'
|
||||
};
|
||||
|
||||
this.socialPlatforms = [googleLabel, facebookLabel, githubLabel];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<mat-card class="section-card">
|
||||
<mat-toolbar class="section-card-title-bar">
|
||||
<div class="section-card-title">PERSONAL</div>
|
||||
</mat-toolbar>
|
||||
<form>
|
||||
<div fxLayout="row wrap">
|
||||
|
||||
<!-- first and last name fields go on left when screen is large enough -->
|
||||
<div id="user-name" fxFlex fxLayout="column">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>First Name</mat-label>
|
||||
<input
|
||||
id="firstName2"
|
||||
matInput
|
||||
name="lastName"
|
||||
placeholder="Enter First Name"
|
||||
type="text"
|
||||
>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Last Name</mat-label>
|
||||
<input
|
||||
id="lastName2"
|
||||
matInput
|
||||
name="lastName"
|
||||
placeholder="Enter Last Name"
|
||||
type="text"
|
||||
>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- location fields go on right when screen is large enough -->
|
||||
<div id="user-location" fxFlex fxLayout="column">
|
||||
<mat-form-field appearance=outline>
|
||||
<mat-label>Country</mat-label>
|
||||
<mat-select>
|
||||
<mat-option value="option1">Option 1</mat-option>
|
||||
<mat-option value="option2" disabled>Option 2 (disabled)</mat-option>
|
||||
<mat-option value="option3">Option 3</mat-option>
|
||||
</mat-select>
|
||||
<mat-hint>Filter for postal code and time zone</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance=outline>
|
||||
<mat-label>Postal Code</mat-label>
|
||||
<mat-select placeholder="Select country">
|
||||
<mat-option value="option1">Option 1</mat-option>
|
||||
<mat-option value="option2" disabled>Option 2 (disabled)</mat-option>
|
||||
<mat-option value="option3">Option 3</mat-option>
|
||||
</mat-select>
|
||||
<mat-hint>Default postal code for skills (e.g. weather)</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance=outline>
|
||||
<mat-label>Time Zone</mat-label>
|
||||
<mat-select>
|
||||
<mat-option value="option1">Option 1</mat-option>
|
||||
<mat-option value="option2" disabled>Option 2 (disabled)</mat-option>
|
||||
<mat-option value="option3">Option 3</mat-option>
|
||||
</mat-select>
|
||||
<mat-hint>Default time zone for skills (e.g. alarm clock)</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</mat-card>
|
|
@ -0,0 +1,45 @@
|
|||
@import '~@angular/material/theming';
|
||||
@import "mycroft-colors";
|
||||
|
||||
// Angular Material does not support a form field with a map control inside it.
|
||||
// Do our best to make this look like the other form fields
|
||||
@mixin mimic-form-field {
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 6px;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
padding: 15px;
|
||||
|
||||
&:hover {
|
||||
border: 2px solid rgba(0, 0, 0, 0.87);
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
legend {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
margin-left: -7px;
|
||||
padding-top: 5px;
|
||||
padding-left: 3px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
|
||||
mat-form-field {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
@include mimic-form-field;
|
||||
.map {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'account-personal',
|
||||
templateUrl: './personal.component.html',
|
||||
styleUrls: ['./personal.component.scss']
|
||||
})
|
||||
export class PersonalComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() { }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<div>
|
||||
<account-login></account-login>
|
||||
<account-subscription></account-subscription>
|
||||
<!--<account-personal></account-personal>-->
|
||||
<account-agreements></account-agreements>
|
||||
<account-delete></account-delete>
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'account-profile',
|
||||
templateUrl: './profile.component.html',
|
||||
styleUrls: ['./profile.component.scss']
|
||||
})
|
||||
export class ProfileComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import {
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
MatToolbarModule
|
||||
} from '@angular/material';
|
||||
|
||||
import { ProfileComponent } from './profile.component';
|
||||
import { LoginComponent } from './login/login.component';
|
||||
import { PersonalComponent } from './personal/personal.component';
|
||||
import { SubscriptionComponent } from './subscription/subscription.component';
|
||||
import { DeleteComponent } from './delete/delete.component';
|
||||
import { AgreementsComponent } from './agreements/agreements.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ProfileComponent,
|
||||
LoginComponent,
|
||||
PersonalComponent,
|
||||
SubscriptionComponent,
|
||||
DeleteComponent,
|
||||
AgreementsComponent
|
||||
],
|
||||
entryComponents: [
|
||||
LoginComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexLayoutModule,
|
||||
FontAwesomeModule,
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
MatToolbarModule
|
||||
]
|
||||
})
|
||||
export class ProfileModule { }
|
|
@ -0,0 +1,17 @@
|
|||
<mat-card class="section-card">
|
||||
<mat-toolbar class="section-card-title-bar">
|
||||
<div class="section-card-title">Support Mycroft</div>
|
||||
</mat-toolbar>
|
||||
<div fxLayout="column" fxLayoutAlign="center center">
|
||||
<mat-button-toggle-group [vertical]="alignVertical">
|
||||
<ng-container *ngFor="let subscription of subscriptionTypes">
|
||||
<mat-button-toggle style="padding: 8px">
|
||||
<div class="mat-h3">{{subscription.name}}</div>
|
||||
<div class="mat-body">{{subscription.price}} USD</div>
|
||||
</mat-button-toggle>
|
||||
</ng-container>
|
||||
</mat-button-toggle-group>
|
||||
<div id="subscription-date" class="mat-body">Proudly supporting Mycroft for {{subscriptionDuration}}</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
.mat-h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
mat-button-toggle-group {
|
||||
border: none;
|
||||
padding: 16px;
|
||||
|
||||
mat-button-toggle {
|
||||
margin: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
#subscription-date {
|
||||
margin-bottom: 16px;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { MediaChange, ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
export interface SubscriptionType {
|
||||
name: string;
|
||||
price: string;
|
||||
period: string;
|
||||
}
|
||||
|
||||
const nonSupporter: SubscriptionType = {
|
||||
name: 'NON-SUPPORTER',
|
||||
price: '$0',
|
||||
period: null
|
||||
};
|
||||
const monthlySupporter: SubscriptionType = {
|
||||
name: 'MONTHLY SUPPORTER',
|
||||
price: '$1.99',
|
||||
period: 'month'
|
||||
};
|
||||
const yearlySupporter: SubscriptionType = {
|
||||
name: 'YEARLY SUPPORTER',
|
||||
price: '$19.99',
|
||||
period: 'year'
|
||||
};
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'account-subscription',
|
||||
templateUrl: './subscription.component.html',
|
||||
styleUrls: ['./subscription.component.scss']
|
||||
})
|
||||
export class SubscriptionComponent implements OnDestroy {
|
||||
public subscriptionTypes: SubscriptionType[];
|
||||
public subscriptionDuration = '3 years 10 months';
|
||||
public alignVertical: boolean;
|
||||
private mediaWatcher: Subscription;
|
||||
|
||||
constructor(public media: ObservableMedia) {
|
||||
this.mediaWatcher = media.subscribe(
|
||||
(change: MediaChange) => {
|
||||
this.alignVertical = ['xs', 'sm'].includes(change.mqAlias);
|
||||
}
|
||||
);
|
||||
this.subscriptionTypes = [yearlySupporter, monthlySupporter, nonSupporter];
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.mediaWatcher.unsubscribe();
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,10 @@
|
|||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="60" height="60" fill="#22A7F0"/>
|
||||
<rect x="19" y="11" width="22" height="38" rx="8" fill="white"/>
|
||||
<rect x="16.5" y="8.5" width="27" height="43" rx="9.5" stroke="white"/>
|
||||
<line x1="30" y1="38" x2="30" y2="22" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="33" y1="35" x2="33" y2="25" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="24" y1="32" x2="24" y2="28" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="27" y1="35" x2="27" y2="25" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="36" y1="32" x2="36" y2="28" stroke="#22A7F0" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 771 B |
|
@ -0,0 +1,10 @@
|
|||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="60" height="60" fill="white"/>
|
||||
<rect x="19" y="11" width="22" height="38" rx="8" fill="#5B6984"/>
|
||||
<rect x="16.5" y="8.5" width="27" height="43" rx="9.5" stroke="#5B6984"/>
|
||||
<line x1="30" y1="38" x2="30" y2="22" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="33" y1="35" x2="33" y2="25" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="24" y1="32" x2="24" y2="28" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="27" y1="35" x2="27" y2="25" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="36" y1="32" x2="36" y2="28" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 763 B |
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1"
|
||||
id="svg821" inkscape:version="0.91 r13725" sodipodi:docname="KDElogoBoxBlue.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 40 40"
|
||||
style="enable-background:new 0 0 40 40;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#6C7A89;}
|
||||
</style>
|
||||
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:bbox-nodes="true" inkscape:current-layer="layer1" inkscape:cx="62.936714" inkscape:cy="68.6291" inkscape:document-units="mm" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:snap-bbox="true" inkscape:window-height="2045" inkscape:window-maximized="1" inkscape:window-width="3840" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="5.6" pagecolor="#ffffff" showgrid="true" units="px" width="128px">
|
||||
<inkscape:grid id="grid1391" type="xygrid"></inkscape:grid>
|
||||
</sodipodi:namedview>
|
||||
<g>
|
||||
<rect id="rect4157" x="5.6" y="5.6" class="st0" width="28.8" height="28.8"/>
|
||||
<path id="path5692_2_-3" inkscape:connector-curvature="0" class="st1" d="M21.6,9.3l-3.7,0.4v15.1l3.6-0.5v-6.4l4.9,7.1l3.8-1.2
|
||||
l-5-6.9l5-6.5l-3.9-0.9l-4.8,6.5L21.6,9.3z M13.3,13c0,0-0.1,0-0.1,0.1l-1.4,1.4c-0.1,0.1-0.1,0.2,0,0.2l1.7,2.8
|
||||
c-0.3,0.5-0.5,1-0.7,1.6l-3.1,0.6c-0.1,0-0.1,0.1-0.1,0.2v2c0,0.1,0.1,0.2,0.1,0.2l3,0.7c0.2,0.7,0.4,1.3,0.7,1.9l-1.7,2.6
|
||||
c0,0.1,0,0.2,0,0.2l1.4,1.4c0.1,0.1,0.2,0.1,0.2,0l2.7-1.7c0.5,0.3,1.1,0.6,1.7,0.7l0.6,3c0,0.1,0.1,0.1,0.2,0.1h2
|
||||
c0.1,0,0.2-0.1,0.2-0.1l0.7-3.1c0.6-0.2,1.2-0.4,1.8-0.7l2.7,1.8c0.1,0,0.2,0,0.2,0l1.4-1.4c0.1-0.1,0.1-0.2,0-0.2l-1-1.6l-0.3,0.1
|
||||
c0,0-0.1,0-0.1,0c0,0-0.6-0.9-1.4-2.1c-1,1.9-2.9,3.2-5.2,3.2c-3.2,0-5.8-2.6-5.8-5.8c0-2.4,1.4-4.4,3.4-5.3v-1.5
|
||||
c-0.4,0.1-0.7,0.3-1.1,0.5c0,0,0,0,0,0L13.4,13C13.4,13,13.3,13,13.3,13L13.3,13z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,7 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M37.7801 9.38C37.7801 11.48 36.6301 13 34.5501 14.05C34.3901 14.96 34.2701 16.12 34.2601 16.27C34.2649 16.386 34.2283 16.5 34.1569 16.5916C34.0854 16.6832 33.9838 16.7464 33.8701 16.77C33.4945 16.8409 33.1119 16.8677 32.7301 16.85C32.2857 16.8524 31.8426 16.802 31.4101 16.7C31.0201 16.61 30.9901 16.5 30.9901 16.5C30.8806 16.1776 30.6954 15.8861 30.4501 15.65C30.3843 15.5725 30.3106 15.5021 30.2301 15.44C26.4847 16.0743 22.688 16.3555 18.8901 16.28C15.004 16.3662 11.1187 16.0715 7.29008 15.4C7.16467 15.4893 7.05051 15.5933 6.95009 15.71C6.70849 15.9433 6.52669 16.2315 6.42008 16.55C6.42008 16.55 6.42008 16.66 6.00008 16.76C5.56716 16.8586 5.12407 16.9056 4.68008 16.9C4.29496 16.9172 3.90912 16.8904 3.53008 16.82C3.41725 16.7962 3.31675 16.7326 3.24697 16.6408C3.17719 16.549 3.1428 16.4351 3.15008 16.32C3.15008 16.16 2.99008 14.76 2.81008 13.84C1.97279 13.4321 1.26607 12.7984 0.769591 12.0104C0.273107 11.2224 0.00659219 10.3114 8.47899e-05 9.38C-0.00235877 8.95211 0.0480221 8.52555 0.150085 8.11V8.11C0.650085 4.98 5.41009 1.84 12.6101 1.17C13.4601 1.09 14.5001 1.06 15.6801 1.06V0.24L15.8901 0C15.8901 0 17.0101 0 18.7301 0C20.4501 0 21.6701 0 21.6701 0L21.8901 0.21V1.05C23.4601 1.05 24.7601 1.11 25.5901 1.21C32.5901 2.02 37.0601 5.04 37.6501 8.03C37.7536 8.47217 37.7973 8.92621 37.7801 9.38V9.38Z" transform="translate(1 12)" stroke="#6C7A89" stroke-width="0.75" stroke-linejoin="round"/>
|
||||
<path d="M35.7 6C35.7 11 27.7 12 17.85 12C8 12 0 10.84 0 6C0 1.16 8 0 17.85 0C27.7 0 35.7 1.06 35.7 6Z" transform="translate(2.04004 15.1602)" fill="#6C7A89"/>
|
||||
<path d="M2.87 5.74C4.45506 5.74 5.74 4.45506 5.74 2.87C5.74 1.28494 4.45506 0 2.87 0C1.28494 0 0 1.28494 0 2.87C0 4.45506 1.28494 5.74 2.87 5.74Z" transform="translate(4.11035 18.3599)" stroke="white" stroke-linejoin="round"/>
|
||||
<path d="M2.87 5.74C4.45506 5.74 5.74 4.45506 5.74 2.87C5.74 1.28494 4.45506 0 2.87 0C1.28495 0 0 1.28494 0 2.87C0 4.45506 1.28495 5.74 2.87 5.74Z" transform="translate(29.5996 18.3599)" stroke="white" stroke-linejoin="round"/>
|
||||
<path d="M0 0L1.65 1.08H7.7L9.36 0H0Z" transform="translate(15.04 22.6299)" fill="white" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,6 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.52 29.8869C19.4771 30.5082 19.3766 31.1241 19.22 31.7269C19.2264 31.7532 19.2264 31.7806 19.22 31.8069C19.0677 32.3492 18.8874 32.8832 18.68 33.4069C18.57 33.6669 18.43 33.9369 18.29 34.1969C18.1326 34.4505 17.9554 34.6913 17.76 34.9169C17.5849 35.1432 17.3676 35.3334 17.12 35.4769C16.8678 35.6114 16.5858 35.6802 16.3 35.6769H3.53C3.24706 35.683 2.96756 35.614 2.72 35.4769C2.46971 35.3332 2.2491 35.1432 2.07 34.9169C1.88106 34.6909 1.71052 34.4501 1.56 34.1969C1.4 33.9369 1.28 33.6669 1.16 33.4069C1.02759 33.1247 0.914004 32.8341 0.820001 32.5369C0.820001 32.5369 0.700001 32.1169 0.650001 31.8969C0.650001 31.8369 0.43 30.7269 0.39 30.1369C0.0600003 25.3569 0 11.2269 0 11.2269C0 5.42689 3.17 0.00689305 9.88 0.00689305C11.2703 -0.0466351 12.655 0.212137 13.9321 0.764182C15.2092 1.31623 16.3464 2.14751 17.26 3.19689C18.9775 5.33145 19.8781 8.00826 19.8 10.7469C19.8 10.7469 19.89 25.1869 19.52 29.8869Z" transform="translate(10 2)" stroke="#6C7A89" stroke-width="0.75" stroke-linejoin="round"/>
|
||||
<path d="M13.8432 19.94C13.8432 19.53 13.8432 19.11 13.8432 18.69V9.77C13.8432 9.62333 13.8432 9.47667 13.8432 9.33C13.8432 4.4 12.9932 0 7.00319 0C0.81319 0 0.00318953 4.47 0.00318953 9.45V19.06C0.00318953 19.49 0.00318953 19.93 0.00318953 20.35C-0.0288053 22.0015 0.180056 23.6488 0.623189 25.24C1.34319 27.77 3.15319 29.53 6.84319 29.59C12.8432 29.69 13.7332 25.01 13.7832 19.96L13.8432 19.94Z" transform="translate(13.0469 5.1167)" fill="#6C7A89"/>
|
||||
<path d="M0.380812 1.96426C0.323184 1.96438 0.266283 1.9514 0.214414 1.92628C0.162545 1.90117 0.117067 1.86459 0.0814202 1.81931C0.0457737 1.77403 0.0208922 1.72123 0.00865958 1.66492C-0.00357306 1.6086 -0.00283688 1.55025 0.010812 1.49426C0.122676 1.06626 0.373284 0.687426 0.723414 0.417047C1.07354 0.146667 1.50344 0 1.94581 0C2.38819 0 2.81808 0.146667 3.16821 0.417047C3.51834 0.687426 3.76895 1.06626 3.88081 1.49426C3.89446 1.55025 3.8952 1.6086 3.88296 1.66492C3.87073 1.72123 3.84585 1.77403 3.8102 1.81931C3.77456 1.86459 3.72908 1.90117 3.67721 1.92628C3.62534 1.9514 3.56844 1.96438 3.51081 1.96426C3.42466 1.96216 3.34163 1.93158 3.27469 1.87731C3.20775 1.82303 3.16067 1.74812 3.14081 1.66426C3.072 1.40106 2.91787 1.1681 2.70255 1.00184C2.48722 0.835573 2.22286 0.745385 1.95081 0.745385C1.67877 0.745385 1.4144 0.835573 1.19908 1.00184C0.983753 1.1681 0.829625 1.40106 0.760812 1.66426C0.74095 1.74812 0.693873 1.82303 0.626934 1.87731C0.559995 1.93158 0.476964 1.96216 0.390812 1.96426H0.380812Z" transform="translate(14.4189 15.1528)" fill="white"/>
|
||||
<path d="M0.380812 1.96426C0.323184 1.96438 0.266282 1.9514 0.214413 1.92628C0.162544 1.90117 0.117066 1.86459 0.0814196 1.81931C0.0457732 1.77403 0.0208927 1.72123 0.00866002 1.66492C-0.00357263 1.6086 -0.0028374 1.55025 0.0108115 1.49426C0.122675 1.06626 0.373284 0.687426 0.723414 0.417047C1.07354 0.146667 1.50344 0 1.94581 0C2.38819 0 2.81808 0.146667 3.16821 0.417047C3.51834 0.687426 3.76895 1.06626 3.88081 1.49426C3.89446 1.55025 3.8952 1.6086 3.88296 1.66492C3.87073 1.72123 3.84585 1.77403 3.8102 1.81931C3.77456 1.86459 3.72908 1.90117 3.67721 1.92628C3.62534 1.9514 3.56844 1.96438 3.51081 1.96426C3.42466 1.96216 3.34163 1.93158 3.27469 1.87731C3.20775 1.82303 3.16067 1.74812 3.14081 1.66426C3.072 1.40106 2.91787 1.1681 2.70255 1.00184C2.48722 0.835573 2.22286 0.745385 1.95081 0.745385C1.67877 0.745385 1.4144 0.835573 1.19908 1.00184C0.983753 1.1681 0.829625 1.40106 0.760812 1.66426C0.74095 1.74812 0.693872 1.82303 0.626933 1.87731C0.559994 1.93158 0.476965 1.96216 0.390813 1.96426H0.380812Z" transform="translate(21.6191 15.1528)" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,12 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.01 0H0.889999C0.398466 0 0 0.398466 0 0.889999V14.16C0 14.6515 0.398466 15.05 0.889999 15.05H22.01C22.5015 15.05 22.9 14.6515 22.9 14.16V0.889999C22.9 0.398466 22.5015 0 22.01 0Z" transform="translate(8 12)" fill="#6C7A89"/>
|
||||
<path d="M4.47 0H0V3.5H4.47V0Z" transform="translate(27.1201 12.6602)" fill="white" stroke="#6C7A89" stroke-width="0.26" stroke-miterlimit="10"/>
|
||||
<path d="M5.11 0H0V4.24H5.11V0Z" transform="translate(26.4902 21.9399)" fill="white" stroke="#6C7A89" stroke-width="0.25" stroke-miterlimit="10"/>
|
||||
<path d="M0.75 1.5C1.16421 1.5 1.5 1.16421 1.5 0.75C1.5 0.335786 1.16421 0 0.75 0C0.335786 0 0 0.335786 0 0.75C0 1.16421 0.335786 1.5 0.75 1.5Z" transform="translate(9.0498 24.5601)" fill="white"/>
|
||||
<path d="M0.75 1.5C1.16421 1.5 1.5 1.16421 1.5 0.75C1.5 0.335786 1.16421 0 0.75 0C0.335786 0 0 0.335786 0 0.75C0 1.16421 0.335786 1.5 0.75 1.5Z" transform="translate(24.0898 24.5601)" fill="white"/>
|
||||
<path d="M0.75 1.5C1.16421 1.5 1.5 1.16421 1.5 0.75C1.5 0.335786 1.16421 0 0.75 0C0.335786 0 0 0.335786 0 0.75C0 1.16421 0.335786 1.5 0.75 1.5Z" transform="translate(24.0898 12.98)" fill="white"/>
|
||||
<path d="M0.75 1.5C1.16421 1.5 1.5 1.16421 1.5 0.75C1.5 0.335786 1.16421 0 0.75 0C0.335786 0 0 0.335786 0 0.75C0 1.16421 0.335786 1.5 0.75 1.5Z" transform="translate(9.0498 12.98)" fill="white"/>
|
||||
<path d="M4.47 0H0V3.5H4.47V0Z" transform="translate(27.1201 17.3501)" fill="white" stroke="#6C7A89" stroke-width="0.26" stroke-miterlimit="10"/>
|
||||
<path d="M4.78 9.56C3.83461 9.56 2.91044 9.27966 2.12438 8.75443C1.33831 8.22919 0.725645 7.48266 0.363858 6.60923C0.00207138 5.7358 -0.0925889 4.7747 0.0918484 3.84747C0.276286 2.92024 0.731537 2.06853 1.40003 1.40003C2.06853 0.731536 2.92024 0.276286 3.84747 0.0918484C4.7747 -0.0925889 5.7358 0.00207138 6.60923 0.363858C7.48266 0.725645 8.22919 1.33831 8.75443 2.12438C9.27966 2.91044 9.56 3.83461 9.56 4.78C9.56 5.40772 9.43636 6.02929 9.19615 6.60923C8.95593 7.18917 8.60384 7.71611 8.15997 8.15997C7.71611 8.60384 7.18916 8.95593 6.60923 9.19615C6.02929 9.43636 5.40772 9.56 4.78 9.56Z" transform="translate(12.5195 14.6401)" fill="white"/>
|
||||
<path d="M4 0C3.20888 0 2.43552 0.234596 1.77772 0.674122C1.11992 1.11365 0.607234 1.73836 0.304484 2.46927C0.00173312 3.20017 -0.0774802 4.00444 0.0768607 4.78036C0.231202 5.55629 0.612165 6.26902 1.17157 6.82843C1.73098 7.38784 2.44372 7.7688 3.21964 7.92314C3.99556 8.07748 4.79983 7.99827 5.53074 7.69552C6.26164 7.39277 6.88635 6.88008 7.32588 6.22228C7.76541 5.56448 8 4.79113 8 4C7.98703 2.94316 7.56144 1.93327 6.81409 1.18591C6.06674 0.43856 5.05684 0.0129688 4 0ZM4 7.38C3.11683 7.38 2.26983 7.02916 1.64534 6.40466C1.02084 5.78017 0.670002 4.93317 0.670002 4.05C0.670002 3.16683 1.02084 2.31983 1.64534 1.69534C2.26983 1.07084 3.11683 0.719999 4 0.719999V7.38Z" transform="translate(13.2998 15.3599)" fill="#6C7A89"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,3 @@
|
|||
export const environment = {
|
||||
production: true
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
mycroftUrls: {
|
||||
chat: 'https://chat.mycroft.ai',
|
||||
forum: 'https://community.mycroft.ai',
|
||||
singleSignOn: 'http://localhost:4201',
|
||||
account: 'https://home-test.mycroft.ai',
|
||||
marketplace: 'http://localhost:4202',
|
||||
mimic: 'http://mimic.mycroft,ai',
|
||||
translate: 'https://translate-test.mycroft.ai',
|
||||
wordpress: 'https://test.mycroft.ai'
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* In development mode, to ignore zone related error stack frames such as
|
||||
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
|
||||
* import the following file, but please comment it out in production mode
|
||||
* because it will have performance impact when throw error
|
||||
*/
|
||||
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
After Width: | Height: | Size: 114 KiB |
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Account</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
|
||||
<body style="margin: 0;">
|
||||
<account-root></account-root>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* 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 Safari >= 10, Chrome >= 55 (including Opera),
|
||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
||||
// import 'core-js/es6/symbol';
|
||||
// import 'core-js/es6/object';
|
||||
// import 'core-js/es6/function';
|
||||
// import 'core-js/es6/parse-int';
|
||||
// import 'core-js/es6/parse-float';
|
||||
// import 'core-js/es6/number';
|
||||
// import 'core-js/es6/math';
|
||||
// import 'core-js/es6/string';
|
||||
// import 'core-js/es6/date';
|
||||
// import 'core-js/es6/array';
|
||||
// import 'core-js/es6/regexp';
|
||||
// import 'core-js/es6/map';
|
||||
// import 'core-js/es6/weak-map';
|
||||
// import 'core-js/es6/set';
|
||||
|
||||
/**
|
||||
* If the application will be indexed by Google Search, the following is required.
|
||||
* Googlebot uses a renderer based on Chrome 41.
|
||||
* https://developers.google.com/search/docs/guides/rendering
|
||||
**/
|
||||
// import 'core-js/es6/array';
|
||||
|
||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||
// import 'core-js/es6/reflect';
|
||||
|
||||
/**
|
||||
* Web Animations `@angular/platform-browser/animations`
|
||||
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||
**/
|
||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
*/
|
||||
|
||||
// (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__BLACK_LISTED_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;
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
|
@ -0,0 +1 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
|
@ -0,0 +1,20 @@
|
|||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/app",
|
||||
"types": []
|
||||
},
|
||||
"exclude": [
|
||||
"test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts",
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"account",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"account",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// 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-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage'),
|
||||
reports: ['html', 'lcovonly'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
});
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/globalnav",
|
||||
"lib": {
|
||||
"entryFile": "src/public_api.ts",
|
||||
"cssUrl": "inline",
|
||||
"umdModuleIds": {
|
||||
"@fortawesome/angular-fontawesome": "angularFontawesome",
|
||||
"@fortawesome/free-brands-svg-icons": "freeBrandsSvgIcons",
|
||||
"@fortawesome/free-solid-svg-icons": "freeSolidSvgIcons"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "globalnav",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^7.0.0",
|
||||
"@angular/core": "^7.0.0",
|
||||
"@angular/flex-layout": "^7.0.0-beta.19"
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<div class="nav-footer">
|
||||
<mat-divider></mat-divider>
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start" class="social-icons">
|
||||
<a *ngFor="let media of socialMediaIcons" href="{{media.url}}">
|
||||
<button mat-icon-button class="social-icon-button">
|
||||
<fa-icon [icon]="media.icon"></fa-icon>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div *ngFor="let item of footerItems">
|
||||
<a href="{{item.url}}">
|
||||
<button mat-flat-button class="footer-text">{{item.text}}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mat-body-2">© Mycroft AI, Inc.</div>
|
||||
</div>
|
|
@ -0,0 +1,26 @@
|
|||
.nav-footer {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.social-icons {
|
||||
width: 180px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.social-icon-button {
|
||||
color: #6c7a89;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
color: #6c7a89;
|
||||
font-weight: 400;
|
||||
line-height: 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mat-body-2 {
|
||||
color: #6c7a89;
|
||||
margin-top: 5px;
|
||||
font-weight: 400;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { NavItem } from '../globalnav.service';
|
||||
|
||||
import {
|
||||
faFacebook,
|
||||
faInstagram,
|
||||
faLinkedin,
|
||||
faMedium,
|
||||
faReddit,
|
||||
faTelegram,
|
||||
faTwitter,
|
||||
faYoutube,
|
||||
} from '@fortawesome/free-brands-svg-icons';
|
||||
|
||||
@Component({
|
||||
selector: 'globalnav-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.scss']
|
||||
})
|
||||
export class FooterComponent implements OnInit {
|
||||
@Input() footerItems: NavItem[];
|
||||
public socialMediaIcons = [
|
||||
{icon: faTwitter, url: 'https://twitter.com/mycroft_ai'},
|
||||
{icon: faFacebook, url: 'https://www.facebook.com/aiforeveryone/'},
|
||||
{icon: faInstagram, url: 'https://www.instagram.com/mycroft_ai/'},
|
||||
{icon: faYoutube, url: 'https://www.youtube.com/channel/UC1dlmB1lup9RwFQBSGnhA-g'},
|
||||
{icon: faTelegram, url: 'https://t.me/mycroft_ai'},
|
||||
{icon: faReddit, url: 'https://www.reddit.com/r/Mycroftai/'},
|
||||
{icon: faLinkedin, url: 'https://www.linkedin.com/company/mycroft-a.i./'},
|
||||
{icon: faMedium, url: 'https://medium.com/@mycroftai'}
|
||||
];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<mat-toolbar fxLayout="row" fxLayoutAlign="space-between" color="primary">
|
||||
|
||||
<!-- At the start of the title bar, put the hamburger menu icon and -->
|
||||
<!-- the Mycroft logo. The latter is also a link to the WordPress home page-->
|
||||
<div fxLayout="row" fxLayoutAlign="start center" fxFlex>
|
||||
<button mat-icon-button class="menu-button" (click)="snav.toggle()">
|
||||
<fa-icon [icon]="menuIcon"></fa-icon>
|
||||
</button>
|
||||
<a href="{{mycroftUrls.wordpress}}">
|
||||
<div class="globalnav-logo"></div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- At the end of the title bar is a login/logout control -->
|
||||
<!-- The logout control is displayed whenever the user is logged in... -->
|
||||
<div *ngIf="isLoggedIn" fxLayout="row" fxLayoutAlign="end center">
|
||||
<button
|
||||
mat-flat-button
|
||||
class="sign-in-button"
|
||||
[matMenuTriggerFor]="authMenu"
|
||||
>
|
||||
<fa-icon [icon]="userIcon"></fa-icon>
|
||||
{{userName}}
|
||||
</button>
|
||||
<mat-menu #authMenu="matMenu">
|
||||
<button mat-menu-item (click)="navigateToSignOut()">
|
||||
<fa-icon [icon]="signOutIcon" style="margin-right: 10px;"></fa-icon>
|
||||
Logout
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<!-- ...and the login control is displayed whenever the user is logged out. -->
|
||||
<button
|
||||
*ngIf="!isLoggedIn"
|
||||
mat-flat-button
|
||||
class="sign-in-button"
|
||||
(click)="navigateToSignIn()"
|
||||
>
|
||||
<fa-icon [icon]="signInIcon"></fa-icon>
|
||||
SIGN IN
|
||||
</button>
|
||||
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-sidenav-container>
|
||||
|
||||
<!-- This is the global sidenav menu for navigating all Mycroft sites -->
|
||||
<mat-sidenav
|
||||
#snav
|
||||
[mode]="mobileQuery.matches ? 'over' : 'side'"
|
||||
[opened]="!mobileQuery.matches"
|
||||
[fixedInViewport]="true"
|
||||
>
|
||||
<div fxFill fxLayout="column">
|
||||
<mat-nav-list fxFlex [disableRipple]="true">
|
||||
<globalnav-primary-nav-item
|
||||
*ngFor="let nav of navigationItems"
|
||||
[primaryNavItem]="nav"
|
||||
>
|
||||
</globalnav-primary-nav-item>
|
||||
</mat-nav-list>
|
||||
<globalnav-footer [footerItems]="footerItems"></globalnav-footer>
|
||||
</div>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- This is the area where any non-menu content can go. -->
|
||||
<!-- Mycroft web apps must specify the appBody identifier so that their -->
|
||||
<!-- content is placed within the mat-sidenav-content area. -->
|
||||
<mat-sidenav-content>
|
||||
<ng-content select="[appBody]"></ng-content>
|
||||
</mat-sidenav-content>
|
||||
|
||||
</mat-sidenav-container>
|
|
@ -0,0 +1,64 @@
|
|||
mat-toolbar {
|
||||
height: 50px;
|
||||
position: fixed;
|
||||
z-index: 2; // Put this on top of the sidenav container
|
||||
|
||||
.menu-button {
|
||||
margin-left: -10px;
|
||||
margin-right: 10px;
|
||||
fa-icon {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// Use inline css to display the logo at top of sidebar because Angular
|
||||
// libraries do not support static assets yet.
|
||||
.globalnav-logo {
|
||||
background: url("toolbar-logo.svg") no-repeat;
|
||||
height: 25px;
|
||||
margin-top: -5px;
|
||||
width: 168px;
|
||||
}
|
||||
|
||||
.sign-in-button {
|
||||
background-color: #22a7f0;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
fa-icon {
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
margin-right: 10px
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mat-sidenav-container {
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
|
||||
.mat-drawer-container{
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
mat-sidenav {
|
||||
border: none;
|
||||
margin-top: 50px;
|
||||
|
||||
mat-divider {
|
||||
width: 200px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
mat-nav-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
mat-sidenav-content {
|
||||
padding-left: 3vw;
|
||||
padding-right: 3vw;
|
||||
margin-top: 80px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MediaMatcher } from '@angular/cdk/layout';
|
||||
import { Observable } from 'rxjs';
|
||||
import {
|
||||
faBars,
|
||||
faLightbulb,
|
||||
faRobot,
|
||||
faRocket,
|
||||
faRss,
|
||||
faSignInAlt,
|
||||
faSignOutAlt,
|
||||
faStore,
|
||||
faUserCircle,
|
||||
faUsers
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import {
|
||||
expireTokenCookies,
|
||||
NavItem,
|
||||
PrimaryNavItem,
|
||||
setLoginStatus,
|
||||
User
|
||||
} from './globalnav.service';
|
||||
|
||||
@Component({
|
||||
selector: 'globalnav-sidenav',
|
||||
templateUrl: './globalnav.component.html',
|
||||
styleUrls: ['./globalnav.component.scss']
|
||||
})
|
||||
|
||||
export class GlobalnavComponent implements OnInit {
|
||||
@Input() mycroftUrls: any;
|
||||
@Input() user$: Observable<User>;
|
||||
public footerItems: NavItem[];
|
||||
public isLoggedIn: boolean;
|
||||
public signInIcon = faSignInAlt;
|
||||
public signOutIcon = faSignOutAlt;
|
||||
public menuIcon = faBars;
|
||||
public mobileQuery: MediaQueryList;
|
||||
public navigationItems: PrimaryNavItem[];
|
||||
public userIcon = faUserCircle;
|
||||
public userName: string;
|
||||
|
||||
constructor(private media: MediaMatcher) {
|
||||
this.mobileQuery = media.matchMedia('(max-width: 600px)');
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.isLoggedIn = setLoginStatus();
|
||||
this.getUser();
|
||||
this.buildNavigationItems();
|
||||
this.buildAccountNav();
|
||||
}
|
||||
|
||||
getUser() {
|
||||
if (this.isLoggedIn) {
|
||||
this.user$.subscribe(
|
||||
(user) => {
|
||||
if (user.name) {
|
||||
this.userName = user.name;
|
||||
} else {
|
||||
this.userName = 'Logged In';
|
||||
}
|
||||
},
|
||||
(response) => {
|
||||
if (response.status === 401) {
|
||||
expireTokenCookies();
|
||||
this.isLoggedIn = setLoginStatus();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
buildNavigationItems(): void {
|
||||
const aboutMycroftNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Team', url: this.mycroftUrls.wordpress + '/team'},
|
||||
{text: 'Careers', url: this.mycroftUrls.wordpress + '/careers'}
|
||||
],
|
||||
icon: faRobot,
|
||||
text: 'About Mycroft'
|
||||
};
|
||||
const blogNav: PrimaryNavItem = {
|
||||
icon: faRss,
|
||||
text: 'Blog',
|
||||
url: this.mycroftUrls.wordpress + '/blog'
|
||||
};
|
||||
const communityNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Chat', url: this.mycroftUrls.chat},
|
||||
{text: 'Forum', url: this.mycroftUrls.forum}
|
||||
],
|
||||
icon: faUsers,
|
||||
text: 'Community'
|
||||
};
|
||||
const contributeNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Source Code', url: 'https://github.com/MycroftAI'},
|
||||
{text: 'Translate', url: this.mycroftUrls.translate},
|
||||
{text: 'Wake Word', url: this.mycroftUrls.account + '/#/precise'},
|
||||
{text: 'Speech to Text', url: this.mycroftUrls.account + '/#/deepspeech'},
|
||||
{text: 'Text to Speech', url: this.mycroftUrls.mimic}
|
||||
],
|
||||
icon: faLightbulb,
|
||||
text: 'Contribute'
|
||||
};
|
||||
const getStartedNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Get Mycroft', url: this.mycroftUrls.wordpress + '/download'},
|
||||
{text: 'Documentation', url: this.mycroftUrls.wordpress + '/documentation'}
|
||||
],
|
||||
icon: faRocket,
|
||||
text: 'Get Started'
|
||||
};
|
||||
const marketplaceNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Skills', url: this.mycroftUrls.marketplace + '/skills'},
|
||||
{text: 'Hardware', url: this.mycroftUrls.wordpress + '/shop'}
|
||||
],
|
||||
icon: faStore,
|
||||
text: 'Marketplace'
|
||||
};
|
||||
|
||||
this.navigationItems = [
|
||||
aboutMycroftNav,
|
||||
getStartedNav,
|
||||
blogNav,
|
||||
communityNav,
|
||||
contributeNav,
|
||||
marketplaceNav,
|
||||
];
|
||||
|
||||
this.footerItems = [
|
||||
{text: 'Contact Us', url: this.mycroftUrls.wordpress + '/contact'},
|
||||
{text: 'Media Kit', url: this.mycroftUrls.wordpress + '/media'},
|
||||
{text: 'Privacy Policy', url: this.mycroftUrls.account + '/#/privacy-policy'},
|
||||
{text: 'Terms of Use', url: this.mycroftUrls.account + '/#/terms-of-use'}
|
||||
];
|
||||
}
|
||||
|
||||
buildAccountNav() {
|
||||
const accountNav: PrimaryNavItem = {
|
||||
children: [
|
||||
{text: 'Devices', url: this.mycroftUrls.account + '/#/device'},
|
||||
{text: 'Profile', url: this.mycroftUrls.account + '/#/profile'},
|
||||
{text: 'Skill Settings', url: this.mycroftUrls.account + '/#/skill'},
|
||||
{text: 'Subscription', url: this.mycroftUrls.account + '/#/account'},
|
||||
{text: 'User Settings', url: this.mycroftUrls.account + '/#/setting/basic'},
|
||||
],
|
||||
icon: faUserCircle,
|
||||
text: 'My Account',
|
||||
};
|
||||
|
||||
if (this.isLoggedIn) {
|
||||
this.navigationItems.push(accountNav);
|
||||
}
|
||||
}
|
||||
|
||||
navigateToSignIn() {
|
||||
window.location.assign(
|
||||
this.mycroftUrls.singleSignOn + '/login?redirect=' + window.location.href
|
||||
);
|
||||
}
|
||||
|
||||
navigateToSignOut() {
|
||||
window.location.assign(
|
||||
this.mycroftUrls.singleSignOn + '/logout?redirect=' + window.location.href
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatListModule } from '@angular/material';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
|
||||
import { GlobalnavComponent } from './globalnav.component';
|
||||
import { NavItemComponent } from './nav-item/nav-item.component';
|
||||
import { PrimaryNavItemComponent } from './primary-nav-item/primary-nav-item.component';
|
||||
import { FooterComponent } from './footer/footer.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexLayoutModule,
|
||||
FontAwesomeModule,
|
||||
MatButtonModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
],
|
||||
declarations: [
|
||||
GlobalnavComponent,
|
||||
NavItemComponent,
|
||||
PrimaryNavItemComponent,
|
||||
FooterComponent
|
||||
],
|
||||
exports: [
|
||||
GlobalnavComponent
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class GlobalnavModule { }
|