mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-21 06:52:33 +00:00
Improved URL-to-reference conversion (#8916)
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
parent
d1a338d313
commit
c7847a035c
@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { Analytics } from '@hcengineering/analytics'
|
||||||
import attachment, { Attachment, AttachmentsEvents } from '@hcengineering/attachment'
|
import attachment, { Attachment, AttachmentsEvents } from '@hcengineering/attachment'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import core, { BlobMetadata, Doc, PersonId, Ref, generateId, type Blob, type Space } from '@hcengineering/core'
|
import core, { BlobMetadata, Doc, PersonId, Ref, generateId, type Blob, type Space } from '@hcengineering/core'
|
||||||
@ -34,11 +35,9 @@
|
|||||||
defaultRefActions,
|
defaultRefActions,
|
||||||
getModelRefActions
|
getModelRefActions
|
||||||
} from '@hcengineering/text-editor-resources'
|
} from '@hcengineering/text-editor-resources'
|
||||||
import { AnySvelteComponent, getEventPositionElement, getPopupPositionElement, navigate } from '@hcengineering/ui'
|
import { AnySvelteComponent, getEventPositionElement, getPopupPositionElement } from '@hcengineering/ui'
|
||||||
import { type FileUploadCallbackParams, uploadFiles } from '@hcengineering/uploader'
|
import { uploadFiles, type FileUploadCallbackParams } from '@hcengineering/uploader'
|
||||||
import view from '@hcengineering/view'
|
import { getCollaborationUser, getObjectId, openDoc } from '@hcengineering/view-resources'
|
||||||
import { getCollaborationUser, getObjectId, getObjectLinkFragment } from '@hcengineering/view-resources'
|
|
||||||
import { Analytics } from '@hcengineering/analytics'
|
|
||||||
|
|
||||||
import AttachmentsGrid from './AttachmentsGrid.svelte'
|
import AttachmentsGrid from './AttachmentsGrid.svelte'
|
||||||
|
|
||||||
@ -324,8 +323,7 @@
|
|||||||
on:open-document={async (event) => {
|
on:open-document={async (event) => {
|
||||||
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc)
|
await openDoc(client.getHierarchy(), doc)
|
||||||
navigate(location)
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:focus
|
on:focus
|
||||||
|
@ -13,13 +13,11 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Doc, Class, Ref, updateAttribute } from '@hcengineering/core'
|
import { Class, Doc, Ref, updateAttribute } from '@hcengineering/core'
|
||||||
|
|
||||||
import { IntlString } from '@hcengineering/platform'
|
import { IntlString } from '@hcengineering/platform'
|
||||||
import { createQuery, getAttribute, getClient, KeyedAttribute } from '@hcengineering/presentation'
|
import { createQuery, getAttribute, getClient, KeyedAttribute } from '@hcengineering/presentation'
|
||||||
import { navigate } from '@hcengineering/ui'
|
import { openDoc } from '@hcengineering/view-resources'
|
||||||
import view from '@hcengineering/view'
|
|
||||||
import { getObjectLinkFragment } from '@hcengineering/view-resources'
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import AttachmentStyledBox from './AttachmentStyledBox.svelte'
|
import AttachmentStyledBox from './AttachmentStyledBox.svelte'
|
||||||
|
|
||||||
@ -137,8 +135,7 @@
|
|||||||
save(object, description)
|
save(object, description)
|
||||||
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc)
|
await openDoc(client.getHierarchy(), doc)
|
||||||
navigate(location)
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -20,9 +20,7 @@
|
|||||||
import { getClient } from '@hcengineering/presentation'
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Heading } from '@hcengineering/text-editor'
|
import { Heading } from '@hcengineering/text-editor'
|
||||||
import { TableOfContents } from '@hcengineering/text-editor-resources'
|
import { TableOfContents } from '@hcengineering/text-editor-resources'
|
||||||
import { navigate } from '@hcengineering/ui'
|
import { openDoc } from '@hcengineering/view-resources'
|
||||||
import view from '@hcengineering/view'
|
|
||||||
import { getObjectLinkFragment } from '@hcengineering/view-resources'
|
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
import ContentEditor from './ContentEditor.svelte'
|
import ContentEditor from './ContentEditor.svelte'
|
||||||
@ -107,8 +105,7 @@
|
|||||||
on:open-document={async (event) => {
|
on:open-document={async (event) => {
|
||||||
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc)
|
await openDoc(client.getHierarchy(), doc)
|
||||||
navigate(location)
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
bind:this={editor}
|
bind:this={editor}
|
||||||
|
@ -13,48 +13,47 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, onDestroy, tick } from 'svelte'
|
|
||||||
import { merge } from 'effector'
|
|
||||||
import { type Ref, type Blob, generateId } from '@hcengineering/core'
|
|
||||||
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
|
|
||||||
import { getClient } from '@hcengineering/presentation'
|
|
||||||
import view from '@hcengineering/view'
|
|
||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import documents, { DocumentState } from '@hcengineering/controlled-documents'
|
import documents, { DocumentState } from '@hcengineering/controlled-documents'
|
||||||
|
import { type Blob, type Ref, generateId } from '@hcengineering/core'
|
||||||
|
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||||
|
import { getClient } from '@hcengineering/presentation'
|
||||||
import { Editor, Heading } from '@hcengineering/text-editor'
|
import { Editor, Heading } from '@hcengineering/text-editor'
|
||||||
import {
|
import {
|
||||||
CollaboratorEditor,
|
CollaboratorEditor,
|
||||||
TableOfContents,
|
|
||||||
TableOfContentsContent,
|
|
||||||
FocusExtension,
|
FocusExtension,
|
||||||
HeadingsExtension,
|
HeadingsExtension,
|
||||||
IsEmptyContentExtension,
|
IsEmptyContentExtension,
|
||||||
NodeHighlightExtension,
|
NodeHighlightExtension,
|
||||||
NodeHighlightType,
|
NodeHighlightType,
|
||||||
highlightUpdateCommand,
|
TableOfContents,
|
||||||
getNodeElement
|
TableOfContentsContent,
|
||||||
|
getNodeElement,
|
||||||
|
highlightUpdateCommand
|
||||||
} from '@hcengineering/text-editor-resources'
|
} from '@hcengineering/text-editor-resources'
|
||||||
import { navigate, EditBox, Scroller, Label } from '@hcengineering/ui'
|
import { EditBox, Label, Scroller } from '@hcengineering/ui'
|
||||||
import { getCollaborationUser, getObjectLinkFragment } from '@hcengineering/view-resources'
|
import { getCollaborationUser, openDoc } from '@hcengineering/view-resources'
|
||||||
|
import { merge } from 'effector'
|
||||||
|
import { createEventDispatcher, onDestroy, tick } from 'svelte'
|
||||||
import plugin from '../../plugin'
|
import plugin from '../../plugin'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
$areDocumentCommentPopupsOpened as areDocumentCommentPopupsOpened,
|
$areDocumentCommentPopupsOpened as areDocumentCommentPopupsOpened,
|
||||||
$controlledDocument as controlledDocument,
|
|
||||||
$isEditable as isEditable,
|
|
||||||
$documentCommentHighlightedLocation as documentCommentHighlightedLocation,
|
|
||||||
$areDocumentCommentPopupsOpened as arePopupsOpened,
|
$areDocumentCommentPopupsOpened as arePopupsOpened,
|
||||||
$canAddDocumentComments as canAddDocumentComments,
|
$canAddDocumentComments as canAddDocumentComments,
|
||||||
$canViewDocumentComments as canViewDocumentComments,
|
$canViewDocumentComments as canViewDocumentComments,
|
||||||
|
$controlledDocument as controlledDocument,
|
||||||
|
$documentCommentHighlightedLocation as documentCommentHighlightedLocation,
|
||||||
$documentComments as documentComments,
|
$documentComments as documentComments,
|
||||||
documentCommentsDisplayRequested,
|
documentCommentsDisplayRequested,
|
||||||
documentCommentsHighlightUpdated,
|
documentCommentsHighlightUpdated,
|
||||||
documentCommentsLocationNavigateRequested,
|
documentCommentsLocationNavigateRequested,
|
||||||
$documentReleasedVersions as documentReleasedVersions
|
$documentReleasedVersions as documentReleasedVersions,
|
||||||
|
$isEditable as isEditable
|
||||||
} from '../../stores/editors/document'
|
} from '../../stores/editors/document'
|
||||||
import DocumentTitle from './DocumentTitle.svelte'
|
|
||||||
import DocumentPrintTitlePage from '../print/DocumentPrintTitlePage.svelte'
|
|
||||||
import { syncDocumentMetaTitle } from '../../utils'
|
import { syncDocumentMetaTitle } from '../../utils'
|
||||||
|
import DocumentPrintTitlePage from '../print/DocumentPrintTitlePage.svelte'
|
||||||
|
import DocumentTitle from './DocumentTitle.svelte'
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
const hierarchy = client.getHierarchy()
|
||||||
@ -295,8 +294,7 @@
|
|||||||
on:open-document={async (event) => {
|
on:open-document={async (event) => {
|
||||||
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc)
|
await openDoc(client.getHierarchy(), doc)
|
||||||
navigate(location)
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
attachFile={async (file) => {
|
attachFile={async (file) => {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { Analytics } from '@hcengineering/analytics'
|
||||||
import attachment, { Attachment } from '@hcengineering/attachment'
|
import attachment, { Attachment } from '@hcengineering/attachment'
|
||||||
import core, { Doc, Ref, WithLookup, generateId, type Blob } from '@hcengineering/core'
|
import core, { Doc, Ref, WithLookup, generateId, type Blob } from '@hcengineering/core'
|
||||||
import { Document, DocumentEvents } from '@hcengineering/document'
|
import { Document, DocumentEvents } from '@hcengineering/document'
|
||||||
@ -35,7 +36,6 @@
|
|||||||
TimeSince,
|
TimeSince,
|
||||||
createFocusManager,
|
createFocusManager,
|
||||||
getPlatformColorDef,
|
getPlatformColorDef,
|
||||||
navigate,
|
|
||||||
showPopup,
|
showPopup,
|
||||||
themeStore
|
themeStore
|
||||||
} from '@hcengineering/ui'
|
} from '@hcengineering/ui'
|
||||||
@ -45,14 +45,13 @@
|
|||||||
IconPicker,
|
IconPicker,
|
||||||
ParentsNavigator,
|
ParentsNavigator,
|
||||||
RelationsEditor,
|
RelationsEditor,
|
||||||
getObjectLinkFragment,
|
openDoc,
|
||||||
restrictionStore,
|
restrictionStore,
|
||||||
showMenu
|
showMenu
|
||||||
} from '@hcengineering/view-resources'
|
} from '@hcengineering/view-resources'
|
||||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||||
import { Analytics } from '@hcengineering/analytics'
|
|
||||||
|
|
||||||
import { starDocument, unstarDocument, unlockContent } from '..'
|
import { starDocument, unlockContent, unstarDocument } from '..'
|
||||||
import document from '../plugin'
|
import document from '../plugin'
|
||||||
import { getDocumentUrl } from '../utils'
|
import { getDocumentUrl } from '../utils'
|
||||||
import DocumentEditor from './DocumentEditor.svelte'
|
import DocumentEditor from './DocumentEditor.svelte'
|
||||||
@ -389,8 +388,7 @@
|
|||||||
on:open-document={async (event) => {
|
on:open-document={async (event) => {
|
||||||
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
const doc = await client.findOne(event.detail._class, { _id: event.detail._id })
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc)
|
await openDoc(client.getHierarchy(), doc)
|
||||||
navigate(location)
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:loaded={() => {
|
on:loaded={() => {
|
||||||
|
@ -408,7 +408,12 @@ export async function getReferenceLabel<T extends Doc> (
|
|||||||
const identifier = (await labelProviderFn?.(client, id, doc)) ?? ''
|
const identifier = (await labelProviderFn?.(client, id, doc)) ?? ''
|
||||||
const title = (await titleProviderFn?.(client, id, doc)) ?? ''
|
const title = (await titleProviderFn?.(client, id, doc)) ?? ''
|
||||||
|
|
||||||
const label = identifier !== '' && title !== '' && identifier !== title ? `${identifier} ${title}` : title ?? ''
|
const label =
|
||||||
|
identifier !== '' && title !== '' && identifier !== title
|
||||||
|
? `${identifier} ${title}`
|
||||||
|
: title !== ''
|
||||||
|
? title
|
||||||
|
: identifier
|
||||||
|
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
@ -451,7 +456,6 @@ export async function getTargetObjectFromUrl (
|
|||||||
urlOrLocation: string | Location
|
urlOrLocation: string | Location
|
||||||
): Promise<{ _id: Ref<Doc>, _class: Ref<Class<Doc>> } | undefined> {
|
): Promise<{ _id: Ref<Doc>, _class: Ref<Class<Doc>> } | undefined> {
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const hierarchy = client.getHierarchy()
|
|
||||||
|
|
||||||
let location: Location
|
let location: Location
|
||||||
if (typeof urlOrLocation === 'string') {
|
if (typeof urlOrLocation === 'string') {
|
||||||
@ -469,19 +473,43 @@ export async function getTargetObjectFromUrl (
|
|||||||
|
|
||||||
const appAlias = (location.path[2] ?? '').trim()
|
const appAlias = (location.path[2] ?? '').trim()
|
||||||
if (!(appAlias.length > 0)) return
|
if (!(appAlias.length > 0)) return
|
||||||
|
|
||||||
const excludedApps = getMetadata(workbench.metadata.ExcludedApplications) ?? []
|
const excludedApps = getMetadata(workbench.metadata.ExcludedApplications) ?? []
|
||||||
const apps: Application[] = client
|
const apps: Application[] = client
|
||||||
.getModel()
|
.getModel()
|
||||||
.findAllSync<Application>(workbench.class.Application, { hidden: false, _id: { $nin: excludedApps } })
|
.findAllSync<Application>(workbench.class.Application, { hidden: false, _id: { $nin: excludedApps } })
|
||||||
|
|
||||||
const app = apps.find((p) => p.alias === appAlias)
|
const app = apps.find((p) => p.alias === appAlias)
|
||||||
|
const locationResolver = app?.locationResolver
|
||||||
|
const locationDataResolver = app?.locationDataResolver
|
||||||
|
|
||||||
if (app?.locationResolver === undefined) return
|
if ((location.fragment ?? '') !== '') {
|
||||||
const locationResolverFn = await getResource(app.locationResolver)
|
const obj = await getObjectFromFragment(location.fragment ?? '')
|
||||||
const resolvedLocation = await locationResolverFn(location)
|
if (obj !== undefined) return obj
|
||||||
|
}
|
||||||
|
|
||||||
const locationParts = decodeURIComponent(resolvedLocation?.loc?.fragment ?? '').split('|')
|
if (locationResolver !== undefined) {
|
||||||
|
const locationResolverFn = await getResource(locationResolver)
|
||||||
|
const resolvedLocation = await locationResolverFn(location)
|
||||||
|
const obj = await getObjectFromFragment(resolvedLocation?.loc?.fragment ?? '')
|
||||||
|
if (obj !== undefined) return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locationDataResolver !== undefined) {
|
||||||
|
const locationDataResolverFn = await getResource(locationDataResolver)
|
||||||
|
const locationData = await locationDataResolverFn(location)
|
||||||
|
if (locationData.objectId !== undefined && locationData.objectClass !== undefined) {
|
||||||
|
return { _id: locationData.objectId, _class: locationData.objectClass }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getObjectFromFragment (
|
||||||
|
fragment: string
|
||||||
|
): Promise<{ _id: Ref<Doc>, _class: Ref<Class<Doc>> } | undefined> {
|
||||||
|
const client = getClient()
|
||||||
|
const hierarchy = client.getHierarchy()
|
||||||
|
|
||||||
|
const locationParts = decodeURIComponent(fragment).split('|')
|
||||||
const id = locationParts[1] as Ref<Doc>
|
const id = locationParts[1] as Ref<Doc>
|
||||||
const objectclass = locationParts[2] as Ref<Class<Doc>>
|
const objectclass = locationParts[2] as Ref<Class<Doc>>
|
||||||
if (id === undefined || objectclass === undefined) return
|
if (id === undefined || objectclass === undefined) return
|
||||||
|
@ -399,7 +399,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
loc.query = resolved.loc.query ?? loc.query ?? currentQuery ?? resolved.defaultLocation.query
|
loc.query = resolved.loc.query ?? loc.query ?? currentQuery ?? resolved.defaultLocation.query
|
||||||
loc.fragment = resolved.loc.fragment ?? loc.fragment ?? resolved.defaultLocation.fragment
|
loc.fragment =
|
||||||
|
(loc.fragment ?? '') !== '' && resolved.loc.fragment === resolved.defaultLocation.fragment
|
||||||
|
? loc.fragment
|
||||||
|
: resolved.loc.fragment ?? resolved.defaultLocation.fragment
|
||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user