Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions frontend/src/components/CippCards/CippUniversalSearchV2.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,35 @@ async function loadTabOptions() {
"/tenant/gdap-management",
"/tenant/gdap-management/relationships/relationship",
"/cipp/settings",
// Template pages folded into their parent pages as tabs — listed here so the
// universal page search still indexes them (they are no longer nav leaves).
"/email/administration/contacts",
"/email/administration/tenant-allow-block-lists",
"/email/transport/list-rules",
"/email/transport/list-connectors",
"/email/spamfilter/list-spamfilter",
"/email/spamfilter/list-connectionfilter",
"/security/safelinks/safelinks",
"/security/compliance/dlp",
"/security/compliance/retention",
"/security/compliance/labels",
"/security/compliance/sit",
"/identity/administration/groups",
"/identity/administration/jit-admin",
"/endpoint/MEM/list-policies",
"/endpoint/MEM/reusable-settings",
"/endpoint/MEM/assignment-filters",
"/endpoint/applications/list",
"/tenant/conditional/list-policies",
"/teams-share/sharepoint",
];

const tabOptions = [];

for (const basePath of tabOptionPaths) {
try {
const module = await import(`../../pages${basePath}/tabOptions.json`);
const options = module.default || module;
const tabModule = await import(`../../pages${basePath}/tabOptions.json`);
const options = tabModule.default || tabModule;

options.forEach((option) => {
tabOptions.push({
Expand Down Expand Up @@ -242,6 +263,11 @@ export const CippUniversalSearchV2 = React.forwardRef(
const normalizedTabPath = tab.path.replace(/\/$/, "");
const normalizedBasePath = tab.basePath?.replace(/\/$/, "");

// A tab whose own path is a real nav leaf is already surfaced as a Page result
// (every tabOptions list starts with its parent). Skip it here so it is not listed
// twice — the same page once as "Page" and once as "Tab".
if (leafItemIndex[normalizedTabPath]) return null;

let pageItem = leafItemIndex[normalizedTabPath];

if (!pageItem && normalizedBasePath) {
Expand Down
191 changes: 45 additions & 146 deletions frontend/src/layouts/config.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ export const nativeMenuItems = [
path: '/identity/administration/groups',
permissions: ['Identity.Group.*'],
},
{
title: 'Group Templates',
path: '/identity/administration/group-templates',
permissions: ['Identity.Group.*'],
scope: 'global',
},
{
title: 'Devices',
path: '/identity/administration/devices',
Expand All @@ -72,18 +66,6 @@ export const nativeMenuItems = [
path: '/identity/administration/jit-admin',
permissions: ['Identity.Role.*'],
},
{
title: 'JIT Admin Templates',
path: '/identity/administration/jit-admin-templates',
permissions: ['Identity.Role.*'],
scope: 'global',
},
{
title: 'JIT Role Templates',
path: '/identity/administration/jit-role-templates',
permissions: ['Identity.Role.*'],
scope: 'global',
},
{
title: 'Vacation Mode',
path: '/identity/administration/vacation-mode',
Expand Down Expand Up @@ -251,10 +233,9 @@ export const nativeMenuItems = [
permissions: ['Tenant.ConditionalAccess.*'],
},
{
title: 'CA Templates',
path: '/tenant/conditional/list-template',
title: 'CA Vacation Mode',
path: '/tenant/conditional/deploy-vacation',
permissions: ['Tenant.ConditionalAccess.*'],
scope: 'global',
},
{
title: 'Named Locations',
Expand Down Expand Up @@ -406,12 +387,6 @@ export const nativeMenuItems = [
path: '/security/safelinks/safelinks',
permissions: ['Security.SafeLinksPolicy.*'],
},
{
title: 'Safe Links Templates',
path: '/security/safelinks/safelinks-template',
permissions: ['Security.SafeLinksPolicy.*'],
scope: 'global',
},
],
},
{
Expand All @@ -428,45 +403,21 @@ export const nativeMenuItems = [
path: '/security/compliance/dlp',
permissions: ['Security.DlpCompliancePolicy.*'],
},
{
title: 'DLP Policy Templates',
path: '/security/compliance/dlp-templates',
permissions: ['Security.DlpCompliancePolicy.*'],
scope: 'global',
},
{
title: 'Retention Policies',
path: '/security/compliance/retention',
permissions: ['Security.RetentionCompliancePolicy.*'],
},
{
title: 'Retention Policy Templates',
path: '/security/compliance/retention-templates',
permissions: ['Security.RetentionCompliancePolicy.*'],
scope: 'global',
},
{
title: 'Sensitivity Labels',
path: '/security/compliance/labels',
permissions: ['Security.SensitivityLabel.*'],
},
{
title: 'Sensitivity Label Templates',
path: '/security/compliance/labels-templates',
permissions: ['Security.SensitivityLabel.*'],
scope: 'global',
},
{
title: 'Sensitive Information Types',
path: '/security/compliance/sit',
permissions: ['Security.SensitiveInfoType.*'],
},
{
title: 'Sensitive Info Type Templates',
path: '/security/compliance/sit-templates',
permissions: ['Security.SensitiveInfoType.*'],
scope: 'global',
},
],
},
],
Expand Down Expand Up @@ -555,13 +506,6 @@ export const nativeMenuItems = [
path: '/endpoint/applications/queue',
permissions: ['Endpoint.Application.*'],
},
{
title: 'Application Templates',
path: '/endpoint/applications/templates',
docsPath: 'endpoint/applications/application-templates',
permissions: ['Endpoint.Application.*'],
scope: 'global',
},
],
},
{
Expand Down Expand Up @@ -624,39 +568,18 @@ export const nativeMenuItems = [
docsPath: 'endpoint/mem/list-appprotection-policies',
permissions: ['Endpoint.MEM.*'],
},
{
title: 'Policy Templates',
path: '/endpoint/MEM/list-templates',
docsPath: 'endpoint/mem/list-templates',
permissions: ['Endpoint.MEM.*'],
scope: 'global',
},
{
title: 'Reusable Settings',
path: '/endpoint/MEM/reusable-settings',
docsPath: 'endpoint/mem/reusable-settings',
permissions: ['Endpoint.MEM.*'],
},
{
title: 'Reusable Settings Templates',
path: '/endpoint/MEM/reusable-settings-templates',
docsPath: 'endpoint/mem/reusable-settings-templates',
permissions: ['Endpoint.MEM.*'],
scope: 'global',
},
{
title: 'Assignment Filters',
path: '/endpoint/MEM/assignment-filters',
docsPath: 'endpoint/mem/assignment-filters',
permissions: ['Endpoint.MEM.*'],
},
{
title: 'Assignment Filter Templates',
path: '/endpoint/MEM/assignment-filter-templates',
docsPath: 'endpoint/mem/assignment-filter-templates',
permissions: ['Endpoint.MEM.*'],
scope: 'global',
},
{
title: 'Scripts',
path: '/endpoint/MEM/list-scripts',
Expand Down Expand Up @@ -729,25 +652,28 @@ export const nativeMenuItems = [
path: '/teams-share/sharepoint',
permissions: ['Sharepoint.Admin.*'],
},
{
title: 'SharePoint Templates',
path: '/teams-share/sharepoint-templates',
permissions: ['Sharepoint.Admin.*'],
},
{
title: 'Deleted Sites',
path: '/teams-share/deleted-sites',
permissions: ['Sharepoint.Admin.*'],
},
{
title: 'Sharing Report',
path: '/teams-share/sharing-report',
permissions: ['Sharepoint.Site.*'],
},
{
title: 'Permissions Report',
path: '/teams-share/permissions-report',
title: 'Reports',
permissions: ['Sharepoint.Site.*'],
items: [
{
title: 'Sharing Report',
path: '/teams-share/reports/sharing-report',
docsPath: 'teams-share/sharing-report',
permissions: ['Sharepoint.Site.*'],
},
{
title: 'Permissions Report',
path: '/teams-share/reports/permissions-report',
docsPath: 'teams-share/permissions-report',
permissions: ['Sharepoint.Site.*'],
},
],
},
{
title: 'External Users',
Expand Down Expand Up @@ -828,12 +754,6 @@ export const nativeMenuItems = [
path: '/email/administration/contacts',
permissions: ['Exchange.Contact.*'],
},
{
title: 'Contact Templates',
path: '/email/administration/contacts-template',
permissions: ['Exchange.Contact.*'],
scope: 'global',
},
{
title: 'Quarantine',
path: '/email/administration/quarantine',
Expand All @@ -849,12 +769,6 @@ export const nativeMenuItems = [
path: '/email/administration/tenant-allow-block-lists',
permissions: ['Exchange.SpamFilter.*'],
},
{
title: 'Allow/Block List Templates',
path: '/email/administration/tenant-allow-block-list-templates',
permissions: ['Exchange.SpamFilter.*'],
scope: 'global',
},
{
title: 'Retention Policies & Tags',
path: '/email/administration/exchange-retention/policies',
Expand All @@ -871,23 +785,11 @@ export const nativeMenuItems = [
path: '/email/transport/list-rules',
permissions: ['Exchange.TransportRule.*'],
},
{
title: 'Transport Templates',
path: '/email/transport/list-templates',
permissions: ['Exchange.TransportRule.*'],
scope: 'global',
},
{
title: 'Connectors',
path: '/email/transport/list-connectors',
permissions: ['Exchange.Connector.*'],
},
{
title: 'Connector Templates',
path: '/email/transport/list-connector-templates',
permissions: ['Exchange.Connector.*'],
scope: 'global',
},
],
},
{
Expand All @@ -899,23 +801,11 @@ export const nativeMenuItems = [
path: '/email/spamfilter/list-spamfilter',
permissions: ['Exchange.SpamFilter.*'],
},
{
title: 'Spamfilter Templates',
path: '/email/spamfilter/list-templates',
permissions: ['Exchange.SpamFilter.*'],
scope: 'global',
},
{
title: 'Connection Filter',
path: '/email/spamfilter/list-connectionfilter',
permissions: ['Exchange.ConnectionFilter.*'],
},
{
title: 'Connection Filter Templates',
path: '/email/spamfilter/list-connectionfilter-templates',
permissions: ['Exchange.ConnectionFilter.*'],
scope: 'global',
},
{
title: 'Quarantine Policies',
path: '/email/spamfilter/list-quarantine-policies',
Expand Down Expand Up @@ -1158,25 +1048,34 @@ export const nativeMenuItems = [
scope: 'global',
},
{
title: 'Template Library',
path: '/tools/templatelib',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['CIPP.Core.*'],
scope: 'global',
},
{
title: 'Catalog',
path: '/tools/community-repos',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['CIPP.Core.*'],
scope: 'global',
},
{
title: 'Template Package Manager',
path: '/tools/template-packages',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['Tenant.ConditionalAccess.*', 'Endpoint.MEM.*'],
scope: 'global',
title: 'Template Tools',
permissions: ['CIPP.Core.*', 'Tenant.ConditionalAccess.*', 'Endpoint.MEM.*'],
items: [
{
title: 'Template Library',
path: '/tools/template-tools/templatelib',
docsPath: 'tools/templatelib',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['CIPP.Core.*'],
scope: 'global',
},
{
title: 'Catalog',
path: '/tools/template-tools/community-repos',
docsPath: 'tools/community-repos',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['CIPP.Core.*'],
scope: 'global',
},
{
title: 'Template Package Manager',
path: '/tools/template-tools/template-packages',
docsPath: 'tools/template-packages',
roles: ['editor', 'admin', 'superadmin'],
permissions: ['Tenant.ConditionalAccess.*', 'Endpoint.MEM.*'],
scope: 'global',
},
],
},
{
title: 'Scheduler',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Layout as DashboardLayout } from "../../../../layouts/index";
import { TabbedLayout } from "../../../../layouts/TabbedLayout";
import tabOptions from "../contacts/tabOptions.json";
import { CippIcons } from "../../../../utils/icon-registry"
import { Button } from "@mui/material";
import Link from "next/link";
Expand Down Expand Up @@ -112,5 +114,9 @@ const Page = () => {
);
};

Page.getLayout = (page) => <DashboardLayout>{page}</DashboardLayout>;
Page.getLayout = (page) => (
<DashboardLayout>
<TabbedLayout tabOptions={tabOptions}>{page}</TabbedLayout>
</DashboardLayout>
);
export default Page;
Loading
Loading