| @@ -0,0 +1,20 @@ | |||||
| # IDEs and editors | |||||
| .idea/ | |||||
| .project | |||||
| .classpath | |||||
| .c9/ | |||||
| *.launch | |||||
| .settings/ | |||||
| *.sublime-workspace | |||||
| # Visual Studio Code | |||||
| .vscode/* | |||||
| !.vscode/settings.json | |||||
| !.vscode/tasks.json | |||||
| !.vscode/launch.json | |||||
| !.vscode/extensions.json | |||||
| .history/* | |||||
| # System files | |||||
| .DS_Store | |||||
| Thumbs.db | |||||
| @@ -1,2 +1,16 @@ | |||||
| # matsen-tool-fe | # matsen-tool-fe | ||||
| # BEFORE Installation: | |||||
| - npm -v (minimum is 20.9.0) | |||||
| - node --version (minimum is 8.0.0) | |||||
| - brew upgrade node | |||||
| ## Installation | |||||
| - npm i -g @angular/cli | |||||
| - ng new matsen-tool | |||||
| - cd matsen-tool -> ng serve | |||||
| ## Install Bootstrap | |||||
| - npm i bootstrap @popperjs/core --save | |||||
| @@ -0,0 +1,16 @@ | |||||
| # Editor configuration, see https://editorconfig.org | |||||
| root = true | |||||
| [*] | |||||
| charset = utf-8 | |||||
| indent_style = space | |||||
| indent_size = 2 | |||||
| insert_final_newline = true | |||||
| trim_trailing_whitespace = true | |||||
| [*.ts] | |||||
| quote_type = single | |||||
| [*.md] | |||||
| max_line_length = off | |||||
| trim_trailing_whitespace = false | |||||
| @@ -0,0 +1,42 @@ | |||||
| # See http://help.github.com/ignore-files/ for more about ignoring files. | |||||
| # Compiled output | |||||
| /dist | |||||
| /tmp | |||||
| /out-tsc | |||||
| /bazel-out | |||||
| # Node | |||||
| /node_modules | |||||
| npm-debug.log | |||||
| yarn-error.log | |||||
| # IDEs and editors | |||||
| .idea/ | |||||
| .project | |||||
| .classpath | |||||
| .c9/ | |||||
| *.launch | |||||
| .settings/ | |||||
| *.sublime-workspace | |||||
| # Visual Studio Code | |||||
| .vscode/* | |||||
| !.vscode/settings.json | |||||
| !.vscode/tasks.json | |||||
| !.vscode/launch.json | |||||
| !.vscode/extensions.json | |||||
| .history/* | |||||
| # Miscellaneous | |||||
| /.angular/cache | |||||
| .sass-cache/ | |||||
| /connect.lock | |||||
| /coverage | |||||
| /libpeerconnection.log | |||||
| testem.log | |||||
| /typings | |||||
| # System files | |||||
| .DS_Store | |||||
| Thumbs.db | |||||
| @@ -0,0 +1,4 @@ | |||||
| { | |||||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 | |||||
| "recommendations": ["angular.ng-template"] | |||||
| } | |||||
| @@ -0,0 +1,20 @@ | |||||
| { | |||||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | |||||
| "version": "0.2.0", | |||||
| "configurations": [ | |||||
| { | |||||
| "name": "ng serve", | |||||
| "type": "chrome", | |||||
| "request": "launch", | |||||
| "preLaunchTask": "npm: start", | |||||
| "url": "http://localhost:4200/" | |||||
| }, | |||||
| { | |||||
| "name": "ng test", | |||||
| "type": "chrome", | |||||
| "request": "launch", | |||||
| "preLaunchTask": "npm: test", | |||||
| "url": "http://localhost:9876/debug.html" | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,42 @@ | |||||
| { | |||||
| // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 | |||||
| "version": "2.0.0", | |||||
| "tasks": [ | |||||
| { | |||||
| "type": "npm", | |||||
| "script": "start", | |||||
| "isBackground": true, | |||||
| "problemMatcher": { | |||||
| "owner": "typescript", | |||||
| "pattern": "$tsc", | |||||
| "background": { | |||||
| "activeOnStart": true, | |||||
| "beginsPattern": { | |||||
| "regexp": "(.*?)" | |||||
| }, | |||||
| "endsPattern": { | |||||
| "regexp": "bundle generation complete" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "type": "npm", | |||||
| "script": "test", | |||||
| "isBackground": true, | |||||
| "problemMatcher": { | |||||
| "owner": "typescript", | |||||
| "pattern": "$tsc", | |||||
| "background": { | |||||
| "activeOnStart": true, | |||||
| "beginsPattern": { | |||||
| "regexp": "(.*?)" | |||||
| }, | |||||
| "endsPattern": { | |||||
| "regexp": "bundle generation complete" | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| # MatsenTool | |||||
| This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.5. | |||||
| ## 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. | |||||
| @@ -0,0 +1,112 @@ | |||||
| { | |||||
| "$schema": "./node_modules/@angular/cli/lib/config/schema.json", | |||||
| "version": 1, | |||||
| "newProjectRoot": "projects", | |||||
| "projects": { | |||||
| "matsen-tool": { | |||||
| "projectType": "application", | |||||
| "schematics": { | |||||
| "@schematics/angular:component": { | |||||
| "style": "scss" | |||||
| } | |||||
| }, | |||||
| "root": "", | |||||
| "sourceRoot": "src", | |||||
| "prefix": "app", | |||||
| "architect": { | |||||
| "build": { | |||||
| "builder": "@angular-devkit/build-angular:application", | |||||
| "options": { | |||||
| "outputPath": "dist/matsen-tool", | |||||
| "index": "src/index.html", | |||||
| "browser": "src/main.ts", | |||||
| "polyfills": [ | |||||
| "zone.js" | |||||
| ], | |||||
| "tsConfig": "tsconfig.app.json", | |||||
| "inlineStyleLanguage": "scss", | |||||
| "assets": [ | |||||
| "src/favicon.ico", | |||||
| "src/assets" | |||||
| ], | |||||
| "styles": [ | |||||
| "@angular/material/prebuilt-themes/purple-green.css", | |||||
| "./node_modules/bootstrap/dist/css/bootstrap.min.css", | |||||
| "src/styles.scss" | |||||
| ], | |||||
| "scripts": [ | |||||
| "./node_modules/@popperjs/core/dist/umd/popper.min.js", | |||||
| "./node_modules/bootstrap/dist/js/bootstrap.min.js" | |||||
| ], | |||||
| "server": "src/main.server.ts", | |||||
| "prerender": true, | |||||
| "ssr": { | |||||
| "entry": "server.ts" | |||||
| } | |||||
| }, | |||||
| "configurations": { | |||||
| "production": { | |||||
| "budgets": [ | |||||
| { | |||||
| "type": "initial", | |||||
| "maximumWarning": "500kb", | |||||
| "maximumError": "1mb" | |||||
| }, | |||||
| { | |||||
| "type": "anyComponentStyle", | |||||
| "maximumWarning": "2kb", | |||||
| "maximumError": "4kb" | |||||
| } | |||||
| ], | |||||
| "outputHashing": "all" | |||||
| }, | |||||
| "development": { | |||||
| "optimization": false, | |||||
| "extractLicenses": false, | |||||
| "sourceMap": true | |||||
| } | |||||
| }, | |||||
| "defaultConfiguration": "production" | |||||
| }, | |||||
| "serve": { | |||||
| "builder": "@angular-devkit/build-angular:dev-server", | |||||
| "configurations": { | |||||
| "production": { | |||||
| "buildTarget": "matsen-tool:build:production" | |||||
| }, | |||||
| "development": { | |||||
| "buildTarget": "matsen-tool:build:development" | |||||
| } | |||||
| }, | |||||
| "defaultConfiguration": "development" | |||||
| }, | |||||
| "extract-i18n": { | |||||
| "builder": "@angular-devkit/build-angular:extract-i18n", | |||||
| "options": { | |||||
| "buildTarget": "matsen-tool:build" | |||||
| } | |||||
| }, | |||||
| "test": { | |||||
| "builder": "@angular-devkit/build-angular:karma", | |||||
| "options": { | |||||
| "polyfills": [ | |||||
| "zone.js", | |||||
| "zone.js/testing" | |||||
| ], | |||||
| "tsConfig": "tsconfig.spec.json", | |||||
| "inlineStyleLanguage": "scss", | |||||
| "assets": [ | |||||
| "src/favicon.ico", | |||||
| "src/assets" | |||||
| ], | |||||
| "styles": [ | |||||
| "@angular/material/prebuilt-themes/purple-green.css", | |||||
| "src/styles.scss" | |||||
| ], | |||||
| "scripts": [] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| { | |||||
| "name": "matsen-tool", | |||||
| "version": "0.0.0", | |||||
| "scripts": { | |||||
| "ng": "ng", | |||||
| "start": "ng serve", | |||||
| "build": "ng build", | |||||
| "watch": "ng build --watch --configuration development", | |||||
| "test": "ng test", | |||||
| "serve:ssr:matsen-tool": "node dist/matsen-tool/server/server.mjs" | |||||
| }, | |||||
| "private": true, | |||||
| "dependencies": { | |||||
| "@angular/animations": "^17.0.0", | |||||
| "@angular/cdk": "^17.0.1", | |||||
| "@angular/common": "^17.0.0", | |||||
| "@angular/compiler": "^17.0.0", | |||||
| "@angular/core": "^17.0.0", | |||||
| "@angular/forms": "^17.0.0", | |||||
| "@angular/material": "^17.0.1", | |||||
| "@angular/platform-browser": "^17.0.0", | |||||
| "@angular/platform-browser-dynamic": "^17.0.0", | |||||
| "@angular/platform-server": "^17.0.0", | |||||
| "@angular/router": "^17.0.0", | |||||
| "@angular/ssr": "^17.0.5", | |||||
| "@popperjs/core": "^2.11.8", | |||||
| "bootstrap": "^5.3.2", | |||||
| "express": "^4.18.2", | |||||
| "rxjs": "~7.8.0", | |||||
| "tslib": "^2.3.0", | |||||
| "zone.js": "~0.14.2" | |||||
| }, | |||||
| "devDependencies": { | |||||
| "@angular-devkit/build-angular": "^17.0.5", | |||||
| "@angular/cli": "^17.0.5", | |||||
| "@angular/compiler-cli": "^17.0.0", | |||||
| "@types/express": "^4.17.17", | |||||
| "@types/jasmine": "~5.1.0", | |||||
| "@types/node": "^18.18.0", | |||||
| "jasmine-core": "~5.1.0", | |||||
| "karma": "~6.4.0", | |||||
| "karma-chrome-launcher": "~3.2.0", | |||||
| "karma-coverage": "~2.2.0", | |||||
| "karma-jasmine": "~5.1.0", | |||||
| "karma-jasmine-html-reporter": "~2.1.0", | |||||
| "typescript": "~5.2.2" | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,56 @@ | |||||
| import { APP_BASE_HREF } from '@angular/common'; | |||||
| import { CommonEngine } from '@angular/ssr'; | |||||
| import express from 'express'; | |||||
| import { fileURLToPath } from 'node:url'; | |||||
| import { dirname, join, resolve } from 'node:path'; | |||||
| import bootstrap from './src/main.server'; | |||||
| // The Express app is exported so that it can be used by serverless Functions. | |||||
| export function app(): express.Express { | |||||
| const server = express(); | |||||
| const serverDistFolder = dirname(fileURLToPath(import.meta.url)); | |||||
| const browserDistFolder = resolve(serverDistFolder, '../browser'); | |||||
| const indexHtml = join(serverDistFolder, 'index.server.html'); | |||||
| const commonEngine = new CommonEngine(); | |||||
| server.set('view engine', 'html'); | |||||
| server.set('views', browserDistFolder); | |||||
| // Example Express Rest API endpoints | |||||
| // server.get('/api/**', (req, res) => { }); | |||||
| // Serve static files from /browser | |||||
| server.get('*.*', express.static(browserDistFolder, { | |||||
| maxAge: '1y' | |||||
| })); | |||||
| // All regular routes use the Angular engine | |||||
| server.get('*', (req, res, next) => { | |||||
| const { protocol, originalUrl, baseUrl, headers } = req; | |||||
| commonEngine | |||||
| .render({ | |||||
| bootstrap, | |||||
| documentFilePath: indexHtml, | |||||
| url: `${protocol}://${headers.host}${originalUrl}`, | |||||
| publicPath: browserDistFolder, | |||||
| providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], | |||||
| }) | |||||
| .then((html) => res.send(html)) | |||||
| .catch((err) => next(err)); | |||||
| }); | |||||
| return server; | |||||
| } | |||||
| function run(): void { | |||||
| const port = process.env['PORT'] || 4000; | |||||
| // Start up the Node server | |||||
| const server = app(); | |||||
| server.listen(port, () => { | |||||
| console.log(`Node Express server listening on http://localhost:${port}`); | |||||
| }); | |||||
| } | |||||
| run(); | |||||
| @@ -0,0 +1 @@ | |||||
| <router-outlet></router-outlet> | |||||
| @@ -0,0 +1,29 @@ | |||||
| import { TestBed } from '@angular/core/testing'; | |||||
| import { AppComponent } from './app.component'; | |||||
| describe('AppComponent', () => { | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| imports: [AppComponent], | |||||
| }).compileComponents(); | |||||
| }); | |||||
| it('should create the app', () => { | |||||
| const fixture = TestBed.createComponent(AppComponent); | |||||
| const app = fixture.componentInstance; | |||||
| expect(app).toBeTruthy(); | |||||
| }); | |||||
| it(`should have the 'matsen-tool' title`, () => { | |||||
| const fixture = TestBed.createComponent(AppComponent); | |||||
| const app = fixture.componentInstance; | |||||
| expect(app.title).toEqual('matsen-tool'); | |||||
| }); | |||||
| it('should render title', () => { | |||||
| const fixture = TestBed.createComponent(AppComponent); | |||||
| fixture.detectChanges(); | |||||
| const compiled = fixture.nativeElement as HTMLElement; | |||||
| expect(compiled.querySelector('h1')?.textContent).toContain('Hello, matsen-tool'); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,14 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| import { CommonModule } from '@angular/common'; | |||||
| import { RouterOutlet } from '@angular/router'; | |||||
| @Component({ | |||||
| selector: 'app-root', | |||||
| standalone: true, | |||||
| imports: [CommonModule, RouterOutlet], | |||||
| templateUrl: './app.component.html', | |||||
| styleUrl: './app.component.scss' | |||||
| }) | |||||
| export class AppComponent { | |||||
| title = 'matsen-tool'; | |||||
| } | |||||
| @@ -0,0 +1,11 @@ | |||||
| import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; | |||||
| import { provideServerRendering } from '@angular/platform-server'; | |||||
| import { appConfig } from './app.config'; | |||||
| const serverConfig: ApplicationConfig = { | |||||
| providers: [ | |||||
| provideServerRendering() | |||||
| ] | |||||
| }; | |||||
| export const config = mergeApplicationConfig(appConfig, serverConfig); | |||||
| @@ -0,0 +1,10 @@ | |||||
| import { ApplicationConfig } from '@angular/core'; | |||||
| import { provideRouter } from '@angular/router'; | |||||
| import { routes } from './app.routes'; | |||||
| import { provideClientHydration } from '@angular/platform-browser'; | |||||
| import { provideAnimations } from '@angular/platform-browser/animations'; | |||||
| export const appConfig: ApplicationConfig = { | |||||
| providers: [provideRouter(routes), provideClientHydration(), provideAnimations()] | |||||
| }; | |||||
| @@ -0,0 +1,3 @@ | |||||
| import { Routes } from '@angular/router'; | |||||
| export const routes: Routes = []; | |||||
| @@ -0,0 +1,15 @@ | |||||
| <!doctype html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="utf-8"> | |||||
| <title>MatsenTool</title> | |||||
| <base href="/"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <link rel="icon" type="image/x-icon" href="favicon.ico"> | |||||
| <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> | |||||
| <body class="mat-typography"> | |||||
| <app-root></app-root> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,7 @@ | |||||
| import { bootstrapApplication } from '@angular/platform-browser'; | |||||
| import { AppComponent } from './app/app.component'; | |||||
| import { config } from './app/app.config.server'; | |||||
| const bootstrap = () => bootstrapApplication(AppComponent, config); | |||||
| export default bootstrap; | |||||
| @@ -0,0 +1,6 @@ | |||||
| import { bootstrapApplication } from '@angular/platform-browser'; | |||||
| import { appConfig } from './app/app.config'; | |||||
| import { AppComponent } from './app/app.component'; | |||||
| bootstrapApplication(AppComponent, appConfig) | |||||
| .catch((err) => console.error(err)); | |||||
| @@ -0,0 +1,4 @@ | |||||
| /* You can add global styles to this file, and also import other style files */ | |||||
| html, body { height: 100%; } | |||||
| body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } | |||||
| @@ -0,0 +1,18 @@ | |||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
| { | |||||
| "extends": "./tsconfig.json", | |||||
| "compilerOptions": { | |||||
| "outDir": "./out-tsc/app", | |||||
| "types": [ | |||||
| "node" | |||||
| ] | |||||
| }, | |||||
| "files": [ | |||||
| "src/main.ts", | |||||
| "src/main.server.ts", | |||||
| "server.ts" | |||||
| ], | |||||
| "include": [ | |||||
| "src/**/*.d.ts" | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,32 @@ | |||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
| { | |||||
| "compileOnSave": false, | |||||
| "compilerOptions": { | |||||
| "outDir": "./dist/out-tsc", | |||||
| "forceConsistentCasingInFileNames": true, | |||||
| "strict": true, | |||||
| "noImplicitOverride": true, | |||||
| "noPropertyAccessFromIndexSignature": true, | |||||
| "noImplicitReturns": true, | |||||
| "noFallthroughCasesInSwitch": true, | |||||
| "esModuleInterop": true, | |||||
| "sourceMap": true, | |||||
| "declaration": false, | |||||
| "experimentalDecorators": true, | |||||
| "moduleResolution": "node", | |||||
| "importHelpers": true, | |||||
| "target": "ES2022", | |||||
| "module": "ES2022", | |||||
| "useDefineForClassFields": false, | |||||
| "lib": [ | |||||
| "ES2022", | |||||
| "dom" | |||||
| ] | |||||
| }, | |||||
| "angularCompilerOptions": { | |||||
| "enableI18nLegacyMessageIdFormat": false, | |||||
| "strictInjectionParameters": true, | |||||
| "strictInputAccessModifiers": true, | |||||
| "strictTemplates": true | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| /* To learn more about this file see: https://angular.io/config/tsconfig. */ | |||||
| { | |||||
| "extends": "./tsconfig.json", | |||||
| "compilerOptions": { | |||||
| "outDir": "./out-tsc/spec", | |||||
| "types": [ | |||||
| "jasmine" | |||||
| ] | |||||
| }, | |||||
| "include": [ | |||||
| "src/**/*.spec.ts", | |||||
| "src/**/*.d.ts" | |||||
| ] | |||||
| } | |||||
| @@ -0,0 +1,6 @@ | |||||
| { | |||||
| "name": "matsen-tool-fe", | |||||
| "lockfileVersion": 3, | |||||
| "requires": true, | |||||
| "packages": {} | |||||
| } | |||||