mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-17 13:54:11 +00:00
Support for draft attrubutes (#2407)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com> Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
e83e0ee622
commit
e87b7fd27f
packages
plugins/view-resources/src
@ -1,4 +1,6 @@
|
||||
import { PlatformError, Severity, Status } from '@hcengineering/platform'
|
||||
import { Doc } from './classes'
|
||||
import core from './component'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -27,6 +29,40 @@ export function getObjectValue (key: string, doc: Doc): any {
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function setObjectValue (key: string, doc: Doc, newValue: any): void {
|
||||
// Check dot notation
|
||||
if (key.length === 0) {
|
||||
return
|
||||
}
|
||||
key = key.split('\\$').join('$')
|
||||
let dots = key.split('.')
|
||||
// Replace escapting, since memdb is not escape keys
|
||||
|
||||
const last = dots[dots.length - 1]
|
||||
dots = dots.slice(0, -1)
|
||||
|
||||
// We have dots, so iterate in depth
|
||||
let value = doc as any
|
||||
for (const d of dots) {
|
||||
if (Array.isArray(value) && isNestedArrayQuery(value, d)) {
|
||||
// Arrays are not supported
|
||||
throw new PlatformError(new Status(Severity.ERROR, core.status.ObjectNotFound, { _id: 'dots' }))
|
||||
}
|
||||
const lvalue = value?.[d]
|
||||
if (lvalue === undefined) {
|
||||
value[d] = {}
|
||||
value = value?.[d]
|
||||
} else {
|
||||
value = lvalue
|
||||
}
|
||||
}
|
||||
value[last] = newValue
|
||||
return value
|
||||
}
|
||||
|
||||
function isNestedArrayQuery (value: any, d: string): boolean {
|
||||
return Number.isNaN(Number.parseInt(d)) && value?.[d as any] === undefined
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
import type { KeysByType } from 'simplytyped'
|
||||
import type { Account, Arr, AttachedDoc, Class, Data, Doc, Domain, Mixin, PropertyType, Ref, Space } from './classes'
|
||||
import core from './component'
|
||||
import { setObjectValue } from './objvalue'
|
||||
import { _getOperator } from './operator'
|
||||
import { _toDoc } from './proxy'
|
||||
import type { DocumentQuery, TxResult } from './storage'
|
||||
@ -295,7 +296,7 @@ export abstract class TxProcessor implements WithTx {
|
||||
const operator = _getOperator(key)
|
||||
operator(doc, ops[key])
|
||||
} else {
|
||||
;(doc as any)[key] = ops[key]
|
||||
setObjectValue(key, doc, ops[key])
|
||||
}
|
||||
}
|
||||
doc.modifiedBy = tx.modifiedBy
|
||||
@ -312,7 +313,7 @@ export abstract class TxProcessor implements WithTx {
|
||||
const operator = _getOperator(key)
|
||||
operator(mixin, ops[key])
|
||||
} else {
|
||||
mixin[key] = ops[key]
|
||||
setObjectValue(key, mixin, ops[key])
|
||||
}
|
||||
}
|
||||
rawDoc.modifiedBy = tx.modifiedBy
|
||||
|
@ -18,20 +18,24 @@
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { AnySvelteComponent, Label, tooltip } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { getAttribute, KeyedAttribute, updateAttribute } from '../attributes'
|
||||
import { AttributeCategory, getAttributePresenterClass, getClient } from '../utils'
|
||||
|
||||
export let key: KeyedAttribute | string
|
||||
export let object: Doc
|
||||
export let object: Doc | Record<string, any>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let maxWidth: string | undefined = undefined
|
||||
export let focus: boolean = false
|
||||
export let showHeader: boolean = true
|
||||
export let readonly = false
|
||||
export let draft = false
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: attribute = typeof key === 'string' ? hierarchy.getAttribute(_class, key) : key.attr
|
||||
$: attributeKey = typeof key === 'string' ? key : key.key
|
||||
$: presenterClass = attribute !== undefined ? getAttributePresenterClass(hierarchy, attribute) : undefined
|
||||
@ -67,7 +71,12 @@
|
||||
|
||||
function onChange (value: any) {
|
||||
const doc = object as Doc
|
||||
updateAttribute(client, doc, _class, { key: attributeKey, attr: attribute }, value)
|
||||
if (draft) {
|
||||
;(doc as any)[attributeKey] = value
|
||||
dispatch('update', { key, value })
|
||||
} else {
|
||||
updateAttribute(client, doc, _class, { key: attributeKey, attr: attribute }, value)
|
||||
}
|
||||
}
|
||||
$: isReadonly = (attribute.readonly ?? false) || readonly
|
||||
</script>
|
||||
|
@ -18,16 +18,17 @@
|
||||
import { KeyedAttribute } from '../attributes'
|
||||
import AttributeBarEditor from './AttributeBarEditor.svelte'
|
||||
|
||||
export let object: Doc
|
||||
export let object: Doc | Record<string, any>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let keys: (string | KeyedAttribute)[]
|
||||
export let showHeader: boolean = true
|
||||
export let readonly = false
|
||||
export let draft = false
|
||||
</script>
|
||||
|
||||
<div class="attributes-bar-container vertical">
|
||||
{#each keys as key (typeof key === 'string' ? key : key.key)}
|
||||
<AttributeBarEditor {key} {_class} {object} {showHeader} {readonly} />
|
||||
<AttributeBarEditor {key} {_class} {object} {showHeader} {readonly} {draft} on:update />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
import { Button, getCurrentLocation, Label, navigate } from '@hcengineering/ui'
|
||||
import { getFiltredKeys, isCollectionAttr } from '../utils'
|
||||
|
||||
export let object: Doc
|
||||
export let object: Doc | Record<string, any>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let to: Ref<Class<Doc>> | undefined = core.class.Doc
|
||||
export let ignoreKeys: string[] = []
|
||||
@ -28,6 +28,7 @@
|
||||
export let readonly = false
|
||||
export let showLabel: IntlString | undefined = undefined
|
||||
export let defaultCollapsed = false
|
||||
export let draft = false
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
@ -84,7 +85,7 @@
|
||||
</div>
|
||||
{#if keys.length}
|
||||
<div class="collapsed-container" class:collapsed>
|
||||
<AttributesBar {_class} {object} keys={keys.map((p) => p.key)} {readonly} />
|
||||
<AttributesBar {_class} {object} keys={keys.map((p) => p.key)} {readonly} {draft} on:update />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
@ -93,7 +93,9 @@ export {
|
||||
getObjectPresenter,
|
||||
LoadingProps,
|
||||
setActiveViewletId,
|
||||
getActiveViewletId
|
||||
getActiveViewletId,
|
||||
getFiltredKeys,
|
||||
isCollectionAttr
|
||||
} from './utils'
|
||||
export {
|
||||
HTMLPresenter,
|
||||
|
Loading…
Reference in New Issue
Block a user