TASKS-1823 WebManager module

This commit is contained in:
Igor Martyniuk
2026-08-28 08:35:58 +00:00
parent fdb2cf3837
commit c93d8c025b
654 changed files with 26232 additions and 6075 deletions
@@ -0,0 +1,50 @@
import { BREADCRUMB_PAGE_TYPE_PARENTS } from '#base_modules/WebManager/config/general'
/**
* Utility functions that identify candidate pages for buildBreadcrumbs database queries.
* Breadcrumbs climb hierarchically from a target page to the home page.
* To avoid querying all published pages in a locale, queries are filtered down to two
* predictable sets of candidates:
* 1. Path-based ancestors: The small chain of parent paths above the target page.
* 2. Group-key ancestors: Static relationships where pages belong to a specific parent
* type regardless of location (e.g., blog-item under blog).
*/
export const BREADCRUMB_PARENT_GROUP_KEYS = [
...new Set(Object.values(BREADCRUMB_PAGE_TYPE_PARENTS)),
]
/**
* The paths a page can climb to, nearest parent first, ending at the home page (`''`).
*
* 'blog/post/hello' → ['blog/post', 'blog', '']
* 'about' → ['']
* '' → ['']
*
* The page's own path is never included — a page cannot be its own parent.
*/
export function ancestorPaths(path: string) {
const segments = path.split('/').filter(Boolean)
const paths: string[] = []
for (let depth = segments.length - 1; depth >= 1; depth--) {
paths.push(segments.slice(0, depth).join('/'))
}
paths.push('')
return paths
}
/**
* True when `path` is an already loaded path or an ancestor of one. Only false after a
* group-key jump to another branch, never during a path climb.
*/
export function ancestorsAlreadyLoaded(path: string, loadedPaths: Iterable<string>) {
for (const loaded of loadedPaths) {
// The trailing slash keeps 'blog' from matching 'blogging'; '' matches every path.
if (loaded === path || loaded.startsWith(path === '' ? '' : `${path}/`)) return true
}
return false
}