Skip to content

feat: transfer add drag sort #51

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

Merged
merged 7 commits into from
Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 10 additions & 4 deletions packages/devui-vue/devui/transfer/common/use-transfer-base.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { computed, ExtractPropTypes, PropType, ComputedRef } from 'vue'
import { IItem, TState, TResult } from '../types'
import { TransferProps } from './use-transfer'
import { transferCommon, transferDragFunctions } from './use-transfer-common'

export type TransferOperationProps = ExtractPropTypes<typeof transferBaseProps>

export const transferBaseProps = {
...transferCommon,
...transferDragFunctions,
sourceOption: {
type: Array as () => IItem[],
default(): Array<IItem> {
Expand Down Expand Up @@ -57,13 +60,13 @@ export const transferBaseProps = {
type: Number,
default: (): number => 0
},
showTooltip: {
isSourceDroppable: {
type: Boolean,
default: (): boolean => false
},
tooltipPosition: {
type: String as PropType<'top' | 'right' | 'bottom' | 'left'>,
default: (): string => 'top'
isTargetDroppable: {
type: Boolean,
default: (): boolean => false
},
scopedSlots: {
type: Object
Expand All @@ -76,6 +79,9 @@ export const transferBaseProps = {
},
onUpdateCheckeds: {
type: Function as PropType<(val: string[]) => void>
},
onDragend: {
type: Function as unknown as () => ((dragItem: IItem, dropItem: IItem) => void)
}
}

Expand Down
17 changes: 17 additions & 0 deletions packages/devui-vue/devui/transfer/common/use-transfer-checkbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ExtractPropTypes } from 'vue'
import { IItem } from '../types'
import { transferCommon } from './use-transfer-common'

const transferCheckboxProps = {
...transferCommon,
data: {
type: Object as () => IItem,
},
id: {
type: Number
}
}

export type TransferCheckboxProps = ExtractPropTypes<typeof transferCheckboxProps>

export default transferCheckboxProps
34 changes: 34 additions & 0 deletions packages/devui-vue/devui/transfer/common/use-transfer-common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PropType } from 'vue'
import { IItem } from '../types'

export const transferCommon = {
showTooltip: {
type: Boolean,
default: (): boolean => false
},
tooltipPosition: {
type: String as PropType<'top' | 'right' | 'bottom' | 'left'>,
default: (): string => 'top'
}
}

export const transferDragFunctions = {
onDragstart: {
type: Function as unknown as () => ((event: Event, dragItem: IItem) => void)
},
onDrop: {
type: Function as unknown as () => ((event: Event, dropItem: IItem) => void)
},
onDragleave: {
type: Function as unknown as () => ((event: Event, dragItem: IItem) => void)
},
onDragover: {
type: Function as unknown as () => ((event: Event, dragItem: IItem) => void)
},
onDragenter: {
type: Function as unknown as () => ((event: Event, dragItem: IItem) => void)
},
onDragend: {
type: Function as unknown as () => ((event: Event, dropItem: IItem) => void)
}
}
20 changes: 20 additions & 0 deletions packages/devui-vue/devui/transfer/common/use-transfer-drag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PropType, ExtractPropTypes } from '@vue/runtime-core'
import { IItem } from '../types'
import { transferCommon, transferDragFunctions } from './use-transfer-common'

const transferDragProps = {
...transferCommon,
...transferDragFunctions,
itemData: {
type: Object as PropType<IItem>
},
id: {
type: Number,
default: (): number | null => null
},

}

export type TransferDragProps = ExtractPropTypes<typeof transferDragProps>

export default transferDragProps
13 changes: 5 additions & 8 deletions packages/devui-vue/devui/transfer/common/use-transfer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ExtractPropTypes, PropType, SetupContext } from 'vue'
import { IItem, ITitles, IModel, TState } from '../types'
import { transferCommon } from './use-transfer-common'

export const transferProps = {
...transferCommon,
sourceOption: {
type: Array as () => IItem[],
require: true,
Expand Down Expand Up @@ -44,14 +46,6 @@ export const transferProps = {
type: Boolean,
default: (): boolean => false
},
showTooltip: {
type: Boolean,
default: (): boolean => false
},
tooltipPosition: {
type: String as PropType<'top' | 'right' | 'bottom' | 'left'>,
default: (): string => 'top'
},
beforeTransfer: {
type: Function as unknown as () => ((sourceOption: TState, targetOption: TState) => boolean | Promise<boolean>)
},
Expand All @@ -72,6 +66,9 @@ export const transferProps = {
},
afterTransfer: {
type: Function as unknown as () => ((targetOption: TState) => void)
},
onDragend: {
type: Function as unknown as () => ((direction: string, dragItem: IItem, dropItem: IItem) => void)
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/devui-vue/devui/transfer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import type { App } from 'vue'
import Transfer from './src/transfer'

Transfer.install = function (app: App) {
app.component(Transfer.name, Transfer)
app.component(Transfer.name, Transfer)
}

export { Transfer }

export default {
title: 'Transfer 穿梭框',
category: '数据录入',
status: '10%',
status: '40%',
install(app: App): void {
app.use(Transfer as any)
}
Expand Down
120 changes: 87 additions & 33 deletions packages/devui-vue/devui/transfer/src/transfer-base.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,108 @@
import { defineComponent, computed } from 'vue'
import { defineComponent, computed, ref, watch, SetupContext } from 'vue'
import { transferBaseProps, TransferBaseClass, TransferBaseProps } from '../common/use-transfer-base'
import DCheckbox from '../../checkbox/src/checkbox'
import DCheckboxGroup from '../../checkbox/src/checkbox-group'
import DSearch from '../../search/src/search'
import DTooltip from '../../tooltip/src/tooltip'
import DTransferDrag from './transfer-drag-item'
import DTransfeCheckbox from './transfer-checkbox'
export default defineComponent({
name: 'DTransferBase',
components: {
DSearch,
DCheckboxGroup,
DCheckbox,
DTooltip
DTransferDrag,
DTransfeCheckbox
},
props: transferBaseProps,
setup(props: TransferBaseProps, ctx) {
setup(props: TransferBaseProps, ctx: SetupContext) {
/** data start **/
const allHalfchecked = ref(false)//ref(props.allChecked)
const modelValues = computed(() => props.checkedValues as Array<string>)
const dragWrapClass = computed(() => {
const isDrag = props.isSourceDroppable || props.isTargetDroppable
return `devui-transfer-panel-body-list devui-transfer-panel-body-${isDrag ? '' : 'no'}drag`
})
const searchQuery = computed(() => props.filter)
const baseClass = TransferBaseClass(props)
const dropItem = ref(null)

/** data end **/

/** watch start **/
watch(
() => props.checkedNum,
(nVal) => {
if (props.allChecked) {
allHalfchecked.value = !props.allChecked
} else {
allHalfchecked.value = nVal !== 0
}
},
{
immediate: true
}
)
/** watch end **/

/** methods start **/
const updateSearchQuery = (val: string): void => ctx.emit('changeQuery', val)

const renderCheckbox = (props, key, showTooltip = false, tooltipPosition = 'top') => {
const checkbox = <DCheckbox
class="devui-transfer-panel-body-list-item"
label={props.key}
value={props.value}
disabled={props.disabled}
key={key}>
</DCheckbox>
return !showTooltip ? checkbox : <DTooltip
position={tooltipPosition}
content={props.key}>{checkbox}</DTooltip>
const renderCheckboxGroup = () => {
return <DCheckboxGroup
modelValue={modelValues.value}
onChange={
(values: string[]): void => ctx.emit('updateCheckeds', values)
}>
{
props.sourceOption.map((item, idx) => {
return <DTransfeCheckbox
data={item}
id={idx}
showTooltip={props.showTooltip}
tooltipPosition={props.tooltipPosition}>
</DTransfeCheckbox>
})
}
</DCheckboxGroup>
}

const renderDragCheckboxGroup = () => {
return <DCheckboxGroup
modelValue={modelValues.value}
onChange={
(values: string[]): void => ctx.emit('updateCheckeds', values)
}>
{
props.sourceOption.map((item, idx) => {
return <DTransferDrag
itemData={item}
id={idx}
showTooltip={props.showTooltip}
tooltipPosition={props.tooltipPosition}
onDrop={(event, item) => {
dropItem.value = item
}}
onDragend={(event, dragItem) => {
props.onDragend && props.onDragend(dragItem, dropItem.value)
}} />
})
}
</DCheckboxGroup>
}

/** methods start **/

return {
baseClass,
searchQuery,
dragWrapClass,
modelValues,
dropItem,
allHalfchecked,
updateSearchQuery,
renderCheckbox
renderCheckboxGroup,
renderDragCheckboxGroup
}
},
render() {
Expand All @@ -54,16 +111,18 @@ export default defineComponent({
baseClass,
checkedNum,
allChecked,
allHalfchecked,
sourceOption,
allCount,
updateSearchQuery,
search,
searchQuery,
modelValues,
dragWrapClass,
height,
showTooltip,
tooltipPosition,
renderCheckbox,
isSourceDroppable,
isTargetDroppable,
renderCheckboxGroup,
renderDragCheckboxGroup
} = this

return (
Expand All @@ -72,8 +131,11 @@ export default defineComponent({
this.$slots.header ? this.$slots.header() : (<div class="devui-transfer-panel-header">
<div class="devui-transfer-panel-header-allChecked">
<DCheckbox
halfchecked={allHalfchecked}
modelValue={allChecked}
onChange={(value: boolean) => this.$emit('changeAllSource', value)}>
onChange={(value: boolean) => {
this.$emit('changeAllSource', value)
}}>
{title}
</DCheckbox>
</div>
Expand All @@ -86,19 +148,11 @@ export default defineComponent({
{search && <div class="devui-transfer-panel-body-search">
<DSearch modelValue={searchQuery} onUpdate:modelValue={updateSearchQuery} />
</div>}
<div class="devui-transfer-panel-body-list" style={{ height: height }}>
<div class={dragWrapClass} style={{ height: height }}>
{
sourceOption.length ? <DCheckboxGroup
modelValue={modelValues}
onChange={
(values: string[]): void => this.$emit('updateCheckeds', values)}>
{
sourceOption.map((item, idx) => {
return renderCheckbox(item, idx, showTooltip, tooltipPosition)
})
}
</DCheckboxGroup> :
<div class="devui-transfer-panel-body-list-empty">无数据</div>
sourceOption.length ?
(isSourceDroppable || isTargetDroppable ? renderDragCheckboxGroup() : renderCheckboxGroup())
: <div class="devui-transfer-panel-body-list-empty">无数据</div>
}
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions packages/devui-vue/devui/transfer/src/transfer-checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { defineComponent } from 'vue'
import DCheckbox from '../../checkbox/src/checkbox'
import DTooltip from '../../tooltip/src/tooltip'
import transferCheckboxProps, { TransferCheckboxProps } from '../common/use-transfer-checkbox'

export default defineComponent({
name: 'DTransferCheckbox',
components: {
DCheckbox,
DTooltip
},
props: transferCheckboxProps,
setup(props: TransferCheckboxProps) {
/** data start **/
const renderCheckbox = () => {
return <DCheckbox
label={props.data.key}
value={props.data.value}
disabled={props.data.disabled}
class="devui-transfer-panel-body-list-item"
key={props.id}>
</DCheckbox>
}
/** data end **/

/** watch start **/
/** watch end **/

/** methods start **/
/** methods end **/

return () => {
return (
!props.showTooltip ? renderCheckbox() :
<DTooltip class="devui-transfer-panel-body-list-tooltip"
position={props.tooltipPosition}
content={props.data.key}>{renderCheckbox()}
</DTooltip>
)
}
}
})
Loading