Skip to content

Commit f7dec37

Browse files
fix: canvas component border & switch style & add validator & tree plugin display sync & bind variable confirm disabled (#1649)
1 parent 847f30d commit f7dec37

File tree

8 files changed

+144
-39
lines changed

8 files changed

+144
-39
lines changed

packages/canvas/DesignCanvas/src/DesignCanvas.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export default {
8787
footData.value = useCanvas().getNodePath(node?.id)
8888
pageState.currentSchema = {}
8989
pageState.properties = null
90+
// 删除节点后,重置pageState中组件的属性
91+
// 后续需要改造
92+
useProperties().getProps(null, null)
9093
}
9194
9295
const isBlock = useCanvas().isBlock
@@ -106,9 +109,9 @@ export default {
106109
empty: () => '应用下暂无页面,需新建页面后体验画布功能',
107110
release: (type) => `当前${componentType[type]}未锁定,点击右上角 “锁定” 图标后编辑${componentType[type]}`,
108111
lock: (type) =>
109-
`当前${componentType[type]}${pageInfo?.username || ''} 锁定,如需编辑请先联系他解锁文件,然后再锁定该${
112+
`当前${componentType[type]}${pageInfo?.username || ''} 锁定,您可以创建新页面,如需编辑请先联系他解锁${
110113
componentType[type]
111-
}后编辑!`
114+
},然后再锁定该${componentType[type]}后编辑!`
112115
}
113116
114117
const renderMsg = message[pageStatus.state](pageSchema.componentName)

packages/canvas/container/src/components/CanvasAction.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ export default {
251251
}
252252
253253
const hide = () => {
254-
getRenderer().setCondition(getCurrent().schema?.id, false)
254+
if (getCurrent().schema?.id) {
255+
const { clearSelect } = useCanvas().canvasApi.value
256+
getRenderer().setCondition(getCurrent().schema.id, false)
257+
useCanvas().pageState.nodesStatus[getCurrent().schema.id] = false
258+
clearSelect()
259+
}
255260
updateRect()
256261
}
257262

packages/canvas/container/src/container.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,34 @@ const setSelectRect = (
466466
)
467467
}
468468

469+
const getElementDurationTime = (elementId?: string) => {
470+
const element = elementId ? querySelectById(elementId) : getDocument().body
471+
const transitionDuration = window.getComputedStyle(element).getPropertyValue('transition-duration')
472+
const transitionDelay = window.getComputedStyle(element).getPropertyValue('transition-delay')
473+
let delayTime = 0
474+
const getMaxMillisecondNumber = (arr: string[]) => {
475+
const millisecondNumber = arr.map((item) => {
476+
if (item.endsWith('ms')) {
477+
return parseFloat(item)
478+
} else {
479+
return parseFloat(item) * 1000
480+
}
481+
})
482+
return millisecondNumber.length ? Math.max(...millisecondNumber) : 0
483+
}
484+
if (transitionDuration) {
485+
const transitionDurations = transitionDuration.split(',')
486+
delayTime += getMaxMillisecondNumber(transitionDurations)
487+
}
488+
489+
if (transitionDelay) {
490+
const transitionDelays = transitionDelay.split(',')
491+
delayTime += getMaxMillisecondNumber(transitionDelays)
492+
}
493+
494+
return delayTime
495+
}
496+
469497
export const updateRect = (id?: string) => {
470498
id = (typeof id === 'string' && id) || getCurrent().schema?.id
471499
clearHover()
@@ -481,7 +509,9 @@ export const updateRect = (id?: string) => {
481509
const isBodySelected = !selectState.componentName && selectState.width > 0
482510

483511
if (id || isBodySelected) {
484-
setTimeout(() => setSelectRect(id))
512+
// 获取元素动画持续时间
513+
const waitTime = getElementDurationTime(id)
514+
setTimeout(() => setSelectRect(id), waitTime)
485515
} else {
486516
clearSelect()
487517
}
@@ -816,7 +846,6 @@ export const dragMove = (event: DragEvent, isHover: boolean) => {
816846
// type == clickTree, 为点击大纲; type == loop-id=xxx ,为点击循环数据
817847
export const selectNode = async (id: string, type?: string, isMultiple = false) => {
818848
const { node } = useCanvas().getNodeWithParentById(id) || {}
819-
820849
let element = querySelectById(id)
821850

822851
if (element && node) {
@@ -825,7 +854,6 @@ export const selectNode = async (id: string, type?: string, isMultiple = false)
825854
}
826855

827856
const nodeIsSelected = setSelectRect(id, element, { isMultiple, type, schema: node })
828-
829857
// 执行setSelectRect之后再去判断multiSelectedStates的长度
830858
if (multiSelectedStates.value.length === 1) {
831859
const { schema: node, parent, type } = multiSelectedStates.value[0]
@@ -851,6 +879,7 @@ export const selectNode = async (id: string, type?: string, isMultiple = false)
851879
if (multiSelectedStates.value.length === 1) {
852880
const { schema: node, parent, type, id } = multiSelectedStates.value[0]
853881
canvasState.emit('selected', node, parent, type, id)
882+
854883
return node
855884
} else {
856885
canvasState.emit('selected')

packages/configurator/src/html-attributes-configurator/HtmlAttributesConfigurator.vue

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="attr-header">
3-
<span class="header-title">自定义属性</span>
3+
<span class="header-title">原生属性</span>
44
<tiny-popover
55
v-model="state.visible"
66
placement="bottom"
@@ -11,11 +11,18 @@
1111
>
1212
<div class="attr-form">
1313
<icon-close class="icon-close" @click="closePopover"></icon-close>
14-
<tiny-form label-position="left" label-width="53px">
15-
<tiny-form-item label="name">
14+
<tiny-form
15+
ref="attrFormRef"
16+
:model="state.formData"
17+
:rules="rules"
18+
validate-type="text"
19+
label-position="left"
20+
label-width="53px"
21+
>
22+
<tiny-form-item label="name" prop="key">
1623
<tiny-input v-model="state.formData.key"></tiny-input>
1724
</tiny-form-item>
18-
<tiny-form-item label="value">
25+
<tiny-form-item label="value" prop="value">
1926
<tiny-input v-model="state.formData.value"></tiny-input>
2027
</tiny-form-item>
2128
<div class="footer">
@@ -81,9 +88,18 @@ export default {
8188
currentAttr: {}
8289
})
8390
91+
const attrFormRef = ref()
8492
const attrs = ref([])
8593
const properties = ['style']
8694
95+
const rules = {
96+
key: [
97+
{ required: true, message: '名称必填', trigger: 'blur' },
98+
{ max: 20, message: '长度不大于20', trigger: 'change' }
99+
],
100+
value: [{ max: 200, message: '长度不大于200', trigger: 'change' }]
101+
}
102+
87103
watchEffect(() => {
88104
if (!useProperties().getSchema()?.props) {
89105
return
@@ -144,24 +160,29 @@ export default {
144160
}
145161
146162
const save = () => {
147-
state.visible = false
148-
const data = {}
149-
let index = -1
163+
attrFormRef.value.validate((valid) => {
164+
if (!valid) {
165+
return
166+
}
167+
state.visible = false
168+
const data = {}
169+
let index = -1
150170
151-
if (state.currentAttr.id) {
152-
index = attrs.value.findIndex((item) => item.id === state.currentAttr.id)
153-
data.id = state.currentAttr.id
154-
state.currentAttr = {}
155-
} else {
156-
data.id = utils.guid()
157-
index = attrs.value.length
158-
}
171+
if (state.currentAttr.id) {
172+
index = attrs.value.findIndex((item) => item.id === state.currentAttr.id)
173+
data.id = state.currentAttr.id
174+
state.currentAttr = {}
175+
} else {
176+
data.id = utils.guid()
177+
index = attrs.value.length
178+
}
159179
160-
data.text = `${state.formData.key} = '${state.formData.value}'`
161-
data.data = { key: state.formData.key, value: state.formData.value }
180+
data.text = `${state.formData.key} = '${state.formData.value}'`
181+
data.data = { key: state.formData.key, value: state.formData.value }
162182
163-
attrs.value.splice(index, 1, data)
164-
updateSchema()
183+
attrs.value.splice(index, 1, data)
184+
updateSchema()
185+
})
165186
}
166187
167188
const edit = (attr) => {
@@ -187,7 +208,9 @@ export default {
187208
}
188209
189210
return {
211+
attrFormRef,
190212
state,
213+
rules,
191214
cancel,
192215
save,
193216
attrs,
@@ -248,6 +271,11 @@ export default {
248271
display: grid;
249272
grid-template-columns: 3fr auto;
250273
274+
.item-content {
275+
word-wrap: break-word;
276+
white-space: normal;
277+
word-break: break-all;
278+
}
251279
.item-controller {
252280
display: grid;
253281
column-gap: 3px;

packages/configurator/src/slot-configurator/SlotConfigurator.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export default {
186186
.e__switch-core::after {
187187
content: '';
188188
position: absolute;
189-
top: 1px;
189+
top: 2px;
190190
left: 1px;
191191
border-radius: 100%;
192192
transition: all 0.3s;

packages/configurator/src/variable-configurator/VariableConfigurator.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
:value="state.variable"
7171
:options="editorOptions"
7272
@editorDidMount="editorDidMount"
73+
@change="editorChange"
7374
></monaco-editor>
7475
<div v-if="isDataSource" class="datasource-poll-wrap">
7576
<tiny-tooltip
@@ -109,10 +110,12 @@
109110

110111
<template #footer>
111112
<div class="bind-dialog-footer">
112-
<tiny-button type="danger" plain @click="remove">移除绑定</tiny-button>
113+
<tiny-button type="danger" plain :disabled="modelValue?.type !== 'JSExpression'" @click="remove"
114+
>移除绑定</tiny-button
115+
>
113116
<div class="right">
114117
<tiny-button @click="cancel">取 消</tiny-button>
115-
<tiny-button type="info" @click="confirm">确 定</tiny-button>
118+
<tiny-button type="info" :disabled="confirmDisabled" @click="confirm">确 定</tiny-button>
116119
</div>
117120
</div>
118121
</template>
@@ -260,6 +263,8 @@ export default {
260263
261264
const isDataSource = computed(() => state.active === CONSTANTS.DATASOUCE)
262265
266+
const confirmDisabled = computed(() => !state.variable?.trim())
267+
263268
// 每次弹窗打开时都记录下绑定变量的旧值,用来判断保存按钮状态
264269
watch(
265270
() => state.isVisible,
@@ -309,6 +314,10 @@ export default {
309314
})
310315
}
311316
317+
const editorChange = (value) => {
318+
state.variable = value
319+
}
320+
312321
const removeInterval = (start, end, intervalId, pageSchema) => {
313322
const unmountedFn = pageSchema.lifeCycles?.onUnmounted?.value
314323
const fetchBody = `
@@ -543,7 +552,9 @@ export default {
543552
}
544553
545554
return {
555+
confirmDisabled,
546556
editorDidMount,
557+
editorChange,
547558
editorOptions,
548559
variableClick,
549560
remove,

packages/plugins/materials/src/composable/useResource.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ const initBlock = async (blockId: string) => {
119119
const initPageOrBlock = async () => {
120120
const { pageId, blockId } = getMetaApi(META_SERVICE.GlobalService).getBaseInfo()
121121
const pagePluginApi = getMetaApi(META_APP.AppManage)
122+
const globalState = getMetaApi(META_SERVICE.GlobalService).getState()
122123

123124
if (pageId) {
124125
const data = await pagePluginApi.getPageById(pageId)
@@ -132,15 +133,38 @@ const initPageOrBlock = async () => {
132133
return
133134
}
134135

135-
// url 没有 pageid 或 blockid,到页面首页或第一页
136-
const pageInfo = appSchemaState.pageTree.find((page) => page?.meta?.isHome) ||
137-
appSchemaState.pageTree.find(
136+
// url 没有 pageid 或 blockid,页面打开顺序:可访问主页 -> 可访问的第一个页面 -> 不可访问首页 -> 不可访问全页面顺位第一页
137+
const getPageInfo = () => {
138+
// 页面是否被他人锁定 (被锁定 且 非当前用户锁定)
139+
const isPageOccupierdByOthers = (page) => {
140+
return page.meta?.occupier && page.meta.occupier.id !== globalState.userInfo.id
141+
}
142+
// 首页
143+
const homePage = appSchemaState.pageTree.find((page) => page?.meta?.isHome)
144+
// 顺位首个页面
145+
const firstPage = appSchemaState.pageTree.find(
138146
(page) => page.componentName === COMPONENT_NAME.Page && page?.meta?.group !== 'publicPages'
139-
) || {
147+
)
148+
// 顺位首个可访问页面(当前用户锁定 或 未锁定)
149+
const firstUnoccupiedPage = appSchemaState.pageTree.find(
150+
(page) =>
151+
page.componentName === COMPONENT_NAME.Page &&
152+
page?.meta?.group !== 'publicPages' &&
153+
!isPageOccupierdByOthers(page)
154+
)
155+
// 空页面
156+
const emptyPage = {
140157
page_content: {
141158
componentName: COMPONENT_NAME.Page
142159
}
143160
}
161+
// 可访问主页 (当前用户锁定 或 未锁定)
162+
if (homePage && !isPageOccupierdByOthers(homePage)) {
163+
return homePage
164+
}
165+
return firstUnoccupiedPage || homePage || firstPage || emptyPage
166+
}
167+
const pageInfo = getPageInfo()
144168

145169
if (pageInfo.meta?.id) {
146170
// 这里重新请求一遍页面详情数据,是因为 appSchemaState 的页面信息存在字段转换,比如 route 被转换成了 router 字段,导致调用页面保存接口的时候报错

packages/plugins/tree/src/Main.vue

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
row.label
2828
}}</span>
2929
<template v-if="row.id !== 'body'">
30-
<svg-icon :name="eyeOpen(row.id) ? 'eye' : 'eye-invisible'" @mouseup="showNode(row.rawData)"></svg-icon>
30+
<svg-icon
31+
:name="eyeOpen(row.id) ? 'eye' : 'eye-invisible'"
32+
@click="showNode($event, row.rawData)"
33+
></svg-icon>
3134
<svg-icon name="delete" @mouseup="delNode(row.rawData)"></svg-icon>
3235
</template>
3336
</div>
@@ -96,7 +99,6 @@ export default {
9699
const translateChild = (data) => {
97100
data.forEach((item) => {
98101
item.show = pageState.nodesStatus[item.id] !== false
99-
item.showEye = !item.show
100102
const child = item.children
101103
if (Array.isArray(child)) {
102104
translateChild(item.children)
@@ -150,14 +152,17 @@ export default {
150152
return pageState.nodesStatus[id] !== false
151153
}
152154
153-
const showNode = (data) => {
154-
data.show = !data.show
155-
pageState.nodesStatus[data.id] = data.show
156-
155+
const showNode = (event, data) => {
156+
pageState.nodesStatus[data.id] = !(pageState.nodesStatus[data.id] !== false)
157+
data.show = pageState.nodesStatus[data.id]
157158
const { getRenderer, clearSelect } = useCanvas().canvasApi.value
158159
159160
getRenderer().setCondition(data.id, data.show)
160-
clearSelect()
161+
162+
if (!data.show) {
163+
event?.stopPropagation()
164+
clearSelect()
165+
}
161166
}
162167
163168
const delNode = (data) => {

0 commit comments

Comments
 (0)