From bdd4f2cb74845b43aab14f80f3c18bc9840a1e96 Mon Sep 17 00:00:00 2001 From: Thomas Hansen Date: Tue, 9 Jan 2024 16:11:00 +0200 Subject: [PATCH] b --- .../ide-tree/ide-tree.component.html | 13 ++- .../components/ide-tree/ide-tree.component.ts | 34 +++++++- ...penapi-specification-dialog.component.html | 30 +++++++ ...penapi-specification-dialog.component.scss | 10 +++ .../openapi-specification-dialog.component.ts | 37 ++++++++ .../create/hyper-ide/module/ide.module.ts | 2 + frontend/src/app/services/crudify.service.ts | 84 ------------------- frontend/src/app/services/endpoint.service.ts | 23 +++++ 8 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.html create mode 100644 frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.scss create mode 100644 frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.ts diff --git a/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.html b/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.html index e574ffb313..b93e899643 100644 --- a/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.html +++ b/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.html @@ -28,7 +28,16 @@ mat-icon-button color="primary" class="tree-action-btn" - title="New file..." + title="Copy OpenAPI specification URL" + (click)="copyOpenAPISpecificationUrl()"> + http + + + @@ -37,7 +46,7 @@ mat-icon-button color="primary" class="tree-action-btn" - title="New folder..." + title="New folder ..." (click)="createNewFileObject('folder')"> create_new_folder diff --git a/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.ts b/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.ts index 6de8bf57cb..bb06f6b8c2 100644 --- a/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.ts +++ b/frontend/src/app/components/protected/create/hyper-ide/components/ide-tree/ide-tree.component.ts @@ -16,12 +16,15 @@ import { FileNode } from '../../models/file-node.model'; import { FileService } from 'src/app/services/file.service'; import { GeneralService } from 'src/app/services/general.service'; import { WorkflowService } from 'src/app/services/workflow.service'; +import { EndpointService } from 'src/app/services/endpoint.service'; import { MagicResponse } from 'src/app/models/magic-response.model'; import { CodemirrorActionsService } from 'src/app/services/codemirror-actions.service'; +import { ParametriseActionDialog } from '../parametrise-action-dialog/parametrise-action-dialog.component'; +import { OpenAPISpecifictionDialogComponent } from '../openapi-specification-dialog/openapi-specification-dialog.component'; import { ConfirmationDialogComponent } from 'src/app/components/protected/common/confirmation-dialog/confirmation-dialog.component'; import { NewFileFolderDialogComponent } from 'src/app/components/protected/create/hyper-ide/components/new-file-folder-dialog/new-file-folder-dialog.component'; import { IncompatibleFileDialogComponent } from 'src/app/components/protected/create/hyper-ide/components/incompatible-file-dialog/incompatible-file-dialog.component'; -import { ParametriseActionDialog } from '../parametrise-action-dialog/parametrise-action-dialog.component'; +import { BackendService } from 'src/app/services/backend.service'; /** * Tree component for Hyper IDE displaying files and folders, allowing user @@ -67,7 +70,9 @@ export class IdeTreeComponent implements OnInit { private dialog: MatDialog, private fileService: FileService, private cdr: ChangeDetectorRef, + private endpointSerivce: EndpointService, private workflowService: WorkflowService, + private backendService: BackendService, private generalService: GeneralService, private codemirrorActionsService: CodemirrorActionsService) { } @@ -95,6 +100,33 @@ export class IdeTreeComponent implements OnInit { }); } + copyOpenAPISpecificationUrl() { + + this.generalService.showLoading(); + this.endpointSerivce.getOpenAPISpecification(this.activeFolder).subscribe({ + + next: (result: any) => { + + this.generalService.hideLoading(); + this.dialog.open(OpenAPISpecifictionDialogComponent, { + width: '750px', + maxWidth: '80vw', + autoFocus: true, + data: { + json: JSON.stringify(result, null, 2), + url: this.backendService.active.url + '/magic/system/endpoints/openapi?system=true&filter=' + this.activeFolder, + } + }); + }, + + error: (error: any) => { + + this.generalService.hideLoading(); + this.generalService.showFeedback(error?.error?.message ?? error, 'errorMessage', 'Ok', 4000); + } + }); + } + /** * Returns true if currently open file is a Hyperlambda file. */ diff --git a/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.html b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.html new file mode 100644 index 0000000000..39335c4cc8 --- /dev/null +++ b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.html @@ -0,0 +1,30 @@ +

OpenAPI Specification for endpoints

+ +
+ +
+ {{data.url}} +
+ +

+  
+
+ +
+ + + + + +
\ No newline at end of file diff --git a/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.scss b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.scss new file mode 100644 index 0000000000..2be8e870a6 --- /dev/null +++ b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.scss @@ -0,0 +1,10 @@ +pre.result { + color: #fafafa; + border-radius: 5px; + box-shadow: 3px 3px 5px rgba(0,0,0,.2); + height: 400px; + margin: 0; + text-wrap:wrap; + padding: 1rem; + overflow: auto; +} diff --git a/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.ts b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.ts new file mode 100644 index 0000000000..2f0deb072d --- /dev/null +++ b/frontend/src/app/components/protected/create/hyper-ide/components/openapi-specification-dialog/openapi-specification-dialog.component.ts @@ -0,0 +1,37 @@ + +/* + * Copyright (c) 2023 Thomas Hansen - For license inquiries you can contact thomas@ainiro.io. + */ + +// Angular and system imports. +import { Clipboard } from '@angular/cdk/clipboard'; +import { Component, Inject, OnInit } from '@angular/core'; + +// Application specific imports. +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { GeneralService } from 'src/app/services/general.service'; + +/** + * Modal dialog showing JSON JSON output encapsulating OpenAPI specification. + */ +@Component({ + selector: 'app-openapi-specification-dialog', + templateUrl: './openapi-specification-dialog.component.html', + styleUrls: ['./openapi-specification-dialog.component.scss'] +}) +export class OpenAPISpecifictionDialogComponent { + + /** + * Creates an instance of your component. + */ + constructor( + private clipBoard: Clipboard, + private generalService: GeneralService, + @Inject(MAT_DIALOG_DATA) public data: any) { } + + copy() { + + this.clipBoard.copy(this.data.json); + this.generalService.showFeedback('You can find the content on your clipboard', 'successMessage'); + } +} diff --git a/frontend/src/app/components/protected/create/hyper-ide/module/ide.module.ts b/frontend/src/app/components/protected/create/hyper-ide/module/ide.module.ts index 6235f1cd26..6548f4594f 100644 --- a/frontend/src/app/components/protected/create/hyper-ide/module/ide.module.ts +++ b/frontend/src/app/components/protected/create/hyper-ide/module/ide.module.ts @@ -38,6 +38,7 @@ import { FormlyAutocompleteTextareaComponent } from '../components/parametrise-a import { ExecuteFeedbackDialog } from '../components/execute-feedback-dialog/execute-feedback-dialog.component'; import { FormlyWorkflowComponent } from '../components/parametrise-action-dialog/components/formly-workflow/formly-workflow.component'; import { FormlyActionComponent } from '../components/parametrise-action-dialog/components/formly-action/formly-action.component'; +import { OpenAPISpecifictionDialogComponent } from '../components/openapi-specification-dialog/openapi-specification-dialog.component'; @NgModule({ declarations: [ @@ -63,6 +64,7 @@ import { FormlyActionComponent } from '../components/parametrise-action-dialog/c CreateKeyValueDialogComponent, CreateArrayDialogComponent, ExecuteFeedbackDialog, + OpenAPISpecifictionDialogComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/services/crudify.service.ts b/frontend/src/app/services/crudify.service.ts index 8efc80b910..e8bec4149d 100644 --- a/frontend/src/app/services/crudify.service.ts +++ b/frontend/src/app/services/crudify.service.ts @@ -28,20 +28,13 @@ export class CrudifyService { /** * Creates an instance of your service. - * - * @param httpService HTTP service to use for backend invocations - * @param feedbackService Needed to provide feedback to user - * @param locale Needed to format strings according to locale */ constructor( private httpService: HttpService, - private generalService: GeneralService, @Inject(LOCALE_ID) public locale: string) { } /** * Crudifies a database table for a specified HTTP verb. - * - * @param data Input for process */ crudify(data: Crudify) { @@ -66,86 +59,9 @@ export class CrudifyService { /** * Generates an SQL endpoint for a specified HTTP verb. - * - * @param data Input for process */ generateSqlEndpoint(data: CustomSql) { return this.httpService.post('/magic/system/crudifier/custom-sql', data); } - - /** - * Returns a list of all templates the backend has stored. - */ - templates() { - - return this.httpService.get('/magic/system/crudifier/templates'); - } - - /** - * Returns the custom arguments associated with the specified template. - * - * @param name Name of template to retrieve custom arguments for - */ - templateCustomArgs(name: string) { - - return this.httpService.get('/magic/system/crudifier/template-args?name=' + encodeURIComponent(name)); - } - - /** - * Generates a frontend and downloads to client as a ZIP file. - * - * @param templateName Name of template to use - * @param apiUrl API root URL to use when generating template - * @param frontendUrl Frontend URL of where app is supposed to be deployed - * @param email Email address of user required to renew SSL certificate - * @param name Name of application - * @param copyright Copyright notice to put at top of all files - * @param endpoints Endpoints you want to embed into your result - * @param deployLocally If true frontend is deployed locally on server - * @param args Custom args endpoint requires - * @param onAfter Callback to be invoked once process is done - */ - generate( - templateName: string, - apiUrl: string, - name: string, - copyright: string, - endpoints: any[], - deployLocally: boolean, - args: any, - onAfter: () => void = null, - onError: () => void = null) { - - const payload = { - templateName, - apiUrl, - name, - copyright, - endpoints, - deployLocally, - args - }; - - this.httpService.downloadPost('/magic/system/crudifier/generate-frontend', payload).subscribe({ - next: (res) => { - - const disp = res.headers.get('Content-Disposition'); - if (disp) { - let filename = disp.split(';')[1].trim().split('=')[1].replace(/"/g, ''); - const file = new Blob([res.body]); - saveAs(file, filename); - } - if (onAfter) { - onAfter(); - } - }, - error: () => { - - if (onError) { - onError(); - } - } - }); - } } diff --git a/frontend/src/app/services/endpoint.service.ts b/frontend/src/app/services/endpoint.service.ts index 56dd9cb083..626c879eeb 100644 --- a/frontend/src/app/services/endpoint.service.ts +++ b/frontend/src/app/services/endpoint.service.ts @@ -26,6 +26,9 @@ export class EndpointService { return this.httpService.get('/magic/system/endpoints/list'); } + /** + * Invokes URL using HTTP GET verb. + */ get(url: string, responseType: string = 'json') { return this.httpService.get(url, { @@ -34,6 +37,9 @@ export class EndpointService { }); } + /** + * Invokes URL using HTTP DELETE verb. + */ delete(url: string, responseType: string = 'json') { return this.httpService.delete(url, { @@ -42,6 +48,9 @@ export class EndpointService { }); } + /** + * Invokes URL using HTTP POST verb. + */ post(url: string, args: any, responseType: string = 'json') { return this.httpService.post(url, args, { @@ -50,6 +59,9 @@ export class EndpointService { }); } + /** + * Invokes URL using HTTP PUT verb. + */ put(url: string, args: any, responseType: string = 'json') { return this.httpService.put(url, args, { @@ -58,6 +70,9 @@ export class EndpointService { }); } + /** + * Invokes URL using HTTP PATCH verb. + */ patch(url: string, args: any, responseType: string = 'json') { return this.httpService.patch(url, args, { @@ -65,4 +80,12 @@ export class EndpointService { responseType, }); } + + /** + * Returns OpenAPI specification for the specified folder. + */ + getOpenAPISpecification(folder: string) { + + return this.httpService.get('/magic/system/endpoints/openapi?system=true&filter=' + encodeURIComponent(folder)); + } }