Skip to content

Commit cce05dc

Browse files
fix: canvas component border & switch style & add validator & tree plugin display sync & bind variable confirm disabled (#1659)
1 parent 552e339 commit cce05dc

8 files changed

Lines changed: 140 additions & 36 deletions

File tree

packages/canvas/DesignCanvas/src/DesignCanvas.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export default {
8787
footData.value = useCanvas().getNodePath(node?.id)
8888
pageState.currentSchema = {}
8989
pageState.properties = null
90+
// 删除节点后,重置pagestate中组件的属性
91+
useProperties().getProps(null, null)
9092
}
9193
9294
const isBlock = useCanvas().isBlock
@@ -106,9 +108,9 @@ export default {
106108
empty: () => '应用下暂无页面,需新建页面后体验画布功能',
107109
release: (type) => `当前${componentType[type]}未锁定,点击右上角 “锁定” 图标后编辑${componentType[type]}`,
108110
lock: (type) =>
109-
`当前${componentType[type]}${pageInfo?.username || ''} 锁定,如需编辑请先联系他解锁文件,然后再锁定该${
111+
`当前${componentType[type]}${pageInfo?.username || ''} 锁定,您可以创建新页面,如需编辑请先联系他解锁${
110112
componentType[type]
111-
}后编辑!`
113+
},然后再锁定该${componentType[type]}后编辑!`
112114
}
113115
114116
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: 30 additions & 1 deletion
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+
const unit = item.slice(-2)
477+
if (unit === 'ms') {
478+
return parseFloat(item)
479+
} else {
480+
return parseFloat(item) * 1000
481+
}
482+
})
483+
return millisecondNumber.length ? Math.max(...millisecondNumber) : 0
484+
}
485+
if (transitionDuration) {
486+
const transitionDurations = transitionDuration.split(',')
487+
delayTime += getMaxMillisecondNumber(transitionDurations)
488+
}
489+
490+
if (transitionDelay) {
491+
const transitionDelays = transitionDelay.split(',')
492+
delayTime += getMaxMillisecondNumber(transitionDelays)
493+
}
494+
return delayTime === 0 ? 300 : delayTime
495+
}
496+
469497
export const updateRect = (id?: string) => {
470498
id = (typeof id === 'string' && id) || getCurrent().schema?.id
471499
clearHover()
@@ -481,7 +509,8 @@ export const updateRect = (id?: string) => {
481509
const isBodySelected = !selectState.componentName && selectState.width > 0
482510

483511
if (id || isBodySelected) {
484-
setTimeout(() => setSelectRect(id))
512+
const waitTime = getElementDurationTime(id)
513+
setTimeout(() => setSelectRect(id), waitTime)
485514
} else {
486515
clearSelect()
487516
}

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">
@@ -80,9 +87,18 @@ export default {
8087
currentAttr: {}
8188
})
8289
90+
const attrFormRef = ref()
8391
const attrs = ref([])
8492
const properties = ['style']
8593
94+
const rules = {
95+
key: [
96+
{ required: true, message: '名称必填', trigger: 'blur' },
97+
{ max: 20, message: '长度不大于20', trigger: 'change' }
98+
],
99+
value: [{ max: 200, message: '长度不大于200', trigger: 'change' }]
100+
}
101+
86102
watchEffect(() => {
87103
if (!useProperties().getSchema()?.props) {
88104
return
@@ -143,24 +159,29 @@ export default {
143159
}
144160
145161
const save = () => {
146-
state.visible = false
147-
const data = {}
148-
let index = -1
162+
attrFormRef.value.validate((valid) => {
163+
if (!valid) {
164+
return
165+
}
166+
state.visible = false
167+
const data = {}
168+
let index = -1
149169
150-
if (state.currentAttr.id) {
151-
index = attrs.value.findIndex((item) => item.id === state.currentAttr.id)
152-
data.id = state.currentAttr.id
153-
state.currentAttr = {}
154-
} else {
155-
data.id = utils.guid()
156-
index = attrs.value.length
157-
}
170+
if (state.currentAttr.id) {
171+
index = attrs.value.findIndex((item) => item.id === state.currentAttr.id)
172+
data.id = state.currentAttr.id
173+
state.currentAttr = {}
174+
} else {
175+
data.id = utils.guid()
176+
index = attrs.value.length
177+
}
158178
159-
data.text = `${state.formData.key} = '${state.formData.value}'`
160-
data.data = { key: state.formData.key, value: state.formData.value }
179+
data.text = `${state.formData.key} = '${state.formData.value}'`
180+
data.data = { key: state.formData.key, value: state.formData.value }
161181
162-
attrs.value.splice(index, 1, data)
163-
updateSchema()
182+
attrs.value.splice(index, 1, data)
183+
updateSchema()
184+
})
164185
}
165186
166187
const edit = (attr) => {
@@ -186,7 +207,9 @@ export default {
186207
}
187208
188209
return {
210+
attrFormRef,
189211
state,
212+
rules,
190213
cancel,
191214
save,
192215
attrs,
@@ -247,6 +270,11 @@ export default {
247270
display: grid;
248271
grid-template-columns: 3fr auto;
249272
273+
.item-content {
274+
word-wrap: break-word;
275+
white-space: normal;
276+
word-break: break-all;
277+
}
250278
.item-controller {
251279
display: grid;
252280
column-gap: 3px;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export default {
185185
.e__switch-core::after {
186186
content: '';
187187
position: absolute;
188-
top: 1px;
188+
top: 2px;
189189
left: 1px;
190190
border-radius: 100%;
191191
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>
@@ -259,6 +262,8 @@ export default {
259262
260263
const isDataSource = computed(() => state.active === CONSTANTS.DATASOUCE)
261264
265+
const confirmDisabled = computed(() => !state.variable?.trim?.())
266+
262267
// 每次弹窗打开时都记录下绑定变量的旧值,用来判断保存按钮状态
263268
watch(
264269
() => state.isVisible,
@@ -308,6 +313,10 @@ export default {
308313
})
309314
}
310315
316+
const editorChange = (value) => {
317+
state.variable = value
318+
}
319+
311320
const removeInterval = (start, end, intervalId, pageSchema) => {
312321
const unmountedFn = pageSchema.lifeCycles?.onUnmounted?.value
313322
const fetchBody = `
@@ -542,7 +551,9 @@ export default {
542551
}
543552
544553
return {
554+
confirmDisabled,
545555
editorDidMount,
556+
editorChange,
546557
editorOptions,
547558
variableClick,
548559
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: 11 additions & 6 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
155+
const showNode = (event, data) => {
156+
pageState.nodesStatus[data.id] = !(pageState.nodesStatus[data.id] !== false)
157+
data.show = pageState.nodesStatus[data.id]
156158
157159
const { getRenderer, clearSelect } = useCanvas().canvasApi.value
158160
159161
getRenderer().setCondition(data.id, data.show)
160-
clearSelect()
162+
if (!data.show) {
163+
event?.stopPropagation()
164+
clearSelect()
165+
}
161166
}
162167
163168
const delNode = (data) => {

0 commit comments

Comments
 (0)