Skip to content

Commit

Permalink
feat: Extend API operation filter in the Swagger UI (#2397)
Browse files Browse the repository at this point in the history
* Include utils folder for coverage

Signed-off-by: at670475 <[email protected]>

* refactoring and test

Signed-off-by: at670475 <[email protected]>
  • Loading branch information
taban03 authored May 31, 2022
1 parent 4ccc822 commit cffd6cf
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 2 deletions.
5 changes: 3 additions & 2 deletions api-catalog-ui/frontend/src/components/Swagger/SwaggerUI.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import './Swagger.css';
import InstanceInfo from '../ServiceTab/InstanceInfo';
import getBaseUrl from '../../helpers/urls';
import { BasicSnippedGenerator } from '../../utils/generateSnippets';
import { AdvancedFilterPlugin } from '../../utils/filterApis';

function transformSwaggerToCurrentHost(swagger) {
swagger.host = window.location.host;
Expand Down Expand Up @@ -101,7 +102,7 @@ export default class SwaggerUI extends Component {
spec: swagger,
presets: [SwaggerUi.presets.apis],
requestSnippetsEnabled: true,
plugins: [this.customPlugins, BasicSnippedGenerator],
plugins: [this.customPlugins, BasicSnippedGenerator, AdvancedFilterPlugin],
filter: true,
});
}
Expand All @@ -113,7 +114,7 @@ export default class SwaggerUI extends Component {
url,
presets: [SwaggerUi.presets.apis],
requestSnippetsEnabled: true,
plugins: [this.customPlugins, BasicSnippedGenerator],
plugins: [this.customPlugins, BasicSnippedGenerator, AdvancedFilterPlugin],
filter: true,
responseInterceptor: (res) => {
// response.text field is used to render the swagger
Expand Down
58 changes: 58 additions & 0 deletions api-catalog-ui/frontend/src/utils/filterApis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*/

/**
* Extend the filter by allowing to search not only by tags, but also by description and summary.
* The filter is also case-insensitive.
* @param phrase the search input
* @param taggedOps the API doc
* @param system the system
* @returns {*} the filtered API operation
*/
export function extendFilter(phrase, taggedOps, system) {
// eslint-disable-next-line no-param-reassign
phrase = phrase.toLowerCase();
const normalTaggedOps = JSON.parse(JSON.stringify(taggedOps));
Object.keys(normalTaggedOps).forEach((tagObj) => {
const { operations } = normalTaggedOps[tagObj];
let i = operations.length;
// eslint-disable-next-line no-plusplus
while (i--) {
const { operation } = operations[i];
if (
operations[i].path.toLowerCase().indexOf(phrase) === -1 &&
operation.summary !== undefined &&
operation.description !== undefined &&
operation.summary.toLowerCase().indexOf(phrase) === -1 &&
operation.description.toLowerCase().indexOf(phrase) === -1
) {
operations.splice(i, 1);
}
}
if (operations.length === 0) {
delete normalTaggedOps[tagObj];
} else {
normalTaggedOps[tagObj].operations = operations;
}
});
return system.Im.fromJS(normalTaggedOps);
}

/**
* Custom Plugin which extends the SwaggerUI filter functionality to filter APIs by tag, summary and description
*/
// eslint-disable-next-line import/prefer-default-export
export const AdvancedFilterPlugin = function (system) {
return {
fn: {
opsFilter: (taggedOps, phrase) => extendFilter(phrase, taggedOps, system),
},
};
};
84 changes: 84 additions & 0 deletions api-catalog-ui/frontend/src/utils/filterApis.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*/
import { extendFilter } from './filterApis';

describe('>>> Filter APIs', () => {
it('should filter the operation', () => {
const system = {
Im: {
fromJS: (obj) => obj,
},
};
const spec = {
'API Catalog': {
tagDetails: {
name: 'API Catalog',
description: 'Api Catalog Controller',
},
operations: [
{
path: '/containers',
method: 'get',
operation: {
tags: ['API Catalog'],
summary: 'Lists catalog dashboard tiles',
description: 'Returns a list of tiles including status and tile description',
operationId: 'getAllAPIContainersUsingGET',
produces: ['application/json'],
parameters: [],
responses: {
200: {
description: 'OK',
schema: {
type: 'array',
items: {
$ref: '#/definitions/APIContainer',
},
},
},
},
},
id: 'get-/containers',
},
{
path: '/containers/{id}',
method: 'get',
operation: {
tags: ['API Catalog'],
summary: 'Retrieves a specific dashboard tile information',
description:
'Returns information for a specific tile {id} including status and tile description',
operationId: 'getAPIContainerByIdUsingGET',
parameters: [
{
name: 'id',
},
],
responses: {
200: {
description: 'OK',
schema: {
type: 'array',
items: {
$ref: '#/definitions/APIContainer',
},
},
},
},
},
id: 'get-/containers/{id}',
},
],
},
};
const filteredApi = extendFilter('Lists catalog', spec, system);
expect(filteredApi['API Catalog'].operations[0].operation.summary).toEqual('Lists catalog dashboard tiles');
});
});

0 comments on commit cffd6cf

Please sign in to comment.