Open MastersoftGroup opened 3 years ago
Hi, thanks for creating a ticket. The feature you are looking for is a whole word match. I'm updating the ticket title to reflect this. That said, we're open to any and all PR feature requests. ;)
@tim-lai @MastersoftGroup Just implemented the feature have a look at the preview.
The following is my implementation of an exact match filter. Having accomplished this I have a couple observations about what makes this more difficult than is otherwise apparent when looking at the solution.
import SwaggerUI from 'swagger-ui';
import { List, Map, OrderedMap } from 'immutable';
import { OpenAPI, OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
export type Operations = List<OpenAPI.Operation>; // But not really it is yet another Map :(
export type TagDetails = Map<'name' | 'description', string>;
export type TaggedOperations = OrderedMap<string, TaggedOperationCollection>;
export type TaggedOperationCollection = Map<'tagDetails', TagDetails> &
Map<'operations', Operations>;
...
private _renderSwaggerUI() {
SwaggerUI({
domNode: this.swaggerContainer?.nativeElement,
spec: this._options?.openApiDocument,
deepLinking: false,
withCredentials: false,
tryItOutEnabled: true,
filter: this._options?.tag?.name,
plugins: [
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(_system: unknown) => {
return {
fn: {
// The default filter function does a contains match on the filter expression.
// This may be useful when filtering based on a search input but is not useful
// when driving the filter from a tag selection in a navigation tree. We need
// an exact match on the tag name in this case.
opsFilter: (
taggedOps: TaggedOperations,
filterExpression: string
) => {
// The variable assignment and logging are solely for demonstrating that property access
// requires use of "magic strings" rather than providing typed access. Remove these in
// production code.
return taggedOps.filter((val, key) => {
const tagDetails: TagDetails | undefined =
val.get('tagDetails');
const operations: Operations | undefined =
val.get('operations');
console.log('tagDetails', tagDetails);
console.log('operations', operations);
return key === filterExpression;
});
},
},
};
},
]
});
}
...
Q&A (please complete the following information)
Content & configuration
Using SwaggerUIBundle with filter, which is using tags. I've noticed if I have a tag that the value contains in other tags (case-sensitive), e.g. tag "street" and tag "streetNumber", when I use
filter: "street"
, it will display all operations for "street" tag as well as "streetNumber" tag. I want to only display operations for "street" tag.Currently my workaround is adding an extra space: "street " tag, but this is not ideal because that means everytime we update or add new tags, we need to check all other tags to make sure no tag value contains other tag value.
To reproduce...
Steps to reproduce the behavior:
@ApiOperation
withtags
on method1 and method2:filter: "street"
to a html pageExpected behavior
My expectation is only operations for that exact tag value will be displayed, e.g. using the above example, only method1 should be displayed, not both method1 and method2.