mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-29 11:43:49 +00:00
EZQMS-1393: implemented folders in controlled documents (#7803)
* EZQMS-1393: implemented folders in controlled documents Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> * formatting Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com> --------- Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
parent
f8a8c94bc2
commit
40931c81ca
@ -66,6 +66,8 @@ import {
|
||||
TDocumentComment
|
||||
} from './types'
|
||||
import { defineSpaceType } from './spaceType'
|
||||
import { type Class, type Doc, type Ref } from '@hcengineering/core'
|
||||
import { type Action } from '@hcengineering/view'
|
||||
|
||||
export { documentsId } from '@hcengineering/controlled-documents/src/index'
|
||||
export * from './types'
|
||||
@ -459,6 +461,51 @@ export function createModel (builder: Builder): void {
|
||||
documentsPlugin.action.CreateChildTemplate
|
||||
)
|
||||
|
||||
createAction<Document>(
|
||||
builder,
|
||||
{
|
||||
action: documents.actionImpl.CreateChildFolder,
|
||||
label: documentsPlugin.string.CreateChildFolder,
|
||||
icon: documents.icon.Folder,
|
||||
category: view.category.General,
|
||||
input: 'focus', // should only work for one document, not bulk
|
||||
target: documents.class.ProjectDocument,
|
||||
visibilityTester: documents.function.CanCreateChildFolder,
|
||||
context: { mode: ['context'], group: 'create' }
|
||||
},
|
||||
documentsPlugin.action.CreateChildFolder
|
||||
)
|
||||
|
||||
createAction<Document>(
|
||||
builder,
|
||||
{
|
||||
action: documents.actionImpl.RenameFolder,
|
||||
label: view.string.Rename,
|
||||
icon: view.icon.Edit,
|
||||
category: view.category.General,
|
||||
input: 'focus', // should only work for one document, not bulk
|
||||
target: documents.class.ProjectDocument,
|
||||
visibilityTester: documents.function.CanRenameFolder,
|
||||
context: { mode: ['context'], group: 'edit' }
|
||||
},
|
||||
documentsPlugin.action.RenameFolder
|
||||
)
|
||||
|
||||
createAction<Document>(
|
||||
builder,
|
||||
{
|
||||
action: documents.actionImpl.DeleteFolder,
|
||||
label: view.string.Delete,
|
||||
icon: view.icon.Delete,
|
||||
category: view.category.General,
|
||||
input: 'focus', // should only work for one document, not bulk
|
||||
target: documents.class.ProjectDocument,
|
||||
visibilityTester: documents.function.CanDeleteFolder,
|
||||
context: { mode: ['context'], group: 'remove' }
|
||||
},
|
||||
documentsPlugin.action.DeleteFolder
|
||||
)
|
||||
|
||||
createAction<DocumentSpace>(
|
||||
builder,
|
||||
{
|
||||
@ -489,6 +536,21 @@ export function createModel (builder: Builder): void {
|
||||
documentsPlugin.action.CreateTemplate
|
||||
)
|
||||
|
||||
createAction<DocumentSpace>(
|
||||
builder,
|
||||
{
|
||||
action: documents.actionImpl.CreateFolder,
|
||||
label: documentsPlugin.string.CreateFolder,
|
||||
icon: documents.icon.Folder,
|
||||
category: view.category.General,
|
||||
input: 'none',
|
||||
target: documents.class.DocumentSpace,
|
||||
visibilityTester: documents.function.CanCreateFolder,
|
||||
context: { mode: ['context'], group: 'create' }
|
||||
},
|
||||
documentsPlugin.action.CreateFolder
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
@ -758,22 +820,60 @@ export function createModel (builder: Builder): void {
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: print.actionImpl.Print,
|
||||
actionProps: {
|
||||
signed: true
|
||||
},
|
||||
label: print.string.PrintToPDF,
|
||||
icon: print.icon.Print,
|
||||
action: view.actionImpl.Open,
|
||||
label: view.string.Open,
|
||||
icon: view.icon.Open,
|
||||
keyBinding: ['Enter'],
|
||||
input: 'focus',
|
||||
category: view.category.General,
|
||||
input: 'focus', // NOTE: should only work for one doc for now, not bulk
|
||||
target: documents.class.Document,
|
||||
context: { mode: ['context', 'browser'], group: 'tools' },
|
||||
visibilityTester: print.function.CanPrint,
|
||||
override: [print.action.Print]
|
||||
target: documents.class.ProjectDocument,
|
||||
context: { mode: ['browser', 'context'], group: 'edit' },
|
||||
visibilityTester: documents.function.CanOpenDocument,
|
||||
override: [view.action.Open]
|
||||
},
|
||||
documents.action.Print
|
||||
documents.action.OpenDocument
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.OpenInNewTab,
|
||||
label: view.string.OpenInNewTab,
|
||||
icon: view.icon.Open,
|
||||
input: 'focus',
|
||||
category: view.category.General,
|
||||
target: documents.class.ProjectDocument,
|
||||
context: { mode: ['browser', 'context'], group: 'edit' },
|
||||
visibilityTester: documents.function.CanOpenDocument,
|
||||
override: [view.action.OpenInNewTab]
|
||||
},
|
||||
documents.action.OpenDocumentInNewTab
|
||||
)
|
||||
|
||||
function createPrintAction<T extends Doc = Doc> (target: Ref<Class<T>>, id?: Ref<Action<T, any>>): void {
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: print.actionImpl.Print,
|
||||
actionProps: {
|
||||
signed: true
|
||||
},
|
||||
label: print.string.PrintToPDF,
|
||||
icon: print.icon.Print,
|
||||
category: view.category.General,
|
||||
input: 'focus', // NOTE: should only work for one doc for now, not bulk
|
||||
target,
|
||||
context: { mode: ['context', 'browser'], group: 'tools' },
|
||||
visibilityTester: documents.function.CanPrintDocument,
|
||||
override: [print.action.Print]
|
||||
},
|
||||
id
|
||||
)
|
||||
}
|
||||
|
||||
createPrintAction(documents.class.ProjectDocument, documents.action.PrintProjectDocument)
|
||||
createPrintAction(documents.class.Document, documents.action.Print)
|
||||
|
||||
defineSpaceType(builder)
|
||||
definePermissions(builder)
|
||||
defineNotifications(builder)
|
||||
|
@ -59,8 +59,12 @@ export default mergeIds(documentsId, documents, {
|
||||
actionImpl: {
|
||||
CreateChildDocument: '' as ViewAction,
|
||||
CreateChildTemplate: '' as ViewAction,
|
||||
CreateChildFolder: '' as ViewAction,
|
||||
RenameFolder: '' as ViewAction,
|
||||
DeleteFolder: '' as ViewAction,
|
||||
CreateDocument: '' as ViewAction,
|
||||
CreateTemplate: '' as ViewAction,
|
||||
CreateFolder: '' as ViewAction,
|
||||
TransferTemplate: '' as ViewAction,
|
||||
DeleteDocument: '' as ViewAction,
|
||||
ArchiveDocument: '' as ViewAction,
|
||||
|
@ -62,4 +62,8 @@
|
||||
<path d="M8.99976 1.99976C8.44747 1.99976 7.99976 2.44747 7.99976 2.99976V6.09976C5.69976 6.59976 3.99976 8.59976 3.99976 10.9998C3.99976 13.3998 5.69976 15.3998 7.99976 15.8998L7.99976 28.9998C7.99976 29.552 8.44747 29.9998 8.99976 29.9998C9.55204 29.9998 9.99976 29.552 9.99976 28.9998L9.99976 15.8998C12.2998 15.3998 13.9998 13.3998 13.9998 10.9998C13.9998 8.59976 12.2998 6.59976 9.99976 6.09976V2.99976C9.99976 2.44747 9.55204 1.99976 8.99976 1.99976ZM11.9998 10.9998C11.9998 12.6998 10.6998 13.9998 8.99976 13.9998C7.29976 13.9998 5.99976 12.6998 5.99976 10.9998C5.99976 9.29976 7.29976 7.99976 8.99976 7.99976C10.6998 7.99976 11.9998 9.29976 11.9998 10.9998Z"/>
|
||||
<path d="M22.9998 29.9998C23.552 29.9998 23.9998 29.552 23.9998 28.9998V25.8998C26.2998 25.3998 27.9998 23.3998 27.9998 20.9998C27.9998 18.5998 26.2998 16.5998 23.9998 16.0998V2.99976C23.9998 2.44747 23.552 1.99976 22.9998 1.99976C22.4475 1.99976 21.9998 2.44747 21.9998 2.99976V16.0998C19.6998 16.5998 17.9998 18.5998 17.9998 20.9998C17.9998 23.3998 19.6998 25.3998 21.9998 25.8998V28.9998C21.9998 29.552 22.4475 29.9998 22.9998 29.9998ZM19.9998 20.9998C19.9998 19.2998 21.2998 17.9998 22.9998 17.9998C24.6998 17.9998 25.9998 19.2998 25.9998 20.9998C25.9998 22.6998 24.6998 23.9998 22.9998 23.9998C21.2998 23.9998 19.9998 22.6998 19.9998 20.9998Z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="c-folder" viewBox="0 0 32 32">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 9C2 6.23858 4.23858 4 7 4H10.6716C11.4672 4 12.2303 4.31607 12.7929 4.87868L15.6213 7.70711C15.8089 7.89464 16.0632 8 16.3284 8H25C27.7614 8 30 10.2386 30 13V23C30 25.7614 27.7614 28 25 28H7C4.23858 28 2 25.7614 2 23V9ZM7 6C5.34315 6 4 7.34315 4 9V23C4 24.6569 5.34315 26 7 26H25C26.6569 26 28 24.6569 28 23V13C28 11.3431 26.6569 10 25 10H16.3284C15.5328 10 14.7697 9.68393 14.2071 9.12132L11.3787 6.29289C11.1911 6.10536 10.9368 6 10.6716 6H7Z" fill="currentColor"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 10 KiB |
@ -291,7 +291,11 @@
|
||||
"Transfer": "Přenos",
|
||||
"TransferWarning": "Někteří členové týmu mohou po této akci ztratit možnost prohlížet nebo upravovat tento dokument.",
|
||||
"TransferDocuments": "Přenos řízených dokumentů",
|
||||
"TransferDocumentsHint": "Dokumenty, které mají být přeneseny do vybraného prostoru:"
|
||||
"TransferDocumentsHint": "Dokumenty, které mají být přeneseny do vybraného prostoru:",
|
||||
|
||||
"CreateFolder": "Vytvořit novou složku",
|
||||
"RenameFolder": "Přejmenovat složku",
|
||||
"CreateChildFolder": "Vytvořit podsložku"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -298,7 +298,11 @@
|
||||
"Transfer": "Übertragung",
|
||||
"TransferWarning": "Einige Teammitglieder können dieses Dokument nach dieser Aktion möglicherweise nicht mehr anzeigen oder bearbeiten.",
|
||||
"TransferDocuments": "Übertragung kontrollierter Dokumente",
|
||||
"TransferDocumentsHint": "Dokumente, die in den ausgewählten Bereich übertragen werden sollen:"
|
||||
"TransferDocumentsHint": "Dokumente, die in den ausgewählten Bereich übertragen werden sollen:",
|
||||
|
||||
"CreateFolder": "Neuen Ordner erstellen",
|
||||
"RenameFolder": "Ordner umbenennen",
|
||||
"CreateChildFolder": "Unterordner erstellen"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -300,7 +300,11 @@
|
||||
"Transfer": "Transfer",
|
||||
"TransferWarning": "Some team members may lose the ability to view or edit this document after this action.",
|
||||
"TransferDocuments": "Transfer controlled documents",
|
||||
"TransferDocumentsHint": "Documents to be transferred to the selected space:"
|
||||
"TransferDocumentsHint": "Documents to be transferred to the selected space:",
|
||||
|
||||
"CreateFolder": "Create new folder",
|
||||
"RenameFolder": "Rename folder",
|
||||
"CreateChildFolder": "Create child folder"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -258,7 +258,11 @@
|
||||
"Transfer": "Transfert",
|
||||
"TransferWarning": "Certains membres de l'équipe peuvent perdre la possibilité de visualiser ou de modifier ce document après cette action.",
|
||||
"TransferDocuments": "Transférer des documents contrôlés",
|
||||
"TransferDocumentsHint": "Documents à transférer dans l'espace sélectionné:"
|
||||
"TransferDocumentsHint": "Documents à transférer dans l'espace sélectionné:",
|
||||
|
||||
"CreateFolder": "Créer un nouveau dossier",
|
||||
"RenameFolder": "Renommer le dossier",
|
||||
"CreateChildFolder": "Créer un sous-dossier"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -256,7 +256,11 @@
|
||||
"Transfer": "Trasferimento",
|
||||
"TransferWarning": "Alcuni membri del team potrebbero perdere la possibilità di visualizzare o modificare il documento dopo questa azione.",
|
||||
"TransferDocuments": "Trasferimento di documenti controllati",
|
||||
"TransferDocumentsHint": "Documenti da trasferire nello spazio selezionato:"
|
||||
"TransferDocumentsHint": "Documenti da trasferire nello spazio selezionato:",
|
||||
|
||||
"CreateFolder": "Crea nuova cartella",
|
||||
"RenameFolder": "Rinomina cartella",
|
||||
"CreateChildFolder": "Crea sottocartella"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -300,7 +300,11 @@
|
||||
"Transfer": "Трансфер",
|
||||
"TransferWarning": "После этого действия некоторые члены команды могут потерять возможность просматривать или редактировать этот документ.",
|
||||
"TransferDocuments": "Трансфер управляемых документов",
|
||||
"TransferDocumentsHint": "Документы, которые будут перенесены в выбранное пространство:"
|
||||
"TransferDocumentsHint": "Документы, которые будут перенесены в выбранное пространство:",
|
||||
|
||||
"CreateFolder": "Создать новую папку",
|
||||
"RenameFolder": "Переименовать папку",
|
||||
"CreateChildFolder": "Создать подпапку"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -297,7 +297,11 @@
|
||||
"Transfer": "转让",
|
||||
"TransferWarning": "执行此操作后,某些团队成员可能会失去查看或编辑此文档的能力",
|
||||
"TransferDocuments": "移交受控文件",
|
||||
"TransferDocumentsHint": "要转移到所选空间的文件:"
|
||||
"TransferDocumentsHint": "要转移到所选空间的文件:",
|
||||
|
||||
"CreateFolder": "创建新文件夹",
|
||||
"RenameFolder": "重命名文件夹",
|
||||
"CreateChildFolder": "创建子文件夹"
|
||||
},
|
||||
"controlledDocStates": {
|
||||
"Empty": "",
|
||||
|
@ -21,6 +21,7 @@ loadMetadata(documents.icon, {
|
||||
Approvals: `${icons}#approvals`,
|
||||
DocumentApplication: `${icons}#documentapplication`,
|
||||
NewDocument: `${icons}#newdocument`,
|
||||
Folder: `${icons}#c-folder`,
|
||||
Document: `${icons}#document`,
|
||||
Library: `${icons}#library`,
|
||||
StateApproved: `${icons}#state-approved`,
|
||||
|
@ -71,6 +71,7 @@
|
||||
"svelte": "^4.2.19",
|
||||
"slugify": "^1.6.6",
|
||||
"fast-equals": "^5.0.1",
|
||||
"@hcengineering/rank": "^0.6.4"
|
||||
"@hcengineering/rank": "^0.6.4",
|
||||
"@hcengineering/print": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
<!--
|
||||
//
|
||||
// Copyright © 2025 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.
|
||||
//
|
||||
-->
|
||||
<script lang="ts">
|
||||
import documents, {
|
||||
createNewFolder,
|
||||
DocumentMeta,
|
||||
type DocumentSpace,
|
||||
type Project,
|
||||
type ProjectDocument
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import core, { Ref } from '@hcengineering/core'
|
||||
import { Card, getClient } from '@hcengineering/presentation'
|
||||
import { EditBox, FocusHandler, createFocusManager } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export function canClose (): boolean {
|
||||
return name === ''
|
||||
}
|
||||
|
||||
export let folder: DocumentMeta | undefined
|
||||
export let name: string = ''
|
||||
|
||||
export let space: Ref<DocumentSpace> | undefined
|
||||
export let project: Ref<Project<DocumentSpace>> | undefined
|
||||
export let parent: Ref<ProjectDocument> | undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
|
||||
$: canSave = getTitle(name).length > 0 && (folder !== undefined || space !== undefined)
|
||||
|
||||
function getTitle (value: string): string {
|
||||
return value.trim()
|
||||
}
|
||||
|
||||
async function create (): Promise<void> {
|
||||
const title = getTitle(name)
|
||||
if (title.length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (folder !== undefined) {
|
||||
await client.update(folder, { title })
|
||||
} else if (space !== undefined) {
|
||||
await createNewFolder(client, space, project ?? documents.ids.NoProject, parent, title)
|
||||
}
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
const manager = createFocusManager()
|
||||
</script>
|
||||
|
||||
<FocusHandler {manager} />
|
||||
|
||||
<Card
|
||||
label={folder ? documents.string.RenameFolder : documents.string.CreateFolder}
|
||||
okAction={create}
|
||||
accentHeader
|
||||
{canSave}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
on:changeContent
|
||||
>
|
||||
<div class="flex-row-center clear-mins">
|
||||
<EditBox placeholder={core.string.Name} bind:value={name} autoFocus focusIndex={1} />
|
||||
</div>
|
||||
</Card>
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { type Ref, type Doc, SortingOrder, getCurrentAccount, WithLookup } from '@hcengineering/core'
|
||||
import { type Ref, type Doc, SortingOrder, getCurrentAccount, WithLookup, toIdMap } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import type { PersonAccount } from '@hcengineering/contact'
|
||||
import { type Action } from '@hcengineering/ui'
|
||||
@ -80,6 +80,11 @@
|
||||
let lastSeqNumber = -1
|
||||
|
||||
for (const prjdoc of result) {
|
||||
if (prjdoc.document === documents.ids.Folder) {
|
||||
docs.push(prjdoc)
|
||||
continue
|
||||
}
|
||||
|
||||
const doc = prjdoc.$lookup?.document as ControlledDocument | undefined
|
||||
if (doc === undefined) continue
|
||||
if (doc.state === DocumentState.Deleted) continue
|
||||
@ -120,29 +125,45 @@
|
||||
}
|
||||
)
|
||||
|
||||
let docsMeta: DocumentMeta[] = []
|
||||
|
||||
const metaQuery = createQuery()
|
||||
$: metaQuery.query(documents.class.DocumentMeta, { _id: { $in: projectMeta.map((p) => p.meta) } }, (result) => {
|
||||
docsMeta = result
|
||||
})
|
||||
|
||||
async function getDocMoreActions (obj: Doc): Promise<Action[]> {
|
||||
return getMoreActions !== undefined ? await getMoreActions(obj) : []
|
||||
}
|
||||
|
||||
$: projectMetaById = toIdMap(projectMeta)
|
||||
$: docsMetaById = toIdMap(docsMeta)
|
||||
</script>
|
||||
|
||||
{#each docs as prjdoc}
|
||||
{@const pjmeta = projectMetaById.get(prjdoc.attachedTo)}
|
||||
{@const doc = prjdoc.$lookup?.document}
|
||||
{@const metaid = pjmeta?.meta}
|
||||
{@const meta = metaid ? docsMetaById.get(metaid) : undefined}
|
||||
{@const title = doc ? getDocumentName(doc) : meta?.title ?? ''}
|
||||
{@const docid = doc?._id ?? prjdoc._id}
|
||||
{@const isFolder = prjdoc.document === documents.ids.Folder}
|
||||
|
||||
{#if doc}
|
||||
{@const children = childrenByParent[doc.attachedTo] ?? []}
|
||||
{@const isDraggedOver = draggedOver === doc.attachedTo}
|
||||
{#if metaid}
|
||||
{@const children = childrenByParent[metaid] ?? []}
|
||||
{@const isDraggedOver = draggedOver === metaid}
|
||||
<div class="flex-col relative">
|
||||
{#if isDraggedOver}
|
||||
<DropArea />
|
||||
{/if}
|
||||
<TreeItem
|
||||
_id={doc._id}
|
||||
icon={documents.icon.Document}
|
||||
_id={docid}
|
||||
icon={isFolder ? documents.icon.Folder : documents.icon.Document}
|
||||
iconProps={{
|
||||
fill: 'currentColor'
|
||||
}}
|
||||
title={getDocumentName(doc)}
|
||||
selected={selected === doc._id || selected === prjdoc._id}
|
||||
{title}
|
||||
selected={selected === docid || selected === prjdoc._id}
|
||||
isFold
|
||||
empty={children.length === 0 || children === undefined}
|
||||
actions={getMoreActions !== undefined ? () => getDocMoreActions(prjdoc) : undefined}
|
||||
@ -154,16 +175,16 @@
|
||||
}}
|
||||
draggable={onDragStart !== undefined}
|
||||
on:dragstart={(evt) => {
|
||||
onDragStart?.(evt, doc.attachedTo)
|
||||
onDragStart?.(evt, metaid)
|
||||
}}
|
||||
on:dragover={(evt) => {
|
||||
onDragOver?.(evt, doc.attachedTo)
|
||||
onDragOver?.(evt, metaid)
|
||||
}}
|
||||
on:dragend={(evt) => {
|
||||
onDragEnd?.(evt, doc.attachedTo)
|
||||
onDragEnd?.(evt, metaid)
|
||||
}}
|
||||
on:drop={(evt) => {
|
||||
onDrop?.(evt, doc.attachedTo)
|
||||
onDrop?.(evt, metaid)
|
||||
}}
|
||||
>
|
||||
<svelte:fragment slot="dropbox">
|
||||
|
@ -51,7 +51,9 @@
|
||||
canCreateChildDocument,
|
||||
moveDocument,
|
||||
moveDocumentBefore,
|
||||
moveDocumentAfter
|
||||
moveDocumentAfter,
|
||||
canCreateChildFolder,
|
||||
createFolder
|
||||
} from '../../utils'
|
||||
|
||||
import documents from '../../plugin'
|
||||
@ -178,6 +180,21 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (
|
||||
spaceType?.projects === true &&
|
||||
(await isEditableProject(project)) &&
|
||||
(await canCreateChildFolder(space, true))
|
||||
) {
|
||||
actions.push({
|
||||
icon: documents.icon.Folder,
|
||||
label: documents.string.CreateFolder,
|
||||
group: 'create',
|
||||
action: async () => {
|
||||
await createFolder(space)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return orderActions(actions)
|
||||
}
|
||||
|
||||
|
@ -12,54 +12,54 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import { type PersonAccount } from '@hcengineering/contact'
|
||||
import {
|
||||
type Document,
|
||||
type DocumentMeta,
|
||||
type DocumentSpace,
|
||||
DocumentState,
|
||||
type Project,
|
||||
type ProjectDocument
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import {
|
||||
checkPermission,
|
||||
type Class,
|
||||
type Client,
|
||||
type Doc,
|
||||
type DocumentQuery,
|
||||
getCurrentAccount,
|
||||
type Ref,
|
||||
type RelatedDocument,
|
||||
SortingOrder,
|
||||
type WithLookup,
|
||||
type Doc,
|
||||
getCurrentAccount,
|
||||
checkPermission
|
||||
type WithLookup
|
||||
} from '@hcengineering/core'
|
||||
import {
|
||||
type Document,
|
||||
type DocumentSpace,
|
||||
DocumentState,
|
||||
type DocumentMeta,
|
||||
type ProjectDocument,
|
||||
type Project
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import { type Resources } from '@hcengineering/platform'
|
||||
import { type ObjectSearchResult, getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import { getClient, MessageBox, type ObjectSearchResult } from '@hcengineering/presentation'
|
||||
import { showPopup } from '@hcengineering/ui'
|
||||
import { type PersonAccount } from '@hcengineering/contact'
|
||||
|
||||
import CreateDocument from './components/CreateDocument.svelte'
|
||||
import DeleteCategoryPopup from './components/category/popups/DeleteCategoryPopup.svelte'
|
||||
import QmsDocumentWizard from './components/create-doc/QmsDocumentWizard.svelte'
|
||||
import QmsTemplateWizard from './components/create-doc/QmsTemplateWizard.svelte'
|
||||
import DocumentStatusTag from './components/document/common/DocumentStatusTag.svelte'
|
||||
import DocumentSpacePresenter from './components/hierarchy/DocumentSpacePresenter.svelte'
|
||||
import DocumentPresenter from './components/document/presenters/DocumentPresenter.svelte'
|
||||
import StatePresenter from './components/document/presenters/StatePresenter.svelte'
|
||||
import StateFilterValuePresenter from './components/document/presenters/StateFilterValuePresenter.svelte'
|
||||
import TitlePresenter from './components/document/presenters/TitlePresenter.svelte'
|
||||
import OwnerPresenter from './components/document/presenters/OwnerPresenter.svelte'
|
||||
import AddCommentPopup from './components/document/popups/AddCommentPopup.svelte'
|
||||
import DocumentCommentsPopup from './components/document/popups/DocumentCommentsPopup.svelte'
|
||||
import ChangeOwnerPopup from './components/document/popups/ChangeOwnerPopup.svelte'
|
||||
import DeleteCategoryPopup from './components/category/popups/DeleteCategoryPopup.svelte'
|
||||
import DocumentCommentsPopup from './components/document/popups/DocumentCommentsPopup.svelte'
|
||||
import DocumentPresenter from './components/document/presenters/DocumentPresenter.svelte'
|
||||
import OwnerPresenter from './components/document/presenters/OwnerPresenter.svelte'
|
||||
import StateFilterValuePresenter from './components/document/presenters/StateFilterValuePresenter.svelte'
|
||||
import StatePresenter from './components/document/presenters/StatePresenter.svelte'
|
||||
import TitlePresenter from './components/document/presenters/TitlePresenter.svelte'
|
||||
import DocumentSpacePresenter from './components/hierarchy/DocumentSpacePresenter.svelte'
|
||||
|
||||
import CategoryPresenter from './components/category/presenters/CategoryPresenter.svelte'
|
||||
import DocumentItem from './components/DocumentItem.svelte'
|
||||
import Documents from './components/Documents.svelte'
|
||||
import DocumentsContainer from './components/DocumentsContainer.svelte'
|
||||
import MyDocuments from './components/MyDocuments.svelte'
|
||||
import EditDoc from './components/EditDoc.svelte'
|
||||
import EditProjectDoc from './components/EditProjectDoc.svelte'
|
||||
import DocumentItem from './components/DocumentItem.svelte'
|
||||
import MyDocuments from './components/MyDocuments.svelte'
|
||||
import NewDocumentHeader from './components/NewDocumentHeader.svelte'
|
||||
import CategoryPresenter from './components/category/presenters/CategoryPresenter.svelte'
|
||||
import DocumentIcon from './components/icons/DocumentIcon.svelte'
|
||||
|
||||
import DocumentTemplates from './components/DocumentTemplates.svelte'
|
||||
@ -67,43 +67,53 @@ import DocumentTemplates from './components/DocumentTemplates.svelte'
|
||||
import Categories from './components/Categories.svelte'
|
||||
import EditDocumentCategory from './components/EditDocumentCategory.svelte'
|
||||
|
||||
import DocumentMetaPresenter from './components/DocumentMetaPresenter.svelte'
|
||||
import CreateDocumentSpaceType from './components/docspace/CreateDocumentSpaceType.svelte'
|
||||
import CreateDocumentsSpace from './components/docspace/CreateDocumentsSpace.svelte'
|
||||
import DocumentTitle from './components/document/DocumentTitle.svelte'
|
||||
import EditDocContent from './components/document/EditDocContent.svelte'
|
||||
import ControlledStateFilterValuePresenter from './components/document/presenters/ControlledStateFilterValuePresenter.svelte'
|
||||
import DocumentVersionPresenter from './components/document/presenters/DocumentVersionPresenter.svelte'
|
||||
import DocumentReviewRequest from './components/requests/DocumentReviewRequest.svelte'
|
||||
import DocumentReviewRequestPresenter from './components/requests/DocumentReviewRequestPresenter.svelte'
|
||||
import DocumentApprovalRequest from './components/requests/DocumentApprovalRequest.svelte'
|
||||
import DocumentApprovalRequestPresenter from './components/requests/DocumentApprovalRequestPresenter.svelte'
|
||||
import ControlledStateFilterValuePresenter from './components/document/presenters/ControlledStateFilterValuePresenter.svelte'
|
||||
import DocumentMetaPresenter from './components/DocumentMetaPresenter.svelte'
|
||||
import CreateDocumentsSpace from './components/docspace/CreateDocumentsSpace.svelte'
|
||||
import CreateDocumentSpaceType from './components/docspace/CreateDocumentSpaceType.svelte'
|
||||
import DocumentReviewRequest from './components/requests/DocumentReviewRequest.svelte'
|
||||
import DocumentReviewRequestPresenter from './components/requests/DocumentReviewRequestPresenter.svelte'
|
||||
|
||||
import Projects from './components/project/Projects.svelte'
|
||||
import ProjectPresenter from './components/project/ProjectPresenter.svelte'
|
||||
import ProjectRefPresenter from './components/project/ProjectRefPresenter.svelte'
|
||||
import Projects from './components/project/Projects.svelte'
|
||||
|
||||
import { getPrintBaseURL } from '@hcengineering/print'
|
||||
import CreateFolder from './components/create-doc/CreateFolder.svelte'
|
||||
import TransferDocumentPopup from './components/document/popups/TransferDocumentPopup.svelte'
|
||||
import { resolveLocation } from './navigation'
|
||||
import documents from './plugin'
|
||||
import './styles/_colors.scss'
|
||||
import { resolveLocation } from './navigation'
|
||||
import { comment, isCommentVisible } from './text'
|
||||
import {
|
||||
getVisibleFilters,
|
||||
sortDocumentStates,
|
||||
getAllDocumentStates,
|
||||
canChangeDocumentOwner,
|
||||
canDeleteDocumentCategory,
|
||||
canCreateChildTemplate,
|
||||
canCreateChildDocument,
|
||||
documentIdentifierProvider,
|
||||
getControlledDocumentTitle,
|
||||
getDocumentMetaLinkFragment,
|
||||
canCreateChildFolder,
|
||||
canCreateChildTemplate,
|
||||
canDeleteDocumentCategory,
|
||||
canDeleteFolder,
|
||||
canRenameFolder,
|
||||
createChildDocument,
|
||||
createChildFolder,
|
||||
createChildTemplate,
|
||||
createDocument,
|
||||
createTemplate
|
||||
createFolder,
|
||||
createTemplate,
|
||||
deleteFolder,
|
||||
documentIdentifierProvider,
|
||||
getAllDocumentStates,
|
||||
getControlledDocumentTitle,
|
||||
getDocumentMetaLinkFragment,
|
||||
getVisibleFilters,
|
||||
isFolder,
|
||||
renameFolder,
|
||||
sortDocumentStates
|
||||
} from './utils'
|
||||
import { comment, isCommentVisible } from './text'
|
||||
import TransferDocumentPopup from './components/document/popups/TransferDocumentPopup.svelte'
|
||||
|
||||
export { DocumentStatusTag, DocumentTitle, DocumentVersionPresenter, StatePresenter }
|
||||
|
||||
@ -210,6 +220,37 @@ async function canArchiveDocument (obj?: Doc | Doc[]): Promise<boolean> {
|
||||
).then((res) => res.every((r) => r))
|
||||
}
|
||||
|
||||
async function canOpenDocument (obj?: ProjectDocument | ProjectDocument[]): Promise<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const h = getClient().getHierarchy()
|
||||
|
||||
const objs = Array.isArray(obj) ? obj : [obj]
|
||||
return !objs.some((d) => isFolder(h, d))
|
||||
}
|
||||
|
||||
async function canPrintDocument (obj?: Document | Document[] | ProjectDocument | ProjectDocument[]): Promise<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const h = getClient().getHierarchy()
|
||||
|
||||
const objs = Array.isArray(obj) ? obj : [obj]
|
||||
if (objs.some((d) => isFolder(h, d))) return false
|
||||
|
||||
let printURL = ''
|
||||
try {
|
||||
printURL = getPrintBaseURL()
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return printURL?.length > 0
|
||||
}
|
||||
|
||||
async function canTransferDocument (obj?: Doc | Doc[]): Promise<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
@ -339,7 +380,8 @@ export default async (): Promise<Resources> => ({
|
||||
Projects,
|
||||
ProjectPresenter,
|
||||
ProjectRefPresenter,
|
||||
DocumentIcon
|
||||
DocumentIcon,
|
||||
CreateFolder
|
||||
},
|
||||
completion: {
|
||||
DocumentMetaQuery: async (
|
||||
@ -356,8 +398,12 @@ export default async (): Promise<Resources> => ({
|
||||
CanChangeDocumentOwner: canChangeDocumentOwner,
|
||||
CanCreateTemplate: canCreateChildTemplate,
|
||||
CanCreateDocument: canCreateChildDocument,
|
||||
CanCreateFolder: canCreateChildFolder,
|
||||
CanCreateChildTemplate: canCreateChildTemplate,
|
||||
CanCreateChildDocument: canCreateChildDocument,
|
||||
CanCreateChildFolder: canCreateChildFolder,
|
||||
CanRenameFolder: canRenameFolder,
|
||||
CanDeleteFolder: canDeleteFolder,
|
||||
CanDeleteDocumentCategory: canDeleteDocumentCategory,
|
||||
GetVisibleFilters: getVisibleFilters,
|
||||
DocumentStateSort: sortDocumentStates,
|
||||
@ -366,6 +412,8 @@ export default async (): Promise<Resources> => ({
|
||||
CanDeleteDocument: canDeleteDocument,
|
||||
CanArchiveDocument: canArchiveDocument,
|
||||
CanTransferDocument: canTransferDocument,
|
||||
CanOpenDocument: canOpenDocument,
|
||||
CanPrintDocument: canPrintDocument,
|
||||
DocumentIdentifierProvider: documentIdentifierProvider,
|
||||
ControlledDocumentTitleProvider: getControlledDocumentTitle,
|
||||
Comment: comment,
|
||||
@ -374,8 +422,12 @@ export default async (): Promise<Resources> => ({
|
||||
actionImpl: {
|
||||
CreateChildDocument: createChildDocument,
|
||||
CreateChildTemplate: createChildTemplate,
|
||||
CreateChildFolder: createChildFolder,
|
||||
RenameFolder: renameFolder,
|
||||
DeleteFolder: deleteFolder,
|
||||
CreateDocument: createDocument,
|
||||
CreateTemplate: createTemplate,
|
||||
CreateFolder: createFolder,
|
||||
DeleteDocument: deleteDocuments,
|
||||
ArchiveDocument: archiveDocuments,
|
||||
TransferDocument: transferDocuments,
|
||||
|
@ -226,8 +226,12 @@ export default mergeIds(documentsId, documents, {
|
||||
function: {
|
||||
CanCreateTemplate: '' as Resource<ViewActionAvailabilityFunction<DocumentSpace>>,
|
||||
CanCreateDocument: '' as Resource<ViewActionAvailabilityFunction<DocumentSpace>>,
|
||||
CanCreateFolder: '' as Resource<ViewActionAvailabilityFunction<DocumentSpace>>,
|
||||
CanCreateChildTemplate: '' as Resource<ViewActionAvailabilityFunction<Document>>,
|
||||
CanCreateChildDocument: '' as Resource<ViewActionAvailabilityFunction<Document>>,
|
||||
CanCreateChildFolder: '' as Resource<ViewActionAvailabilityFunction<Document>>,
|
||||
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction<Document>>,
|
||||
CanDeleteFolder: '' as Resource<ViewActionAvailabilityFunction<Document>>,
|
||||
CheckIsDocumentCreationDisabled: '' as Resource<() => Promise<boolean>>,
|
||||
CheckAreTemplatesDisabled: '' as Resource<() => Promise<boolean>>,
|
||||
CheckAreDomainsDisabled: '' as Resource<() => Promise<boolean>>,
|
||||
@ -238,6 +242,8 @@ export default mergeIds(documentsId, documents, {
|
||||
GetDocumentMetaLinkFragment: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
CanDeleteDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanArchiveDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanOpenDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanPrintDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
CanTransferDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
ControlledDocumentTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
||||
}
|
||||
|
@ -119,6 +119,11 @@ export function isProjectDocument (hierarchy: Hierarchy, doc: Doc): doc is Proje
|
||||
return hierarchy.isDerived(doc._class, documents.class.ProjectDocument)
|
||||
}
|
||||
|
||||
export function isFolder (hierarchy: Hierarchy, doc: Doc): doc is ProjectDocument {
|
||||
if (!isProjectDocument(hierarchy, doc)) return false
|
||||
return doc.document === documents.ids.Folder
|
||||
}
|
||||
|
||||
export async function getVisibleFilters (filters: KeyFilter[], space?: Ref<Space>): Promise<KeyFilter[]> {
|
||||
// Removes the "Space" filter if a specific space is provided
|
||||
return space === undefined ? filters : filters.filter((f) => f.key !== 'space')
|
||||
@ -461,6 +466,112 @@ export async function canCreateChildDocument (
|
||||
return true
|
||||
}
|
||||
|
||||
export async function canCreateChildFolder (
|
||||
doc?: Document | Document[] | DocumentSpace | DocumentSpace[] | ProjectDocument | ProjectDocument[],
|
||||
includeProjects = false
|
||||
): Promise<boolean> {
|
||||
if (doc === null || doc === undefined) {
|
||||
return false
|
||||
}
|
||||
if (Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const spaceId: Ref<DocumentSpace> = isSpace(hierarchy, doc) ? doc._id : doc.space
|
||||
|
||||
const canCreateDocument = await checkPermission(client, documents.permission.CreateDocument, spaceId)
|
||||
if (!canCreateDocument) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (isSpace(hierarchy, doc)) {
|
||||
const spaceType = await client.findOne(documents.class.DocumentSpaceType, { _id: doc.type })
|
||||
return includeProjects || spaceType?.projects !== true
|
||||
}
|
||||
|
||||
if (isProjectDocument(hierarchy, doc)) {
|
||||
return await isEditableProject(doc.project)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export async function canRenameFolder (
|
||||
doc?: Document | Document[] | DocumentSpace | DocumentSpace[] | ProjectDocument | ProjectDocument[],
|
||||
includeProjects = false
|
||||
): Promise<boolean> {
|
||||
if (doc === null || doc === undefined) {
|
||||
return false
|
||||
}
|
||||
if (Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const spaceId: Ref<DocumentSpace> = isSpace(hierarchy, doc) ? doc._id : doc.space
|
||||
|
||||
const canCreateDocument = await checkPermission(client, documents.permission.CreateDocument, spaceId)
|
||||
if (!canCreateDocument) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (isSpace(hierarchy, doc)) {
|
||||
const spaceType = await client.findOne(documents.class.DocumentSpaceType, { _id: doc.type })
|
||||
return includeProjects || spaceType?.projects !== true
|
||||
}
|
||||
|
||||
if (!isFolder(hierarchy, doc)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return await isEditableProject(doc.project)
|
||||
}
|
||||
|
||||
export async function canDeleteFolder (obj?: Doc | Doc[]): Promise<boolean> {
|
||||
if (obj == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
const objs = (Array.isArray(obj) ? obj : [obj]) as Document[]
|
||||
|
||||
const isFolders = objs.every((doc) => isFolder(hierarchy, doc))
|
||||
if (!isFolders) {
|
||||
return false
|
||||
}
|
||||
|
||||
const folders = objs as unknown as ProjectDocument[]
|
||||
|
||||
const pjMeta = await client.findAll(documents.class.ProjectMeta, { _id: { $in: folders.map((f) => f.attachedTo) } })
|
||||
const directChildren = await client.findAll(documents.class.ProjectMeta, {
|
||||
parent: { $in: pjMeta.map((p) => p.meta) }
|
||||
})
|
||||
|
||||
if (directChildren.length > 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const currentUser = getCurrentAccount() as PersonAccount
|
||||
const isOwner = objs.every((doc) => doc.owner === currentUser.person)
|
||||
|
||||
if (isOwner) {
|
||||
return true
|
||||
}
|
||||
|
||||
const spaces = new Set(objs.map((doc) => doc.space))
|
||||
|
||||
return await Promise.all(
|
||||
Array.from(spaces).map(
|
||||
async (space) => await checkPermission(getClient(), documents.permission.ArchiveDocument, space)
|
||||
)
|
||||
).then((res) => res.every((r) => r))
|
||||
}
|
||||
|
||||
export async function canDeleteDocumentCategory (doc?: Doc | Doc[]): Promise<boolean> {
|
||||
if (doc === null || doc === undefined) {
|
||||
return false
|
||||
@ -627,6 +738,54 @@ export async function createChildTemplate (doc: ProjectDocument): Promise<void>
|
||||
showPopup(documents.component.QmsTemplateWizard, {})
|
||||
}
|
||||
|
||||
export async function createChildFolder (doc: ProjectDocument): Promise<void> {
|
||||
const props = {
|
||||
space: doc.space,
|
||||
project: doc.project,
|
||||
parent: doc._id
|
||||
}
|
||||
|
||||
showPopup(documents.component.CreateFolder, props)
|
||||
}
|
||||
|
||||
export async function renameFolder (doc: ProjectDocument): Promise<void> {
|
||||
const client = getClient()
|
||||
|
||||
const pjmeta = await client.findOne(documents.class.ProjectMeta, { _id: doc.attachedTo })
|
||||
if (pjmeta === undefined) return
|
||||
|
||||
const meta = await client.findOne(documents.class.DocumentMeta, { _id: pjmeta.meta })
|
||||
if (meta === undefined) return
|
||||
|
||||
const props = {
|
||||
folder: meta,
|
||||
name: meta.title
|
||||
}
|
||||
|
||||
showPopup(documents.component.CreateFolder, props)
|
||||
}
|
||||
|
||||
export async function deleteFolder (obj: ProjectDocument | ProjectDocument[]): Promise<void> {
|
||||
const client = getClient()
|
||||
|
||||
if (!(await canDeleteFolder(obj))) {
|
||||
return
|
||||
}
|
||||
|
||||
const objs = Array.isArray(obj) ? obj : [obj]
|
||||
|
||||
const pjmeta = await client.findAll(documents.class.ProjectMeta, { _id: { $in: objs.map((p) => p.attachedTo) } })
|
||||
const meta = await client.findAll(documents.class.DocumentMeta, { _id: { $in: pjmeta.map((p) => p.meta) } })
|
||||
|
||||
const docsToRemove = [...objs, ...pjmeta, ...meta]
|
||||
const ops = client.apply()
|
||||
for (const doc of docsToRemove) {
|
||||
await ops.remove(doc)
|
||||
}
|
||||
|
||||
await ops.commit()
|
||||
}
|
||||
|
||||
export async function createDocument (space: DocumentSpace): Promise<void> {
|
||||
const project = await getLatestProjectId(space._id)
|
||||
wizardOpened({
|
||||
@ -642,6 +801,15 @@ export async function createTemplate (space: OrgSpace): Promise<void> {
|
||||
showPopup(documents.component.QmsTemplateWizard, {})
|
||||
}
|
||||
|
||||
export async function createFolder (space: DocumentSpace): Promise<void> {
|
||||
const project = await getLatestProjectId(space._id)
|
||||
const props = {
|
||||
space: space._id,
|
||||
project: project ?? documents.ids.NoProject
|
||||
}
|
||||
showPopup(documents.component.CreateFolder, props)
|
||||
}
|
||||
|
||||
export function formatSignatureDate (date: number): string {
|
||||
const timeZone: string = getUserTimezone()
|
||||
|
||||
|
@ -357,3 +357,55 @@ export async function createDocumentTemplateMetadata (
|
||||
|
||||
return { success: success.result, seqNumber, code, documentMetaId, projectDocumentId }
|
||||
}
|
||||
|
||||
export async function createNewFolder (
|
||||
client: TxOperations,
|
||||
space: Ref<DocumentSpace>,
|
||||
project: Ref<Project> | undefined,
|
||||
parent: Ref<ProjectDocument> | undefined,
|
||||
title: string
|
||||
): Promise<{
|
||||
success: boolean
|
||||
documentMetaId: Ref<DocumentMeta>
|
||||
projectDocumentId: Ref<ProjectDocument>
|
||||
}> {
|
||||
const projectId = project ?? documents.ids.NoProject
|
||||
|
||||
const ops = client.apply()
|
||||
|
||||
const documentMetaId = await ops.createDoc(documents.class.DocumentMeta, space, { documents: 0, title })
|
||||
|
||||
let path: Array<Ref<DocumentMeta>> = []
|
||||
if (parent !== undefined) {
|
||||
path = await getParentPath(client, parent)
|
||||
}
|
||||
|
||||
const parentMeta = path[0] ?? documents.ids.NoParent
|
||||
const lastRank = await getFirstRank(client, space, projectId, parentMeta)
|
||||
|
||||
const projectMetaId = await ops.createDoc(documents.class.ProjectMeta, space, {
|
||||
project: projectId,
|
||||
meta: documentMetaId,
|
||||
path,
|
||||
parent: parentMeta,
|
||||
documents: 0,
|
||||
rank: makeRank(lastRank, undefined)
|
||||
})
|
||||
|
||||
const projectDocumentId = await client.addCollection(
|
||||
documents.class.ProjectDocument,
|
||||
space,
|
||||
projectMetaId,
|
||||
documents.class.ProjectMeta,
|
||||
'documents',
|
||||
{
|
||||
project: projectId,
|
||||
initial: projectId,
|
||||
document: documents.ids.Folder
|
||||
}
|
||||
)
|
||||
|
||||
const success = await ops.commit()
|
||||
|
||||
return { success: success.result, documentMetaId, projectDocumentId }
|
||||
}
|
||||
|
@ -107,20 +107,28 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
DocumentMetaPresenter: '' as AnyComponent,
|
||||
DocumentVersionPresenter: '' as AnyComponent,
|
||||
DeleteCategoryPopup: '' as AnyComponent,
|
||||
DocumentIcon: '' as AnyComponent
|
||||
DocumentIcon: '' as AnyComponent,
|
||||
CreateFolder: '' as AnyComponent
|
||||
},
|
||||
action: {
|
||||
ChangeDocumentOwner: '' as Ref<Action<Doc, any>>,
|
||||
CreateChildDocument: '' as Ref<Action<Document, any>>,
|
||||
CreateChildTemplate: '' as Ref<Action<Document, any>>,
|
||||
CreateChildFolder: '' as Ref<Action<Document, any>>,
|
||||
RenameFolder: '' as Ref<Action<Document, any>>,
|
||||
DeleteFolder: '' as Ref<Action<Document, any>>,
|
||||
CreateDocument: '' as Ref<Action<DocumentSpace, any>>,
|
||||
CreateTemplate: '' as Ref<Action<DocumentSpace, any>>,
|
||||
CreateFolder: '' as Ref<Action<DocumentSpace, any>>,
|
||||
DeleteDocumentCategory: '' as Ref<Action<Doc, any>>,
|
||||
DeleteDocument: '' as Ref<Action>,
|
||||
ArchiveDocument: '' as Ref<Action>,
|
||||
EditDocSpace: '' as Ref<Action>,
|
||||
TransferDocument: '' as Ref<Action>,
|
||||
Print: '' as Ref<Action<Doc, { signed: boolean }>>
|
||||
Print: '' as Ref<Action<Doc, { signed: boolean }>>,
|
||||
PrintProjectDocument: '' as Ref<Action<Doc, { signed: boolean }>>,
|
||||
OpenDocument: '' as Ref<Action<Doc, { signed: boolean }>>,
|
||||
OpenDocumentInNewTab: '' as Ref<Action<Doc, { signed: boolean }>>
|
||||
},
|
||||
function: {
|
||||
CanChangeDocumentOwner: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
|
||||
@ -131,6 +139,7 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
CheckmarkCircle: '' as Asset,
|
||||
DocumentApplication: '' as Asset,
|
||||
NewDocument: '' as Asset,
|
||||
Folder: '' as Asset,
|
||||
Document: '' as Asset,
|
||||
Library: '' as Asset,
|
||||
StateDraft: '' as Asset,
|
||||
@ -212,6 +221,8 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
ChangeOwnerWarning: '' as IntlString,
|
||||
CreateDocument: '' as IntlString,
|
||||
CreateTemplate: '' as IntlString,
|
||||
CreateFolder: '' as IntlString,
|
||||
RenameFolder: '' as IntlString,
|
||||
DeleteCategory: '' as IntlString,
|
||||
DeleteCategoryHint: '' as IntlString,
|
||||
DeleteCategoryWarning: '' as IntlString,
|
||||
@ -228,6 +239,7 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
Path: '' as IntlString,
|
||||
CreateChildDocument: '' as IntlString,
|
||||
CreateChildTemplate: '' as IntlString,
|
||||
CreateChildFolder: '' as IntlString,
|
||||
All: '' as IntlString,
|
||||
ImpactAnalysis: '' as IntlString,
|
||||
ImpactedDocuments: '' as IntlString,
|
||||
@ -270,7 +282,8 @@ export const documentsPlugin = plugin(documentsId, {
|
||||
},
|
||||
ids: {
|
||||
NoParent: '' as Ref<DocumentMeta>,
|
||||
NoProject: '' as Ref<Project>
|
||||
NoProject: '' as Ref<Project>,
|
||||
Folder: '' as Ref<HierarchyDocument>
|
||||
},
|
||||
sequence: {
|
||||
Templates: '' as Ref<Sequence>,
|
||||
|
@ -443,9 +443,9 @@ async function _transferDocuments (
|
||||
if (bundle.DocumentMeta.length !== 1) return false
|
||||
if (bundle.ProjectMeta.length !== 1) return false
|
||||
if (bundle.DocumentMeta[0].space !== cx.request.sourceSpaceId) return false
|
||||
if (bundle.ControlledDocument.length < 1) return false
|
||||
|
||||
const isTemplate = hierarchy.hasMixin(bundle.ControlledDocument[0], documents.mixin.DocumentTemplate)
|
||||
const anydoc = bundle.ControlledDocument[0]
|
||||
const isTemplate = anydoc !== undefined && hierarchy.hasMixin(anydoc, documents.mixin.DocumentTemplate)
|
||||
if (isTemplate && hierarchy.isDerived(cx.targetSpace._class, documents.class.ExternalSpace)) return false
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user