* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { computed } from 'vue'
import { constants } from '@opentiny/tiny-engine-utils'
import { useBlock } from '@opentiny/tiny-engine-meta-register'
import type { PageState } from '@opentiny/tiny-engine-canvas'
import type { Property, Linked } from '@opentiny/tiny-engine-plugin-materials'
const { SCHEMA_DATA_TYPE } = constants
interface AddPropertyLinksOptions {
linked: Linked
propertyName: string
componentProperties: Property[]
defaultValue: unknown
}
const addPropertyLinks = ({ linked, propertyName, componentProperties, defaultValue: _ }: AddPropertyLinksOptions) => {
for (let i = 0; i < componentProperties.length; i++) {
const propertyList = componentProperties[i].content
for (let j = 0; j < propertyList.length; j++) {
const property = propertyList[j]
if (property.property === propertyName) {
Object.assign(property, {
linked,
widget: {
props: {
modelValue: {
type: SCHEMA_DATA_TYPE.JSExpression,
value: `this.props.${linked.blockProperty}`
}
}
}
})
}
}
}
}
interface FindLinkedOptions {
componentProperties: Property[]
componentId: string
blockProperties: Property['content'][number][]
}
const findLinked = (options: FindLinkedOptions) => {
const { componentProperties, componentId, blockProperties } = options
for (let i = 0; i < blockProperties.length; i++) {
const property = blockProperties[i]
if (property.linked && componentId === property.linked.id) {
addPropertyLinks({
componentProperties,
linked: { ...property.linked, blockProperty: property.property },
defaultValue: property.defaultValue,
propertyName: property.linked.property
})
}
}
}
const resetLink = (properties: Property[]) => {
if (properties && Array.isArray(properties)) {
properties.forEach((group) => {
if (group?.content && Array.isArray(group.content)) {
group.content.forEach((property) => {
property.linked = null
})
}
})
}
}
const getProperty = ({ pageState }: { pageState: PageState }) => {
const { getCurrentBlock, getBlockProperties } = useBlock()
const properties = computed(() => {
resetLink(pageState.properties as Property[])
if (pageState.isBlock && pageState.currentSchema?.id) {
findLinked({
componentProperties: pageState.properties as Property[],
componentId: pageState.currentSchema.id,
blockProperties: getBlockProperties(getCurrentBlock())
})
}
return pageState.properties
})
return {
properties
}
}
export default () => ({ getProperty })