stash
This commit is contained in:
parent
9814ec7ecd
commit
197f173097
14 changed files with 170 additions and 89 deletions
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<span style="position: relative; display: inline-block;">
|
||||
<div class="delete-button">
|
||||
<button class="btn btn-danger btn-sm" @click="triggerDelete">
|
||||
<guarded-button class="btn btn-danger btn-sm" :confirm-message="confirmMessage" @confirm="$emit('delete')">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</button>
|
||||
</guarded-button>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</span>
|
||||
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
<script>
|
||||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
|
||||
export default {
|
||||
name: "DeletableWrapper",
|
||||
components: {
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
props: {
|
||||
|
|
@ -33,12 +35,6 @@ export default {
|
|||
default: null
|
||||
}
|
||||
},
|
||||
emits: ["delete"],
|
||||
methods: {
|
||||
triggerDelete() {
|
||||
if (this.confirmMessage && !confirm(this.confirmMessage)) return;
|
||||
this.$emit("delete");
|
||||
}
|
||||
}
|
||||
emits: ["delete"]
|
||||
}
|
||||
</script>
|
||||
43
frontend/src/components/GuardedButton.vue
Normal file
43
frontend/src/components/GuardedButton.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<component :is="tag" v-bind="rootProps" :class="{unguarded: shiftHeld}" @click="handleClick">
|
||||
<slot></slot>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {reactive} from "vue"
|
||||
|
||||
const shiftState = reactive({held: false})
|
||||
window.addEventListener("keydown", event => shiftState.held = event.shiftKey)
|
||||
window.addEventListener("keyup", event => shiftState.held = event.shiftKey)
|
||||
|
||||
export default {
|
||||
name: "GuardedButton",
|
||||
props: {
|
||||
confirmMessage: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
default: "button"
|
||||
}
|
||||
},
|
||||
emits: ["confirm"],
|
||||
computed: {
|
||||
rootProps() {
|
||||
return this.tag === "a" ? {href: "#"} : {}
|
||||
},
|
||||
shiftHeld() {
|
||||
return shiftState.held
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(event) {
|
||||
if (this.tag === "a") event.preventDefault()
|
||||
if (this.confirmMessage && !event.shiftKey && !confirm(this.confirmMessage)) return
|
||||
this.$emit("confirm", event)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -38,10 +38,12 @@
|
|||
<div v-if="photos.length > 0" class="photo-gallery mb-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="mb-0">Captured Photos ({{ photos.length }})</h6>
|
||||
<button class="btn btn-sm btn-outline-danger" @click="clearAllPhotos">
|
||||
<guarded-button class="btn btn-sm btn-outline-danger"
|
||||
confirm-message="Are you sure you want to remove all photos?"
|
||||
@confirm="clearAllPhotos">
|
||||
<b-icon-trash class="me-1"></b-icon-trash>
|
||||
Clear All
|
||||
</button>
|
||||
</guarded-button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div v-for="(photo, index) in photos" :key="index" class="col-sm-6 col-md-4 col-lg-3 mb-3">
|
||||
|
|
@ -279,6 +281,7 @@
|
|||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import {mapActions, mapState} from "vuex";
|
||||
import AuthenticatedImage from "@/components/AuthenticatedImage.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import DragDropFileSource from "@/components/inputs/DragDropFileSource.vue";
|
||||
import CameraFileSource from "@/components/inputs/CameraFileSource.vue";
|
||||
import FsFileSource from "@/components/inputs/FsFileSource.vue";
|
||||
|
|
@ -350,6 +353,7 @@ export default {
|
|||
components: {
|
||||
WebcamFileSource,
|
||||
AuthenticatedImage,
|
||||
GuardedButton,
|
||||
DragDropFileSource,
|
||||
CameraFileSource,
|
||||
FsFileSource,
|
||||
|
|
@ -500,14 +504,12 @@ export default {
|
|||
},
|
||||
|
||||
async clearAllPhotos() {
|
||||
if (confirm('Are you sure you want to remove all photos?')) {
|
||||
const removed = this.photos;
|
||||
this.photos = [];
|
||||
await Promise.all(removed.map(photo =>
|
||||
this.unstageFile({lifetime_id: this.workflowInstance.id, file_hash: photo.hash})
|
||||
.catch(error => console.error('Failed to unstage photo:', error))
|
||||
));
|
||||
}
|
||||
},
|
||||
|
||||
proceedFromStep1() {
|
||||
|
|
|
|||
|
|
@ -46,10 +46,12 @@
|
|||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
Edit
|
||||
</a-->
|
||||
<a href="#" class="align-middle" @click="tryDropFriend(friend)">
|
||||
<guarded-button tag="a" class="align-middle"
|
||||
:confirm-message='`Are you sure you want to remove "${friend.handle}" as a friend?`'
|
||||
@confirm="tryDropFriend(friend)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
Delete
|
||||
</a>
|
||||
</guarded-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -107,6 +109,7 @@ import * as BIcons from "bootstrap-icons-vue";
|
|||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import AuthenticatedImage from "@/components/AuthenticatedImage.vue";
|
||||
import UserNameTag from "@/components/UserNameTag.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
|
||||
export default {
|
||||
name: 'Inventory',
|
||||
|
|
@ -114,6 +117,7 @@ export default {
|
|||
BaseLayout,
|
||||
AuthenticatedImage,
|
||||
UserNameTag,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
data() {
|
||||
|
|
@ -173,7 +177,6 @@ export default {
|
|||
})
|
||||
},
|
||||
tryDropFriend(friend) {
|
||||
if (!confirm(`Are you sure you want to remove "${friend.handle}" as a friend?`)) return
|
||||
this.dropFriend(friend).then((ok) => {
|
||||
if (ok) {
|
||||
delete this.friends[friend.handle]
|
||||
|
|
|
|||
|
|
@ -40,10 +40,12 @@
|
|||
<user-name-tag :user="member"/>
|
||||
</td>
|
||||
<td class="table-action">
|
||||
<a href="#" class="align-middle" @click.prevent="tryRemoveMember(member)">
|
||||
<guarded-button tag="a" class="align-middle"
|
||||
:confirm-message='`Are you sure you want to remove "${member.handle}" from ${group.handle}?`'
|
||||
@confirm="tryRemoveMember(member)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
Remove
|
||||
</a>
|
||||
</guarded-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -61,6 +63,7 @@ import {mapActions} from "vuex";
|
|||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import UserNameTag from "@/components/UserNameTag.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {decodeHandleFromUrl} from "@/router";
|
||||
|
||||
export default {
|
||||
|
|
@ -68,6 +71,7 @@ export default {
|
|||
components: {
|
||||
BaseLayout,
|
||||
UserNameTag,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
props: {
|
||||
|
|
@ -107,7 +111,6 @@ export default {
|
|||
})
|
||||
},
|
||||
tryRemoveMember(member) {
|
||||
if (!confirm(`Are you sure you want to remove "${member.handle}" from ${this.group.handle}?`)) return
|
||||
this.removeGroupMember({groupHandle: this.group.handle, identityId: member.id})
|
||||
.then(() => {
|
||||
this.refresh()
|
||||
|
|
|
|||
|
|
@ -61,9 +61,11 @@
|
|||
<router-link v-if="canEdit" :to="itemEditRoute(item)" title="Edit">
|
||||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
</router-link>
|
||||
<a v-if="canEdit" href="#" title="Delete" @click.prevent="tryDeleteItem(item)">
|
||||
<guarded-button v-if="canEdit" tag="a" title="Delete"
|
||||
:confirm-message='`Are you sure you want to delete "${item.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteItem(item)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</a>
|
||||
</guarded-button>
|
||||
<router-link v-if="shortIdLink(item)" :to="shortIdLink(item)">
|
||||
<b-icon-link></b-icon-link>
|
||||
</router-link>
|
||||
|
|
@ -93,10 +95,12 @@
|
|||
<span class="float-right">{{ item.owned_quantity }}</span>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button v-if="canEdit" class="btn btn-danger btn-sm"
|
||||
title="Delete" @click="tryDeleteItem(item)">
|
||||
<guarded-button v-if="canEdit" class="btn btn-danger btn-sm"
|
||||
title="Delete"
|
||||
:confirm-message='`Are you sure you want to delete "${item.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteItem(item)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</button>
|
||||
</guarded-button>
|
||||
<router-link v-if="canEdit" :to="itemEditRoute(item)"
|
||||
class="btn btn-primary btn-sm" title="Edit">
|
||||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
|
|
@ -135,10 +139,12 @@
|
|||
<span class="float-right">{{ item.owned_quantity }}</span>
|
||||
</div>
|
||||
<div class="btn-group mt-auto">
|
||||
<button v-if="canEdit" class="btn btn-danger btn-sm"
|
||||
title="Delete" @click="tryDeleteItem(item)">
|
||||
<guarded-button v-if="canEdit" class="btn btn-danger btn-sm"
|
||||
title="Delete"
|
||||
:confirm-message='`Are you sure you want to delete "${item.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteItem(item)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</button>
|
||||
</guarded-button>
|
||||
<router-link v-if="canEdit" :to="itemEditRoute(item)"
|
||||
class="btn btn-primary btn-sm" title="Edit">
|
||||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
|
|
@ -171,6 +177,7 @@ import {mapActions, mapGetters, mapMutations, mapState} from "vuex";
|
|||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import AuthenticatedImage from "../components/AuthenticatedImage.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {shortenedRoute, encodeHandleForUrl, decodeHandleFromUrl} from "@/router";
|
||||
|
||||
export default {
|
||||
|
|
@ -185,6 +192,7 @@ export default {
|
|||
components: {
|
||||
AuthenticatedImage,
|
||||
BaseLayout,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -241,7 +249,6 @@ export default {
|
|||
return this.fetchFriendInventoryItems({friendHandle: this.selectedOwner})
|
||||
},
|
||||
tryDeleteItem(item) {
|
||||
if (!confirm(`Are you sure you want to delete "${item.name}"? This cannot be undone.`)) return
|
||||
this.deleteInventoryItem(item).then(() => {
|
||||
this.fetchItemsForOwner()
|
||||
})
|
||||
|
|
@ -331,4 +338,11 @@ export default {
|
|||
column-count: 6;
|
||||
}
|
||||
}
|
||||
|
||||
.unguarded.btn-danger,
|
||||
.unguarded.btn-danger:hover,
|
||||
.unguarded.btn-danger:focus {
|
||||
background-color: orange;
|
||||
border-color: orange;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -45,11 +45,12 @@
|
|||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
Edit
|
||||
</button>
|
||||
<button type="submit" class="btn btn-danger"
|
||||
@click="tryDeleteItem">
|
||||
<guarded-button class="btn btn-danger"
|
||||
:confirm-message='`Are you sure you want to delete "${item.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteItem">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
Delete
|
||||
</button>
|
||||
</guarded-button>
|
||||
<button v-if="canPrint" class="btn btn-secondary"
|
||||
@click="$router.push({name: 'print', query: {kind: 'item', userHandle: decodedHandle, id: id}})">
|
||||
<b-icon-printer></b-icon-printer>
|
||||
|
|
@ -68,6 +69,7 @@ import * as BIcons from "bootstrap-icons-vue";
|
|||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import {mapActions, mapGetters, mapState} from "vuex";
|
||||
import AuthenticatedImage from "@/components/AuthenticatedImage.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {decodeHandleFromUrl, ownerOverviewRoute} from "@/router";
|
||||
|
||||
export default {
|
||||
|
|
@ -75,6 +77,7 @@ export default {
|
|||
components: {
|
||||
AuthenticatedImage,
|
||||
BaseLayout,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
props: {
|
||||
|
|
@ -118,7 +121,6 @@ export default {
|
|||
this.item = await this.fetchItemByHandle({handle: this.decodedHandle, id: this.id}) || {}
|
||||
},
|
||||
tryDeleteItem() {
|
||||
if (!confirm(`Are you sure you want to delete "${this.item.name}"? This cannot be undone.`)) return
|
||||
this.deleteInventoryItem(this.item).then(() => this.$router.push(ownerOverviewRoute(this.item)))
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,10 +35,11 @@
|
|||
<router-link class="list-group-item list-group-item-action" :to="{name: 'data'}"
|
||||
active-class="active">Your data
|
||||
</router-link>
|
||||
<a class="list-group-item list-group-item-action delete" @click="deleteAccount"
|
||||
href="#">
|
||||
<guarded-button tag="a" class="list-group-item list-group-item-action delete"
|
||||
confirm-message="Are you sure you want to permanently delete your account? All your data will be deleted and you will not be able to log back in. This cannot be undone."
|
||||
@confirm="deleteAccount">
|
||||
Delete account
|
||||
</a>
|
||||
</guarded-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -55,11 +56,12 @@
|
|||
|
||||
<script>
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {mapActions, mapGetters, mapMutations} from "vuex";
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
components: {BaseLayout},
|
||||
components: {BaseLayout, GuardedButton},
|
||||
data() {
|
||||
return {
|
||||
deleteError: null,
|
||||
|
|
@ -74,10 +76,6 @@ export default {
|
|||
...mapMutations(['logout']),
|
||||
async deleteAccount() {
|
||||
this.deleteError = null;
|
||||
if (!confirm('Are you sure you want to permanently delete your account? ' +
|
||||
'All your data will be deleted and you will not be able to log back in. This cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const servers = await this.getHomeServers();
|
||||
const response = await servers.delete(this.signAuth, '/api/v1/account/');
|
||||
|
|
|
|||
|
|
@ -58,9 +58,11 @@
|
|||
<router-link :to="locationEditRoute(location)" title="Edit">
|
||||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
</router-link>
|
||||
<a href="#" title="Delete" @click.prevent="tryDeleteLocation(location)">
|
||||
<guarded-button tag="a" title="Delete"
|
||||
:confirm-message='`Are you sure you want to delete "${location.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteLocation(location)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</a>
|
||||
</guarded-button>
|
||||
<router-link v-if="shortIdLink(location)" :to="shortIdLink(location)">
|
||||
<b-icon-link></b-icon-link>
|
||||
</router-link>
|
||||
|
|
@ -91,10 +93,12 @@
|
|||
<small>{{ location.description }}</small>
|
||||
</div>
|
||||
<div class="btn-group mt-auto">
|
||||
<button class="btn btn-danger btn-sm"
|
||||
title="Delete" @click="tryDeleteLocation(location)">
|
||||
<guarded-button class="btn btn-danger btn-sm"
|
||||
title="Delete"
|
||||
:confirm-message='`Are you sure you want to delete "${location.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteLocation(location)">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
</button>
|
||||
</guarded-button>
|
||||
<router-link :to="locationEditRoute(location)"
|
||||
class="btn btn-primary btn-sm" title="Edit">
|
||||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
|
|
@ -126,6 +130,7 @@
|
|||
import {mapActions, mapGetters, mapState} from "vuex";
|
||||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {shortenedRoute, encodeHandleForUrl, decodeHandleFromUrl} from "@/router";
|
||||
|
||||
export default {
|
||||
|
|
@ -139,6 +144,7 @@ export default {
|
|||
},
|
||||
components: {
|
||||
BaseLayout,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -186,7 +192,6 @@ export default {
|
|||
: this.fetchGroupStorageLocations({groupHandle: this.selectedOwner})
|
||||
},
|
||||
tryDeleteLocation(location) {
|
||||
if (!confirm(`Are you sure you want to delete "${location.name}"? This cannot be undone.`)) return
|
||||
this.deleteStorageLocation(location).then(() => {
|
||||
this.fetchLocationsForOwner()
|
||||
})
|
||||
|
|
@ -242,4 +247,11 @@ export default {
|
|||
.btn-group.mt-auto .btn {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.unguarded.btn-danger,
|
||||
.unguarded.btn-danger:hover,
|
||||
.unguarded.btn-danger:focus {
|
||||
background-color: orange;
|
||||
border-color: orange;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -38,11 +38,12 @@
|
|||
<b-icon-pencil-square></b-icon-pencil-square>
|
||||
Edit
|
||||
</button>
|
||||
<button type="submit" class="btn btn-danger"
|
||||
@click="tryDeleteLocation">
|
||||
<guarded-button class="btn btn-danger"
|
||||
:confirm-message='`Are you sure you want to delete "${location.name}"? This cannot be undone.`'
|
||||
@confirm="tryDeleteLocation">
|
||||
<b-icon-trash></b-icon-trash>
|
||||
Delete
|
||||
</button>
|
||||
</guarded-button>
|
||||
<button class="btn btn-secondary"
|
||||
@click="$router.push({name: 'print', query: {kind: 'storage-location', userHandle: decodedHandle, id: id}})">
|
||||
<b-icon-printer></b-icon-printer>
|
||||
|
|
@ -58,6 +59,7 @@
|
|||
<script>
|
||||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {mapActions, mapGetters, mapState} from "vuex";
|
||||
import {decodeHandleFromUrl, ownerLocationOverviewRoute} from "@/router";
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ export default {
|
|||
name: "StorageLocationDetail",
|
||||
components: {
|
||||
BaseLayout,
|
||||
GuardedButton,
|
||||
...BIcons
|
||||
},
|
||||
props: {
|
||||
|
|
@ -105,7 +108,6 @@ export default {
|
|||
this.location = await this.fetchStorageLocationByHandle({handle: this.decodedHandle, id: this.id}) || {}
|
||||
},
|
||||
tryDeleteLocation() {
|
||||
if (!confirm(`Are you sure you want to delete "${this.location.name}"? This cannot be undone.`)) return
|
||||
this.deleteStorageLocation(this.location).then(() => this.$router.push(ownerLocationOverviewRoute(this.location)))
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
<b-icon-arrow-left class="me-1"></b-icon-arrow-left>
|
||||
Back
|
||||
</button>
|
||||
<button v-if="canAbort" class="btn btn-outline-danger" @click="abortWorkflow" :disabled="loading">
|
||||
<guarded-button v-if="canAbort" class="btn btn-outline-danger"
|
||||
:confirm-message='`Are you sure you want to abort "${getWorkflowDisplayName || workflowInstance.title}"?`'
|
||||
@confirm="abortWorkflow" :disabled="loading">
|
||||
<b-icon-x-circle class="me-1"></b-icon-x-circle>
|
||||
Abort
|
||||
</button>
|
||||
</guarded-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -199,6 +201,7 @@
|
|||
<script>
|
||||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
import { getWorkflow, getWorkflowComponent } from '@/workflows.js';
|
||||
|
||||
|
|
@ -206,7 +209,8 @@ export default {
|
|||
name: 'WorkflowDetail',
|
||||
components: {
|
||||
...BIcons,
|
||||
BaseLayout
|
||||
BaseLayout,
|
||||
GuardedButton
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
|
|
@ -416,8 +420,6 @@ export default {
|
|||
},
|
||||
|
||||
async abortWorkflow() {
|
||||
const displayName = this.getWorkflowDisplayName || this.workflowInstance.title;
|
||||
if (!confirm(`Are you sure you want to abort "${displayName}"?`)) return;
|
||||
try {
|
||||
this.loading = true;
|
||||
await this.deleteWorkflow(this.workflowInstance.id);
|
||||
|
|
|
|||
|
|
@ -54,11 +54,12 @@
|
|||
:disabled="loading">
|
||||
<b-icon-eye></b-icon-eye>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-danger"
|
||||
@click="abortWorkflowInstance(workflow)"
|
||||
<guarded-button class="btn btn-sm btn-outline-danger"
|
||||
:confirm-message='`Are you sure you want to abort "${getWorkflowDisplayName(workflow)}"?`'
|
||||
@confirm="abortWorkflowInstance(workflow)"
|
||||
:disabled="loading">
|
||||
<b-icon-x-circle></b-icon-x-circle>
|
||||
</button>
|
||||
</guarded-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -132,6 +133,7 @@
|
|||
<script>
|
||||
import * as BIcons from "bootstrap-icons-vue";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
import {mapState, mapActions} from 'vuex';
|
||||
import {getAllWorkflows, getWorkflow, buildWorkflowApiPayload} from '@/workflows.js';
|
||||
|
||||
|
|
@ -139,7 +141,8 @@ export default {
|
|||
name: 'Workflows',
|
||||
components: {
|
||||
...BIcons,
|
||||
BaseLayout
|
||||
BaseLayout,
|
||||
GuardedButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -264,7 +267,6 @@ export default {
|
|||
},
|
||||
async abortWorkflowInstance(workflow) {
|
||||
const displayName = this.getWorkflowDisplayName(workflow);
|
||||
if (confirm(`Are you sure you want to abort "${displayName}"?`)) {
|
||||
try {
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
|
@ -279,7 +281,6 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@
|
|||
<fs-file-source @input="uploadPicture">
|
||||
<span class="btn btn-primary"><i class="fas fa-upload"></i> Upload</span>
|
||||
</fs-file-source>
|
||||
<button class="btn btn-outline-secondary ml-2" type="button" @click="removePicture">
|
||||
<guarded-button class="btn btn-outline-secondary ml-2" type="button"
|
||||
confirm-message="Are you sure you want to remove your profile picture?"
|
||||
@confirm="removePicture">
|
||||
Remove
|
||||
</button>
|
||||
</guarded-button>
|
||||
</div>
|
||||
<small>For best results, use an image at least 128px by
|
||||
128px in .jpg format</small>
|
||||
|
|
@ -107,10 +109,11 @@
|
|||
import {mapActions, mapState} from "vuex";
|
||||
import AuthenticatedImage from "@/components/AuthenticatedImage.vue";
|
||||
import FsFileSource from "@/components/inputs/FsFileSource.vue";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
|
||||
export default {
|
||||
name: 'Account',
|
||||
components: {AuthenticatedImage, FsFileSource},
|
||||
components: {AuthenticatedImage, FsFileSource, GuardedButton},
|
||||
computed: {
|
||||
...mapState(['user', 'user_profile']),
|
||||
profilePictureSrc() {
|
||||
|
|
@ -130,7 +133,6 @@ export default {
|
|||
await this.updateUserProfilePicture({file: image});
|
||||
},
|
||||
async removePicture() {
|
||||
if (!confirm('Are you sure you want to remove your profile picture?')) return;
|
||||
await this.updateUserProfilePicture({file: null});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@
|
|||
<div class="mb-3">
|
||||
<label class="form-label
|
||||
d-block">Delete your data</label>
|
||||
<button type="button" class="btn btn-danger" @click="deleteData">
|
||||
<guarded-button type="button" class="btn btn-danger"
|
||||
confirm-message="Are you sure you want to permanently delete all your data (inventory, locations, settings, friends and files)? Your account itself will stay - this cannot be undone."
|
||||
@confirm="deleteData">
|
||||
Delete
|
||||
</button>
|
||||
</guarded-button>
|
||||
<br>
|
||||
<small>Delete all your data including photos, videos,
|
||||
comments, profile information and more</small>
|
||||
|
|
@ -78,12 +80,15 @@
|
|||
<script>
|
||||
import {mapActions, mapGetters} from 'vuex';
|
||||
import router from "@/router";
|
||||
import GuardedButton from "@/components/GuardedButton.vue";
|
||||
|
||||
//import VueQrcode from '@chenfengyuan/vue-qrcode';
|
||||
|
||||
export default {
|
||||
name: 'Data',
|
||||
components: {},
|
||||
components: {
|
||||
GuardedButton
|
||||
},
|
||||
data: () => ({
|
||||
selectedFile: null,
|
||||
localUserIdentityRecord: null,
|
||||
|
|
@ -106,10 +111,6 @@ export default {
|
|||
async deleteData() {
|
||||
this.deleteError = null;
|
||||
this.deleteSuccess = null;
|
||||
if (!confirm('Are you sure you want to permanently delete all your data (inventory, locations, ' +
|
||||
'settings, friends and files)? Your account itself will stay - this cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const servers = await this.getHomeServers();
|
||||
const response = await servers.delete(this.signAuth, '/api/v1/account_data/');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue