Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for document hierarchy presentation in QMS #7938

Merged
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -14,184 +14,70 @@
-->

<script lang="ts">
import { type Ref, SortingOrder, getCurrentAccount } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { type PersonAccount } from '@hcengineering/contact'
import documents, {
type ControlledDocument,
type DocumentMeta,
import {
DocumentBundle,
ProjectDocumentTree,
type HierarchyDocument,
type Project,
type ProjectMeta
type Project
} from '@hcengineering/controlled-documents'
import { type Ref } from '@hcengineering/core'

import { compareDocs, notEmpty } from '../../../../utils'
import { createDocumentHierarchyQuery } from '../../../../utils'
import DocumentFlatTreeElement from './DocumentFlatTreeElement.svelte'

export let document: HierarchyDocument | undefined
export let project: Ref<Project>

const currentUser = getCurrentAccount() as PersonAccount
const currentPerson = currentUser.person
let tree = new ProjectDocumentTree()

let meta: ProjectMeta | undefined
const projectMetaQuery = createQuery()
const query = createDocumentHierarchyQuery()
$: if (document !== undefined && project !== undefined) {
projectMetaQuery.query(
documents.class.ProjectMeta,
{
project,
meta: document.attachedTo
},
(result) => {
;[meta] = result
}
)
query.query(document.space, project, (data) => {
tree = data
})
}

let parentMetas: ProjectMeta[] | undefined
const parentMetasQuery = createQuery()
$: if (meta !== undefined) {
parentMetasQuery.query(
documents.class.ProjectMeta,
{
meta: { $in: meta.path },
project: meta.project
},
(result) => {
parentMetas = result
}
)
} else {
parentMetasQuery.unsubscribe()
}

let directChildrenMetas: ProjectMeta[] | undefined
const childrenMetasQuery = createQuery()
$: if (meta !== undefined) {
childrenMetasQuery.query(
documents.class.ProjectMeta,
{
parent: meta?.meta,
project: meta.project
},
(result) => {
if (meta === undefined) {
return
}

directChildrenMetas = result
}
)
} else {
childrenMetasQuery.unsubscribe()
}

let docs: Record<Ref<DocumentMeta>, ControlledDocument> = {}
const docsQuery = createQuery()
$: if (parentMetas !== undefined && directChildrenMetas !== undefined) {
docsQuery.query(
documents.class.ProjectDocument,
{
attachedTo: { $in: [...parentMetas.map((p) => p._id), ...directChildrenMetas.map((p) => p._id)] }
},
(result) => {
docs = {}
let lastTemplate: string | undefined = '###'
let lastSeqNumber = -1

for (const prjdoc of result) {
const doc = prjdoc.$lookup?.document as ControlledDocument | undefined
if (doc === undefined) continue
$: docmetaid = tree.metaOf(document?._id)

// TODO add proper fix, when document with no template copied, saved value is null
const template = doc.template ?? undefined

if (template === lastTemplate && doc.seqNumber === lastSeqNumber) {
continue
}

if (
doc.owner === currentPerson ||
doc.coAuthors.findIndex((emp) => emp === currentPerson) >= 0 ||
doc.approvers.findIndex((emp) => emp === currentPerson) >= 0 ||
doc.reviewers.findIndex((emp) => emp === currentPerson) >= 0
) {
docs[doc.attachedTo] = doc

lastTemplate = template
lastSeqNumber = doc.seqNumber
}
}
},
{
lookup: {
document: documents.class.ControlledDocument
},
sort: {
'$lookup.document.template': SortingOrder.Ascending,
'$lookup.document.seqNumber': SortingOrder.Ascending,
'$lookup.document.major': SortingOrder.Descending,
'$lookup.document.minor': SortingOrder.Descending,
'$lookup.document.patch': SortingOrder.Descending
}
}
)
} else {
docsQuery.unsubscribe()
}

let directChildrenDocs: ControlledDocument[] = []
$: if (directChildrenMetas !== undefined) {
directChildrenDocs = Object.values(docs).filter(
(d) => directChildrenMetas !== undefined && directChildrenMetas.findIndex((m) => m.meta === d.attachedTo) >= 0
)
directChildrenDocs.sort(compareDocs)
}

let parentDocs: ControlledDocument[] = []
$: if (meta !== undefined) {
parentDocs = [...meta.path]
.reverse()
.map((mId) => docs[mId])
.filter(notEmpty)
}

let levels: Array<[HierarchyDocument[], boolean]> = []
let levels: Array<[DocumentBundle[], boolean]> = []
$: {
levels = []

if (parentDocs?.length > 0) {
levels.push([parentDocs, false])
}

if (document !== undefined) {
levels.push([[document], true])
}

if (directChildrenDocs?.length > 0) {
levels.push([directChildrenDocs, false])
const parents = tree
.parentChainOf(docmetaid)
.reverse()
.map((ref) => tree.bundleOf(ref))
.filter((r) => r !== undefined)
const me = tree.bundleOf(docmetaid)
const children = tree
.childrenOf(docmetaid)
.map((ref) => tree.bundleOf(ref))
.filter((r) => r !== undefined)

if (parents.length > 0) levels.push([parents as DocumentBundle[], false])
if (me) {
levels.push([[me], true])
}
if (children.length > 0) levels.push([children as DocumentBundle[], false])
}
</script>

{#if levels.length > 0}
{@const [firstDocs, firstHltd] = levels[0]}
<div class="root">
{#each firstDocs as doc}
<DocumentFlatTreeElement {doc} {project} highlighted={firstHltd} />
{#each firstDocs as bundle}
<DocumentFlatTreeElement {bundle} {project} highlighted={firstHltd} />
{/each}
{#if levels.length > 1}
{@const [secondDocs, secondHltd] = levels[1]}
<div class="container">
{#each secondDocs as doc}
<DocumentFlatTreeElement {doc} {project} highlighted={secondHltd} />
{#each secondDocs as bundle}
<DocumentFlatTreeElement {bundle} {project} highlighted={secondHltd} />
{/each}
{#if levels.length > 2}
{@const [thirdDocs, thirdHltd] = levels[2]}
<div class="container">
{#each thirdDocs as doc}
<DocumentFlatTreeElement {doc} {project} highlighted={thirdHltd} />
{#each thirdDocs as bundle}
<DocumentFlatTreeElement {bundle} {project} highlighted={thirdHltd} />
{/each}
</div>
{/if}
Expand All @@ -215,5 +101,8 @@
padding: 0 1rem;
border-left: 2px solid var(--theme-navpanel-border);
gap: 0.25rem;

padding-left: 0.25rem;
margin-left: 0.75rem;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,34 @@
-->

<script lang="ts">
import documents, { getDocumentName, type Document, type Project } from '@hcengineering/controlled-documents'
import documents, {
DocumentBundle,
getDocumentName,
isFolder,
type Project
} from '@hcengineering/controlled-documents'
import { type Ref } from '@hcengineering/core'
import { Icon, navigate } from '@hcengineering/ui'

import { getProjectDocumentLink } from '../../../../navigation'

export let doc: Document
export let bundle: DocumentBundle
export let project: Ref<Project>
export let highlighted: boolean = false

const icon = documents.icon.Document
$: meta = bundle?.DocumentMeta[0]
$: prjdoc = bundle?.ProjectDocument[0]
$: document = bundle?.ControlledDocument[0]
$: icon = isFolder(prjdoc) ? documents.icon.Folder : documents.icon.Document
</script>

<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="antiNav-element root"
on:click={() => {
const loc = getProjectDocumentLink(doc, project)
if (!document) return
const loc = getProjectDocumentLink(document, project)
navigate(loc)
}}
>
Expand All @@ -48,7 +57,7 @@
</div>
{/if}
<span class="an-element__label" class:font-medium={highlighted}>
{getDocumentName(doc)}
{document ? getDocumentName(document) : meta.title}
</span>
</div>

Expand Down
Loading