Skip to content
Snippets Groups Projects
Commit f689a3fd authored by Adam Procter's avatar Adam Procter
Browse files

nodes in sandbox

parent 878ae84f
No related branches found
No related tags found
No related merge requests found
<template>
<div ref="nodes" class="node">
<div v-for="(value, index) in configPositions" v-bind:key="index">
<vue-draggable-resizable
class="innernode"
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
@activated="onActivated"
@dragging="onDrag"
@resizing="onResize"
@dragstop="onDragstop"
@resizestop="onResizestop"
:drag-cancel="'.drag-cancel'"
style="background-color: rgb(205, 234, 255);"
>
<form>
<div v-if="readmode == false">
<div v-for="value in myNodes" v-bind:key="value.node_id">
<!-- <div v-if="readmode == false"> -->
<textarea
v-if="nodeid == value.node_id"
@focus="editTrue(true)"
@blur="editTrue(false)"
autofocus
@input="editNode"
v-model="value.node_text"
:id="nodeid"
class="drag-cancel"
ref="nodetext"
placeholder="Idea goes here!"
></textarea>
<div v-if="toolmode == 'move'">
<!-- make draggable false as we are panning around -->
<vue-draggable-resizable
class="innernode"
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
:draggable="false"
style="background-color: rgb(205, 234, 255);"
>
<form>
<div v-if="readmode == false">
<div v-for="value in myNodes" v-bind:key="value.node_id">
<!-- <div v-if="readmode == false"> -->
<textarea
v-if="nodeid == value.node_id"
@focus="editTrue(true)"
@blur="editTrue(false)"
autofocus
@input="editNode"
v-model="value.node_text"
:id="nodeid"
class="drag-cancel"
ref="nodetext"
placeholder="Idea goes here!"
></textarea>
</div>
</div>
</div>
<!-- FIXME: What is this doing below now ? Looks old -->
<div v-else>
<p :id="nodeid" :inner-html.prop="nodetext | marked">
{{ nodeid }}
</p>
</div>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<p class="info">*markdown supported</p>
<div class="btn-row">
<BaseButton buttonClass="danger" @click="deleteFlag()"
>Delete</BaseButton
>
<BaseButton class="read" buttonClass="action" @click="readFlag()">{{
mode
}}</BaseButton>
</div>
</form>
</vue-draggable-resizable>
<!-- FIXME: What is this doing below now ? Looks old -->
<div v-else>
<p :id="nodeid" :inner-html.prop="nodetext | marked">
{{ nodeid }}
</p>
</div>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<p class="info">*markdown supported</p>
<div class="btn-row">
<BaseButton buttonClass="danger" @click="deleteFlag()"
>Delete</BaseButton
>
<BaseButton
class="read"
buttonClass="action"
@click="readFlag()"
>{{ mode }}</BaseButton
>
</div>
</form>
</vue-draggable-resizable>
</div>
<div v-else>
<vue-draggable-resizable
class="innernode"
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
@activated="onActivated"
@dragging="onDrag"
@resizing="onResize"
@dragstop="onDragstop"
@resizestop="onResizestop"
:drag-cancel="'.drag-cancel'"
style="background-color: rgb(205, 234, 255);"
>
<form>
<div v-if="readmode == false">
<div v-for="value in myNodes" v-bind:key="value.node_id">
<!-- <div v-if="readmode == false"> -->
<textarea
v-if="nodeid == value.node_id"
@focus="editTrue(true)"
@blur="editTrue(false)"
autofocus
@input="editNode"
v-model="value.node_text"
:id="nodeid"
class="drag-cancel"
ref="nodetext"
placeholder="Idea goes here!"
></textarea>
</div>
</div>
<!-- FIXME: What is this doing below now ? Looks old -->
<div v-else>
<p :id="nodeid" :inner-html.prop="nodetext | marked">
{{ nodeid }}
</p>
</div>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<p class="info">*markdown supported</p>
<div class="btn-row">
<BaseButton buttonClass="danger" @click="deleteFlag()"
>Delete</BaseButton
>
<BaseButton
class="read"
buttonClass="action"
@click="readFlag()"
>{{ mode }}</BaseButton
>
</div>
</form>
</vue-draggable-resizable>
</div>
</div>
</div>
</template>
......@@ -76,19 +144,19 @@ export default {
nodetext: String,
nodewidth: Number,
nodeheight: Number,
deleted: Boolean
deleted: Boolean,
},
data() {
return {
pickupz: 99,
readmode: false,
mode: 'Read'
mode: 'Read',
}
},
filters: {
marked: marked
marked: marked,
},
// FIXME: how do we know how to focus on the newest node ?
......@@ -106,9 +174,10 @@ export default {
// },
computed: mapState({
myNodes: state => state.myNodes,
configPositions: state => state.configPositions,
configEmoji: state => state.configEmoji
myNodes: (state) => state.myNodes,
configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
toolmode: (state) => state.ui.mode,
}),
methods: {
onActivated() {
......@@ -146,7 +215,7 @@ export default {
y,
width,
height,
zindex
zindex,
})
},
onDrag(x, y) {
......@@ -172,7 +241,7 @@ export default {
y,
width,
height,
zindex
zindex,
})
},
......@@ -198,8 +267,8 @@ export default {
this.readmode = true
this.mode = 'Edit'
}
}
}
},
},
}
</script>
......
<template>
<div ref="othernodes" class="node">
<div v-for="(value, index) in configPositions" v-bind:key="index">
<vue-draggable-resizable
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
@activated="onActivated"
@dragging="onDrag"
@resizing="onResize"
@dragstop="onDragstop"
@resizestop="onResizestop"
style="border: 1px solid black; background-color: rgb(205, 234, 255);"
>
<p :id="nodeid" :inner-html.prop="nodetext | marked">{{ nodeid }}</p>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<div class="react" v-if="nodeid != undefined">
<h2>React</h2>
<div class="eeee">
<input :value="nodeid" name="id" readonly hidden />
<input
id="emojifield"
class="regular-input"
v-model="input"
readonly
/>
<div v-if="toolmode == 'move'">
<!-- make draggable false as we are panning around -->
<vue-draggable-resizable
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
@activated="onActivated"
@dragging="onDrag"
@resizing="onResize"
:draggable="false"
@dragstop="onDragstop"
@resizestop="onResizestop"
style="border: 1px solid black; background-color: rgb(205, 234, 255);"
>
<p :id="nodeid" :inner-html.prop="nodetext | marked">{{ nodeid }}</p>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<div class="react" v-if="nodeid != undefined">
<h2>React</h2>
<div class="eeee">
<input :value="nodeid" name="id" readonly hidden />
<input
id="emojifield"
class="regular-input"
v-model="input"
readonly
/>
<emoji-picker @emoji="append" :search="search">
<div
class="emoji-invoker"
slot="emoji-invoker"
slot-scope="{ events: { click: clickEvent } }"
@click.stop="clickEvent"
>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
<emoji-picker @emoji="append" :search="search">
<div
class="emoji-invoker"
slot="emoji-invoker"
slot-scope="{ events: { click: clickEvent } }"
@click.stop="clickEvent"
>
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
/>
</svg>
</div>
<div slot="emoji-picker" slot-scope="{ emojis, insert, display }">
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
/>
</svg>
</div>
<div
class="emoji-picker"
:style="{ top: display.y + 'px', left: display.x + 'px' }"
slot="emoji-picker"
slot-scope="{ emojis, insert, display }"
>
<div class="emoji-picker__search">
<input type="text" v-model="search" v-focus />
<div
class="emoji-picker"
:style="{ top: display.y + 'px', left: display.x + 'px' }"
>
<div class="emoji-picker__search">
<input type="text" v-model="search" v-focus />
</div>
<div>
<div
v-for="(emojiGroup, category) in emojis"
:key="category"
>
<h5>{{ category }}</h5>
<div class="emojis">
<span
v-for="(emoji, emojiName) in emojiGroup"
:key="emojiName"
@click="insert(emoji)"
:title="emojiName"
>{{ emoji }}</span
>
</div>
</div>
</div>
</div>
<div>
<div
v-for="(emojiGroup, category) in emojis"
:key="category"
>
<h5>{{ category }}</h5>
<div class="emojis">
<span
v-for="(emoji, emojiName) in emojiGroup"
:key="emojiName"
@click="insert(emoji)"
:title="emojiName"
>{{ emoji }}</span
>
</div>
</emoji-picker>
<BaseButton buttonClass="action" @click="sentReact()"
>Send Reaction</BaseButton
>
</div>
</div>
</vue-draggable-resizable>
</div>
<div v-else>
<!-- make draggable false as we are panning around -->
<vue-draggable-resizable
v-if="nodeid == value.node_id"
:w="value.width"
:h="value.height"
:x="value.x_pos"
:y="value.y_pos"
:z="value.z_index"
@activated="onActivated"
@dragging="onDrag"
@resizing="onResize"
@dragstop="onDragstop"
@resizestop="onResizestop"
style="border: 1px solid black; background-color: rgb(205, 234, 255);"
>
<p :id="nodeid" :inner-html.prop="nodetext | marked">{{ nodeid }}</p>
<h3>Reactions</h3>
<div v-for="(emojis, index) in configEmoji" :key="index">
<p class="allemoji" v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
<div class="react" v-if="nodeid != undefined">
<h2>React</h2>
<div class="eeee">
<input :value="nodeid" name="id" readonly hidden />
<input
id="emojifield"
class="regular-input"
v-model="input"
readonly
/>
<emoji-picker @emoji="append" :search="search">
<div
class="emoji-invoker"
slot="emoji-invoker"
slot-scope="{ events: { click: clickEvent } }"
@click.stop="clickEvent"
>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
/>
</svg>
</div>
<div
slot="emoji-picker"
slot-scope="{ emojis, insert, display }"
>
<div
class="emoji-picker"
:style="{ top: display.y + 'px', left: display.x + 'px' }"
>
<div class="emoji-picker__search">
<input type="text" v-model="search" v-focus />
</div>
<div>
<div
v-for="(emojiGroup, category) in emojis"
:key="category"
>
<h5>{{ category }}</h5>
<div class="emojis">
<span
v-for="(emoji, emojiName) in emojiGroup"
:key="emojiName"
@click="insert(emoji)"
:title="emojiName"
>{{ emoji }}</span
>
</div>
</div>
</div>
</div>
</div>
</div>
</emoji-picker>
<BaseButton buttonClass="action" @click="sentReact()"
>Send Reaction</BaseButton
>
</emoji-picker>
<BaseButton buttonClass="action" @click="sentReact()"
>Send Reaction</BaseButton
>
</div>
</div>
</div>
</vue-draggable-resizable>
</vue-draggable-resizable>
</div>
</div>
</div>
</template>
......@@ -99,32 +198,33 @@ export default {
name: 'otherNodeslayer',
components: {
EmojiPicker
EmojiPicker,
},
props: {
nodeid: String,
nodetext: String,
nodewidth: Number,
nodeheight: Number
nodeheight: Number,
},
data() {
return {
input: '',
search: '',
pickupz: 99
pickupz: 99,
}
},
filters: {
marked: marked
marked: marked,
},
mounted() {},
computed: mapState({
otherNodes: state => state.otherNodes,
configPositions: state => state.configPositions,
configEmoji: state => state.configEmoji
otherNodes: (state) => state.otherNodes,
configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
toolmode: (state) => state.ui.mode,
}),
methods: {
onActivated() {
......@@ -162,7 +262,7 @@ export default {
y,
width,
height,
zindex
zindex,
})
},
onDrag(x, y) {
......@@ -188,7 +288,7 @@ export default {
y,
width,
height,
zindex
zindex,
})
},
append(emoji) {
......@@ -199,19 +299,19 @@ export default {
nodeid = this.nodeid
this.$store.dispatch('addEmoji', {
nodeid,
emojitext
emojitext,
})
this.input = ''
}
},
},
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
},
},
},
}
</script>
......
<style scoped>
.outer {
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
background-color: rgb(245, 245, 245);
}
.inner {
width: 2000px;
height: 2000px;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
background-size: 40px 40px;
background-color: rgb(245, 245, 245);
border: 1px solid rgba(0, 0, 0, 0.25);
background-image: radial-gradient(
circle,
rgba(0, 0, 0, 0.5) 1px,
rgba(0, 0, 0, 0) 1px
);
}
.inner.active {
touch-action: none;
-ms-touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
</style>
<template>
<div
v-if="mode == 'move'"
ref="container"
class="outer"
v-on:wheel.capture="onWheel"
......@@ -54,7 +22,23 @@
transform: `translate(${translation.x}px, ${translation.y}px) scale(${scale})`,
}"
>
{{ JSON.stringify(interaction) }}
<!-- {{ JSON.stringify(interaction) }} -->
<!-- view paramaters not being utilised ? -->
<!-- {{ mode }} -->
<slot />
</div>
</div>
<div v-else ref="container" class="outer">
<div
ref="innerContainer"
v-bind:class="{ inner: true, active: true }"
v-bind:style="{
width: `${width}px`,
height: `${height}px`,
transform: `translate(${translation.x}px, ${translation.y}px) scale(${scale})`,
}"
>
<slot />
</div>
</div>
......@@ -78,6 +62,7 @@ export default {
computed: {
...mapState({
interaction: (state) => state.ui.interaction,
mode: (state) => state.ui.mode,
}),
},
props: {
......@@ -219,3 +204,36 @@ export default {
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.outer {
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
background-color: rgb(245, 245, 245);
}
.inner {
width: 2000px;
height: 2000px;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
background-size: 40px 40px;
background-color: rgb(245, 245, 245);
/* border: 1px solid rgba(0, 0, 0, 0.25); */
background-image: radial-gradient(
circle,
rgba(0, 0, 0, 0.5) 1px,
rgba(0, 0, 0, 0) 1px
);
}
.inner.active {
touch-action: none;
-ms-touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
</style>
......@@ -17,7 +17,7 @@ const store = {
links: [],
nodes: [],
},
mode: 'move',
mode: 'select',
scale: 1,
translation: {
x: 0,
......
......@@ -6,8 +6,6 @@
v-bind:scale="scale"
v-bind:translation="translation"
>
<h1>Nodes</h1>
<OtherNodeslayer
v-for="value in otherNodes"
v-bind:key="value.node_id"
......@@ -21,12 +19,12 @@
v-bind:nodetext="value.node_text"
/>
</PanZoomContainer>
<SelectionLayer
<!-- <SelectionLayer
v-if="domContainerReady"
v-bind:shape="interaction.shape"
v-bind:width="elementWidth"
v-bind:height="elementHeight"
/>
/> -->
<ModeToolbar />
<ViewToolbar />
</div>
......@@ -38,11 +36,13 @@ import NodesLayer from '@/components/NodesLayer'
import OtherNodeslayer from '@/components/OtherNodeslayer.vue'
import ModeToolbar from '@/experimental/ModeToolbar'
import ViewToolbar from '@/experimental/ViewToolbar'
import SelectionLayer from '@/experimental/layers/SelectionLayer'
// import SelectionLayer from '@/experimental/layers/SelectionLayer'
import { shortcutsMixin } from '@/components/mixins/shortcutsMixin.js'
import { mapGetters, mapState } from 'vuex'
export default {
name: 'Sandbox',
mixins: [shortcutsMixin],
data: function () {
return {
elementWidth: undefined,
......@@ -61,6 +61,7 @@ export default {
translation: (state) => state.ui.translation,
myNodes: (state) => state.myNodes,
otherNodes: (state) => state.otherNodes,
shortcutstate: (state) => state.shortcutstate,
}),
...mapGetters({
activeMode: 'ui/activeMode',
......@@ -71,6 +72,19 @@ export default {
window.addEventListener('resize', this.handleResize)
this.handleResize()
},
created() {
if (typeof window !== 'undefined') {
document.addEventListener('keydown', this.handleKeyPress)
}
},
beforeDestroy() {
if (typeof window !== 'undefined') {
document.removeEventListener('keydown', this.handleKeyPress)
}
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
......@@ -80,12 +94,17 @@ export default {
this.elementWidth = offsetWidth
this.elementHeight = offsetHeight
},
// This is here to support the shortcuts
addNode() {
this.$store.dispatch('addNode')
},
},
components: {
ModeToolbar,
ViewToolbar,
PanZoomContainer,
SelectionLayer,
// SelectionLayer,
NodesLayer,
OtherNodeslayer,
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment