mirror of https://github.com/goharbor/harbor.git
Refactor swagger ui (#17428)
Signed-off-by: AllForNothing <sshijun@vmware.com> Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
861ca553df
commit
83bce02e61
|
@ -21,6 +21,8 @@ src/portal/coverage/
|
|||
src/portal/dist/
|
||||
src/portal/html-report/
|
||||
src/portal/node_modules/
|
||||
src/portal/app-swagger-ui/node_modules/
|
||||
src/portal/app-swagger-ui/webpack.dev.js
|
||||
src/portal/typings/
|
||||
**/*npm-debug.log.*
|
||||
**/*yarn-error.log.*
|
||||
|
|
|
@ -29,9 +29,13 @@ RUN python -c 'import sys, yaml, json; y=yaml.load(sys.stdin.read()); print json
|
|||
RUN cp swagger.yaml dist
|
||||
COPY ./LICENSE /build_dir/dist
|
||||
|
||||
RUN cd app-swagger-ui && npm install --unsafe-perm
|
||||
RUN cd app-swagger-ui && npm run build
|
||||
|
||||
FROM ${harbor_base_namespace}/harbor-portal-base:${harbor_base_image_version}
|
||||
|
||||
COPY --from=nodeportal /build_dir/dist /usr/share/nginx/html
|
||||
COPY --from=nodeportal /build_dir/app-swagger-ui/dist /usr/share/nginx/html
|
||||
COPY --from=nodeportal /build_dir/package*.json /usr/share/nginx/
|
||||
|
||||
VOLUME /var/cache/nginx /var/log/nginx /run
|
||||
|
|
|
@ -40,6 +40,10 @@ http {
|
|||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
location /devcenter-api-2.0 {
|
||||
try_files $uri $uri/ /swagger-ui-index.html;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
@ -48,4 +52,4 @@ http {
|
|||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"root": true,
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
"projects/**/*",
|
||||
"**/*.js"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
"no-empty-source": null
|
||||
},
|
||||
"ignoreFiles": [
|
||||
"src/**/*.html"
|
||||
"**/*.md",
|
||||
"src/**/*.html",
|
||||
"app-swagger-ui/**/*.html"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
```text
|
||||
{
|
||||
"name": "harbor",
|
||||
"version": "2.5.0",
|
||||
"version": "2.7.0",
|
||||
"description": "Harbor UI with Clarity",
|
||||
"angular-cli": {},
|
||||
"scripts": {
|
||||
|
@ -54,16 +54,16 @@
|
|||
"@angular/localize": "~14.1.0",
|
||||
"@angular/platform-browser": "~14.1.0",
|
||||
"@angular/platform-browser-dynamic": "~14.1.0",
|
||||
"@angular/router": "~13.2.2",
|
||||
"@angular/router": "~14.1.0",
|
||||
"rxjs": "^7.4.0",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4",
|
||||
|
||||
// Clarity UI. Required
|
||||
"@clr/angular": "13.0.2",
|
||||
"@cds/core": "5.6.4",
|
||||
"@clr/angular": "13.7.0",
|
||||
"@cds/core": "6.0.0",
|
||||
"@clr/icons": "13.0.2",
|
||||
"@clr/ui": "13.0.2",
|
||||
"@clr/ui": "13.7.0",
|
||||
|
||||
// For Harbor i18n functionality. Required
|
||||
"@ngx-translate/core": "^13.0.0",
|
||||
|
@ -81,11 +81,6 @@
|
|||
// To render markdown data. Required
|
||||
"ngx-markdown": "~13.0.0",
|
||||
|
||||
// For swagger API center. Required
|
||||
"swagger-ui": "~4.9.0",
|
||||
"buffer": "^6.0.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
|
||||
// To convert yaml to json. Required
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
|
|
|
@ -76,6 +76,16 @@ Start
|
|||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/chartrepo/*": {
|
||||
"target": "https://hostname",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/LICENSE": {
|
||||
"target": "https://hostname",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/swagger.json": {
|
||||
"target": "https://hostname",
|
||||
"secure": false,
|
||||
|
@ -86,12 +96,12 @@ Start
|
|||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/chartrepo/*": {
|
||||
"/devcenter-api-2.0": {
|
||||
"target": "https://hostname",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/LICENSE": {
|
||||
"/swagger-ui.bundle.js": {
|
||||
"target": "https://hostname",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
|
|
|
@ -12,20 +12,8 @@
|
|||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"allowedCommonJsDependencies": [
|
||||
"swagger-ui",
|
||||
"buffer",
|
||||
"js-yaml",
|
||||
"hoist-non-react-statics",
|
||||
"lodash",
|
||||
"core-js-pure",
|
||||
"prop-types",
|
||||
"randexp",
|
||||
"react-copy-to-clipboard",
|
||||
"react-debounce-input",
|
||||
"react-immutable-proptypes",
|
||||
"redux-immutable",
|
||||
"url-parse",
|
||||
"xml-but-prettier"
|
||||
"cron-validator",
|
||||
"js-yaml"
|
||||
],
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
|
@ -41,7 +29,6 @@
|
|||
"styles": [
|
||||
"node_modules/@clr/icons/clr-icons.min.css",
|
||||
"node_modules/@clr/ui/clr-ui.min.css",
|
||||
"node_modules/swagger-ui/dist/swagger-ui.css",
|
||||
"node_modules/prismjs/themes/prism-solarizedlight.css",
|
||||
"src/global.scss",
|
||||
{
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
Swagger UI
|
||||
============
|
||||
This is the project based on Swagger UI and Webpack.
|
||||
|
||||
|
||||
|
||||
Start
|
||||
============
|
||||
1. npm install
|
||||
2. change `webpack.dev.js.temp` to `webpack.dev.js`,
|
||||
```shell
|
||||
mv webpack.dev.js.temp webpack.dev.js
|
||||
```
|
||||
3. modify `webpack.dev.js`, replace `https://example.com` with an available Harbor server
|
||||
4. npm run start
|
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Harbor</title>
|
||||
<base href="/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico?v=2" />
|
||||
<style>
|
||||
.spinner {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: inline-block;
|
||||
width: 108px;
|
||||
height: 108px;
|
||||
animation: spin 1s linear infinite;
|
||||
background: url(data:image/svg+xml;charset=utf8,%3Csvg%20id%3D%22Layer_2%22%20data-name%3D%22Layer%202%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2072%2072%22%3E%0A%20%20%20%20%3Cdefs%3E%0A%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.cls-1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20.cls-2%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fill%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stroke-miterlimit%3A%2010%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stroke-width%3A%205px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20.cls-1%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stroke%3A%20%23000000%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stroke-opacity%3A%200.15%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20.cls-2%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stroke%3A%20%230072a3%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%3C%2Fstyle%3E%0A%20%20%20%20%3C%2Fdefs%3E%0A%20%20%20%20%3Ctitle%3EPreloader_72x2%3C%2Ftitle%3E%0A%20%20%20%20%3Ccircle%20class%3D%22cls-1%22%20cx%3D%2236%22%20cy%3D%2236%22%20r%3D%2233%22%2F%3E%0A%20%20%20%20%3Cpath%20class%3D%22cls-2%22%20d%3D%22M14.3%2C60.9A33%2C33%2C0%2C0%2C1%2C36%2C3%22%3E%0A%20%20%20%20%3C%2Fpath%3E%0A%3C%2Fsvg%3E%0A);
|
||||
text-indent: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotateZ(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui-container" class="spinner">Loading...</div>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "swagger-ui",
|
||||
"version": "2.7.0",
|
||||
"description": "Swagger UI for Harbor APIs",
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.prod.js && mv dist/index.html dist/swagger-ui-index.html",
|
||||
"start": "webpack serve --open --config webpack.dev.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"css-loader": "^6.7.1",
|
||||
"style-loader": "^3.3.1",
|
||||
"swagger-ui": "4.13.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.10.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
import SwaggerUI from 'swagger-ui'
|
||||
import 'swagger-ui/dist/swagger-ui.css';
|
||||
|
||||
const helpInfo =
|
||||
' If you want to enable basic authorization,' +
|
||||
' please logout Harbor first or manually delete the cookies under the current domain.';
|
||||
const SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS', 'TRACE'];
|
||||
|
||||
// get swagger.json and swagger2.json from portal container then render swagger ui
|
||||
// before rendering, the ui shows a loading style
|
||||
Promise.all([
|
||||
fetch('/swagger.json').then(value => value.json()),
|
||||
fetch('/swagger2.json').then(value => value.json())
|
||||
])
|
||||
.then(value => {
|
||||
// merger swagger.json and swagger2.json
|
||||
const json = {};
|
||||
mergeDeep(json, value[0], value[1]);
|
||||
json['host'] = window.location.host;
|
||||
const protocal = window.location.protocol;
|
||||
json['schemes'] = [protocal.replace(':', '')];
|
||||
json.info.description = json.info.description + helpInfo;
|
||||
// start to render
|
||||
SwaggerUI({
|
||||
spec: json,
|
||||
dom_id: '#swagger-ui-container',
|
||||
deepLinking: true,
|
||||
presets: [SwaggerUI.presets.apis],
|
||||
requestInterceptor: request => {
|
||||
// Get the csrf token from localstorage
|
||||
const token = localStorage.getItem('__csrf');
|
||||
const headers = request.headers || {};
|
||||
if (token) {
|
||||
if (
|
||||
request.method &&
|
||||
SAFE_METHODS.indexOf(
|
||||
request.method.toUpperCase()
|
||||
) === -1
|
||||
) {
|
||||
headers['X-Harbor-CSRF-Token'] = token;
|
||||
}
|
||||
}
|
||||
return request;
|
||||
},
|
||||
responseInterceptor: response => {
|
||||
const headers = response.headers || {};
|
||||
const responseToken =
|
||||
headers['X-Harbor-CSRF-Token'];
|
||||
if (responseToken) {
|
||||
// Set the csrf token to localstorage
|
||||
localStorage.setItem('__csrf', responseToken);
|
||||
}
|
||||
return response;
|
||||
},
|
||||
});
|
||||
// remove loading style
|
||||
document.getElementById('swagger-ui-container').removeAttribute('class');
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function mergeDeep(target, ...sources) {
|
||||
if (!sources.length) {
|
||||
return target;
|
||||
}
|
||||
const source = sources.shift();
|
||||
|
||||
if (isObject(target) && isObject(source)) {
|
||||
for (const key in source) {
|
||||
if (isObject(source[key])) {
|
||||
if (!target[key]) {
|
||||
Object.assign(target, { [key]: {} });
|
||||
}
|
||||
mergeDeep(target[key], source[key]);
|
||||
} else {
|
||||
Object.assign(target, { [key]: source[key] });
|
||||
}
|
||||
}
|
||||
}
|
||||
return mergeDeep(target, ...sources);
|
||||
}
|
||||
|
||||
function isObject(item) {
|
||||
return item && typeof item === 'object' && !Array.isArray(item);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
|
||||
|
||||
const outputPath = path.resolve(__dirname, 'dist');
|
||||
|
||||
module.exports = {
|
||||
devServer: {
|
||||
proxy: {
|
||||
'/swagger.json': {
|
||||
target: 'https://example.com',
|
||||
"secure": false,
|
||||
},
|
||||
'/swagger2.json': {
|
||||
target: 'https://example.com',
|
||||
"secure": false,
|
||||
}
|
||||
}
|
||||
},
|
||||
mode: 'development',
|
||||
entry: {
|
||||
app: require.resolve('./src/index'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' },
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
`favicon.ico`
|
||||
]
|
||||
}),
|
||||
new CleanWebpackPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'index.html'
|
||||
})
|
||||
],
|
||||
output: {
|
||||
filename: 'swagger-ui.bundle.js',
|
||||
path: outputPath,
|
||||
}
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const outputPath = path.resolve(__dirname, 'dist');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
app: require.resolve('./src/index'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' },
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'index.html'
|
||||
})
|
||||
],
|
||||
output: {
|
||||
filename: 'swagger-ui.bundle.js',
|
||||
path: outputPath,
|
||||
}
|
||||
};
|
|
@ -19,10 +19,15 @@ RUN python -c 'import sys, yaml, json; y=yaml.load(sys.stdin.read()); print json
|
|||
|
||||
COPY LICENSE /build_dir/dist
|
||||
|
||||
RUN cd app-swagger-ui && npm install --unsafe-perm
|
||||
RUN cd app-swagger-ui && npm run build
|
||||
|
||||
FROM nginx:1.17
|
||||
|
||||
|
||||
|
||||
COPY --from=builder /build_dir/dist /usr/share/nginx/html
|
||||
COPY --from=builder /build_dir/app-swagger-ui/dist /usr/share/nginx/html
|
||||
COPY src/portal/docker-build/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 8080
|
||||
|
|
|
@ -26,6 +26,10 @@ http {
|
|||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
location /devcenter-api-2.0 {
|
||||
try_files $uri $uri/ /swagger-ui-index.html;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "harbor",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.0",
|
||||
"description": "Harbor UI with Clarity",
|
||||
"angular-cli": {},
|
||||
"scripts": {
|
||||
|
@ -42,15 +42,12 @@
|
|||
"@clr/ui": "13.7.0",
|
||||
"@ngx-translate/core": "^13.0.0",
|
||||
"@ngx-translate/http-loader": "^6.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cron-validator": "^1.2.1",
|
||||
"cron-validator": "^1.3.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"ngx-clipboard": "^12.3.1",
|
||||
"ngx-cookie": "^5.0.2",
|
||||
"ngx-clipboard": "^15.1.0",
|
||||
"ngx-cookie": "^6.0.1",
|
||||
"ngx-markdown": "14.0.1",
|
||||
"rxjs": "^7.4.0",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"swagger-ui": "~4.10.3",
|
||||
"tslib": "^2.2.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import { AfterViewInit, Component, Directive, OnInit } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CookieService } from 'ngx-cookie';
|
||||
|
||||
@Directive()
|
||||
export abstract class DevCenterBaseDirective implements OnInit, AfterViewInit {
|
||||
protected constructor(
|
||||
public translate: TranslateService,
|
||||
public cookieService: CookieService,
|
||||
public titleService: Title
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.setTitle('APP_TITLE.HARBOR_SWAGGER');
|
||||
}
|
||||
|
||||
private setTitle(key: string) {
|
||||
this.translate.get(key).subscribe((res: string) => {
|
||||
this.titleService.setTitle(res);
|
||||
});
|
||||
}
|
||||
abstract getSwaggerUI();
|
||||
abstract ngAfterViewInit();
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<div class="swagger-container"></div>
|
|
@ -1,8 +0,0 @@
|
|||
.swagger-container {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
import { ComponentFixture, TestBed, getTestBed } from '@angular/core/testing';
|
||||
import { HttpTestingController } from '@angular/common/http/testing';
|
||||
import { DevCenterComponent } from './dev-center.component';
|
||||
import { CookieService } from 'ngx-cookie';
|
||||
import { SharedTestingModule } from '../shared/shared.module';
|
||||
|
||||
describe('DevCenterComponent', () => {
|
||||
let component: DevCenterComponent;
|
||||
let fixture: ComponentFixture<DevCenterComponent>;
|
||||
const mockCookieService = {
|
||||
get: () => {
|
||||
return 'xsrf';
|
||||
},
|
||||
};
|
||||
let cookie = 'fdsa|ds';
|
||||
let injector: TestBed;
|
||||
let httpMock: HttpTestingController;
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [DevCenterComponent],
|
||||
imports: [SharedTestingModule],
|
||||
providers: [
|
||||
{
|
||||
provide: CookieService,
|
||||
useValue: mockCookieService,
|
||||
},
|
||||
],
|
||||
}).compileComponents();
|
||||
injector = getTestBed();
|
||||
httpMock = injector.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DevCenterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.autoDetectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
it('get swagger should return data', () => {
|
||||
const req = httpMock.expectOne('/swagger.json');
|
||||
expect(req.request.method).toBe('GET');
|
||||
req.flush({
|
||||
host: '122.33',
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,96 +0,0 @@
|
|||
import { AfterViewInit, Component, ElementRef, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { throwError as observableThrowError, forkJoin } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CookieService } from 'ngx-cookie';
|
||||
import SwaggerUI from 'swagger-ui';
|
||||
import { mergeDeep } from '../shared/units/utils';
|
||||
import { DevCenterBaseDirective } from './dev-center-base';
|
||||
import { SAFE_METHODS } from '../services/intercept-http.service';
|
||||
|
||||
enum SwaggerJsonUrls {
|
||||
SWAGGER1 = '/swagger.json',
|
||||
SWAGGER2 = '/swagger2.json',
|
||||
}
|
||||
|
||||
const helpInfo: string =
|
||||
' If you want to enable basic authorization,' +
|
||||
' please logout Harbor first or manually delete the cookies under the current domain.';
|
||||
|
||||
@Component({
|
||||
selector: 'dev-center',
|
||||
templateUrl: 'dev-center.component.html',
|
||||
viewProviders: [Title],
|
||||
styleUrls: ['dev-center.component.scss'],
|
||||
})
|
||||
export class DevCenterComponent
|
||||
extends DevCenterBaseDirective
|
||||
implements AfterViewInit, OnInit
|
||||
{
|
||||
private ui: any;
|
||||
constructor(
|
||||
private el: ElementRef,
|
||||
private http: HttpClient,
|
||||
public translate: TranslateService,
|
||||
public cookieService: CookieService,
|
||||
public titleService: Title
|
||||
) {
|
||||
super(translate, cookieService, titleService);
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.getSwaggerUI();
|
||||
}
|
||||
getSwaggerUI() {
|
||||
forkJoin([
|
||||
this.http.get(SwaggerJsonUrls.SWAGGER1),
|
||||
this.http.get(SwaggerJsonUrls.SWAGGER2),
|
||||
])
|
||||
.pipe(catchError(error => observableThrowError(error)))
|
||||
.subscribe(jsonArr => {
|
||||
const json: any = {};
|
||||
mergeDeep(json, jsonArr[0], jsonArr[1]);
|
||||
json['host'] = window.location.host;
|
||||
const protocal = window.location.protocol;
|
||||
json['schemes'] = [protocal.replace(':', '')];
|
||||
json.info.description = json.info.description + helpInfo;
|
||||
this.ui = SwaggerUI({
|
||||
spec: json,
|
||||
domNode:
|
||||
this.el.nativeElement.querySelector(
|
||||
'.swagger-container'
|
||||
),
|
||||
deepLinking: true,
|
||||
presets: [SwaggerUI.presets.apis],
|
||||
requestInterceptor: request => {
|
||||
// Get the csrf token from localstorage
|
||||
const token = localStorage.getItem('__csrf');
|
||||
const headers = request.headers || {};
|
||||
if (token) {
|
||||
if (
|
||||
request.method &&
|
||||
SAFE_METHODS.indexOf(
|
||||
request.method.toUpperCase()
|
||||
) === -1
|
||||
) {
|
||||
headers['X-Harbor-CSRF-Token'] = token;
|
||||
}
|
||||
}
|
||||
return request;
|
||||
},
|
||||
responseInterceptor: response => {
|
||||
const headers = response.headers || {};
|
||||
const responseToken: string =
|
||||
headers['X-Harbor-CSRF-Token'];
|
||||
if (responseToken) {
|
||||
// Set the csrf token to localstorage
|
||||
localStorage.setItem('__csrf', responseToken);
|
||||
}
|
||||
return response;
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { DevCenterComponent } from './dev-center.component';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DevCenterComponent,
|
||||
},
|
||||
];
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
declarations: [DevCenterComponent],
|
||||
})
|
||||
export class DeveloperCenterModule {}
|
|
@ -30,13 +30,6 @@ const harborRoutes: Routes = [
|
|||
loadChildren: () =>
|
||||
import('./account/account.module').then(m => m.AccountModule),
|
||||
},
|
||||
{
|
||||
path: 'devcenter-api-2.0',
|
||||
loadChildren: () =>
|
||||
import('./dev-center/dev-center.module').then(
|
||||
m => m.DeveloperCenterModule
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'oidc-onboard',
|
||||
canActivate: [OidcGuard, SignInGuard],
|
||||
|
|
|
@ -79,6 +79,3 @@ import 'zone.js'; // Included with Angular CLI.
|
|||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
||||
(window as any).global = window; // this is for swagger UI
|
||||
// @ts-ignore
|
||||
window.Buffer = window.Buffer || require('buffer').Buffer; // this is for swagger UI
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"stream": [ "./node_modules/stream-browserify" ]
|
||||
},
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
|
|
Loading…
Reference in New Issue