Skip to content

Commit c5c4b1b

Browse files
committed
Merge branch 'keyla/dragAndDrop' into Johnny
2 parents 59958e2 + bed0221 commit c5c4b1b

File tree

8 files changed

+241
-16
lines changed

8 files changed

+241
-16
lines changed

src/components/composables/useCreateComponent.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export function useCreateComponent(importObj) {
4141
state: [],
4242
parent: {},
4343
isActive: false,
44+
idDrag: '',
45+
idDrop: '',
4446
color: "#ffffff85",
4547
htmlAttributes:{
4648
class:"",

src/components/left-sidebar/ComponentTab/CreateMenuHTMLQueue.vue

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Description:
55
-->
66

77
<template>
8-
<section class="html-queue">
8+
<section class="html-queue" @dragover="dragOver($event), false">
99
<div
1010
group="people"
1111
class="list-group"
@@ -14,13 +14,21 @@ Description:
1414
:class="activeHTML === element[2] ? 'list-group-item-selected' : 'list-group-item'"
1515
@dblclick.self="setActiveElement(element)"
1616
v-for="(element) in renderList" :key="element[1] + Date.now()"
17+
@dragenter="dragEnter($event, element[2])"
1718
>
18-
<i v-if='activeComponent === "" || exceptions.includes(element[0]) '></i>
19-
<i v-else class="fas fa fa-angle-double-down fa-md" @click="setLayer({text: element[0], id: element[2]})"></i>
20-
{{ element[0] }}
21-
<i class="fas fa fa-trash fa-md" @click.self="deleteElement([element[1],element[2]])"></i>
19+
<div
20+
:class="activeHTML === element[2] ? 'list-group-item-selected' : 'list-group-item'"
21+
@dblclick.self="setActiveElement(element)"
22+
@dragstart="startDrag($event, element[2])"
23+
@dragend="endDrag($event)"
24+
draggable="true"
25+
>
26+
<i v-if='activeComponent === "" || exceptions.includes(element[0]) '></i>
27+
<i v-else class="fas fa fa-angle-double-down fa-md" @click="setLayer({text: element[0], id: element[2]})"></i>
28+
{{ element[0] }}
29+
<i class="fas fa fa-trash fa-md" @click.self="deleteElement([element[1],element[2]])"></i>
30+
</div>
2231
</div>
23-
2432
</div>
2533
</section>
2634
</template>
@@ -78,7 +86,7 @@ export default {
7886
7987
},
8088
methods: {
81-
...mapActions(['setActiveHTML', 'setActiveLayer', 'upOneLayer']),
89+
...mapActions(['setActiveHTML', 'setActiveLayer', 'upOneLayer', 'setSelectedIdDrag', 'setIdDrag', 'setSelectedIdDrop', 'setIdDrop', 'dragDropSortHtmlElements', 'dragDropSortSelectedHtmlElements']),
8290
deleteElement (id) {
8391
if (this.activeComponent === '') this.$store.dispatch(deleteSelectedElement, id[0])
8492
else this.$store.dispatch(deleteFromComponentHtmlList, id[1])
@@ -95,7 +103,33 @@ export default {
95103
if (this.activeLayer.id !== '') {
96104
this.upOneLayer(this.activeLayer.id)
97105
}
98-
}
106+
},
107+
//METHODS FOR DRAG-AND-DROP
108+
startDrag (event, id) {
109+
//add a class of 'currentlyDragging' to the HTML element that you are currently dragging
110+
event.target.classList.add('currentlyDragging')
111+
const dragId = id;
112+
if (this.activeComponent === '') this.setSelectedIdDrag(dragId)
113+
else this.setIdDrag(dragId)
114+
},
115+
dragEnter (event, id) {
116+
event.preventDefault();
117+
const dropId = id;
118+
if (this.activeComponent === '') this.setSelectedIdDrop(dropId)
119+
else this.setIdDrop(dropId)
120+
},
121+
dragOver (event) {
122+
//needed stop the dragend animation so endDrag is invoked automatically
123+
event.preventDefault();
124+
},
125+
endDrag (event) {
126+
//remove the 'currentlyDragging' class after the HTML is dropped
127+
event.preventDefault();
128+
event.target.classList.remove('currentlyDragging')
129+
//invoke the action that will use the idDrag and idDrop to sort the HtmlList
130+
if (this.activeComponent === '') this.dragDropSortSelectedHtmlElements()
131+
else this.dragDropSortHtmlElements()
132+
},
99133
},
100134
watch: {
101135
activeComponent: function () {

src/components/right-sidebar/CodeSnippet.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default {
7474
// Creates beginner boilerplate
7575
createTemplate(componentName) {
7676
let templateTagStr = this.writeTemplateTag(componentName);
77-
77+
7878
//if/else statement to determine if there are class and id attributes present in the html element
7979
if (this.activeComponentObj.htmlAttributes.class !== "" && this.activeComponentObj.htmlAttributes.id !== "") {
8080
return `<template>\n <div id = "${this.activeComponentObj.htmlAttributes.id}" class = "${this.activeComponentObj.htmlAttributes.class}">\n${templateTagStr} </div>\n</template>`;

src/components/right-sidebar/HTMLQueue.vue

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,51 @@ Description:
55
-->
66

77
<template>
8-
<section class="html-queue">
8+
<section class="html-queue" @dragover="dragOver($event), false">
99
<span class='list-title' v-if='this.activeLayer.id !== ""'>
1010
<i class="fas fa fa-chevron-up fa-md" @click="setParentLayer"></i>
11-
&nbsp; &nbsp; Viewing Elements in {{ this.activeComponent }} '{{ depth }}'
11+
12+
&nbsp; &nbsp; Viewing Elements in {{this.activeComponent}} '{{ depth }}'
13+
<hr>
14+
</span>
15+
<span class='list-title' v-else-if='!this.activeComponent'></span>
16+
17+
<div group="people" class="list-group">
18+
19+
<p v-if='!this.componentMap[this.activeComponent]?.htmlList.length'>No HTML elements in component</p>
20+
<!---->
21+
<div
22+
id="tooltipCon"
23+
v-for="(element) in renderList" :key="element[1] + Date.now()"
24+
@dragenter="dragEnter($event, element[2])"
25+
>
26+
<div
27+
:class="activeHTML === element[2] ? 'list-group-item-selected' : 'list-group-item'"
28+
@dblclick.self="setActiveElement(element)"
29+
@dragstart="startDrag($event, element[2])"
30+
@dragend="endDrag($event)"
31+
draggable="true"
32+
>
33+
<!--invisible button for tooltip-->
34+
<button class="attributeButton" @click="setActiveElement(element)">
35+
<div class="tooltip"> Edit {{ element[0] }} attributes </div>
36+
</button>
37+
<i v-if='activeComponent === "" || exceptions.includes(element[0]) '></i>
38+
<i v-else class="fas fa fa-angle-double-down fa-md" @click="setLayer({text: element[0], id: element[2]})"></i>
39+
{{ element[0] }}
40+
<i class="fas fa fa-trash fa-md" @click.self="deleteElement([element[1],element[2]])"></i>
41+
</div>
42+
</div>
43+
</div>
44+
45+
<!--START OF CHANGES-->>
46+
<!-- &nbsp; &nbsp; Viewing Elements in {{ this.activeComponent }} '{{ depth }}'
1247
<hr>
1348
</span>
1449
<span class='list-title' v-else-if='!this.activeComponent'></span>
1550
<div group="people" class="list-group">
1651
<p v-if='!this.componentMap[this.activeComponent]?.htmlList.length'>No HTML elements in component</p>
52+
1753
<div id="tooltipCon" :class="activeHTML === element[2] ? 'list-group-item-selected' : 'list-group-item'"
1854
v-for="(element) in renderList" :key="element[1] + Date.now()">
1955
@@ -25,7 +61,7 @@ Description:
2561
{{ element[0] }}
2662
<i class="fas fa fa-trash fa-md" @click.self="deleteElement([element[1], element[2]])"></i>
2763
</div>
28-
</div>
64+
</div> -->
2965

3066
<!-- attribute pop-up -->
3167
<q-dialog v-model="attributeModal">
@@ -55,6 +91,7 @@ Description:
5591

5692
<script>
5793
94+
import { keys } from 'localforage'
5895
import { mapState, mapActions } from 'vuex'
5996
import { setSelectedElementList, deleteSelectedElement, deleteFromComponentHtmlList } from '../../store/types'
6097
import { breadthFirstSearch } from '../../utils/search.util'
@@ -65,7 +102,7 @@ export default {
65102
name: {
66103
type: String
67104
},
68-
listToRender: {
105+
listToRender:{
69106
type: Array
70107
}
71108
},
@@ -108,8 +145,8 @@ export default {
108145
109146
},
110147
methods: {
111-
...mapActions(['setActiveHTML', 'setActiveLayer', 'upOneLayer', 'openAttributeModal', 'addActiveComponentClass']),
112-
deleteElement(id) {
148+
...mapActions(['setActiveHTML', 'setActiveLayer', 'upOneLayer', 'setSelectedIdDrag', 'setIdDrag', 'setSelectedIdDrop', 'setIdDrop', 'dragDropSortHtmlElements', 'dragDropSortSelectedHtmlElements', 'openAttributeModal', 'addActiveComponentClass']),
149+
deleteElement (id) {
113150
if (this.activeComponent === '') this.$store.dispatch(deleteSelectedElement, id[0])
114151
else this.$store.dispatch(deleteFromComponentHtmlList, id[1])
115152
},
@@ -134,6 +171,32 @@ export default {
134171
this.upOneLayer(this.activeLayer.id)
135172
}
136173
},
174+
//METHODS FOR DRAG-AND-DROP
175+
startDrag (event, id) {
176+
//add a class of 'currentlyDragging' to the HTML element that you are currently dragging
177+
event.target.classList.add('currentlyDragging')
178+
const dragId = id;
179+
if (this.activeComponent === '') this.setSelectedIdDrag(dragId)
180+
else this.setIdDrag(dragId)
181+
},
182+
dragEnter (event, id) {
183+
event.preventDefault();
184+
const dropId = id;
185+
if (this.activeComponent === '') this.setSelectedIdDrop(dropId)
186+
else this.setIdDrop(dropId)
187+
},
188+
dragOver (event) {
189+
//needed stop the dragend animation so endDrag is invoked automatically
190+
event.preventDefault();
191+
},
192+
endDrag (event) {
193+
//remove the 'currentlyDragging' class after the HTML is dropped
194+
event.preventDefault();
195+
event.target.classList.remove('currentlyDragging')
196+
//invoke the action that will use the idDrag and idDrop to sort the HtmlList
197+
if (this.activeComponent === '') this.dragDropSortSelectedHtmlElements()
198+
else this.dragDropSortHtmlElements()
199+
},
137200
submitClass(element, idNum) {
138201
if (element === '') {
139202
return;
@@ -181,11 +244,12 @@ li {
181244
height: 35px;
182245
padding-top: 6px;
183246
text-align: center;
247+
cursor: move;
184248
}
185249
186250
.list-group-item-selected {
187251
display: inline-block;
188-
margin: 2px 1.5%;
252+
margin: 4px 1.5%;
189253
min-width: 175px;
190254
width: 30%;
191255
border-radius: 0.5cm;
@@ -194,6 +258,7 @@ li {
194258
height: 35px;
195259
padding-top: 6px;
196260
text-align: center;
261+
cursor: move;
197262
}
198263
199264
.fa-trash:hover {
@@ -238,7 +303,13 @@ hr {
238303
border: 1px solid grey
239304
}
240305
306+
.currentlyDragging {
307+
opacity: .5;
308+
}
241309
310+
.ignoreByDragover {
311+
pointer-events: none;
312+
}
242313
#tooltipCon {
243314
position: relative;
244315
cursor: pointer;

src/store/actions.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,30 @@ const actions = {
316316
[types.upOneLayer]: ({ commit }, payload) => {
317317
commit(types.UP_ONE_LAYER, payload);
318318
},
319+
//FOR MUTATING HTML WITH DRAG AND DROP
320+
[types.setIdDrag]: ({ commit }, payload) => {
321+
commit(types.SET_ID_DRAG, payload)
322+
},
323+
324+
[types.setIdDrop]: ({ commit }, payload) => {
325+
commit(types.SET_ID_DROP, payload)
326+
},
327+
328+
[types.setSelectedIdDrag]: ({ commit }, payload) => {
329+
commit(types.SET_SELECTED_ID_DRAG, payload)
330+
},
331+
332+
[types.setSelectedIdDrop]: ({ commit }, payload) => {
333+
commit(types.SET_SELECTED_ID_DROP, payload)
334+
},
335+
336+
[types.dragDropSortHtmlElements]: ({ commit }, payload) => {
337+
commit(types.DRAG_DROP_SORT_HTML_ELEMENTS)
338+
},
339+
340+
[types.dragDropSortSelectedHtmlElements]: ({ commit }, payload) => {
341+
commit(types.DRAG_DROP_SORT_SELECTED_HTML_ELEMENTS)
342+
},
319343

320344
// end of HTML segment ////////////////////////////////////////////////
321345

src/store/mutations.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,81 @@ const mutations = {
464464
state.activeHTML = "";
465465
},
466466

467+
[types.SET_ID_DRAG]: (state, payload) => {
468+
const componentName = state.activeComponent;
469+
state.componentMap[componentName].idDrag = payload;
470+
},
471+
472+
[types.SET_ID_DROP]: (state, payload) => {
473+
const componentName = state.activeComponent;
474+
state.componentMap[componentName].idDrop = payload;
475+
},
476+
477+
[types.SET_SELECTED_ID_DRAG]: (state, payload) => {
478+
state.selectedIdDrag = payload;
479+
},
480+
481+
[types.SET_SELECTED_ID_DROP]: (state, payload) => {
482+
state.selectedIdDrop = payload;
483+
},
484+
485+
[types.DRAG_DROP_SORT_HTML_ELEMENTS]: (state) => {
486+
const componentName = state.activeComponent;
487+
const idDrag = state.componentMap[componentName].idDrag;
488+
const idDrop = state.componentMap[componentName].idDrop;
489+
490+
if(idDrag !== idDrop && idDrag !== '' && idDrop !== '') {
491+
let indexDrag;
492+
let indexDrop;
493+
const htmlList = state.componentMap[componentName].htmlList.slice(0)
494+
495+
if (state.activeLayer.id === "") {
496+
htmlList.forEach((el, i) => {
497+
if(el.id === idDrag){
498+
indexDrag = i;
499+
} else if (el.id === idDrop){
500+
indexDrop = i;
501+
}
502+
})
503+
const draggedEl = htmlList.splice(indexDrag, 1)[0]
504+
htmlList.splice(indexDrop,0,draggedEl)
505+
} else {
506+
const nestedDrag = breadthFirstSearchParent(htmlList, idDrag);
507+
const nestedDrop = breadthFirstSearchParent(htmlList, idDrop);
508+
let nestedEl =nestedDrag.evaluated.children.splice(nestedDrag.index, 1)[0]
509+
nestedDrop.evaluated.children.splice(nestedDrop.index, 0, nestedEl)
510+
}
511+
state.componentMap[componentName].htmlList = htmlList;
512+
}
513+
state.componentMap[componentName].idDrag = '';
514+
state.componentMap[componentName].idDrop = '';
515+
},
516+
517+
[types.DRAG_DROP_SORT_SELECTED_HTML_ELEMENTS]: (state) => {
518+
const selectedIdDrag = state.selectedIdDrag;
519+
const selectedIdDrop = state.selectedIdDrop;
520+
521+
if(selectedIdDrag !== selectedIdDrop && selectedIdDrag !== '' && selectedIdDrop !== ''){
522+
const htmlList = state.selectedElementList.slice(0)
523+
524+
let indexDrag;
525+
let indexDrop;
526+
527+
htmlList.forEach((el, i) => {
528+
if(el.id === selectedIdDrag){
529+
indexDrag = i;
530+
} else if (el.id === selectedIdDrop){
531+
indexDrop = i;
532+
}
533+
})
534+
535+
const draggedEl = htmlList.splice(indexDrag, 1)[0]
536+
htmlList.splice(indexDrop,0,draggedEl)
537+
state.selectedElementList = htmlList;
538+
}
539+
state.selectedIdDrag = '';
540+
state.selectedIdDrop = '';
541+
},
467542
// *** COMPONENTS *** //////////////////////////////////////////////
468543
// adds the component to the selected route (ex: HomeView)
469544
[types.ADD_COMPONENT_TO_ACTIVE_ROUTE_CHILDREN]: (state, payload) => {
@@ -489,6 +564,8 @@ const mutations = {
489564
isActive,
490565
actions,
491566
props,
567+
idDrag,
568+
idDrop,
492569
htmlAttributes,
493570
} = payload;
494571
const s = payload.state;
@@ -508,6 +585,8 @@ const mutations = {
508585
actions,
509586
props,
510587
state: s,
588+
idDrag,
589+
idDrop,
511590
htmlAttributes,
512591
},
513592
};

src/store/state/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ const newState = {
4848
selectedState: [],
4949
selectedActions: [],
5050
selectedElementList: [],
51+
selectedIdDrag: '',
52+
selectedIdDrop: '',
5153
projectNumber: 2,
5254
activeTab: 0,
5355
componentChildrenMultiselectValue: [],

0 commit comments

Comments
 (0)