mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Add /devfile PUT and GET endpoints (#6950)
* Serve /devfile * Implement /devfile endpoints * Load/Save devfile from UI * Required metadata fields in the response * Add an Apply button on 1st tab * Fix: validate new devfile, not previous one * Add generated UI files to gitattributes file * Fix rebase
This commit is contained in:
3
ui/src/app/api-gen/.openapi-generator/FILES
generated
3
ui/src/app/api-gen/.openapi-generator/FILES
generated
@@ -14,6 +14,8 @@ model/componentGet200Response.ts
|
||||
model/compositeCommand.ts
|
||||
model/container.ts
|
||||
model/devfileContent.ts
|
||||
model/devfileGet200Response.ts
|
||||
model/devfilePutRequest.ts
|
||||
model/devstateApplyCommandPostRequest.ts
|
||||
model/devstateChartGet200Response.ts
|
||||
model/devstateCommandCommandNameMovePostRequest.ts
|
||||
@@ -34,6 +36,7 @@ model/image.ts
|
||||
model/imageCommand.ts
|
||||
model/instanceGet200Response.ts
|
||||
model/metadata.ts
|
||||
model/metadataRequest.ts
|
||||
model/models.ts
|
||||
model/resource.ts
|
||||
param.ts
|
||||
|
||||
137
ui/src/app/api-gen/api/default.service.ts
generated
137
ui/src/app/api-gen/api/default.service.ts
generated
@@ -25,6 +25,10 @@ import { ComponentGet200Response } from '../model/componentGet200Response';
|
||||
// @ts-ignore
|
||||
import { DevfileContent } from '../model/devfileContent';
|
||||
// @ts-ignore
|
||||
import { DevfileGet200Response } from '../model/devfileGet200Response';
|
||||
// @ts-ignore
|
||||
import { DevfilePutRequest } from '../model/devfilePutRequest';
|
||||
// @ts-ignore
|
||||
import { DevstateApplyCommandPostRequest } from '../model/devstateApplyCommandPostRequest';
|
||||
// @ts-ignore
|
||||
import { DevstateChartGet200Response } from '../model/devstateChartGet200Response';
|
||||
@@ -55,7 +59,7 @@ import { GeneralSuccess } from '../model/generalSuccess';
|
||||
// @ts-ignore
|
||||
import { InstanceGet200Response } from '../model/instanceGet200Response';
|
||||
// @ts-ignore
|
||||
import { Metadata } from '../model/metadata';
|
||||
import { MetadataRequest } from '../model/metadataRequest';
|
||||
|
||||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||
@@ -246,6 +250,125 @@ export class DefaultService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw content of the Devfile used by the current dev session
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public devfileGet(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<DevfileGet200Response>;
|
||||
public devfileGet(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<DevfileGet200Response>>;
|
||||
public devfileGet(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<DevfileGet200Response>>;
|
||||
public devfileGet(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||
|
||||
let localVarHeaders = this.defaultHeaders;
|
||||
|
||||
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = [
|
||||
'application/json'
|
||||
];
|
||||
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
}
|
||||
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||
if (localVarHttpContext === undefined) {
|
||||
localVarHttpContext = new HttpContext();
|
||||
}
|
||||
|
||||
|
||||
let responseType_: 'text' | 'json' | 'blob' = 'json';
|
||||
if (localVarHttpHeaderAcceptSelected) {
|
||||
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||
responseType_ = 'text';
|
||||
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
|
||||
responseType_ = 'json';
|
||||
} else {
|
||||
responseType_ = 'blob';
|
||||
}
|
||||
}
|
||||
|
||||
let localVarPath = `/devfile`;
|
||||
return this.httpClient.request<DevfileGet200Response>('get', `${this.configuration.basePath}${localVarPath}`,
|
||||
{
|
||||
context: localVarHttpContext,
|
||||
responseType: <any>responseType_,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: localVarHeaders,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Devfile used by the current dev session
|
||||
* @param devfilePutRequest
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public devfilePut(devfilePutRequest?: DevfilePutRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<GeneralSuccess>;
|
||||
public devfilePut(devfilePutRequest?: DevfilePutRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<GeneralSuccess>>;
|
||||
public devfilePut(devfilePutRequest?: DevfilePutRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<GeneralSuccess>>;
|
||||
public devfilePut(devfilePutRequest?: DevfilePutRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||
|
||||
let localVarHeaders = this.defaultHeaders;
|
||||
|
||||
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = [
|
||||
'application/json'
|
||||
];
|
||||
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
}
|
||||
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||
if (localVarHttpContext === undefined) {
|
||||
localVarHttpContext = new HttpContext();
|
||||
}
|
||||
|
||||
|
||||
// to determine the Content-Type header
|
||||
const consumes: string[] = [
|
||||
'application/json'
|
||||
];
|
||||
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||
if (httpContentTypeSelected !== undefined) {
|
||||
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
let responseType_: 'text' | 'json' | 'blob' = 'json';
|
||||
if (localVarHttpHeaderAcceptSelected) {
|
||||
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||
responseType_ = 'text';
|
||||
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
|
||||
responseType_ = 'json';
|
||||
} else {
|
||||
responseType_ = 'blob';
|
||||
}
|
||||
}
|
||||
|
||||
let localVarPath = `/devfile`;
|
||||
return this.httpClient.request<GeneralSuccess>('put', `${this.configuration.basePath}${localVarPath}`,
|
||||
{
|
||||
context: localVarHttpContext,
|
||||
body: devfilePutRequest,
|
||||
responseType: <any>responseType_,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: localVarHeaders,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Apply Command to the Devfile
|
||||
* @param devstateApplyCommandPostRequest
|
||||
@@ -1235,14 +1358,14 @@ export class DefaultService {
|
||||
|
||||
/**
|
||||
* Updates the metadata for the Devfile
|
||||
* @param metadata
|
||||
* @param metadataRequest
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public devstateMetadataPut(metadata?: Metadata, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<DevfileContent>;
|
||||
public devstateMetadataPut(metadata?: Metadata, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<DevfileContent>>;
|
||||
public devstateMetadataPut(metadata?: Metadata, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<DevfileContent>>;
|
||||
public devstateMetadataPut(metadata?: Metadata, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||
public devstateMetadataPut(metadataRequest?: MetadataRequest, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<DevfileContent>;
|
||||
public devstateMetadataPut(metadataRequest?: MetadataRequest, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<DevfileContent>>;
|
||||
public devstateMetadataPut(metadataRequest?: MetadataRequest, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<DevfileContent>>;
|
||||
public devstateMetadataPut(metadataRequest?: MetadataRequest, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||
|
||||
let localVarHeaders = this.defaultHeaders;
|
||||
|
||||
@@ -1288,7 +1411,7 @@ export class DefaultService {
|
||||
return this.httpClient.request<DevfileContent>('put', `${this.configuration.basePath}${localVarPath}`,
|
||||
{
|
||||
context: localVarHttpContext,
|
||||
body: metadata,
|
||||
body: metadataRequest,
|
||||
responseType: <any>responseType_,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: localVarHeaders,
|
||||
|
||||
17
ui/src/app/api-gen/model/devfileGet200Response.ts
generated
Normal file
17
ui/src/app/api-gen/model/devfileGet200Response.ts
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* odo dev
|
||||
* API interface for \'odo dev\'
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
export interface DevfileGet200Response {
|
||||
content?: string;
|
||||
}
|
||||
|
||||
17
ui/src/app/api-gen/model/devfilePutRequest.ts
generated
Normal file
17
ui/src/app/api-gen/model/devfilePutRequest.ts
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* odo dev
|
||||
* API interface for \'odo dev\'
|
||||
*
|
||||
* The version of the OpenAPI document: 0.1
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
export interface DevfilePutRequest {
|
||||
content: string;
|
||||
}
|
||||
|
||||
26
ui/src/app/api-gen/model/metadata.ts
generated
26
ui/src/app/api-gen/model/metadata.ts
generated
@@ -12,18 +12,18 @@
|
||||
|
||||
|
||||
export interface Metadata {
|
||||
name?: string;
|
||||
version?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
tags?: string;
|
||||
architectures?: string;
|
||||
icon?: string;
|
||||
globalMemoryLimit?: string;
|
||||
projectType?: string;
|
||||
language?: string;
|
||||
website?: string;
|
||||
provider?: string;
|
||||
supportUrl?: string;
|
||||
name: string;
|
||||
version: string;
|
||||
displayName: string;
|
||||
description: string;
|
||||
tags: string;
|
||||
architectures: string;
|
||||
icon: string;
|
||||
globalMemoryLimit: string;
|
||||
projectType: string;
|
||||
language: string;
|
||||
website: string;
|
||||
provider: string;
|
||||
supportUrl: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
|
||||
export interface DevstateMetadataPutRequest {
|
||||
export interface MetadataRequest {
|
||||
name?: string;
|
||||
version?: string;
|
||||
displayName?: string;
|
||||
3
ui/src/app/api-gen/model/models.ts
generated
3
ui/src/app/api-gen/model/models.ts
generated
@@ -5,6 +5,8 @@ export * from './componentGet200Response';
|
||||
export * from './compositeCommand';
|
||||
export * from './container';
|
||||
export * from './devfileContent';
|
||||
export * from './devfileGet200Response';
|
||||
export * from './devfilePutRequest';
|
||||
export * from './devstateApplyCommandPostRequest';
|
||||
export * from './devstateChartGet200Response';
|
||||
export * from './devstateCommandCommandNameMovePostRequest';
|
||||
@@ -25,4 +27,5 @@ export * from './image';
|
||||
export * from './imageCommand';
|
||||
export * from './instanceGet200Response';
|
||||
export * from './metadata';
|
||||
export * from './metadataRequest';
|
||||
export * from './resource';
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
<mat-label>Devfile YAML</mat-label>
|
||||
<textarea data-cy="yaml-input" matInput #input id="input" rows="20" [value]="devfileYaml"></textarea>
|
||||
</mat-form-field>
|
||||
<button data-cy="yaml-save" mat-flat-button color="primary" (click)="onButtonClick(input.value)">Save</button>
|
||||
<button data-cy="yaml-clear" mat-flat-button color="warn" (click)="clear()">Clear</button>
|
||||
<button data-cy="yaml-send" matTooltip="Save Devfile to disk" mat-flat-button color="primary" (click)="onButtonClick(input.value, true)">Save</button>
|
||||
<button data-cy="yaml-save" matTooltip="Apply changes to other tabs" mat-flat-button color="normal" (click)="onButtonClick(input.value, false)">Apply</button>
|
||||
<button data-cy="yaml-clear" matTooltip="Clear Devfile content" mat-flat-button color="normal" (click)="clear()">Clear</button>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { MermaidService } from './services/mermaid.service';
|
||||
import { StateService } from './services/state.service';
|
||||
import { MatIconRegistry } from "@angular/material/icon";
|
||||
import { OdoapiService } from './services/odoapi.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -20,6 +21,7 @@ export class AppComponent implements OnInit {
|
||||
protected sanitizer: DomSanitizer,
|
||||
private matIconRegistry: MatIconRegistry,
|
||||
private wasmGo: DevstateService,
|
||||
private odoApi: OdoapiService,
|
||||
private mermaid: MermaidService,
|
||||
private state: StateService,
|
||||
) {
|
||||
@@ -35,10 +37,12 @@ export class AppComponent implements OnInit {
|
||||
loading.style.visibility = "hidden";
|
||||
}
|
||||
|
||||
const devfile = this.wasmGo.getDevfileContent();
|
||||
const devfile = this.odoApi.getDevfile();
|
||||
devfile.subscribe({
|
||||
next: (devfile) => {
|
||||
this.onButtonClick(devfile.content);
|
||||
if (devfile.content != undefined) {
|
||||
this.onButtonClick(devfile.content, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -62,12 +66,20 @@ export class AppComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
onButtonClick(content: string){
|
||||
onButtonClick(content: string, save: boolean){
|
||||
const result = this.wasmGo.setDevfileContent(content);
|
||||
result.subscribe({
|
||||
next: (value) => {
|
||||
this.errorMessage = '';
|
||||
this.state.changeDevfileYaml(value);
|
||||
this.state.changeDevfileYaml(value);
|
||||
if (save) {
|
||||
this.odoApi.saveDevfile(value.content).subscribe({
|
||||
next: () => {},
|
||||
error: (error) => {
|
||||
this.errorMessage = error.error.message;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
this.errorMessage = error.error.message;
|
||||
@@ -79,7 +91,7 @@ export class AppComponent implements OnInit {
|
||||
if (confirm('You will delete the content of the Devfile. Continue?')) {
|
||||
this.wasmGo.clearDevfileContent().subscribe({
|
||||
next: (value) => {
|
||||
this.onButtonClick(value.content);
|
||||
this.onButtonClick(value.content, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,5 +64,5 @@
|
||||
</mat-form-field>
|
||||
</form>
|
||||
|
||||
<button [disabled]="form.invalid" mat-flat-button color="primary" (click)="onSave()">Save</button>
|
||||
<button [disabled]="form.invalid" mat-flat-button color="primary" (click)="onSave()">Apply</button>
|
||||
</div>
|
||||
|
||||
16
ui/src/app/services/odoapi.service.spec.ts
Normal file
16
ui/src/app/services/odoapi.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OdoapiService } from './odoapi.service';
|
||||
|
||||
describe('OdoapiService', () => {
|
||||
let service: OdoapiService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(OdoapiService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
24
ui/src/app/services/odoapi.service.ts
Normal file
24
ui/src/app/services/odoapi.service.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DevfileGet200Response, GeneralSuccess } from '../api-gen';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class OdoapiService {
|
||||
|
||||
private base = "/api/v1";
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
getDevfile(): Observable<DevfileGet200Response> {
|
||||
return this.http.get<DevfileGet200Response>(this.base+"/devfile");
|
||||
}
|
||||
|
||||
saveDevfile(content: string): Observable<GeneralSuccess> {
|
||||
return this.http.put<GeneralSuccess>(this.base+"/devfile", {
|
||||
content: content
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user