mirror of
https://github.com/docker/awesome-compose.git
synced 2025-04-26 02:38:07 +02:00
add mongodb-angular-expressjs-nodejs docker sample
Signed-off-by: Sohaib Manah <souhaibemanah@gmail.com>
This commit is contained in:
parent
e6b1d2755f
commit
c5c2efb203
62 changed files with 12812 additions and 0 deletions
160
mongodb-angular-expressjs-nodejs/README.md
Normal file
160
mongodb-angular-expressjs-nodejs/README.md
Normal file
|
@ -0,0 +1,160 @@
|
|||
## Compose sample application
|
||||
|
||||
## Node.js application with Angular and Nginx proxy and Mongodb database
|
||||
|
||||
Project structure:
|
||||
```
|
||||
|
||||
mongodb-angular-expressjs-nodejs/
|
||||
├── backend
|
||||
│ ├── db
|
||||
│ │ └── mongodb.js
|
||||
│ ├── Dockerfile
|
||||
│ ├── package.json
|
||||
│ ├── package-lock.json
|
||||
│ └── server.js
|
||||
├── compose.yaml
|
||||
├── frontend
|
||||
│ ├── angular.json
|
||||
│ ├── Dockerfile
|
||||
│ ├── karma.conf.js
|
||||
│ ├── node_modules
|
||||
│ ├── output.png
|
||||
│ ├── package.json
|
||||
│ ├── package-lock.json
|
||||
│ ├── README.md
|
||||
│ ├── src
|
||||
│ │ ├── app
|
||||
│ │ │ ├── app.component.css
|
||||
│ │ │ ├── app.component.html
|
||||
│ │ │ ├── app.component.spec.ts
|
||||
│ │ │ ├── app.component.ts
|
||||
│ │ │ ├── app.module.ts
|
||||
│ │ │ └── app-routing.module.ts
|
||||
│ │ ├── assets
|
||||
│ │ ├── environments
|
||||
│ │ │ ├── environment.prod.ts
|
||||
│ │ │ └── environment.ts
|
||||
│ │ ├── favicon.ico
|
||||
│ │ ├── index.html
|
||||
│ │ ├── main.ts
|
||||
│ │ ├── polyfills.ts
|
||||
│ │ ├── styles.css
|
||||
│ │ └── test.ts
|
||||
│ ├── tsconfig.app.json
|
||||
│ ├── tsconfig.json
|
||||
│ └── tsconfig.spec.json
|
||||
├── nginx
|
||||
│ ├── Dockerfile
|
||||
│ └── nginx.conf
|
||||
└── README.md
|
||||
|
||||
9 directories, 33 files
|
||||
|
||||
|
||||
```
|
||||
[_compose.yaml_](compose.yaml)
|
||||
```
|
||||
services:
|
||||
backend:
|
||||
restart: on-failure
|
||||
build: ./backend
|
||||
volumes:
|
||||
- ./backend:/usr/src/app
|
||||
hostname: backend
|
||||
container_name: backend
|
||||
mongo:
|
||||
restart: on-failure
|
||||
image: mongo
|
||||
ports:
|
||||
- '27017:27017'
|
||||
volumes:
|
||||
- /data/db
|
||||
hostname: mongo
|
||||
container_name: mongo
|
||||
nginx:
|
||||
build: ./nginx
|
||||
ports:
|
||||
- '80:80'
|
||||
depends_on:
|
||||
- backend
|
||||
- mongo
|
||||
hostname: nginx
|
||||
container_name: nginx
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: frontend
|
||||
target: builder
|
||||
ports:
|
||||
- 4200:4200
|
||||
volumes:
|
||||
- ./frontend:/project
|
||||
- /project/node_modules
|
||||
hostname: frontend
|
||||
container_name: frontend
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
The compose file defines an application with tree services `nginx`, `front` and `backend`.
|
||||
When deploying the application, docker compose maps port 4200 of the nginx service container to port 4200 of the host as specified in the file.
|
||||
also you can access to angular app on port 4200
|
||||
and the mongoDB on port 27017
|
||||
|
||||
|
||||
## Deploy with docker compose
|
||||
|
||||
```shell
|
||||
docker compose up -d
|
||||
[+] Running 4/0
|
||||
⠿ Container backend Created 0.0s
|
||||
⠿ Container frontend Created 0.0s
|
||||
⠿ Container mongo Created 0.0s
|
||||
⠿ Container nginx Created
|
||||
|
||||
```
|
||||
|
||||
## Expected result
|
||||
|
||||
Listing containers must show three containers running and the port mapping as below:
|
||||
|
||||
|
||||
```
|
||||
docker-compose ps
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
f7e46df7806f mongodb-angular-expressjs-nodejs-nginx "/docker-entrypoint.…" 5 minutes ago Up 16 seconds 0.0.0.0:80->80/tcp nginx
|
||||
7cd374f14cba mongodb-angular-expressjs-nodejs-backend "docker-entrypoint.s…" 5 minutes ago Up 17 seconds 5000/tcp backend
|
||||
526c12817555 mongodb-angular-expressjs-nodejs-frontend "docker-entrypoint.s…" 5 minutes ago Up 17 seconds 0.0.0.0:4200->4200/tcp frontend
|
||||
1923a93dae8d mongo "docker-entrypoint.s…" 5 minutes ago Up 17 seconds 0.0.0.0:27017->27017/tcp
|
||||
```
|
||||
|
||||
## Testing the app
|
||||
|
||||
1. After the application starts, navigate to
|
||||
`http://localhost:4200`
|
||||
|
||||
|
||||
2. Check the mongoDB connection with mongodb compass or mongo shell
|
||||
|
||||
```
|
||||
mongosh "mongodb://localhost:27017"
|
||||
```
|
||||
|
||||
3. Check the backend connection with postman or curl
|
||||
|
||||
```
|
||||
curl http://localhost
|
||||
```
|
||||
|
||||
|
||||
## Stop and remove the containers
|
||||
|
||||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
|
1
mongodb-angular-expressjs-nodejs/backend/.env.example
Normal file
1
mongodb-angular-expressjs-nodejs/backend/.env.example
Normal file
|
@ -0,0 +1 @@
|
|||
MONGODB_URI=mongodb://mongo:27017
|
2
mongodb-angular-expressjs-nodejs/backend/.gitignore
vendored
Normal file
2
mongodb-angular-expressjs-nodejs/backend/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules
|
||||
.env
|
13
mongodb-angular-expressjs-nodejs/backend/Dockerfile
Normal file
13
mongodb-angular-expressjs-nodejs/backend/Dockerfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
FROM node:19-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["npm","start"]
|
29
mongodb-angular-expressjs-nodejs/backend/db/mongodb.js
Normal file
29
mongodb-angular-expressjs-nodejs/backend/db/mongodb.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { MongoClient, ServerApiVersion } from "mongodb";
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
|
||||
const client = new MongoClient(
|
||||
process.env.MONGODB_URI || "mongodb://mongo:27017",
|
||||
{
|
||||
serverApi: {
|
||||
version: ServerApiVersion.v1,
|
||||
strict: true,
|
||||
deprecationErrors: true,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
try {
|
||||
// Connect the client to the server (optional starting in v4.7)
|
||||
await client.connect();
|
||||
|
||||
// Send a ping to confirm a successful connection
|
||||
await client.db("admin").command({ ping: 1 });
|
||||
console.log("Pinged your deployment. You successfully connected to MongoDB!");
|
||||
} finally {
|
||||
// Ensures that the client will close when you finish/error
|
||||
await client.close();
|
||||
}
|
||||
|
||||
export default client.connect();
|
1117
mongodb-angular-expressjs-nodejs/backend/package-lock.json
generated
Normal file
1117
mongodb-angular-expressjs-nodejs/backend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
19
mongodb-angular-expressjs-nodejs/backend/package.json
Normal file
19
mongodb-angular-expressjs-nodejs/backend/package.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"description": "Running Node.js and Express.js on Docker",
|
||||
"main": "server.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "nodemon server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"express": "^4.18.2",
|
||||
"mongodb": "^5.1.0",
|
||||
"nodemon": "^2.0.22"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
14
mongodb-angular-expressjs-nodejs/backend/server.js
Normal file
14
mongodb-angular-expressjs-nodejs/backend/server.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import express from "express";
|
||||
import client from "./db/mongodb.js";
|
||||
const app = express();
|
||||
import cors from "cors";
|
||||
|
||||
app.use(cors("http://localhost:4200"));
|
||||
|
||||
app.get("/", function (req, res) {
|
||||
res.status(200).json({ message: "Hello World" });
|
||||
});
|
||||
|
||||
app.listen(5000, function () {
|
||||
console.log("Web application is listening on port 5000");
|
||||
});
|
41
mongodb-angular-expressjs-nodejs/compose.yaml
Normal file
41
mongodb-angular-expressjs-nodejs/compose.yaml
Normal file
|
@ -0,0 +1,41 @@
|
|||
services:
|
||||
backend:
|
||||
restart: on-failure
|
||||
build: ./backend
|
||||
volumes:
|
||||
- ./backend:/usr/src/app
|
||||
hostname: backend
|
||||
container_name: backend
|
||||
mongo:
|
||||
restart: on-failure
|
||||
image: mongo
|
||||
ports:
|
||||
- '27017:27017'
|
||||
volumes:
|
||||
- /data/db
|
||||
hostname: mongo
|
||||
container_name: mongo
|
||||
nginx:
|
||||
build: ./nginx
|
||||
ports:
|
||||
- '80:80'
|
||||
depends_on:
|
||||
- backend
|
||||
- mongo
|
||||
hostname: nginx
|
||||
container_name: nginx
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: frontend
|
||||
target: builder
|
||||
ports:
|
||||
- 4200:4200
|
||||
volumes:
|
||||
- ./frontend:/project
|
||||
- /project/node_modules
|
||||
hostname: frontend
|
||||
container_name: frontend
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { sample } from './sample';\nimport { interval } from '../observable/interval';\nexport function sampleTime(period, scheduler = asyncScheduler) {\n return sample(interval(period, scheduler));\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/sampleTime.js"],"names":["asyncScheduler","sample","interval","sampleTime","period","scheduler"],"mappings":"AAAA,SAASA,cAAT,QAA+B,oBAA/B;AACA,SAASC,MAAT,QAAuB,UAAvB;AACA,SAASC,QAAT,QAAyB,wBAAzB;AACA,OAAO,SAASC,UAAT,CAAoBC,MAApB,EAA4BC,SAAS,GAAGL,cAAxC,EAAwD;AAC3D,SAAOC,MAAM,CAACC,QAAQ,CAACE,MAAD,EAASC,SAAT,CAAT,CAAb;AACH","sourcesContent":["import { asyncScheduler } from '../scheduler/async';\nimport { sample } from './sample';\nimport { interval } from '../observable/interval';\nexport function sampleTime(period, scheduler = asyncScheduler) {\n return sample(interval(period, scheduler));\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { Observable } from '../Observable';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleAsyncIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n\n return new Observable(subscriber => {\n executeSchedule(subscriber, scheduler, () => {\n const iterator = input[Symbol.asyncIterator]();\n executeSchedule(subscriber, scheduler, () => {\n iterator.next().then(result => {\n if (result.done) {\n subscriber.complete();\n } else {\n subscriber.next(result.value);\n }\n });\n }, 0, true);\n });\n });\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/scheduled/scheduleAsyncIterable.js"],"names":["Observable","executeSchedule","scheduleAsyncIterable","input","scheduler","Error","subscriber","iterator","Symbol","asyncIterator","next","then","result","done","complete","value"],"mappings":"AAAA,SAASA,UAAT,QAA2B,eAA3B;AACA,SAASC,eAAT,QAAgC,yBAAhC;AACA,OAAO,SAASC,qBAAT,CAA+BC,KAA/B,EAAsCC,SAAtC,EAAiD;AACpD,MAAI,CAACD,KAAL,EAAY;AACR,UAAM,IAAIE,KAAJ,CAAU,yBAAV,CAAN;AACH;;AACD,SAAO,IAAIL,UAAJ,CAAgBM,UAAD,IAAgB;AAClCL,IAAAA,eAAe,CAACK,UAAD,EAAaF,SAAb,EAAwB,MAAM;AACzC,YAAMG,QAAQ,GAAGJ,KAAK,CAACK,MAAM,CAACC,aAAR,CAAL,EAAjB;AACAR,MAAAA,eAAe,CAACK,UAAD,EAAaF,SAAb,EAAwB,MAAM;AACzCG,QAAAA,QAAQ,CAACG,IAAT,GAAgBC,IAAhB,CAAsBC,MAAD,IAAY;AAC7B,cAAIA,MAAM,CAACC,IAAX,EAAiB;AACbP,YAAAA,UAAU,CAACQ,QAAX;AACH,WAFD,MAGK;AACDR,YAAAA,UAAU,CAACI,IAAX,CAAgBE,MAAM,CAACG,KAAvB;AACH;AACJ,SAPD;AAQH,OATc,EASZ,CATY,EAST,IATS,CAAf;AAUH,KAZc,CAAf;AAaH,GAdM,CAAP;AAeH","sourcesContent":["import { Observable } from '../Observable';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleAsyncIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n return new Observable((subscriber) => {\n executeSchedule(subscriber, scheduler, () => {\n const iterator = input[Symbol.asyncIterator]();\n executeSchedule(subscriber, scheduler, () => {\n iterator.next().then((result) => {\n if (result.done) {\n subscriber.complete();\n }\n else {\n subscriber.next(result.value);\n }\n });\n }, 0, true);\n });\n });\n}\n"]},"metadata":{},"sourceType":"module"}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { async } from '../scheduler/async';\nimport { scan } from './scan';\nimport { defer } from '../observable/defer';\nimport { map } from './map';\nexport function timeInterval(scheduler = async) {\n return source => defer(() => {\n return source.pipe(scan(({\n current\n }, value) => ({\n value,\n current: scheduler.now(),\n last: current\n }), {\n current: scheduler.now(),\n value: undefined,\n last: undefined\n }), map(({\n current,\n last,\n value\n }) => new TimeInterval(value, current - last)));\n });\n}\nexport class TimeInterval {\n constructor(value, interval) {\n this.value = value;\n this.interval = interval;\n }\n\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/timeInterval.js"],"names":["async","scan","defer","map","timeInterval","scheduler","source","pipe","current","value","now","last","undefined","TimeInterval","constructor","interval"],"mappings":"AAAA,SAASA,KAAT,QAAsB,oBAAtB;AACA,SAASC,IAAT,QAAqB,QAArB;AACA,SAASC,KAAT,QAAsB,qBAAtB;AACA,SAASC,GAAT,QAAoB,OAApB;AACA,OAAO,SAASC,YAAT,CAAsBC,SAAS,GAAGL,KAAlC,EAAyC;AAC5C,SAAQM,MAAD,IAAYJ,KAAK,CAAC,MAAM;AAC3B,WAAOI,MAAM,CAACC,IAAP,CAAYN,IAAI,CAAC,CAAC;AAAEO,MAAAA;AAAF,KAAD,EAAcC,KAAd,MAAyB;AAAEA,MAAAA,KAAF;AAASD,MAAAA,OAAO,EAAEH,SAAS,CAACK,GAAV,EAAlB;AAAmCC,MAAAA,IAAI,EAAEH;AAAzC,KAAzB,CAAD,EAA+E;AAClGA,MAAAA,OAAO,EAAEH,SAAS,CAACK,GAAV,EADyF;AAElGD,MAAAA,KAAK,EAAEG,SAF2F;AAGlGD,MAAAA,IAAI,EAAEC;AAH4F,KAA/E,CAAhB,EAIHT,GAAG,CAAC,CAAC;AAAEK,MAAAA,OAAF;AAAWG,MAAAA,IAAX;AAAiBF,MAAAA;AAAjB,KAAD,KAA8B,IAAII,YAAJ,CAAiBJ,KAAjB,EAAwBD,OAAO,GAAGG,IAAlC,CAA/B,CAJA,CAAP;AAKH,GANuB,CAAxB;AAOH;AACD,OAAO,MAAME,YAAN,CAAmB;AACtBC,EAAAA,WAAW,CAACL,KAAD,EAAQM,QAAR,EAAkB;AACzB,SAAKN,KAAL,GAAaA,KAAb;AACA,SAAKM,QAAL,GAAgBA,QAAhB;AACH;;AAJqB","sourcesContent":["import { async } from '../scheduler/async';\nimport { scan } from './scan';\nimport { defer } from '../observable/defer';\nimport { map } from './map';\nexport function timeInterval(scheduler = async) {\n return (source) => defer(() => {\n return source.pipe(scan(({ current }, value) => ({ value, current: scheduler.now(), last: current }), {\n current: scheduler.now(),\n value: undefined,\n last: undefined,\n }), map(({ current, last, value }) => new TimeInterval(value, current - last)));\n });\n}\nexport class TimeInterval {\n constructor(value, interval) {\n this.value = value;\n this.interval = interval;\n }\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { defaultThrottleConfig, throttle } from './throttle';\nimport { timer } from '../observable/timer';\nexport function throttleTime(duration, scheduler = asyncScheduler, config = defaultThrottleConfig) {\n const duration$ = timer(duration, scheduler);\n return throttle(() => duration$, config);\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/throttleTime.js"],"names":["asyncScheduler","defaultThrottleConfig","throttle","timer","throttleTime","duration","scheduler","config","duration$"],"mappings":"AAAA,SAASA,cAAT,QAA+B,oBAA/B;AACA,SAASC,qBAAT,EAAgCC,QAAhC,QAAgD,YAAhD;AACA,SAASC,KAAT,QAAsB,qBAAtB;AACA,OAAO,SAASC,YAAT,CAAsBC,QAAtB,EAAgCC,SAAS,GAAGN,cAA5C,EAA4DO,MAAM,GAAGN,qBAArE,EAA4F;AAC/F,QAAMO,SAAS,GAAGL,KAAK,CAACE,QAAD,EAAWC,SAAX,CAAvB;AACA,SAAOJ,QAAQ,CAAC,MAAMM,SAAP,EAAkBD,MAAlB,CAAf;AACH","sourcesContent":["import { asyncScheduler } from '../scheduler/async';\nimport { defaultThrottleConfig, throttle } from './throttle';\nimport { timer } from '../observable/timer';\nexport function throttleTime(duration, scheduler = asyncScheduler, config = defaultThrottleConfig) {\n const duration$ = timer(duration, scheduler);\n return throttle(() => duration$, config);\n}\n"]},"metadata":{},"sourceType":"module"}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function debounceTime(dueTime, scheduler = asyncScheduler) {\n return operate((source, subscriber) => {\n let activeTask = null;\n let lastValue = null;\n let lastTime = null;\n\n const emit = () => {\n if (activeTask) {\n activeTask.unsubscribe();\n activeTask = null;\n const value = lastValue;\n lastValue = null;\n subscriber.next(value);\n }\n };\n\n function emitWhenIdle() {\n const targetTime = lastTime + dueTime;\n const now = scheduler.now();\n\n if (now < targetTime) {\n activeTask = this.schedule(undefined, targetTime - now);\n subscriber.add(activeTask);\n return;\n }\n\n emit();\n }\n\n source.subscribe(new OperatorSubscriber(subscriber, value => {\n lastValue = value;\n lastTime = scheduler.now();\n\n if (!activeTask) {\n activeTask = scheduler.schedule(emitWhenIdle, dueTime);\n subscriber.add(activeTask);\n }\n }, () => {\n emit();\n subscriber.complete();\n }, undefined, () => {\n lastValue = activeTask = null;\n }));\n });\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/debounceTime.js"],"names":["asyncScheduler","operate","OperatorSubscriber","debounceTime","dueTime","scheduler","source","subscriber","activeTask","lastValue","lastTime","emit","unsubscribe","value","next","emitWhenIdle","targetTime","now","schedule","undefined","add","subscribe","complete"],"mappings":"AAAA,SAASA,cAAT,QAA+B,oBAA/B;AACA,SAASC,OAAT,QAAwB,cAAxB;AACA,SAASC,kBAAT,QAAmC,sBAAnC;AACA,OAAO,SAASC,YAAT,CAAsBC,OAAtB,EAA+BC,SAAS,GAAGL,cAA3C,EAA2D;AAC9D,SAAOC,OAAO,CAAC,CAACK,MAAD,EAASC,UAAT,KAAwB;AACnC,QAAIC,UAAU,GAAG,IAAjB;AACA,QAAIC,SAAS,GAAG,IAAhB;AACA,QAAIC,QAAQ,GAAG,IAAf;;AACA,UAAMC,IAAI,GAAG,MAAM;AACf,UAAIH,UAAJ,EAAgB;AACZA,QAAAA,UAAU,CAACI,WAAX;AACAJ,QAAAA,UAAU,GAAG,IAAb;AACA,cAAMK,KAAK,GAAGJ,SAAd;AACAA,QAAAA,SAAS,GAAG,IAAZ;AACAF,QAAAA,UAAU,CAACO,IAAX,CAAgBD,KAAhB;AACH;AACJ,KARD;;AASA,aAASE,YAAT,GAAwB;AACpB,YAAMC,UAAU,GAAGN,QAAQ,GAAGN,OAA9B;AACA,YAAMa,GAAG,GAAGZ,SAAS,CAACY,GAAV,EAAZ;;AACA,UAAIA,GAAG,GAAGD,UAAV,EAAsB;AAClBR,QAAAA,UAAU,GAAG,KAAKU,QAAL,CAAcC,SAAd,EAAyBH,UAAU,GAAGC,GAAtC,CAAb;AACAV,QAAAA,UAAU,CAACa,GAAX,CAAeZ,UAAf;AACA;AACH;;AACDG,MAAAA,IAAI;AACP;;AACDL,IAAAA,MAAM,CAACe,SAAP,CAAiB,IAAInB,kBAAJ,CAAuBK,UAAvB,EAAoCM,KAAD,IAAW;AAC3DJ,MAAAA,SAAS,GAAGI,KAAZ;AACAH,MAAAA,QAAQ,GAAGL,SAAS,CAACY,GAAV,EAAX;;AACA,UAAI,CAACT,UAAL,EAAiB;AACbA,QAAAA,UAAU,GAAGH,SAAS,CAACa,QAAV,CAAmBH,YAAnB,EAAiCX,OAAjC,CAAb;AACAG,QAAAA,UAAU,CAACa,GAAX,CAAeZ,UAAf;AACH;AACJ,KAPgB,EAOd,MAAM;AACLG,MAAAA,IAAI;AACJJ,MAAAA,UAAU,CAACe,QAAX;AACH,KAVgB,EAUdH,SAVc,EAUH,MAAM;AAChBV,MAAAA,SAAS,GAAGD,UAAU,GAAG,IAAzB;AACH,KAZgB,CAAjB;AAaH,GApCa,CAAd;AAqCH","sourcesContent":["import { asyncScheduler } from '../scheduler/async';\nimport { operate } from '../util/lift';\nimport { OperatorSubscriber } from './OperatorSubscriber';\nexport function debounceTime(dueTime, scheduler = asyncScheduler) {\n return operate((source, subscriber) => {\n let activeTask = null;\n let lastValue = null;\n let lastTime = null;\n const emit = () => {\n if (activeTask) {\n activeTask.unsubscribe();\n activeTask = null;\n const value = lastValue;\n lastValue = null;\n subscriber.next(value);\n }\n };\n function emitWhenIdle() {\n const targetTime = lastTime + dueTime;\n const now = scheduler.now();\n if (now < targetTime) {\n activeTask = this.schedule(undefined, targetTime - now);\n subscriber.add(activeTask);\n return;\n }\n emit();\n }\n source.subscribe(new OperatorSubscriber(subscriber, (value) => {\n lastValue = value;\n lastTime = scheduler.now();\n if (!activeTask) {\n activeTask = scheduler.schedule(emitWhenIdle, dueTime);\n subscriber.add(activeTask);\n }\n }, () => {\n emit();\n subscriber.complete();\n }, undefined, () => {\n lastValue = activeTask = null;\n }));\n });\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { Observable } from '../Observable';\nimport { async as asyncScheduler } from '../scheduler/async';\nimport { isScheduler } from '../util/isScheduler';\nimport { isValidDate } from '../util/isDate';\nexport function timer(dueTime = 0, intervalOrScheduler, scheduler = asyncScheduler) {\n let intervalDuration = -1;\n\n if (intervalOrScheduler != null) {\n if (isScheduler(intervalOrScheduler)) {\n scheduler = intervalOrScheduler;\n } else {\n intervalDuration = intervalOrScheduler;\n }\n }\n\n return new Observable(subscriber => {\n let due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime;\n\n if (due < 0) {\n due = 0;\n }\n\n let n = 0;\n return scheduler.schedule(function () {\n if (!subscriber.closed) {\n subscriber.next(n++);\n\n if (0 <= intervalDuration) {\n this.schedule(undefined, intervalDuration);\n } else {\n subscriber.complete();\n }\n }\n }, due);\n });\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/observable/timer.js"],"names":["Observable","async","asyncScheduler","isScheduler","isValidDate","timer","dueTime","intervalOrScheduler","scheduler","intervalDuration","subscriber","due","now","n","schedule","closed","next","undefined","complete"],"mappings":"AAAA,SAASA,UAAT,QAA2B,eAA3B;AACA,SAASC,KAAK,IAAIC,cAAlB,QAAwC,oBAAxC;AACA,SAASC,WAAT,QAA4B,qBAA5B;AACA,SAASC,WAAT,QAA4B,gBAA5B;AACA,OAAO,SAASC,KAAT,CAAeC,OAAO,GAAG,CAAzB,EAA4BC,mBAA5B,EAAiDC,SAAS,GAAGN,cAA7D,EAA6E;AAChF,MAAIO,gBAAgB,GAAG,CAAC,CAAxB;;AACA,MAAIF,mBAAmB,IAAI,IAA3B,EAAiC;AAC7B,QAAIJ,WAAW,CAACI,mBAAD,CAAf,EAAsC;AAClCC,MAAAA,SAAS,GAAGD,mBAAZ;AACH,KAFD,MAGK;AACDE,MAAAA,gBAAgB,GAAGF,mBAAnB;AACH;AACJ;;AACD,SAAO,IAAIP,UAAJ,CAAgBU,UAAD,IAAgB;AAClC,QAAIC,GAAG,GAAGP,WAAW,CAACE,OAAD,CAAX,GAAuB,CAACA,OAAD,GAAWE,SAAS,CAACI,GAAV,EAAlC,GAAoDN,OAA9D;;AACA,QAAIK,GAAG,GAAG,CAAV,EAAa;AACTA,MAAAA,GAAG,GAAG,CAAN;AACH;;AACD,QAAIE,CAAC,GAAG,CAAR;AACA,WAAOL,SAAS,CAACM,QAAV,CAAmB,YAAY;AAClC,UAAI,CAACJ,UAAU,CAACK,MAAhB,EAAwB;AACpBL,QAAAA,UAAU,CAACM,IAAX,CAAgBH,CAAC,EAAjB;;AACA,YAAI,KAAKJ,gBAAT,EAA2B;AACvB,eAAKK,QAAL,CAAcG,SAAd,EAAyBR,gBAAzB;AACH,SAFD,MAGK;AACDC,UAAAA,UAAU,CAACQ,QAAX;AACH;AACJ;AACJ,KAVM,EAUJP,GAVI,CAAP;AAWH,GAjBM,CAAP;AAkBH","sourcesContent":["import { Observable } from '../Observable';\nimport { async as asyncScheduler } from '../scheduler/async';\nimport { isScheduler } from '../util/isScheduler';\nimport { isValidDate } from '../util/isDate';\nexport function timer(dueTime = 0, intervalOrScheduler, scheduler = asyncScheduler) {\n let intervalDuration = -1;\n if (intervalOrScheduler != null) {\n if (isScheduler(intervalOrScheduler)) {\n scheduler = intervalOrScheduler;\n }\n else {\n intervalDuration = intervalOrScheduler;\n }\n }\n return new Observable((subscriber) => {\n let due = isValidDate(dueTime) ? +dueTime - scheduler.now() : dueTime;\n if (due < 0) {\n due = 0;\n }\n let n = 0;\n return scheduler.schedule(function () {\n if (!subscriber.closed) {\n subscriber.next(n++);\n if (0 <= intervalDuration) {\n this.schedule(undefined, intervalDuration);\n }\n else {\n subscriber.complete();\n }\n }\n }, due);\n });\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { async } from '../scheduler/async';\nimport { isValidDate } from '../util/isDate';\nimport { timeout } from './timeout';\nexport function timeoutWith(due, withObservable, scheduler) {\n let first;\n let each;\n\n let _with;\n\n scheduler = scheduler !== null && scheduler !== void 0 ? scheduler : async;\n\n if (isValidDate(due)) {\n first = due;\n } else if (typeof due === 'number') {\n each = due;\n }\n\n if (withObservable) {\n _with = () => withObservable;\n } else {\n throw new TypeError('No observable provided to switch to');\n }\n\n if (first == null && each == null) {\n throw new TypeError('No timeout provided.');\n }\n\n return timeout({\n first,\n each,\n scheduler,\n with: _with\n });\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/timeoutWith.js"],"names":["async","isValidDate","timeout","timeoutWith","due","withObservable","scheduler","first","each","_with","TypeError","with"],"mappings":"AAAA,SAASA,KAAT,QAAsB,oBAAtB;AACA,SAASC,WAAT,QAA4B,gBAA5B;AACA,SAASC,OAAT,QAAwB,WAAxB;AACA,OAAO,SAASC,WAAT,CAAqBC,GAArB,EAA0BC,cAA1B,EAA0CC,SAA1C,EAAqD;AACxD,MAAIC,KAAJ;AACA,MAAIC,IAAJ;;AACA,MAAIC,KAAJ;;AACAH,EAAAA,SAAS,GAAGA,SAAS,KAAK,IAAd,IAAsBA,SAAS,KAAK,KAAK,CAAzC,GAA6CA,SAA7C,GAAyDN,KAArE;;AACA,MAAIC,WAAW,CAACG,GAAD,CAAf,EAAsB;AAClBG,IAAAA,KAAK,GAAGH,GAAR;AACH,GAFD,MAGK,IAAI,OAAOA,GAAP,KAAe,QAAnB,EAA6B;AAC9BI,IAAAA,IAAI,GAAGJ,GAAP;AACH;;AACD,MAAIC,cAAJ,EAAoB;AAChBI,IAAAA,KAAK,GAAG,MAAMJ,cAAd;AACH,GAFD,MAGK;AACD,UAAM,IAAIK,SAAJ,CAAc,qCAAd,CAAN;AACH;;AACD,MAAIH,KAAK,IAAI,IAAT,IAAiBC,IAAI,IAAI,IAA7B,EAAmC;AAC/B,UAAM,IAAIE,SAAJ,CAAc,sBAAd,CAAN;AACH;;AACD,SAAOR,OAAO,CAAC;AACXK,IAAAA,KADW;AAEXC,IAAAA,IAFW;AAGXF,IAAAA,SAHW;AAIXK,IAAAA,IAAI,EAAEF;AAJK,GAAD,CAAd;AAMH","sourcesContent":["import { async } from '../scheduler/async';\nimport { isValidDate } from '../util/isDate';\nimport { timeout } from './timeout';\nexport function timeoutWith(due, withObservable, scheduler) {\n let first;\n let each;\n let _with;\n scheduler = scheduler !== null && scheduler !== void 0 ? scheduler : async;\n if (isValidDate(due)) {\n first = due;\n }\n else if (typeof due === 'number') {\n each = due;\n }\n if (withObservable) {\n _with = () => withObservable;\n }\n else {\n throw new TypeError('No observable provided to switch to');\n }\n if (first == null && each == null) {\n throw new TypeError('No timeout provided.');\n }\n return timeout({\n first,\n each,\n scheduler,\n with: _with,\n });\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { async } from '../scheduler/async';\nimport { audit } from './audit';\nimport { timer } from '../observable/timer';\nexport function auditTime(duration, scheduler = async) {\n return audit(() => timer(duration, scheduler));\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/auditTime.js"],"names":["async","audit","timer","auditTime","duration","scheduler"],"mappings":"AAAA,SAASA,KAAT,QAAsB,oBAAtB;AACA,SAASC,KAAT,QAAsB,SAAtB;AACA,SAASC,KAAT,QAAsB,qBAAtB;AACA,OAAO,SAASC,SAAT,CAAmBC,QAAnB,EAA6BC,SAAS,GAAGL,KAAzC,EAAgD;AACnD,SAAOC,KAAK,CAAC,MAAMC,KAAK,CAACE,QAAD,EAAWC,SAAX,CAAZ,CAAZ;AACH","sourcesContent":["import { async } from '../scheduler/async';\nimport { audit } from './audit';\nimport { timer } from '../observable/timer';\nexport function auditTime(duration, scheduler = async) {\n return audit(() => timer(duration, scheduler));\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { isFunction } from './isFunction';\nexport function isAsyncIterable(obj) {\n return Symbol.asyncIterator && isFunction(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/util/isAsyncIterable.js"],"names":["isFunction","isAsyncIterable","obj","Symbol","asyncIterator"],"mappings":"AAAA,SAASA,UAAT,QAA2B,cAA3B;AACA,OAAO,SAASC,eAAT,CAAyBC,GAAzB,EAA8B;AACjC,SAAOC,MAAM,CAACC,aAAP,IAAwBJ,UAAU,CAACE,GAAG,KAAK,IAAR,IAAgBA,GAAG,KAAK,KAAK,CAA7B,GAAiC,KAAK,CAAtC,GAA0CA,GAAG,CAACC,MAAM,CAACC,aAAR,CAA9C,CAAzC;AACH","sourcesContent":["import { isFunction } from './isFunction';\nexport function isAsyncIterable(obj) {\n return Symbol.asyncIterator && isFunction(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\nexport const async = asyncScheduler;","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/scheduler/async.js"],"names":["AsyncAction","AsyncScheduler","asyncScheduler","async"],"mappings":"AAAA,SAASA,WAAT,QAA4B,eAA5B;AACA,SAASC,cAAT,QAA+B,kBAA/B;AACA,OAAO,MAAMC,cAAc,GAAG,IAAID,cAAJ,CAAmBD,WAAnB,CAAvB;AACP,OAAO,MAAMG,KAAK,GAAGD,cAAd","sourcesContent":["import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\nexport const async = asyncScheduler;\n"]},"metadata":{},"sourceType":"module"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { __asyncGenerator, __await } from \"tslib\";\nimport { isFunction } from './isFunction';\nexport function readableStreamLikeToAsyncGenerator(readableStream) {\n return __asyncGenerator(this, arguments, function* readableStreamLikeToAsyncGenerator_1() {\n const reader = readableStream.getReader();\n\n try {\n while (true) {\n const {\n value,\n done\n } = yield __await(reader.read());\n\n if (done) {\n return yield __await(void 0);\n }\n\n yield yield __await(value);\n }\n } finally {\n reader.releaseLock();\n }\n });\n}\nexport function isReadableStreamLike(obj) {\n return isFunction(obj === null || obj === void 0 ? void 0 : obj.getReader);\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/util/isReadableStreamLike.js"],"names":["__asyncGenerator","__await","isFunction","readableStreamLikeToAsyncGenerator","readableStream","arguments","readableStreamLikeToAsyncGenerator_1","reader","getReader","value","done","read","releaseLock","isReadableStreamLike","obj"],"mappings":"AAAA,SAASA,gBAAT,EAA2BC,OAA3B,QAA0C,OAA1C;AACA,SAASC,UAAT,QAA2B,cAA3B;AACA,OAAO,SAASC,kCAAT,CAA4CC,cAA5C,EAA4D;AAC/D,SAAOJ,gBAAgB,CAAC,IAAD,EAAOK,SAAP,EAAkB,UAAUC,oCAAV,GAAiD;AACtF,UAAMC,MAAM,GAAGH,cAAc,CAACI,SAAf,EAAf;;AACA,QAAI;AACA,aAAO,IAAP,EAAa;AACT,cAAM;AAAEC,UAAAA,KAAF;AAASC,UAAAA;AAAT,YAAkB,MAAMT,OAAO,CAACM,MAAM,CAACI,IAAP,EAAD,CAArC;;AACA,YAAID,IAAJ,EAAU;AACN,iBAAO,MAAMT,OAAO,CAAC,KAAK,CAAN,CAApB;AACH;;AACD,cAAM,MAAMA,OAAO,CAACQ,KAAD,CAAnB;AACH;AACJ,KARD,SASQ;AACJF,MAAAA,MAAM,CAACK,WAAP;AACH;AACJ,GAdsB,CAAvB;AAeH;AACD,OAAO,SAASC,oBAAT,CAA8BC,GAA9B,EAAmC;AACtC,SAAOZ,UAAU,CAACY,GAAG,KAAK,IAAR,IAAgBA,GAAG,KAAK,KAAK,CAA7B,GAAiC,KAAK,CAAtC,GAA0CA,GAAG,CAACN,SAA/C,CAAjB;AACH","sourcesContent":["import { __asyncGenerator, __await } from \"tslib\";\nimport { isFunction } from './isFunction';\nexport function readableStreamLikeToAsyncGenerator(readableStream) {\n return __asyncGenerator(this, arguments, function* readableStreamLikeToAsyncGenerator_1() {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = yield __await(reader.read());\n if (done) {\n return yield __await(void 0);\n }\n yield yield __await(value);\n }\n }\n finally {\n reader.releaseLock();\n }\n });\n}\nexport function isReadableStreamLike(obj) {\n return isFunction(obj === null || obj === void 0 ? void 0 : obj.getReader);\n}\n"]},"metadata":{},"sourceType":"module"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { timer } from './timer';\nexport function interval(period = 0, scheduler = asyncScheduler) {\n if (period < 0) {\n period = 0;\n }\n\n return timer(period, period, scheduler);\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/observable/interval.js"],"names":["asyncScheduler","timer","interval","period","scheduler"],"mappings":"AAAA,SAASA,cAAT,QAA+B,oBAA/B;AACA,SAASC,KAAT,QAAsB,SAAtB;AACA,OAAO,SAASC,QAAT,CAAkBC,MAAM,GAAG,CAA3B,EAA8BC,SAAS,GAAGJ,cAA1C,EAA0D;AAC7D,MAAIG,MAAM,GAAG,CAAb,EAAgB;AACZA,IAAAA,MAAM,GAAG,CAAT;AACH;;AACD,SAAOF,KAAK,CAACE,MAAD,EAASA,MAAT,EAAiBC,SAAjB,CAAZ;AACH","sourcesContent":["import { asyncScheduler } from '../scheduler/async';\nimport { timer } from './timer';\nexport function interval(period = 0, scheduler = asyncScheduler) {\n if (period < 0) {\n period = 0;\n }\n return timer(period, period, scheduler);\n}\n"]},"metadata":{},"sourceType":"module"}
|
|
@ -0,0 +1 @@
|
|||
{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { delayWhen } from './delayWhen';\nimport { timer } from '../observable/timer';\nexport function delay(due, scheduler = asyncScheduler) {\n const duration = timer(due, scheduler);\n return delayWhen(() => duration);\n}","map":{"version":3,"sources":["/project/node_modules/rxjs/dist/esm/internal/operators/delay.js"],"names":["asyncScheduler","delayWhen","timer","delay","due","scheduler","duration"],"mappings":"AAAA,SAASA,cAAT,QAA+B,oBAA/B;AACA,SAASC,SAAT,QAA0B,aAA1B;AACA,SAASC,KAAT,QAAsB,qBAAtB;AACA,OAAO,SAASC,KAAT,CAAeC,GAAf,EAAoBC,SAAS,GAAGL,cAAhC,EAAgD;AACnD,QAAMM,QAAQ,GAAGJ,KAAK,CAACE,GAAD,EAAMC,SAAN,CAAtB;AACA,SAAOJ,SAAS,CAAC,MAAMK,QAAP,CAAhB;AACH","sourcesContent":["import { asyncScheduler } from '../scheduler/async';\nimport { delayWhen } from './delayWhen';\nimport { timer } from '../observable/timer';\nexport function delay(due, scheduler = asyncScheduler) {\n const duration = timer(due, scheduler);\n return delayWhen(() => duration);\n}\n"]},"metadata":{},"sourceType":"module"}
|
31
mongodb-angular-expressjs-nodejs/frontend/Dockerfile
Normal file
31
mongodb-angular-expressjs-nodejs/frontend/Dockerfile
Normal file
|
@ -0,0 +1,31 @@
|
|||
# syntax=docker/dockerfile:1.4
|
||||
|
||||
FROM --platform=$BUILDPLATFORM node:17.0.1-bullseye-slim as builder
|
||||
|
||||
RUN mkdir /project
|
||||
WORKDIR /project
|
||||
|
||||
RUN npm install -g @angular/cli@13
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
CMD ["ng", "serve", "--host", "0.0.0.0"]
|
||||
|
||||
FROM builder as dev-envs
|
||||
|
||||
RUN <<EOF
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends git
|
||||
EOF
|
||||
|
||||
RUN <<EOF
|
||||
useradd -s /bin/bash -m vscode
|
||||
groupadd docker
|
||||
usermod -aG docker vscode
|
||||
EOF
|
||||
# install Docker tools (cli, buildx, compose)
|
||||
COPY --from=gloursdocker/docker / /
|
||||
|
||||
CMD ["ng", "serve", "--host", "0.0.0.0"]
|
27
mongodb-angular-expressjs-nodejs/frontend/README.md
Normal file
27
mongodb-angular-expressjs-nodejs/frontend/README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Angular
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.0.1.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app 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.
|
106
mongodb-angular-expressjs-nodejs/frontend/angular.json
Normal file
106
mongodb-angular-expressjs-nodejs/frontend/angular.json
Normal file
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"angular": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/angular",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": false,
|
||||
"optimization": false,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "angular:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "angular:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "angular"
|
||||
}
|
44
mongodb-angular-expressjs-nodejs/frontend/karma.conf.js
Normal file
44
mongodb-angular-expressjs-nodejs/frontend/karma.conf.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/angular'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
BIN
mongodb-angular-expressjs-nodejs/frontend/output.png
Normal file
BIN
mongodb-angular-expressjs-nodejs/frontend/output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 333 KiB |
10371
mongodb-angular-expressjs-nodejs/frontend/package-lock.json
generated
Normal file
10371
mongodb-angular-expressjs-nodejs/frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
39
mongodb-angular-expressjs-nodejs/frontend/package.json
Normal file
39
mongodb-angular-expressjs-nodejs/frontend/package.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "angular",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.0.0",
|
||||
"@angular/common": "~13.0.0",
|
||||
"@angular/compiler": "~13.0.0",
|
||||
"@angular/core": "~13.0.0",
|
||||
"@angular/forms": "~13.0.0",
|
||||
"@angular/platform-browser": "~13.0.0",
|
||||
"@angular/platform-browser-dynamic": "~13.0.0",
|
||||
"@angular/router": "~13.0.0",
|
||||
"rxjs": "~7.4.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^13.2.6",
|
||||
"@angular/cli": "~13.0.1",
|
||||
"@angular/compiler-cli": "~13.0.0",
|
||||
"@types/jasmine": "~3.10.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"jasmine-core": "~3.10.0",
|
||||
"karma": "^6.3.17",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.4.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
|
@ -0,0 +1,501 @@
|
|||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * Delete the template below * * * * * * * * * * -->
|
||||
<!-- * * * * * * * to get started with your project! * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
|
||||
<style>
|
||||
:host {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #1976d2;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.toolbar img {
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.toolbar #twitter-logo {
|
||||
height: 40px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.toolbar #youtube-logo {
|
||||
height: 40px;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.toolbar #twitter-logo:hover,
|
||||
.toolbar #youtube-logo:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
margin: 82px auto 32px;
|
||||
padding: 0 16px;
|
||||
max-width: 960px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
svg.material-icons {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
svg.material-icons:not(:last-child) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.card svg.material-icons path {
|
||||
fill: #888;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
all: unset;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fafafa;
|
||||
height: 40px;
|
||||
width: 200px;
|
||||
margin: 0 8px 16px;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 0.2s ease-in-out;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.card-container .card:not(:last-child) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.card.card-small {
|
||||
height: 16px;
|
||||
width: 168px;
|
||||
}
|
||||
|
||||
.card-container .card:not(.highlight-card) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card-container .card:not(.highlight-card):hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.card-container .card:not(.highlight-card):hover .material-icons path {
|
||||
fill: rgb(105, 103, 103);
|
||||
}
|
||||
|
||||
.card.highlight-card {
|
||||
background-color: #1976d2;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
width: auto;
|
||||
min-width: 30%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card.card.highlight-card span {
|
||||
margin-left: 60px;
|
||||
}
|
||||
|
||||
svg#rocket {
|
||||
width: 80px;
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: -24px;
|
||||
}
|
||||
|
||||
svg#rocket-smoke {
|
||||
height: calc(100vh - 95px);
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 180px;
|
||||
z-index: -10;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited,
|
||||
a:hover {
|
||||
color: #1976d2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #125699;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
max-width: 600px;
|
||||
border-radius: 6px;
|
||||
padding-top: 45px;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
background-color: rgb(15, 15, 16);
|
||||
}
|
||||
|
||||
.terminal::before {
|
||||
content: "\2022 \2022 \2022";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4px;
|
||||
background: rgb(58, 58, 58);
|
||||
color: #c2c3c4;
|
||||
width: 100%;
|
||||
font-size: 2rem;
|
||||
line-height: 0;
|
||||
padding: 14px 0;
|
||||
text-indent: 4px;
|
||||
}
|
||||
|
||||
.terminal pre {
|
||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
||||
color: white;
|
||||
padding: 0 1rem 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.circle-link {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border-radius: 40px;
|
||||
margin: 8px;
|
||||
background-color: white;
|
||||
border: 1px solid #eeeeee;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
transition: 1s ease-out;
|
||||
}
|
||||
|
||||
.circle-link:hover {
|
||||
transform: translateY(-0.25rem);
|
||||
box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
footer a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.github-star-badge {
|
||||
color: #24292e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
padding: 3px 10px;
|
||||
border: 1px solid rgba(27,31,35,.2);
|
||||
border-radius: 3px;
|
||||
background-image: linear-gradient(-180deg,#fafbfc,#eff3f6 90%);
|
||||
margin-left: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.github-star-badge:hover {
|
||||
background-image: linear-gradient(-180deg,#f0f3f6,#e6ebf1 90%);
|
||||
border-color: rgba(27,31,35,.35);
|
||||
background-position: -.5em;
|
||||
}
|
||||
|
||||
.github-star-badge .material-icons {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
svg#clouds {
|
||||
position: fixed;
|
||||
bottom: -160px;
|
||||
left: -230px;
|
||||
z-index: -10;
|
||||
width: 1920px;
|
||||
}
|
||||
|
||||
/* Responsive Styles */
|
||||
@media screen and (max-width: 767px) {
|
||||
.card-container > *:not(.circle-link) ,
|
||||
.terminal {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card:not(.highlight-card) {
|
||||
height: 16px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.card.highlight-card span {
|
||||
margin-left: 72px;
|
||||
}
|
||||
|
||||
svg#rocket-smoke {
|
||||
right: 120px;
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 575px) {
|
||||
svg#rocket-smoke {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Toolbar -->
|
||||
<div class="toolbar" role="banner">
|
||||
<img
|
||||
width="40"
|
||||
alt="Angular Logo"
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="
|
||||
/>
|
||||
<span>Welcome</span>
|
||||
<div class="spacer"></div>
|
||||
<a aria-label="Angular on twitter" target="_blank" rel="noopener" href="https://twitter.com/angular" title="Twitter">
|
||||
<svg id="twitter-logo" height="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
|
||||
<rect width="400" height="400" fill="none"/>
|
||||
<path d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23" fill="#fff"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a aria-label="Angular on YouTube" target="_blank" rel="noopener" href="https://youtube.com/angular" title="YouTube">
|
||||
<svg id="youtube-logo" height="24" width="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff">
|
||||
<path d="M0 0h24v24H0V0z" fill="none"/>
|
||||
<path d="M21.58 7.19c-.23-.86-.91-1.54-1.77-1.77C18.25 5 12 5 12 5s-6.25 0-7.81.42c-.86.23-1.54.91-1.77 1.77C2 8.75 2 12 2 12s0 3.25.42 4.81c.23.86.91 1.54 1.77 1.77C5.75 19 12 19 12 19s6.25 0 7.81-.42c.86-.23 1.54-.91 1.77-1.77C22 15.25 22 12 22 12s0-3.25-.42-4.81zM10 15V9l5.2 3-5.2 3z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="content" role="main">
|
||||
|
||||
<!-- Highlight Card -->
|
||||
<div class="card highlight-card card-small">
|
||||
|
||||
<svg id="rocket" xmlns="http://www.w3.org/2000/svg" width="101.678" height="101.678" viewBox="0 0 101.678 101.678">
|
||||
<title>Rocket Ship</title>
|
||||
<g id="Group_83" data-name="Group 83" transform="translate(-141 -696)">
|
||||
<circle id="Ellipse_8" data-name="Ellipse 8" cx="50.839" cy="50.839" r="50.839" transform="translate(141 696)" fill="#dd0031"/>
|
||||
<g id="Group_47" data-name="Group 47" transform="translate(165.185 720.185)">
|
||||
<path id="Path_33" data-name="Path 33" d="M3.4,42.615a3.084,3.084,0,0,0,3.553,3.553,21.419,21.419,0,0,0,12.215-6.107L9.511,30.4A21.419,21.419,0,0,0,3.4,42.615Z" transform="translate(0.371 3.363)" fill="#fff"/>
|
||||
<path id="Path_34" data-name="Path 34" d="M53.3,3.221A3.09,3.09,0,0,0,50.081,0,48.227,48.227,0,0,0,18.322,13.437c-6-1.666-14.991-1.221-18.322,7.218A33.892,33.892,0,0,1,9.439,25.1l-.333.666a3.013,3.013,0,0,0,.555,3.553L23.985,43.641a2.9,2.9,0,0,0,3.553.555l.666-.333A33.892,33.892,0,0,1,32.647,53.3c8.55-3.664,8.884-12.326,7.218-18.322A48.227,48.227,0,0,0,53.3,3.221ZM34.424,9.772a6.439,6.439,0,1,1,9.106,9.106,6.368,6.368,0,0,1-9.106,0A6.467,6.467,0,0,1,34.424,9.772Z" transform="translate(0 0.005)" fill="#fff"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<span>{{ title }} app is running!</span>
|
||||
|
||||
<svg id="rocket-smoke" xmlns="http://www.w3.org/2000/svg" width="516.119" height="1083.632" viewBox="0 0 516.119 1083.632">
|
||||
<title>Rocket Ship Smoke</title>
|
||||
<path id="Path_40" data-name="Path 40" d="M644.6,141S143.02,215.537,147.049,870.207s342.774,201.755,342.774,201.755S404.659,847.213,388.815,762.2c-27.116-145.51-11.551-384.124,271.9-609.1C671.15,139.365,644.6,141,644.6,141Z" transform="translate(-147.025 -140.939)" fill="#f5f5f5"/>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Resources -->
|
||||
<h2>Resources</h2>
|
||||
<p>Here are some links to help you get started:</p>
|
||||
|
||||
<div class="card-container">
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/tutorial">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></svg>
|
||||
<span>Learn Angular</span>
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg> </a>
|
||||
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/cli">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>
|
||||
<span>CLI Documentation</span>
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
|
||||
</a>
|
||||
|
||||
<a class="card" target="_blank" rel="noopener" href="https://blog.angular.io/">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"/></svg>
|
||||
<span>Angular Blog</span>
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
|
||||
</a>
|
||||
|
||||
<a class="card" target="_blank" rel="noopener" href="https://angular.io/devtools/">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><path d="M14.73,13.31C15.52,12.24,16,10.93,16,9.5C16,5.91,13.09,3,9.5,3S3,5.91,3,9.5C3,13.09,5.91,16,9.5,16 c1.43,0,2.74-0.48,3.81-1.27L19.59,21L21,19.59L14.73,13.31z M9.5,14C7.01,14,5,11.99,5,9.5S7.01,5,9.5,5S14,7.01,14,9.5 S11.99,14,9.5,14z"/><polygon points="10.29,8.44 9.5,6 8.71,8.44 6.25,8.44 8.26,10.03 7.49,12.5 9.5,10.97 11.51,12.5 10.74,10.03 12.75,8.44"/></g></g></svg>
|
||||
<span>Angular DevTools</span>
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Next Steps -->
|
||||
<h2>Next Steps</h2>
|
||||
<p>What do you want to do next with your app?</p>
|
||||
|
||||
<input type="hidden" #selection>
|
||||
|
||||
<div class="card-container">
|
||||
<button class="card card-small" (click)="selection.value = 'component'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>New Component</span>
|
||||
</button>
|
||||
|
||||
<button class="card card-small" (click)="selection.value = 'material'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>Angular Material</span>
|
||||
</button>
|
||||
|
||||
<button class="card card-small" (click)="selection.value = 'pwa'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>Add PWA Support</span>
|
||||
</button>
|
||||
|
||||
<button class="card card-small" (click)="selection.value = 'dependency'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>Add Dependency</span>
|
||||
</button>
|
||||
|
||||
<button class="card card-small" (click)="selection.value = 'test'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>Run and Watch Tests</span>
|
||||
</button>
|
||||
|
||||
<button class="card card-small" (click)="selection.value = 'build'" tabindex="0">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
<span>Build for Production</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Terminal -->
|
||||
<div class="terminal" [ngSwitch]="selection.value">
|
||||
<pre *ngSwitchDefault>ng generate component xyz</pre>
|
||||
<pre *ngSwitchCase="'material'">ng add @angular/material</pre>
|
||||
<pre *ngSwitchCase="'pwa'">ng add @angular/pwa</pre>
|
||||
<pre *ngSwitchCase="'dependency'">ng add _____</pre>
|
||||
<pre *ngSwitchCase="'test'">ng test</pre>
|
||||
<pre *ngSwitchCase="'build'">ng build</pre>
|
||||
</div>
|
||||
|
||||
<!-- Links -->
|
||||
<div class="card-container">
|
||||
<a class="circle-link" title="Animations" href="https://angular.io/guide/animations" target="_blank" rel="noopener">
|
||||
<svg id="Group_20" data-name="Group 20" xmlns="http://www.w3.org/2000/svg" width="21.813" height="23.453" viewBox="0 0 21.813 23.453">
|
||||
<path id="Path_15" data-name="Path 15" d="M4099.584,972.736h0l-10.882,3.9,1.637,14.4,9.245,5.153,9.245-5.153,1.686-14.4Z" transform="translate(-4088.702 -972.736)" fill="#ffa726"/>
|
||||
<path id="Path_16" data-name="Path 16" d="M4181.516,972.736v23.453l9.245-5.153,1.686-14.4Z" transform="translate(-4170.633 -972.736)" fill="#fb8c00"/>
|
||||
<path id="Path_17" data-name="Path 17" d="M4137.529,1076.127l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1058.315)" fill="#ffe0b2"/>
|
||||
<path id="Path_18" data-name="Path 18" d="M4137.529,1051.705l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1036.757)" fill="#fff3e0"/>
|
||||
<path id="Path_19" data-name="Path 19" d="M4137.529,1027.283l-7.7-3.723,4.417-2.721,7.753,3.723Z" transform="translate(-4125.003 -1015.199)" fill="#fff"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<a class="circle-link" title="CLI" href="https://cli.angular.io/" target="_blank" rel="noopener">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21.762" height="23.447" viewBox="0 0 21.762 23.447">
|
||||
<title>Angular CLI Logo</title>
|
||||
<g id="Group_21" data-name="Group 21" transform="translate(0)">
|
||||
<path id="Path_20" data-name="Path 20" d="M2660.313,313.618h0l-10.833,3.9,1.637,14.4,9.2,5.152,9.244-5.152,1.685-14.4Z" transform="translate(-2649.48 -313.618)" fill="#37474f"/>
|
||||
<path id="Path_21" data-name="Path 21" d="M2741.883,313.618v23.447l9.244-5.152,1.685-14.4Z" transform="translate(-2731.05 -313.618)" fill="#263238"/>
|
||||
<path id="Path_22" data-name="Path 22" d="M2692.293,379.169h11.724V368.618h-11.724Zm11.159-.6h-10.608v-9.345h10.621v9.345Z" transform="translate(-2687.274 -362.17)" fill="#fff"/>
|
||||
<path id="Path_23" data-name="Path 23" d="M2709.331,393.688l.4.416,2.265-2.28-2.294-2.294-.4.4,1.893,1.893Z" transform="translate(-2702.289 -380.631)" fill="#fff"/>
|
||||
<rect id="Rectangle_12" data-name="Rectangle 12" width="3.517" height="0.469" transform="translate(9.709 13.744)" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<a class="circle-link" title="Find a Local Meetup" href="https://www.meetup.com/find/?keywords=angular" target="_blank" rel="noopener">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24.607" height="23.447" viewBox="0 0 24.607 23.447">
|
||||
<title>Meetup Logo</title>
|
||||
<path id="logo--mSwarm" d="M21.221,14.95A4.393,4.393,0,0,1,17.6,19.281a4.452,4.452,0,0,1-.8.069c-.09,0-.125.035-.154.117a2.939,2.939,0,0,1-2.506,2.091,2.868,2.868,0,0,1-2.248-.624.168.168,0,0,0-.245-.005,3.926,3.926,0,0,1-2.589.741,4.015,4.015,0,0,1-3.7-3.347,2.7,2.7,0,0,1-.043-.38c0-.106-.042-.146-.143-.166a3.524,3.524,0,0,1-1.516-.69A3.623,3.623,0,0,1,2.23,14.557a3.66,3.66,0,0,1,1.077-3.085.138.138,0,0,0,.026-.2,3.348,3.348,0,0,1-.451-1.821,3.46,3.46,0,0,1,2.749-3.28.44.44,0,0,0,.355-.281,5.072,5.072,0,0,1,3.863-3,5.028,5.028,0,0,1,3.555.666.31.31,0,0,0,.271.03A4.5,4.5,0,0,1,18.3,4.7a4.4,4.4,0,0,1,1.334,2.751,3.658,3.658,0,0,1,.022.706.131.131,0,0,0,.1.157,2.432,2.432,0,0,1,1.574,1.645,2.464,2.464,0,0,1-.7,2.616c-.065.064-.051.1-.014.166A4.321,4.321,0,0,1,21.221,14.95ZM13.4,14.607a2.09,2.09,0,0,0,1.409,1.982,4.7,4.7,0,0,0,1.275.221,1.807,1.807,0,0,0,.9-.151.542.542,0,0,0,.321-.545.558.558,0,0,0-.359-.534,1.2,1.2,0,0,0-.254-.078c-.262-.047-.526-.086-.787-.138a.674.674,0,0,1-.617-.75,3.394,3.394,0,0,1,.218-1.109c.217-.658.509-1.286.79-1.918a15.609,15.609,0,0,0,.745-1.86,1.95,1.95,0,0,0,.06-1.073,1.286,1.286,0,0,0-1.051-1.033,1.977,1.977,0,0,0-1.521.2.339.339,0,0,1-.446-.042c-.1-.092-.2-.189-.307-.284a1.214,1.214,0,0,0-1.643-.061,7.563,7.563,0,0,1-.614.512A.588.588,0,0,1,10.883,8c-.215-.115-.437-.215-.659-.316a2.153,2.153,0,0,0-.695-.248A2.091,2.091,0,0,0,7.541,8.562a9.915,9.915,0,0,0-.405.986c-.559,1.545-1.015,3.123-1.487,4.7a1.528,1.528,0,0,0,.634,1.777,1.755,1.755,0,0,0,1.5.211,1.35,1.35,0,0,0,.824-.858c.543-1.281,1.032-2.584,1.55-3.875.142-.355.28-.712.432-1.064a.548.548,0,0,1,.851-.24.622.622,0,0,1,.185.539,2.161,2.161,0,0,1-.181.621c-.337.852-.68,1.7-1.018,2.552a2.564,2.564,0,0,0-.173.528.624.624,0,0,0,.333.71,1.073,1.073,0,0,0,.814.034,1.22,1.22,0,0,0,.657-.655q.758-1.488,1.511-2.978.35-.687.709-1.37a1.073,1.073,0,0,1,.357-.434.43.43,0,0,1,.463-.016.373.373,0,0,1,.153.387.7.7,0,0,1-.057.236c-.065.157-.127.316-.2.469-.42.883-.846,1.763-1.262,2.648A2.463,2.463,0,0,0,13.4,14.607Zm5.888,6.508a1.09,1.09,0,0,0-2.179.006,1.09,1.09,0,0,0,2.179-.006ZM1.028,12.139a1.038,1.038,0,1,0,.01-2.075,1.038,1.038,0,0,0-.01,2.075ZM13.782.528a1.027,1.027,0,1,0-.011,2.055A1.027,1.027,0,0,0,13.782.528ZM22.21,6.95a.882.882,0,0,0-1.763.011A.882.882,0,0,0,22.21,6.95ZM4.153,4.439a.785.785,0,1,0,.787-.78A.766.766,0,0,0,4.153,4.439Zm8.221,18.22a.676.676,0,1,0-.677.666A.671.671,0,0,0,12.374,22.658ZM22.872,12.2a.674.674,0,0,0-.665.665.656.656,0,0,0,.655.643.634.634,0,0,0,.655-.644A.654.654,0,0,0,22.872,12.2ZM7.171-.123A.546.546,0,0,0,6.613.43a.553.553,0,1,0,1.106,0A.539.539,0,0,0,7.171-.123ZM24.119,9.234a.507.507,0,0,0-.493.488.494.494,0,0,0,.494.494.48.48,0,0,0,.487-.483A.491.491,0,0,0,24.119,9.234Zm-19.454,9.7a.5.5,0,0,0-.488-.488.491.491,0,0,0-.487.5.483.483,0,0,0,.491.479A.49.49,0,0,0,4.665,18.936Z" transform="translate(0 0.123)" fill="#f64060"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<a class="circle-link" title="Join the Conversation on Discord" href="https://discord.gg/angular" target="_blank" rel="noopener">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 245 240">
|
||||
<title>Discord Logo</title>
|
||||
<path d="M104.4 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1.1-6.1-4.5-11.1-10.2-11.1zM140.9 103.9c-5.7 0-10.2 5-10.2 11.1s4.6 11.1 10.2 11.1c5.7 0 10.2-5 10.2-11.1s-4.5-11.1-10.2-11.1z"/>
|
||||
<path d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
Love Angular?
|
||||
<a href="https://github.com/angular/angular" target="_blank" rel="noopener"> Give our repo a star.
|
||||
<div class="github-star-badge">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>
|
||||
Star
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://github.com/angular/angular" target="_blank" rel="noopener">
|
||||
<svg class="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" fill="#1976d2"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
||||
</a>
|
||||
</footer>
|
||||
|
||||
<svg id="clouds" xmlns="http://www.w3.org/2000/svg" width="2611.084" height="485.677" viewBox="0 0 2611.084 485.677">
|
||||
<title>Gray Clouds Background</title>
|
||||
<path id="Path_39" data-name="Path 39" d="M2379.709,863.793c10-93-77-171-168-149-52-114-225-105-264,15-75,3-140,59-152,133-30,2.83-66.725,9.829-93.5,26.25-26.771-16.421-63.5-23.42-93.5-26.25-12-74-77-130-152-133-39-120-212-129-264-15-54.084-13.075-106.753,9.173-138.488,48.9-31.734-39.726-84.4-61.974-138.487-48.9-52-114-225-105-264,15a162.027,162.027,0,0,0-103.147,43.044c-30.633-45.365-87.1-72.091-145.206-58.044-52-114-225-105-264,15-75,3-140,59-152,133-53,5-127,23-130,83-2,42,35,72,70,86,49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33,61.112,8.015,113.854-5.72,150.492-29.764a165.62,165.62,0,0,0,110.861-3.236c47,94,178,113,251,33,31.385,4.116,60.563,2.495,86.487-3.311,25.924,5.806,55.1,7.427,86.488,3.311,73,80,204,61,251-33a165.625,165.625,0,0,0,120,0c51,13,108,15,157-5a147.188,147.188,0,0,0,33.5-18.694,147.217,147.217,0,0,0,33.5,18.694c49,20,106,18,157,5a165.625,165.625,0,0,0,120,0c47,94,178,113,251,33C2446.709,1093.793,2554.709,922.793,2379.709,863.793Z" transform="translate(142.69 -634.312)" fill="#eee"/>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * The content above * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * -->
|
||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
||||
|
||||
<router-outlet></router-outlet>
|
|
@ -0,0 +1,35 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
RouterTestingModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'angular'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('angular');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('.content span')?.textContent).toContain('angular app is running!');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'angular';
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
|
@ -0,0 +1,3 @@
|
|||
export const environment = {
|
||||
production: true
|
||||
};
|
|
@ -0,0 +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 = {
|
||||
production: false
|
||||
};
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||
*
|
||||
* This import should be commented out in production mode because it will have a negative impact
|
||||
* on performance if an error is thrown.
|
||||
*/
|
||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
BIN
mongodb-angular-expressjs-nodejs/frontend/src/favicon.ico
Normal file
BIN
mongodb-angular-expressjs-nodejs/frontend/src/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 948 B |
13
mongodb-angular-expressjs-nodejs/frontend/src/index.html
Normal file
13
mongodb-angular-expressjs-nodejs/frontend/src/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Angular</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>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
12
mongodb-angular-expressjs-nodejs/frontend/src/main.ts
Normal file
12
mongodb-angular-expressjs-nodejs/frontend/src/main.ts
Normal file
|
@ -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));
|
53
mongodb-angular-expressjs-nodejs/frontend/src/polyfills.ts
Normal file
53
mongodb-angular-expressjs-nodejs/frontend/src/polyfills.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||
* will put import in the top of bundle, so user need to create a separate file
|
||||
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||
* into that file, and then add the following code before importing zone.js.
|
||||
* import './zone-flags';
|
||||
*
|
||||
* The flags allowed in zone-flags.ts are listed here.
|
||||
*
|
||||
* The following flags will work for all browsers.
|
||||
*
|
||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
*
|
||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||
*
|
||||
* (window as any).__Zone_enable_cross_context_check = true;
|
||||
*
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
1
mongodb-angular-expressjs-nodejs/frontend/src/styles.css
Normal file
1
mongodb-angular-expressjs-nodejs/frontend/src/styles.css
Normal file
|
@ -0,0 +1 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
26
mongodb-angular-expressjs-nodejs/frontend/src/test.ts
Normal file
26
mongodb-angular-expressjs-nodejs/frontend/src/test.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// 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);
|
15
mongodb-angular-expressjs-nodejs/frontend/tsconfig.app.json
Normal file
15
mongodb-angular-expressjs-nodejs/frontend/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"
|
||||
]
|
||||
}
|
32
mongodb-angular-expressjs-nodejs/frontend/tsconfig.json
Normal file
32
mongodb-angular-expressjs-nodejs/frontend/tsconfig.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2017",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
18
mongodb-angular-expressjs-nodejs/frontend/tsconfig.spec.json
Normal file
18
mongodb-angular-expressjs-nodejs/frontend/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"
|
||||
]
|
||||
}
|
3
mongodb-angular-expressjs-nodejs/nginx/Dockerfile
Normal file
3
mongodb-angular-expressjs-nodejs/nginx/Dockerfile
Normal file
|
@ -0,0 +1,3 @@
|
|||
FROM nginx:1.21.6
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
11
mongodb-angular-expressjs-nodejs/nginx/nginx.conf
Normal file
11
mongodb-angular-expressjs-nodejs/nginx/nginx.conf
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
location / {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade websocket;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_pass http://backend:5000;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue