Updated
This commit is contained in:
parent
200574099b
commit
8e818b179b
@ -1,67 +0,0 @@
|
|||||||
version: 2
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
docker:
|
|
||||||
- image: circleci/node:10.4-browsers
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- v1-dependencies-{{ checksum "package.json" }}
|
|
||||||
- v1-dependencies-
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Install Dependancies
|
|
||||||
command: yarn
|
|
||||||
|
|
||||||
- save_cache:
|
|
||||||
key: v1-dependencies-{{ checksum "package.json" }}
|
|
||||||
paths:
|
|
||||||
- node_modules
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Build
|
|
||||||
command: yarn build
|
|
||||||
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: ./
|
|
||||||
paths:
|
|
||||||
- node_modules
|
|
||||||
- dist/ZaksCode
|
|
||||||
|
|
||||||
- store_artifacts:
|
|
||||||
path: ./dist/ZaksCode
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
docker:
|
|
||||||
- image: circleci/node:10.4-browsers
|
|
||||||
|
|
||||||
working_directory: ~/repo
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
|
|
||||||
- attach_workspace:
|
|
||||||
at: ./
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Deploy
|
|
||||||
command: yarn firebase deploy --token "${FIREBASE_TOKEN}"
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
|
|
||||||
build_and_deply:
|
|
||||||
jobs:
|
|
||||||
- build
|
|
||||||
- deploy:
|
|
||||||
requires:
|
|
||||||
- build
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only: master
|
|
@ -3,7 +3,7 @@ root = true
|
|||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = space
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
@ -11,3 +11,7 @@ trim_trailing_whitespace = true
|
|||||||
[*.md]
|
[*.md]
|
||||||
max_line_length = off
|
max_line_length = off
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"projects": {
|
|
||||||
"default": "zaks-code"
|
|
||||||
}
|
|
||||||
}
|
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -44,3 +44,4 @@ testem.log
|
|||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
/package-lock.json
|
||||||
|
27
Dockerfile
Normal file
27
Dockerfile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
FROM node:16 as build
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
ARG NODE_ENV=prod
|
||||||
|
ARG NODE_OPTIONS=""
|
||||||
|
ENV NG_CLI_ANALYTICS=ci \
|
||||||
|
NODE_ENV=${NODE_ENV} \
|
||||||
|
NODE_OPTIONS=${NODE_OPTIONS}
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
RUN npm config set unsafe-perm true && \
|
||||||
|
mkdir /app
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Install
|
||||||
|
RUN if [ ! -d "dist" ] && [ ! -d "node_modules" ]; then npm install; fi
|
||||||
|
|
||||||
|
# Build
|
||||||
|
if [ ! -d "dist" ]; then npm run "build:$NODE_ENV"; fi
|
||||||
|
|
||||||
|
# Use Nginx to serve
|
||||||
|
FROM nginx:1.20-alpine
|
||||||
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
|
COPY docker/robots.txt /usr/share/nginx/html/robots.txt
|
||||||
|
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
EXPOSE 80
|
28
README.md
28
README.md
@ -1,3 +1,27 @@
|
|||||||
# ZaksCode
|
# Zakscode
|
||||||
|
|
||||||
WIP: An Angular + Firebase replacement for my old personal site writen in Django.
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.3.4.
|
||||||
|
|
||||||
|
## Development server
|
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
||||||
|
11
ZaksCode.iml
11
ZaksCode.iml
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
133
angular.json
133
angular.json
@ -3,73 +3,87 @@
|
|||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"ZaksCode": {
|
"zakscode": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:application": {
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": "",
|
"root": "",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"projectType": "application",
|
|
||||||
"prefix": "app",
|
"prefix": "app",
|
||||||
"schematics": {},
|
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist/ZaksCode",
|
"outputPath": "dist/zakscode",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
"assets": [
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/custom-theme.scss",
|
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": []
|
||||||
"es5BrowserSupport": true
|
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "500kb",
|
||||||
|
"maximumError": "1mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
],
|
||||||
"fileReplacements": [
|
"fileReplacements": [
|
||||||
{
|
{
|
||||||
"replace": "src/environments/environment.ts",
|
"replace": "src/environments/environment.ts",
|
||||||
"with": "src/environments/environment.prod.ts"
|
"with": "src/environments/environment.prod.ts"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"optimization": true,
|
"outputHashing": "all"
|
||||||
"outputHashing": "all",
|
},
|
||||||
"sourceMap": false,
|
"development": {
|
||||||
"extractCss": true,
|
"buildOptimizer": false,
|
||||||
"namedChunks": false,
|
"optimization": false,
|
||||||
"aot": true,
|
"vendorChunk": true,
|
||||||
"extractLicenses": true,
|
"extractLicenses": false,
|
||||||
"vendorChunk": false,
|
"sourceMap": true,
|
||||||
"buildOptimizer": true,
|
"namedChunks": true
|
||||||
"budgets": [
|
|
||||||
{
|
|
||||||
"type": "initial",
|
|
||||||
"maximumWarning": "2mb",
|
|
||||||
"maximumError": "5mb"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
},
|
},
|
||||||
"serve": {
|
"serve": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
"options": {
|
|
||||||
"browserTarget": "ZaksCode:build"
|
|
||||||
},
|
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"browserTarget": "ZaksCode:build:production"
|
"browserTarget": "zakscode:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"browserTarget": "zakscode:build:development"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
},
|
},
|
||||||
"extract-i18n": {
|
"extract-i18n": {
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
"options": {
|
"options": {
|
||||||
"browserTarget": "ZaksCode:build"
|
"browserTarget": "zakscode:build"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
@ -77,60 +91,21 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"main": "src/test.ts",
|
"main": "src/test.ts",
|
||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
"tsConfig": "tsconfig.spec.json",
|
||||||
"karmaConfig": "src/karma.conf.js",
|
"karmaConfig": "karma.conf.js",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/custom-theme.scss",
|
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": [],
|
"scripts": []
|
||||||
"assets": [
|
|
||||||
"src/assets"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"src/tsconfig.app.json",
|
|
||||||
"src/tsconfig.spec.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ZaksCode-e2e": {
|
|
||||||
"root": "e2e/",
|
|
||||||
"projectType": "application",
|
|
||||||
"prefix": "",
|
|
||||||
"architect": {
|
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "e2e/protractor.conf.js",
|
|
||||||
"devServerTarget": "ZaksCode:serve"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "ZaksCode:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultProject": "ZaksCode"
|
"defaultProject": "zakscode"
|
||||||
}
|
}
|
||||||
|
31
docker/nginx.conf
Normal file
31
docker/nginx.conf
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
worker_processes auto;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_types text/plain text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript application/json application/x-font-woff;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
|
||||||
|
|
||||||
|
sendfile off;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
index index.html;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
autoindex off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri$args $uri$args/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
docker/robots.txt
Normal file
2
docker/robots.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
User-Agent: *
|
||||||
|
Allow: /
|
@ -1,28 +0,0 @@
|
|||||||
// 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 } }));
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
import { AppPage } from './app.po';
|
|
||||||
import { browser, logging } from 'protractor';
|
|
||||||
|
|
||||||
describe('workspace-project App', () => {
|
|
||||||
let page: AppPage;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new AppPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
|
||||||
page.navigateTo();
|
|
||||||
expect(page.getTitleText()).toEqual('Welcome to ZaksCode!');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(async () => {
|
|
||||||
// Assert that there are no errors emitted from the browser
|
|
||||||
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
|
|
||||||
expect(logs).not.toContain(jasmine.objectContaining({
|
|
||||||
level: logging.Level.SEVERE,
|
|
||||||
} as logging.Entry));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,11 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
|
|
||||||
export class AppPage {
|
|
||||||
navigateTo() {
|
|
||||||
return browser.get(browser.baseUrl) as Promise<any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTitleText() {
|
|
||||||
return element(by.css('app-root h1')).getText() as Promise<string>;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/app",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"jasminewd2",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"firestore": {
|
|
||||||
"rules": "firestore.rules",
|
|
||||||
"indexes": "firestore.indexes.json"
|
|
||||||
},
|
|
||||||
"hosting": {
|
|
||||||
"public": "dist/ZaksCode",
|
|
||||||
"ignore": [
|
|
||||||
"firebase.json",
|
|
||||||
"**/.*",
|
|
||||||
"**/node_modules/**"
|
|
||||||
],
|
|
||||||
"rewrites": [
|
|
||||||
{
|
|
||||||
"source": "**",
|
|
||||||
"destination": "/index.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"storage": {
|
|
||||||
"rules": "storage.rules"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"indexes": [],
|
|
||||||
"fieldOverrides": []
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
service cloud.firestore {
|
|
||||||
match /databases/{database}/documents {
|
|
||||||
match /{document=**} {
|
|
||||||
allow read;
|
|
||||||
allow write: if request.auth != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
108
gitlab/.gitlab-ci.yml
Normal file
108
gitlab/.gitlab-ci.yml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
image: node:16
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- publish
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
npm:
|
||||||
|
stage: build
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- dist
|
||||||
|
expire_in: 1 week
|
||||||
|
cache:
|
||||||
|
- key:
|
||||||
|
files:
|
||||||
|
- package.json
|
||||||
|
paths:
|
||||||
|
- node_modules
|
||||||
|
- package-lock.json
|
||||||
|
policy: pull-push
|
||||||
|
- key: $CI_PIPELINE_ID
|
||||||
|
paths:
|
||||||
|
- dist
|
||||||
|
policy: push
|
||||||
|
script:
|
||||||
|
- npm i
|
||||||
|
- npm run build:prod
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH
|
||||||
|
|
||||||
|
audit:
|
||||||
|
stage: test
|
||||||
|
cache:
|
||||||
|
- key:
|
||||||
|
files:
|
||||||
|
- package.json
|
||||||
|
paths:
|
||||||
|
- node_modules
|
||||||
|
policy: pull
|
||||||
|
script:
|
||||||
|
- echo "vulnerabilities_high $(npm audit | grep -oE '[0-9]+ high' | grep -oE '[0-9]+' || echo 0)" > metrics.txt
|
||||||
|
- echo "vulnerabilities_medium $(npm audit | grep -oE '[0-9]+ moderate' | grep -oE '[0-9]+' || echo 0)" >> metrics.txt
|
||||||
|
- echo "vulnerabilities_low $(npm audit | grep -oE '[0-9]+ low' | grep -oE '[0-9]+' || echo 0)" >> metrics.txt
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
metrics: metrics.txt
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH
|
||||||
|
|
||||||
|
eslint:
|
||||||
|
stage: test
|
||||||
|
cache:
|
||||||
|
- key:
|
||||||
|
files:
|
||||||
|
- package.json
|
||||||
|
paths:
|
||||||
|
- node_modules
|
||||||
|
policy: pull
|
||||||
|
script:
|
||||||
|
- npm run lint
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH
|
||||||
|
|
||||||
|
registry:
|
||||||
|
stage: publish
|
||||||
|
image: docker
|
||||||
|
cache:
|
||||||
|
- key: $CI_PIPELINE_ID
|
||||||
|
paths:
|
||||||
|
- dist
|
||||||
|
policy: pull
|
||||||
|
before_script:
|
||||||
|
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||||
|
script:
|
||||||
|
- TAG=$(echo "$CI_COMMIT_BRANCH" | sed -E "s/[_/]/-/g")
|
||||||
|
- docker build --no-cache -t "$CI_REGISTRY_IMAGE:$TAG" .
|
||||||
|
- docker push "$CI_REGISTRY_IMAGE:$TAG"
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH
|
||||||
|
|
||||||
|
tag:
|
||||||
|
stage: publish
|
||||||
|
image:
|
||||||
|
name: alpine/git
|
||||||
|
entrypoint: [ "" ]
|
||||||
|
cache: [ ]
|
||||||
|
before_script:
|
||||||
|
- git remote set-url origin "http://gitlab-ci-token:$DEPLOY_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
|
||||||
|
script:
|
||||||
|
- VERSION=$(cat package.json | grep version | grep -Eo ':.+' | grep -Eo '[[:alnum:]\.\/\-]+')
|
||||||
|
- git tag -f $VERSION $CI_COMMIT_SHA
|
||||||
|
- git push -f origin $VERSION
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||||
|
|
||||||
|
production:
|
||||||
|
stage: deploy
|
||||||
|
image: node:16
|
||||||
|
cache: [ ]
|
||||||
|
script:
|
||||||
|
- echo "Make curl request to portainer"
|
||||||
|
environment:
|
||||||
|
name: Production
|
||||||
|
url: https://zakscode.com
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "production" && $CI_DEPLOY_FREEZE == null'
|
@ -9,16 +9,28 @@ module.exports = function (config) {
|
|||||||
require('karma-jasmine'),
|
require('karma-jasmine'),
|
||||||
require('karma-chrome-launcher'),
|
require('karma-chrome-launcher'),
|
||||||
require('karma-jasmine-html-reporter'),
|
require('karma-jasmine-html-reporter'),
|
||||||
require('karma-coverage-istanbul-reporter'),
|
require('karma-coverage'),
|
||||||
require('@angular-devkit/build-angular/plugins/karma')
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
],
|
],
|
||||||
client: {
|
client: {
|
||||||
|
jasmine: {
|
||||||
|
// you can add configuration options for Jasmine here
|
||||||
|
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||||
|
// for example, you can disable the random execution with `random: false`
|
||||||
|
// or set a specific seed with `seed: 4321`
|
||||||
|
},
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
},
|
},
|
||||||
coverageIstanbulReporter: {
|
jasmineHtmlReporter: {
|
||||||
dir: require('path').join(__dirname, '../coverage/ZaksCode'),
|
suppressAll: true // removes the duplicated traces
|
||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
},
|
||||||
fixWebpackSourcePaths: true
|
coverageReporter: {
|
||||||
|
dir: require('path').join(__dirname, './coverage/zakscode'),
|
||||||
|
subdir: '.',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'html' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
reporters: ['progress', 'kjhtml'],
|
reporters: ['progress', 'kjhtml'],
|
||||||
port: 9876,
|
port: 9876,
|
92
package.json
92
package.json
@ -1,55 +1,41 @@
|
|||||||
{
|
{
|
||||||
"name": "zaks-code",
|
"name": "zakscode",
|
||||||
"version": "1.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"test": "ng test",
|
"watch": "ng build --watch --configuration development",
|
||||||
"lint": "ng lint",
|
"test": "ng test"
|
||||||
"e2e": "ng e2e"
|
},
|
||||||
},
|
"private": true,
|
||||||
"private": true,
|
"dependencies": {
|
||||||
"dependencies": {
|
"@angular/animations": "~13.3.0",
|
||||||
"@angular/animations": "~7.2.0",
|
"@angular/cdk": "^13.3.5",
|
||||||
"@angular/cdk": "~7.3.7",
|
"@angular/common": "~13.3.0",
|
||||||
"@angular/common": "~7.2.0",
|
"@angular/compiler": "~13.3.0",
|
||||||
"@angular/compiler": "~7.2.0",
|
"@angular/core": "~13.3.0",
|
||||||
"@angular/core": "~7.2.0",
|
"@angular/forms": "~13.3.0",
|
||||||
"@angular/fire": "~5.1.2",
|
"@angular/material": "^13.3.5",
|
||||||
"@angular/forms": "~7.2.0",
|
"@angular/platform-browser": "~13.3.0",
|
||||||
"@angular/material": "^7.3.7",
|
"@angular/platform-browser-dynamic": "~13.3.0",
|
||||||
"@angular/platform-browser": "~7.2.0",
|
"@angular/router": "~13.3.0",
|
||||||
"@angular/platform-browser-dynamic": "~7.2.0",
|
"rxjs": "~7.5.0",
|
||||||
"@angular/router": "~7.2.0",
|
"tslib": "^2.3.0",
|
||||||
"@thisissoon/angular-inviewport": "^4.2.2",
|
"zone.js": "~0.11.4"
|
||||||
"core-js": "^2.5.4",
|
},
|
||||||
"firebase": "^5.1.0",
|
"devDependencies": {
|
||||||
"hammerjs": "^2.0.8",
|
"@angular-devkit/build-angular": "~13.3.4",
|
||||||
"rxjs": "~6.3.3",
|
"@angular/cli": "~13.3.4",
|
||||||
"tslib": "^1.9.0",
|
"@angular/compiler-cli": "~13.3.0",
|
||||||
"zone.js": "~0.8.26"
|
"@types/jasmine": "~3.10.0",
|
||||||
},
|
"@types/node": "^12.11.1",
|
||||||
"devDependencies": {
|
"jasmine-core": "~4.0.0",
|
||||||
"@angular-devkit/build-angular": "^0.13.9",
|
"karma": "~6.3.0",
|
||||||
"@angular/cli": "~7.3.8",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"@angular/compiler-cli": "~7.2.0",
|
"karma-coverage": "~2.1.0",
|
||||||
"@angular/language-service": "~7.2.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"@types/jasmine": "~2.8.8",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"typescript": "~4.6.2"
|
||||||
"@types/node": "~8.9.4",
|
}
|
||||||
"codelyzer": "~4.5.0",
|
|
||||||
"firebase-tools": "^6.0.1",
|
|
||||||
"jasmine-core": "~2.99.1",
|
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
|
||||||
"karma": "~4.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",
|
|
||||||
"protractor": "~5.4.0",
|
|
||||||
"ts-node": "~7.0.0",
|
|
||||||
"tslint": "~5.11.0",
|
|
||||||
"typescript": "~3.2.2"
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,58 +0,0 @@
|
|||||||
<div class="w-100">
|
|
||||||
<div class="container d-flex align-items-center" style="height: 300px">
|
|
||||||
<div class="w-100 text-center">
|
|
||||||
<typewriter text="Admin Panel" [delay]="500"></typewriter>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container mb-md-5 p-0 bg-white">
|
|
||||||
<div class="p-4">
|
|
||||||
<h3>Users</h3>
|
|
||||||
<table class="table mt-3">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>First Name</th>
|
|
||||||
<th>Last Name</th>
|
|
||||||
<th>Email</th>
|
|
||||||
<th class="text-center">Admin</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let user of adminService.users | async">
|
|
||||||
<td>{{user.firstName}}</td>
|
|
||||||
<td>{{user.lastName}}</td>
|
|
||||||
<td>{{user.email}}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" id="adminCheck" [checked]="user.admin"
|
|
||||||
disabled>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="p-4">
|
|
||||||
<h3>Quotes</h3>
|
|
||||||
<table class="table mt-3">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Quote</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr *ngFor="let quote of store.quotes | async">
|
|
||||||
<td>{{quote.text}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a routerLink="">+ Add Quote</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<footer class="p-1 bg-dark text-center" style="color: grey">
|
|
||||||
© 2019 ZaksCode
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,11 +0,0 @@
|
|||||||
import {Component} from '@angular/core';
|
|
||||||
import {AdminService} from './admin.service';
|
|
||||||
import {AppStore} from '../app.store';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'admin',
|
|
||||||
templateUrl: 'admin.component.html'
|
|
||||||
})
|
|
||||||
export class AdminComponent {
|
|
||||||
constructor(public adminService: AdminService, public store: AppStore) {}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import {Observable} from 'rxjs';
|
|
||||||
import {DbUser} from '../models/dbUser';
|
|
||||||
import {AngularFirestore} from '@angular/fire/firestore';
|
|
||||||
import {Injectable} from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class AdminService {
|
|
||||||
users: Observable<DbUser[]>;
|
|
||||||
|
|
||||||
constructor(private firestore: AngularFirestore) {
|
|
||||||
this.users = this.firestore.collection<DbUser>('users').valueChanges();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<div style="position: absolute; top: 1em; right: 1em">
|
|
||||||
<div *ngIf="loggedIn">
|
|
||||||
<a routerLink="/admin" class="mr-3">Admin Panel</a>
|
|
||||||
<a routerLink="" (click)="authService.logout()">Logout</a>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!loggedIn">
|
|
||||||
<a routerLink="" (click)="authService.googleLogin()">Login</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<router-outlet></router-outlet>
|
|
@ -1,20 +0,0 @@
|
|||||||
import {Component} from '@angular/core';
|
|
||||||
import {AuthService} from './auth.service';
|
|
||||||
import {ActivatedRoute} from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
templateUrl: 'app.component.html'
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
loggedIn = false;
|
|
||||||
|
|
||||||
set title(title: string) {
|
|
||||||
document.getElementsByTagName('title')[0].innerHTML = `Zaks Code${title ? ` - ${title}` : ''}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, public authService: AuthService) {
|
|
||||||
this.route.url.subscribe(() => this.title = ''); // Clear the title on nav event
|
|
||||||
this.authService.user.subscribe(user => this.loggedIn = !!user);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +1,17 @@
|
|||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {AngularFireModule} from '@angular/fire';
|
import {HomeComponent} from './views/home/home.component';
|
||||||
import {AngularFirestoreModule, FirestoreSettingsToken} from '@angular/fire/firestore';
|
|
||||||
|
|
||||||
import {HomeComponent} from './home/home.component';
|
|
||||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||||
import {MaterialModule} from './material.module';
|
import {MaterialModule} from './material.module';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {TypewriterComponent} from './components/typewriter/typewriter.component';
|
import {TypewriterComponent} from './components/typewriter/typewriter.component';
|
||||||
import {SlideShowComponent} from './components/slideShow/slideShow.component';
|
import {SlideShowComponent} from './components/slideShow/slideShow.component';
|
||||||
import {environment} from '../environments/environment';
|
import {AppComponent} from './views/app/app.component';
|
||||||
import {AppComponent} from './app.component';
|
|
||||||
import {AppRouting} from './app.routing';
|
import {AppRouting} from './app.routing';
|
||||||
import {AdminComponent} from './admin/admin.component';
|
|
||||||
import {AngularFireAuthModule} from '@angular/fire/auth';
|
|
||||||
import {ConsoleComponent} from './components/console/console.component';
|
import {ConsoleComponent} from './components/console/console.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AdminComponent,
|
|
||||||
AppComponent,
|
AppComponent,
|
||||||
ConsoleComponent,
|
ConsoleComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
@ -26,18 +19,12 @@ import {ConsoleComponent} from './components/console/console.component';
|
|||||||
TypewriterComponent
|
TypewriterComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
AngularFireAuthModule,
|
|
||||||
AngularFireModule.initializeApp(environment.firebase),
|
|
||||||
AngularFirestoreModule,
|
|
||||||
AppRouting,
|
AppRouting,
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MaterialModule,
|
MaterialModule,
|
||||||
],
|
],
|
||||||
providers: [
|
|
||||||
{ provide: FirestoreSettingsToken, useValue: {} }
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import {HomeComponent} from './home/home.component';
|
import {HomeComponent} from './views/home/home.component';
|
||||||
import {AdminComponent} from './admin/admin.component';
|
|
||||||
import {AuthService} from './auth.service';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forRoot([
|
RouterModule.forRoot([
|
||||||
{path: '', component: HomeComponent},
|
{path: '', component: HomeComponent},
|
||||||
{path: 'admin', component: AdminComponent, canActivate: [AuthService]},
|
|
||||||
{path: '**', redirectTo: ''}
|
{path: '**', redirectTo: ''}
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {BehaviorSubject, Observable} from 'rxjs';
|
|
||||||
import {AngularFirestore} from '@angular/fire/firestore';
|
|
||||||
import {Quote} from './models/quote';
|
|
||||||
import {DbUser} from './models/dbUser';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class AppStore {
|
|
||||||
quotes: Observable<Quote[]>;
|
|
||||||
|
|
||||||
constructor(private firestore: AngularFirestore) {
|
|
||||||
this.quotes = this.firestore.collection<Quote>('quotes').valueChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
addQuote(text: string) {
|
|
||||||
return this.firestore.collection<Quote>('quotes').add({text: text});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getUser(uid: string) {
|
|
||||||
let user = await this.firestore.collection<DbUser>('users').doc(uid).get().toPromise();
|
|
||||||
return user.data();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {AngularFireAuth} from '@angular/fire/auth';
|
|
||||||
import {CanActivate, Router} from '@angular/router';
|
|
||||||
import {BehaviorSubject, Observable} from 'rxjs';
|
|
||||||
import { auth } from 'firebase';
|
|
||||||
|
|
||||||
import {map} from 'rxjs/operators';
|
|
||||||
import {User} from './models/user';
|
|
||||||
import {AppStore} from './app.store';
|
|
||||||
import {tap} from 'rxjs/internal/operators/tap';
|
|
||||||
import {filter} from 'rxjs/internal/operators/filter';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class AuthService implements CanActivate {
|
|
||||||
user = new BehaviorSubject<User>(null);
|
|
||||||
|
|
||||||
constructor(private store: AppStore, private afAuth: AngularFireAuth, private router: Router) {
|
|
||||||
this.afAuth.user.subscribe(async user => {
|
|
||||||
this.user.next(user ? <User>Object.assign(await this.store.getUser(user.uid), user): null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canActivate(): Observable<boolean> {
|
|
||||||
return this.user.pipe(
|
|
||||||
filter(user => !!user),
|
|
||||||
map(user => !user.isAnonymous),
|
|
||||||
tap(user => user ? null : this.googleLogin())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
googleLogin() {
|
|
||||||
return this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
async logout() {
|
|
||||||
await this.afAuth.auth.signOut();
|
|
||||||
this.router.navigate(['/']);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,10 @@
|
|||||||
<div clas="p-1" style="background-color: #353535; color: #fff;">
|
<div class="p-3 d-flex flex-column justify-content-end console overflow-hidden" [style.height]="height">
|
||||||
<div class="pl-2 pt-2" style="height: 10rem;">
|
<div>
|
||||||
<h4 *ngFor="let o of output">{{o}}</h4>
|
<h4 class="m-0" *ngFor="let o of output">{{o}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="pl-2 pb-2">
|
<div class="mt-2">
|
||||||
<h4 class="d-inline mr-2" style="color: #22ff22">></h4><typewriter [text]="input" (done)="enter()"></typewriter>
|
<h4 class="m-0">
|
||||||
|
{{prompt}} <typewriter class="pl-2" [text]="input" (done)="done()"></typewriter>
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,32 +1,35 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component, Input, ViewChild} from '@angular/core';
|
||||||
import {AppStore} from '../../app.store';
|
import { take } from 'rxjs';
|
||||||
import {map} from 'rxjs/operators';
|
import {TypewriterComponent} from '../typewriter/typewriter.component';
|
||||||
|
|
||||||
|
export type ConsoleConfig = {
|
||||||
|
input: string,
|
||||||
|
output: () => string
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'console',
|
selector: 'console',
|
||||||
templateUrl: './console.component.html'
|
templateUrl: './console.component.html',
|
||||||
|
styleUrls: ['./console.component.scss']
|
||||||
})
|
})
|
||||||
export class ConsoleComponent {
|
export class ConsoleComponent {
|
||||||
private done = false;
|
input = '';
|
||||||
|
output: string[] = [];
|
||||||
|
prompt = '>'
|
||||||
|
|
||||||
input = './motd.sh';
|
done = () => {};
|
||||||
output = [];
|
|
||||||
quote;
|
|
||||||
|
|
||||||
constructor(private store: AppStore) {
|
@Input() height: string = 'auto';
|
||||||
store.quotes.subscribe(quotes => {
|
|
||||||
const quote = quotes[Math.floor(Math.random() * quotes.length)];
|
|
||||||
this.quote = quote.text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
enter() {
|
@ViewChild(TypewriterComponent) typewriter!: TypewriterComponent;
|
||||||
if(this.done) return;
|
|
||||||
setTimeout(() => {
|
exec(input: string, output: () => string) {
|
||||||
this.output.push(this.input);
|
this.done = () => {
|
||||||
this.input = '';
|
this.output.push(`${this.prompt} ${input}`);
|
||||||
setTimeout(() => this.output.push(this.quote), 500);
|
console.log(output());
|
||||||
}, 1500);
|
this.output.push(output());
|
||||||
this.done = true;
|
this.input = '';
|
||||||
}
|
};
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {Slide} from '../../models/slide';
|
|
||||||
|
export type Slide = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'slideshow',
|
selector: 'slideshow',
|
||||||
templateUrl: 'slideShow.component.html'
|
templateUrl: 'slideShow.component.html'
|
||||||
})
|
})
|
||||||
export class SlideShowComponent {
|
export class SlideShowComponent {
|
||||||
@Input() slides: Slide[];
|
@Input() slides: Slide[] = [];
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,30 @@
|
|||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {Observable, timer} from 'rxjs';
|
import {Observable, of, timer} from 'rxjs';
|
||||||
import {filter, map, tap} from 'rxjs/operators';
|
import {filter, map, tap} from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'typewriter',
|
selector: 'typewriter',
|
||||||
template: `
|
template: `<span class="typewriter">{{output | async}}</span>`,
|
||||||
<div class="d-inline typewriter"><h4 class="d-inline">{{output | async}}</h4></div>`,
|
|
||||||
styleUrls: ['typewriter.component.scss']
|
styleUrls: ['typewriter.component.scss']
|
||||||
})
|
})
|
||||||
export class TypewriterComponent {
|
export class TypewriterComponent {
|
||||||
|
output?: Observable<string>;
|
||||||
|
|
||||||
@Input() delay = 1500;
|
@Input() delay = 1500;
|
||||||
@Input() speed = 100;
|
@Input() speed = 100;
|
||||||
@Input() set text(text: string) {
|
@Input() set text(text: string) {
|
||||||
this.output = timer(this.delay, this.speed).pipe(
|
if(!text) {
|
||||||
filter(n => n <= (text.length || 0)),
|
this.output = of('');
|
||||||
tap(n => {
|
} else {
|
||||||
if(n == text.length) this.done.emit();
|
this.output = timer(this.delay, this.speed).pipe(
|
||||||
}),
|
filter(n => n <= (text.length || 0)),
|
||||||
map(n => text.slice(0, n))
|
tap(n => {
|
||||||
);
|
if(n == text.length) this.done.emit();
|
||||||
|
}),
|
||||||
|
map(n => text.slice(0, n))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Output() done = new EventEmitter<void>();
|
@Output() done = new EventEmitter<void>();
|
||||||
|
|
||||||
output: Observable<string>;
|
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
<div class="w-100">
|
|
||||||
<div class="w-100" style="height: calc(100vh - 140px)"></div>
|
|
||||||
<div class="container p-0 bg-white">
|
|
||||||
<div class="px-4" style="background-color: #732222">
|
|
||||||
<mat-card style="max-width: 600px; transform: translateY(-33%)">
|
|
||||||
<mat-card-content class="d-flex p-3">
|
|
||||||
<div class="d-none d-md-block pr-3">
|
|
||||||
<img src="assets/img/portrait.jpg" width="150px" height="150px" style="border-radius: 50%" alt="Zakary Timson">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1 class="mb-0">Zakary Timson</h1>
|
|
||||||
<h5 class="text-muted">FULL STACK SOFTWARE ENGINEER</h5>
|
|
||||||
<div class="mt-3">
|
|
||||||
<div><i class="mr-2 fa fa-map-marker-alt"></i> London Ontario, Canada</div>
|
|
||||||
<div><i class="mr-2 fa fa-envelope"></i> <a href="mailto:zaktimson@gmail.com">zaktimson@gmail.com</a>
|
|
||||||
</div>
|
|
||||||
<div><i class="mr-2 fab fa-github"></i> <a href="https://github.com/ztimson" target="_blank">github.com/ztimson</a></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
</div>
|
|
||||||
<div class="p-4">
|
|
||||||
<console></console>
|
|
||||||
</div>
|
|
||||||
<div class="p-4">
|
|
||||||
<h3>About Me</h3>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<p>
|
|
||||||
Zak was born with a keyboard in hand and was learning his first programming language by thirteen. Nearly
|
|
||||||
entirely self taught, Zak challenged his programming courses through both highschool and college while
|
|
||||||
working in the industry to gain professional experience. He is very passionate about technology and as a
|
|
||||||
lifelong learner it has opened the door to many other hobbies like robotics, space and physics. Some of his
|
|
||||||
personal projects include a full sized arcade machine, home automation and a power wall for a home solar
|
|
||||||
system.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex-shrink-1 p-3">
|
|
||||||
<img src="assets/img/keyboard-in-hand.jpg" height="150px" width="auto" style="border-radius: 50%">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- <div class="p-4 text-white" style="background-color: #1c7fc1">
|
|
||||||
<h3>Projects</h3>
|
|
||||||
<div style="height: 400px">
|
|
||||||
<slideshow></slideshow>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
<div class="p-4">
|
|
||||||
<h3>Resume & References</h3>
|
|
||||||
<a class="btn btn-outline-primary" href="https://docs.google.com/document/d/1xP6HASPerXKMJM_x6-PhHVvoYgq-Hym5IRO7g47EX8o/edit?usp=sharing" target="_blank">Resume</a>
|
|
||||||
<div class="ml-3 btn-group" role="group" aria-label="Basic example">
|
|
||||||
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyNWw0UDFzT0ZTeVU/view?usp=sharing" target="_blank">Manager</a>
|
|
||||||
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyaFBhcXBEaGp6YWc/view?usp=sharing" target="_blank">Contractor</a>
|
|
||||||
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyM0YtTWcxQzk0dEE/view?usp=sharing" target="_blank">Teacher</a>
|
|
||||||
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyX2owd0xURjh3RlE/view?usp=sharing" target="_blank">Principle</a>
|
|
||||||
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyMHdaM1BjZ1MwbWxva2lOY290NElwanN4b2JV/view?usp=sharing" target="_blank">CD Project Red</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="p-1 bg-dark text-center" style="color: grey">
|
|
||||||
Copyright © Zakary Timson 2019 | All Rights Reserved
|
|
||||||
</footer>
|
|
||||||
<div class="skirt"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,7 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'home',
|
|
||||||
templateUrl: './home.component.html'
|
|
||||||
})
|
|
||||||
export class HomeComponent { }
|
|
@ -1,5 +1,5 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {MatCardModule} from '@angular/material';
|
import {MatCardModule} from '@angular/material/card';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
MatCardModule
|
MatCardModule
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export interface DbUser {
|
|
||||||
admin: boolean;
|
|
||||||
email: string;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export interface Quote {
|
|
||||||
text: string;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import {SafeUrl} from '@angular/platform-browser';
|
|
||||||
|
|
||||||
export interface Slide {
|
|
||||||
title: string
|
|
||||||
description: string
|
|
||||||
image: string | SafeUrl
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import {User as FirebaseUser} from 'firebase';
|
|
||||||
import {DbUser} from './dbUser';
|
|
||||||
|
|
||||||
export interface User extends FirebaseUser, DbUser { }
|
|
1
src/app/views/app/app.component.html
Normal file
1
src/app/views/app/app.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<router-outlet></router-outlet>
|
17
src/app/views/app/app.component.ts
Normal file
17
src/app/views/app/app.component.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {Title} from '@angular/platform-browser';
|
||||||
|
import {ActivatedRoute} from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: 'app.component.html'
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
constructor(private route: ActivatedRoute, private title: Title) {
|
||||||
|
this.route.url.subscribe(() => this.setTitle(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitle(title: string) {
|
||||||
|
this.title.setTitle(`Zak's Code${title ? ` - ${title}` : ''}`);
|
||||||
|
}
|
||||||
|
}
|
69
src/app/views/home/home.component.html
Normal file
69
src/app/views/home/home.component.html
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<div class="w-100">
|
||||||
|
<div class="w-100" style="height: calc(100vh - 140px)"></div>
|
||||||
|
<div class="container p-0 bg-white">
|
||||||
|
<div class="px-3" style="background-color: #732222">
|
||||||
|
<mat-card style="max-width: 600px; transform: translateY(-33%)">
|
||||||
|
<mat-card-content class="d-flex p-3">
|
||||||
|
<div class="d-none d-md-block pr-3">
|
||||||
|
<img src="assets/img/portrait.jpg" width="150px" height="150px" style="border-radius: 50%" alt="Zakary Timson">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 class="mb-0">Zakary Timson</h1>
|
||||||
|
<h5 class="text-muted">DEVOPS & SOFTWARE ENGINEER</h5>
|
||||||
|
<div class="mt-3">
|
||||||
|
<div><i class="mr-2 fa fa-map-marker-alt"></i> London Ontario, Canada</div>
|
||||||
|
<div><i class="mr-2 fa fa-envelope"></i> <a href="mailto:zaktimson@gmail.com">zaktimson@gmail.com</a>
|
||||||
|
</div>
|
||||||
|
<div><i class="mr-2 fab fa-github"></i> <a href="https://github.com/ztimson" target="_blank">github.com/ztimson</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<div class="p-3">
|
||||||
|
<console height="12rem"></console>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="p-3">-->
|
||||||
|
<!-- <h3>Projects</h3>-->
|
||||||
|
<!-- <iframe class="border-0" src="https://gitlab.zakscode.com/explore" width="100%" height="75vh">-->
|
||||||
|
<!-- </iframe>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="p-3">
|
||||||
|
<h3>About Me</h3>
|
||||||
|
<div>
|
||||||
|
<img alt="Childhood" class="float-right m-3 m-md-0 ml-md-3" src="assets/img/keyboard-in-hand.jpg" height="150px" width="auto" style="border-radius: 50%">
|
||||||
|
<p>
|
||||||
|
Zak was born with a keyboard in hand and was learning his first programming language by thirteen. Nearly
|
||||||
|
entirely self taught, Zak challenged his programming courses through both high-school and college while
|
||||||
|
working in the industry to gain professional experience. He is very passionate about technology and as a
|
||||||
|
lifelong learner it has opened the door to many other hobbies like robotics, space and physics. Some of his
|
||||||
|
personal projects include a full sized arcade machine, home automation and a power wall for a home solar
|
||||||
|
system.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 overflow-hidden">
|
||||||
|
<h3>Resume & References</h3>
|
||||||
|
<a class="mb-3 btn btn-outline-primary" href="https://docs.google.com/document/d/1xP6HASPerXKMJM_x6-PhHVvoYgq-Hym5IRO7g47EX8o/edit?usp=sharing" target="_blank">Resume</a>
|
||||||
|
<ul class="d-md-none list-group">
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://docs.google.com/document/d/1xP6HASPerXKMJM_x6-PhHVvoYgq-Hym5IRO7g47EX8o/edit?usp=sharing" target="_blank">Resume</a>
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyNWw0UDFzT0ZTeVU/view?usp=sharing" target="_blank">Manager</a>
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyaFBhcXBEaGp6YWc/view?usp=sharing" target="_blank">Contractor</a>
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyM0YtTWcxQzk0dEE/view?usp=sharing" target="_blank">Teacher</a>
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyX2owd0xURjh3RlE/view?usp=sharing" target="_blank">Principle</a>
|
||||||
|
<a class="list-group-item list-group-item-action border-info text-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyMHdaM1BjZ1MwbWxva2lOY290NElwanN4b2JV/view?usp=sharing" target="_blank">CD Projekt Red</a>
|
||||||
|
</ul>
|
||||||
|
<div class="d-none d-md-block btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyNWw0UDFzT0ZTeVU/view?usp=sharing" target="_blank">Manager</a>
|
||||||
|
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyaFBhcXBEaGp6YWc/view?usp=sharing" target="_blank">Contractor</a>
|
||||||
|
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyM0YtTWcxQzk0dEE/view?usp=sharing" target="_blank">Teacher</a>
|
||||||
|
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyX2owd0xURjh3RlE/view?usp=sharing" target="_blank">Principle</a>
|
||||||
|
<a class="btn btn-outline-info" href="https://drive.google.com/file/d/0B_iz0vkzXmAyMHdaM1BjZ1MwbWxva2lOY290NElwanN4b2JV/view?usp=sharing" target="_blank">CD Projekt Red</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="p-1 bg-dark text-center" style="color: grey">
|
||||||
|
Copyright © Zakary Timson 2019 | All Rights Reserved
|
||||||
|
</footer>
|
||||||
|
<div class="d-none d-sm-block skirt"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
15
src/app/views/home/home.component.ts
Normal file
15
src/app/views/home/home.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {Component, ViewChild} from '@angular/core';
|
||||||
|
import {ConsoleComponent, ConsoleConfig} from '../../components/console/console.component';
|
||||||
|
import {QuoteService} from '../../services/quote.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'home',
|
||||||
|
templateUrl: './home.component.html'
|
||||||
|
})
|
||||||
|
export class HomeComponent {
|
||||||
|
@ViewChild(ConsoleComponent) console!: ConsoleComponent;
|
||||||
|
|
||||||
|
constructor(private quotes: QuoteService) {
|
||||||
|
setTimeout(() => this.console.exec('bash ./random-thought.sh', () => quotes.random()), 3000);
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
# 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
|
|
@ -1,11 +1,3 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true,
|
production: true
|
||||||
firebase: {
|
|
||||||
apiKey: "AIzaSyC1vKmDDzRR85DnOowPZvAkZEyzJ1EmjGI",
|
|
||||||
authDomain: "zaks-code.firebaseapp.com",
|
|
||||||
databaseURL: "https://zaks-code.firebaseio.com",
|
|
||||||
projectId: "zaks-code",
|
|
||||||
storageBucket: "zaks-code.appspot.com",
|
|
||||||
messagingSenderId: "430075133237"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false
|
||||||
firebase: {
|
|
||||||
apiKey: 'AIzaSyC1vKmDDzRR85DnOowPZvAkZEyzJ1EmjGI',
|
|
||||||
authDomain: 'zaks-code.firebaseapp.com',
|
|
||||||
databaseURL: 'https://zaks-code.firebaseio.com',
|
|
||||||
projectId: 'zaks-code',
|
|
||||||
storageBucket: 'zaks-code.appspot.com',
|
|
||||||
messagingSenderId: '430075133237'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For easier debugging in development mode, you can import the following file
|
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||||
|
*
|
||||||
|
* This import should be commented out in production mode because it will have a negative impact
|
||||||
|
* on performance if an error is thrown.
|
||||||
|
*/
|
||||||
|
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Zaks Code</title>
|
<title>Zaks Code</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name=”robots” content=”index,nofollow” />
|
<meta name=”robots” content=”index,nofollow” />
|
||||||
<meta property=”og:type” content=”website” />
|
<meta property=”og:type” content=”website” />
|
||||||
<meta property=”og:title” content=”Zakary Timson” />
|
<meta property=”og:title” content=”Zakary Timson” />
|
||||||
<meta property=”og:description” content=”Cloud Architecture & Software Engineering” />
|
<meta property=”og:description” content=”Cloud Architecture & Software Engineering” />
|
||||||
<meta property=”og:image” content=”https://zakscode.com/assets/img/ZaksCode.png” />
|
<meta property=”og:image” content=”https://zakscode.com/assets/img/ZaksCode.png” />
|
||||||
<meta property=”og:url” content=”https://zakscode.com” />
|
<meta property=”og:url” content=”https://zakscode.com” />
|
||||||
<meta property=”og:site_name” content=”ZaksCode” />
|
<meta property=”og:site_name” content=”ZaksCode” />
|
||||||
<meta name=”twitter:title” content=”Zakary Timson” />
|
<meta name=”twitter:title” content=”Zakary Timson” />
|
||||||
<meta name=”twitter:description” content=”Cloud Architecture & Software Engineering” />
|
<meta name=”twitter:description” content=”Cloud Architecture & Software Engineering” />
|
||||||
<meta name=”twitter:image” content=”https://zakscode.com/assets/img/ZaksCode.png” />
|
<meta name=”twitter:image” content=”https://zakscode.com/assets/img/ZaksCode.png” />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="assets/img/logo.png">
|
<link rel="icon" type="image/png" href="assets/img/logo.png">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'hammerjs';
|
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
* 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),
|
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||||
*
|
*
|
||||||
* Learn more in https://angular.io/guide/browser-support
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
*/
|
*/
|
||||||
@ -18,16 +18,6 @@
|
|||||||
* BROWSER POLYFILLS
|
* BROWSER POLYFILLS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
|
||||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
@ -35,7 +25,7 @@
|
|||||||
* will put import in the top of bundle, so user need to create a separate file
|
* will put import in the top of bundle, so user need to create a separate file
|
||||||
* in this directory (for example: zone-flags.ts), and put the following flags
|
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||||
* into that file, and then add the following code before importing zone.js.
|
* into that file, and then add the following code before importing zone.js.
|
||||||
* import './zone-flags.ts';
|
* import './zone-flags';
|
||||||
*
|
*
|
||||||
* The flags allowed in zone-flags.ts are listed here.
|
* The flags allowed in zone-flags.ts are listed here.
|
||||||
*
|
*
|
||||||
@ -43,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
* (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_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
*
|
*
|
||||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
* 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
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
@ -55,7 +45,7 @@
|
|||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
* Zone JS is required by default for Angular itself.
|
* Zone JS is required by default for Angular itself.
|
||||||
*/
|
*/
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
import 'zone.js'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
|
@ -1,3 +1,38 @@
|
|||||||
|
|
||||||
|
// Custom Theming for Angular Material
|
||||||
|
// For more information: https://material.angular.io/guide/theming
|
||||||
|
@use '@angular/material' as mat;
|
||||||
|
// Plus imports for other components in your app.
|
||||||
|
|
||||||
|
// Include the common styles for Angular Material. We include this here so that you only
|
||||||
|
// have to load a single css file for Angular Material in your app.
|
||||||
|
// Be sure that you only ever include this mixin once!
|
||||||
|
@include mat.core();
|
||||||
|
|
||||||
|
// Define the palettes for your theme using the Material Design palettes available in palette.scss
|
||||||
|
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
|
||||||
|
// hue. Available color palettes: https://material.io/design/color/
|
||||||
|
$zakscode-primary: mat.define-palette(mat.$indigo-palette);
|
||||||
|
$zakscode-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
|
||||||
|
|
||||||
|
// The warn palette is optional (defaults to red).
|
||||||
|
$zakscode-warn: mat.define-palette(mat.$red-palette);
|
||||||
|
|
||||||
|
// Create the theme object. A theme consists of configurations for individual
|
||||||
|
// theming systems such as "color" or "typography".
|
||||||
|
$zakscode-theme: mat.define-light-theme((
|
||||||
|
color: (
|
||||||
|
primary: $zakscode-primary,
|
||||||
|
accent: $zakscode-accent,
|
||||||
|
warn: $zakscode-warn,
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
// Include theme styles for core and each component used in your app.
|
||||||
|
// Alternatively, you can import and @include the theme mixins for each component
|
||||||
|
// that you are using.
|
||||||
|
@include mat.all-component-themes($zakscode-theme);
|
||||||
|
|
||||||
@import url("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css");
|
@import url("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css");
|
||||||
@import url("https://use.fontawesome.com/releases/v5.8.1/css/all.css");
|
@import url("https://use.fontawesome.com/releases/v5.8.1/css/all.css");
|
||||||
@import url("https://fonts.googleapis.com/icon?family=Material+Icons|Roboto:300,400,500");
|
@import url("https://fonts.googleapis.com/icon?family=Material+Icons|Roboto:300,400,500");
|
||||||
@ -18,17 +53,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Roboto, sans-serif;
|
font-family: Roboto, sans-serif;
|
||||||
background: #354B72 url("/assets/img/ZaksCode.gif") no-repeat fixed center;
|
background: #354B72 url("/assets/img/ZaksCode.gif") no-repeat fixed center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skirt {
|
.skirt {
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #354B72;
|
background-color: #354B72;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html, body { height: 100%; }
|
||||||
|
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||||
|
12
src/test.ts
12
src/test.ts
@ -1,19 +1,25 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
import 'zone.js/dist/zone-testing';
|
import 'zone.js/testing';
|
||||||
import { getTestBed } from '@angular/core/testing';
|
import { getTestBed } from '@angular/core/testing';
|
||||||
import {
|
import {
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
declare const require: any;
|
declare const require: {
|
||||||
|
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||||
|
<T>(id: string): T;
|
||||||
|
keys(): string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting()
|
platformBrowserDynamicTesting(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Then we find all the tests.
|
// Then we find all the tests.
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
// And load the modules.
|
// And load the modules.
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/app",
|
|
||||||
"types": []
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"test.ts",
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/spec",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"test.ts",
|
|
||||||
"polyfills.ts"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"**/*.spec.ts",
|
|
||||||
"**/*.d.ts"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tslint.json",
|
|
||||||
"rules": {
|
|
||||||
"directive-selector": [
|
|
||||||
true,
|
|
||||||
"attribute",
|
|
||||||
"app",
|
|
||||||
"camelCase"
|
|
||||||
],
|
|
||||||
"component-selector": [
|
|
||||||
true,
|
|
||||||
"element",
|
|
||||||
"app",
|
|
||||||
"kebab-case"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
service firebase.storage {
|
|
||||||
match /b/{bucket}/o {
|
|
||||||
match /{allPaths=**} {
|
|
||||||
allow read;
|
|
||||||
allow write: if request.auth != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
15
tsconfig.app.json
Normal file
15
tsconfig.app.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
@ -1,22 +1,32 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"outDir": "./dist/out-tsc",
|
"outDir": "./dist/out-tsc",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"module": "es2015",
|
"downlevelIteration": true,
|
||||||
"moduleResolution": "node",
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es5",
|
"target": "es2017",
|
||||||
"typeRoots": [
|
"module": "es2020",
|
||||||
"node_modules/@types"
|
|
||||||
],
|
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2018",
|
"es2020",
|
||||||
"dom"
|
"dom"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
tsconfig.spec.json
Normal file
18
tsconfig.spec.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/test.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
75
tslint.json
75
tslint.json
@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "tslint:recommended",
|
|
||||||
"rulesDirectory": [
|
|
||||||
"codelyzer"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"array-type": false,
|
|
||||||
"arrow-parens": false,
|
|
||||||
"deprecation": {
|
|
||||||
"severity": "warn"
|
|
||||||
},
|
|
||||||
"import-blacklist": [
|
|
||||||
true,
|
|
||||||
"rxjs/Rx"
|
|
||||||
],
|
|
||||||
"interface-name": false,
|
|
||||||
"max-classes-per-file": false,
|
|
||||||
"max-line-length": [
|
|
||||||
true,
|
|
||||||
140
|
|
||||||
],
|
|
||||||
"member-access": false,
|
|
||||||
"member-ordering": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"order": [
|
|
||||||
"static-field",
|
|
||||||
"instance-field",
|
|
||||||
"static-method",
|
|
||||||
"instance-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-consecutive-blank-lines": false,
|
|
||||||
"no-console": [
|
|
||||||
true,
|
|
||||||
"debug",
|
|
||||||
"info",
|
|
||||||
"time",
|
|
||||||
"timeEnd",
|
|
||||||
"trace"
|
|
||||||
],
|
|
||||||
"no-empty": false,
|
|
||||||
"no-inferrable-types": [
|
|
||||||
true,
|
|
||||||
"ignore-params"
|
|
||||||
],
|
|
||||||
"no-non-null-assertion": true,
|
|
||||||
"no-redundant-jsdoc": true,
|
|
||||||
"no-switch-case-fall-through": true,
|
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-var-requires": false,
|
|
||||||
"object-literal-key-quotes": [
|
|
||||||
true,
|
|
||||||
"as-needed"
|
|
||||||
],
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"ordered-imports": false,
|
|
||||||
"quotemark": [
|
|
||||||
true,
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"trailing-comma": false,
|
|
||||||
"no-output-on-prefix": true,
|
|
||||||
"use-input-property-decorator": true,
|
|
||||||
"use-output-property-decorator": true,
|
|
||||||
"use-host-property-decorator": true,
|
|
||||||
"no-input-rename": true,
|
|
||||||
"no-output-rename": true,
|
|
||||||
"use-life-cycle-interface": true,
|
|
||||||
"use-pipe-transform-interface": true,
|
|
||||||
"component-class-suffix": true,
|
|
||||||
"directive-class-suffix": true
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user