platform/plugins/controlled-documents-resources/src/navigation.ts
Denis Bykhov 8a08e5d620
Some checks are pending
CI / build (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions
Minor acrhived fixes (#7887)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
2025-02-03 22:37:59 +07:00

161 lines
5.1 KiB
TypeScript

//
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public 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 https://www.eclipse.org/legal/epl-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 documents, {
documentsId,
type ControlledDocument,
type Document,
type Project,
type ProjectDocument
} from '@hcengineering/controlled-documents'
import { type Doc, type Ref } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import { getCurrentResolvedLocation, getPanelURI, type Location, type ResolvedLocation } from '@hcengineering/ui'
import view, { type ObjectPanel } from '@hcengineering/view'
import { accessDeniedStore } from '@hcengineering/view-resources'
import slugify from 'slugify'
export function getPanelFragment<T extends Doc> (object: Pick<T, '_class' | '_id'>): string {
const hierarchy = getClient().getHierarchy()
const objectPanelMixin = hierarchy.classHierarchyMixin<Doc, ObjectPanel>(object._class, view.mixin.ObjectPanel)
const component = objectPanelMixin?.component ?? view.component.EditDoc
return getPanelURI(component, object._id, object._class, 'content')
}
async function generateDocumentLocation (
loc: Location,
document: Ref<ControlledDocument>
): Promise<ResolvedLocation | undefined> {
const client = getClient()
const doc = await client.findOne(documents.class.ControlledDocument, { _id: document }, { showArchived: true })
if (doc === undefined) {
accessDeniedStore.set(true)
console.error(`Could not find document ${document}.`)
return undefined
}
const appComponent = loc.path[0] ?? ''
const workspace = loc.path[1] ?? ''
return {
loc: {
path: [appComponent, workspace],
fragment: getPanelFragment(doc)
},
defaultLocation: {
path: [appComponent, workspace, documentsId, 'library'],
fragment: getPanelFragment(doc)
}
}
}
async function generateProjectDocumentLocation (
loc: Location,
document: Ref<ControlledDocument>,
project: Ref<Project>
): Promise<ResolvedLocation | undefined> {
const client = getClient()
const doc = await client.findOne(documents.class.ControlledDocument, { _id: document }, { showArchived: true })
if (doc === undefined) {
accessDeniedStore.set(true)
console.error(`Could not find document ${document}.`)
return undefined
}
const prjdoc = await client.findOne(documents.class.ProjectDocument, { document, project }, { showArchived: true })
if (prjdoc === undefined) {
accessDeniedStore.set(true)
console.error(`Could not find project document ${project} ${document}.`)
return undefined
}
const appComponent = loc.path[0] ?? ''
const workspace = loc.path[1] ?? ''
return {
loc: {
path: [appComponent, workspace],
fragment: getPanelFragment(prjdoc)
},
defaultLocation: {
path: [appComponent, workspace, documentsId, 'library'],
fragment: getPanelFragment(prjdoc)
}
}
}
export function getProjectDocumentLink (doc: Document | Ref<Document>, project: Ref<Project>): Location {
const loc = getCurrentResolvedLocation()
loc.fragment = undefined
loc.query = undefined
loc.path.length = 2
loc.path[2] = documentsId
loc.path[3] = typeof doc === 'string' ? doc : getDocumentLinkId(doc)
if (project !== documents.ids.NoProject) {
loc.path[4] = project
}
return loc
}
export function getDocumentLink (doc: Document): Location {
const loc = getCurrentResolvedLocation()
loc.fragment = undefined
loc.query = undefined
loc.path.length = 4
loc.path[2] = documentsId
loc.path[3] = getDocumentLinkId(doc)
return loc
}
function getDocumentLinkId (doc: Document): string {
const slug = slugify(doc.title, { lower: true })
return `${slug}---${doc._id}`
}
function parseDocumentId (shortLink?: string): Ref<ControlledDocument> | undefined {
if (shortLink === undefined) return undefined
const parts = shortLink.split('---')
if (parts.length > 1) {
return parts[parts.length - 1] as Ref<ControlledDocument>
}
return shortLink as Ref<ControlledDocument>
}
export function getDocumentIdFromFragment (fragment: string): Ref<ProjectDocument> | undefined {
const props = decodeURIComponent(fragment).split('|')
return props[1] != null ? (props[1] as Ref<ProjectDocument>) : undefined
}
export async function resolveLocation (loc: Location): Promise<ResolvedLocation | undefined> {
if (loc.path[2] !== documentsId) {
return undefined
}
const shortLink = loc.path[3]
const id = parseDocumentId(shortLink)
const projectId = loc.path[4] as Ref<Project>
if (id !== undefined) {
return projectId !== undefined
? await generateProjectDocumentLocation(loc, id, projectId)
: await generateDocumentLocation(loc, id)
}
return undefined
}