/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/app/src/components/Navigation/utils.ts
126 строк
4 KB
Ken McGrady
Update copyright header to 2026 (#13491)
02 янв 2026, 16:21
Не верифицирован
02 янв 2026, 16:21
374540a
Код
Авторство
О чём код?
/** * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { groupBy } from "lodash-es" import { IAppPage } from "@streamlit/protobuf" export interface NavigationSections { [sectionHeader: string]: IAppPage[] } export interface ProcessedNavigation { individualPages: IAppPage[] sections: NavigationSections } /** * Determines if navigation should be shown based on pages and sections. * Navigation should be hidden only when: * - There is only 1 page total (no sections) * - There is 1 section with only 1 page in it * Otherwise, navigation should be shown. */ export function shouldShowNavigation( appPages: IAppPage[], navSections: string[] ): boolean { // If there's only one page total, hide nav if (appPages.length <= 1) { return false } // If there are no sections, we have multiple pages without sections, show nav if (navSections.length === 0) { return true } // If there are multiple sections, show nav if (navSections.length > 1) { return true } // If there's exactly one section, we need to check how many pages it has // If it has more than 1 page, show nav // The fact that we got here means appPages.length > 1 and navSections.length === 1 // So the single section must have multiple pages return true } /** * Groups app pages by their section header. */ export function groupPagesBySection(appPages: IAppPage[]): NavigationSections { return groupBy(appPages, page => page.sectionHeader || "") } /** * Determines if navigation should render with sections based on whether * there are any non-empty section headers. */ export function hasNonEmptySections(navSections: NavigationSections): boolean { return Object.keys(navSections).some(key => key !== "") } /** * Processes navigation sections to separate individual pages (those with empty * section headers) from sectioned pages when there are mixed sections. * * This ensures consistent behavior between sidebar and top navigation: * - Pages with empty section headers ("") are displayed as individual items * - Pages with non-empty section headers are grouped into sections */ export function processNavigationStructure( navSections: NavigationSections ): ProcessedNavigation { const hasNamedSections = hasNonEmptySections(navSections) if (!hasNamedSections) { // If there are no named sections, all pages are individual return { individualPages: Object.values(navSections).flat(), sections: {}, } } // If there are named sections, separate empty section pages as individuals const individualPages = navSections[""] || [] const sections: NavigationSections = {} Object.entries(navSections).forEach(([header, pages]) => { // Only include non-empty section headers if (header && header !== "" && header !== "undefined") { sections[header] = pages } }) return { individualPages, sections, } } /** * Helper to get all pages in display order (individuals first, then sections) */ export function getAllPagesInOrder( processed: ProcessedNavigation ): IAppPage[] { return [ ...processed.individualPages, ...Object.values(processed.sections).flat(), ] }