Replace the draggable component by the vueuse one

This commit is contained in:
Bubka 2023-11-14 13:59:30 +01:00
parent 53e3698076
commit 9ae52ae78f
4 changed files with 192 additions and 43 deletions

View File

@ -148,8 +148,12 @@ public function reorder(TwoFAccountReorderRequest $request)
$this->authorize('updateEach', [new TwoFAccount(), $twofaccounts]);
TwoFAccount::setNewOrder($validated['orderedIds']);
$orderedIds = $request->user()->twofaccounts->sortBy('order_column')->pluck('id');
return response()->json(['message' => 'order saved'], 200);
return response()->json([
'message' => 'order saved',
'orderedIds' => $orderedIds
], 200);
}
/**

164
package-lock.json generated
View File

@ -13,6 +13,7 @@
"@vitejs/plugin-vue": "^4.3.4",
"@vueuse/components": "^10.4.1",
"@vueuse/core": "^10.4.1",
"@vueuse/integrations": "^10.6.1",
"axios": "^1.1.2",
"bulma": "^0.9.4",
"bulma-checkradio": "^2.1.3",
@ -21,10 +22,10 @@
"laravel-vue-i18n": "^2.7.1",
"pinia": "^2.1.6",
"sass": "^1.67.0",
"sortablejs": "^1.15.0",
"unplugin-auto-import": "^0.16.6",
"vite": "^4.4.9",
"vue": "^3.3.4",
"vue-draggable-plus": "^0.2.6",
"vue-qrcode-reader": "^5.4.0",
"vue-router": "^4.2.4"
}
@ -629,13 +630,6 @@
"optional": true,
"peer": true
},
"node_modules/@types/sortablejs": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.4.tgz",
"integrity": "sha512-7oL7CcPSfoyoNx3Ba1+79ykJzpEKVhHUyfAiN5eT/FoeDXOR3eBDLXf9ndDNuxaExmjpI+zVi2dMMuaoXUOzNA==",
"dev": true,
"peer": true
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.17",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz",
@ -851,6 +845,140 @@
}
}
},
"node_modules/@vueuse/integrations": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.6.1.tgz",
"integrity": "sha512-mPDupuofMJ4DPmtX/FfP1MajmWRzYDv8WSaTCo8LQ5kFznjWgmUQ16ApjYqgMquqffNY6+IRMdMgosLDRZOSZA==",
"dev": true,
"dependencies": {
"@vueuse/core": "10.6.1",
"@vueuse/shared": "10.6.1",
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"async-validator": "*",
"axios": "*",
"change-case": "*",
"drauu": "*",
"focus-trap": "*",
"fuse.js": "*",
"idb-keyval": "*",
"jwt-decode": "*",
"nprogress": "*",
"qrcode": "*",
"sortablejs": "*",
"universal-cookie": "*"
},
"peerDependenciesMeta": {
"async-validator": {
"optional": true
},
"axios": {
"optional": true
},
"change-case": {
"optional": true
},
"drauu": {
"optional": true
},
"focus-trap": {
"optional": true
},
"fuse.js": {
"optional": true
},
"idb-keyval": {
"optional": true
},
"jwt-decode": {
"optional": true
},
"nprogress": {
"optional": true
},
"qrcode": {
"optional": true
},
"sortablejs": {
"optional": true
},
"universal-cookie": {
"optional": true
}
}
},
"node_modules/@vueuse/integrations/node_modules/@types/web-bluetooth": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==",
"dev": true
},
"node_modules/@vueuse/integrations/node_modules/@vueuse/core": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.6.1.tgz",
"integrity": "sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==",
"dev": true,
"dependencies": {
"@types/web-bluetooth": "^0.0.20",
"@vueuse/metadata": "10.6.1",
"@vueuse/shared": "10.6.1",
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/integrations/node_modules/@vueuse/metadata": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.6.1.tgz",
"integrity": "sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/integrations/node_modules/@vueuse/shared": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.6.1.tgz",
"integrity": "sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==",
"dev": true,
"dependencies": {
"vue-demi": ">=0.14.6"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/integrations/node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"dev": true,
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.4.1.tgz",
@ -1659,6 +1787,12 @@
"integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==",
"dev": true
},
"node_modules/sortablejs": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz",
"integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==",
"dev": true
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -1895,20 +2029,6 @@
"@vue/shared": "3.3.4"
}
},
"node_modules/vue-draggable-plus": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/vue-draggable-plus/-/vue-draggable-plus-0.2.6.tgz",
"integrity": "sha512-d+0omKIBIfLiJFggc6H4ePRaifbX+33+OiCMsxn8rG59yWXlJGrobexxgXetnSo/1NLTd0TkYZKNc4CA6iwJZw==",
"dev": true,
"peerDependencies": {
"@types/sortablejs": "^1.15.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-qrcode-reader": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-5.4.0.tgz",

View File

@ -14,6 +14,7 @@
"@vitejs/plugin-vue": "^4.3.4",
"@vueuse/components": "^10.4.1",
"@vueuse/core": "^10.4.1",
"@vueuse/integrations": "^10.6.1",
"axios": "^1.1.2",
"bulma": "^0.9.4",
"bulma-checkradio": "^2.1.3",
@ -22,10 +23,10 @@
"laravel-vue-i18n": "^2.7.1",
"pinia": "^2.1.6",
"sass": "^1.67.0",
"sortablejs": "^1.15.0",
"unplugin-auto-import": "^0.16.6",
"vite": "^4.4.9",
"vue": "^3.3.4",
"vue-draggable-plus": "^0.2.6",
"vue-qrcode-reader": "^5.4.0",
"vue-router": "^4.2.4"
}

View File

@ -16,7 +16,7 @@
import { useGroups } from '@/stores/groups'
import { useAppSettingsStore } from '@/stores/appSettings'
import { useDisplayablePassword } from '@/composables/helpers'
import { vDraggable } from 'vue-draggable-plus'
import { useSortable, moveArrayElement } from '@vueuse/integrations/useSortable'
const $2fauth = inject('2fauth')
const router = useRouter()
@ -39,12 +39,34 @@
const looperRefs = ref([])
const dotsRefs = ref([])
let stopSortable
watch(showOtpInModal, (val) => {
if (val == false) {
otpDisplay.value?.clearOTP()
}
})
watch(
() => twofaccounts.items,
(val) => {
stopSortable
if (bus.inManagementMode) {
setSortable()
}
}
)
watch(
() => bus.inManagementMode,
(val) => {
stopSortable
if (val) {
setSortable()
}
}
)
/**
* Returns whether or not the accounts should be displayed
*/
@ -65,6 +87,24 @@
groups.fetch()
})
// Enables the sortable behaviour of the twofaccounts list
function setSortable() {
const { stop } = useSortable('#dv', twofaccounts.filtered, {
animation: 200,
handle: '.drag-handle',
onUpdate: (e) => {
const movedId = twofaccounts.filtered[e.oldIndex].id
const inItemsIndex = twofaccounts.items.findIndex(item => item.id == movedId)
moveArrayElement(twofaccounts.items, inItemsIndex, e.newIndex)
nextTick(() => {
twofaccounts.saveOrder()
})
}
})
stopSortable = stop
}
/**
* Runs some updates after accounts assignement/withdrawal
*/
@ -284,16 +324,7 @@
<div class="container" v-if="showAccounts" :class="bus.inManagementMode ? 'is-edit-mode' : ''">
<!-- accounts -->
<div class="accounts">
<span class="columns is-multiline" :class="{ 'is-centered': user.preferences.displayMode === 'grid' }" v-draggable="[
twofaccounts.filtered,
{
animation: 150,
ghostClass: 'ghost',
handle: '.tfa-dots',
onEnd,
onStart
}
]">
<span id="dv" class="columns is-multiline" :class="{ 'is-centered': user.preferences.displayMode === 'grid' }">
<div :class="[user.preferences.displayMode === 'grid' ? 'tfa-grid' : 'tfa-list']" class="column is-narrow" v-for="account in twofaccounts.filtered" :key="account.id">
<div class="tfa-container">
<transition name="slideCheckbox">
@ -345,7 +376,7 @@
</div>
</transition>
<transition name="fadeInOut">
<div class="tfa-cell tfa-dots has-text-grey" v-if="bus.inManagementMode">
<div class="drag-handle tfa-cell tfa-dots has-text-grey" v-if="bus.inManagementMode">
<FontAwesomeIcon :icon="['fas', 'bars']" />
</div>
</transition>
@ -378,10 +409,3 @@
</span>
</div>
</template>
<style scoped>
.ghost {
opacity: 1;
/*background: hsl(0, 0%, 21%);*/
}
</style>