完成信号源显示,信号源拖拽开窗,替换窗口
This commit is contained in:
parent
74abf865fd
commit
267d827fdb
|
@ -19,6 +19,7 @@
|
||||||
"qrcode.vue": "^3.3.3",
|
"qrcode.vue": "^3.3.3",
|
||||||
"quasar": "^2.6.2",
|
"quasar": "^2.6.2",
|
||||||
"reconnecting-websocket": "^4.4.0",
|
"reconnecting-websocket": "^4.4.0",
|
||||||
|
"sortablejs": "^1.15.0",
|
||||||
"ts-md5": "^1.2.11",
|
"ts-md5": "^1.2.11",
|
||||||
"v-viewer": "^3.0.9",
|
"v-viewer": "^3.0.9",
|
||||||
"vconsole": "^3.14.6",
|
"vconsole": "^3.14.6",
|
||||||
|
|
|
@ -32,4 +32,5 @@ export namespace EventNamesDefine {
|
||||||
export const CurrentConnectDisconnect = "onCurrentConnectDisconnect";
|
export const CurrentConnectDisconnect = "onCurrentConnectDisconnect";
|
||||||
export const CurrentConnectConnected = "onCurrentConnectConnected";
|
export const CurrentConnectConnected = "onCurrentConnectConnected";
|
||||||
export const CurrentClientChanged = "onCurrentClientChanged";
|
export const CurrentClientChanged = "onCurrentClientChanged";
|
||||||
|
export const DropToWall = "onDropToWall";
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,35 @@
|
||||||
</div>
|
</div>
|
||||||
<q-separator />
|
<q-separator />
|
||||||
|
|
||||||
<q-tab-panels v-model="tab" animated class="fit">
|
<q-tab-panels v-model="tab" animated class="fit text-black">
|
||||||
<q-tab-panel name="signal_source" class="full-width __panel_item">
|
<q-tab-panel
|
||||||
signal_sourcesignal_sourcesignal_sourcesignal_source
|
name="signal_source"
|
||||||
|
class="full-width __panel_item q-pa-xs"
|
||||||
|
>
|
||||||
|
<q-scroll-area class="fit q-pr-md">
|
||||||
|
<draggable
|
||||||
|
class="row q-px-md"
|
||||||
|
v-model="signal_sources"
|
||||||
|
group="signal_source"
|
||||||
|
item-key="uuid"
|
||||||
|
:move="() => false"
|
||||||
|
@drop="onSignalSourceDrop($event)"
|
||||||
|
>
|
||||||
|
<template #item="{ element }">
|
||||||
|
<div class="col-4 q-pr-sm q-pb-sm">
|
||||||
|
<q-btn
|
||||||
|
class="col-row fit overflow-hidden bg-accent text-white"
|
||||||
|
:icon="getItemIcon(element.window_type)"
|
||||||
|
>
|
||||||
|
<span class="col q-ml-md text-left">
|
||||||
|
{{ element.name }}
|
||||||
|
</span>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</draggable>
|
||||||
|
</q-scroll-area>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
|
||||||
<q-tab-panel name="singal_polling" class="full-width __panel_item">
|
<q-tab-panel name="singal_polling" class="full-width __panel_item">
|
||||||
singal_pollingsingal_pollingsingal_pollingsingal_polling
|
singal_pollingsingal_pollingsingal_pollingsingal_polling
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
@ -132,14 +156,18 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, Ref, ref } from "vue";
|
import { defineComponent, Ref, ref, computed, watch } from "vue";
|
||||||
import { useQuasar } from "quasar";
|
import { useQuasar } from "quasar";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useStore } from "src/store";
|
import { useStore } from "src/store";
|
||||||
|
import draggable from "src/third_lib/vuedraggable/vuedraggable";
|
||||||
|
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
|
||||||
|
import { Common } from "src/common/Common";
|
||||||
|
import EventBus, { EventNamesDefine } from "src/common/EventBus";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "PadBottomBarPage",
|
name: "PadBottomBarPage",
|
||||||
components: {},
|
components: { draggable },
|
||||||
setup() {
|
setup() {
|
||||||
const $store = useStore();
|
const $store = useStore();
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
|
@ -148,14 +176,61 @@ export default defineComponent({
|
||||||
const paused = ref(false);
|
const paused = ref(false);
|
||||||
const muted = ref(false);
|
const muted = ref(false);
|
||||||
|
|
||||||
|
const signal_sources = computed({
|
||||||
|
get: () => $store.state.signal_sources,
|
||||||
|
set: (val) => null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modes = computed({
|
||||||
|
get: () => $store.state.modes,
|
||||||
|
set: (val) => null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const pollings = computed({
|
||||||
|
get: () => $store.state.pollings,
|
||||||
|
set: (val) => null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const plans = computed({
|
||||||
|
get: () => $store.state.plans,
|
||||||
|
set: (val) => null,
|
||||||
|
});
|
||||||
|
|
||||||
const tab = ref("signal_source");
|
const tab = ref("signal_source");
|
||||||
return {
|
return {
|
||||||
tab,
|
tab,
|
||||||
paused,
|
paused,
|
||||||
muted,
|
muted,
|
||||||
|
signal_sources,
|
||||||
|
modes,
|
||||||
|
pollings,
|
||||||
|
plans,
|
||||||
loga(a: any) {
|
loga(a: any) {
|
||||||
console.log(a);
|
console.log(a);
|
||||||
},
|
},
|
||||||
|
getItemIcon(item_type: string) {
|
||||||
|
return Common.getSignalSourceIcon(item_type);
|
||||||
|
},
|
||||||
|
onSignalSourceDrop(evt: any) {
|
||||||
|
console.log(evt);
|
||||||
|
if (
|
||||||
|
evt.data &&
|
||||||
|
evt.event &&
|
||||||
|
evt.event.changedTouches &&
|
||||||
|
evt.event.changedTouches.length
|
||||||
|
) {
|
||||||
|
const touchX = evt.event.changedTouches[0].pageX;
|
||||||
|
const touchY = evt.event.changedTouches[0].pageY;
|
||||||
|
EventBus.getInstance().emit(EventNamesDefine.DropToWall, {
|
||||||
|
data: evt.data,
|
||||||
|
type: "signal_source",
|
||||||
|
pos: {
|
||||||
|
x: touchX,
|
||||||
|
y: touchY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
}"
|
}"
|
||||||
class="wall_content"
|
class="wall_content"
|
||||||
>
|
>
|
||||||
<div id="windows" style="position: absolute">
|
<div id="windows" ref="dom_windows" style="position: absolute">
|
||||||
<vue3-resize-drag
|
<vue3-resize-drag
|
||||||
:w="item.width * ($refs.wall_content?.clientWidth ?? 0)"
|
:w="item.width * ($refs.wall_content?.clientWidth ?? 0)"
|
||||||
:h="item.height * ($refs.wall_content?.clientHeight ?? 0)"
|
:h="item.height * ($refs.wall_content?.clientHeight ?? 0)"
|
||||||
|
@ -189,6 +189,7 @@ export default defineComponent({
|
||||||
|
|
||||||
const wall: Ref<any> = ref(null);
|
const wall: Ref<any> = ref(null);
|
||||||
const wall_content: Ref<any> = ref(null);
|
const wall_content: Ref<any> = ref(null);
|
||||||
|
const dom_windows: Ref<any> = ref(null);
|
||||||
|
|
||||||
const file_manage_dialog: Ref<any> = ref(null);
|
const file_manage_dialog: Ref<any> = ref(null);
|
||||||
|
|
||||||
|
@ -534,6 +535,171 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface _IDropToWall {
|
||||||
|
data: any;
|
||||||
|
type: string;
|
||||||
|
pos: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EventBus.getInstance().on(
|
||||||
|
EventNamesDefine.DropToWall,
|
||||||
|
(evt: _IDropToWall) => {
|
||||||
|
if (evt && evt.data) {
|
||||||
|
// const x =
|
||||||
|
// evt.pos.x -
|
||||||
|
// (wall.value.parentElement?.offsetLeft ?? 0) -
|
||||||
|
// wall_content.value.offsetLeft;
|
||||||
|
// const y =
|
||||||
|
// evt.pos.y -
|
||||||
|
// (wall.value.parentElement?.offsetTop ?? 0) -
|
||||||
|
// wall_content.value.offsetTop;
|
||||||
|
|
||||||
|
const dom = document.elementFromPoint(
|
||||||
|
evt.pos.x,
|
||||||
|
evt.pos.y
|
||||||
|
) as HTMLElement;
|
||||||
|
|
||||||
|
const signal_sources = GlobalData.getInstance().signal_source.filter(
|
||||||
|
(item) => (item as any)?.uuid == evt.data.uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dom) {
|
||||||
|
if (dom.classList.contains("wall_item_flag")) {
|
||||||
|
// 开窗
|
||||||
|
// 不知道为什么有1像素的差别
|
||||||
|
const x =
|
||||||
|
(dom.offsetLeft - wall_content.value.offsetLeft - 1) /
|
||||||
|
wall_content.value.clientWidth;
|
||||||
|
const y =
|
||||||
|
(dom.offsetTop - wall_content.value.offsetTop - 1) /
|
||||||
|
wall_content.value.clientHeight;
|
||||||
|
const width = dom.offsetWidth / wall_content.value.clientWidth;
|
||||||
|
const height = dom.offsetHeight / wall_content.value.clientHeight;
|
||||||
|
|
||||||
|
switch (evt.type) {
|
||||||
|
case "polling":
|
||||||
|
GlobalData.getInstance()
|
||||||
|
.getCurrentClient()
|
||||||
|
?.openPolling(
|
||||||
|
new Protocol.OpenPollingRequestEntity(
|
||||||
|
evt.data.uuid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "signal_source" /**OpenPollingRequestEntity */:
|
||||||
|
if (signal_sources.length) {
|
||||||
|
const signal_source = signal_sources[0];
|
||||||
|
if (signal_source) {
|
||||||
|
GlobalData.getInstance()
|
||||||
|
.getCurrentClient()
|
||||||
|
?.openWindow(
|
||||||
|
new Protocol.OpenWindowRequestEntity(
|
||||||
|
signal_source.uuid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (dom.classList.contains("window_flag")) {
|
||||||
|
// 拖拽信号源替换窗口 后面还有一处替换窗口
|
||||||
|
const rep_uuid = dom.getAttribute("uuid");
|
||||||
|
if (rep_uuid) {
|
||||||
|
let window = $store.state.windows.find(
|
||||||
|
(item) => item.uuid == rep_uuid
|
||||||
|
);
|
||||||
|
if (window) {
|
||||||
|
let client = GlobalData.getInstance().getCurrentClient();
|
||||||
|
if (client) {
|
||||||
|
let x = window.x;
|
||||||
|
let y = window.y;
|
||||||
|
let width = window.width;
|
||||||
|
let height = window.height;
|
||||||
|
|
||||||
|
client.closeWindow(window.window_id);
|
||||||
|
const open_window_request =
|
||||||
|
new Protocol.OpenPollingRequestEntity(
|
||||||
|
evt.data.uuid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
open_window_request.muted = window.muted;
|
||||||
|
open_window_request.volume = window.volume;
|
||||||
|
open_window_request.paused = window.paused;
|
||||||
|
open_window_request.play_speed = window.play_speed;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (evt.type) {
|
||||||
|
case "polling":
|
||||||
|
{
|
||||||
|
const open_polling_request =
|
||||||
|
new Protocol.OpenPollingRequestEntity(
|
||||||
|
evt.data.uuid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
open_polling_request.muted = window.muted;
|
||||||
|
open_polling_request.volume = window.volume;
|
||||||
|
open_polling_request.paused = window.paused;
|
||||||
|
open_polling_request.play_speed = window.play_speed;
|
||||||
|
GlobalData.getInstance()
|
||||||
|
.getCurrentClient()
|
||||||
|
?.openPolling(open_polling_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "signal_source":
|
||||||
|
{
|
||||||
|
if (signal_sources.length) {
|
||||||
|
const signal_source = signal_sources[0];
|
||||||
|
if (signal_source) {
|
||||||
|
const open_window_request =
|
||||||
|
new Protocol.OpenWindowRequestEntity(
|
||||||
|
signal_source.uuid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
open_window_request.muted = window.muted;
|
||||||
|
open_window_request.volume = window.volume;
|
||||||
|
open_window_request.paused = window.paused;
|
||||||
|
open_window_request.play_speed =
|
||||||
|
window.play_speed;
|
||||||
|
client?.openWindow(open_window_request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wall,
|
wall,
|
||||||
file_manage_dialog,
|
file_manage_dialog,
|
||||||
|
@ -550,6 +716,7 @@ export default defineComponent({
|
||||||
last_context_menu_pos_y,
|
last_context_menu_pos_y,
|
||||||
windows,
|
windows,
|
||||||
wall_content,
|
wall_content,
|
||||||
|
dom_windows,
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
moveWindow,
|
moveWindow,
|
||||||
|
@ -699,18 +866,6 @@ export default defineComponent({
|
||||||
if (event && event.changedTouches && event.changedTouches.length) {
|
if (event && event.changedTouches && event.changedTouches.length) {
|
||||||
last_context_menu_pos_x.value = event.changedTouches[0].pageX;
|
last_context_menu_pos_x.value = event.changedTouches[0].pageX;
|
||||||
last_context_menu_pos_y.value = event.changedTouches[0].pageY;
|
last_context_menu_pos_y.value = event.changedTouches[0].pageY;
|
||||||
console.log(event.changedTouches[0]);
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
last_context_menu_pos_x.value -
|
|
||||||
(wall.value.parentElement?.offsetLeft ?? 0) -
|
|
||||||
wall_content.value.offsetLeft
|
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
last_context_menu_pos_y.value -
|
|
||||||
(wall.value.parentElement?.offsetTop ?? 0) -
|
|
||||||
wall_content.value.offsetTop
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async openWindowByLocalFile(event: MouseEvent) {
|
async openWindowByLocalFile(event: MouseEvent) {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
根据源仓库 https://github.com/zzz0908/vue3-resize-drag 修改而来
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { camelize } from "../util/string";
|
||||||
|
import { events, isReadOnly } from "./sortableEvents";
|
||||||
|
import { isHtmlAttribute } from "../util/tags";
|
||||||
|
|
||||||
|
function project(entries) {
|
||||||
|
return entries.reduce((res, [key, value]) => {
|
||||||
|
res[key] = value;
|
||||||
|
return res;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComponentAttributes({ $attrs, componentData = {} }) {
|
||||||
|
const attributes = project(
|
||||||
|
Object.entries($attrs).filter(([key, _]) => isHtmlAttribute(key))
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...attributes,
|
||||||
|
...componentData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSortableOption({ $attrs, callBackBuilder }) {
|
||||||
|
const options = project(getValidSortableEntries($attrs));
|
||||||
|
Object.entries(callBackBuilder).forEach(([eventType, eventBuilder]) => {
|
||||||
|
events[eventType].forEach(event => {
|
||||||
|
options[`on${event}`] = eventBuilder(event);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const draggable = `[data-draggable]${options.draggable || ""}`;
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
draggable
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidSortableEntries(value) {
|
||||||
|
return Object.entries(value)
|
||||||
|
.filter(([key, _]) => !isHtmlAttribute(key))
|
||||||
|
.map(([key, value]) => [camelize(key), value])
|
||||||
|
.filter(([key, _]) => !isReadOnly(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getComponentAttributes,
|
||||||
|
createSortableOption,
|
||||||
|
getValidSortableEntries
|
||||||
|
};
|
|
@ -0,0 +1,69 @@
|
||||||
|
const getHtmlElementFromNode = ({ el }) => el;
|
||||||
|
const addContext = (domElement, context) =>
|
||||||
|
(domElement.__draggable_context = context);
|
||||||
|
const getContext = domElement => domElement.__draggable_context;
|
||||||
|
|
||||||
|
class ComponentStructure {
|
||||||
|
constructor({
|
||||||
|
nodes: { header, default: defaultNodes, footer },
|
||||||
|
root,
|
||||||
|
realList
|
||||||
|
}) {
|
||||||
|
this.defaultNodes = defaultNodes;
|
||||||
|
this.children = [...header, ...defaultNodes, ...footer];
|
||||||
|
this.externalComponent = root.externalComponent;
|
||||||
|
this.rootTransition = root.transition;
|
||||||
|
this.tag = root.tag;
|
||||||
|
this.realList = realList;
|
||||||
|
}
|
||||||
|
|
||||||
|
get _isRootComponent() {
|
||||||
|
return this.externalComponent || this.rootTransition;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(h, attributes) {
|
||||||
|
const { tag, children, _isRootComponent } = this;
|
||||||
|
const option = !_isRootComponent ? children : { default: () => children };
|
||||||
|
return h(tag, attributes, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
updated() {
|
||||||
|
const { defaultNodes, realList } = this;
|
||||||
|
defaultNodes.forEach((node, index) => {
|
||||||
|
addContext(getHtmlElementFromNode(node), {
|
||||||
|
element: realList[index],
|
||||||
|
index
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnderlyingVm(domElement) {
|
||||||
|
return getContext(domElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
getVmIndexFromDomIndex(domIndex, element) {
|
||||||
|
const { defaultNodes } = this;
|
||||||
|
const { length } = defaultNodes;
|
||||||
|
const domChildren = element.children;
|
||||||
|
const domElement = domChildren.item(domIndex);
|
||||||
|
|
||||||
|
if (domElement === null) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
const context = getContext(domElement);
|
||||||
|
if (context) {
|
||||||
|
return context.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const firstDomListElement = getHtmlElementFromNode(defaultNodes[0]);
|
||||||
|
const indexFirstDomListElement = [...domChildren].findIndex(
|
||||||
|
element => element === firstDomListElement
|
||||||
|
);
|
||||||
|
return domIndex < indexFirstDomListElement ? 0 : length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ComponentStructure };
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { ComponentStructure } from "./componentStructure";
|
||||||
|
import { isHtmlTag, isTransition } from "../util/tags";
|
||||||
|
import { resolveComponent, TransitionGroup } from "vue";
|
||||||
|
|
||||||
|
function getSlot(slots, key) {
|
||||||
|
const slotValue = slots[key];
|
||||||
|
return slotValue ? slotValue() : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeNodes({ $slots, realList, getKey }) {
|
||||||
|
const normalizedList = realList || [];
|
||||||
|
const [header, footer] = ["header", "footer"].map(name =>
|
||||||
|
getSlot($slots, name)
|
||||||
|
);
|
||||||
|
const { item } = $slots;
|
||||||
|
if (!item) {
|
||||||
|
throw new Error("draggable element must have an item slot");
|
||||||
|
}
|
||||||
|
const defaultNodes = normalizedList.flatMap((element, index) =>
|
||||||
|
item({ element, index }).map(node => {
|
||||||
|
node.key = getKey(element);
|
||||||
|
node.props = { ...(node.props || {}), "data-draggable": true };
|
||||||
|
return node;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (defaultNodes.length !== normalizedList.length) {
|
||||||
|
throw new Error("Item slot must have only one child");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
default: defaultNodes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRootInformation(tag) {
|
||||||
|
const transition = isTransition(tag);
|
||||||
|
const externalComponent = !isHtmlTag(tag) && !transition;
|
||||||
|
return {
|
||||||
|
transition,
|
||||||
|
externalComponent,
|
||||||
|
tag: externalComponent
|
||||||
|
? resolveComponent(tag)
|
||||||
|
: transition
|
||||||
|
? TransitionGroup
|
||||||
|
: tag
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeComponentStructure({ $slots, tag, realList, getKey }) {
|
||||||
|
const nodes = computeNodes({ $slots, realList, getKey });
|
||||||
|
const root = getRootInformation(tag);
|
||||||
|
return new ComponentStructure({ nodes, root, realList });
|
||||||
|
}
|
||||||
|
|
||||||
|
export { computeComponentStructure };
|
|
@ -0,0 +1,18 @@
|
||||||
|
const manageAndEmit = ["Start", "Add", "Remove", "Update", "End"];
|
||||||
|
const emit = ["Choose", "Unchoose", "Sort", "Filter", "Clone"];
|
||||||
|
const manage = ["Move"];
|
||||||
|
const eventHandlerNames = [manage, manageAndEmit, emit]
|
||||||
|
.flatMap(events => events)
|
||||||
|
.map(evt => `on${evt}`);
|
||||||
|
|
||||||
|
const events = {
|
||||||
|
manage,
|
||||||
|
manageAndEmit,
|
||||||
|
emit
|
||||||
|
};
|
||||||
|
|
||||||
|
function isReadOnly(eventName) {
|
||||||
|
return eventHandlerNames.indexOf(eventName) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { events, isReadOnly };
|
|
@ -0,0 +1 @@
|
||||||
|
根据源仓库 https://github.com/SortableJS/vue.draggable.next 修改而来
|
|
@ -0,0 +1,9 @@
|
||||||
|
function getConsole() {
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
return window.console;
|
||||||
|
}
|
||||||
|
return global.console;
|
||||||
|
}
|
||||||
|
const console = getConsole();
|
||||||
|
|
||||||
|
export { console };
|
|
@ -0,0 +1,15 @@
|
||||||
|
function removeNode(node) {
|
||||||
|
if (node.parentElement !== null) {
|
||||||
|
node.parentElement.removeChild(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertNodeAt(fatherNode, node, position) {
|
||||||
|
const refNode =
|
||||||
|
position === 0
|
||||||
|
? fatherNode.children[0]
|
||||||
|
: fatherNode.children[position - 1].nextSibling;
|
||||||
|
fatherNode.insertBefore(node, refNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { insertNodeAt, removeNode };
|
|
@ -0,0 +1,12 @@
|
||||||
|
function cached(fn) {
|
||||||
|
const cache = Object.create(null);
|
||||||
|
return function cachedFn(str) {
|
||||||
|
const hit = cache[str];
|
||||||
|
return hit || (cache[str] = fn(str));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const regex = /-(\w)/g;
|
||||||
|
const camelize = cached(str => str.replace(regex, (_, c) => c.toUpperCase()));
|
||||||
|
|
||||||
|
export { camelize };
|
|
@ -0,0 +1,138 @@
|
||||||
|
const tags = [
|
||||||
|
"a",
|
||||||
|
"abbr",
|
||||||
|
"address",
|
||||||
|
"area",
|
||||||
|
"article",
|
||||||
|
"aside",
|
||||||
|
"audio",
|
||||||
|
"b",
|
||||||
|
"base",
|
||||||
|
"bdi",
|
||||||
|
"bdo",
|
||||||
|
"blockquote",
|
||||||
|
"body",
|
||||||
|
"br",
|
||||||
|
"button",
|
||||||
|
"canvas",
|
||||||
|
"caption",
|
||||||
|
"cite",
|
||||||
|
"code",
|
||||||
|
"col",
|
||||||
|
"colgroup",
|
||||||
|
"data",
|
||||||
|
"datalist",
|
||||||
|
"dd",
|
||||||
|
"del",
|
||||||
|
"details",
|
||||||
|
"dfn",
|
||||||
|
"dialog",
|
||||||
|
"div",
|
||||||
|
"dl",
|
||||||
|
"dt",
|
||||||
|
"em",
|
||||||
|
"embed",
|
||||||
|
"fieldset",
|
||||||
|
"figcaption",
|
||||||
|
"figure",
|
||||||
|
"footer",
|
||||||
|
"form",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"h4",
|
||||||
|
"h5",
|
||||||
|
"h6",
|
||||||
|
"head",
|
||||||
|
"header",
|
||||||
|
"hgroup",
|
||||||
|
"hr",
|
||||||
|
"html",
|
||||||
|
"i",
|
||||||
|
"iframe",
|
||||||
|
"img",
|
||||||
|
"input",
|
||||||
|
"ins",
|
||||||
|
"kbd",
|
||||||
|
"label",
|
||||||
|
"legend",
|
||||||
|
"li",
|
||||||
|
"link",
|
||||||
|
"main",
|
||||||
|
"map",
|
||||||
|
"mark",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menuitem",
|
||||||
|
"meta",
|
||||||
|
"meter",
|
||||||
|
"nav",
|
||||||
|
"noscript",
|
||||||
|
"object",
|
||||||
|
"ol",
|
||||||
|
"optgroup",
|
||||||
|
"option",
|
||||||
|
"output",
|
||||||
|
"p",
|
||||||
|
"param",
|
||||||
|
"picture",
|
||||||
|
"pre",
|
||||||
|
"progress",
|
||||||
|
"q",
|
||||||
|
"rb",
|
||||||
|
"rp",
|
||||||
|
"rt",
|
||||||
|
"rtc",
|
||||||
|
"ruby",
|
||||||
|
"s",
|
||||||
|
"samp",
|
||||||
|
"script",
|
||||||
|
"section",
|
||||||
|
"select",
|
||||||
|
"slot",
|
||||||
|
"small",
|
||||||
|
"source",
|
||||||
|
"span",
|
||||||
|
"strong",
|
||||||
|
"style",
|
||||||
|
"sub",
|
||||||
|
"summary",
|
||||||
|
"sup",
|
||||||
|
"svg",
|
||||||
|
"table",
|
||||||
|
"tbody",
|
||||||
|
"td",
|
||||||
|
"template",
|
||||||
|
"textarea",
|
||||||
|
"tfoot",
|
||||||
|
"th",
|
||||||
|
"thead",
|
||||||
|
"time",
|
||||||
|
"title",
|
||||||
|
"tr",
|
||||||
|
"track",
|
||||||
|
"u",
|
||||||
|
"ul",
|
||||||
|
"var",
|
||||||
|
"video",
|
||||||
|
"wbr"
|
||||||
|
];
|
||||||
|
|
||||||
|
function isHtmlTag(name) {
|
||||||
|
return tags.includes(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTransition(name) {
|
||||||
|
return ["transition-group", "TransitionGroup"].includes(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHtmlAttribute(value) {
|
||||||
|
return (
|
||||||
|
["id", "class", "role", "style"].includes(value) ||
|
||||||
|
value.startsWith("data-") ||
|
||||||
|
value.startsWith("aria-") ||
|
||||||
|
value.startsWith("on")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { isHtmlTag, isHtmlAttribute, isTransition };
|
|
@ -0,0 +1,74 @@
|
||||||
|
declare const draggableComponent: import("vue").DefineComponent<{
|
||||||
|
list: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
modelValue: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
itemKey: {
|
||||||
|
type: (FunctionConstructor | StringConstructor)[];
|
||||||
|
required: boolean;
|
||||||
|
};
|
||||||
|
clone: {
|
||||||
|
type: FunctionConstructor;
|
||||||
|
default: (original: any) => any;
|
||||||
|
};
|
||||||
|
tag: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
move: {
|
||||||
|
type: FunctionConstructor;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
componentData: {
|
||||||
|
type: ObjectConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
}, unknown, {
|
||||||
|
error: boolean;
|
||||||
|
}, {
|
||||||
|
realList(): any;
|
||||||
|
getKey(): any;
|
||||||
|
}, {
|
||||||
|
getUnderlyingVm(domElement: any): any;
|
||||||
|
getUnderlyingPotencialDraggableComponent(htmElement: any): any;
|
||||||
|
emitChanges(evt: any): void;
|
||||||
|
alterList(onList: any): void;
|
||||||
|
spliceList(): void;
|
||||||
|
updatePosition(oldIndex: any, newIndex: any): void;
|
||||||
|
getRelatedContextFromMoveEvent({ to, related }: {
|
||||||
|
to: any;
|
||||||
|
related: any;
|
||||||
|
}): any;
|
||||||
|
getVmIndexFromDomIndex(domIndex: any): any;
|
||||||
|
onDragStart(evt: any): void;
|
||||||
|
onDragAdd(evt: any): void;
|
||||||
|
onDragRemove(evt: any): void;
|
||||||
|
onDragUpdate(evt: any): void;
|
||||||
|
computeFutureIndex(relatedContext: any, evt: any): any;
|
||||||
|
onDragMove(evt: any, originalEvent: any): any;
|
||||||
|
onDragEnd(): void;
|
||||||
|
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any[], any, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
||||||
|
move: Function;
|
||||||
|
tag: string;
|
||||||
|
clone: Function;
|
||||||
|
list: unknown[];
|
||||||
|
modelValue: unknown[];
|
||||||
|
componentData: Record<string, any>;
|
||||||
|
} & {
|
||||||
|
itemKey?: string | Function;
|
||||||
|
}>, {
|
||||||
|
move: Function;
|
||||||
|
tag: string;
|
||||||
|
clone: Function;
|
||||||
|
list: unknown[];
|
||||||
|
modelValue: unknown[];
|
||||||
|
componentData: Record<string, any>;
|
||||||
|
}>;
|
||||||
|
export default draggableComponent;
|
|
@ -0,0 +1,365 @@
|
||||||
|
import Sortable from "sortablejs";
|
||||||
|
import { insertNodeAt, removeNode } from "./util/htmlHelper";
|
||||||
|
import { console } from "./util/console";
|
||||||
|
import {
|
||||||
|
getComponentAttributes,
|
||||||
|
createSortableOption,
|
||||||
|
getValidSortableEntries,
|
||||||
|
} from "./core/componentBuilderHelper";
|
||||||
|
import { computeComponentStructure } from "./core/renderHelper";
|
||||||
|
import { events } from "./core/sortableEvents";
|
||||||
|
import { h, defineComponent, nextTick } from "vue";
|
||||||
|
|
||||||
|
function emit(evtName, evtData) {
|
||||||
|
nextTick(() => this.$emit(evtName.toLowerCase(), evtData));
|
||||||
|
}
|
||||||
|
|
||||||
|
function manage(evtName) {
|
||||||
|
return (evtData, originalElement) => {
|
||||||
|
if (this.realList !== null) {
|
||||||
|
return this[`onDrag${evtName}`](evtData, originalElement);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function manageAndEmit(evtName) {
|
||||||
|
const delegateCallBack = manage.call(this, evtName);
|
||||||
|
return (evtData, originalElement) => {
|
||||||
|
delegateCallBack.call(this, evtData, originalElement);
|
||||||
|
emit.call(this, evtName, evtData);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let draggingElement = null;
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
itemKey: {
|
||||||
|
type: [String, Function],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
clone: {
|
||||||
|
type: Function,
|
||||||
|
default: (original) => {
|
||||||
|
return original;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
type: String,
|
||||||
|
default: "div",
|
||||||
|
},
|
||||||
|
move: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
componentData: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const emits = [
|
||||||
|
"update:modelValue",
|
||||||
|
"change",
|
||||||
|
"drop",
|
||||||
|
...[...events.manageAndEmit, ...events.emit].map((evt) => evt.toLowerCase()),
|
||||||
|
];
|
||||||
|
|
||||||
|
const draggableComponent = defineComponent({
|
||||||
|
name: "draggable",
|
||||||
|
|
||||||
|
inheritAttrs: false,
|
||||||
|
|
||||||
|
props,
|
||||||
|
|
||||||
|
emits,
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
error: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
try {
|
||||||
|
this.error = false;
|
||||||
|
const { $slots, $attrs, tag, componentData, realList, getKey } = this;
|
||||||
|
const componentStructure = computeComponentStructure({
|
||||||
|
$slots,
|
||||||
|
tag,
|
||||||
|
realList,
|
||||||
|
getKey,
|
||||||
|
});
|
||||||
|
this.componentStructure = componentStructure;
|
||||||
|
const attributes = getComponentAttributes({ $attrs, componentData });
|
||||||
|
return componentStructure.render(h, attributes);
|
||||||
|
} catch (err) {
|
||||||
|
this.error = true;
|
||||||
|
return h("pre", { style: { color: "red" } }, err.stack);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.list !== null && this.modelValue !== null) {
|
||||||
|
console.error(
|
||||||
|
"modelValue and list props are mutually exclusive! Please set one or another."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
if (this.error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const { $attrs, $el, componentStructure } = this;
|
||||||
|
componentStructure.updated();
|
||||||
|
|
||||||
|
const sortableOptions = createSortableOption({
|
||||||
|
$attrs,
|
||||||
|
callBackBuilder: {
|
||||||
|
manageAndEmit: (event) => manageAndEmit.call(this, event),
|
||||||
|
emit: (event) => emit.bind(this, event),
|
||||||
|
manage: (event) => manage.call(this, event),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const targetDomElement = $el.nodeType === 1 ? $el : $el.parentElement;
|
||||||
|
|
||||||
|
function AfxTestPlugin() {
|
||||||
|
function AfxTest() {
|
||||||
|
this.defaults = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AfxTest.prototype = {
|
||||||
|
dropGlobal: function dropGlobal(evt) {
|
||||||
|
console.log("oooooooooooooooooooo");
|
||||||
|
console.log(evt);
|
||||||
|
try {
|
||||||
|
self.$emit("drop", {
|
||||||
|
data: evt.dragEl.__draggable_context.element,
|
||||||
|
event: evt.originalEvent,
|
||||||
|
});
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function _extends() {
|
||||||
|
_extends =
|
||||||
|
Object.assign ||
|
||||||
|
function (target) {
|
||||||
|
for (var i = 1; i < arguments.length; i++) {
|
||||||
|
var source = arguments[i];
|
||||||
|
|
||||||
|
for (var key in source) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||||
|
target[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
|
||||||
|
return _extends.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return _extends(AfxTest, {
|
||||||
|
pluginName: "afxtest",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Sortable.mount(new AfxTestPlugin());
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
sortableOptions.fallbackOnBody = true;
|
||||||
|
this._sortable = new Sortable(targetDomElement, sortableOptions);
|
||||||
|
this.targetDomElement = targetDomElement;
|
||||||
|
targetDomElement.__draggable_component__ = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
updated() {
|
||||||
|
this.componentStructure.updated();
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeUnmount() {
|
||||||
|
if (this._sortable !== undefined) this._sortable.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
realList() {
|
||||||
|
const { list } = this;
|
||||||
|
return list ? list : this.modelValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
getKey() {
|
||||||
|
const { itemKey } = this;
|
||||||
|
if (typeof itemKey === "function") {
|
||||||
|
return itemKey;
|
||||||
|
}
|
||||||
|
return (element) => element[itemKey];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
$attrs: {
|
||||||
|
handler(newOptionValue) {
|
||||||
|
const { _sortable } = this;
|
||||||
|
if (!_sortable) return;
|
||||||
|
getValidSortableEntries(newOptionValue).forEach(([key, value]) => {
|
||||||
|
_sortable.option(key, value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getUnderlyingVm(domElement) {
|
||||||
|
return this.componentStructure.getUnderlyingVm(domElement) || null;
|
||||||
|
},
|
||||||
|
|
||||||
|
getUnderlyingPotencialDraggableComponent(htmElement) {
|
||||||
|
//TODO check case where you need to see component children
|
||||||
|
return htmElement.__draggable_component__;
|
||||||
|
},
|
||||||
|
|
||||||
|
emitChanges(evt) {
|
||||||
|
nextTick(() => this.$emit("change", evt));
|
||||||
|
},
|
||||||
|
|
||||||
|
alterList(onList) {
|
||||||
|
if (this.list) {
|
||||||
|
onList(this.list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newList = [...this.modelValue];
|
||||||
|
onList(newList);
|
||||||
|
this.$emit("update:modelValue", newList);
|
||||||
|
},
|
||||||
|
|
||||||
|
spliceList() {
|
||||||
|
const spliceList = (list) => list.splice(...arguments);
|
||||||
|
this.alterList(spliceList);
|
||||||
|
},
|
||||||
|
|
||||||
|
updatePosition(oldIndex, newIndex) {
|
||||||
|
const updatePosition = (list) =>
|
||||||
|
list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]);
|
||||||
|
this.alterList(updatePosition);
|
||||||
|
},
|
||||||
|
|
||||||
|
getRelatedContextFromMoveEvent({ to, related }) {
|
||||||
|
const component = this.getUnderlyingPotencialDraggableComponent(to);
|
||||||
|
if (!component) {
|
||||||
|
return { component };
|
||||||
|
}
|
||||||
|
const list = component.realList;
|
||||||
|
const context = { list, component };
|
||||||
|
if (to !== related && list) {
|
||||||
|
const destination = component.getUnderlyingVm(related) || {};
|
||||||
|
return { ...destination, ...context };
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
},
|
||||||
|
|
||||||
|
getVmIndexFromDomIndex(domIndex) {
|
||||||
|
return this.componentStructure.getVmIndexFromDomIndex(
|
||||||
|
domIndex,
|
||||||
|
this.targetDomElement
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragStart(evt) {
|
||||||
|
this.context = this.getUnderlyingVm(evt.item);
|
||||||
|
evt.item._underlying_vm_ = this.clone(this.context.element);
|
||||||
|
draggingElement = evt.item;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragAdd(evt) {
|
||||||
|
const element = evt.item._underlying_vm_;
|
||||||
|
if (element === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeNode(evt.item);
|
||||||
|
const newIndex = this.getVmIndexFromDomIndex(evt.newIndex);
|
||||||
|
this.spliceList(newIndex, 0, element);
|
||||||
|
const added = { element, newIndex };
|
||||||
|
this.emitChanges({ added });
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragRemove(evt) {
|
||||||
|
insertNodeAt(this.$el, evt.item, evt.oldIndex);
|
||||||
|
if (evt.pullMode === "clone") {
|
||||||
|
removeNode(evt.clone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { index: oldIndex, element } = this.context;
|
||||||
|
this.spliceList(oldIndex, 1);
|
||||||
|
const removed = { element, oldIndex };
|
||||||
|
this.emitChanges({ removed });
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragUpdate(evt) {
|
||||||
|
removeNode(evt.item);
|
||||||
|
insertNodeAt(evt.from, evt.item, evt.oldIndex);
|
||||||
|
const oldIndex = this.context.index;
|
||||||
|
const newIndex = this.getVmIndexFromDomIndex(evt.newIndex);
|
||||||
|
this.updatePosition(oldIndex, newIndex);
|
||||||
|
const moved = { element: this.context.element, oldIndex, newIndex };
|
||||||
|
this.emitChanges({ moved });
|
||||||
|
},
|
||||||
|
|
||||||
|
computeFutureIndex(relatedContext, evt) {
|
||||||
|
if (!relatedContext.element) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const domChildren = [...evt.to.children].filter(
|
||||||
|
(el) => el.style["display"] !== "none"
|
||||||
|
);
|
||||||
|
const currentDomIndex = domChildren.indexOf(evt.related);
|
||||||
|
const currentIndex =
|
||||||
|
relatedContext.component.getVmIndexFromDomIndex(currentDomIndex);
|
||||||
|
const draggedInList = domChildren.indexOf(draggingElement) !== -1;
|
||||||
|
return draggedInList || !evt.willInsertAfter
|
||||||
|
? currentIndex
|
||||||
|
: currentIndex + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragMove(evt, originalEvent) {
|
||||||
|
const { move, realList } = this;
|
||||||
|
if (!move || !realList) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedContext = this.getRelatedContextFromMoveEvent(evt);
|
||||||
|
const futureIndex = this.computeFutureIndex(relatedContext, evt);
|
||||||
|
const draggedContext = {
|
||||||
|
...this.context,
|
||||||
|
futureIndex,
|
||||||
|
};
|
||||||
|
const sendEvent = {
|
||||||
|
...evt,
|
||||||
|
relatedContext,
|
||||||
|
draggedContext,
|
||||||
|
};
|
||||||
|
return move(sendEvent, originalEvent);
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragEnd() {
|
||||||
|
draggingElement = null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default draggableComponent;
|
|
@ -6669,6 +6669,11 @@ sort-keys@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-plain-obj "^1.0.0"
|
is-plain-obj "^1.0.0"
|
||||||
|
|
||||||
|
sortablejs@^1.15.0:
|
||||||
|
version "1.15.0"
|
||||||
|
resolved "https://registry.npmmirror.com/sortablejs/-/sortablejs-1.15.0.tgz#53230b8aa3502bb77a29e2005808ffdb4a5f7e2a"
|
||||||
|
integrity sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==
|
||||||
|
|
||||||
source-list-map@^2.0.0:
|
source-list-map@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npmmirror.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
resolved "https://registry.npmmirror.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||||
|
|
Loading…
Reference in New Issue