Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request and Implementation for Multi-Level Tag Grouping #2482

Open
fakeyanss opened this issue Jan 26, 2024 · 3 comments
Open

Feature Request and Implementation for Multi-Level Tag Grouping #2482

fakeyanss opened this issue Jan 26, 2024 · 3 comments

Comments

@fakeyanss
Copy link

fakeyanss commented Jan 26, 2024

Dear Developer Team,

I encountered a need similar to issue #1489 during my use: the requirement for multi-level tag grouping. Currently, the three-tier structure provided by x-tagGroups (group - tag - operation) seems insufficient for our needs. Additionally, when I attempted to define a description for x-tagGroups, I discovered that it does not support the corresponding syntax.

With complex service systems and a large number of APIs, a three-tier sidebar can easily become overly lengthy. When dealing with complex businesses, maintaining a structured relationship is more conducive to understanding and managing APIs than simply flattening all relationships.

I’ve read the code related to the sidebar logic in the redoc project and attempted to modify the MenuBuilder class on my own to implement the nested tag feature, without limiting the number of nesting levels. Theoretically, as long as the page width allows, an unlimited number of nesting levels is possible.

I noticed in the MenuBuilder.ts#GroupModel class that a parent property has already been defined to represent parent-child relationships, which made my modification work relatively straightforward. I’m curious to know if the developer team originally planned to support multi-level tagging.

export class GroupModel implements IMenuItem {
...
  parent?: GroupModel;
...

To achieve multi-level tagging, I’ve established a naming convention within my team, using slashes / to separate multiple tag names (such as tag_name1/tag_name2/tag_name3).

An multi-level tag example like this:

tags:
  - name: pet
    description: Everything about your Pets
  - name: pet/pet1111111
    x-displayName: pet1111111
  - name: pet/pet2222222
    x-displayName: pet2222222
  - name: pet/pet2222222/pet21111111
    x-displayName: pet21111111

Then, I rewrote the MenuBuilder.ts#getTagsItems method to properly handle tags with slashes and nest them under their respective parent tags.

      const slashCount = tag.name.split('/').length - 1;
      if (slashCount > 0) {
        const rootTagname = tag.name.substring(0, tag.name.indexOf('/'));
        const rootItem = resMap[rootTagname];
        let parentItem;
        const parentTagNames = tag.name.split('/');
        for (let i = 0; i < slashCount; i++) {
          if (i == 0) {
            parentItem = rootItem;
          } else {
            parentItem = <GroupModel>(
              parentItem.items.filter(it => it.name === parentTagNames[i])[0]
            );
          }
        }
        item.parent = parentItem;
        parentItem.items.push(item);
        // reset depthes for items
        for (const it of parentItem.items) {
          it.depth = parentItem.depth + 1;
        }
        for (const it of item.items) {
          it.depth = item.depth + 1;
        }
      } else {
        res.push(item);
        resMap[tag.name] = item;
      }

Additionally, I adjusted the CSS definition in styled.elements.ts#menuItemDepth so that different levels of tag items can calculate their left padding based on their depth.

export const menuItemDepth = {
  0: css`
    opacity: 0.7;
    text-transform: ${({ theme }) => theme.sidebar.groupItems.textTransform};
    font-size: 0.8em;
    padding-bottom: 0;
    cursor: default;
  `,
  1: css`
    font-size: 0.929em;
    text-transform: ${({ theme }) => theme.sidebar.level1Items.textTransform};
  `,
  2: css`
    padding-left: ${20 + 10}px;
  `,
  3: css`
    padding-left: ${20 + 10 * 2}px;
  `,
  4: css`
    padding-left: ${20 + 10 * 3}px;
  `,
  5: css`
    padding-left: ${20 + 10 * 4}px;
  `,
  6: css`
    padding-left: ${20 + 10 * 5}px;
  `,
  7: css`
    padding-left: ${20 + 10 * 6}px;
  `,
  8: css`
    padding-left: ${20 + 10 * 7}px;
  `,
  9: css`
    padding-left: ${20 + 10 * 8}px;
  `,
  10: css`
    padding-left: ${20 + 10 * 9}px;
  `,
};

Although I am a backend developer with just a basic understanding of JS, my modifications may not be the most elegant. However, I’m curious to know if there is a plan by the development team to support the functionality of multi-level tag nesting? If interested in the modifications I’ve made, I’d be happy to submit a PR for your assessment.

Thank you for your hard work, looking forward to your reply.

Attachment:

image
@fakeyanss fakeyanss changed the title Support nested tags Feature Request and Implementation for Multi-Level Tag Grouping Jan 26, 2024
@fakeyanss fakeyanss reopened this Jan 26, 2024
@Orest-Yastremskyy
Copy link

Hi @fakeyanss,

Thank you for taking the time to share this idea with us.

I have added it to our list of ideas so that our Product Team can evaluate how it fits our roadmap.

As soon as we have news regarding this, we will be sure to let you know.

@cleverly87
Copy link

Love this idea - just even having that one additional level would make such a difference to it

@fakeyanss
Copy link
Author

I’m glad that nested tags will be supported by developers. If anyone else wants to experience this feature, you can rely on my fork implementation, with the npm scope package being @fakeyanss/redocly-cli.

@fakeyanss fakeyanss reopened this Feb 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants