Skip to content

Commit

Permalink
Backport 1.15.x Update packages and OpenApi styling (#23700) (#23833)
Browse files Browse the repository at this point in the history
* Update packages and OpenApi styling (#23700)

* update packages

* changelog

* wip better

* clean up

* and it works, it always worked we just hid it working :/

* clean up

* playing around with adding the queryparam, not working

* the fix no queryparams

* lets just see how this works out.

* maybe this will help

* remove copy/pasta

* Update ui/lib/open-api-explorer/addon/components/swagger-ui.js

Co-authored-by: Jordan Reimer <zofskeez@gmail.com>

---------

Co-authored-by: Jordan Reimer <zofskeez@gmail.com>

* Update swagger-ui-test.js

---------

Co-authored-by: Jordan Reimer <zofskeez@gmail.com>
  • Loading branch information
Monkeychip and zofskeez authored Oct 26, 2023
1 parent 7754bc7 commit e5d1a0f
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 344 deletions.
3 changes: 3 additions & 0 deletions changelog/23700.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: Update flat, shell-quote and swagger-ui-dist packages. Remove swagger-ui styling overrides.
```
3 changes: 3 additions & 0 deletions ui/app/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
@import './utils/mixins';
@import './utils/animations';

// Open-api styling
@import './utils/swagger';

// Core Styles: each file styles a class that is not associated with a component. Ex: box and not box-label.
@import './core/box';
@import './core/breadcrumb';
Expand Down
11 changes: 11 additions & 0 deletions ui/app/styles/utils/swagger.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

// This file defines the scss for open-api-explorer.

/* align list items with container */
.swagger-ember .swagger-ui .wrapper {
padding: 0;
}
169 changes: 76 additions & 93 deletions ui/lib/open-api-explorer/addon/components/swagger-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,107 +3,90 @@
* SPDX-License-Identifier: BUSL-1.1
*/

import Component from '@ember/component';
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import parseURL from 'core/utils/parse-url';
import config from 'open-api-explorer/config/environment';
import { guidFor } from '@ember/object/internals';

const { APP } = config;

const SearchFilterPlugin = () => {
return {
fn: {
opsFilter: (taggedOps, phrase) => {
// map over the options and filter out operations where the path doesn't match what's typed
return (
taggedOps
.map((tagObj) => {
const operations = tagObj.get('operations').filter((operationObj) => {
return operationObj.get('path').includes(phrase);
});
return tagObj.set('operations', operations);
})
// then traverse again and remove the top level item if there are no operations left after filtering
.filter((tagObj) => !!tagObj.get('operations').size)
);
},
},
};
};
export default class SwaggerUiComponent extends Component {
@service auth;
@service namespace;

const CONFIG = (SwaggerUIBundle, componentInstance, initialFilter) => {
return {
dom_id: `#${componentInstance.elementId}-swagger`,
url: '/v1/sys/internal/specs/openapi',
deepLinking: false,
presets: [SwaggerUIBundle.presets.apis],
plugins: [SwaggerUIBundle.plugins.DownloadUrl, SearchFilterPlugin],
// 'list' expands tags, but not operations
docExpansion: 'list',
operationsSorter: 'alpha',
filter: initialFilter || true,
// this makes sure we show the x-vault- options
showExtensions: true,
// we don't have any models defined currently
defaultModelsExpandDepth: -1,
defaultModelExpandDepth: 1,
requestInterceptor: (req) => {
// we need to add vault authorization header
// and namepace headers for things to work properly
req.headers['X-Vault-Token'] = componentInstance.auth.currentToken;
@tracked swaggerLoading = true;

const namespace = componentInstance.namespaceService.path;
if (namespace && !APP.NAMESPACE_ROOT_URLS.some((str) => req.url.includes(str))) {
req.headers['X-Vault-Namespace'] = namespace;
}
// we want to link to the right JSON in swagger UI so
// it's already been pre-pended
if (!req.loadSpec) {
const { protocol, host, pathname, search } = parseURL(req.url);
//paths in the spec don't have /v1 in them, so we need to add that here
// http(s): vlt.io:4200 /sys/mounts
req.url = `${protocol}//${host}/v1${pathname}${search}`;
}
return req;
},
onComplete: () => {
componentInstance.set('swaggerLoading', false);
},
};
};
inputId = `${guidFor(this)}-swagger`;

export default Component.extend({
auth: service(),
namespaceService: service('namespace'),
initialFilter: null,
onFilterChange() {},
swaggerLoading: true,
SearchFilterPlugin() {
return {
fn: {
opsFilter: (taggedOps, phrase) => {
// map over the options and filter out operations where the path doesn't match what's typed
return (
taggedOps
.map((tagObj) => {
const operations = tagObj.get('operations').filter((operationObj) => {
return operationObj.get('path').includes(phrase);
});
return tagObj.set('operations', operations);
})
// then traverse again and remove the top level item if there are no operations left after filtering
.filter((tagObj) => !!tagObj.get('operations').size)
);
},
},
};
}

async didInsertElement() {
const { default: SwaggerUIBundle } = await import('swagger-ui-dist/swagger-ui-bundle.js');
this._super(...arguments);
// trim any initial slashes
const initialFilter = this.initialFilter.replace(/^(\/)+/, '');
SwaggerUIBundle(CONFIG(SwaggerUIBundle, this, initialFilter));
},
CONFIG = (SwaggerUIBundle, componentInstance) => {
return {
dom_id: `#${componentInstance.inputId}`,
url: '/v1/sys/internal/specs/openapi',
deepLinking: false,
presets: [SwaggerUIBundle.presets.apis],
plugins: [SwaggerUIBundle.plugins.DownloadUrl, this.SearchFilterPlugin],
// 'list' expands tags, but not operations
docExpansion: 'list',
operationsSorter: 'alpha',
filter: true,
// this makes sure we show the x-vault- options
showExtensions: true,
// we don't have any models defined currently
defaultModelsExpandDepth: -1,
defaultModelExpandDepth: 1,
requestInterceptor: (req) => {
// we need to add vault authorization header
// and namespace headers for things to work properly
req.headers['X-Vault-Token'] = componentInstance.auth.currentToken;
const namespace = componentInstance.namespace.path;
if (namespace && !APP.NAMESPACE_ROOT_URLS.some((str) => req.url.includes(str))) {
req.headers['X-Vault-Namespace'] = namespace;
}
// we want to link to the right JSON in swagger UI so
// it's already been pre-pended
if (!req.loadSpec) {
const { protocol, host, pathname, search } = parseURL(req.url);
//paths in the spec don't have /v1 in them, so we need to add that here
// http(s): vlt.io:4200 /sys/mounts
req.url = `${protocol}//${host}/v1${pathname}${search}`;
}
return req;
},
onComplete: () => {
componentInstance.swaggerLoading = false;
},
};
};

actions: {
// sets the filter so the query param is updated so we get sharable URLs
updateFilter(e) {
this.onFilterChange(e.target.value || '');
},
proxyEvent(e) {
const swaggerInput = this.element.querySelector('.operation-filter-input');
// if this breaks because of a react upgrade,
// change this to
//let originalSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
//originalSetter.call(swaggerInput, e.target.value);
// see post on triggering react events externally for an explanation of
// why this works: https://stackoverflow.com/a/46012210
const evt = new Event('input', { bubbles: true });
evt.simulated = true;
swaggerInput.value = e.target.value.replace(/^(\/)+/, '');
swaggerInput.dispatchEvent(evt);
},
},
});
// using an action to bind the correct "this" context
@action async swaggerInit() {
const { default: SwaggerUIBundle } = await import('swagger-ui-dist/swagger-ui-bundle.js');
// trim any slashes on the filter value
const configSettings = this.CONFIG(SwaggerUIBundle, this);
SwaggerUIBundle(configSettings);
}
}
11 changes: 0 additions & 11 deletions ui/lib/open-api-explorer/addon/controllers/index.js

This file was deleted.

12 changes: 5 additions & 7 deletions ui/lib/open-api-explorer/addon/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default Route.extend({
flashMessages: service(),
// without an empty model hook here, ember likes to use the parent model, and then things get weird with
// query params, so here we're no-op'ing the model hook
model() {},
export default class OpenApiExplorerIndex extends Route {
@service flashMessages;

afterModel() {
const warning = `The "Try it out" functionality in this API explorer will make requests to this Vault server on your behalf.
Expand All @@ -21,5 +19,5 @@ Your token will also be shown on the screen in the example curl command output.`
sticky: true,
preformatted: true,
});
},
});
}
}
Loading

0 comments on commit e5d1a0f

Please sign in to comment.