Skip to content

Commit

Permalink
EZQMS-1166: Revamp doc library sections model (#6358)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexey Zinoviev <[email protected]>
  • Loading branch information
lexiv0re authored Aug 21, 2024
1 parent 1bf50e1 commit 5f795ce
Show file tree
Hide file tree
Showing 94 changed files with 1,331 additions and 3,413 deletions.
5 changes: 1 addition & 4 deletions dev/doc-import-tool/src/extract/sections.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Document } from 'domhandler'
import { Markup, Ref, generateId } from '@hcengineering/core'
import { DocumentSection } from '@hcengineering/controlled-documents'
import { Markup } from '@hcengineering/core'

import { GenericNodeSpec, NodeType, SectionSpec, SectionType, TocSectionSpec } from './types'
import { AnyContainer, createNodeExtractor } from './nodes'
Expand All @@ -11,7 +10,6 @@ import { AnyContainer, createNodeExtractor } from './nodes'
* can be found in a document (TOC, history, etc.)
*/
export interface ExtractedSection {
id: Ref<DocumentSection>
type: SectionType
title: string
content: Markup
Expand All @@ -25,7 +23,6 @@ export function extractSections (doc: Document, sectionSpecs: SectionSpec[]): Ex
try {
const extractedSection = sectionExtractor.extract(doc)
sections.push({
id: generateId(),
type: section.type,
title: extractedSection.getTitle(),
content: extractedSection.getContent()
Expand Down
100 changes: 18 additions & 82 deletions dev/doc-import-tool/src/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import attachment, { Attachment } from '@hcengineering/attachment'
import { getClient as getCollaboratorClient } from '@hcengineering/collaborator-client'
import documents, {
ChangeControl,
CollaborativeDocumentSection,
ControlledDocument,
DEFAULT_PERIODIC_REVIEW_INTERVAL,
DEFAULT_SECTION_TITLE,
Document,
DocumentCategory,
DocumentState,
DocumentTemplate,
calcRank,
createChangeControl,
createControlledDocFromTemplate,
createDocumentTemplate
Expand All @@ -36,7 +33,6 @@ import { parseDocument } from 'htmlparser2'
import { Config } from './config'
import { ExtractedFile } from './extract/extract'
import { ExtractedSection } from './extract/sections'
import { compareStrExact } from './helpers'

export default async function importExtractedFile (
ctx: MeasureContext,
Expand All @@ -56,6 +52,10 @@ export default async function importExtractedFile (
try {
const docId = await createDocument(txops, extractedFile, config)
const createdDoc = await txops.findOne(documents.class.Document, { _id: docId })
if (createdDoc == null) {
throw new Error(`Failed to obtain created document: ${docId}`)
}

await createSections(ctx, txops, extractedFile, config, createdDoc)
} finally {
await txops.close()
Expand Down Expand Up @@ -87,7 +87,6 @@ async function createDocument (
major: 0,
minor: 1,
commentSequence: 0,
sections: 0,
template: templateId,
state: DocumentState.Draft,
requests: 0,
Expand Down Expand Up @@ -185,10 +184,7 @@ async function createTemplateIfNotExist (
prefix,
data,
category,
owner,
{
title: DEFAULT_SECTION_TITLE
}
owner
)
if (!success) {
throw new Error('Failed to create document template')
Expand All @@ -206,95 +202,34 @@ async function createSections (
txops: TxOperations,
extractedFile: ExtractedFile,
config: Config,
doc?: Document
doc: Document
): Promise<void> {
if (doc?.template == null) {
throw new Error(`Invalid document: ${JSON.stringify(doc)}`)
}

const h = txops.getHierarchy()

const { space, collaboratorApiURL, token, workspaceId } = config
const { collaboratorApiURL, token, workspaceId } = config
const collaborator = getCollaboratorClient(txops.getHierarchy(), workspaceId, token, collaboratorApiURL)

console.log('Creating document sections')
console.log('Creating document content')

const collabId = doc.content

console.log(`Collab doc ID: ${collabId}`)

const docSections = await txops.findAll(documents.class.DocumentSection, { attachedTo: doc._id })
const shouldMergeSections = docSections.some((s) => s.title !== DEFAULT_SECTION_TITLE)

try {
let prevSection: { rank: string } | undefined
let content: string = ''
for (const section of extractedFile.sections) {
if (section.type !== 'generic') {
continue
}

const existingSection = shouldMergeSections
? docSections.find((s) => s.title !== DEFAULT_SECTION_TITLE && compareStrExact(s.title, section.title))
: undefined
await processImages(ctx, txops, section, config, doc)

// skipping sections that are not present in the document/template
if (shouldMergeSections && existingSection == null) {
continue
}

if (existingSection == null) {
const sectionData: AttachedData<CollaborativeDocumentSection> = {
title: section.title,
rank: calcRank(prevSection, undefined),
key: section.id,
collaboratorSectionId: section.id
}

console.log(`Creating section data: ${JSON.stringify(sectionData)}`)

await txops.addCollection(
documents.class.CollaborativeDocumentSection,
space,
doc._id,
doc._class,
'sections',
sectionData,
section.id
)

prevSection = sectionData
} else {
prevSection = existingSection
}

await processImages(ctx, txops, section, config)

const collabSectionId =
existingSection != null && h.isDerived(existingSection._class, documents.class.CollaborativeDocumentSection)
? (existingSection as CollaborativeDocumentSection).collaboratorSectionId
: section.id

await collaborator.updateContent(collabId, collabSectionId, section.content)
content += `<h1>${section.title}</h1>${section.content}`
}

// deleting the default section if it was the only one and there were other sections added from the extracted doc
// doing it after import, so that the trigger doesn't re-create a new empty section
if (
docSections.length === 1 &&
docSections[0].title === DEFAULT_SECTION_TITLE &&
extractedFile.sections.some((es) => es.type === 'generic')
) {
const defaultSection = docSections[0]

await txops.removeCollection(
defaultSection._class,
defaultSection.space,
defaultSection._id,
doc._id,
doc._class,
'sections'
)
}
await collaborator.updateContent(collabId, 'content', content)
} finally {
// do nothing
}
Expand All @@ -304,12 +239,13 @@ export async function processImages (
ctx: MeasureContext,
txops: TxOperations,
section: ExtractedSection,
config: Config
config: Config,
doc: Document
): Promise<void> {
const dom = parseDocument(section.content)
const imageNodes = findAll((n) => n.tagName === 'img', dom.children)

const { storageAdapter, workspaceId, uploadURL, space } = config
const { storageAdapter, workspaceId, uploadURL } = config

const imageUploads = imageNodes.map(async (img) => {
const src = img.attribs.src
Expand All @@ -335,9 +271,9 @@ export async function processImages (
const attachmentId: Ref<Attachment> = generateId()
await txops.addCollection(
attachment.class.Attachment,
space,
section.id,
documents.class.CollaborativeDocumentSection,
doc.space,
doc._id,
doc._class,
'attachments',
{
file: uuid as Ref<Blob>,
Expand Down
3 changes: 2 additions & 1 deletion models/controlled-documents/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@hcengineering/notification": "^0.6.23",
"@hcengineering/model-notification": "^0.6.0",
"@hcengineering/chunter": "^0.6.20",
"@hcengineering/text-editor": "^0.6.0"
"@hcengineering/text-editor": "^0.6.0",
"@hcengineering/collaboration": "^0.6.0"
}
}
131 changes: 0 additions & 131 deletions models/controlled-documents/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,10 @@ import {
TDocumentCategory,
TControlledDocument,
TChangeControl,
TDocumentSection,
TCollaborativeDocumentSection,
TAttachmentsDocumentSection,
TSequence,
TDocumentRequest,
TDocumentReviewRequest,
TDocumentApprovalRequest,
TDocumentSectionEditor,
TDocumentSectionPresenter,
TDocumentSectionCreator,
TDocumentTemplateSection,
TTypeDocumentState,
TTypeControlledDocumentState,
TDocumentComment
Expand Down Expand Up @@ -97,20 +90,11 @@ export function createModel (builder: Builder): void {
TDocumentCategory,
TControlledDocument,
TChangeControl,

TDocumentSection,
TCollaborativeDocumentSection,
TAttachmentsDocumentSection,

TSequence,

TDocumentRequest,
TDocumentReviewRequest,
TDocumentApprovalRequest,
TDocumentSectionEditor,
TDocumentSectionPresenter,
TDocumentSectionCreator,
TDocumentTemplateSection,

TTypeDocumentState,
TTypeControlledDocumentState,
Expand Down Expand Up @@ -413,39 +397,6 @@ export function createModel (builder: Builder): void {
encode: documents.function.GetDocumentMetaLinkFragment
})

builder.mixin(documents.class.CollaborativeDocumentSection, core.class.Class, view.mixin.ObjectPresenter, {
presenter: documents.component.CollaborativeSectionPresenter
})

builder.mixin(documents.class.CollaborativeDocumentSection, core.class.Class, documents.mixin.DocumentSectionEditor, {
editor: documents.component.CollaborativeSectionEditor
})

builder.mixin(
documents.class.CollaborativeDocumentSection,
core.class.Class,
documents.mixin.DocumentSectionCreator,
{
creator: documents.function.CollaborativeSectionCreator
}
)

builder.mixin(documents.class.AttachmentsDocumentSection, core.class.Class, view.mixin.ObjectPresenter, {
presenter: documents.component.AttachmentsSectionPresenter
})

builder.mixin(documents.class.AttachmentsDocumentSection, core.class.Class, documents.mixin.DocumentSectionEditor, {
editor: documents.component.AttachmentsSectionEditor
})

builder.mixin(documents.class.AttachmentsDocumentSection, core.class.Class, documents.mixin.DocumentSectionCreator, {
creator: documents.function.AttachmentsSectionCreator
})

builder.mixin(documents.class.DocumentSection, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.Open, print.action.Print, tracker.action.NewRelatedIssue]
})

builder.mixin(documents.class.Document, core.class.Class, view.mixin.ObjectPresenter, {
presenter: documents.component.DocumentPresenter
})
Expand Down Expand Up @@ -692,87 +643,6 @@ export function createModel (builder: Builder): void {
}
)

createAction(builder, {
action: documents.actionImpl.AddCollaborativeSectionAbove,
label: documents.string.AddSectionAbove,
icon: documents.icon.ArrowUp,
input: 'any',
category: view.category.General,
target: documents.class.CollaborativeDocumentSection,
context: {
mode: ['context', 'browser'],
group: 'create'
}
})

createAction(builder, {
action: documents.actionImpl.AddCollaborativeSectionBelow,
label: documents.string.AddSectionBelow,
icon: documents.icon.ArrowDown,
input: 'any',
category: view.category.General,
target: documents.class.CollaborativeDocumentSection,
context: {
mode: ['context', 'browser'],
group: 'create'
}
})

createAction(builder, {
action: documents.actionImpl.Duplicate,
label: documents.string.Duplicate,
icon: documents.icon.Duplicate,
input: 'any',
category: view.category.General,
target: documents.class.DocumentSection,
context: {
mode: ['context', 'browser'],
group: 'edit'
}
})

createAction(builder, {
action: documents.actionImpl.DeleteCollaborativeSection,
label: view.string.Delete,
icon: view.icon.Delete,
keyBinding: ['Meta + Backspace'],
category: view.category.General,
input: 'any',
target: documents.class.DocumentSection,
context: { mode: ['context', 'browser'], group: 'edit' },
override: [view.action.Delete]
})

createAction(builder, {
action: documents.actionImpl.EditDescription,
label: documents.string.EditDescription,
icon: documents.icon.EditDescription,
input: 'any',
category: view.category.General,
target: documents.mixin.DocumentTemplateSection,
context: {
mode: ['context', 'browser'],
group: 'tools'
}
})

createAction(builder, {
action: documents.actionImpl.EditGuidance,
label: documents.string.EditGuidance,
icon: documents.icon.EditGuidance,
input: 'any',
category: view.category.General,
target: documents.mixin.DocumentTemplateSection,
context: {
mode: ['context', 'browser'],
group: 'tools'
}
})

builder.mixin(documents.class.CollaborativeDocumentSection, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.Delete]
})

builder.mixin(documents.class.DocumentSpace, core.class.Class, view.mixin.IgnoreActions, {
actions: [tracker.action.EditRelatedTargets]
})
Expand Down Expand Up @@ -980,7 +850,6 @@ export function defineNotifications (builder: Builder): void {
'author',
'content',
'labels',
'sections',
'abstract',
'snapshots',
'requests',
Expand Down
Loading

0 comments on commit 5f795ce

Please sign in to comment.