Files
huly-platform/plugins/card-resources/src/components/EditCardOld.svelte
T
2025-12-10 19:02:51 +05:00

235 lines
6.2 KiB
Svelte

<!--
//
// 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 { Attachments } from '@hcengineering/attachment-resources'
import { Card } from '@hcengineering/card'
import { Doc, Mixin, Ref, WithLookup } from '@hcengineering/core'
import notification from '@hcengineering/notification'
import { Panel } from '@hcengineering/panel'
import { getResource } from '@hcengineering/platform'
import { ComponentExtensions, createQuery, getClient } from '@hcengineering/presentation'
import {
Button,
EditBox,
FocusHandler,
IconMoreH,
createFocusManager,
getCurrentLocation,
navigate
} from '@hcengineering/ui'
import view from '@hcengineering/view'
import {
ParentsNavigator,
RelationsEditor,
canChangeDoc,
getDocMixins,
showMenu
} from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy } from 'svelte'
import card from '../plugin'
import CardAttributeEditor from './CardAttributeEditor.svelte'
import CardIcon from './CardIcon.svelte'
import CardPresenter from './CardPresenter.svelte'
import Childs from './Childs.svelte'
import Content from './Content.svelte'
import TagsEditor from './TagsEditor.svelte'
import { permissionsStore } from '@hcengineering/contact-resources'
export let _id: Ref<Card>
export let readonly: boolean = false
export let embedded: boolean = false
let useMaxWidth = getUseMaxWidth()
$: saveUseMaxWidth(useMaxWidth)
let lastId: Ref<Doc> = _id
const query = createQuery()
const dispatch = createEventDispatcher()
const client = getClient()
let doc: WithLookup<Card> | undefined
let title = ''
let innerWidth: number
const notificationClient = getResource(notification.function.GetInboxNotificationsClient).then((res) => res())
$: read(_id)
function read (_id: Ref<Doc>): void {
if (lastId !== _id) {
const prev = lastId
lastId = _id
void notificationClient.then((client) => client.readDoc(prev))
}
}
onDestroy(async () => {
void notificationClient.then((client) => client.readDoc(_id))
})
$: _id !== undefined &&
query.query(card.class.Card, { _id }, async (result) => {
if (result.length > 0) {
;[doc] = result
title = doc?.title ?? ''
} else {
const loc = getCurrentLocation()
loc.path.length = 3
navigate(loc)
}
})
$: _readonly = (readonly || doc?.readonly) ?? false
$: updatePermissionForbidden = doc && !canChangeDoc(doc?._class, doc?.space, $permissionsStore)
$: canSave = title.trim().length > 0 && !_readonly
async function saveTitle (ev: Event): Promise<void> {
ev.preventDefault()
if (doc === undefined || !canSave) {
return
}
const nameTrimmed = title.trim()
if (nameTrimmed.length > 0 && nameTrimmed !== doc.title) {
await client.update(doc, { title: nameTrimmed })
}
}
function getUseMaxWidth (): boolean {
const useMaxWidth = localStorage.getItem('document.useMaxWidth')
return useMaxWidth === 'true'
}
function saveUseMaxWidth (useMaxWidth: boolean): void {
localStorage.setItem('document.useMaxWidth', useMaxWidth.toString())
}
let content: HTMLElement
const manager = createFocusManager()
let mixins: Array<Mixin<Doc>> = []
$: mixins = doc !== undefined ? getDocMixins(doc) : []
</script>
<FocusHandler {manager} />
{#if doc !== undefined}
<Panel
object={doc}
allowClose={!embedded}
isAside={false}
isHeader={false}
isSub={false}
bind:useMaxWidth
printHeader={false}
{embedded}
adaptive={'default'}
bind:content
bind:innerWidth
floatAside={false}
on:open
on:close={() => dispatch('close')}
>
<svelte:fragment slot="beforeTitle">
<CardIcon value={doc} />
</svelte:fragment>
<svelte:fragment slot="title">
<ParentsNavigator element={doc} />
<CardPresenter value={doc} noUnderline />
</svelte:fragment>
<svelte:fragment slot="extra">
<ComponentExtensions
extension={card.extensions.EditCardHeaderExtension}
props={{
card: doc
}}
/>
<slot name="extra" />
</svelte:fragment>
<div class="container">
<div class="title flex-row-center">
<EditBox
focusIndex={1}
bind:value={title}
disabled={_readonly || updatePermissionForbidden}
placeholder={card.string.Card}
on:blur={(evt) => saveTitle(evt)}
/>
</div>
<TagsEditor {doc} readonly={_readonly} />
<CardAttributeEditor value={doc} {mixins} readonly={_readonly} ignoreKeys={['title', 'content', 'parent']} />
<Content {doc} readonly={_readonly || updatePermissionForbidden} bind:content />
</div>
<ComponentExtensions
extension={card.extensions.EditCardExtension}
props={{
card: doc
}}
/>
<Childs object={doc} readonly={_readonly} />
<RelationsEditor object={doc} readonly={_readonly} />
<Attachments
objectId={doc._id}
_class={doc._class}
space={doc.space}
readonly={_readonly}
attachments={doc.attachments ?? 0}
/>
<svelte:fragment slot="utils">
{#if !_readonly}
<Button
icon={IconMoreH}
iconProps={{ size: 'medium' }}
kind={'icon'}
dataId={'btnMoreActions'}
on:click={(e) => {
showMenu(e, { object: doc, excludedActions: [view.action.Open] })
}}
/>
{/if}
</svelte:fragment>
</Panel>
{/if}
<style lang="scss">
.container {
display: flex;
flex-direction: column;
width: 100%;
margin: auto;
}
.title {
font-size: 2.25rem;
margin-top: 1.75rem;
margin-bottom: 1rem;
}
</style>