mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-30 04:05:39 +00:00
Default values (#2792)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
79fbb9e6f3
commit
95ea0aab98
@ -152,6 +152,7 @@ export class TAttribute extends TDoc implements AnyAttribute {
|
||||
type!: Type<any>
|
||||
label!: IntlString
|
||||
isCustom?: boolean
|
||||
defaultValue?: any
|
||||
}
|
||||
|
||||
@Model(core.class.Type, core.class.Obj, DOMAIN_MODEL)
|
||||
|
@ -115,6 +115,7 @@ export interface Attribute<T extends PropertyType> extends Doc, UXObject {
|
||||
index?: IndexKind
|
||||
shortLabel?: IntlString
|
||||
isCustom?: boolean
|
||||
defaultValue?: any
|
||||
|
||||
// Extra customization properties
|
||||
[key: string]: any
|
||||
@ -192,6 +193,11 @@ export type Data<T extends Doc> = Omit<T, keyof Doc>
|
||||
*/
|
||||
export type AttachedData<T extends AttachedDoc> = Omit<T, keyof AttachedDoc>
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type DocData<T extends Doc> = T extends AttachedDoc ? AttachedData<T> : Data<T>
|
||||
|
||||
// T Y P E S
|
||||
|
||||
/**
|
||||
|
@ -13,9 +13,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Account, AnyAttribute, Class, Doc, DocIndexState, IndexKind, Obj, Ref } from './classes'
|
||||
import { FindResult } from './storage'
|
||||
import { Account, AnyAttribute, Class, Doc, DocData, DocIndexState, IndexKind, Obj, Ref } from './classes'
|
||||
import core from './component'
|
||||
import { Hierarchy } from './hierarchy'
|
||||
import { FindResult } from './storage'
|
||||
|
||||
function toHex (value: number, chars: number): string {
|
||||
const result = value.toString(16)
|
||||
@ -199,3 +200,23 @@ export function concatLink (host: string, path: string): string {
|
||||
return `${host}${path}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function fillDefaults<T extends Doc> (
|
||||
hierarchy: Hierarchy,
|
||||
object: DocData<T> | T,
|
||||
_class: Ref<Class<T>>
|
||||
): DocData<T> | T {
|
||||
const baseClass = hierarchy.isDerived(_class, core.class.AttachedDoc) ? core.class.AttachedDoc : core.class.Doc
|
||||
const attributes = hierarchy.getAllAttributes(_class, baseClass)
|
||||
for (const attribute of attributes) {
|
||||
if (attribute[1].defaultValue !== undefined) {
|
||||
if ((object as any)[attribute[0]] === undefined) {
|
||||
;(object as any)[attribute[0]] = attribute[1].defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Channel, findContacts, Organization } from '@hcengineering/contact'
|
||||
import { AttachedData, generateId, Ref, TxOperations, WithLookup } from '@hcengineering/core'
|
||||
import { AttachedData, fillDefaults, generateId, Ref, TxOperations, WithLookup } from '@hcengineering/core'
|
||||
import { Card, getClient, InlineAttributeBar } from '@hcengineering/presentation'
|
||||
import { Button, createFocusManager, EditBox, FocusHandler, IconInfo, Label } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@ -37,6 +37,9 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
fillDefaults(hierarchy, object, contact.class.Organization)
|
||||
|
||||
async function createOrganization () {
|
||||
await client.createDoc(contact.class.Organization, contact.space.Contacts, object, id)
|
||||
|
@ -22,6 +22,7 @@
|
||||
Account,
|
||||
Class,
|
||||
Client,
|
||||
fillDefaults,
|
||||
Doc,
|
||||
FindOptions,
|
||||
generateId,
|
||||
@ -99,6 +100,7 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
fillDefaults(hierarchy, doc, recruit.class.Applicant)
|
||||
|
||||
export function canClose (): boolean {
|
||||
return (preserveCandidate || _candidate === undefined) && assignee === undefined
|
||||
@ -184,6 +186,7 @@
|
||||
dueDate: null,
|
||||
createOn: Date.now()
|
||||
}
|
||||
fillDefaults(hierarchy, doc, recruit.class.Applicant)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
AttachedData,
|
||||
Data,
|
||||
Doc,
|
||||
fillDefaults,
|
||||
generateId,
|
||||
MixinData,
|
||||
Ref,
|
||||
@ -109,8 +110,11 @@
|
||||
remote: draft?.remote
|
||||
} as Candidate
|
||||
}
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
const object: Candidate = toCandidate(draft)
|
||||
fillDefaults(hierarchy, object, recruit.mixin.Candidate)
|
||||
|
||||
function resumeDraft () {
|
||||
return {
|
||||
@ -125,7 +129,6 @@
|
||||
let resume = resumeDraft() as resumeFile
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
|
||||
let inputFile: HTMLInputElement
|
||||
let loading = false
|
||||
@ -544,6 +547,7 @@
|
||||
object.avatar = undefined
|
||||
object.onsite = undefined
|
||||
object.remote = undefined
|
||||
fillDefaults(hierarchy, object, recruit.mixin.Candidate)
|
||||
}
|
||||
|
||||
export async function onOutsideClick () {
|
||||
|
@ -15,7 +15,15 @@
|
||||
<script lang="ts">
|
||||
import { AttachmentStyledBox } from '@hcengineering/attachment-resources'
|
||||
import contact, { Organization } from '@hcengineering/contact'
|
||||
import core, { Data, FindResult, generateId, getCurrentAccount, Ref, SortingOrder } from '@hcengineering/core'
|
||||
import core, {
|
||||
Data,
|
||||
fillDefaults,
|
||||
FindResult,
|
||||
generateId,
|
||||
getCurrentAccount,
|
||||
Ref,
|
||||
SortingOrder
|
||||
} from '@hcengineering/core'
|
||||
import { Card, createQuery, getClient, InlineAttributeBar, MessageBox, UserBox } from '@hcengineering/presentation'
|
||||
import { Vacancy as VacancyClass } from '@hcengineering/recruit'
|
||||
import tags from '@hcengineering/tags'
|
||||
@ -69,7 +77,6 @@
|
||||
fullDescription: '',
|
||||
location: ''
|
||||
}
|
||||
|
||||
export function canClose (): boolean {
|
||||
return name === '' && templateId !== undefined
|
||||
}
|
||||
@ -77,7 +84,9 @@
|
||||
let changed = false
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const templateQ = createQuery()
|
||||
fillDefaults(hierarchy, vacancyData, recruit.class.Vacancy)
|
||||
$: templateQ.query(task.class.KanbanTemplate, { _id: templateId }, (result) => {
|
||||
const { _class, _id, description, ...templateData } = result[0]
|
||||
vacancyData = { ...(templateData as unknown as Data<VacancyClass>), fullDescription: description }
|
||||
|
@ -69,6 +69,7 @@
|
||||
"Visibility": "Visibility",
|
||||
"Hidden": "Hidden",
|
||||
"Configure": "Configure",
|
||||
"InviteSettings": "Workspace invite settings"
|
||||
"InviteSettings": "Workspace invite settings",
|
||||
"DefaultValue": "Default value"
|
||||
}
|
||||
}
|
@ -70,6 +70,7 @@
|
||||
"Visibility": "Видимость",
|
||||
"Hidden": "Спрятанный",
|
||||
"Configure": "Настроить",
|
||||
"InviteSettings": "Настройки приглашений в пространство"
|
||||
"InviteSettings": "Настройки приглашений в пространство",
|
||||
"DefaultValue": "Значение по умолчанию"
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@
|
||||
let name: string
|
||||
let type: Type<PropertyType> | undefined
|
||||
let index: IndexKind | undefined
|
||||
let defaultValue: any | undefined
|
||||
let is: AnyComponent | undefined
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
@ -49,7 +50,8 @@
|
||||
name: name.trim().replace('/', '').replace(' ', '') + '_' + generateId(),
|
||||
label: getEmbeddedLabel(name),
|
||||
isCustom: true,
|
||||
type
|
||||
type,
|
||||
defaultValue
|
||||
}
|
||||
if (index !== undefined) {
|
||||
data.index = index
|
||||
@ -89,6 +91,7 @@
|
||||
const handleChange = (e: any) => {
|
||||
type = e.detail?.type
|
||||
index = e.detail?.index
|
||||
defaultValue = e.detail?.defaultValue
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
let name: string
|
||||
let type: Type<PropertyType> | undefined = attribute.type
|
||||
let index: IndexKind | undefined = attribute.index
|
||||
let defaultValue: any | undefined = attribute.defaultValue
|
||||
let is: AnyComponent | undefined
|
||||
|
||||
const client = getClient()
|
||||
@ -40,6 +41,9 @@
|
||||
if (newLabel !== attribute.label) {
|
||||
update.label = newLabel
|
||||
}
|
||||
if (defaultValue !== attribute.defaultValue) {
|
||||
update.defaultValue = defaultValue
|
||||
}
|
||||
if (!exist) {
|
||||
if (index !== attribute.index) {
|
||||
update.index = index
|
||||
@ -83,6 +87,7 @@
|
||||
const handleChange = (e: any) => {
|
||||
type = e.detail?.type
|
||||
index = e.detail?.index
|
||||
defaultValue = e.detail?.defaultValue
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -119,6 +124,7 @@
|
||||
{is}
|
||||
props={{
|
||||
type,
|
||||
defaultValue,
|
||||
editable: !exist
|
||||
}}
|
||||
on:change={handleChange}
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { TypeEnum } from '@hcengineering/model'
|
||||
import presentation, { getClient } from '@hcengineering/presentation'
|
||||
import { Button, Label, showPopup } from '@hcengineering/ui'
|
||||
import { EnumEditor } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import setting from '../../plugin'
|
||||
import EnumSelect from './EnumSelect.svelte'
|
||||
@ -24,11 +25,12 @@
|
||||
export let type: EnumOf | undefined
|
||||
export let editable: boolean = true
|
||||
export let value: Enum | undefined
|
||||
export let defaultValue: string | undefined
|
||||
|
||||
const client = getClient()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: value && dispatch('change', { type: TypeEnum(value._id) })
|
||||
$: value && changeEnum(value)
|
||||
$: ref = value?._id ?? type?.of
|
||||
|
||||
const create = {
|
||||
@ -36,6 +38,11 @@
|
||||
component: setting.component.EditEnum
|
||||
}
|
||||
|
||||
function changeEnum (value: Enum) {
|
||||
type = TypeEnum(value._id)
|
||||
dispatch('change', { type, defaultValue })
|
||||
}
|
||||
|
||||
async function updateSelected (ref: Ref<Enum> | undefined) {
|
||||
value = ref !== undefined ? await client.findOne(core.class.Enum, { _id: ref }) : undefined
|
||||
}
|
||||
@ -48,24 +55,42 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={core.string.Enum} />
|
||||
<div class="ml-4">
|
||||
{#if editable}
|
||||
<EnumSelect label={core.string.Enum} bind:value {create} />
|
||||
{:else if value}
|
||||
{value.name}
|
||||
<div>
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={core.string.Enum} />
|
||||
<div class="ml-4">
|
||||
{#if editable}
|
||||
<EnumSelect label={core.string.Enum} bind:value {create} />
|
||||
{:else if value}
|
||||
{value.name}
|
||||
{/if}
|
||||
</div>
|
||||
{#if value}
|
||||
<div class="ml-2">
|
||||
<Button
|
||||
icon={setting.icon.Setting}
|
||||
kind={'no-border'}
|
||||
size={'small'}
|
||||
showTooltip={{ label: presentation.string.Edit }}
|
||||
on:click={edit}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if value}
|
||||
<div class="ml-2">
|
||||
<Button
|
||||
icon={setting.icon.Setting}
|
||||
kind={'no-border'}
|
||||
size={'small'}
|
||||
showTooltip={{ label: presentation.string.Edit }}
|
||||
on:click={edit}
|
||||
/>
|
||||
{#if value && type}
|
||||
<div class="flex-row-center mt-2">
|
||||
<Label label={setting.string.DefaultValue} />
|
||||
<div class="ml-2">
|
||||
<EnumEditor
|
||||
label={setting.string.DefaultValue}
|
||||
{type}
|
||||
value={defaultValue ?? ''}
|
||||
onChange={(e) => {
|
||||
defaultValue = e
|
||||
dispatch('change', { type, defaultValue })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -62,6 +62,7 @@ export default mergeIds(settingId, setting, {
|
||||
ShowAttribute: '' as IntlString,
|
||||
Visibility: '' as IntlString,
|
||||
Hidden: '' as IntlString,
|
||||
InviteSettings: '' as IntlString
|
||||
InviteSettings: '' as IntlString,
|
||||
DefaultValue: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
@ -21,6 +21,7 @@
|
||||
AttachedData,
|
||||
Data,
|
||||
Doc,
|
||||
fillDefaults,
|
||||
generateId,
|
||||
Ref,
|
||||
SortingOrder,
|
||||
@ -95,6 +96,8 @@
|
||||
export let onDraftChanged: () => void
|
||||
|
||||
const draft: IssueDraft | undefined = shouldSaveDraft ? getUserDraft(tracker.class.IssueDraft) : undefined
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
let subIssuesComponent: SubIssues
|
||||
|
||||
@ -145,6 +148,7 @@
|
||||
childInfo: []
|
||||
}
|
||||
: toIssue(defaultIssue, draft)
|
||||
fillDefaults(hierarchy, object, tracker.class.Issue)
|
||||
|
||||
function resetObject (): void {
|
||||
templateId = undefined
|
||||
@ -156,6 +160,7 @@
|
||||
updateIssueStatusId(currentProject, status)
|
||||
updateAssigneeId(currentProject)
|
||||
}
|
||||
fillDefaults(hierarchy, object, tracker.class.Issue)
|
||||
}
|
||||
|
||||
let templateId: Ref<IssueTemplate> | undefined = draft?.template?.template
|
||||
@ -223,7 +228,6 @@
|
||||
$: updateTemplate(template)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const statusesQuery = createQuery()
|
||||
const spaceQuery = createQuery()
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
export let _id: Ref<Doc>
|
||||
export let _class: Ref<Class<Doc>>
|
||||
|
||||
console.log('OPEN EDIT DOC')
|
||||
|
||||
let realObjectClass: Ref<Class<Doc>> = _class
|
||||
let lastId: Ref<Doc> = _id
|
||||
let lastClass: Ref<Class<Doc>> = _class
|
||||
|
@ -145,7 +145,8 @@ export {
|
||||
TreeNode,
|
||||
TreeItem,
|
||||
StringEditor,
|
||||
DocNavLink
|
||||
DocNavLink,
|
||||
EnumEditor
|
||||
}
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
|
Loading…
Reference in New Issue
Block a user