+ )
+ }
+}
diff --git a/src/core/components/operations.jsx b/src/core/components/operations.jsx
index b50e2afb4cf..8f32b9694f5 100644
--- a/src/core/components/operations.jsx
+++ b/src/core/components/operations.jsx
@@ -8,7 +8,6 @@ const SWAGGER2_OPERATION_METHODS = [
const OAS3_OPERATION_METHODS = SWAGGER2_OPERATION_METHODS.concat(["trace"])
-
export default class Operations extends React.Component {
static propTypes = {
@@ -36,84 +35,163 @@ export default class Operations extends React.Component {
fn
} = this.props
- let taggedOps = specSelectors.taggedOperations()
-
- const OperationContainer = getComponent("OperationContainer", true)
- const OperationTag = getComponent("OperationTag")
-
+ // Get pertinent options
let {
maxDisplayedTags,
- } = getConfigs()
+ hierarchicalTags,
+ tagSplitterChar,
+ } = getConfigs();
- let filter = layoutSelectors.currentFilter()
+ // Set default tagSplitterChar if necessary
+ tagSplitterChar = tagSplitterChar || /[:|]/;
+
+ // Get a flat map of tag names to tag info and operations. Note that this will always return a
+ // flat list, even if the `hierarchicalTags` option is set to `true`.
+ let taggedOps = specSelectors.taggedOperations()
+ // Filter, if requested
+ let filter = layoutSelectors.currentFilter()
if (filter) {
if (filter !== true && filter !== "true" && filter !== "false") {
taggedOps = fn.opsFilter(taggedOps, filter)
}
}
+ // Limit to [max] items, if specified
if (maxDisplayedTags && !isNaN(maxDisplayedTags) && maxDisplayedTags >= 0) {
taggedOps = taggedOps.slice(0, maxDisplayedTags)
}
- return (
-
- {
- taggedOps.map( (tagObj, tag) => {
- const operations = tagObj.get("operations")
- return (
-
- {
- operations.map( op => {
- const path = op.get("path")
- const method = op.get("method")
- const specPath = Im.List(["paths", path, method])
-
-
- // FIXME: (someday) this logic should probably be in a selector,
- // but doing so would require further opening up
- // selectors to the plugin system, to allow for dynamic
- // overriding of low-level selectors that other selectors
- // rely on. --KS, 12/17
- const validMethods = specSelectors.isOAS3() ?
- OAS3_OPERATION_METHODS : SWAGGER2_OPERATION_METHODS
-
- if(validMethods.indexOf(method) === -1) {
- return null
- }
-
- return
- }).toArray()
- }
-
-
-
- )
- }).toArray()
+ // Render either hierarchical or flat depending on config
+ if (hierarchicalTags) {
+ // If the `hierarchicalTags` option is set, we want to break down the tags into a deep
+ // hierarchy. We're using a "raw" object for cleanliness here, but later we'll convert that
+ // into an immutable map. Here are the types we're dealing with:
+ //
+ // const operationTagsRaw: TagMap;
+ // type TagMap = { [TagName: string]: TagData };
+ // type TagData = {
+ // canonicalName: string;
+ // data: TagInfoAndOperations | null;
+ // childTags: TagMap;
+ // }
+ // TODO: Explicitly define TagInfoAndOperations
+
+ const operationTagsRaw = {};
+
+ // For each raw tag....
+ taggedOps.map((tagObj, tagName) => {
+ // Split the raw tag name into parts
+ const parts = tagName.split(tagSplitterChar);
+
+ // Set a pointer for use in traversing the hierarchy
+ let current = operationTagsRaw;
+
+ // Iterate through the parts defined by this tag
+ for (let i = 0; i < parts.length; i++) {
+ const part = parts[i];
+
+ // If there's no object defined for the current part, define one with just childTags as an
+ // empty set
+ if (current[part] === undefined) {
+ // Compose canonical name from parts up to this point
+ const canonicalName = parts.reduce(
+ (name, p, j) => ((j > i) ? name : name.concat([p])),
+ []
+ ).join("|");
+ current[part] = {
+ canonicalName,
+ data: null,
+ childTags: {}
+ }
}
- { taggedOps.size < 1 ?
No operations defined in spec!
: null }
-
- )
- }
+ // If this is the last part, set data on this object
+ if (i === parts.length - 1) {
+ current[part].data = tagObj;
+ }
+ // Move to the next level of the hierarchy before looping around
+ current = current[part].childTags;
+ }
+ });
+
+ // Convert to immutable map
+ const operationTags = Im.fromJS(operationTagsRaw);
+ const HierarchicalOperationTag = getComponent("HierarchicalOperationTag")
+ return operationTags.size === 0
+ ?