Skip to content

Commit

Permalink
feat(generator): delete element automatically selects the neighboring…
Browse files Browse the repository at this point in the history
… previous element or the parent
  • Loading branch information
mengshang918 committed May 9, 2022
1 parent 944fb4b commit 945196a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 84 deletions.
89 changes: 23 additions & 66 deletions packages/drip-form/src/reducers/deleteField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @Author: jiangxiaowei
* @Date: 2021-10-26 19:25:56
* @Last Modified by: jiangxiaowei
* @Last Modified time: 2022-03-09 14:10:37
* @Last Modified time: 2022-04-24 18:33:29
*/
import { produce, original } from 'immer'
import { deleteDeepProp, setDeepProp } from '@jdfed/utils'
Expand Down Expand Up @@ -70,72 +70,21 @@ const deleteField = ({
}
case 'object': {
const order: Array<string> = deleteParentUiSchema.order || []
// 祖父容器类型
let grandUiType = 'object'
// 祖父容器路径
let grandParentPath = ''
const deleteParenPathArr = deleteParentPath.split('.')
if (deleteParenPathArr.length > 1) {
grandParentPath = deleteParenPathArr
.slice(0, deleteParenPathArr.length - 1)
.join('.')
// 待添加的组父级表单
const { uiSchema: addGrandParentUiSchema } = get(grandParentPath)
// 待添加表单 祖父级元素类型 默认对象类型
if (addGrandParentUiSchema.type === 'array') {
if (['normal', 'tuple'].includes(addGrandParentUiSchema.mode)) {
grandUiType = 'tuple'
// 元祖
} else {
// 自增数组
grandUiType = 'array'
}
}
const index = order.findIndex((item) => item == fieldKey.split('.').pop())
// 删除order
if (index != -1) {
deleteDeepProp(orderPath.concat(index), state.uiSchema)
}
// 祖父是数组容器时,删除对象容器最后一个属性,需要同时删除对象容器
if (grandUiType === 'array' && order.length === 1) {
const deleteUiSchemaPath = getKey(
`${grandParentPath}.0`,
'uiSchema'
).split('.')
const deleteDataSchemaPath = getKey(
`${grandParentPath}.0`,
'dataSchema'
).split('.')
// 删除order
deleteDeepProp(
getKey(grandParentPath, 'uiSchema').split('.').concat('order'),
state.uiSchema
)
// 删除uiSchema
deleteDeepProp(deleteUiSchemaPath, state.uiSchema)
// 删除dataSchema
deleteDeepProp(deleteDataSchemaPath, state.dataSchema)
// 删除typePath
Object.keys(state.typePath).map((item) => {
if (item.startsWith(getTypeKey(`${grandParentPath}.0`))) {
delete state.typePath[item]
}
})
} else {
const index = order.findIndex(
(item) => item == fieldKey.split('.').pop()
)
// 删除order
if (index != -1) {
deleteDeepProp(orderPath.concat(index), state.uiSchema)
// 删除uiSchema
deleteDeepProp(deleteUiSchemaPath, state.uiSchema)
// 删除dataSchema
deleteDeepProp(deleteDataSchemaPath, state.dataSchema)
// 删除typePath
Object.keys(state.typePath).map((item) => {
if (item.startsWith(getTypeKey(fieldKey))) {
delete state.typePath[item]
}
// 删除uiSchema
deleteDeepProp(deleteUiSchemaPath, state.uiSchema)
// 删除dataSchema
deleteDeepProp(deleteDataSchemaPath, state.dataSchema)
// 删除typePath
Object.keys(state.typePath).map((item) => {
if (item.startsWith(getTypeKey(fieldKey))) {
delete state.typePath[item]
}
})
}
})
// TODO 删除formData
// TODO 删除dataSchema的其它等字段
break
Expand All @@ -152,7 +101,15 @@ const deleteField = ({
}
})
// 删除dataSchema
deleteDeepProp(deleteDataSchemaPath, state.dataSchema)
if (order.length === 1) {
// 元祖中删除最后一个元素时,需要同步删除父级的items,否则jsonSchema会报错
deleteDeepProp(
deleteDataSchemaPath.slice(0, deleteDataSchemaPath.length - 1),
state.dataSchema
)
} else {
deleteDeepProp(deleteDataSchemaPath, state.dataSchema)
}
const oldProperties: Record<string, any> = deleteParentUiSchema.properties
const newProperties = produce(oldProperties, (draft) => {
const index = order.findIndex(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* @Author: jiangxiaowei
* @Date: 2022-03-02 13:04:51
* @Last Modified by: jiangxiaowei
* @Last Modified time: 2022-03-02 13:04:51
* @Last Modified by: jiangxiaowei
* @Last Modified time: 2022-04-22 14:13:13
*/
import React, { memo } from 'react'
import { useRecoilValue } from 'recoil'
Expand All @@ -25,6 +25,7 @@ const ActiveTools = memo<{
<Item icon="xiangxia" />
<Item icon="fuzhi1" /> */}
{showDeleteIcon && (
// undefined避免传递event
<Item icon="shanchu" onClick={deleteField.bind(this, undefined)} />
)}
</div>
Expand Down
62 changes: 49 additions & 13 deletions packages/generator/src/hooks/useDeleteField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,67 @@
* @Author: jiangxiaowei
* @Date: 2021-10-27 14:32:51
* @Last Modified by: jiangxiaowei
* @Last Modified time: 2021-11-22 13:46:03
* @Last Modified time: 2022-04-24 10:20:18
*/

import { useCallback, useContext } from 'react'
import { useRecoilValue } from 'recoil'
import { useContext } from 'react'
import { selectedAtom, GeneratorContext } from '@generator/store'
import { message } from 'antd'
import { useRecoilCallback } from 'recoil'
import useCanEditJson from './useCanEditJson'

type DeleteField = (fieldKey?: string) => void

const useDeleteField = (): DeleteField => {
const generatorContext = useContext(GeneratorContext)
const selectedKey = useRecoilValue(selectedAtom)
const canEdit = useCanEditJson()

const deleteField = useCallback<DeleteField>(
(fieldKey = selectedKey || '') => {
if (!canEdit) {
message.warning('请先保存JSON编辑结果,再退出!', 2)
return
} // 当DripForm中有元素时,可以通过内置的deleteField方法来添加元素
generatorContext.current?.__generator__.deleteField(fieldKey)
},
[canEdit, generatorContext, selectedKey]
const deleteField = useRecoilCallback<[string | undefined], void>(
({ snapshot, set }) =>
async (fieldKey) => {
if (!canEdit) {
message.warning('请先保存JSON编辑结果,再退出!', 2)
return
} // 当DripForm中有元素时,可以通过内置的deleteField方法来添加元素
const selectedKey = await snapshot.getPromise(selectedAtom)
// 待删除的表单fieldKey
const deleteFieldKey = fieldKey || selectedKey || ''
const keyPath = deleteFieldKey.split('.')
// 删除元素的父级
const parentKey = keyPath.slice(0, keyPath.length - 1).join('.')
const order =
generatorContext.current?.get(parentKey).uiSchema.order || []
generatorContext.current?.__generator__.deleteField(
deleteFieldKey,
() => {
// 删除元素,选中上一个元素,没有上一个元素,则选中父级。设置selectFieldKey
let type =
generatorContext.current?.get(parentKey).uiSchema.type || 'object'
const mode = generatorContext.current?.get(parentKey).uiSchema.mode
if (
type === 'array' &&
mode &&
['normal', 'tuple'].includes(mode)
) {
type = 'tuple'
}
const index = order.findIndex(
(item) => String(item) === keyPath.slice(-1).join()
)
// 存在上一个相邻元素
if (index > 0) {
set(
selectedAtom,
`${parentKey ? parentKey + '.' : ''}${order[index - 1]}`
)
} else {
//不存在上一个相邻元素,自动选中父级
set(selectedAtom, parentKey)
}
}
)
},
[canEdit, generatorContext]
)
return deleteField
}
Expand Down
7 changes: 4 additions & 3 deletions packages/hooks/src/useSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @Author: jiangxiaowei
* @Date: 2021-08-06 15:33:25
* @Last Modified by: jiangxiaowei
* @Last Modified time: 2022-02-11 14:12:02
* @Last Modified time: 2022-04-22 11:31:56
*/
import { typeCheck } from '@jdfed/utils'
import { useCallback } from 'react'
Expand Down Expand Up @@ -34,7 +34,7 @@ export type Set = (
type: SetType,
value: SetFn | StaticValue
) => void
export type DeleteField = (fieldKey: string) => void
export type DeleteField = (fieldKey: string, cb?: () => void) => void
export type AddField = (params: {
fieldKey: string
closestEdge: ClosestEdge
Expand Down Expand Up @@ -324,7 +324,7 @@ const useSchema = ({
* 删除一个表单项(同步删除uiSchema、dataSchema中的配置)
*/
const deleteField = useCallback(
(key) => {
(key, cb) => {
dispatch({
type: 'deleteField',
action: {
Expand All @@ -334,6 +334,7 @@ const useSchema = ({
getTypeKey,
},
})
cb && cb()
},
[dispatch, get, getKey, getTypeKey]
)
Expand Down

0 comments on commit 945196a

Please sign in to comment.