| @@ -1,16 +1,38 @@ | |||||
| # matsen-tool-fe | # matsen-tool-fe | ||||
| # BEFORE Installation: | # BEFORE Installation: | ||||
| - npm -v (minimum is 20.9.0) | |||||
| - node --version (minimum is 8.0.0) | |||||
| - npm -v (minimum is 8.0.0) | |||||
| - node --version (minimum is 20.9.0) | |||||
| - brew upgrade node | - brew upgrade node | ||||
| ## Installation | ## Installation | ||||
| - npm i -g @angular/cli | - npm i -g @angular/cli | ||||
| - ng new matsen-tool | |||||
| - ng new matsen-tool --no-standalone | |||||
| - Standalone is now the new default in v17 (no app.module.ts) | |||||
| - cd matsen-tool -> ng serve | - cd matsen-tool -> ng serve | ||||
| ## Install Bootstrap | ## Install Bootstrap | ||||
| - cd matsen-tool | |||||
| - npm i bootstrap @popperjs/core --save | - npm i bootstrap @popperjs/core --save | ||||
| ## Install Angular Material | |||||
| - cd matsen-tool | |||||
| - ng add @angular/material | |||||
| ## Generate Dummy data | |||||
| - cd matsen-tool | |||||
| - npm i @openapitools/openapi-generator-cli -D | |||||
| - package.json: Scripts block: | |||||
| - "generate:api": "openapi-generator-cli generate -i ./openapi.yaml -g typescript-angular -o src/app/core/api/v1 -p=removeOperationIdPrefix=true" | |||||
| - Java must be installed | |||||
| - cd matsen-tool | |||||
| - npm run generate:api | |||||
| ## Module anlegen | |||||
| - cd app | |||||
| - ng g m registration --route register --module app.module | |||||
| ## Interesting Links | |||||
| - https://openapi-generator.tech/docs/installation | |||||
| - https://www.kevinboosten.dev/how-i-use-an-openapi-spec-in-my-angular-projects | |||||
| @@ -1,6 +1,6 @@ | |||||
| # MatsenTool | # MatsenTool | ||||
| This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.5. | |||||
| This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.6. | |||||
| ## Development server | ## Development server | ||||
| @@ -7,7 +7,14 @@ | |||||
| "projectType": "application", | "projectType": "application", | ||||
| "schematics": { | "schematics": { | ||||
| "@schematics/angular:component": { | "@schematics/angular:component": { | ||||
| "style": "scss" | |||||
| "style": "scss", | |||||
| "standalone": false | |||||
| }, | |||||
| "@schematics/angular:directive": { | |||||
| "standalone": false | |||||
| }, | |||||
| "@schematics/angular:pipe": { | |||||
| "standalone": false | |||||
| } | } | ||||
| }, | }, | ||||
| "root": "", | "root": "", | ||||
| @@ -30,14 +37,10 @@ | |||||
| "src/assets" | "src/assets" | ||||
| ], | ], | ||||
| "styles": [ | "styles": [ | ||||
| "@angular/material/prebuilt-themes/purple-green.css", | |||||
| "./node_modules/bootstrap/dist/css/bootstrap.min.css", | |||||
| "@angular/material/prebuilt-themes/pink-bluegrey.css", | |||||
| "src/styles.scss" | "src/styles.scss" | ||||
| ], | ], | ||||
| "scripts": [ | |||||
| "./node_modules/@popperjs/core/dist/umd/popper.min.js", | |||||
| "./node_modules/bootstrap/dist/js/bootstrap.min.js" | |||||
| ], | |||||
| "scripts": [], | |||||
| "server": "src/main.server.ts", | "server": "src/main.server.ts", | ||||
| "prerender": true, | "prerender": true, | ||||
| "ssr": { | "ssr": { | ||||
| @@ -100,7 +103,7 @@ | |||||
| "src/assets" | "src/assets" | ||||
| ], | ], | ||||
| "styles": [ | "styles": [ | ||||
| "@angular/material/prebuilt-themes/purple-green.css", | |||||
| "@angular/material/prebuilt-themes/pink-bluegrey.css", | |||||
| "src/styles.scss" | "src/styles.scss" | ||||
| ], | ], | ||||
| "scripts": [] | "scripts": [] | ||||
| @@ -0,0 +1,693 @@ | |||||
| openapi: 3.1.0 | |||||
| info: | |||||
| title: 'Matsen API Platform' | |||||
| description: '' | |||||
| version: 1.0.0 | |||||
| servers: | |||||
| - | |||||
| url: / | |||||
| description: '' | |||||
| paths: | |||||
| /api/posts: | |||||
| get: | |||||
| operationId: api_posts_get_collection | |||||
| tags: | |||||
| - Post | |||||
| responses: | |||||
| 200: | |||||
| description: 'Post collection' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| type: object | |||||
| properties: | |||||
| 'hydra:member': { type: array, items: { $ref: '#/components/schemas/Post.jsonld' } } | |||||
| 'hydra:totalItems': { type: integer, minimum: 0 } | |||||
| 'hydra:view': { type: object, properties: { '@id': { type: string, format: iri-reference }, '@type': { type: string }, 'hydra:first': { type: string, format: iri-reference }, 'hydra:last': { type: string, format: iri-reference }, 'hydra:previous': { type: string, format: iri-reference }, 'hydra:next': { type: string, format: iri-reference } }, example: { '@id': string, type: string, 'hydra:first': string, 'hydra:last': string, 'hydra:previous': string, 'hydra:next': string } } | |||||
| 'hydra:search': { type: object, properties: { '@type': { type: string }, 'hydra:template': { type: string }, 'hydra:variableRepresentation': { type: string }, 'hydra:mapping': { type: array, items: { type: object, properties: { '@type': { type: string }, variable: { type: string }, property: { type: [string, 'null'] }, required: { type: boolean } } } } } } | |||||
| required: | |||||
| - 'hydra:member' | |||||
| application/json: | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| $ref: '#/components/schemas/Post' | |||||
| text/html: | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| $ref: '#/components/schemas/Post' | |||||
| application/hal+json: | |||||
| schema: | |||||
| type: object | |||||
| properties: | |||||
| _embedded: { type: array, items: { $ref: '#/components/schemas/Post.jsonhal' } } | |||||
| totalItems: { type: integer, minimum: 0 } | |||||
| itemsPerPage: { type: integer, minimum: 0 } | |||||
| _links: { type: object, properties: { self: { type: object, properties: { href: { type: string, format: iri-reference } } }, first: { type: object, properties: { href: { type: string, format: iri-reference } } }, last: { type: object, properties: { href: { type: string, format: iri-reference } } }, next: { type: object, properties: { href: { type: string, format: iri-reference } } }, previous: { type: object, properties: { href: { type: string, format: iri-reference } } } } } | |||||
| required: | |||||
| - _links | |||||
| - _embedded | |||||
| summary: 'Retrieves the collection of Post resources.' | |||||
| description: 'Retrieves the collection of Post resources.' | |||||
| parameters: | |||||
| - | |||||
| name: page | |||||
| in: query | |||||
| description: 'The collection page number' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: integer | |||||
| default: 1 | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | |||||
| post: | |||||
| operationId: api_posts_post | |||||
| tags: | |||||
| - Post | |||||
| responses: | |||||
| 201: | |||||
| description: 'Post resource created' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonhal' | |||||
| links: { } | |||||
| 400: | |||||
| description: 'Invalid input' | |||||
| 422: | |||||
| description: 'Unprocessable entity' | |||||
| summary: 'Creates a Post resource.' | |||||
| description: 'Creates a Post resource.' | |||||
| parameters: [] | |||||
| requestBody: | |||||
| description: 'The new Post resource' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonhal' | |||||
| required: true | |||||
| deprecated: false | |||||
| parameters: [] | |||||
| '/api/posts/{id}': | |||||
| get: | |||||
| operationId: api_posts_id_get | |||||
| tags: | |||||
| - Post | |||||
| responses: | |||||
| 200: | |||||
| description: 'Post resource' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonhal' | |||||
| 404: | |||||
| description: 'Resource not found' | |||||
| summary: 'Retrieves a Post resource.' | |||||
| description: 'Retrieves a Post resource.' | |||||
| parameters: | |||||
| - | |||||
| name: id | |||||
| in: path | |||||
| description: 'PostingApi identifier' | |||||
| required: true | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: string | |||||
| style: simple | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | |||||
| delete: | |||||
| operationId: api_posts_id_delete | |||||
| tags: | |||||
| - Post | |||||
| responses: | |||||
| 204: | |||||
| description: 'Post resource deleted' | |||||
| 404: | |||||
| description: 'Resource not found' | |||||
| summary: 'Removes the Post resource.' | |||||
| description: 'Removes the Post resource.' | |||||
| parameters: | |||||
| - | |||||
| name: id | |||||
| in: path | |||||
| description: 'PostingApi identifier' | |||||
| required: true | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: string | |||||
| style: simple | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | |||||
| patch: | |||||
| operationId: api_posts_id_patch | |||||
| tags: | |||||
| - Post | |||||
| responses: | |||||
| 200: | |||||
| description: 'Post resource updated' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post.jsonhal' | |||||
| links: { } | |||||
| 400: | |||||
| description: 'Invalid input' | |||||
| 422: | |||||
| description: 'Unprocessable entity' | |||||
| 404: | |||||
| description: 'Resource not found' | |||||
| summary: 'Updates the Post resource.' | |||||
| description: 'Updates the Post resource.' | |||||
| parameters: | |||||
| - | |||||
| name: id | |||||
| in: path | |||||
| description: 'PostingApi identifier' | |||||
| required: true | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: string | |||||
| style: simple | |||||
| explode: false | |||||
| allowReserved: false | |||||
| requestBody: | |||||
| description: 'The updated Post resource' | |||||
| content: | |||||
| application/merge-patch+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/Post' | |||||
| required: true | |||||
| deprecated: false | |||||
| parameters: [] | |||||
| /api/users: | |||||
| get: | |||||
| operationId: api_users_get_collection | |||||
| tags: | |||||
| - User | |||||
| responses: | |||||
| 200: | |||||
| description: 'User collection' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| type: object | |||||
| properties: | |||||
| 'hydra:member': { type: array, items: { $ref: '#/components/schemas/User.jsonld' } } | |||||
| 'hydra:totalItems': { type: integer, minimum: 0 } | |||||
| 'hydra:view': { type: object, properties: { '@id': { type: string, format: iri-reference }, '@type': { type: string }, 'hydra:first': { type: string, format: iri-reference }, 'hydra:last': { type: string, format: iri-reference }, 'hydra:previous': { type: string, format: iri-reference }, 'hydra:next': { type: string, format: iri-reference } }, example: { '@id': string, type: string, 'hydra:first': string, 'hydra:last': string, 'hydra:previous': string, 'hydra:next': string } } | |||||
| 'hydra:search': { type: object, properties: { '@type': { type: string }, 'hydra:template': { type: string }, 'hydra:variableRepresentation': { type: string }, 'hydra:mapping': { type: array, items: { type: object, properties: { '@type': { type: string }, variable: { type: string }, property: { type: [string, 'null'] }, required: { type: boolean } } } } } } | |||||
| required: | |||||
| - 'hydra:member' | |||||
| application/json: | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| $ref: '#/components/schemas/User' | |||||
| text/html: | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| $ref: '#/components/schemas/User' | |||||
| application/hal+json: | |||||
| schema: | |||||
| type: object | |||||
| properties: | |||||
| _embedded: { type: array, items: { $ref: '#/components/schemas/User.jsonhal' } } | |||||
| totalItems: { type: integer, minimum: 0 } | |||||
| itemsPerPage: { type: integer, minimum: 0 } | |||||
| _links: { type: object, properties: { self: { type: object, properties: { href: { type: string, format: iri-reference } } }, first: { type: object, properties: { href: { type: string, format: iri-reference } } }, last: { type: object, properties: { href: { type: string, format: iri-reference } } }, next: { type: object, properties: { href: { type: string, format: iri-reference } } }, previous: { type: object, properties: { href: { type: string, format: iri-reference } } } } } | |||||
| required: | |||||
| - _links | |||||
| - _embedded | |||||
| summary: 'Retrieves the collection of User resources.' | |||||
| description: 'Retrieves the collection of User resources.' | |||||
| parameters: | |||||
| - | |||||
| name: page | |||||
| in: query | |||||
| description: 'The collection page number' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: integer | |||||
| default: 1 | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | |||||
| post: | |||||
| operationId: api_users_post | |||||
| tags: | |||||
| - User | |||||
| responses: | |||||
| 201: | |||||
| description: 'User resource created' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonhal' | |||||
| links: { } | |||||
| 400: | |||||
| description: 'Invalid input' | |||||
| 422: | |||||
| description: 'Unprocessable entity' | |||||
| summary: 'Creates a User resource.' | |||||
| description: 'Creates a User resource.' | |||||
| parameters: [] | |||||
| requestBody: | |||||
| description: 'The new User resource' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonhal' | |||||
| required: true | |||||
| deprecated: false | |||||
| parameters: [] | |||||
| '/api/users/{id}': | |||||
| get: | |||||
| operationId: api_users_id_get | |||||
| tags: | |||||
| - User | |||||
| responses: | |||||
| 200: | |||||
| description: 'User resource' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonhal' | |||||
| 404: | |||||
| description: 'Resource not found' | |||||
| summary: 'Retrieves a User resource.' | |||||
| description: 'Retrieves a User resource.' | |||||
| parameters: | |||||
| - | |||||
| name: id | |||||
| in: path | |||||
| description: 'UserApi identifier' | |||||
| required: true | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: string | |||||
| style: simple | |||||
| explode: false | |||||
| allowReserved: false | |||||
| deprecated: false | |||||
| patch: | |||||
| operationId: api_users_id_patch | |||||
| tags: | |||||
| - User | |||||
| responses: | |||||
| 200: | |||||
| description: 'User resource updated' | |||||
| content: | |||||
| application/ld+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonld' | |||||
| application/json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| text/html: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| application/hal+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User.jsonhal' | |||||
| links: { } | |||||
| 400: | |||||
| description: 'Invalid input' | |||||
| 422: | |||||
| description: 'Unprocessable entity' | |||||
| 404: | |||||
| description: 'Resource not found' | |||||
| summary: 'Updates the User resource.' | |||||
| description: 'Updates the User resource.' | |||||
| parameters: | |||||
| - | |||||
| name: id | |||||
| in: path | |||||
| description: 'UserApi identifier' | |||||
| required: true | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: string | |||||
| style: simple | |||||
| explode: false | |||||
| allowReserved: false | |||||
| requestBody: | |||||
| description: 'The updated User resource' | |||||
| content: | |||||
| application/merge-patch+json: | |||||
| schema: | |||||
| $ref: '#/components/schemas/User' | |||||
| required: true | |||||
| deprecated: false | |||||
| parameters: [] | |||||
| components: | |||||
| schemas: | |||||
| Post: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - message | |||||
| properties: | |||||
| message: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| owner: | |||||
| 'owl:maxCardinality': 1 | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: iri-reference | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| Post.jsonhal: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - message | |||||
| properties: | |||||
| _links: | |||||
| type: object | |||||
| properties: | |||||
| self: | |||||
| type: object | |||||
| properties: | |||||
| href: | |||||
| type: string | |||||
| format: iri-reference | |||||
| message: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| owner: | |||||
| 'owl:maxCardinality': 1 | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: iri-reference | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| Post.jsonld: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - message | |||||
| properties: | |||||
| '@context': | |||||
| readOnly: true | |||||
| oneOf: | |||||
| - | |||||
| type: string | |||||
| - | |||||
| type: object | |||||
| properties: | |||||
| '@vocab': | |||||
| type: string | |||||
| hydra: | |||||
| type: string | |||||
| enum: ['http://www.w3.org/ns/hydra/core#'] | |||||
| required: | |||||
| - '@vocab' | |||||
| - hydra | |||||
| additionalProperties: true | |||||
| '@id': | |||||
| readOnly: true | |||||
| type: string | |||||
| '@type': | |||||
| readOnly: true | |||||
| type: string | |||||
| message: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| owner: | |||||
| 'owl:maxCardinality': 1 | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: iri-reference | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| User: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - firstName | |||||
| - lastName | |||||
| properties: | |||||
| email: | |||||
| format: email | |||||
| externalDocs: | |||||
| url: 'https://schema.org/email' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| firstName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| lastName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| password: | |||||
| writeOnly: true | |||||
| description: 'The plaintext password when being set or changed.' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| active: | |||||
| type: boolean | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| userPosts: | |||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| format: iri-reference | |||||
| User.jsonhal: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - firstName | |||||
| - lastName | |||||
| properties: | |||||
| _links: | |||||
| type: object | |||||
| properties: | |||||
| self: | |||||
| type: object | |||||
| properties: | |||||
| href: | |||||
| type: string | |||||
| format: iri-reference | |||||
| email: | |||||
| format: email | |||||
| externalDocs: | |||||
| url: 'https://schema.org/email' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| firstName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| lastName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| password: | |||||
| writeOnly: true | |||||
| description: 'The plaintext password when being set or changed.' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| active: | |||||
| type: boolean | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| userPosts: | |||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| format: iri-reference | |||||
| User.jsonld: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| required: | |||||
| - firstName | |||||
| - lastName | |||||
| properties: | |||||
| '@context': | |||||
| readOnly: true | |||||
| oneOf: | |||||
| - | |||||
| type: string | |||||
| - | |||||
| type: object | |||||
| properties: | |||||
| '@vocab': | |||||
| type: string | |||||
| hydra: | |||||
| type: string | |||||
| enum: ['http://www.w3.org/ns/hydra/core#'] | |||||
| required: | |||||
| - '@vocab' | |||||
| - hydra | |||||
| additionalProperties: true | |||||
| '@id': | |||||
| readOnly: true | |||||
| type: string | |||||
| '@type': | |||||
| readOnly: true | |||||
| type: string | |||||
| email: | |||||
| format: email | |||||
| externalDocs: | |||||
| url: 'https://schema.org/email' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| firstName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| lastName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| password: | |||||
| writeOnly: true | |||||
| description: 'The plaintext password when being set or changed.' | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| active: | |||||
| type: boolean | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: date-time | |||||
| userPosts: | |||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| format: iri-reference | |||||
| responses: { } | |||||
| parameters: { } | |||||
| examples: { } | |||||
| requestBodies: { } | |||||
| headers: { } | |||||
| securitySchemes: { } | |||||
| security: [] | |||||
| tags: [] | |||||
| @@ -0,0 +1,49 @@ | |||||
| openapi: 3.0.0 | |||||
| info: | |||||
| title: JSON Placeholder OpenAPI | |||||
| description: Example spec of the well known JSON Placeholder website | |||||
| version: 0.1.9 | |||||
| servers: | |||||
| - url: https://jsonplaceholder.typicode.com | |||||
| paths: | |||||
| /posts: | |||||
| get: | |||||
| tags: ['posts'] | |||||
| summary: Returns a list of Posts. | |||||
| description: Optional extended description in CommonMark or HTML. | |||||
| operationId: GetPosts | |||||
| responses: | |||||
| '200': | |||||
| description: A JSON array of Posts | |||||
| content: | |||||
| application/json: | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| $ref: '#/components/schemas/Post' | |||||
| components: | |||||
| schemas: | |||||
| Post: | |||||
| required: | |||||
| - id | |||||
| - userId | |||||
| - title | |||||
| - body | |||||
| type: object | |||||
| properties: | |||||
| id: | |||||
| type: number | |||||
| description: record id | |||||
| example: 1 | |||||
| userId: | |||||
| type: string | |||||
| description: unique user identifier | |||||
| example: 2 | |||||
| title: | |||||
| type: string | |||||
| description: title of this Post | |||||
| example: sunt aut facere repellat provident occaecati excepturi optio reprehenderit | |||||
| body: | |||||
| type: string | |||||
| description: description of this post | |||||
| example: quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto | |||||
| @@ -0,0 +1,7 @@ | |||||
| { | |||||
| "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", | |||||
| "spaces": 2, | |||||
| "generator-cli": { | |||||
| "version": "7.1.0" | |||||
| } | |||||
| } | |||||
| @@ -7,22 +7,23 @@ | |||||
| "build": "ng build", | "build": "ng build", | ||||
| "watch": "ng build --watch --configuration development", | "watch": "ng build --watch --configuration development", | ||||
| "test": "ng test", | "test": "ng test", | ||||
| "serve:ssr:matsen-tool": "node dist/matsen-tool/server/server.mjs" | |||||
| "serve:ssr:matsen-tool": "node dist/matsen-tool/server/server.mjs", | |||||
| "generate:api": "openapi-generator-cli generate -i ./openapi.yaml -g typescript-angular -o src/app/core/api/v1 -p=removeOperationIdPrefix=true" | |||||
| }, | }, | ||||
| "private": true, | "private": true, | ||||
| "dependencies": { | "dependencies": { | ||||
| "@angular/animations": "^17.0.0", | "@angular/animations": "^17.0.0", | ||||
| "@angular/cdk": "^17.0.1", | |||||
| "@angular/cdk": "^17.0.3", | |||||
| "@angular/common": "^17.0.0", | "@angular/common": "^17.0.0", | ||||
| "@angular/compiler": "^17.0.0", | "@angular/compiler": "^17.0.0", | ||||
| "@angular/core": "^17.0.0", | "@angular/core": "^17.0.0", | ||||
| "@angular/forms": "^17.0.0", | "@angular/forms": "^17.0.0", | ||||
| "@angular/material": "^17.0.1", | |||||
| "@angular/material": "^17.0.3", | |||||
| "@angular/platform-browser": "^17.0.0", | "@angular/platform-browser": "^17.0.0", | ||||
| "@angular/platform-browser-dynamic": "^17.0.0", | "@angular/platform-browser-dynamic": "^17.0.0", | ||||
| "@angular/platform-server": "^17.0.0", | "@angular/platform-server": "^17.0.0", | ||||
| "@angular/router": "^17.0.0", | "@angular/router": "^17.0.0", | ||||
| "@angular/ssr": "^17.0.5", | |||||
| "@angular/ssr": "^17.0.6", | |||||
| "@popperjs/core": "^2.11.8", | "@popperjs/core": "^2.11.8", | ||||
| "bootstrap": "^5.3.2", | "bootstrap": "^5.3.2", | ||||
| "express": "^4.18.2", | "express": "^4.18.2", | ||||
| @@ -31,9 +32,10 @@ | |||||
| "zone.js": "~0.14.2" | "zone.js": "~0.14.2" | ||||
| }, | }, | ||||
| "devDependencies": { | "devDependencies": { | ||||
| "@angular-devkit/build-angular": "^17.0.5", | |||||
| "@angular/cli": "^17.0.5", | |||||
| "@angular-devkit/build-angular": "^17.0.6", | |||||
| "@angular/cli": "^17.0.6", | |||||
| "@angular/compiler-cli": "^17.0.0", | "@angular/compiler-cli": "^17.0.0", | ||||
| "@openapitools/openapi-generator-cli": "^2.7.0", | |||||
| "@types/express": "^4.17.17", | "@types/express": "^4.17.17", | ||||
| "@types/jasmine": "~5.1.0", | "@types/jasmine": "~5.1.0", | ||||
| "@types/node": "^18.18.0", | "@types/node": "^18.18.0", | ||||
| @@ -45,4 +47,4 @@ | |||||
| "karma-jasmine-html-reporter": "~2.1.0", | "karma-jasmine-html-reporter": "~2.1.0", | ||||
| "typescript": "~5.2.2" | "typescript": "~5.2.2" | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -3,7 +3,7 @@ import { CommonEngine } from '@angular/ssr'; | |||||
| import express from 'express'; | import express from 'express'; | ||||
| import { fileURLToPath } from 'node:url'; | import { fileURLToPath } from 'node:url'; | ||||
| import { dirname, join, resolve } from 'node:path'; | import { dirname, join, resolve } from 'node:path'; | ||||
| import bootstrap from './src/main.server'; | |||||
| import AppServerModule from './src/main.server'; | |||||
| // The Express app is exported so that it can be used by serverless Functions. | // The Express app is exported so that it can be used by serverless Functions. | ||||
| export function app(): express.Express { | export function app(): express.Express { | ||||
| @@ -30,7 +30,7 @@ export function app(): express.Express { | |||||
| commonEngine | commonEngine | ||||
| .render({ | .render({ | ||||
| bootstrap, | |||||
| bootstrap: AppServerModule, | |||||
| documentFilePath: indexHtml, | documentFilePath: indexHtml, | ||||
| url: `${protocol}://${headers.host}${originalUrl}`, | url: `${protocol}://${headers.host}${originalUrl}`, | ||||
| publicPath: browserDistFolder, | publicPath: browserDistFolder, | ||||
| @@ -0,0 +1,10 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { RouterModule, Routes } from '@angular/router'; | |||||
| const routes: Routes = [{ path: 'test', loadChildren: () => import('./test/test.module').then(m => m.TestModule) }]; | |||||
| @NgModule({ | |||||
| imports: [RouterModule.forRoot(routes)], | |||||
| exports: [RouterModule] | |||||
| }) | |||||
| export class AppRoutingModule { } | |||||
| @@ -1 +1,11 @@ | |||||
| <app-login></app-login> | |||||
| <!--<ul>--> | |||||
| <!-- <li>Posts</li>--> | |||||
| <!-- <li *ngFor="let post of posts$ | async">--> | |||||
| <!-- <h2>{{post.}} - {{post.owner}}</h2>--> | |||||
| <!-- <p>{{post.message}}</p>--> | |||||
| <!-- </li>--> | |||||
| <!--</ul>--> | |||||
| <router-outlet></router-outlet> | <router-outlet></router-outlet> | ||||
| @@ -1,10 +1,16 @@ | |||||
| import { TestBed } from '@angular/core/testing'; | import { TestBed } from '@angular/core/testing'; | ||||
| import { RouterTestingModule } from '@angular/router/testing'; | |||||
| import { AppComponent } from './app.component'; | import { AppComponent } from './app.component'; | ||||
| describe('AppComponent', () => { | describe('AppComponent', () => { | ||||
| beforeEach(async () => { | beforeEach(async () => { | ||||
| await TestBed.configureTestingModule({ | await TestBed.configureTestingModule({ | ||||
| imports: [AppComponent], | |||||
| imports: [ | |||||
| RouterTestingModule | |||||
| ], | |||||
| declarations: [ | |||||
| AppComponent | |||||
| ], | |||||
| }).compileComponents(); | }).compileComponents(); | ||||
| }); | }); | ||||
| @@ -14,7 +20,7 @@ describe('AppComponent', () => { | |||||
| expect(app).toBeTruthy(); | expect(app).toBeTruthy(); | ||||
| }); | }); | ||||
| it(`should have the 'matsen-tool' title`, () => { | |||||
| it(`should have as title 'matsen-tool'`, () => { | |||||
| const fixture = TestBed.createComponent(AppComponent); | const fixture = TestBed.createComponent(AppComponent); | ||||
| const app = fixture.componentInstance; | const app = fixture.componentInstance; | ||||
| expect(app.title).toEqual('matsen-tool'); | expect(app.title).toEqual('matsen-tool'); | ||||
| @@ -1,14 +1,14 @@ | |||||
| import { Component } from '@angular/core'; | import { Component } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | |||||
| import { RouterOutlet } from '@angular/router'; | |||||
| // import { PostService } from './core/api/v1'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-root', | selector: 'app-root', | ||||
| standalone: true, | |||||
| imports: [CommonModule, RouterOutlet], | |||||
| templateUrl: './app.component.html', | templateUrl: './app.component.html', | ||||
| styleUrl: './app.component.scss' | styleUrl: './app.component.scss' | ||||
| }) | }) | ||||
| export class AppComponent { | export class AppComponent { | ||||
| title = 'matsen-tool'; | title = 'matsen-tool'; | ||||
| // posts$ = this.postService.postsGetCollection(); | |||||
| // constructor(private postService: PostService) {} | |||||
| } | } | ||||
| @@ -1,11 +0,0 @@ | |||||
| 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); | |||||
| @@ -1,10 +0,0 @@ | |||||
| 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,14 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { ServerModule } from '@angular/platform-server'; | |||||
| import { AppModule } from './app.module'; | |||||
| import { AppComponent } from './app.component'; | |||||
| @NgModule({ | |||||
| imports: [ | |||||
| AppModule, | |||||
| ServerModule, | |||||
| ], | |||||
| bootstrap: [AppComponent], | |||||
| }) | |||||
| export class AppServerModule {} | |||||
| @@ -0,0 +1,36 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { BrowserModule, provideClientHydration } from '@angular/platform-browser'; | |||||
| import { AppRoutingModule } from './app-routing.module'; | |||||
| import { AppComponent } from './app.component'; | |||||
| import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; | |||||
| import {ApiModule, Configuration, ConfigurationParameters} from "./core/api/v1"; | |||||
| import {HttpClientModule} from "@angular/common/http"; | |||||
| import {environment} from "../environment"; | |||||
| import { LoginModule } from './login/login.module'; | |||||
| export function apiConfigFactory(): Configuration { | |||||
| const params: ConfigurationParameters = { | |||||
| basePath: environment.basePath, | |||||
| }; | |||||
| return new Configuration(params); | |||||
| } | |||||
| @NgModule({ | |||||
| declarations: [ | |||||
| AppComponent | |||||
| ], | |||||
| imports: [ | |||||
| BrowserModule, | |||||
| ApiModule.forRoot(apiConfigFactory), | |||||
| HttpClientModule, | |||||
| AppRoutingModule, | |||||
| BrowserAnimationsModule, | |||||
| LoginModule | |||||
| ], | |||||
| providers: [ | |||||
| provideClientHydration() | |||||
| ], | |||||
| bootstrap: [AppComponent] | |||||
| }) | |||||
| export class AppModule { } | |||||
| @@ -1,3 +0,0 @@ | |||||
| import { Routes } from '@angular/router'; | |||||
| export const routes: Routes = []; | |||||
| @@ -0,0 +1,18 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { CommonModule } from '@angular/common'; | |||||
| import { LoginComponent } from './login/login.component'; | |||||
| @NgModule({ | |||||
| declarations: [ | |||||
| LoginComponent | |||||
| ], | |||||
| exports: [ | |||||
| LoginComponent | |||||
| ], | |||||
| imports: [ | |||||
| CommonModule | |||||
| ] | |||||
| }) | |||||
| export class LoginModule { } | |||||
| @@ -0,0 +1 @@ | |||||
| <p>login works!</p> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { LoginComponent } from './login.component'; | |||||
| describe('LoginComponent', () => { | |||||
| let component: LoginComponent; | |||||
| let fixture: ComponentFixture<LoginComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [LoginComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(LoginComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,10 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-login', | |||||
| templateUrl: './login.component.html', | |||||
| styleUrl: './login.component.scss' | |||||
| }) | |||||
| export class LoginComponent { | |||||
| } | |||||
| @@ -0,0 +1,11 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { RouterModule, Routes } from '@angular/router'; | |||||
| import { TestComponent } from './test.component'; | |||||
| const routes: Routes = [{ path: '', component: TestComponent }]; | |||||
| @NgModule({ | |||||
| imports: [RouterModule.forChild(routes)], | |||||
| exports: [RouterModule] | |||||
| }) | |||||
| export class TestRoutingModule { } | |||||
| @@ -0,0 +1 @@ | |||||
| <p>test works!</p> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { TestComponent } from './test.component'; | |||||
| describe('TestComponent', () => { | |||||
| let component: TestComponent; | |||||
| let fixture: ComponentFixture<TestComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [TestComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(TestComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,10 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-test', | |||||
| templateUrl: './test.component.html', | |||||
| styleUrl: './test.component.scss' | |||||
| }) | |||||
| export class TestComponent { | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { CommonModule } from '@angular/common'; | |||||
| import { TestRoutingModule } from './test-routing.module'; | |||||
| import { TestComponent } from './test.component'; | |||||
| @NgModule({ | |||||
| declarations: [ | |||||
| TestComponent | |||||
| ], | |||||
| imports: [ | |||||
| CommonModule, | |||||
| TestRoutingModule | |||||
| ] | |||||
| }) | |||||
| export class TestModule { } | |||||
| @@ -0,0 +1,4 @@ | |||||
| export const environment = { | |||||
| production: true, | |||||
| basePath: 'https://jsonplaceholder.typicode.com', | |||||
| }; | |||||
| @@ -0,0 +1,4 @@ | |||||
| export const environment = { | |||||
| production: false, | |||||
| basePath: 'https://matsen-tool-be.ddev.site:8443', | |||||
| }; | |||||
| @@ -1,7 +1 @@ | |||||
| 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; | |||||
| export { AppServerModule as default } from './app/app.module.server'; | |||||
| @@ -1,6 +1,7 @@ | |||||
| import { bootstrapApplication } from '@angular/platform-browser'; | |||||
| import { appConfig } from './app/app.config'; | |||||
| import { AppComponent } from './app/app.component'; | |||||
| import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; | |||||
| bootstrapApplication(AppComponent, appConfig) | |||||
| .catch((err) => console.error(err)); | |||||
| import { AppModule } from './app/app.module'; | |||||
| platformBrowserDynamic().bootstrapModule(AppModule) | |||||
| .catch(err => console.error(err)); | |||||
| @@ -9,6 +9,7 @@ | |||||
| "noPropertyAccessFromIndexSignature": true, | "noPropertyAccessFromIndexSignature": true, | ||||
| "noImplicitReturns": true, | "noImplicitReturns": true, | ||||
| "noFallthroughCasesInSwitch": true, | "noFallthroughCasesInSwitch": true, | ||||
| "skipLibCheck": true, | |||||
| "esModuleInterop": true, | "esModuleInterop": true, | ||||
| "sourceMap": true, | "sourceMap": true, | ||||
| "declaration": false, | "declaration": false, | ||||