96 lines
2.1 KiB
Vue
96 lines
2.1 KiB
Vue
<template>
|
|
<VueFlow
|
|
v-model:nodes="nodes"
|
|
v-model:edges="edges"
|
|
:apply-default="false"
|
|
:connection-mode="ConnectionMode.Strict"
|
|
:connection-line-type="ConnectionLineType.Step"
|
|
>
|
|
<Background />
|
|
|
|
<RemoteCursor
|
|
v-for="client in remoteClients"
|
|
:key="client.id"
|
|
:username="client.id.toString()"
|
|
:position="client.cursorPosition ?? { x: 0, y: 0 }"
|
|
:style="{
|
|
backgroundColor: client.color,
|
|
zIndex: 999,
|
|
}"
|
|
/>
|
|
|
|
<div v-if="clientId" class="info">
|
|
Ваш ID: {{ clientId }} | Клиентов: {{ clients.length }}
|
|
</div>
|
|
</VueFlow>
|
|
|
|
<div class="menu">
|
|
<button @click="addRandomNode('input')">
|
|
+ Вход
|
|
</button>
|
|
<button @click="addRandomNode()">
|
|
+ Обычная
|
|
</button>
|
|
<button @click="addRandomNode('output')">
|
|
+ Выход
|
|
</button>
|
|
<button @click="reset">
|
|
Сбросить
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { Edge, Node } from '@vue-flow/core'
|
|
import { Background } from '@vue-flow/background'
|
|
import { ConnectionLineType, ConnectionMode, useVueFlow, VueFlow } from '@vue-flow/core'
|
|
import { ref } from 'vue'
|
|
import { useCollaborativeFlow } from '../composables/useCollaborativeFlow.js'
|
|
import RemoteCursor from './RemoteCursor.vue'
|
|
|
|
const props = defineProps<{
|
|
diagramId: string
|
|
}>()
|
|
|
|
const nodes = ref<Node[]>([])
|
|
const edges = ref<Edge[]>([])
|
|
|
|
const { addNodes, onConnect, addEdges } = useVueFlow()
|
|
|
|
onConnect(addEdges)
|
|
|
|
const { clientId, clients, remoteClients, reset } = useCollaborativeFlow(() => props.diagramId)
|
|
|
|
function addRandomNode(type?: Node['type']) {
|
|
addNodes({
|
|
id: Math.random().toString(),
|
|
type,
|
|
position: { x: Math.random() * 500, y: Math.random() * 500 },
|
|
data: {
|
|
label: 'Random Node',
|
|
hello: 'world',
|
|
},
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.menu {
|
|
position: fixed;
|
|
top: 16px;
|
|
right: 16px;
|
|
width: 160px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.info {
|
|
position: fixed;
|
|
bottom: 16px;
|
|
right: 16px;
|
|
pointer-events: none;
|
|
z-index: 1000;
|
|
}
|
|
</style>
|