Issue #122: Done.
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import sortNumEngZhtw from '@/module/sortNumEngZhtw.js';
|
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['data', 'select'],
|
props: ['data', 'select'],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import sortNumEngZhtw from '@/module/sortNumEngZhtw.js';
|
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['title', 'select', 'data', 'category', 'task', 'isSubmit'],
|
props: ['title', 'select', 'data', 'category', 'task', 'isSubmit'],
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="h-full w-full bg-neutral-10 border border-neutral-300 rounded-xl ml-4 p-2 space-y-2">
|
<div class="h-full w-full bg-neutral-10 border border-neutral-300 rounded-xl ml-4 p-2 space-y-2">
|
||||||
<p class="h2 pl-2 border-b mb-3">Activity list</p>
|
<p class="h2 pl-2 border-b mb-3">Activity list</p>
|
||||||
<div class="h-[calc(100%_-_56px)]">
|
<div class="h-[calc(100%_-_56px)]">
|
||||||
<Draggable :list="datadata" :group="{name: 'activity', pull: 'clone' }" itemKey="name" animation="300" :fallbackTolerance="5" :forceFallback="true" :ghostClass="'ghostSelected'" :dragClass="'dragSelected'" @end="onEnd" @add="onMove" class="h-full flex flex-wrap justify-start content-start gap-4 px-2 overflow-y-auto scrollbar">
|
<Draggable :list="datadata" :group="{name: 'activity', pull: 'clone' }" itemKey="name" animation="300" :fallbackTolerance="5" :forceFallback="true" :ghostClass="'ghostSelected'" :dragClass="'dragSelected'" :sort="false" @end="onEnd" class="h-full flex flex-wrap justify-start content-start gap-4 px-2 overflow-y-auto scrollbar">
|
||||||
<template #item="{ element, index }">
|
<template #item="{ element, index }">
|
||||||
<div :class="listSequence.includes(element) ? 'border-primary text-primary' : ''" class="flex items-center w-[166px] border rounded p-2 bg-neutral-10 cursor-pointer hover:bg-primary/20" @dblclick="moveActItem(index, element)">
|
<div :class="listSequence.includes(element) ? 'border-primary text-primary' : ''" class="flex items-center w-[166px] border rounded p-2 bg-neutral-10 cursor-pointer hover:bg-primary/20" @dblclick="moveActItem(index, element)">
|
||||||
<span class="whitespace-nowrap break-keep text-ellipsis overflow-hidden">{{ element }}</span>
|
<span class="whitespace-nowrap break-keep text-ellipsis overflow-hidden">{{ element }}</span>
|
||||||
@@ -23,13 +23,16 @@
|
|||||||
<!-- Have Data -->
|
<!-- Have Data -->
|
||||||
<div class="m-auto w-full h-[calc(100%_-_56px)]">
|
<div class="m-auto w-full h-[calc(100%_-_56px)]">
|
||||||
<div class="w-full h-full overflow-y-auto overflow-x-auto scrollbar px-4 text-center">
|
<div class="w-full h-full overflow-y-auto overflow-x-auto scrollbar px-4 text-center">
|
||||||
<draggable class="h-full" :group="{name: 'activity', pull: true, put: true }" :list="listSequence" itemKey="name" animation="300" :forceFallback="true" :dragClass="'dragSelected'" :fallbackTolerance="5" @start="onStart" @end="onEnd" :component-data="getComponentData()">
|
<draggable class="h-full" :group="{name: 'activity'}" :list="listSequence" itemKey="name" animation="300" :forceFallback="true" :dragClass="'dragSelected'" :fallbackTolerance="5" @start="onStart" @end="onEnd" :component-data="getComponentData()">
|
||||||
<template #item="{ element, index }">
|
<template #item="{ element, index }">
|
||||||
<div>
|
<div>
|
||||||
<div class="w-full p-2 border rounded bg-neutral-10 cursor-pointer hover:bg-primary/20" @dblclick="moveSeqItem(index, element)">
|
<div class="flex justify-center items-center">
|
||||||
<span>{{ element }}</span>
|
<div class="w-full p-2 border rounded bg-neutral-10 cursor-pointer hover:bg-primary/20" @dblclick="moveSeqItem(index, element)">
|
||||||
|
<span>{{ element }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="material-symbols-outlined pl-1 cursor-pointer duration-300 hover:text-danger" @click.stop.native="moveSeqItem(index, element)">close</span>
|
||||||
</div>
|
</div>
|
||||||
<span v-show="index !== listSequence.length - 1 && index !== lastItemIndex - 1" class="pi pi-chevron-down !text-lg inline-block py-2"></span>
|
<span v-show="index !== listSequence.length - 1 && index !== lastItemIndex - 1" class="pi pi-chevron-down !text-lg inline-block py-2 pr-7"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
@@ -40,7 +43,7 @@
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import sortNumEngZhtw from '@/module/sortNumEngZhtw.js';
|
import { sortNumEngZhtw } from '@/module/sortNumEngZhtw.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['data', 'listSeq', 'isSubmit', 'category'],
|
props: ['data', 'listSeq', 'isSubmit', 'category'],
|
||||||
@@ -89,15 +92,6 @@ export default {
|
|||||||
task: this.listSequence,
|
task: this.listSequence,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Event when you move an item in the list or between lists
|
|
||||||
*/
|
|
||||||
onMove(evt) {
|
|
||||||
let task = evt.item.innerText;
|
|
||||||
let data = this.datadata;
|
|
||||||
data.splice(data.indexOf(task), 1);
|
|
||||||
sortNumEngZhtw(data);
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Element dragging started
|
* Element dragging started
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
<th class="font-semibold leading-10 px-2 border-b border-neutral-500 text-start" colspan="3">Occurrences</th>
|
<th class="font-semibold leading-10 px-2 border-b border-neutral-500 text-start" colspan="3">Occurrences</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<Draggable :list="data" group="activity" itemKey="name" tag="tbody" animation="300" @end="onEnd" :fallbackTolerance="5" :sort="false" :forceFallback="true" :ghostClass="'ghostSelected'" :dragClass="'dragSelected'">
|
<Draggable :list="data" :group="{ name: 'activity', pull: 'clone', put: false }" itemKey="name" tag="tbody" animation="300" @end="onEnd" :fallbackTolerance="5" :forceFallback="true" :ghostClass="'ghostSelected'" :dragClass="'dragSelected'" :sort="false">
|
||||||
<template #item="{ element, index }">
|
<template #item="{ element, index }">
|
||||||
<tr @dblclick="moveActItem(index, element)">
|
<tr @dblclick="moveActItem(index, element)" :class="listSequence.includes(element) ? 'text-primary' : ''">
|
||||||
<td class="px-4 py-2" :id="element.label">{{ element.label }}</td>
|
<td class="px-4 py-2" :id="element.label">{{ element.label }}</td>
|
||||||
<td class="px-4 py-2 w-24">
|
<td class="px-4 py-2 w-24">
|
||||||
<div class="h-4 min-w-[96px] bg-neutral-300 rounded-sm overflow-hidden">
|
<div class="h-4 min-w-[96px] bg-neutral-300 rounded-sm overflow-hidden">
|
||||||
@@ -40,13 +40,15 @@
|
|||||||
<!-- Have Data -->
|
<!-- Have Data -->
|
||||||
<div class="py-4 m-auto w-full h-[calc(100%_-_56px)]">
|
<div class="py-4 m-auto w-full h-[calc(100%_-_56px)]">
|
||||||
<div class="w-full h-full overflow-y-auto overflow-x-auto scrollbar px-4 text-center listSequence">
|
<div class="w-full h-full overflow-y-auto overflow-x-auto scrollbar px-4 text-center listSequence">
|
||||||
<draggable class="h-full" :list="listSequence" group="activity" itemKey="name" animation="300" :forceFallback="true" :dragClass="'dragSelected'" :fallbackTolerance="5" @start="onStart" @end="onEnd" @choose="onChoose">
|
<draggable class="h-full" :list="listSequence" :group="{name: 'activity'}" itemKey="name" animation="300" :forceFallback="true" :fallbackTolerance="5" :dragClass="'!opacity-100'" @start="onStart" @end="onEnd" :component-data="getComponentData()" >
|
||||||
<template #item="{ element, index }">
|
<template #item="{ element, index }">
|
||||||
<div>
|
<div>
|
||||||
<div class="w-full p-2 border border-primary rounded text-primary" @dblclick="moveSeqItem(index, element)">
|
<div class="flex justify-center items-center">
|
||||||
<span>{{ element.label }}</span>
|
<div class="w-full p-2 border border-primary rounded text-primary bg-neutral-10" @dblclick="moveSeqItem(index, element)"><span>{{ element.label }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="material-symbols-outlined pl-1 cursor-pointer duration-300 hover:text-danger" @click.stop.native="moveSeqItem(index, element)">close</span>
|
||||||
</div>
|
</div>
|
||||||
<span v-show="index !== listSeq.length - 1 && index !== lastItemIndex - 1" class="pi pi-chevron-down !text-lg inline-block py-2"></span>
|
<span v-show="index !== listSeq.length - 1 && index !== lastItemIndex - 1" class="pi pi-chevron-down !text-lg inline-block py-2 pr-7"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
@@ -54,8 +56,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { sortNumEngZhtwForFilter } from '@/module/sortNumEngZhtw.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
filterTaskData: {
|
filterTaskData: {
|
||||||
@@ -76,14 +79,16 @@ export default {
|
|||||||
listSequence: this.listSeq,
|
listSequence: this.listSeq,
|
||||||
filteredData: this.filterTaskData,
|
filteredData: this.filterTaskData,
|
||||||
lastItemIndex: null,
|
lastItemIndex: null,
|
||||||
isDragging: false,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
data: function() {
|
data: function() {
|
||||||
// TODO Activity List 的 dblclick, drag & drop 要改假刪除
|
|
||||||
// Activity List 要排序
|
// Activity List 要排序
|
||||||
return this.filteredData.sort((x, y) => y.occurrences - x.occurrences);
|
this.filteredData = this.filteredData.sort((x, y) => {
|
||||||
|
y.occurrences - x.occurrences
|
||||||
|
if(y.occurrences === x.occurrences) sortNumEngZhtwForFilter(x.label, y.label);
|
||||||
|
});
|
||||||
|
return this.filteredData;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -91,7 +96,7 @@ export default {
|
|||||||
this.listSequence = newval;
|
this.listSequence = newval;
|
||||||
},
|
},
|
||||||
filterTaskData(newval){
|
filterTaskData(newval){
|
||||||
this.data = newval;
|
this.filteredData = newval;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -101,7 +106,6 @@ export default {
|
|||||||
* @param {object} element data item
|
* @param {object} element data item
|
||||||
*/
|
*/
|
||||||
moveActItem(index, element){
|
moveActItem(index, element){
|
||||||
this.data.splice(index, 1);
|
|
||||||
this.listSequence.push(element);
|
this.listSequence.push(element);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -111,13 +115,19 @@ export default {
|
|||||||
*/
|
*/
|
||||||
moveSeqItem(index, element){
|
moveSeqItem(index, element){
|
||||||
this.listSequence.splice(index, 1);
|
this.listSequence.splice(index, 1);
|
||||||
this.data.push(element);
|
},
|
||||||
|
/**
|
||||||
|
* get listSequence
|
||||||
|
*/
|
||||||
|
getComponentData(){
|
||||||
|
this.$emit('update:listSeq', this.listSequence);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Element dragging started
|
* Element dragging started
|
||||||
*/
|
*/
|
||||||
onStart(evt) {
|
onStart(evt) {
|
||||||
this.isDragging = true;
|
const lastChild = evt.to.lastChild.lastChild;
|
||||||
|
lastChild.style.display = 'none';
|
||||||
// 隱藏拖曳元素原位置
|
// 隱藏拖曳元素原位置
|
||||||
const originalElement = evt.item;
|
const originalElement = evt.item;
|
||||||
originalElement.style.display = 'none';
|
originalElement.style.display = 'none';
|
||||||
@@ -129,7 +139,6 @@ export default {
|
|||||||
* Element dragging ended
|
* Element dragging ended
|
||||||
*/
|
*/
|
||||||
onEnd(evt) {
|
onEnd(evt) {
|
||||||
this.isDragging = false;
|
|
||||||
// 顯示拖曳元素
|
// 顯示拖曳元素
|
||||||
const originalElement = evt.item;
|
const originalElement = evt.item;
|
||||||
originalElement.style.display = '';
|
originalElement.style.display = '';
|
||||||
@@ -139,31 +148,15 @@ export default {
|
|||||||
evt.oldIndex !== listIndex ? lastChild.style.display = '' : null;
|
evt.oldIndex !== listIndex ? lastChild.style.display = '' : null;
|
||||||
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
// reset: 拖曳最後一個元素時,倒數第二的元素的箭頭要隱藏
|
||||||
this.lastItemIndex = null;
|
this.lastItemIndex = null;
|
||||||
this.$emit('update:listSeq', this.listSequence);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Element is chosen
|
|
||||||
*/
|
|
||||||
onChoose(evt) {
|
|
||||||
// 拖曳時要隱藏箭頭
|
|
||||||
// isDragging: 只有拖曳才要隱藏,dblclick 不用
|
|
||||||
const lastChild = evt.item.lastChild;
|
|
||||||
if (this.isDragging) lastChild.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.ghostSelected {
|
.ghostSelected {
|
||||||
/* @apply shadow-inner bg-neutral-900 shadow-neutral-500 */
|
|
||||||
@apply shadow-[0px_0px_100px_-10px_inset] shadow-neutral-200
|
@apply shadow-[0px_0px_100px_-10px_inset] shadow-neutral-200
|
||||||
}
|
}
|
||||||
.dragSelected {
|
.dragSelected {
|
||||||
@apply shadow-[0px_0px_4px_2px] bg-neutral-10 shadow-neutral-300 !opacity-100
|
@apply shadow-[0px_0px_4px_2px] bg-neutral-10 shadow-neutral-300 !opacity-100
|
||||||
}
|
}
|
||||||
.dragged-item {
|
|
||||||
@apply !opacity-100
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -476,7 +476,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 將資料指向 Vue data 雙向綁定
|
// 將資料指向 Vue data 雙向綁定
|
||||||
console.log(data);
|
|
||||||
const postData = Array.isArray(data) ? data : [data];
|
const postData = Array.isArray(data) ? data : [data];
|
||||||
|
|
||||||
// 快速檢查每一 filter 規則是否為空集合
|
// 快速檢查每一 filter 規則是否為空集合
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @param {array} data
|
* @param {array} data
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export default function sortNumEngZhtw(data) {
|
export function sortNumEngZhtw(data) {
|
||||||
return data.sort((a, b) => {
|
return data.sort((a, b) => {
|
||||||
// 檢查兩個值是否都是數字
|
// 檢查兩個值是否都是數字
|
||||||
var isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
var isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
||||||
@@ -20,3 +20,24 @@ export default function sortNumEngZhtw(data) {
|
|||||||
return a.localeCompare(b, 'zh-Hant-TW', { sensitivity: 'accent' });
|
return a.localeCompare(b, 'zh-Hant-TW', { sensitivity: 'accent' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 數字、英文、中文,給 Filter Table 排序
|
||||||
|
* @param {string} a label
|
||||||
|
* @param {string} b label
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function sortNumEngZhtwForFilter(a, b) {
|
||||||
|
// 檢查兩個值是否都是數字
|
||||||
|
var isANumber = !isNaN(parseFloat(a)) && isFinite(a);
|
||||||
|
var isBNumber = !isNaN(parseFloat(b)) && isFinite(b);
|
||||||
|
|
||||||
|
// 如果兩個值都是數字,直接比較大小
|
||||||
|
if (isANumber && isBNumber) return parseFloat(a) - parseFloat(b);
|
||||||
|
|
||||||
|
// 如果其中一個值是數字,將數字視為最小,排在前面
|
||||||
|
if (isANumber) return -1;
|
||||||
|
if (isBNumber) return 1;
|
||||||
|
|
||||||
|
// 其他情況下,使用 localeCompare 方法進行中文排序
|
||||||
|
return a.localeCompare(b, 'zh-Hant-TW', { sensitivity: 'accent' });
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user