Compare commits
37 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
b568985860 | |
![]() |
8507b65683 | |
![]() |
aa79110d52 | |
![]() |
4ea63abba7 | |
![]() |
452563a569 | |
![]() |
4cd3c3b8ea | |
![]() |
b72e7ea5e7 | |
![]() |
0935220b77 | |
![]() |
eda10e58c8 | |
![]() |
e828de2970 | |
![]() |
3a831bf833 | |
|
2ce7c4a201 | |
![]() |
5fa99f8a8e | |
![]() |
603be3bdb9 | |
![]() |
50f968f27d | |
![]() |
9ccfc9fa8a | |
![]() |
c35c34e036 | |
![]() |
76c23b767b | |
![]() |
c218724543 | |
![]() |
871463f185 | |
![]() |
59eaf035bb | |
![]() |
1ed91983b0 | |
|
a442108e2b | |
![]() |
3a204624af | |
![]() |
0d36f2d344 | |
![]() |
a383421c38 | |
![]() |
fd164a1cd2 | |
![]() |
fec563dda3 | |
![]() |
732bed9795 | |
![]() |
2c27f9141a | |
![]() |
66268d3ec3 | |
![]() |
e651dffa2b | |
![]() |
91d3ae108c | |
![]() |
277be2f11e | |
![]() |
2c478ce391 | |
![]() |
c341f4c2c5 | |
![]() |
858e178af6 |
|
@ -88,9 +88,9 @@ gantt
|
|||
dateFormat YYYY-MM-DD
|
||||
axisFormat %Y-%m-%d
|
||||
|
||||
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
|
||||
1.0.0-rc version : 2024-04-01, 2024-06-30
|
||||
1.0.0 version : 2024-07-01, 2024-07-31
|
||||
1.0.0-beta.x version : 2023-09-25, 2024-05-20
|
||||
1.0.0-rc version(refactor version) : 2024-10-01
|
||||
1.0.0 version : 2024-11-01
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -84,13 +84,13 @@ pnpm run build:alpha 或 build:prod
|
|||
## 里程碑
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %Y-%m-%d
|
||||
|
||||
1.0.0-beta.x version :active,2023-09-25, 2024-03-31
|
||||
1.0.0-rc version : 2024-04-01, 2024-06-30
|
||||
1.0.0 version : 2024-07-01, 2024-07-31
|
||||
1.0.0-beta.x version : 2023-09-25, 2024-05-20
|
||||
1.0.0-rc version(refactor version) : 2024-10-01
|
||||
1.0.0 version : 2024-11-01
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-mock",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -25,7 +25,7 @@
|
|||
"lint": "eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/tiny-engine-dsl-vue": "^1.0.3",
|
||||
"@opentiny/tiny-engine-dsl-vue": "^1.0.4",
|
||||
"@seald-io/nedb": "^4.0.2",
|
||||
"fs-extra": "^11.1.1",
|
||||
"glob": "^10.3.4",
|
||||
|
|
|
@ -1918,6 +1918,13 @@
|
|||
"destructuring": true,
|
||||
"version": "0.1.17"
|
||||
},
|
||||
{
|
||||
"componentName": "TinyCheckbox",
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "Checkbox",
|
||||
"destructuring": true,
|
||||
"version": "3.14.0"
|
||||
},
|
||||
{
|
||||
"componentName": "TinySelect",
|
||||
"package": "@opentiny/vue",
|
||||
|
@ -1974,6 +1981,76 @@
|
|||
"destructuring": true,
|
||||
"version": "0.1.16"
|
||||
},
|
||||
{
|
||||
"componentName": "TinyCollapse",
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "Collapse",
|
||||
"destructuring": true,
|
||||
"version": "3.14.0"
|
||||
},
|
||||
{
|
||||
"componentName": "TinyCollapseItem",
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "CollapseItem",
|
||||
"destructuring": true,
|
||||
"version": "3.14.0"
|
||||
},
|
||||
{
|
||||
"componentName": "TinyBreadcrumb",
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "Breadcrumb",
|
||||
"destructuring": true,
|
||||
"version": "3.14.0"
|
||||
},
|
||||
{
|
||||
"componentName": "TinyBreadcrumbItem",
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "BreadcrumbItem",
|
||||
"destructuring": true,
|
||||
"version": "3.14.0"
|
||||
},
|
||||
{
|
||||
"componentName": "ElInput",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElInput",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "ElButton",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElButton",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "ElForm",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElForm",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "ElFormItem",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElFormItem",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "ElTable",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElTable",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "ElTableColumn",
|
||||
"package": "element-plus",
|
||||
"exportName": "ElTableColumn",
|
||||
"destructuring": true,
|
||||
"version": "2.4.2"
|
||||
},
|
||||
{
|
||||
"componentName": "PortalHome",
|
||||
"main": "common/components/home",
|
||||
|
|
|
@ -72,7 +72,8 @@ export default class BlockService {
|
|||
|
||||
async detail(blockId) {
|
||||
const result = await this.db.findOneAsync({ _id: blockId })
|
||||
return result
|
||||
|
||||
return getResponseData(result)
|
||||
}
|
||||
|
||||
async delete(blockId) {
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.21.3",
|
||||
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
|
||||
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
|
||||
"@types/node": "^18.0.0",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-block-build",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"description": "translate block to webcomponent template",
|
||||
"main": "./dist/web-components.es.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -43,7 +43,7 @@ export default defineConfig(({ command, mode }) => {
|
|||
}
|
||||
|
||||
const vuePluginConfig = {}
|
||||
const styleLinks = ['https://npm.onmicrosoft.cn/@opentiny/vue-theme@3.14/index.css']
|
||||
const styleLinks = ['https://unpkg.com/@opentiny/vue-theme@3.14/index.css']
|
||||
|
||||
config.publicDir = false
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-builtin-component",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-canvas",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -229,7 +229,10 @@ export default {
|
|||
}
|
||||
|
||||
const showAction = computed(() => {
|
||||
const { parent } = getCurrent()
|
||||
const { schema, parent } = getCurrent()
|
||||
if (schema?.props?.['data-id'] === 'root-container') {
|
||||
return false
|
||||
}
|
||||
return !props.resize && parent && parent?.type !== 'JSSlot'
|
||||
})
|
||||
|
||||
|
|
|
@ -185,6 +185,8 @@ export const dragEnd = () => {
|
|||
if (element && canvasState.type === 'absolute') {
|
||||
data.props = data.props || {}
|
||||
data.props.style = element.style.cssText
|
||||
|
||||
getController().addHistory()
|
||||
}
|
||||
|
||||
// 重置拖拽状态
|
||||
|
@ -541,6 +543,8 @@ const setHoverRect = (element, data) => {
|
|||
return undefined
|
||||
}
|
||||
|
||||
let moveUpdateTimer = null
|
||||
|
||||
// 绝对布局
|
||||
const absoluteMove = (event, element) => {
|
||||
const { clientX, clientY } = event
|
||||
|
@ -572,6 +576,19 @@ const absoluteMove = (event, element) => {
|
|||
element.style.height = `${clientY - y}px`
|
||||
}
|
||||
}
|
||||
|
||||
clearTimeout(moveUpdateTimer)
|
||||
|
||||
const { data } = dragState
|
||||
data.props = data.props || {}
|
||||
|
||||
// 防抖更新位置信息到 schema
|
||||
moveUpdateTimer = setTimeout(() => {
|
||||
data.props.style = element.style.cssText
|
||||
|
||||
getController().addHistory()
|
||||
}, 100)
|
||||
|
||||
updateRect()
|
||||
}
|
||||
|
||||
|
@ -716,11 +733,7 @@ export const onMouseUp = () => {
|
|||
if (absolute) {
|
||||
targetNode.node = getSchema()
|
||||
data.props = data.props || {}
|
||||
data.props.style = {
|
||||
position: 'absolute',
|
||||
top: dragState.mouse.y + 'px',
|
||||
left: dragState.mouse.x + 'px'
|
||||
}
|
||||
data.props.style = `position: absolute; top: ${dragState.mouse.y}px; left: ${dragState.mouse.x}px`
|
||||
}
|
||||
|
||||
insertNode(targetNode, position)
|
||||
|
|
|
@ -379,7 +379,8 @@ export default {
|
|||
// 渲染画布增加根节点,与出码和预览保持一致
|
||||
const rootChildrenSchema = {
|
||||
componentName: 'div',
|
||||
props: schema.props,
|
||||
// 手动添加一个唯一的属性,后续在画布选中此节点时方便处理额外的逻辑。由于没有修改schema,不会影响出码
|
||||
props: { ...schema.props, 'data-id': 'root-container' },
|
||||
children: schema.children
|
||||
}
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ const getBindProps = (schema, scope) => {
|
|||
...parseData(schema.props, scope),
|
||||
[DESIGN_UIDKEY]: id,
|
||||
[DESIGN_TAGKEY]: componentName,
|
||||
onMoseover: stopEvent,
|
||||
onMouseover: stopEvent,
|
||||
onFocus: stopEvent
|
||||
}
|
||||
if (scope) {
|
||||
|
|
|
@ -82,7 +82,7 @@ import {
|
|||
FormItem as TinyFormItem
|
||||
} from '@opentiny/vue'
|
||||
import { theme } from '@opentiny/tiny-engine-controller/adapter'
|
||||
import { useLayout, useNotify, useCanvas } from '@opentiny/tiny-engine-controller'
|
||||
import { useLayout, useNotify, useCanvas, useBlock } from '@opentiny/tiny-engine-controller'
|
||||
import { constants } from '@opentiny/tiny-engine-utils'
|
||||
import VueMonaco from './VueMonaco.vue'
|
||||
|
||||
|
@ -163,7 +163,7 @@ export default {
|
|||
const { getEditBlock, publishBlock } = getPluginApi(PLUGIN_NAME.BlockManage)
|
||||
if (valid) {
|
||||
const params = {
|
||||
block: getEditBlock(),
|
||||
block: getEditBlock() || useBlock().getCurrentBlock(),
|
||||
is_compile: true,
|
||||
deploy_info: formState.deployInfo,
|
||||
version: formState.version,
|
||||
|
|
|
@ -295,16 +295,13 @@ export default {
|
|||
result.message = typeof message === 'string' ? message : message?.[locale.value]
|
||||
}
|
||||
|
||||
const isEmptyInputValue = (value) => {
|
||||
// 通过 value == null 做隐式类型转换
|
||||
// 空值约定为 undefined | null | ''
|
||||
return value == null || (typeOf(value) === TYPES.StringType && value.trim() === '')
|
||||
}
|
||||
const verifyRequired = (value) => {
|
||||
if (typeOf(value) === TYPES.BooleanType) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (typeOf(value) === TYPES.StringType) {
|
||||
return value.trim()
|
||||
}
|
||||
|
||||
return value
|
||||
return !isEmptyInputValue(value)
|
||||
}
|
||||
|
||||
const verifyValue = (value = '', rules = []) => {
|
||||
|
|
|
@ -129,7 +129,7 @@ export default {
|
|||
})
|
||||
|
||||
watchEffect(() => {
|
||||
state.bindLifeCycles = props.bindLifeCycles || useCanvas().canvasApi.value?.getSchema()?.lifeCycles || {}
|
||||
state.bindLifeCycles = props.bindLifeCycles || {}
|
||||
})
|
||||
|
||||
const searchLifeCyclesList = (value) => {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="head-content">
|
||||
<meta-input v-model="state.text" type="textarea" @change="change"></meta-input>
|
||||
<meta-input v-model="state.text" type="textarea" @update:modelValue="change"></meta-input>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
</div>
|
||||
<tiny-form-item
|
||||
:prop="paramsPropPath(index)"
|
||||
:rules="[{ validator: parmasStringValidator, trigger: 'blur' }]"
|
||||
:rules="[{ validator: paramsStringValidator, trigger: 'blur' }]"
|
||||
class="slot-name-form-item"
|
||||
>
|
||||
<tiny-input
|
||||
v-model="slot.params"
|
||||
class="use-slot-params"
|
||||
@change="validParmas(slot, paramsPropPath(index))"
|
||||
@change="validParams(paramsPropPath(index), slot)"
|
||||
></tiny-input>
|
||||
</tiny-form-item>
|
||||
</div>
|
||||
|
@ -84,15 +84,59 @@ export default {
|
|||
|
||||
const paramsPropPath = (index) => `${index}.params`
|
||||
|
||||
const parmasStringValidator = (rule, value, callback) => {
|
||||
if (value && value.split(',').some((parma) => !verifyJsVarName(parma))) {
|
||||
const paramsStringValidator = (rule, value, callback) => {
|
||||
if (value && value.split(',').some((param) => !verifyJsVarName(param))) {
|
||||
callback(new Error('仅支持JavaScript中有效的变量名'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const updateSlotParams = (slotData) => {
|
||||
emit('update:modelValue', slotData)
|
||||
|
||||
// 更新当前选中组件的根属性,不更新在jsslot中的数据非响应式
|
||||
const [propsName] = path.split('.')
|
||||
const schema = useProperties().getSchema()
|
||||
schema.props[propsName] = JSON.parse(JSON.stringify(schema.props[propsName]))
|
||||
}
|
||||
|
||||
const setSlotParams = ({ name, params = '' }) => {
|
||||
if (!props.modelValue?.[name]) {
|
||||
return
|
||||
}
|
||||
|
||||
const slotData = { ...(props.modelValue || {}) }
|
||||
|
||||
if (params.length) {
|
||||
slotData[name].params = params.split(',')
|
||||
} else {
|
||||
delete slotData[name].params
|
||||
}
|
||||
|
||||
updateSlotParams(slotData)
|
||||
}
|
||||
|
||||
const toggleSlot = (idx, { bind, name, params = '' }) => {
|
||||
// 原本绑定的,解除绑定
|
||||
if (bind) {
|
||||
useModal().confirm({
|
||||
title: '提示',
|
||||
message: '关闭后插槽内的内容将被清空,是否继续?',
|
||||
status: 'info',
|
||||
exec: () => {
|
||||
slotList.value[idx].bind = false
|
||||
const { [name]: _deleted, ...rest } = { ...(props.modelValue || {}) }
|
||||
updateSlotParams(rest)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 未绑定的,新增绑定
|
||||
slotList.value[idx].bind = true
|
||||
|
||||
const slotInfo = {
|
||||
[name]: {
|
||||
type: 'JSSlot',
|
||||
|
@ -104,47 +148,17 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
const slotData = { ...slotInfo, ...(props.modelValue || {}) }
|
||||
|
||||
if (params.length) {
|
||||
slotData[name].params = params.split(',')
|
||||
} else {
|
||||
delete slotData[name].params
|
||||
slotInfo[name].params = params.split(',')
|
||||
}
|
||||
if (bind) {
|
||||
useModal().confirm({
|
||||
title: '提示',
|
||||
message: '关闭后插槽内的内容将被清空,是否继续?',
|
||||
status: 'info',
|
||||
exec: () => {
|
||||
slotList.value[idx].bind = false
|
||||
delete slotData[name]
|
||||
emit('update:modelValue', slotData)
|
||||
const [propsName] = path.split('.')
|
||||
const schema = useProperties().getSchema()
|
||||
schema.props[propsName] = JSON.parse(JSON.stringify(schema.props[propsName]))
|
||||
},
|
||||
cancel: () => {}
|
||||
})
|
||||
} else {
|
||||
slotList.value[idx].bind = true
|
||||
}
|
||||
emit('update:modelValue', slotData)
|
||||
|
||||
// 更新当前选中组件的根属性,不根新在jsslot中的数据非响应式
|
||||
const [propsName] = path.split('.')
|
||||
const schema = useProperties().getSchema()
|
||||
schema.props[propsName] = JSON.parse(JSON.stringify(schema.props[propsName]))
|
||||
updateSlotParams({ ...(props.modelValue || {}), ...slotInfo })
|
||||
}
|
||||
|
||||
const setParams = (slot) => {
|
||||
slot.bind && toggleSlot(true, slot)
|
||||
}
|
||||
|
||||
const validParmas = (slot, parmasPath) => {
|
||||
slotRef.value.validateField([parmasPath], (tips) => {
|
||||
if (!tips) {
|
||||
setParams(slot)
|
||||
const validParams = (paramsPath, slot) => {
|
||||
slotRef.value.validateField([paramsPath], (error) => {
|
||||
if (!error) {
|
||||
slot.bind && setSlotParams(slot)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -159,9 +173,8 @@ export default {
|
|||
slotList,
|
||||
paramsPropPath,
|
||||
slotRef,
|
||||
parmasStringValidator,
|
||||
validParmas,
|
||||
setParams,
|
||||
paramsStringValidator,
|
||||
validParams,
|
||||
state,
|
||||
componentsMap
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-common",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ import { useHttp } from '@opentiny/tiny-engine-http'
|
|||
import usePage from '../src/usePage'
|
||||
import useCanvas from '../src/useCanvas'
|
||||
import useNotify from '../src/useNotify'
|
||||
import useBreadcrumb from '../src/useBreadcrumb'
|
||||
import { isVsCodeEnv } from './environments'
|
||||
import { generateRouter, generatePage } from './vscodeGenerateFile'
|
||||
|
||||
|
@ -39,7 +40,7 @@ export const requestEvent = (url, params) => {
|
|||
* @returns { Promise }
|
||||
*
|
||||
*/
|
||||
export const handlePageUpdate = (pageId, params, routerChange) => {
|
||||
export const handlePageUpdate = (pageId, params, routerChange, isCurEditPage) => {
|
||||
return http
|
||||
.post(`/app-center/api/pages/update/${pageId}`, params)
|
||||
.then((res) => {
|
||||
|
@ -60,14 +61,19 @@ export const handlePageUpdate = (pageId, params, routerChange) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (routerChange) {
|
||||
pageSettingState.updateTreeData()
|
||||
}
|
||||
// 更新页面管理的列表,如果不存在,说明还没有打开过页面管理面板
|
||||
pageSettingState.updateTreeData?.()
|
||||
pageSettingState.isNew = false
|
||||
useNotify({ message: '保存成功!', type: 'success' })
|
||||
|
||||
// 更新 页面状态 标志
|
||||
setSaved(true)
|
||||
|
||||
if (isCurEditPage) {
|
||||
const { setBreadcrumbPage } = useBreadcrumb()
|
||||
setBreadcrumbPage([params.name])
|
||||
}
|
||||
|
||||
return res
|
||||
})
|
||||
.catch((err) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-controller",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -293,7 +293,7 @@ const initBlock = async (blockId) => {
|
|||
const blockApi = getPluginApi(PLUGIN_NAME.BlockManage)
|
||||
const blockContent = await blockApi.getBlockById(blockId)
|
||||
|
||||
if (blockContent.public_scope_tenants.length) {
|
||||
if (blockContent?.public_scope_tenants?.length) {
|
||||
blockContent.public_scope_tenants = blockContent.public_scope_tenants.map((e) => e.id)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# alpha mode, used by the "build:alpha" script
|
||||
|
||||
NODE_ENV=production
|
||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
||||
VITE_CDN_DOMAIN=https://unpkg.com
|
||||
VITE_LOCAL_IMPORT_MAPS=false
|
||||
VITE_LOCAL_BUNDLE_DEPS=false
|
||||
# VITE_ORIGIN=
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# development mode, used by the "vite" command
|
||||
|
||||
NODE_ENV=development
|
||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
||||
VITE_CDN_DOMAIN=https://unpkg.com
|
||||
VITE_LOCAL_IMPORT_MAPS=false
|
||||
VITE_LOCAL_BUNDLE_DEPS=false
|
||||
# request data via alpha service
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# prod mode, used by the "build:prod" script
|
||||
|
||||
NODE_ENV=production
|
||||
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
|
||||
VITE_CDN_DOMAIN=https://unpkg.com
|
||||
VITE_LOCAL_IMPORT_MAPS=false
|
||||
VITE_LOCAL_BUNDLE_DEPS=false
|
||||
#VITE_ORIGIN=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine",
|
||||
"version": "1.0.0-beta.4",
|
||||
"version": "1.0.0-rc.1",
|
||||
"description": "TinyEngine enables developers to customize low-code platforms, build low-bit platforms online in real time, and support secondary development or integration of low-bit platform capabilities.",
|
||||
"homepage": "https://opentiny.design/tiny-engine",
|
||||
"keywords": [
|
||||
|
@ -89,7 +89,6 @@
|
|||
"eslint-linter-browserify": "8.57.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jszip": "^3.10.1",
|
||||
"monaco-editor": "0.33.0",
|
||||
"prettier": "2.7.1",
|
||||
"sortablejs": "^1.14.0",
|
||||
|
@ -107,6 +106,7 @@
|
|||
"assert": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"esbuild": "^0.21.5",
|
||||
"esbuild-plugin-copy": "^2.1.1",
|
||||
"eslint": "^8.38.0",
|
||||
"eslint-plugin-vue": "^8.0.0",
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"exportName": "ElInput"
|
||||
"exportName": "ElInput",
|
||||
"destructuring": true
|
||||
},
|
||||
"group": "表单组件",
|
||||
"category": "element-plus",
|
||||
|
@ -300,10 +301,11 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"exportName": "ElButton"
|
||||
"exportName": "ElButton",
|
||||
"destructuring": true
|
||||
},
|
||||
"group": "基础组件",
|
||||
"category": "element-plus",
|
||||
|
@ -621,9 +623,10 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"destructuring": true,
|
||||
"exportName": "ElForm"
|
||||
},
|
||||
"group": "表单组件",
|
||||
|
@ -1078,9 +1081,10 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"destructuring": true,
|
||||
"exportName": "ElFormItem"
|
||||
},
|
||||
"group": "表单组件",
|
||||
|
@ -1428,9 +1432,10 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"destructuring": true,
|
||||
"exportName": "ElTable"
|
||||
},
|
||||
"group": "数据展示",
|
||||
|
@ -2666,9 +2671,10 @@
|
|||
"npm": {
|
||||
"package": "element-plus",
|
||||
"version": "2.4.2",
|
||||
"script": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://npm.onmicrosoft.cn/element-plus@2.4.2/dist/index.css",
|
||||
"script": "https://unpkg.com/element-plus@2.4.2/dist/index.full.mjs",
|
||||
"css": "https://unpkg.com/element-plus@2.4.2/dist/index.css",
|
||||
"dependencies": null,
|
||||
"destructuring": true,
|
||||
"exportName": "ElTableColumn"
|
||||
},
|
||||
"group": "表单组件",
|
||||
|
@ -8901,7 +8907,7 @@
|
|||
"devMode": "proCode",
|
||||
"npm": {
|
||||
"package": "@opentiny/vue",
|
||||
"exportName": "Select",
|
||||
"exportName": "Breadcrumb",
|
||||
"version": "",
|
||||
"destructuring": true
|
||||
},
|
||||
|
@ -14007,20 +14013,10 @@
|
|||
"schema": {
|
||||
"componentName": "TinyBreadcrumb",
|
||||
"props": {
|
||||
"options": [
|
||||
{
|
||||
"to": "{ path: '/' }",
|
||||
"label": "首页"
|
||||
},
|
||||
{
|
||||
"to": "{ path: '/breadcrumb' }",
|
||||
"label": "产品"
|
||||
},
|
||||
{
|
||||
"replace": "true",
|
||||
"label": "软件"
|
||||
}
|
||||
]
|
||||
"options": {
|
||||
"type": "JSExpression",
|
||||
"value": "[{to: { path: '/' },label: '首页'},{to: { path: '/breadcrumb' },label: '产品'},{'replace': true,'label': '软件'}]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -14275,7 +14271,7 @@
|
|||
"schema": {
|
||||
"componentName": "TinyTimeLine",
|
||||
"props": {
|
||||
"active": "2",
|
||||
"active": 2,
|
||||
"data": [
|
||||
{
|
||||
"name": "已下单"
|
||||
|
|
|
@ -86,11 +86,17 @@ export default {
|
|||
.map((name) => fetchBlockSchema(name))
|
||||
|
||||
const schemaList = await Promise.allSettled(promiseList)
|
||||
const extraList = []
|
||||
|
||||
schemaList.forEach((item) => {
|
||||
if (item.status === 'fulfilled' && item.value?.[0]?.content) {
|
||||
res.push(item.value[0].content)
|
||||
res.push(...getBlocksSchema(item.value[0].content, blockSet))
|
||||
extraList.push(getBlocksSchema(item.value[0].content, blockSet))
|
||||
}
|
||||
})
|
||||
;(await Promise.allSettled(extraList)).forEach((item) => {
|
||||
if (item.status === 'fulfilled' && item.value) {
|
||||
res.push(...item.value)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -136,11 +142,10 @@ export default {
|
|||
},
|
||||
...(blocks || []).map((blockSchema) => {
|
||||
return {
|
||||
panelName: blockSchema.fileName,
|
||||
panelName: `${blockSchema.fileName}.vue`,
|
||||
panelValue:
|
||||
genSFCWithDefaultPlugin(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
|
||||
panelType: 'vue',
|
||||
index: true
|
||||
panelType: 'vue'
|
||||
}
|
||||
})
|
||||
]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-http",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-i18n-host",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-block",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<script lang="jsx">
|
||||
import { reactive, ref, watch, watchEffect, computed } from 'vue'
|
||||
import { Button as TinyButton, Collapse as TinyCollapse, CollapseItem as TinyCollapseItem } from '@opentiny/vue'
|
||||
import { getGlobalConfig, useModal } from '@opentiny/tiny-engine-controller'
|
||||
import { getGlobalConfig, useModal, useBlock } from '@opentiny/tiny-engine-controller'
|
||||
import { BlockHistoryList, PluginSetting, CloseIcon, SvgButton } from '@opentiny/tiny-engine-common'
|
||||
import { previewBlock } from '@opentiny/tiny-engine-controller/js/preview'
|
||||
import { LifeCycles } from '@opentiny/tiny-engine-common'
|
||||
|
@ -212,8 +212,11 @@ export default {
|
|||
status,
|
||||
message,
|
||||
exec: async () => {
|
||||
// 获取区块截图
|
||||
block.screenshot = await getBlockBase64()
|
||||
const currentId = useBlock().getCurrentBlock()?.id
|
||||
if (block.id === currentId) {
|
||||
// 获取区块截图
|
||||
block.screenshot = await getBlockBase64()
|
||||
}
|
||||
saveBlock(block)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -276,10 +276,11 @@ export default {
|
|||
boxVisibility.value = false
|
||||
}
|
||||
const editBlock = async (block) => {
|
||||
const isEdite = true
|
||||
const isEdit = true
|
||||
|
||||
if (isSaved()) {
|
||||
await refreshBlockData(block)
|
||||
useBlock().initBlock(block, {}, isEdite)
|
||||
useBlock().initBlock(block, {}, isEdit)
|
||||
useLayout().closePlugin()
|
||||
closePanel()
|
||||
const url = new URL(window.location)
|
||||
|
@ -291,7 +292,7 @@ export default {
|
|||
message: '当前画布内容尚未保存,是否要继续切换?',
|
||||
exec: async () => {
|
||||
await refreshBlockData(block)
|
||||
useBlock().initBlock(block, {}, isEdite)
|
||||
useBlock().initBlock(block, {}, isEdit)
|
||||
useLayout().closePlugin()
|
||||
closePanel()
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ export const refreshBlockData = async (block = {}) => {
|
|||
const newBlock = await fetchBlockContent(block.id)
|
||||
|
||||
if (newBlock) {
|
||||
if (newBlock.public_scope_tenants.length) {
|
||||
if (newBlock?.public_scope_tenants?.length) {
|
||||
newBlock.public_scope_tenants = newBlock.public_scope_tenants.map((e) => e.id)
|
||||
}
|
||||
Object.assign(block, newBlock)
|
||||
|
@ -659,7 +659,14 @@ const updateBlock = (block = {}) => {
|
|||
)
|
||||
.then((data) => {
|
||||
setSaved(true)
|
||||
useBlock().initBlock(data, {}, true)
|
||||
|
||||
const currentId = useBlock().getCurrentBlock()?.id
|
||||
|
||||
// 如果是当前正在编辑的区块,需要同步更新画布
|
||||
if (currentId === id) {
|
||||
useBlock().initBlock(data, {}, true)
|
||||
}
|
||||
|
||||
// 弹出保存区块成功
|
||||
message({ message: '保存区块成功!', status: 'success' })
|
||||
// 本地生成区块服务
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-bridge",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-data",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-datasource",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -489,6 +489,7 @@ export default {
|
|||
grid.value.removeSelecteds()
|
||||
state.totalData = state.totalData.filter(({ _id }) => !selectedData.includes(_id))
|
||||
fetchData()
|
||||
state.isBatchDeleteDisable = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-help",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-i18n",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-materials",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-page",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -195,8 +195,9 @@ export default {
|
|||
|
||||
const updatePage = (id, params) => {
|
||||
const routerChange = pageSettingState.currentPageDataCopy.route !== pageSettingState.currentPageData.route
|
||||
const isCurEditPage = pageState?.currentPage?.id === id
|
||||
|
||||
return handlePageUpdate(id, params, routerChange)
|
||||
return handlePageUpdate(id, params, routerChange, isCurEditPage)
|
||||
}
|
||||
|
||||
const restorePage = (pageData) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-robot",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-schema",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-script",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-tree",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-plugin-tutorial",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-setting-design",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-setting-events",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
</template>
|
||||
<ul class="bind-event-list">
|
||||
<li
|
||||
v-for="(event, name) in state.componentEvents"
|
||||
v-for="(event, name) in renderEventList"
|
||||
:key="name"
|
||||
:class="['bind-event-list-item', { 'bind-event-list-item-notallow': state.bindActions[name] }]"
|
||||
@click="openActionDialog({ eventName: name }, true)"
|
||||
>
|
||||
<div>{{ name }} {{ event?.label?.zh_CN || name }}</div>
|
||||
<div>{{ name }} {{ event?.label?.[locale] || name }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</tiny-popover>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<div class="action-item bind-action-item">
|
||||
<div class="binding-name" @click="openActionDialog(action)">
|
||||
<div>
|
||||
{{ action.eventName }}<span>{{ state.componentEvents[action.eventName].label.zh_CN }}</span>
|
||||
{{ action.eventName }}<span>{{ renderEventList[action.eventName]?.label?.[locale] }}</span>
|
||||
</div>
|
||||
<div :class="{ linked: action.linked }">{{ action.linkedEventName }}</div>
|
||||
<span class="event-bind">{{ action.ref }}</span>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<bind-events-dialog :eventBinding="state.eventBinding"></bind-events-dialog>
|
||||
<add-events-dialog
|
||||
:visible="state.showBindEventDialog"
|
||||
:componentEvents="state.componentEvents"
|
||||
:componentEvents="renderEventList"
|
||||
@closeDialog="handleToggleAddEventDialog(false)"
|
||||
@addEvent="handleAddEvent"
|
||||
></add-events-dialog>
|
||||
|
@ -88,6 +88,7 @@
|
|||
import { computed, reactive, watchEffect } from 'vue'
|
||||
import { Popover, Button } from '@opentiny/vue'
|
||||
import { useCanvas, useModal, useLayout, useBlock, useResource } from '@opentiny/tiny-engine-controller'
|
||||
import i18n from '@opentiny/tiny-engine-controller/js/i18n'
|
||||
import { BlockLinkEvent, SvgButton } from '@opentiny/tiny-engine-common'
|
||||
import { iconHelpQuery, iconChevronDown } from '@opentiny/vue-icon'
|
||||
import BindEventsDialog, { open as openDialog } from './BindEventsDialog.vue'
|
||||
|
@ -112,6 +113,7 @@ export default {
|
|||
const { getBlockEvents, getCurrentBlock, removeEventLink } = useBlock()
|
||||
const { getMaterial } = useResource()
|
||||
const { confirm } = useModal()
|
||||
const locale = i18n.global.locale.value
|
||||
|
||||
const { highlightMethod } = getPluginApi(PLUGIN_NAME.PageController)
|
||||
|
||||
|
@ -119,25 +121,25 @@ export default {
|
|||
eventName: '', // 事件名称
|
||||
eventBinding: null, // 事件绑定的处理方法对象
|
||||
componentEvent: {},
|
||||
componentEvents: commonEvents,
|
||||
customEvents: commonEvents,
|
||||
bindActions: {},
|
||||
showBindEventDialog: false
|
||||
})
|
||||
|
||||
const isBlock = computed(() => Boolean(pageState.isBlock))
|
||||
const isEmpty = computed(() => Object.keys(state.bindActions).length === 0)
|
||||
const renderEventList = computed(() => ({ ...state.componentEvent, ...state.customEvents }))
|
||||
|
||||
watchEffect(() => {
|
||||
const componentName = pageState?.currentSchema?.componentName
|
||||
const componentSchema = getMaterial(componentName)
|
||||
state.componentEvent = componentSchema?.content?.schema?.events || componentSchema?.schema?.events || {}
|
||||
Object.assign(state.componentEvents, state.componentEvent)
|
||||
const props = pageState?.currentSchema?.props || {}
|
||||
const keys = Object.keys(props)
|
||||
state.bindActions = {}
|
||||
|
||||
// 遍历组件事件元数据
|
||||
Object.entries(state.componentEvents).forEach(([eventName, componentEvent]) => {
|
||||
Object.entries(renderEventList.value).forEach(([eventName, componentEvent]) => {
|
||||
// 查找组件已添加的事件
|
||||
if (keys.indexOf(eventName) > -1) {
|
||||
const event = props[eventName]
|
||||
|
@ -225,7 +227,7 @@ export default {
|
|||
const handleAddEvent = (params) => {
|
||||
const { eventName, eventDescription } = params
|
||||
|
||||
Object.assign(state.componentEvents, {
|
||||
Object.assign(state.customEvents, {
|
||||
[eventName]: {
|
||||
label: {
|
||||
zh_CN: eventDescription
|
||||
|
@ -253,7 +255,9 @@ export default {
|
|||
openCodePanel,
|
||||
openActionDialog,
|
||||
handleAddEvent,
|
||||
handleToggleAddEventDialog
|
||||
handleToggleAddEventDialog,
|
||||
renderEventList,
|
||||
locale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<tiny-dialog-box
|
||||
v-show="dialogVisible"
|
||||
:visible="dialogVisible"
|
||||
title="事件绑定"
|
||||
width="50%"
|
||||
:append-to-body="true"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-setting-props",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-setting-styles",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -69,7 +69,6 @@ import { ref, watch } from 'vue'
|
|||
import { Collapse, CollapseItem, Input } from '@opentiny/vue'
|
||||
import { useHistory, useCanvas, useProperties } from '@opentiny/tiny-engine-controller'
|
||||
import { MetaCodeEditor, MetaBindVariable } from '@opentiny/tiny-engine-common'
|
||||
import { formatString } from '@opentiny/tiny-engine-controller/js/ast'
|
||||
import {
|
||||
SizeGroup,
|
||||
LayoutGroup,
|
||||
|
@ -128,7 +127,7 @@ export default {
|
|||
const { getSchema: getCanvasPageSchema, updateRect } = useCanvas().canvasApi.value
|
||||
const pageSchema = getCanvasPageSchema()
|
||||
const schema = getSchema() || pageSchema
|
||||
const styleString = formatString(styleStrRemoveRoot(content), 'css')
|
||||
const styleString = styleStrRemoveRoot(content)
|
||||
const currentSchema = getCurrentSchema() || pageSchema
|
||||
|
||||
state.styleContent = content
|
||||
|
|
|
@ -290,9 +290,7 @@ export default {
|
|||
const state = reactive({
|
||||
showModal: false,
|
||||
activedRadius: RADIUS_SETTING.Single,
|
||||
activedBorder: BORDER_SETTING.All,
|
||||
// 标记是否从 props 来的更新
|
||||
isUpdateFromProps: false
|
||||
activedBorder: BORDER_SETTING.All
|
||||
})
|
||||
|
||||
const { setPosition } = useModal()
|
||||
|
@ -336,12 +334,13 @@ export default {
|
|||
watch(
|
||||
() => props.style,
|
||||
() => {
|
||||
state.isUpdateFromProps = true
|
||||
borderRadius.BorderRadius = parseInt(props.style.borderRadius || 0)
|
||||
borderRadius.BorderTopLeftRadius = parseInt(props.style.borderTopLeftRadius || 0)
|
||||
borderRadius.BorderTopRightRadius = parseInt(props.style.borderTopRightRadius || 0)
|
||||
borderRadius.BorderBottomLeftRadius = parseInt(props.style.borderBottomLeftRadius || 0)
|
||||
borderRadius.BorderBottomRightRadius = parseInt(props.style.borderBottomRightRadius || 0)
|
||||
borderRadius.BorderRadius = parseInt(props.style[BORDER_RADIUS_PROPERTY.BorderRadius] || 0)
|
||||
borderRadius.BorderTopLeftRadius = parseInt(props.style[BORDER_RADIUS_PROPERTY.BorderTopLeftRadius] || 0)
|
||||
borderRadius.BorderTopRightRadius = parseInt(props.style[BORDER_RADIUS_PROPERTY.BorderTopRightRadius] || 0)
|
||||
borderRadius.BorderBottomLeftRadius = parseInt(props.style[BORDER_RADIUS_PROPERTY.BorderBottomLeftRadius] || 0)
|
||||
borderRadius.BorderBottomRightRadius = parseInt(
|
||||
props.style[BORDER_RADIUS_PROPERTY.BorderBottomRightRadius] || 0
|
||||
)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
@ -386,12 +385,13 @@ export default {
|
|||
* 1. 用户在 monacoEditor 更新了样式 border-radius: 9px 然后保存,该组件接收并同步改值
|
||||
* 2. 用户在 monacoEditor 删除了 border-radius: 9px 的样式,然后 watch 函数(props.style),重新计算得到值 0
|
||||
* 3. 0 更新后,会再触发改函数更新,导致自动加上了 border-radius: 0px 的样式
|
||||
* 所以从 props 来的更新不需要再调用一遍 updateStyle(更新 props 数据)
|
||||
* 所以从如果当前值为 0 且 props.style[BORDER_RADIUS_PROPERTY.BorderRadius] 不存在值,不需要触发更新
|
||||
*/
|
||||
if (state.isUpdateFromProps) {
|
||||
state.isUpdateFromProps = false
|
||||
|
||||
if (!value && !props.style[BORDER_RADIUS_PROPERTY.BorderRadius]) {
|
||||
return
|
||||
}
|
||||
|
||||
borderRadius.BorderRadius = value
|
||||
|
||||
updateStyle({
|
||||
|
|
|
@ -429,7 +429,7 @@ export default {
|
|||
|
||||
properties[name] = {
|
||||
value,
|
||||
text: value === 'auto' ? 'auto' : String(Number.parseInt(value || 0)), // 界面 box 中显示的数值
|
||||
text: value === 'auto' ? 'auto' : String(Number.parseInt(value) || 0), // 界面 box 中显示的数值
|
||||
setting: Boolean(value) // 属性是否已设置值
|
||||
}
|
||||
})
|
||||
|
|
|
@ -61,6 +61,10 @@ export default {
|
|||
props.property.value?.indexOf('px') > -1 ? Number.parseInt(props.property.value) : props.property.value
|
||||
)
|
||||
|
||||
const updateStyle = (value) => {
|
||||
emit('update', { [props.property.name]: value })
|
||||
}
|
||||
|
||||
const sliderChange = () => {
|
||||
if (sliderFlag) {
|
||||
updateStyle(`${sliderValue.value}px`)
|
||||
|
@ -83,11 +87,7 @@ export default {
|
|||
|
||||
const reset = () => {
|
||||
sliderFlag = false
|
||||
updateStyle('')
|
||||
}
|
||||
|
||||
const updateStyle = (value) => {
|
||||
emit('update', { [props.property.name]: value })
|
||||
updateStyle(null)
|
||||
}
|
||||
|
||||
const inputChange = (property) => {
|
||||
|
|
|
@ -231,7 +231,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
|||
if (key.includes('comment')) {
|
||||
str += `${value.value}\n`
|
||||
} else {
|
||||
str += `${key}: ${value.value};\n`
|
||||
str += `${key}: ${value.value === '' ? "''" : value.value};\n`
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -249,7 +249,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
|||
// 在 styleObject 的,可能有改动,所以需要用 styleObject 拼接
|
||||
for (const [key, value] of Object.entries(styleObject[item.selectors].rules)) {
|
||||
if (![null, undefined].includes(value)) {
|
||||
str += `${key}: ${value};\n`
|
||||
str += `${key}: ${value === '' ? "''" : value};\n`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ export const stringify = (originParseList, styleObject, config = {}) => {
|
|||
str += `${selector} {\n`
|
||||
|
||||
for (const [declKey, declValue] of Object.entries(value.rules)) {
|
||||
str += `${declKey}: ${declValue};\n`
|
||||
str += `${declKey}: ${declValue === '' ? "''" : declValue};\n`
|
||||
}
|
||||
|
||||
str += '}\n'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-svgs",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -23,7 +23,6 @@
|
|||
"author": "OpenTiny Team",
|
||||
"license": "MIT",
|
||||
"homepage": "https://opentiny.design/tiny-engine",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-theme-dark",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-theme-light",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-breadcrumb",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-clean",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-collaboration",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-fullscreen",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-generate-vue",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -28,6 +28,9 @@ export default defineConfig({
|
|||
formats: ['es']
|
||||
},
|
||||
rollupOptions: {
|
||||
output: {
|
||||
banner: 'import "./style.css"'
|
||||
},
|
||||
external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/, /^prettier.*/]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-lang",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-layout",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -23,7 +23,6 @@
|
|||
"author": "OpenTiny Team",
|
||||
"license": "MIT",
|
||||
"homepage": "https://opentiny.design/tiny-engine",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-checkinout",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-logo",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-logout",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -23,7 +23,6 @@
|
|||
"author": "OpenTiny Team",
|
||||
"license": "MIT",
|
||||
"homepage": "https://opentiny.design/tiny-engine",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-media",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-preview",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-redoundo",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-refresh",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-save",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -51,7 +51,7 @@ const savePage = async (pageSchema) => {
|
|||
}
|
||||
|
||||
isLoading.value = true
|
||||
await handlePageUpdate(currentPage.id, { ...currentPage, ...params })
|
||||
await handlePageUpdate(currentPage.id, { ...currentPage, ...params }, false, true)
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-setting",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-utils",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -30,7 +30,9 @@
|
|||
"vite": "^4.3.7",
|
||||
"vitest": "^1.4.0"
|
||||
},
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentiny/vue-renderless": "^3.14.0",
|
||||
"vue": "^3.4.15"
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// browser File System Access API encapsulation
|
||||
import JSZIP from 'jszip'
|
||||
|
||||
/**
|
||||
* 下载文件到本地
|
||||
* @param {Blob} blobData 文件二进制数据
|
||||
* @param {string} fileName 文件名
|
||||
*/
|
||||
export function saveAs(blobData, fileName) {
|
||||
const downloadLink = document.createElement('a')
|
||||
downloadLink.download = fileName
|
||||
downloadLink.style.display = 'none'
|
||||
downloadLink.href = URL.createObjectURL(blobData)
|
||||
document.body.appendChild(downloadLink)
|
||||
downloadLink.click()
|
||||
document.body.removeChild(downloadLink)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个zip
|
||||
*/
|
||||
export const createZip = () => {
|
||||
return new JSZIP()
|
||||
}
|
||||
|
||||
/**
|
||||
* 往zip里面写入文件夹和文件
|
||||
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||
* FileInfo.filePath 文件相对路径,以'/'相连
|
||||
* FileInfo.fileContent 文件内容
|
||||
* @param {ZipExtraInfo} ZipExtraInfo zip额外信息
|
||||
* {string} zipName 打出来的zip名称
|
||||
* {JSZIP} zipHandle 创建好的zip句柄,可以不传,不传就用新的
|
||||
*/
|
||||
export const writeZip = (filesInfo, { zipHandle, zipName } = {}) => {
|
||||
let zip = zipHandle
|
||||
if (!zipHandle) {
|
||||
zip = createZip()
|
||||
}
|
||||
filesInfo.forEach(({ filePath, fileContent }) => {
|
||||
const file = filePath.split('/')
|
||||
const fileName = file.pop()
|
||||
const path = file.join('/')
|
||||
if (path) {
|
||||
zip.folder(path).file(fileName, fileContent)
|
||||
} else {
|
||||
zip.file(fileName, fileContent)
|
||||
}
|
||||
})
|
||||
// 把打包的内容异步转成blob二进制格式
|
||||
return zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||
// content就是blob数据
|
||||
saveAs(content, `${zipName}.zip`)
|
||||
})
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// browser File System Access API encapsulation
|
||||
|
||||
import { createZip, writeZip } from './fszip'
|
||||
|
||||
// 支持file system api的条件:存在这个方法 && 不处于iframe中
|
||||
export const isSupportFileSystemAccess =
|
||||
Object.prototype.hasOwnProperty.call(window, 'showDirectoryPicker') && window.self === window.top
|
||||
|
||||
/**
|
||||
* 获取用户选择并授权的文件夹根路径
|
||||
* @param {*} options
|
||||
|
@ -19,8 +25,8 @@
|
|||
* @returns dirHandle 目录句柄
|
||||
*/
|
||||
export const getUserBaseDirHandle = async (options = {}) => {
|
||||
if (!window.showOpenFilePicker) {
|
||||
throw new Error('不支持的浏览器!')
|
||||
if (!isSupportFileSystemAccess) {
|
||||
return createZip()
|
||||
}
|
||||
const dirHandle = await window.showDirectoryPicker({ mode: 'readwrite', ...options })
|
||||
return dirHandle
|
||||
|
@ -75,8 +81,8 @@ export async function getFileHandle(baseDirHandle, filePath, { create = false }
|
|||
* @returns fileHandle 文件句柄
|
||||
*/
|
||||
export const getUserFileHandle = async (options = {}) => {
|
||||
if (!window.showOpenFilePicker) {
|
||||
throw new Error('不支持的浏览器!')
|
||||
if (!isSupportFileSystemAccess) {
|
||||
throw new Error('不支持的浏览器或处于iframe中')
|
||||
}
|
||||
const [fileHandle] = await window.showOpenFilePicker({ mode: 'readwrite', ...options })
|
||||
return fileHandle
|
||||
|
@ -166,16 +172,29 @@ export const writeFile = async (handle, { filePath, fileContent }) => {
|
|||
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||
* FileInfo.filePath 文件相对路径
|
||||
* FileInfo.fileContent 文件内容
|
||||
* @param {Boolean} supportZipCache 是否支持zip缓存,zip缓存可能会导致文件不能及时更新,默认不缓存
|
||||
*
|
||||
*/
|
||||
export const writeFiles = async (baseDirHandle, filesInfo) => {
|
||||
export const writeFiles = async (
|
||||
baseDirHandle,
|
||||
filesInfo,
|
||||
zipName = 'tiny-engine-generate-code',
|
||||
supportZipCache = false
|
||||
) => {
|
||||
if (!filesInfo?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isSupportFileSystemAccess) {
|
||||
const zipInfo = { zipName, zipHandle: supportZipCache && baseDirHandle }
|
||||
await writeZip(filesInfo, zipInfo)
|
||||
return
|
||||
}
|
||||
|
||||
let directoryHandle = baseDirHandle
|
||||
if (!directoryHandle) {
|
||||
directoryHandle = await window.showDirectoryPicker({ mode: 'readwrite' })
|
||||
}
|
||||
|
||||
await Promise.all(filesInfo.map((fileInfo) => writeFile(baseDirHandle, fileInfo)))
|
||||
await Promise.all(filesInfo.map((fileInfo) => writeFile(directoryHandle, fileInfo)))
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const { rules } = require('../../.eslintrc')
|
||||
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
|
@ -17,5 +19,6 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
// 忽略 expected 中的内容
|
||||
ignorePatterns: ['**/**/expected/*', '**/**.ts']
|
||||
ignorePatterns: ['**/**/expected/*', '**/**.ts'],
|
||||
rules
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-dsl-vue",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -47,7 +47,7 @@
|
|||
"fs-extra": "^10.0.1",
|
||||
"prettier": "^2.6.1",
|
||||
"vite": "^4.3.7",
|
||||
"vite-plugin-static-copy": "^1.0.4",
|
||||
"vite-plugin-static-copy": "^0.16.0",
|
||||
"vitest": "^1.4.0",
|
||||
"winston": "^3.10.0"
|
||||
},
|
||||
|
|
|
@ -15,8 +15,8 @@ import CodeGenerator from './codeGenerator'
|
|||
|
||||
/**
|
||||
* 整体应用出码
|
||||
* @param {tinyEngineDslVue.IConfig} config
|
||||
* @returns {tinyEngineDslVue.codeGenInstance}
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IConfig} config
|
||||
* @returns {import('@opentiny/tiny-engine-dsl-vue').codeGenInstance}
|
||||
*/
|
||||
|
||||
export function generateApp(config = {}) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { BUILTIN_COMPONENTS_MAP } from '@/constant'
|
||||
import { getImportMap } from './parseImport'
|
||||
import {
|
||||
genTemplateByHook,
|
||||
|
@ -18,7 +19,8 @@ import {
|
|||
handleI18nAttrHook,
|
||||
handleObjBindAttrHook,
|
||||
handleEventAttrHook,
|
||||
handleTinyIconPropsHook
|
||||
handleTinyIconPropsHook,
|
||||
handleJsxModelValueUpdate
|
||||
} from './generateAttribute'
|
||||
import {
|
||||
GEN_SCRIPT_HOOKS,
|
||||
|
@ -212,6 +214,7 @@ export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
|
|||
|
||||
const defaultAttributeHook = [
|
||||
handleTinyGrid,
|
||||
handleJsxModelValueUpdate,
|
||||
handleConditionAttrHook,
|
||||
handleLoopAttrHook,
|
||||
handleSlotBindAttrHook,
|
||||
|
@ -259,7 +262,10 @@ export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
|
|||
}
|
||||
}
|
||||
|
||||
return generateSFCFile(schema, componentsMap, newConfig)
|
||||
// 兼容单独调用的场景,单独调用时,这里会默认加上 builtInComponents
|
||||
const compsMapWithBuiltIn = [...componentsMap, ...BUILTIN_COMPONENTS_MAP]
|
||||
|
||||
return generateSFCFile(schema, compsMapWithBuiltIn, newConfig)
|
||||
}
|
||||
|
||||
export default generateSFCFile
|
||||
|
|
|
@ -229,7 +229,7 @@ export const handleSlotBindAttrHook = (schemaData) => {
|
|||
let paramsValue = ''
|
||||
|
||||
if (Array.isArray(params)) {
|
||||
paramsValue = `={ ${params.join(',')} }`
|
||||
paramsValue = `="{ ${params.join(',')} }"`
|
||||
} else if (typeof params === 'string') {
|
||||
paramsValue = `="${params}"`
|
||||
}
|
||||
|
@ -515,3 +515,28 @@ export const handleBindUtilsHooks = (schemaData, globalHooks, config) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 modelvalue 绑定自动生成 onUpdate:modelValue 事件绑定
|
||||
* @param {*} schemaData
|
||||
* @param {*} globalHooks
|
||||
* @param {*} config
|
||||
*/
|
||||
export const handleJsxModelValueUpdate = (schemaData, globalHooks, config) => {
|
||||
const { schema: { props = {} } = {} } = schemaData || {}
|
||||
const isJSX = config.isJSX
|
||||
|
||||
if (!isJSX) {
|
||||
return
|
||||
}
|
||||
|
||||
const propsEntries = Object.entries(props)
|
||||
const modelValue = propsEntries.find(([_key, value]) => value?.type === JS_EXPRESSION && value?.model === true)
|
||||
const hasUpdateModelValue = propsEntries.find(([key]) => isOn(key) && key.startsWith(`onUpdate:${modelValue?.[0]}`))
|
||||
|
||||
// jsx 形式的 modelvalue, 如果 schema 没有声明,出码需要同时声明 onUpdate:modelValue,否则更新失效
|
||||
if (modelValue && !hasUpdateModelValue) {
|
||||
// 添加 onUpdate:modelKey 事件,让后续钩子生成 对应的事件声明
|
||||
props[`onUpdate:${modelValue?.[0]}`] = { type: JS_EXPRESSION, value: `(value) => ${modelValue[1].value}=value` }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
declare namespace tinyEngineDslVue {
|
||||
type defaultPlugins =
|
||||
declare module '@opentiny/tiny-engine-dsl-vue' {
|
||||
export function generateCode(param: { pageInfo: any; componentsMap?: Array<any>; blocksData?: Array<any> }): {
|
||||
[key: string]: any
|
||||
}
|
||||
export type defaultPlugins =
|
||||
| 'template'
|
||||
| 'block'
|
||||
| 'page'
|
||||
|
@ -12,9 +15,9 @@ declare namespace tinyEngineDslVue {
|
|||
| 'formatCode'
|
||||
| 'parseSchema'
|
||||
|
||||
type IPluginFun = (schema: IAppSchema, context: IContext) => void
|
||||
export type IPluginFun = (schema: IAppSchema, context: IContext) => void
|
||||
|
||||
interface IConfig {
|
||||
export interface IConfig {
|
||||
customPlugins?: {
|
||||
[key in defaultPlugins]?: IPluginFun
|
||||
} & {
|
||||
|
@ -26,7 +29,7 @@ declare namespace tinyEngineDslVue {
|
|||
customContext?: Record<string, any>
|
||||
}
|
||||
|
||||
interface IContext {
|
||||
export interface IContext {
|
||||
config: Record<string, any>
|
||||
genResult: Array<IFile>
|
||||
genLogs: Array<any>
|
||||
|
@ -35,24 +38,24 @@ declare namespace tinyEngineDslVue {
|
|||
|
||||
export function generateApp(config?: IConfig): codeGenInstance
|
||||
|
||||
interface codeGenInstance {
|
||||
generate(IAppSchema): ICodeGenResult
|
||||
export interface codeGenInstance {
|
||||
generate(schema: IAppSchema): ICodeGenResult
|
||||
}
|
||||
|
||||
interface ICodeGenResult {
|
||||
export interface ICodeGenResult {
|
||||
errors: Array<any>
|
||||
genResult: Array<IFile>
|
||||
genLogs: Array<any>
|
||||
}
|
||||
|
||||
interface IFile {
|
||||
export interface IFile {
|
||||
fileType: string
|
||||
fileName: string
|
||||
path: string
|
||||
fileContent: string
|
||||
}
|
||||
|
||||
interface IAppSchema {
|
||||
export interface IAppSchema {
|
||||
i18n: {
|
||||
en_US: Record<string, any>
|
||||
zh_CN: Record<string, any>
|
||||
|
@ -66,37 +69,37 @@ declare namespace tinyEngineDslVue {
|
|||
meta: IMetaInfo
|
||||
}
|
||||
|
||||
interface IUtilsItem {
|
||||
export interface IUtilsItem {
|
||||
name: string
|
||||
type: 'npm' | 'function'
|
||||
content: object
|
||||
}
|
||||
|
||||
interface IDataSource {
|
||||
export interface IDataSource {
|
||||
list: Array<{ id: number; name: string; data: object }>
|
||||
dataHandler?: IFuncType
|
||||
errorHandler?: IFuncType
|
||||
willFetch?: IFuncType
|
||||
}
|
||||
|
||||
interface IFuncType {
|
||||
export interface IFuncType {
|
||||
type: 'JSFunction'
|
||||
value: string
|
||||
}
|
||||
|
||||
interface IExpressionType {
|
||||
export interface IExpressionType {
|
||||
type: 'JSExpression'
|
||||
value: string
|
||||
}
|
||||
|
||||
interface IGlobalStateItem {
|
||||
export interface IGlobalStateItem {
|
||||
id: string
|
||||
state: Record<string, any>
|
||||
actions: Record<string, IFuncType>
|
||||
getters: Record<string, IFuncType>
|
||||
}
|
||||
|
||||
interface IPageSchema {
|
||||
export interface IPageSchema {
|
||||
componentName: 'Page' | 'Block'
|
||||
css: string
|
||||
fileName: string
|
||||
|
@ -120,7 +123,7 @@ declare namespace tinyEngineDslVue {
|
|||
}
|
||||
}
|
||||
|
||||
interface IFolderItem {
|
||||
export interface IFolderItem {
|
||||
componentName: 'Folder'
|
||||
depth: number
|
||||
folderName: string
|
||||
|
@ -129,14 +132,14 @@ declare namespace tinyEngineDslVue {
|
|||
router: string
|
||||
}
|
||||
|
||||
interface ISchemaChildrenItem {
|
||||
export interface ISchemaChildrenItem {
|
||||
children: Array<ISchemaChildrenItem>
|
||||
componentName: string
|
||||
id: string
|
||||
props: Record<string, any>
|
||||
}
|
||||
|
||||
interface IComponentMapItem {
|
||||
export interface IComponentMapItem {
|
||||
componentName: string
|
||||
destructuring: boolean
|
||||
exportName?: string
|
||||
|
@ -144,7 +147,7 @@ declare namespace tinyEngineDslVue {
|
|||
version: string
|
||||
}
|
||||
|
||||
interface IMetaInfo {
|
||||
export interface IMetaInfo {
|
||||
name: string
|
||||
description: string
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ function formatCode(options = {}) {
|
|||
description: 'transform block schema to code',
|
||||
/**
|
||||
* 格式化出码
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema, context) {
|
||||
|
|
|
@ -15,7 +15,7 @@ function genBlockPlugin(options = {}) {
|
|||
description: 'transform block schema to code',
|
||||
/**
|
||||
* 将区块 schema 转换成高代码
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -15,7 +15,7 @@ function genDataSourcePlugin(options = {}) {
|
|||
description: 'transform schema to dataSource plugin',
|
||||
/**
|
||||
* 转换 dataSource
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -63,7 +63,7 @@ function genDependenciesPlugin(options = {}) {
|
|||
description: 'transform dependencies to package.json',
|
||||
/**
|
||||
* 分析依赖,写入 package.json
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -25,7 +25,7 @@ function genDependenciesPlugin(options = {}) {
|
|||
description: 'transform schema to globalState',
|
||||
/**
|
||||
* 转换 globalState
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
@ -44,8 +44,8 @@ function genDependenciesPlugin(options = {}) {
|
|||
.map((item) => {
|
||||
let [key, value] = item
|
||||
|
||||
if (value === '') {
|
||||
value = "''"
|
||||
if (typeof value === 'string') {
|
||||
value = `'${value}'`
|
||||
}
|
||||
|
||||
if (value && typeof value === 'object') {
|
||||
|
@ -57,19 +57,19 @@ function genDependenciesPlugin(options = {}) {
|
|||
.join(',')} })`
|
||||
|
||||
const getterExpression = Object.entries(getters)
|
||||
.filter((item) => item.value?.type === 'JSFunction')
|
||||
.filter((item) => item[1]?.type === 'JSFunction')
|
||||
.map(([key, value]) => `${key}: ${value.value}`)
|
||||
.join(',')
|
||||
|
||||
const actionExpressions = Object.entries(actions)
|
||||
.filter((item) => item.value?.type === 'JSFunction')
|
||||
.filter((item) => item[1]?.type === 'JSFunction')
|
||||
.map(([key, value]) => `${key}: ${value.value}`)
|
||||
.join(',')
|
||||
|
||||
const storeFiles = `
|
||||
${importStatement}
|
||||
export const ${id} = defineStore({
|
||||
id: ${id},
|
||||
id: '${id}',
|
||||
state: ${stateExpression},
|
||||
getters: { ${getterExpression} },
|
||||
actions: { ${actionExpressions} }
|
||||
|
|
|
@ -17,7 +17,7 @@ function genI18nPlugin(options = {}) {
|
|||
description: 'transform i18n schema to i18n code plugin',
|
||||
/**
|
||||
* 将国际化 schema 转换成 i18n 高代码
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -15,7 +15,7 @@ function genPagePlugin(options = {}) {
|
|||
description: 'transform page schema to code',
|
||||
/**
|
||||
* 将页面 schema 转换成高代码
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -36,7 +36,7 @@ function genRouterPlugin(options = {}) {
|
|||
description: 'transform router schema to router code plugin',
|
||||
/**
|
||||
* 根据页面生成路由配置
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -42,7 +42,7 @@ function genUtilsPlugin(options = {}) {
|
|||
description: 'transform utils schema to utils code',
|
||||
/**
|
||||
* 生成 utils 源码
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
|
@ -7,7 +7,7 @@ function parseSchema() {
|
|||
|
||||
/**
|
||||
* 解析schema,预处理 schema
|
||||
* @param {tinyEngineDslVue.IAppSchema} schema
|
||||
* @param {import('@opentiny/tiny-engine-dsl-vue').IAppSchema} schema
|
||||
* @returns
|
||||
*/
|
||||
run(schema) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue