Skip to content

Feat/dragndrop #10

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 9 commits into from
Apr 9, 2025
98 changes: 65 additions & 33 deletions src/components/pivottable-ui/VDragAndDropCell.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
<template>
<td>
<h3>VDragAndDropCell ({{ attrs }})</h3>
<h3>VDragAndDropCell ({{ cellType }})</h3>
<Draggable
v-model="modelItems"
:class="classNames"
:group="{ name: 'sharted', pull: true, put: true }"
ghost-class="pvtPlaceholder"
@change="onChange"
tag="ul"
:list="modelItems"
:group="{ name: 'sharted', pull: true, put: true }"
ghost-class=".pvtFilterBox"
:preventOnfFilter="false"
:class="classes"
@sort="onDrag"
>
<!-- :modelValue="items" -->
<!-- @update:modelValue="onChange" -->
<!-- @sort="onChange"-->
<VDraggableAttribute
v-for="item in modelItems"
:key="item"
:name="item"
:sortable="true"
:draggable="true"
:attrValues="{}"
:sorter="getSort(() => { }, item)"
:menuLimit="500"
:zIndex="1000"
:valueFilter="{}"
:open="false"
:async="false"
:unused="false"
:localeStrings="{}"
:disabled="disabledFromDragDrop.includes(item)"
:sortOnly="restrictedFromDragDrop.includes(item)"
:open="openStatus?.[item]"
:unSelectedFilterValues="valueFilter?.[item]"
:attributeName="item"
:zIndex="zIndices[item]"
:hideDropDown="hideDropDown"
@update:zIndexOfFilterBox="$emit('update:zIndexOfFilterBox')"
@update:unselectedFilterValues="$emit('update:unselectedFilterValues')"
@update:openStatusOfFilterBox="$emit('update:unselectedFilterValues')"
>
<template #pvtAttr="{ attrName }">
{{ attrName }}
Expand All @@ -38,40 +33,77 @@
</template>

<script setup>
import VDraggableAttribute from './VDraggableAttribute.vue'
import { ref, onMounted, computed } from 'vue'
import { VueDraggableNext as Draggable } from 'vue-draggable-next'
import { ref, onMounted } from 'vue'
import { PivotData, getSort, sortAs, aggregators } from '../../helper'
import VDraggableAttribute from './VDraggableAttribute.vue'

const emit = defineEmits(['update:filters'])
const emit = defineEmits([
'update:draggedAttribute',
'update:zIndexOfFilterBox',
'update:unselectedFilterValues',
'update:openStatusOfFilterBox'
])

const props = defineProps({
attrs: {
cellType: {
type: String,
required: true
},
// 삭제할 수 있으면 삭제
classes: {
type: String,
default: ''
},
items: {
attributeNames: {
type: Array,
default: () => []
},
valueFilter: {
type: Object,
default: () => ({})
},
// 같은 셀 내 이동만 가능(정렬)
restrictedFromDragDrop: {
type: Array,
default: () => []
},
classNames: {
// 삭제 보류
disabledFromDragDrop: {
type: Array,
default: () => []
},
hideFilterBoxOfUnusedAttributes: {
type: Boolean,
default: false
},
zIndices: {
type: Object,
default: () => ({})
},
openStatus: {
type: Object,
default: () => ({})
}
})

const modelItems = ref([])

const onChange = evt => {
const onDrag = evt => {
console.log('event', Object.keys(evt)[0])
emit('update:filters', { cellType: props.attrs, filters: modelItems.value })
emit('update:draggedAttribute', {
cellType: props.cellType,
attributes: modelItems.value
})
}

onMounted(() => {
modelItems.value = [...props.items]
modelItems.value = [...props.attributeNames]
})

// 이름 변경해야할 것 같음 hideDropDownInUnusedCell
const hideDropDown = computed(() => {
return props.cellType === 'unused' && props.hideFilterBoxOfUnusedAttrs
})
</script>

<style scoped>
</style>
<style scoped></style>
89 changes: 51 additions & 38 deletions src/components/pivottable-ui/VDraggableAttribute.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
<template>
<li :data-id="!disabled ? name : undefined">
<span class="pvtAttr" :class="[filtered, { sortonly, disabled }]">
<slot name="pvtAttr" :attrName="name">{{ name }}</slot>
<li>
<span class="pvtAttr" :class="[filtered, { sortOnly, disabled }]">
<slot name="pvtAttr" :attrName="attributeName">{{ attributeName }}</slot>
<span
v-if="showDropdown"
v-if="!hideDropDownButton"
@click="toggleFilterBox"
class="pvtTriangle"
> ▾</span>
>
</span>
<VFilterBox
v-if="open"
:valueFilter="valueFilter"
:name="name"
:attrValues="attrValues"
:sorter="sorter"
:menuLimit="menuLimit"
:unselectedFilterValues="unselectedFilterValues"
:filterBoxKey="attributeName"
:zIndex="zIndex"
@update:zIndexOfFilterBox="$emit('update:zIndexOfFilterBox')"
@update:unselectedFilterValues="$emit('update:unselectedFilterValues')"
>
</VFilterBox>
<!-- <VFilterBox v-if="open" ></VFilterBox> -->
<!-- <slot v-if="open" name="filterbox"></slot> -->
</span>
</li>
</template>
Expand All @@ -25,50 +26,62 @@
import VFilterBox from './VFilterBox.vue'
import { computed } from 'vue'

const emit = defineEmits([
'update:zIndexOfFilterBox',
'update:unselectedFilterValues',
'update:openStatusOfFilterBox'
])

const props = defineProps({
draggable: {
type: Boolean,
default: true
attributeName: {
type: String,
required: true
},
sortable: {
disabled: {
type: Boolean,
default: true
default: false
},
name: {
type: String,
required: true
sortOnly: {
type: Boolean,
default: false
},
open: {
type: Boolean,
default: false
},
async: Boolean,
unused: Boolean,
valueFilter: {
unselectedFilterValues: {
type: Object,
default: () => {
return {}
}
default: () => ({})
},
attrValues: {
type: Object,
required: false
zIndex: {
type: Number
},
sorter: {
type: Function,
required: true
hideDropDown: {
type: Boolean,
default: false
},
menuLimit: Number
// 임시 데이터; 필터 목록은 어떻게 할 것인지?
attributeValues: {
type: Array,
default: () => []
}
})

const disabled = computed(() => !props.sortable && !props.draggable)
const sortonly = computed(() => props.sortable && !props.draggable)
const toggleFilterBox = () => {
emit('update:openStatusOfFilterBox', props.attributeName)
}

const filtered = computed(() => Object.keys(props.valueFilter).length !== 0 ? 'pvtFilteredAttribute' : '')
const showDropdown = computed(() => !disabled.value && (props.async ? !props.unused : true))
const hideDropDownButton = computed(
() => props.hideDropDown || !props.attributeValues.length || props.disabled
)

const filtered = computed(() => {
return Object.keys(props.unselectedFilterValues).length !== 0
? 'pvtFilteredAttribute'
: null
})
</script>

<style scoped>

/* css sortonly를 sortOnly로 변경해야함 */
</style>
Loading