From 1eca13c27fbe188b60a7e55526bb6c99e1e079d8 Mon Sep 17 00:00:00 2001 From: Paolo Arena Date: Tue, 19 Feb 2019 18:44:48 +0100 Subject: [PATCH] Drag & Drop hand made... but don't working with the touch --- .env.development | 2 +- package-lock.json | 51 ++++++++++++- package.json | 1 + quasar.conf.js | 3 +- .../todos/SingleTodo/SingleTodo.scss | 73 ++++++++++++++----- src/components/todos/SingleTodo/SingleTodo.ts | 14 +++- .../todos/SingleTodo/SingleTodo.vue | 31 ++++---- src/components/todos/SubMenus/SubMenus.ts | 5 ++ src/components/todos/todo/todo.scss | 28 ++++++- src/components/todos/todo/todo.ts | 69 ++++++++++++++++-- src/components/todos/todo/todo.vue | 40 +++++----- src/plugins/dragula.js | 8 ++ src/store/Api/index.ts | 4 +- 13 files changed, 259 insertions(+), 70 deletions(-) create mode 100644 src/plugins/dragula.js diff --git a/.env.development b/.env.development index 19ae2ec..498e006 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ -APP_VERSION="DEV 0.0.31" +APP_VERSION="DEV 0.0.32" SERVICE_WORKER_FILE='service-worker.js' APP_ID='1' APP_URL='https://freeplanet.app' diff --git a/package-lock.json b/package-lock.json index 2b2bcf6..99029ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "freeplanet", - "version": "0.0.2", + "version": "0.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5059,6 +5059,11 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "atoa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atoa/-/atoa-1.0.0.tgz", + "integrity": "sha1-DMDpGkgOc4+SPrwQNnZHF3mzSkk=" + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -7366,6 +7371,15 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, + "contra": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/contra/-/contra-1.9.4.tgz", + "integrity": "sha1-9TveQtfltZhcrk2ZqNYQUm3o8o0=", + "requires": { + "atoa": "1.0.0", + "ticky": "1.0.1" + } + }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", @@ -7546,6 +7560,14 @@ "which": "1.3.1" } }, + "crossvent": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/crossvent/-/crossvent-1.5.4.tgz", + "integrity": "sha1-2ixPj0DJR4JRe/K+7BBEFIGUq5I=", + "requires": { + "custom-event": "1.0.0" + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -7870,6 +7892,11 @@ "array-find-index": "1.0.2" } }, + "custom-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.0.tgz", + "integrity": "sha1-LkYovhncSyFLXAJjDFlx6BFhgGI=" + }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", @@ -8472,6 +8499,15 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" }, + "dragula": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/dragula/-/dragula-3.7.2.tgz", + "integrity": "sha1-SjXJ05gf+sGpScKcpyhQWOhzk84=", + "requires": { + "contra": "1.9.4", + "crossvent": "1.5.4" + } + }, "duplexer": { "version": "0.1.1", "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -23354,6 +23390,11 @@ "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", "dev": true }, + "ticky": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ticky/-/ticky-1.0.1.tgz", + "integrity": "sha1-t8+nHnaPHJAAxJe5FRswlHxQ5G0=" + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -24406,6 +24447,14 @@ "integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==", "dev": true }, + "vue2-dragula": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/vue2-dragula/-/vue2-dragula-2.5.4.tgz", + "integrity": "sha512-RkVBBeb0xFFfksv0oloxPJLdBphrIJlMsWtYLt5QWpO37MslaV4pnuWMlySDpTjvVONAiDcSsXaw1sS9WfYsig==", + "requires": { + "dragula": "3.7.2" + } + }, "vuedraggable": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.17.0.tgz", diff --git a/package.json b/package.json index cb30e46..038f69c 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "vue-property-decorator": "^7.2.0", "vue-router": "^3.0.1", "vue-svgicon": "^3.1.0", + "vue2-dragula": "^2.5.4", "vuedraggable": "^2.17.0", "vuelidate": "^0.7.4", "vuex": "^3.0.1", diff --git a/quasar.conf.js b/quasar.conf.js index 815f50a..825fde4 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -59,7 +59,7 @@ module.exports = function (ctx) { store: 'src/store/index.ts' }, // app plugins (/src/plugins) - plugins: ['i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb'], + plugins: ['i18n', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb', 'vue2-dragula'], css: [ 'app.styl' ], @@ -153,6 +153,7 @@ module.exports = function (ctx) { 'QContextMenu', 'QProgress', 'QSlider', + 'QPopupEdit', ], directives: [ 'Ripple', diff --git a/src/components/todos/SingleTodo/SingleTodo.scss b/src/components/todos/SingleTodo/SingleTodo.scss index 84d64eb..69959b1 100644 --- a/src/components/todos/SingleTodo/SingleTodo.scss +++ b/src/components/todos/SingleTodo/SingleTodo.scss @@ -1,16 +1,23 @@ $colcompleted: #a2a2a2; -$heightitem: 19px; +$heightitem: 32px; +$heightothers: 32px; +$heightBtn: 100%; $heightcounter: 26px; -$heightdescr: 22px; +$heightdescr: 20px; .flex-item{ // background-color: #d5e2eb; padding: 0px; - margin: 0px; + margin: 1px; + margin-left: 3px; + margin-right: 3px; color: #000; font-size: 0.85rem; + height: $heightBtn; + line-height: $heightBtn; + vertical-align: middle; //flex: 0 0 100%; } @@ -18,7 +25,7 @@ $heightdescr: 22px; .flex-container2 { flex-flow: row wrap; justify-content: space-between; - margin: 2px 5px 2px 5px; // top right bottom left + margin: 0px 5px 0px 5px; // top right bottom left } // Set visibility: visible to the icon menu of pos-item-popover @@ -26,6 +33,7 @@ $heightdescr: 22px; //.flex-container2:hover .pos-item-popover { background-color: rgba(230, 230, 230, 0.8); display: inline-block; + transition: all ease-in-out .3s; } .comp_selected { @@ -68,8 +76,12 @@ $heightdescr: 22px; margin-right: 1px; padding-left: 1px; padding-right: 1px; - height: $heightitem; + margin: 0px; + padding-top: 0px; + padding-bottom: 0px; + //height: $heightitem; line-height: $heightitem; + min-height: $heightitem; text-align: center; // background-color: #ff4081; font-size: 0.75rem; @@ -104,7 +116,8 @@ $heightdescr: 22px; display: none; } color: #777; - height: 100%; + height: $heightitem; + line-height: $heightitem; //visibility: hidden; } @@ -134,7 +147,8 @@ $heightdescr: 22px; text-align: center; vertical-align: middle; display: inline-block; - height: 100%; + height: $heightitem; + line-height: $heightitem; color: #777; } @@ -146,23 +160,38 @@ $heightdescr: 22px; .completed-item { max-width: 24px; min-width: 24px; + height: $heightitem; + line-height: $heightitem; } .progress-item { - max-width: 32px; - min-width: 24px; + margin: 1px; + padding: 2px; + padding-top: 4px; + padding-bottom: 4px; + max-width: 36px; + min-width: 32px; flex: 1; - order: 2; - text-align: right; + order: 1; } +.progrbar-item { + //height: 10px + padding-top: 7px; +} .percProgress { - height: $heightitem; - line-height: $heightitem; + padding-top: 3px; color: #888; + vertical-align: middle; + text-align: center; + cursor: pointer; + //line-height: $heightitem; } +.editProgress{ + //height: 20px; +} .colProgress { } @@ -182,13 +211,14 @@ $heightdescr: 22px; } .myexpired { - padding-top: 0px; - padding-bottom: 0px; - font-size: 12px; + padding-top: 5px; + padding-bottom: 3px; + font-size: 0.85rem; + vertical-align: middle; } .data-item { - max-width: 100px; + max-width: 80px; //min-width: 100px; //display: flex; //visibility: initial; @@ -196,6 +226,8 @@ $heightdescr: 22px; color: #ccc; order: 1; flex: 1; + height: $heightBtn; + line-height: $heightBtn; } @@ -217,10 +249,12 @@ $heightdescr: 22px; .div_descr, .div_descr_edit { margin: auto auto auto 2px; //padding: 2px; - min-width: 200px; + min-width: 100px; vertical-align: middle; text-align: left; color: blue !important; + max-height: 42px; + overflow: hidden; flex: 1; //order: 2; @@ -236,6 +270,9 @@ $heightdescr: 22px; } +.div_descr_edit { + max-height: 90px; +} .div_descr:hover { //border-width: 1px 0px 1px 0px; diff --git a/src/components/todos/SingleTodo/SingleTodo.ts b/src/components/todos/SingleTodo/SingleTodo.ts index a98198d..c07ee16 100644 --- a/src/components/todos/SingleTodo/SingleTodo.ts +++ b/src/components/todos/SingleTodo/SingleTodo.ts @@ -101,7 +101,7 @@ export default class SingleTodo extends Vue { this.classDescrEdit += ' titleLista-item' } - this.classExpiring = 'flex-item data-item' + this.classExpiring = 'flex-item data-item shadow-1' this.classExpiringEx = '' if (this.itemtodo.completed) { this.percentageProgress = 100 @@ -126,8 +126,9 @@ export default class SingleTodo extends Vue { mycolcl = ' highperc' } - if (this.itemtodo.completed) + if (this.itemtodo.completed) { mycolcl = ' percompleted' + } this.colProgress = mycolcl @@ -250,7 +251,9 @@ export default class SingleTodo extends Vue { theField = mythis.$parent.$parent.$parent.$parent.$refs[elem] else theField = mythis.$refs[elem] - theField.focus() + + if (theField !== undefined) + theField.focus() // console.log('focus()') }, 100) } @@ -316,7 +319,7 @@ export default class SingleTodo extends Vue { } else { e.preventDefault() this.deselectRiga() - this.faiFocus('insertTask', true) + this.faiFocus('insertTask', false) } } @@ -399,6 +402,8 @@ export default class SingleTodo extends Vue { return await this.setCompleted() } else if (action === rescodes.MenuAction.PROGRESS_BAR) { return await this.updatedata() + } else if (action === 0) { + this.deselectAndExitEdit() } } @@ -430,4 +435,5 @@ export default class SingleTodo extends Vue { }) } + } diff --git a/src/components/todos/SingleTodo/SingleTodo.vue b/src/components/todos/SingleTodo/SingleTodo.vue index f7c9ff1..2324d3d 100644 --- a/src/components/todos/SingleTodo/SingleTodo.vue +++ b/src/components/todos/SingleTodo/SingleTodo.vue @@ -16,7 +16,7 @@
{{ itemtodo.descr }}--> -
+
{{percentageProgress}}% + + + +
-
-
- +
+ - -
+
-
+
diff --git a/src/components/todos/SubMenus/SubMenus.ts b/src/components/todos/SubMenus/SubMenus.ts index ffde880..0545894 100644 --- a/src/components/todos/SubMenus/SubMenus.ts +++ b/src/components/todos/SubMenus/SubMenus.ts @@ -32,6 +32,11 @@ export default class SubMenus extends Vue { if (this.itemtodo.progress < 0) { this.itemtodo.progress = 0 } + + if (e.key === 'Enter') { + // chiudi il meno + this.$emit('clickMenu', 0) + } } create () { diff --git a/src/components/todos/todo/todo.scss b/src/components/todos/todo/todo.scss index bb62af9..8ae4441 100644 --- a/src/components/todos/todo/todo.scss +++ b/src/components/todos/todo/todo.scss @@ -2,6 +2,7 @@ background-color: rgb(250, 250, 250); padding: 5px; display: flex; + align-items: center; flex-direction: row; justify-content: space-between; } @@ -14,7 +15,7 @@ .myitemdrag { padding: 2px; - margin-top: 4px; + //margin-top: 4px; border-width: 1px 0px 0px 0px; //border: solid 1px #ccc; border-style: solid; @@ -76,3 +77,28 @@ font-size: 0.7rem; font-weight: 350; } + +.draggatodraggato2 { + display: inline-block; +} + +.non-draggato { + display: none; +} + +@keyframes fadeIn { + from { + transform: translateY(-100%); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 0.3; + } +} + +.divdrag{ + animation: fadeIn 0.2s ease-in 1 forwards; + min-height: 50px; + background-color: #9f9f9f; +} diff --git a/src/components/todos/todo/todo.ts b/src/components/todos/todo/todo.ts index bd6d766..8686e60 100644 --- a/src/components/todos/todo/todo.ts +++ b/src/components/todos/todo/todo.ts @@ -17,6 +17,8 @@ import draggable from 'vuedraggable' import VueIdb from 'vue-idb' +// import 'statics/css/dragula.css' + import globalroutines from '../../../globalroutines/index' import $ from 'jquery' @@ -43,9 +45,11 @@ export default class Todo extends Vue { itemDragEnd: any = null selrowid: number = 0 polling = null - mytypetransgroup: string = 'flip-list' + mytypetransgroup: string = '' // 'flip-list' tmpstrTodos: string = '' loadDone: boolean = false + public dragging: number + public itemdrag: any = {} fieldtochange: String [] = ['descr', 'completed', 'category', 'expiring_at', 'priority', 'id_prev', 'id_next', 'pos', 'enableExpiring', 'progress'] @@ -60,6 +64,7 @@ export default class Todo extends Vue { console.log('drag = ' + this.drag) } + @Watch('$route', { immediate: true, deep: true }) onUrlChange(newVal: any) { // Some action @@ -68,9 +73,14 @@ export default class Todo extends Vue { @Watch('$route.params.category') changecat() { // console.log('changecat') - this.mytypetransgroup = 'nessuno' + // this.mytypetransgroup = '' this.updatetable(false, '$route.params.category').then(() => { - this.mytypetransgroup = 'crossfade' + + const mythis = this + setTimeout(function () { + // mythis.mytypetransgroup = 'crossfade' + }, 1000) + }) } @@ -292,7 +302,10 @@ export default class Todo extends Vue { } async onEnd(itemdragend) { - console.log('newindex=', itemdragend.newIndex, 'oldindex=', itemdragend.oldIndex) + console.log('3) newindex=', itemdragend.newIndex, 'oldindex=', itemdragend.oldIndex) + + // MOVE + this.todos_arr.splice(itemdragend.newIndex, 0, this.todos_arr.splice(itemdragend.oldIndex, 1)[0]) if (itemdragend.newIndex === itemdragend.oldIndex) return // If nothing change, exit @@ -616,7 +629,6 @@ export default class Todo extends Vue { console.log('deleteitem: KEY = ', id) - let myobjtrov = this.getElemById(id) if (myobjtrov !== null) { @@ -648,8 +660,8 @@ export default class Todo extends Vue { this.updatetable(true, 'deleteitem') }).catch((error) => { - console.log('err: ', error) - }) + console.log('err: ', error) + }) // 3) Delete from the Server (call) this.deleteItemToSyncAndDb(rescodes.DB.TABLE_DELETE_TODOS, myobjtrov, id, true) @@ -908,4 +920,47 @@ export default class Todo extends Vue { Todos.actions.waitAndcheckPendingMsg() } + dragStart(which, ev) { + this.itemdrag.indTemp = which + console.log('1) DRAG INIZIO: ', which) + this.itemdrag.oldIndex = which + this.dragging = which + } + + public randomHexColor() { + return Math.random().toString(16).slice(2, 8) + } + + dragEnter(index, ev) { + if (this.itemdrag.indTemp !== index) { + console.log(`[${index}] DRAG ENTER`) + this.itemdrag.indTemp = index + + this.getItemDrag(index).addClass('draggato2').removeClass('non-draggato') + } + } + + getItemDrag(index) { + return $('div[name=REF' + index + ']') + } + + dragLeave(index, ev) { + if (this.itemdrag.indTemp !== index) { + this.getItemDrag(index).addClass('non-draggato').removeClass('draggato') + } + } + + dragEnd(ev) { + this.dragging = -1 + } + + dragFinish(to, ev) { + this.itemdrag.indTemp = -1 + this.getItemDrag(to).addClass('non-draggato').removeClass('draggato') + console.log('2) DRAG FINE: ', to) + this.itemdrag.newIndex = to + this.onEnd(this.itemdrag) + + } + } diff --git a/src/components/todos/todo/todo.vue b/src/components/todos/todo/todo.vue index 6cd6f29..7845e12 100644 --- a/src/components/todos/todo/todo.vue +++ b/src/components/todos/todo/todo.vue @@ -10,14 +10,12 @@
{{ prior = 0, priorcomplet = false }}
- - -
{{counter = 0}}
-
- - -
{{counter++, mytodo.counter = counter}}
+ + + +
@@ -27,13 +25,15 @@
{{ priorcomplet = true }}
+
+
{{ prior = mytodo.priority, priorcomplet = mytodo.completed }}
- - +
+
@@ -42,18 +42,18 @@ :after="[{icon: 'arrow_forward', content: true, handler () {}}]" v-on:keyup.enter="insertTodo"/> - {{ tmpstrTodos }} + -
- Get Todo - Set Todo - Reload -
+ + + + + - - + + - + diff --git a/src/plugins/dragula.js b/src/plugins/dragula.js new file mode 100644 index 0000000..9295c25 --- /dev/null +++ b/src/plugins/dragula.js @@ -0,0 +1,8 @@ +import Vue from 'vue' +import { Vue2Dragula } from 'vue2-dragula' + +Vue.use(Vue2Dragula, { + logging: { + service: true // to only log methods in service (DragulaService) + } +}); diff --git a/src/store/Api/index.ts b/src/store/Api/index.ts index cab0936..9af20a8 100644 --- a/src/store/Api/index.ts +++ b/src/store/Api/index.ts @@ -55,7 +55,7 @@ export namespace ApiTool { return sendRequest(url, method, mydata) .then(res => { - console.log('res', res) + // console.log('res', res) UserStore.mutations.setResStatus(res.status) if (res.status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_INVALID_TOKEN) { @@ -108,7 +108,7 @@ export namespace ApiTool { const promises = myrecs.map(rec => { // console.log('syncing', table, '', rec.descr) - let link = process.env.MONGODB_HOST + '/todos' + let link = String(process.env.MONGODB_HOST) + '/todos' if (method !== 'POST') link += '/' + rec._id