From 5663123eb9d2cac73d1925791a5649a850a413b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Couzini=C3=A9?= <couzinie@cines.fr>
Date: Sun, 15 Nov 2020 15:00:15 +0100
Subject: [PATCH] Added form to describe repository's openapi

---
 package-lock.json                             |   5 +
 package.json                                  |   1 +
 src/app/accessapi/accessapi.component.html    |  15 +-
 src/app/app.module.ts                         |  25 +-
 src/app/publishapi/class/http-enum.ts         | 394 ++++++++++++++++++
 src/app/publishapi/class/openapi-dto.ts       |  60 +++
 src/app/publishapi/class/openapi-enum.ts      |  13 +
 src/app/publishapi/class/openapi.ts           |  61 +++
 src/app/publishapi/publishapi.component.html  | 223 +++++++++-
 src/app/publishapi/publishapi.component.scss  |  63 ++-
 src/app/publishapi/publishapi.component.ts    |  82 +++-
 .../services/openapi-dto-mapping-service.ts   |  90 ++++
 .../publishapi/services/openapi-service.ts    | 349 ++++++++++++++++
 src/app/repository/repository.component.html  |  17 +-
 src/styles.scss                               |   3 +-
 15 files changed, 1355 insertions(+), 46 deletions(-)
 create mode 100644 src/app/publishapi/class/http-enum.ts
 create mode 100644 src/app/publishapi/class/openapi-dto.ts
 create mode 100644 src/app/publishapi/class/openapi-enum.ts
 create mode 100644 src/app/publishapi/class/openapi.ts
 create mode 100644 src/app/publishapi/services/openapi-dto-mapping-service.ts
 create mode 100644 src/app/publishapi/services/openapi-service.ts

diff --git a/package-lock.json b/package-lock.json
index 239cbbc2d..69adfc8fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3157,6 +3157,11 @@
       "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
       "dev": true
     },
+    "@types/lodash": {
+      "version": "4.14.165",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz",
+      "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg=="
+    },
     "@types/minimatch": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
diff --git a/package.json b/package.json
index 9c7fbc243..af389bb3d 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
     "@angular/compiler": "~9.1.11",
     "@angular/core": "~9.1.11",
     "@angular/forms": "~9.1.11",
+    "@types/lodash": "^4.14.165",
     "@angular/material": "^9.2.4",
     "@angular/platform-browser": "~9.1.11",
     "@angular/platform-browser-dynamic": "~9.1.11",
diff --git a/src/app/accessapi/accessapi.component.html b/src/app/accessapi/accessapi.component.html
index 6da8eb4e6..9ce046658 100644
--- a/src/app/accessapi/accessapi.component.html
+++ b/src/app/accessapi/accessapi.component.html
@@ -6,14 +6,12 @@
   <label>Or describe your repository and save a new file for publishing in the FDP database:</label><br>
 
   <div class="form-group">
-    <label>title
-      <input type="text" class="form-control" formControlName="title" required>
-    </label>
+    <label>title</label>
+    <input type="text" class="form-control" formControlName="title" required>
   </div>
   <div class="form-group">
-    <label>Description
-      <textarea  class="form-control" formControlName="description"></textarea>
-    </label>
+    <label>Description</label>
+    <textarea  class="form-control" formControlName="description"></textarea>
   </div>
   <div class="form-group">
     <label>version</label>
@@ -24,9 +22,8 @@
     <input  type="text" class="form-control" formControlName="url">
   </div>
   <div class="form-group">
-    <label>Description
-      <textarea  class="form-control" formControlName="urldescription"></textarea>
-    </label>
+    <label>Description</label>
+    <textarea  class="form-control" formControlName="urldescription"></textarea>
   </div>
   <div class="form-group">
     <label>paths</label>
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index a88ee54d8..2f073af7f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -32,9 +32,19 @@ import { ElasticsearchComponent } from './elasticsearch/elasticsearch.component'
 import { PublishApiComponent } from './publishapi/publishapi.component';
 import { SearchComponent } from './search/search.component'
 import { ParseXmlService } from './services/parse-xml.service';
+<<<<<<< HEAD
 
 import { AuthenticationComponent } from './authentication/authentication.component';
 import { AuthenticationModule } from './authentication/authentication.module';
+=======
+import { NbMenuModule,
+  NbThemeModule,NbStepperModule,
+  NbCardModule, NbSidebarModule, NbLayoutModule,
+  NbButtonModule, NbIconModule, NbInputModule, NbContextMenuModule, NbUserModule, NbSpinnerModule, NbSelectModule, NbTabsetModule, NbTooltipModule  } from '@nebular/theme/';
+import { NbEvaIconsModule } from '@nebular/eva-icons';
+import { AccountComponent } from './account/account.component';
+import { AccountModule } from './account/account.module';
+>>>>>>> Added form to describe repository's openapi
 import { SearchModule} from './search/search.module';
 import { StatsComponent } from './stats/stats.component';
 import { NebularModule } from './nebular.module';
@@ -79,20 +89,27 @@ import { DashboardComponent } from './dashboard/dashboard.component';
     HttpClientModule,
     FileSaverModule,
     SearchModule,
+<<<<<<< HEAD
     AppRoutingModule,
     AuthenticationModule,
     NebularModule,    
     BrowserAnimationsModule,
     NbThemeModule.forRoot({ name: 'default' }),
     NbLayoutModule
+=======
+    NbSpinnerModule,
+    NbSelectModule,
+    NbTabsetModule,
+    NbTooltipModule
+>>>>>>> Added form to describe repository's openapi
   ],
 
   providers: [
     AppConfiguration,
     ParseXmlService,
-    { 
-        provide: APP_INITIALIZER, 
-        useFactory: AppConfigurationFactory, 
+    {
+        provide: APP_INITIALIZER,
+        useFactory: AppConfigurationFactory,
         deps: [AppConfiguration, HttpClient], multi: true },
   ],
   bootstrap: [AppComponent]
@@ -101,4 +118,4 @@ export class AppModule { }
 
 export function AppConfigurationFactory(appConfig: AppConfiguration) {
     return () => appConfig.ensureInit();
-  }
\ No newline at end of file
+  }
diff --git a/src/app/publishapi/class/http-enum.ts b/src/app/publishapi/class/http-enum.ts
new file mode 100644
index 000000000..1fcdd1423
--- /dev/null
+++ b/src/app/publishapi/class/http-enum.ts
@@ -0,0 +1,394 @@
+"use strict";
+
+export enum HttpMethod {
+    GET = 'GET',
+    POST = 'POST',
+    PUT = 'PUT',
+    PATCH = 'PATCH',
+    DELETE = 'DELETE',
+    HEAD = 'HEAD',
+    OPTIONS = 'OPTIONS'
+}
+
+
+/**
+ * Hypertext Transfer Protocol (HTTP) response status codes.
+ * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
+ */
+enum HttpStatusCode {
+
+    /**
+     * The server has received the request headers and the client should proceed to send the request body
+     * (in the case of a request for which a body needs to be sent; for example, a POST request).
+     * Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
+     * To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
+     * and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
+     */
+    CONTINUE = 100,
+
+    /**
+     * The requester has asked the server to switch protocols and the server has agreed to do so.
+     */
+    SWITCHING_PROTOCOLS = 101,
+
+    /**
+     * A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
+     * This code indicates that the server has received and is processing the request, but no response is available yet.
+     * This prevents the client from timing out and assuming the request was lost.
+     */
+    PROCESSING = 102,
+
+    /**
+     * Standard response for successful HTTP requests.
+     * The actual response will depend on the request method used.
+     * In a GET request, the response will contain an entity corresponding to the requested resource.
+     * In a POST request, the response will contain an entity describing or containing the result of the action.
+     */
+    OK = 200,
+
+    /**
+     * The request has been fulfilled, resulting in the creation of a new resource.
+     */
+    CREATED = 201,
+
+    /**
+     * The request has been accepted for processing, but the processing has not been completed.
+     * The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
+     */
+    ACCEPTED = 202,
+
+    /**
+     * SINCE HTTP/1.1
+     * The server is a transforming proxy that received a 200 OK from its origin,
+     * but is returning a modified version of the origin's response.
+     */
+    NON_AUTHORITATIVE_INFORMATION = 203,
+
+    /**
+     * The server successfully processed the request and is not returning any content.
+     */
+    NO_CONTENT = 204,
+
+    /**
+     * The server successfully processed the request, but is not returning any content.
+     * Unlike a 204 response, this response requires that the requester reset the document view.
+     */
+    RESET_CONTENT = 205,
+
+    /**
+     * The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
+     * The range header is used by HTTP clients to enable resuming of interrupted downloads,
+     * or split a download into multiple simultaneous streams.
+     */
+    PARTIAL_CONTENT = 206,
+
+    /**
+     * The message body that follows is an XML message and can contain a number of separate response codes,
+     * depending on how many sub-requests were made.
+     */
+    MULTI_STATUS = 207,
+
+    /**
+     * The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
+     * and are not being included again.
+     */
+    ALREADY_REPORTED = 208,
+
+    /**
+     * The server has fulfilled a request for the resource,
+     * and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
+     */
+    IM_USED = 226,
+
+    /**
+     * Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
+     * For example, this code could be used to present multiple video format options,
+     * to list files with different filename extensions, or to suggest word-sense disambiguation.
+     */
+    MULTIPLE_CHOICES = 300,
+
+    /**
+     * This and all future requests should be directed to the given URI.
+     */
+    MOVED_PERMANENTLY = 301,
+
+    /**
+     * This is an example of industry practice contradicting the standard.
+     * The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
+     * (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
+     * with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
+     * to distinguish between the two behaviours. However, some Web applications and frameworks
+     * use the 302 status code as if it were the 303.
+     */
+    FOUND = 302,
+
+    /**
+     * SINCE HTTP/1.1
+     * The response to the request can be found under another URI using a GET method.
+     * When received in response to a POST (or PUT/DELETE), the client should presume that
+     * the server has received the data and should issue a redirect with a separate GET message.
+     */
+    SEE_OTHER = 303,
+
+    /**
+     * Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
+     * In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
+     */
+    NOT_MODIFIED = 304,
+
+    /**
+     * SINCE HTTP/1.1
+     * The requested resource is available only through a proxy, the address for which is provided in the response.
+     * Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
+     */
+    USE_PROXY = 305,
+
+    /**
+     * No longer used. Originally meant "Subsequent requests should use the specified proxy."
+     */
+    SWITCH_PROXY = 306,
+
+    /**
+     * SINCE HTTP/1.1
+     * In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
+     * In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
+     * For example, a POST request should be repeated using another POST request.
+     */
+    TEMPORARY_REDIRECT = 307,
+
+    /**
+     * The request and all future requests should be repeated using another URI.
+     * 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
+     * So, for example, submitting a form to a permanently redirected resource may continue smoothly.
+     */
+    PERMANENT_REDIRECT = 308,
+
+    /**
+     * The server cannot or will not process the request due to an apparent client error
+     * (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
+     */
+    BAD_REQUEST = 400,
+
+    /**
+     * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
+     * been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
+     * requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
+     * "unauthenticated",i.e. the user does not have the necessary credentials.
+     */
+    UNAUTHORIZED = 401,
+
+    /**
+     * Reserved for future use. The original intention was that this code might be used as part of some form of digital
+     * cash or micro payment scheme, but that has not happened, and this code is not usually used.
+     * Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
+     */
+    PAYMENT_REQUIRED = 402,
+
+    /**
+     * The request was valid, but the server is refusing action.
+     * The user might not have the necessary permissions for a resource.
+     */
+    FORBIDDEN = 403,
+
+    /**
+     * The requested resource could not be found but may be available in the future.
+     * Subsequent requests by the client are permissible.
+     */
+    NOT_FOUND = 404,
+
+    /**
+     * A request method is not supported for the requested resource;
+     * for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
+     */
+    METHOD_NOT_ALLOWED = 405,
+
+    /**
+     * The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
+     */
+    NOT_ACCEPTABLE = 406,
+
+    /**
+     * The client must first authenticate itself with the proxy.
+     */
+    PROXY_AUTHENTICATION_REQUIRED = 407,
+
+    /**
+     * The server timed out waiting for the request.
+     * According to HTTP specifications:
+     * "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
+     */
+    REQUEST_TIMEOUT = 408,
+
+    /**
+     * Indicates that the request could not be processed because of conflict in the request,
+     * such as an edit conflict between multiple simultaneous updates.
+     */
+    CONFLICT = 409,
+
+    /**
+     * Indicates that the resource requested is no longer available and will not be available again.
+     * This should be used when a resource has been intentionally removed and the resource should be purged.
+     * Upon receiving a 410 status code, the client should not request the resource in the future.
+     * Clients such as search engines should remove the resource from their indices.
+     * Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
+     */
+    GONE = 410,
+
+    /**
+     * The request did not specify the length of its content, which is required by the requested resource.
+     */
+    LENGTH_REQUIRED = 411,
+
+    /**
+     * The server does not meet one of the preconditions that the requester put on the request.
+     */
+    PRECONDITION_FAILED = 412,
+
+    /**
+     * The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
+     */
+    PAYLOAD_TOO_LARGE = 413,
+
+    /**
+     * The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
+     * in which case it should be converted to a POST request.
+     * Called "Request-URI Too Long" previously.
+     */
+    URI_TOO_LONG = 414,
+
+    /**
+     * The request entity has a media type which the server or resource does not support.
+     * For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
+     */
+    UNSUPPORTED_MEDIA_TYPE = 415,
+
+    /**
+     * The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
+     * For example, if the client asked for a part of the file that lies beyond the end of the file.
+     * Called "Requested Range Not Satisfiable" previously.
+     */
+    RANGE_NOT_SATISFIABLE = 416,
+
+    /**
+     * The server cannot meet the requirements of the Expect request-header field.
+     */
+    EXPECTATION_FAILED = 417,
+
+    /**
+     * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
+     * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
+     * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
+     */
+    I_AM_A_TEAPOT = 418,
+
+    /**
+     * The request was directed at a server that is not able to produce a response (for example because a connection reuse).
+     */
+    MISDIRECTED_REQUEST = 421,
+
+    /**
+     * The request was well-formed but was unable to be followed due to semantic errors.
+     */
+    UNPROCESSABLE_ENTITY = 422,
+
+    /**
+     * The resource that is being accessed is locked.
+     */
+    LOCKED = 423,
+
+    /**
+     * The request failed due to failure of a previous request (e.g., a PROPPATCH).
+     */
+    FAILED_DEPENDENCY = 424,
+
+    /**
+     * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
+     */
+    UPGRADE_REQUIRED = 426,
+
+    /**
+     * The origin server requires the request to be conditional.
+     * Intended to prevent "the 'lost update' problem, where a client
+     * GETs a resource's state, modifies it, and PUTs it back to the server,
+     * when meanwhile a third party has modified the state on the server, leading to a conflict."
+     */
+    PRECONDITION_REQUIRED = 428,
+
+    /**
+     * The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
+     */
+    TOO_MANY_REQUESTS = 429,
+
+    /**
+     * The server is unwilling to process the request because either an individual header field,
+     * or all the header fields collectively, are too large.
+     */
+    REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
+
+    /**
+     * A server operator has received a legal demand to deny access to a resource or to a set of resources
+     * that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
+     */
+    UNAVAILABLE_FOR_LEGAL_REASONS = 451,
+
+    /**
+     * A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
+     */
+    INTERNAL_SERVER_ERROR = 500,
+
+    /**
+     * The server either does not recognize the request method, or it lacks the ability to fulfill the request.
+     * Usually this implies future availability (e.g., a new feature of a web-service API).
+     */
+    NOT_IMPLEMENTED = 501,
+
+    /**
+     * The server was acting as a gateway or proxy and received an invalid response from the upstream server.
+     */
+    BAD_GATEWAY = 502,
+
+    /**
+     * The server is currently unavailable (because it is overloaded or down for maintenance).
+     * Generally, this is a temporary state.
+     */
+    SERVICE_UNAVAILABLE = 503,
+
+    /**
+     * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
+     */
+    GATEWAY_TIMEOUT = 504,
+
+    /**
+     * The server does not support the HTTP protocol version used in the request
+     */
+    HTTP_VERSION_NOT_SUPPORTED = 505,
+
+    /**
+     * Transparent content negotiation for the request results in a circular reference.
+     */
+    VARIANT_ALSO_NEGOTIATES = 506,
+
+    /**
+     * The server is unable to store the representation needed to complete the request.
+     */
+    INSUFFICIENT_STORAGE = 507,
+
+    /**
+     * The server detected an infinite loop while processing the request.
+     */
+    LOOP_DETECTED = 508,
+
+    /**
+     * Further extensions to the request are required for the server to fulfill it.
+     */
+    NOT_EXTENDED = 510,
+
+    /**
+     * The client needs to authenticate to gain network access.
+     * Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
+     * to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
+     */
+    NETWORK_AUTHENTICATION_REQUIRED = 511
+}
+
+export default HttpStatusCode;
diff --git a/src/app/publishapi/class/openapi-dto.ts b/src/app/publishapi/class/openapi-dto.ts
new file mode 100644
index 000000000..ec0f1da6f
--- /dev/null
+++ b/src/app/publishapi/class/openapi-dto.ts
@@ -0,0 +1,60 @@
+import HttpStatusCode, { HttpMethod } from './http-enum'
+import { ParameterType, ShemaType } from './openapi-enum';
+
+
+export interface ServerDTO {
+    url:string;
+}
+
+export interface SchemaDTO {
+    type: ShemaType,
+    default: string
+}
+
+export interface ParameterDTO {
+    in: ParameterType,
+    name: string,
+    schema: SchemaDTO
+}
+
+export interface ItemDTO {
+    type: string
+}
+export interface ResponsSchemaDTO {
+    type: string,
+    items: ItemDTO[]
+}
+
+export interface ContentDTO {
+    schema: ResponsSchemaDTO
+}
+
+export type MimeTypeToContentMapDTO = Map<string,ContentDTO>;
+
+export interface ResponseDTO {
+    description: string,
+    content: MimeTypeToContentMapDTO
+}
+
+export type HttpCodeToResponseMapDTO = Map<HttpStatusCode,ResponseDTO>;
+
+export interface RequestDTO {
+    description: string,
+    tags: string[]
+    parameters: ParameterDTO[],
+    responses : HttpCodeToResponseMapDTO[],
+}
+
+export type MethodToRequestMapDTO = Map<HttpMethod,RequestDTO>;
+
+export type PathMapDTO = Map<string,MethodToRequestMapDTO>;
+
+export type InfoMapDTO = Map<string,string>;
+
+export interface OpenApiDTO {
+    openapi: string;
+    info: InfoMapDTO;
+    servers: ServerDTO[];
+    paths: PathMapDTO;
+}
+
diff --git a/src/app/publishapi/class/openapi-enum.ts b/src/app/publishapi/class/openapi-enum.ts
new file mode 100644
index 000000000..54cbf3f14
--- /dev/null
+++ b/src/app/publishapi/class/openapi-enum.ts
@@ -0,0 +1,13 @@
+export enum ShemaType {
+    string = 'string',
+    integer = 'integer',
+    boolean = 'boolean'
+}
+
+export enum ParameterType {
+    query = 'query',
+    path =  'path',
+    header = 'header',
+    cookie = 'cookie',
+    body = 'body'
+}
diff --git a/src/app/publishapi/class/openapi.ts b/src/app/publishapi/class/openapi.ts
new file mode 100644
index 000000000..30d2a7bbb
--- /dev/null
+++ b/src/app/publishapi/class/openapi.ts
@@ -0,0 +1,61 @@
+import HttpStatusCode, { HttpMethod } from './http-enum'
+import { ParameterType } from './openapi-enum';
+
+export interface Server {
+    url:string;
+}
+
+export interface Schema {
+    type: string,
+    default: string
+}
+
+export interface Parameter {
+    in: ParameterType,
+    name: string,
+    schema: Schema
+}
+
+export interface Item {
+    type: string
+}
+
+export interface ResponseSchema {
+    type: string,
+    items: Item[]
+}
+
+export interface Content {
+    contentType: string,
+    schema: ResponseSchema
+}
+
+export interface Response {
+    httpStatusCode: HttpStatusCode,
+    description: string,
+    contents: Content[]
+}
+
+export interface Request {
+    description: string,
+    tags: string[]
+    parameters: Parameter[],
+    responses: Response[],
+    httpmethod: HttpMethod,
+    toggled: boolean
+}
+
+export interface Path {
+    pathName: string,
+    requests: Request[]
+}
+
+export type InfoMap = Map<string,string>;
+
+export interface OpenApi {
+    openapi: string;
+    info: InfoMap;
+    servers: Server[];
+    paths: Path[];
+}
+
diff --git a/src/app/publishapi/publishapi.component.html b/src/app/publishapi/publishapi.component.html
index 1dcac6658..7038e3131 100644
--- a/src/app/publishapi/publishapi.component.html
+++ b/src/app/publishapi/publishapi.component.html
@@ -5,19 +5,216 @@
 
 <nb-card>
     <nb-card-body>
-      <nb-stepper orientation="horizontal" disableStepNavigation>   
+      <nb-stepper orientation="horizontal" disableStepNavigation>
         <nb-step [label]="labelOne">
           <ng-template #labelOne>First step</ng-template>
-          <h4>Describe API </h4>
-          <p class="lorem">
-            Describe your repository api to access datasets                   
-          </p>
-          <label>Choose your Repository
-            <select class="form-control" formControlName="repotype" required>
-              <option value="1">Inrae</option>>
-              <option value="2">Inrae-2</option>>
-            </select>  
-          </label>  
+          <h4>Describe API</h4>
+          <nb-card>
+            <nb-card-body>
+              <nb-tabset>
+                <nb-tab class="header" tabTitle="Headers" tabIcon="file-text-outline">
+                  <div class="field">
+                    <label class="" for="title">Title</label>
+                    <div>
+                      <input name="title" [(ngModel)]="openApi.info.title" fullWidth nbInput/>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="description">Description</label>
+                    <div>
+                      <textarea name="description " [(ngModel)]="openApi.info.description" placeholder="Textarea" fullWidth  nbInput></textarea>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="version">version</label>
+                    <div>
+                      <input name="version" [(ngModel)]="openApi.info.version" fullWidth  nbInput/>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="x-format">x-format</label>
+                    <div>
+                      <input name="x-format" [(ngModel)]="openApi.info['x-format']" fullWidth  nbInput/>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="x-result">x-result</label>
+                    <div>
+                      <input name="x-result" [(ngModel)]="openApi.info['x-result']" fullWidth  nbInput/>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="x-start-param">x-start-param</label>
+                    <div>
+                      <input name="x-start-param" [(ngModel)]="openApi.info['x-start-param']" fullWidth  nbInput/>
+                    </div>
+                  </div>
+                  <div class="field">
+                    <label for="x-page-param">x-page-param</label>
+                    <div>
+                      <input name="x-page-param" [(ngModel)]="openApi.info['x-page-param']" fullWidth  nbInput/>
+                    </div>
+                  </div>
+                </nb-tab>
+                <nb-tab class="main" tabTitle="Main" tabIcon="edit-2-outline">
+                  <div *ngFor="let path of openApi.paths">
+                    <nb-card>
+                      <nb-card-body>
+                        <!-- <nb-icon icon="plus-outline" nbTooltip="Add path" (click)="addPath()"></nb-icon>
+                        <nb-icon icon="copy-outline" nbTooltip="Duplicate path"(click)="duplicatePath()"></nb-icon>
+                        <nb-icon icon="edit-2-outline" nbTooltip="Edit path description"(click)="editDescriptionPath()"></nb-icon>
+                        <ng-container *ngIf="openApi.paths.length>1">
+                          <nb-icon icon="trash-2-outline" nbTooltip="Delete path" (click)="deletePath(path)"></nb-icon>
+                        </ng-container> -->
+                        <h5 *ngIf="path.requests[0].tags[0]=='datasetlist'">Get list of datasets</h5>
+                        <h5 *ngIf="path.requests[0].tags[0]=='dataset'">Get dataset</h5>
+                        <label for="Path">Path</label>
+                        <input name="path" [(ngModel)]="path.pathName" nbInput/>
+                        <div *ngFor="let request of path.requests">
+                          <nb-card>
+                            <nb-card-body>
+                              <div class="request">
+                                <label>Request</label><br/>
+                                <!-- <nb-icon icon="menu-outline" nbTooltip="Toggle Request" (click)="togglRequest(request)"></nb-icon>
+                                 <nb-icon icon="plus-outline" nbTooltip="Add Request" (click)="addRequest(path)"></nb-icon>
+                                <nb-icon icon="copy-outline" nbTooltip="Duplicate Request" (click)="DuplicateRequest(path)"></nb-icon>
+                                <ng-container *ngIf="path.requests.length>1">
+                                  <nb-icon icon="trash-2-outline" nbTooltip="Delete Request" (click)="deleteRequest(path, request)"></nb-icon>
+                                </ng-container> -->
+                                <span class="title">{{request.httpmethod}}</span>
+                                <span class="title">{{request.description}}</span>
+                                <div class="requestbody">
+                                  <nb-tabset>
+                                    <nb-tab tabTitle="Main" tabIcon="settings-2-outline">
+                                      <nb-card>
+                                        <nb-card-body>
+                                          <table>
+                                            <thead>
+                                              <tr>
+                                                <th>Method</th>
+                                                <th>Description</th>
+                                              </tr>
+                                            </thead>
+                                            <tbody>
+                                              <tr>
+                                                <td>
+                                                  <nb-select [(ngModel)]="request.httpmethod">
+                                                    <nb-option value="GET">GET</nb-option>
+                                                    <nb-option value="POST">POST</nb-option>
+                                                    <nb-option value="PUT">PUT</nb-option>
+                                                    <nb-option value="PATCH">PATCH</nb-option>
+                                                    <nb-option value="DELETE">DELETE</nb-option>
+                                                    <nb-option value="HEAD">HEAD</nb-option>
+                                                    <nb-option value="OPTIONS">OPTIONS</nb-option>
+                                                  </nb-select>
+                                                </td>
+                                                <td>
+                                                  <input name="description" [(ngModel)]="request.description" nbInput/>
+                                                </td>
+                                              </tr>
+                                            </tbody>
+                                          </table>
+                                        </nb-card-body>
+                                      </nb-card>
+                                    </nb-tab>
+                                    <nb-tab tabTitle="Parameters" tabIcon="list-outline">
+                                      <nb-card>
+                                        <nb-card-body>
+                                          <label>Parameters</label>
+                                          <table>
+                                            <thead>
+                                              <tr>
+                                                <th>Name</th>
+                                                <th>Location</th>
+                                                <th>Type</th>
+                                                <th>Default value</th>
+                                                <th></th>
+                                              </tr>
+                                            </thead>
+                                            <tbody>
+                                              <tr *ngFor="let parameter of request.parameters">
+                                                <td>
+                                                  <input [(ngModel)]="parameter.name" nbInput/>
+                                                </td>
+                                                <td>
+                                                  <nb-select [(ngModel)]="parameter.in">
+                                                    <nb-option *ngFor="let type of parametersTypes" value="{{type}}">{{type}}</nb-option>
+                                                  </nb-select>
+                                                </td>
+                                                <td>
+                                                  <nb-select [(ngModel)]="parameter.schema.type">
+                                                    <nb-option *ngFor="let type of shemaTypes" value="{{type}}">{{type}}</nb-option>
+                                                  </nb-select>
+                                                </td>
+                                                <td>
+                                                  <input name="default" [(ngModel)]="parameter.schema.default" nbInput/>
+                                                </td>
+                                                <td>
+                                                  <nb-icon icon="plus-outline" nbTooltip="Add parameter" (click)="addParameter(request)"></nb-icon>
+                                                  <nb-icon icon="copy-outline" nbTooltip="Duplicate parameter" (click)="duplicateParameter(request, parameter)"></nb-icon>
+                                                  <ng-container *ngIf="request.parameters.length>1">
+                                                    <nb-icon icon="trash-2-outline" nbTooltip="Delete parameter" (click)="deleteParameter(request, parameter)"></nb-icon>
+                                                  </ng-container>
+                                                </td>
+                                              </tr>
+                                            </tbody>
+                                          </table>
+                                        </nb-card-body>
+                                      </nb-card>
+                                    </nb-tab>
+                                    <nb-tab tabTitle="Response" tabIcon="checkmark-circle-2-outline">
+                                      <div *ngFor="let response of request.responses">
+                                        <nb-card>
+                                          <nb-card-body>
+                                            <label>Reponse</label><br/>
+                                            <!-- <nb-icon icon="plus-outline" nbTooltip="Add Response" (click)="addResponse(request)"></nb-icon>
+                                            <nb-icon icon="copy-outline" nbTooltip="Duplicate Response" (click)="duplicateResponse(request)"></nb-icon>
+                                            <ng-container *ngIf="request.responses.length>1">
+                                              <nb-icon icon="trash-2-outline" nbTooltip="Delete Response" (click)="deleteResponse(request, response)"></nb-icon>
+                                            </ng-container> -->
+                                            <table>
+                                              <thead>
+                                                <tr>
+                                                  <th>Http Status Code</th>
+                                                  <th>Media-Type</th>
+                                                  <th>Description</th>
+                                                </tr>
+                                              </thead>
+                                              <tbody>
+                                                <tr>
+                                                  <td>
+                                                    <nb-select>
+                                                      <nb-option *ngFor="let code of httpStatusCodes" value="{{code}}">{{code}}</nb-option>
+                                                    </nb-select>
+                                                  </td>
+                                                  <td>
+                                                    <div *ngFor="let content of response.contents">
+                                                      <input name="default" [(ngModel)]="content.contentType" nbInput/>
+                                                    </div>
+                                                  </td>
+                                                  <td>
+                                                    <input name="default" [(ngModel)]="response.description" nbInput/>
+                                                  </td>
+                                                </tr>
+                                              </tbody>
+                                            </table>
+                                          </nb-card-body>
+                                        </nb-card>
+                                      </div>
+                                    </nb-tab>
+                                  </nb-tabset>
+                                </div>
+                              </div>
+                            </nb-card-body>
+                          </nb-card>
+                        </div>
+                      </nb-card-body>
+                    </nb-card>
+                  </div>
+                </nb-tab>
+              </nb-tabset>
+            </nb-card-body>
+          </nb-card>
           <button class="prev-button" nbButton disabled nbStepperNext>prev</button>
           <button class="next-button" nbButton nbStepperNext>next</button>
         </nb-step>
@@ -34,7 +231,7 @@
           <ng-template #labelThree>Third step</ng-template>
           <h4>Map DCAT Schema </h4>
           <p class="lorem">
-            Map your metadata schema with DCAT schema   
+            Map your metadata schema with DCAT schema
           </p>
           <button class="prev-button" nbButton nbStepperPrevious>prev</button>
           <button class="next-button" nbButton nbStepperNext>next</button>
@@ -50,4 +247,4 @@
         </nb-step>
       </nb-stepper>
     </nb-card-body>
-  </nb-card>
\ No newline at end of file
+  </nb-card>
diff --git a/src/app/publishapi/publishapi.component.scss b/src/app/publishapi/publishapi.component.scss
index b4051cfb6..17d278b2e 100644
--- a/src/app/publishapi/publishapi.component.scss
+++ b/src/app/publishapi/publishapi.component.scss
@@ -1,4 +1,65 @@
 
 .prev-button {
     margin-right: 1rem;
-  }
\ No newline at end of file
+}
+
+
+/**
+HEADER TAB
+*/
+.header label {
+  display: inline-block;
+  text-align: right;
+  width: 10rem;
+  margin-right: 1.5rem;
+  vertical-align: top;
+}
+
+.header input {
+  max-width: 100%;
+  width: 100%;
+}
+
+.header textarea {
+  max-height: 600px;
+  min-height: 120px;
+}
+
+.header div.field {
+  margin-bottom: .75rem;
+}
+
+.header div.field div {
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 40rem;
+  min-width: 10rem;
+}
+
+/**
+MAIN TAB
+*/
+
+.main label {
+  display: inline-block;
+  margin-right: 1.5rem;
+}
+
+.main nb-icon {
+  margin: 0.32em;
+  background-color: transparent;
+}
+
+.main nb-icon:hover {
+  color: #598bff !important;
+  cursor: pointer;
+}
+
+.main nb-card {
+  background: rgba(0, 0, 0, 0.030);
+}
+
+.main div.request span.title {
+  margin-right: 0.32em;
+}
diff --git a/src/app/publishapi/publishapi.component.ts b/src/app/publishapi/publishapi.component.ts
index f3ed41202..fc913f07e 100644
--- a/src/app/publishapi/publishapi.component.ts
+++ b/src/app/publishapi/publishapi.component.ts
@@ -1,22 +1,90 @@
 import { ComponentFactoryResolver, OnDestroy, ViewChild } from '@angular/core';
-import { Component, Input, OnInit, TemplateRef } from '@angular/core';
+import { Component,  Input, OnInit, TemplateRef } from '@angular/core';
 import { Directive, ViewContainerRef } from '@angular/core';
-
-
-
-
+import { FormControl } from '@angular/forms';
+import { cloneDeep } from 'lodash';
+import HttpStatusCode from './class/http-enum';
+import { OpenApi, Parameter, Path, Request, Response } from './class/openapi';
+import { ParameterType, ShemaType } from './class/openapi-enum';
+import { OpenApiService } from './services/openapi-service';
 
 @Component({
   selector: 'app-publishapi',
   templateUrl: './publishapi.component.html',
   styleUrls: ['./publishapi.component.scss']
 })
+
 export class PublishApiComponent implements OnInit {
 
-  constructor() { }
+  constructor(private openApiService:OpenApiService) {}
+
+  openApi: OpenApi;
+  parametersTypes: string[];
+  shemaTypes: string[];
+  httpStatusCodes: string[];
 
   ngOnInit(): void {
-  
+    this.openApi = this.openApiService.getFromJson();
+    this.parametersTypes = Object.keys(ParameterType);
+    this.shemaTypes = Object.keys(ShemaType);
+    const httpStatusCodeskeys = Object.keys(HttpStatusCode).filter(k => typeof HttpStatusCode[k as any] === "number");
+    this.httpStatusCodes = httpStatusCodeskeys.map(k => HttpStatusCode[k as any]);
+  }
+
+  addPath(): void {
+    let emptyPath: Path = this.openApiService.getEmptyPath();
+    this.openApi.paths.unshift(emptyPath);
+  }
+
+  deletePath(path: Path): void {
+    const index: number = this.openApi.paths.indexOf(path);
+    if (index !== -1) {
+      this.openApi.paths.splice(index, 1);
+    }
+  }
+
+  addRequest(path: Path): void {
+    let emptyRequest: Request = this.openApiService.getEmptyRequest();
+    path.requests.unshift(emptyRequest);
+  }
+
+  deleteRequest(path: Path, request: Request): void {
+    const indexRequest: number = path.requests.indexOf(request);
+    if (indexRequest !== -1) {
+      path.requests.splice(indexRequest, 1);
+    }
+  }
+
+  togglRequest(request: Request): void {
+    request.toggled = !request.toggled;
+  }
+
+  addParameter(request: Request): void {
+    let emptyParameter: Parameter = this.openApiService.getEmptyParameter();
+    request.parameters.unshift(emptyParameter);
+  }
+
+  duplicateParameter(request: Request, parameter: Parameter): void {
+    request.parameters.unshift(cloneDeep(parameter));
+  }
+
+  deleteParameter(request: Request, parameter: Parameter): void {
+    const indexParameter: number = request.parameters.indexOf(parameter);
+    if (indexParameter !== -1) {
+      request.parameters.splice(indexParameter, 1);
+    }
+  }
+
+  addResponse(request: Request): void {
+    let emptyResponse: Response = this.openApiService.getEmptyResponse();
+    request.responses.unshift(emptyResponse);
+  }
+
+  deleteResponse(request: Request, response: Response): void {
+    const indexResponse: number = request.responses.indexOf(response);
+    if (indexResponse !== -1) {
+      request.responses.splice(indexResponse, 1);
+    }
   }
 
   goToLink()  {
diff --git a/src/app/publishapi/services/openapi-dto-mapping-service.ts b/src/app/publishapi/services/openapi-dto-mapping-service.ts
new file mode 100644
index 000000000..16e8d7432
--- /dev/null
+++ b/src/app/publishapi/services/openapi-dto-mapping-service.ts
@@ -0,0 +1,90 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import HttpStatusCode, { HttpMethod } from '../class/http-enum';
+import { InfoMap, OpenApi, Path, Server, Request, Parameter, Response, Content, ResponseSchema } from '../class/openapi';
+import { ContentDTO, HttpCodeToResponseMapDTO, MethodToRequestMapDTO, MimeTypeToContentMapDTO, OpenApiDTO, ParameterDTO, PathMapDTO, RequestDTO, ResponseDTO } from '../class/openapi-dto';
+
+@Injectable({
+    providedIn: 'root'
+  })
+
+export class OpenApiDTOMappingService {
+    constructor() {}
+
+    mapContentFromDTO(mimeTypeToContentMapDTO: MimeTypeToContentMapDTO, contentType: string){
+        let contentDTO: ContentDTO = mimeTypeToContentMapDTO[contentType];
+        let content: Content = {} as Content;
+        content.contentType = contentType;
+        content.schema = contentDTO.schema as ResponseSchema;
+        return content;
+    }
+
+    mapResponseFromDTO(httpCodeToResponseMapDTO: HttpCodeToResponseMapDTO[], httpStatusCodeToreponseDTOMap: string): Response {
+        let responseDTO: ResponseDTO = httpCodeToResponseMapDTO[httpStatusCodeToreponseDTOMap];
+        let response: Response = {} as Response;
+        response.description = responseDTO.description;
+        response.httpStatusCode = httpStatusCodeToreponseDTOMap as unknown as HttpStatusCode;
+        response.contents = [] as Content[];
+        Object.keys(responseDTO.content).forEach((contentType)=>{
+            let content: Content = this.mapContentFromDTO(responseDTO.content, contentType);
+            response.contents.push(content);
+        });
+        return response;
+    }
+
+    mapParametersFromDTO(parameterDTO: ParameterDTO[]): Parameter[] {
+        return parameterDTO as Parameter[];
+    }
+
+    mapRequestFromDTO(methodToRequestMapDTO: MethodToRequestMapDTO, httpMethod: HttpMethod): Request{
+        let requestDTO: RequestDTO = methodToRequestMapDTO[httpMethod];
+        let request: Request = {} as Request;
+        request.httpmethod = httpMethod;
+        request.description = requestDTO.description;
+        request.tags = Object.create(requestDTO.tags) as string[];
+        request.parameters = this.mapParametersFromDTO(requestDTO.parameters);
+        request.responses = [] as Response[];
+        request.toggled = false;
+        Object.keys(requestDTO.responses).forEach((HttpStatusCode)=>{
+            let response: Response = this.mapResponseFromDTO(requestDTO.responses, HttpStatusCode);
+            request.responses.push(response);
+        });
+        return request;
+    }
+
+    mapPathFromDTO(pathMapDTO: PathMapDTO, pathName: string): Path{
+        let methodToRequestMapDTO: MethodToRequestMapDTO = pathMapDTO[pathName];
+        let path:Path = {} as Path;
+        path.pathName = pathName.trim();
+        path.requests = [] as Request[];
+        Object.keys(methodToRequestMapDTO).forEach((httpMethod:HttpMethod)=>{
+            let request: Request = this.mapRequestFromDTO(methodToRequestMapDTO, httpMethod);
+            path.requests.push(request);
+        });
+        return path;
+    }
+
+    mapOpenApiFromDTO(openApiDTO:OpenApiDTO): OpenApi {
+        let openApi:OpenApi = {} as OpenApi;
+        openApi.info = Object.create(openApiDTO.info) as InfoMap;
+        openApi.openapi = openApiDTO.openapi;
+        openApi.servers = Object.create(openApiDTO.servers) as Server[];
+        openApi.paths = [] as Path[];
+        Object.keys(openApiDTO.paths).forEach((pathName)=>{
+            let path: Path = this.mapPathFromDTO(openApiDTO.paths, pathName);
+            openApi.paths.push(path);
+        });
+        return openApi;
+    }
+
+    /**
+     * TODO Mapping to DTO
+     * @param openApi
+     */
+    mapToDto(openApi:OpenApi): OpenApiDTO {
+        let openApiDTO:OpenApiDTO = {} as OpenApiDTO;
+        // TODO
+        return openApiDTO;
+    }
+
+}
diff --git a/src/app/publishapi/services/openapi-service.ts b/src/app/publishapi/services/openapi-service.ts
new file mode 100644
index 000000000..d0729639f
--- /dev/null
+++ b/src/app/publishapi/services/openapi-service.ts
@@ -0,0 +1,349 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import HttpStatusCode, { HttpMethod } from '../class/http-enum';
+import { OpenApi, Parameter, Path, Request, Response } from '../class/openapi';
+import { HttpCodeToResponseMapDTO, MethodToRequestMapDTO, OpenApiDTO, ParameterDTO, PathMapDTO } from '../class/openapi-dto';
+import { OpenApiDTOMappingService } from './openapi-dto-mapping-service';
+
+@Injectable({
+    providedIn: 'root'
+  })
+
+export class OpenApiService {
+    constructor(private http: HttpClient, private openApiDTOMappingService: OpenApiDTOMappingService) {}
+
+    getFromRepository(repositoryId:string): Observable<OpenApiDTO> {
+        return this.http.get<OpenApiDTO>('/openapi/' + repositoryId);
+    }
+
+    getFromJson(): OpenApi {
+        let openApiDTO = <OpenApiDTO>JSON.parse(this.jsonFull);
+        return this.openApiDTOMappingService.mapOpenApiFromDTO(openApiDTO);
+    }
+
+    getEmptyPath(): Path {
+        let pathDTO = <PathMapDTO>JSON.parse(this.emptyPathJson);
+        let paths = [] as Path[];
+        Object.keys(pathDTO).forEach((pathName)=>{
+            let path: Path = this.openApiDTOMappingService.mapPathFromDTO(pathDTO, pathName);
+            paths.push(path);
+        });
+        return paths[0];
+    }
+
+    getEmptyRequest(): Request {
+        let methodToRequestMapDTO: MethodToRequestMapDTO = <MethodToRequestMapDTO>JSON.parse('{' + this.emptyMethodJson + '}');
+        let requests = [] as Request[];
+        Object.keys(methodToRequestMapDTO).forEach((httpMethod:HttpMethod)=>{
+            let request: Request = this.openApiDTOMappingService.mapRequestFromDTO(methodToRequestMapDTO, httpMethod);
+            requests.push(request);
+        });
+        return requests[0];
+    }
+
+    getEmptyParameter(): Parameter {
+        let parameterDTO: ParameterDTO[] = <ParameterDTO[]>JSON.parse(this.emptyParameter);
+        return this.openApiDTOMappingService.mapParametersFromDTO(parameterDTO)[0];
+    }
+
+    getEmptyResponse(): Response {
+        let httpCodeToResponseMapDTO : HttpCodeToResponseMapDTO[] = <HttpCodeToResponseMapDTO[]>JSON.parse('{' + this.emptyResponse + '}');
+        let responses = [] as Response[];
+        Object.keys(httpCodeToResponseMapDTO).forEach((httpStatusCode:string)=>{
+            let response: Response = this.openApiDTOMappingService.mapResponseFromDTO(httpCodeToResponseMapDTO, httpStatusCode);
+            responses.push(response);
+        });
+        return responses[0];
+    }
+
+
+    private json = '{' +
+    '    "openapi" : "3.0.1",' +
+    '    "info" : {' +
+    '        "title" : "ifremer opensearch",' +
+    '        "description" : "balises  argo",' +
+    '        "version" : "0.1",' +
+    '        "x-format" : "custom",' +
+    '        "x-catalog-id" : "083f3716-1038-4fdd-b275-67c67f0c26b7",' +
+    '        "x-result" : "xml",' +
+    '        "x-start-param" : "startPage",' +
+    '        "x-page-param" : "count"' +
+    '    },' +
+    '    "servers" : [ ' +
+    '        {' +
+    '            "url" : "https://opensearch.ifremer.fr"' +
+    '        }' +
+    '    ],' +
+    '    "paths" : {' +
+    '        "/granules.atom" : {' +
+    '            "GET" : {' +
+    '                "description" : "Liste de liens permettant de télécharger des fichiers correspondant aux critères spatio-temporels demandés",' +
+    '                "tags" : [ ' +
+    '                    "datasetlist"' +
+    '                ],' +
+    '                "parameters" : [ ' +
+    '                    {' +
+    '                        "name" : "timeEnd",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "2020-04-30T00:00:00Z"' +
+    '                        }' +
+    '                    }, ' +
+    '                    {' +
+    '                        "name" : "startPage",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "0"' +
+    '                        }' +
+    '                    }, ' +
+    '                    {' +
+    '                        "name" : "timeStart",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "2020-02-01T00:00:00Z"' +
+    '                        }' +
+    '                    }, ' +
+    '                    {' +
+    '                        "name" : "count",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "10"' +
+    '                        }' +
+    '                    }, ' +
+    '                    {' +
+    '                        "name" : "datasetId",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "argo"' +
+    '                        }' +
+    '                    }, ' +
+    '                    {' +
+    '                        "name" : "geoBox",' +
+    '                        "in" : "query",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "-180.0,-20.0,180.0,20.0"' +
+    '                        }' +
+    '                    }' +
+    '                ],' +
+    '                "responses" : {' +
+    '                    "200" : {' +
+    '                        "description" : "A XML array",' +
+    '                        "content" : {' +
+    '                            "application/xml" : {' +
+    '                                "schema" : {' +
+    '                                    "type" : "array",' +
+    '                                    "items" : {' +
+    '                                        "type" : "string"' +
+    '                                    }' +
+    '                                }' +
+    '                            }' +
+    '                        }' +
+    '                    }' +
+    '                }' +
+    '            }' +
+    '        }' +
+    '    }' +
+    '}';
+
+    private jsonFull =
+    '{' +
+    '    "openapi" : "3.0.0",' +
+    '    "info" : {' +
+    '        "title" : "inrae list datasets",' +
+    '        "version" : "0",' +
+    '        "x-format" : "dataverse",' +
+    '        "x-catalog-id" : "09de0761-f1b5-4dc1-8c5c-92e5e782cb2c",' +
+    '        "x-result" : "json",' +
+    '        "x-start-param" : "start",' +
+    '        "x-page-param" : "per_page"' +
+    '    },' +
+    '    "servers" : [ ' +
+    '        {' +
+    '            "url" : "https://data.inrae.fr/api"' +
+    '        }' +
+    '    ],' +
+    '    "paths" : {' +
+    '        "/search" : {' +
+    '            "GET" : {' +
+    '                "description" : "Returns a list of datasets",' +
+    '                "tags" : [ ' +
+    '                    "datasetlist"' +
+    '                ],' +
+    '                "parameters" : [ ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "q",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "*"' +
+    '                        },' +
+    '                        "description" : "for all  star"' +
+    '                    }, ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "per_page",' +
+    '                        "schema" : {' +
+    '                            "type" : "integer",' +
+    '                            "default" : 10' +
+    '                        },' +
+    '                        "description" : "pages"' +
+    '                    }, ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "type",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "dataset"' +
+    '                        },' +
+    '                        "description" : "dataset"' +
+    '                    }, ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "start",' +
+    '                        "schema" : {' +
+    '                            "type" : "integer",' +
+    '                            "default" : 0' +
+    '                        },' +
+    '                        "description" : "start"' +
+    '                    }, ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "show_entity_ids",' +
+    '                        "schema" : {' +
+    '                            "type" : "boolean",' +
+    '                            "default" : true' +
+    '                        },' +
+    '                        "description" : "id"' +
+    '                    }, ' +
+    '                    {' +
+    '                        "in" : "query",' +
+    '                        "name" : "show_my_data",' +
+    '                        "schema" : {' +
+    '                            "type" : "boolean",' +
+    '                            "default" : true' +
+    '                        },' +
+    '                        "description" : "aaa"' +
+    '                    }' +
+    '                ],' +
+    '                "responses" : {' +
+    '                    "200" : {' +
+    '                        "description" : "A JSON array of datasets",' +
+    '                        "content" : {' +
+    '                            "application/json" : {' +
+    '                                "schema" : {' +
+    '                                    "type" : "array",' +
+    '                                    "items" : {' +
+    '                                        "type" : "string"' +
+    '                                    }' +
+    '                                }' +
+    '                            }' +
+    '                        }' +
+    '                    }' +
+    '                }' +
+    '            }' +
+    '        },' +
+    '        "/datasets/{entity_id}" : {' +
+    '            "GET" : {' +
+    '                "description" : "Get the details on the dataset that the identifier is in parameter ",' +
+    '                "tags" : [ ' +
+    '                    "dataset"' +
+    '                ],' +
+    '                "parameters" : [ ' +
+    '                    {' +
+    '                        "in" : "path",' +
+    '                        "name" : "entity_id",' +
+    '                        "schema" : {' +
+    '                            "type" : "string",' +
+    '                            "default" : "95707"' +
+    '                        },' +
+    '                        "description" : "he Digital Object Identifier (DOI) of the dataset searched."' +
+    '                    }' +
+    '                ],' +
+    '                "responses" : {' +
+    '                    "200" : {' +
+    '                        "description" : "A JSON array of one dataset",' +
+    '                        "content" : {' +
+    '                            "application/json" : {' +
+    '                                "schema" : {' +
+    '                                    "type" : "array",' +
+    '                                    "items" : {' +
+    '                                        "type" : "string"' +
+    '                                    }' +
+    '                                }' +
+    '                            }' +
+    '                        }' +
+    '                    }' +
+    '                }' +
+    '            }' +
+    '        }' +
+    '    }' +
+    '}';
+
+    private emptyResponse =
+    '"200" : {' +
+    '    "description" : "",' +
+    '    "content" : {' +
+    '        " " : {' +
+    '            "schema" : {' +
+    '                "type" : "array",' +
+    '                "items" : {' +
+    '                    "type" : "string"' +
+    '                }' +
+    '            }' +
+    '        }' +
+    '    }' +
+    '}';
+
+    private emptyParameter =
+    '[' +
+    '   {' +
+    '      "name" : "",' +
+    '      "in" : "query",' +
+    '      "schema" : {' +
+    '          "type" : "string",' +
+    '          "default" : ""' +
+    '      }' +
+    '   }' +
+    ']';
+
+
+    private emptyMethodJson =
+    '   "GET" : {' +
+    '       "description" : "",' +
+    '       "tags" : [ ' +
+    '           "datasetlist"' +
+    '       ],' +
+    '       "parameters" : ' +
+                this.emptyParameter +
+    '       ,' +
+    '       "responses" : {' +
+    '           "200" : {' +
+    '               "description" : "",' +
+    '               "content" : {' +
+    '                   "" : {' +
+    '                       "schema" : {' +
+    '                           "type" : "array",' +
+    '                           "items" : {' +
+    '                               "type" : "string"' +
+    '                           }' +
+    '                       }' +
+    '                   }' +
+    '               }' +
+    '           }' +
+    '       }' +
+    '   }';
+
+    private emptyPathJson = '{' +
+    '   " " : {' +
+        this.emptyMethodJson +
+    '   }' +
+    '}';
+
+}
diff --git a/src/app/repository/repository.component.html b/src/app/repository/repository.component.html
index 787fd5ea8..a5a3abd63 100644
--- a/src/app/repository/repository.component.html
+++ b/src/app/repository/repository.component.html
@@ -7,22 +7,19 @@
 
 
   <div>
-  <label>Repository Type
-    <select class="form-control" formControlName="repotype" required>
-      <option value="Dataverse">Dataverse</option>>
-      <option value="Custom">Custom</option>>
-    </select>  
-  </label>    
+  <label>Repository Type</label>
+  <select class="form-control" formControlName="repotype" required>
+    <option value="Dataverse">Dataverse</option>>
+    <option value="Custom">Custom</option>>
+  </select>
   </div>
   <div class="form-group">
-    <label>Repository Name
+    <label>Repository Name</label>
     <input type="text" class="form-control" formControlName="reponame" required>
-    </label>
   </div>
     <div class="form-group">
-    <label>Description
+    <label>Description</label>
     <textarea  class="form-control" formControlName="repodescription"></textarea>
-    </label>
   </div>
   <div class="form-group">
     <label>url</label>
diff --git a/src/styles.scss b/src/styles.scss
index 3c4e4a354..a931d951b 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -40,7 +40,6 @@ button:disabled {
 
 label {
   display: block;
-  width: 40em;
   margin: .5em 0;
   color: #607D8B;
   font-weight: bold;
@@ -87,4 +86,4 @@ textarea {
 // install the framework styles
 @include nb-install() {
   @include nb-theme-global();
-};
\ No newline at end of file
+};
-- 
GitLab