Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/subform #25

Merged
merged 34 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
76bd1d6
feat: add subform
Liberty-liu Aug 15, 2023
862a6ca
Merge branch 'main' into feat/subform
Liberty-liu Aug 18, 2023
b4779e6
test(disassemblyData): fields and layout not separated
Liberty-liu Aug 20, 2023
49cfa51
test(disassemblyData): nested layout:Grid > Grid > field
Liberty-liu Aug 20, 2023
0679226
test(disassemblyData): adjust the test case
Liberty-liu Aug 25, 2023
1d5d9dd
refactor: remove @element-plus/icons-vue
Liberty-liu Aug 25, 2023
ca2f85d
test(disassemblyData): layoutType1|layoutType2
Liberty-liu Aug 29, 2023
064397e
test(disassemblyData): sub-form
Liberty-liu Aug 30, 2023
ff08057
refactor: el-breadcrumb icon
Liberty-liu Aug 30, 2023
db8a4bb
feat(subform): structure
Liberty-liu Sep 4, 2023
c1b340c
feat(subform): ui
Liberty-liu Sep 5, 2023
49f706f
feat(subform): add check
Liberty-liu Sep 6, 2023
bcbfeb8
feat(subform): subform required true, and all fields of the subform a…
Liberty-liu Sep 6, 2023
d0ee76c
feat(subform): subform disabled true
Liberty-liu Sep 7, 2023
edeff4c
test(erFormConfig): subform:pc|Subform:mobile
Liberty-liu Sep 7, 2023
bf26975
feat(subform): set default content and set value
Liberty-liu Sep 8, 2023
e81c8cd
test(subForm): no child
Liberty-liu Sep 9, 2023
84812b0
test(subForm): only one child
Liberty-liu Sep 9, 2023
cd81b76
test(subform): only one child: has 2 default contents
Liberty-liu Sep 9, 2023
7cbbf7f
test(subform): only one child: has 2 default contents && field has de…
Liberty-liu Sep 9, 2023
77b14c3
feat(subform): delete the element below index 0
Liberty-liu Sep 9, 2023
2bc8422
test(subform): added config tests
Liberty-liu Sep 9, 2023
c3f6fa1
test(subform): added default content test
Liberty-liu Sep 9, 2023
42031c5
test(subform): no child: Required
Liberty-liu Sep 10, 2023
ba7cd63
test(subform): only one child: field Required
Liberty-liu Sep 10, 2023
5dece8c
test(subform): only one child: field Disabled
Liberty-liu Sep 10, 2023
42256fc
test(subform): only one child: Disabled
Liberty-liu Sep 10, 2023
8a8afd1
test(subform): only one child: has 2 default contents & Disabled
Liberty-liu Sep 11, 2023
2ea2a74
feat(subform): support logic control
Liberty-liu Sep 11, 2023
0f661bc
test(subform): validator
Liberty-liu Sep 11, 2023
69e8ad0
test(subform): generateFilterdata
Liberty-liu Sep 11, 2023
7341a5c
feat(subform): subform data in layoutType2
Liberty-liu Sep 12, 2023
e525d2b
fix(subform): fixed some issues with logic and subform
Liberty-liu Sep 12, 2023
8a2962b
feat: checkFieldsForNewBadge
Liberty-liu Sep 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions examples/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import Vant, { Locale } from 'vant'
import enUS from 'vant/es/locale/lang/en-US'
// import '@vant/touch-emulator'
Expand All @@ -14,6 +13,3 @@ app.use(router)
app.use(ElementPlus)
app.use(Vant)
app.mount('#app')
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
20 changes: 19 additions & 1 deletion examples/views/formEditor.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
import { ref, onMounted, getCurrentInstance, inject } from 'vue'
import { erFormEditor } from '@ER/formEditor'
const {
lang
} = inject('globalConfig')
const EReditorRef = ref(null)
const handleListener = async ({ type, data }) => {
// console.log(data)
switch (type) {
case 'lang':
lang.value = data
localStorage.setItem('er-lang', data)
break
}
}
const checkFieldsForNewBadge = (field) => {
return field.type === 'subform'
}
</script>
<template>
<er-form-editor
:checkFieldsForNewBadge="checkFieldsForNewBadge"
:lang="lang"
@listener="handleListener"
ref="EReditorRef"/>
</template>
7 changes: 6 additions & 1 deletion examples/views/formEditor/objEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const getObjData = async () => {
}
}
const handleListener = async ({ type, data }) => {
console.log(type)
switch (type) {
case 'lang':
lang.value = data
Expand All @@ -53,6 +52,8 @@ const handleListener = async ({ type, data }) => {
}
loading.value = true
try {
// console.log(data)
// data.fields[0].options.defaultValue = []
const postData = {
name: state.name,
content: Object.assign({
Expand Down Expand Up @@ -89,13 +90,17 @@ const quickImages = ref([
'/public/Everright-logo.svg',
'/public/Everright-logo.svg'
])
const checkFieldsForNewBadge = (field) => {
return field.type === 'subform'
}
</script>
<template>
<div
v-loading="loading"
>
<er-form-editor
:checkPropsBySelected="checkPropsBySelected"
:checkFieldsForNewBadge="checkFieldsForNewBadge"
v-if="isRender"
:quickImages="quickImages"
:layoutType="layoutType"
Expand Down
5 changes: 5 additions & 0 deletions examples/views/formEditorConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ watch(lang, (newLang) => {
node.columns[0].rows[0].columns[0].label = `${node.columns[0].label} > ${node.columns[0].rows[0].columns[0].type}`
store.layouts.push(node.columns[0].rows[0].columns[0])
break
case 'subform':
node.columns[0].list[0].push(erGeneratorData(erComponentsConfig.fieldsConfig[1].list[0], true, 'en'))
// node.columns[0].rows[0].columns[0].label = `${node.columns[0].label} > ${node.columns[0].rows[0].columns[0].type}`
// store.layouts.push(node.columns[0].rows[0].columns[0])
break
}
})
all.value = [...store.fields, ...store.layouts]
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"canvas": "^2.11.2",
"dayjs": "^1.11.7",
"element-plus": "^2.2.28",
"everright-filter": "^0.0.22",
"everright-filter": "^1.1.1",
"jss": "^10.9.2",
"jss-preset-default": "^10.9.2",
"lodash-es": "^4.17.21",
Expand All @@ -79,7 +79,6 @@
"@ckeditor/ckeditor5-vue": "^4.0.1",
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@element-plus/icons-vue": "^2.0.10",
"@vitejs/plugin-vue": "^3.2.0",
"@vitejs/plugin-vue-jsx": "^2.1.1",
"@vue/compiler-sfc": "^3.2.47",
Expand Down
4 changes: 3 additions & 1 deletion packages/formEditor/components/FormTypes/Uploadfile/pc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ const handleError = (error) => {
:before-upload="beforeAvatarUpload"
:on-error="handleError"
>
<el-icon><Plus /></el-icon>
<el-icon>
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728=""><path fill="currentColor" d="M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z"></path></svg>
</el-icon>
</el-upload>

<el-image-viewer
Expand Down
37 changes: 21 additions & 16 deletions packages/formEditor/components/Layout/ControlInsertionPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const setBorder = (el, className) => {
el.classList.add(className)
}
const getDragElement = (node) => {
return node.__draggable_context.element
return node.__draggable_context?.element
}

const setStates = (newTarget, ev, ER) => {
Expand Down Expand Up @@ -313,14 +313,6 @@ function ControlInsertionPlugin (ER) {
}
ControlInsertion.prototype = {
dragStart (e) {
// const {
// rootEl,
// target
// } = e
// const isBlock = _.get(e, 'sortable.options.dataSource', false) === 'block'
// if (isBlock) return false
// const targetContainer = rootEl.parentNode
// targetContainer.style.zIndex = 2
},
drop (e) {
if (!prevEl || !e.activeSortable) {
Expand All @@ -344,7 +336,12 @@ function ControlInsertionPlugin (ER) {
}
}
if (inserRowIndex !== '') {
const store = Array.isArray(prevSortable.options.parent) ? prevSortable.options.parent : prevSortable.options.parent.list
let store = []
if (prevSortable.options.parent.type === 'subform') {
store = prevSortable.options.parent.list[0]
} else {
store = Array.isArray(prevSortable.options.parent) ? prevSortable.options.parent : prevSortable.options.parent.list
}
store.splice(inserRowIndex, 0, newElement)
utils.addContext(store[inserRowIndex], prevSortable.options.parent)
}
Expand Down Expand Up @@ -382,7 +379,7 @@ function ControlInsertionPlugin (ER) {
const {
activeSortable: {
constructor: {
utils
utils: SortableUtils
},
options: {
dataSource
Expand Down Expand Up @@ -413,15 +410,26 @@ function ControlInsertionPlugin (ER) {
if (target.dataset.layoutType === 'grid') {
return false
}
const dragNode = getDragElement(dragEl)
const targetNode = getDragElement(target)
if ((!utils.checkIsField(dragNode) || dragNode.type === 'subform') && utils.checkIsInSubform(targetNode)) {
return false
}
if (target.dataset.layoutType === 'subform') {
// console.log(utils)
if (!utils.checkIsField(dragNode) || dragNode.type === 'subform') {
return false
}
}
originalEvent.stopPropagation && originalEvent.stopPropagation()
const direction = ''
const targetContainer = el.parentNode
const targetOnlyOne = targetList.length === 1
let newTarget = utils.closest(target, this.options.draggable, sortable.el)
let newTarget = SortableUtils.closest(target, this.options.draggable, sortable.el)
if (dragEl.contains(newTarget)) {
return false
}
if (/^(grid-col|tabs-col|td|collapse-col|root|inline)$/.test(target.dataset.layoutType)) {
if (/^(grid-col|tabs-col|td|collapse-col|root|inline|subform)$/.test(target.dataset.layoutType)) {
newTarget = target
const state = (newTarget.__draggable_component__ || newTarget.children[0].__draggable_component__)
if (!state.list.length) {
Expand All @@ -433,9 +441,6 @@ function ControlInsertionPlugin (ER) {
if (/^(root|grid-col)$/.test(target.dataset.layoutType)) {
const rows = el.children
prevEl = lastChild(el)
// if (prevEl.contains(dragEl) && list.length === 1) {
// console.log(prevEl)
// console.log(dragEl)
if (prevEl === dragEl.parentNode.parentNode && list.length === 1) {
prevEl = ''
return false
Expand Down
6 changes: 6 additions & 0 deletions packages/formEditor/components/Layout/DragGable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import LayoutTabsLayout from './TabsLayout'
import LayoutCollapseLayout from './CollapseLayout'
import LayoutTableLayout from './TableLayout'
import LayoutInlineLayout from './InlineLayout'
import LayoutSubformLayout from './SubformLayout'
import Selection from '@ER/formEditor/components/Selection/selectElement.jsx'
import ControlInsertionPlugin from './ControlInsertionPlugin'
const dragGableWrap = defineComponent({
Expand Down Expand Up @@ -143,6 +144,11 @@ export default defineComponent({
case 'inline':
node = (<LayoutInlineLayout key={element.id} data={element} parent={props.data}></LayoutInlineLayout>)
break
case 'subform':
if (unref(isEditModel) || _.get(state.fieldsLogicState.get(element), 'visible', undefined) !== 0) {
node = (<LayoutSubformLayout key={element.id} data={element} parent={props.data}></LayoutSubformLayout>)
}
break
default:
let TypeComponent = ''
if (unref(isEditModel) || _.get(state.fieldsLogicState.get(element), 'visible', undefined) !== 0) {
Expand Down
164 changes: 164 additions & 0 deletions packages/formEditor/components/Layout/SubformLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import {
defineComponent,
useAttrs,
unref,
inject,
onBeforeUnmount
} from 'vue'
import Selection from '@ER/formEditor/components/Selection/selectElement.jsx'
import LayoutDragGable from './DragGable.jsx'
import hooks from '@ER/hooks'
import _ from 'lodash-es'
import utils from '@ER/utils'
import Icon from '@ER/icon'
export default defineComponent({
name: 'SubformLayout',
inheritAttrs: false,
customOptions: {},
props: {
data: Object,
parent: Array
},
setup (props) {
const ER = inject('Everright')
const ExtraParams = inject('EverrightExtraParams', {})
const ns = hooks.useNamespace('SubformLayout')
const {
state,
isEditModel,
isPc,
setSelection
} = hooks.useTarget()
const typeProps = hooks.useProps(state, props.data, unref(isPc))
const addData = unref(isEditModel) ? [] : _.cloneDeep(props.data.list[0])
const handleAdd = () => {
props.data.list.splice(props.data.list.length, 0, _.cloneDeep(addData))
// console.log(props.data.list)
// console.log(props.data.list[props.data.list.length - 1])
props.data.list[props.data.list.length - 1].forEach(e => {
utils.addContext(e, props.data)
})
}
const clearList = () => {
props.data.list.splice(0, props.data.list.length)
}
const setList = (length, values) => {
clearList()
for (let i = 0; i < length; i++) {
handleAdd()
}
props.data.list.forEach((e, index) => {
e.forEach(e => {
e.columns.forEach(e => {
if (props.data.options.defaultValue) {
try {
ER.setValue(e, values[index][e.key])
} catch (e) {
}
}
})
})
})
}
if (!unref(isEditModel)) {
onBeforeUnmount(() => {
props.data.list[0] = addData
})
clearList()
if (ER.state.remoteValues.has(props.data.key)) {
const values = ER.state.remoteValues.get(props.data.key)
setList(values.length, values)
} else {
if (props.data.options.defaultValue.length) {
setList(props.data.options.defaultValue.length, props.data.options.defaultValue)
}
}
}
if (ExtraParams.inSubformDefaultValueComponent) {
ExtraParams.handle.handleAdd = handleAdd
}
const params = {
hasCopy: true,
hasDel: true,
hasDrag: true,
hasWidthScale: true,
data: props.data,
parent: props.parent
}
if (process.env.NODE_ENV === 'test') {
params['data-field-id'] = `${props.data.id}`
}
return () => {
return (
<Selection
{...useAttrs()}
{
...params
}
>
<div class={ns.b()}>
<el-form-item
{...typeProps.value}
>
<div
class={[ns.e('content')]}
>
{
props.data.list.map((node, index) =>
(
<div
class={[
ns.e('item'),
!unref(isEditModel) && !typeProps.value.disabled && ns.e('edit')
]}
{...utils.addTestId('SubformLayout:item')}
>
<div
class={[ns.e('button')]}>
<el-button
size="large"
circle
>
{index + 1}
</el-button>
<el-button
size="large"
circle
type="danger"
onClick={() => props.data.list.splice(index, 1)}
icon={<Icon class={[ns.e('icon')]} icon="delete"></Icon>}
>
</el-button>
</div>
<LayoutDragGable
data-layout-type={'subform'}
data={node}
ControlInsertion={true}
parent={props.data}/>
</div>
))
}
{
(!typeProps.value.disabled && !ExtraParams.inSubformDefaultValueComponent && addData.length)
? (<div
class={[ns.e('addButton')]}
{...utils.addTestId('SubformLayout:addButton')}
>
<el-button
link
type="primary"
onClick={!unref(isEditModel) && handleAdd}
>
Add new
</el-button>
</div>)
: ''
}
</div>
</el-form-item>
</div>
</Selection>
)
}
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ const handleSuccess = (response, uploadFile) => {
:on-success="handleSuccess"
:on-error="handleError"
>
<el-icon><Plus /></el-icon>
<el-icon>
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-ea893728=""><path fill="currentColor" d="M480 480V128a32 32 0 0 1 64 0v352h352a32 32 0 1 1 0 64H544v352a32 32 0 1 1-64 0V544H128a32 32 0 0 1 0-64h352z"></path></svg>
</el-icon>
</el-upload>
</li>
<li
Expand Down
Loading