简体   繁体   中英

Angular nested array filtering based on another array (Navigation menu)

I have a navigation menu + a list of user roles. It's actually a legacy application and that's why I have so many user roles.

Basically, I want to show the navigation menu based on the roles the user has.

  • A user can have multiple roles.
  • A menu item can be accessed by multiple roles.
  • Compare the role mentioned in the menu item and child menu item with the user role array.

Both User role array and Navigation Item array are given below.

Basically, I want to reduce the navigation item array by comparing it to the user role.

User Role Array:

[ABS,ADM,AUTH,BAGGED,BLQ3E,MUMA12,MUMA13,MUMA14,MUMP12,MUMP13,MUMP14,MUMADM,MANAGER,SAF_ADM,XXXDDD,CRYPTRESP,SCHEDULEADM,INTERNALUSER,INTERNALMANAGER,GROUPHEAD,USER]

Nav Item array

export interface NavItem {
  displayName: string;
  disabled?: boolean;
  iconName: string;
  route?: string;
  children?: Array<NavItem>;
  role: string[];
}


navItems: Array<NavItem> = [
    {
      displayName: 'Accounts',
      iconName: 'account_circle',
      route: 'dummyroute',
      role: ['USER'],
      children: [
        {
          displayName: 'My Account',
          iconName: 'group',
          route: 'devfestfl/speakers',
          role: ['USER'],
        },
        {
          displayName: 'Change My Password',
          iconName: 'password',
          route: 'devfestfl/sessions',
          role: ['USER'],
        },
        {
          displayName: 'Manage Other Accounts',
          iconName: 'manage_accounts',
          route: 'devfestfl/feedback',
          role: ['ADM'],
        },
        {
          displayName: 'XXXX Accounts',
          iconName: 'account_tree',
          route: 'devfestfl/feedback',
          role: ['ADM'],
        },
        {
          displayName: 'XXXX',
          iconName: 'account_tree',
          route: 'dummyroute',
          role: ['ADM', 'SAF_ADM']
        }
      ]
    },
    {
      displayName: 'First Menu Item',
      iconName: 'dock',
      route: 'dummyroute',
      role: ['CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'ADM', 'CRG_USER', 'USER'],
      children: [
        {
          displayName: 'XX Menu Item',
          iconName: '',
          route: 'dummy',
          role: ['USER'],
        },
        {
          displayName: 'YY Menu Item',
          iconName: '',
          route: 'dummy',
          role: ['ADM'],
        },
        {
          displayName: 'ZZ Menu Item',
          iconName: '',
          route: 'dummy',
          role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'],
        }
        {
          displayName: 'PP Management',
          iconName: '',
          route: 'dummy',
          role: ['ADM', 'BAGGED'],
          children: [
            {
              displayName: 'PP Datasets',
              iconName: '',
              route: 'dummy',
              role: ['ADM'],
            },
            {
              displayName: 'PP Groups',
              iconName: '',
              route: 'dummy',
              role: ['BAGGED'],
            }
          ]
        },
        {
          displayName: 'Beamline Schedule',
          iconName: '',
          route: 'beamlineschedule',
          role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'INTERNALMANAGER'],
          children: [
            {
              displayName: 'Manage Schedule',
              iconName: '',
              route: 'manageschedule',
              role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'INTERNALMANAGER'],
            },
            {
              displayName: 'Show Finalized Runs',
              iconName: '',
              route: 'showfinalizedruns',
              role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'],
            },
            {
              displayName: 'Scheduling Bulk Import',
              iconName: '',
              route: 'schedulingbulkimport',
              role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'],
            },
            {
              displayName: 'Beamline Accounts',
              iconName: '',
              route: 'beamlineaccounts',
              role: ['ADM', 'ABS', 'BLQ3E'],
            }
          ]
        },
        {
          displayName: 'Machine Operation Schedule',
          iconName: '',
          route: 'machineoperationschedule',
          role: ['ADM'],
        },
        {
          displayName: 'End of Shift Forms',
          iconName: '',
          route: 'feedbackforms',
          role: ['ADM'],
        },
        {
          displayName: 'External Funded Proposals',
          iconName: '',
          route: 'externalfundedproposals',
          role: ['ADM'],
          children: [
            {
              displayName: 'Submitted Reports',
              iconName: '',
              route: 'submittedreports',
              role: ['ADM'],
            },
            {
              displayName: 'Pending Reports',
              iconName: '',
              route: 'pendingreports',
              role: ['ADM'],
            },
            {
              displayName: 'iNEXT-Discovery Proposals',
              iconName: '',
              route: 'inextdproposals',
              role: ['ADM'],
            }
          ]
        }
      ],
    },
    {
      displayName: 'Safety',
      iconName: 'health_and_safety',
      route: 'dummy',
      role: ['ADM', 'USER'],
      children: [
        {
          displayName: 'Safety child menu',
          iconName: '',
          route: 'dummy',
          role: ['ADM', 'USER'],
          children: [
            {
              displayName: 'safety grandchild',
              iconName: '',
              route: 'dummy',
              role: ['ADM', 'USER'],
            },
            {
              displayName: 'grandchild2',
              iconName: '',
              route: 'dummy',
              role: ['ADM', 'USER'],
            }
          ]
        },
        {
          displayName: 'safety second child menu',
          iconName: '',
          route: 'dummy',
          role: ['ADM'],
        }
      ]
    },
  ];

What I've tried until now has failed. The closest I've come is as below. I'm pretty sure I'm doing something wrong because it just doesn't work.

for (var navitem of this.navItems) {
  for (var userrole of this.userRolesArray) {
    if (navitem.role.some(item => item.includes(userrole))) {
      if (!this.newNavItemsArray.includes(navitem)) {
        for (var navchild of navitem.children) {
          if (navchild.role.some(item => item.includes(userrole))) {
            this.newNavItemsArray.push({ navitem, children: [navchild] })
          }
        }
      }
    }
  }
}

Please help:)

I took a different approach using reduce and a couple some methods. I assumed that if the target role was not in the main nav, it should skip the children.

navItems.reduce((b, a) => {
    if (!a.role.some(r => r === role)) return b;
    a.children = a.children.filter(f => f.role.some(r => r === role))
    return [...b, a]
  }, [])

 let navItems = [{ displayName: 'Accounts', iconName: 'account_circle', route: 'dummyroute', role: ['USER'], children: [{ displayName: 'My Account', iconName: 'group', route: 'devfestfl/speakers', role: ['USER'], }, { displayName: 'Change My Password', iconName: 'password', route: 'devfestfl/sessions', role: ['USER'], }, { displayName: 'Manage Other Accounts', iconName: 'manage_accounts', route: 'devfestfl/feedback', role: ['ADM'], }, { displayName: 'XXXX Accounts', iconName: 'account_tree', route: 'devfestfl/feedback', role: ['ADM'], }, { displayName: 'XXXX', iconName: 'account_tree', route: 'dummyroute', role: ['ADM', 'SAF_ADM'] } ] }, { displayName: 'First Menu Item', iconName: 'dock', route: 'dummyroute', role: ['CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'ADM', 'CRG_USER', 'USER'], children: [{ displayName: 'XX Menu Item', iconName: '', route: 'dummy', role: ['USER'], }, { displayName: 'YY Menu Item', iconName: '', route: 'dummy', role: ['ADM'], }, { displayName: 'ZZ Menu Item', iconName: '', route: 'dummy', role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'], }, { displayName: 'PP Management', iconName: '', route: 'dummy', role: ['ADM', 'BAGGED'], children: [{ displayName: 'PP Datasets', iconName: '', route: 'dummy', role: ['ADM'], }, { displayName: 'PP Groups', iconName: '', route: 'dummy', role: ['BAGGED'], } ] }, { displayName: 'Beamline Schedule', iconName: '', route: 'beamlineschedule', role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'INTERNALMANAGER'], children: [{ displayName: 'Manage Schedule', iconName: '', route: 'manageschedule', role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM', 'BLSTAFF', 'INTERNALMANAGER'], }, { displayName: 'Show Finalized Runs', iconName: '', route: 'showfinalizedruns', role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'], }, { displayName: 'Scheduling Bulk Import', iconName: '', route: 'schedulingbulkimport', role: ['ADM', 'CRYPTRESP', 'SCHEDULEADM'], }, { displayName: 'Beamline Accounts', iconName: '', route: 'beamlineaccounts', role: ['ADM', 'ABS', 'BLQ3E'], } ] }, { displayName: 'Machine Operation Schedule', iconName: '', route: 'machineoperationschedule', role: ['ADM'], }, { displayName: 'End of Shift Forms', iconName: '', route: 'feedbackforms', role: ['ADM'], }, { displayName: 'External Funded Proposals', iconName: '', route: 'externalfundedproposals', role: ['ADM'], children: [{ displayName: 'Submitted Reports', iconName: '', route: 'submittedreports', role: ['ADM'], }, { displayName: 'Pending Reports', iconName: '', route: 'pendingreports', role: ['ADM'], }, { displayName: 'iNEXT-Discovery Proposals', iconName: '', route: 'inextdproposals', role: ['ADM'], } ] } ], }, { displayName: 'Safety', iconName: 'health_and_safety', route: 'dummy', role: ['ADM', 'USER'], children: [{ displayName: 'Safety child menu', iconName: '', route: 'dummy', role: ['ADM', 'USER'], children: [{ displayName: 'safety grandchild', iconName: '', route: 'dummy', role: ['ADM', 'USER'], }, { displayName: 'grandchild2', iconName: '', route: 'dummy', role: ['ADM', 'USER'], } ] }, { displayName: 'safety second child menu', iconName: '', route: 'dummy', role: ['ADM'], } ] }, ]; const getNavForRole = (role) => { return navItems.reduce((b, a) => { if (.a.role;some(r => r === role)) return bachildren = a.children.filter(f => f.role.some(r => r === role)) return [..,b, a] }. []) } console.log(getNavForRole('CRYPTRESP')) console.log('------') console.log(getNavForRole('USER'))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM