mirror of
https://github.com/MarcZierle/photo-log-frontend.git
synced 2025-04-07 13:04:37 +00:00
add photo picker
This commit is contained in:
parent
c97742efd7
commit
e750480fd0
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
BIN
public/favicon.png
Normal file
BIN
public/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="https://www.zierle-training.de/images/152x152/2980389/favicon.png">
|
||||
<link rel="icon" href="favicon.png">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -12,4 +12,40 @@ const apiClient = axios.create({
|
||||
|
||||
export function getPhotoLogList() {
|
||||
return apiClient.get('/photologs/')
|
||||
}
|
||||
|
||||
export function getPhotoLog(id) {
|
||||
return apiClient.get('/photolog/'+id+'/')
|
||||
}
|
||||
|
||||
export function addNewPhotoLog(title, date) {
|
||||
return apiClient.post('/addphotolog/', {
|
||||
title,
|
||||
date: date,
|
||||
render_date: true,
|
||||
start_slide_image: null,
|
||||
slides: []
|
||||
})
|
||||
}
|
||||
|
||||
export function updatePhotoLog({id, title, date, render_date, start_slide_image, slides}) {
|
||||
return apiClient.put('/updatephotolog/'+id+'/', {
|
||||
title,
|
||||
date,
|
||||
render_date,
|
||||
start_slide_image,
|
||||
slides
|
||||
})
|
||||
}
|
||||
|
||||
export function deletePhotoLog(id) {
|
||||
return apiClient.delete('/deletephotolog/'+id+'/')
|
||||
}
|
||||
|
||||
export function getPhotoGroups() {
|
||||
return apiClient.get('/photogroups/')
|
||||
}
|
||||
|
||||
export function getPhotosByGroup(group_id) {
|
||||
return apiClient.get('/photos/?photogroup='+group_id)
|
||||
}
|
157
src/components/PhotoSelectModal.vue
Normal file
157
src/components/PhotoSelectModal.vue
Normal file
@ -0,0 +1,157 @@
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<template>
|
||||
<n-modal v-model:show="showSelection" :mask-closable=false>
|
||||
<n-card
|
||||
style="width: 75vw"
|
||||
title="Select Photos"
|
||||
:bordered="false"
|
||||
size="huge"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
<template #header-extra>
|
||||
<p v-if="isFinite(max_select) && !or_less">
|
||||
{{num_selected}}/{{max_select}} photo(s) selected
|
||||
</p>
|
||||
<p v-else-if="isFinite(max_select) && or_less">
|
||||
maximum of {{selecions_left}} photo(s) left
|
||||
</p>
|
||||
<p v-else>
|
||||
{{num_selected}} photo(s) selected
|
||||
</p>
|
||||
</template>
|
||||
<n-scrollbar style="max-height: 80vh;">
|
||||
<n-collapse :default-expanded-names="[first_group_id]">
|
||||
<n-collapse-item v-for="group in sortedPhotoGroups"
|
||||
:key="group.id"
|
||||
:title="group.name"
|
||||
:name="group.id">
|
||||
|
||||
<n-image-group>
|
||||
<n-space>
|
||||
<n-image
|
||||
v-for="photo in photos[group.id]"
|
||||
:key="photo.id"
|
||||
width="100"
|
||||
:src="photo.cropped_image !== null ? photo.cropped_image : photo.original_image"
|
||||
@click="toggle_select_photo(photo.id)"
|
||||
:class="{selected: is_photo_selected(photo.id)}"
|
||||
preview-disabled />
|
||||
</n-space>
|
||||
</n-image-group>
|
||||
|
||||
<template #header-extra>{{group.date}}</template>
|
||||
</n-collapse-item>
|
||||
</n-collapse>
|
||||
</n-scrollbar>
|
||||
<template #action>
|
||||
<n-space justify="end">
|
||||
<n-button @click="this.$emit('closed')">Cancel</n-button>
|
||||
<n-button @click="this.$emit('closed'); this.$emit('selected', this.selection)" type="primary">Select</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useMessage } from 'naive-ui'
|
||||
|
||||
export default {
|
||||
name: 'PhotoSelectModal',
|
||||
emits: [ 'closed', 'selected' ],
|
||||
props: {
|
||||
showSelection: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
max_select: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: Infinity,
|
||||
},
|
||||
or_less: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
alreadySelected: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => {return []}
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const message = useMessage()
|
||||
return { message }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selection: [],
|
||||
photoGroups: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showSelection: function () {
|
||||
if (this.showSelection) {
|
||||
this.selection = [...this.alreadySelected]
|
||||
this.$store.dispatch('loadPhotoGroups').then(() => {
|
||||
this.photoGroups = this.$store.getters.photoGroups
|
||||
this.$store.dispatch('loadPhotosInAllGroups')
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
photos() {
|
||||
return this.$store.getters.photos
|
||||
},
|
||||
num_selected() {
|
||||
return this.selection.length
|
||||
},
|
||||
selecions_left() {
|
||||
return this.max_select - this.num_selected
|
||||
},
|
||||
first_group_id() {
|
||||
if (this.sortedPhotoGroups.length > 0)
|
||||
return this.sortedPhotoGroups[0].id
|
||||
return -1
|
||||
},
|
||||
sortedPhotoGroups() {
|
||||
return [...this.photoGroups].sort((a,b) => {
|
||||
if (a.date === null) return 1
|
||||
if (b.date === null) return -1
|
||||
return a.date > b.date ? -1 : 1
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle_select_photo(photo_id) {
|
||||
if (this.is_photo_selected(photo_id)) {
|
||||
const index = this.selection.indexOf(photo_id)
|
||||
this.selection.splice(index, 1)
|
||||
} else {
|
||||
if (this.selecions_left > 0) {
|
||||
this.selection.push(photo_id)
|
||||
} else {
|
||||
this.message.error('You can only select ' + this.max_select + ' photo(s)')
|
||||
}
|
||||
}
|
||||
},
|
||||
is_photo_selected(photo_id) {
|
||||
return this.selection.includes(photo_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.n-image {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selected {
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
@ -17,9 +17,16 @@ const routes = [
|
||||
component: LogsList
|
||||
},
|
||||
{
|
||||
path: '/logs/create',
|
||||
path: '/logs/create/:e?',
|
||||
name: 'CreateLog',
|
||||
component: CreateLog
|
||||
component: CreateLog,
|
||||
props: (route) => {
|
||||
const e = Number.parseInt(route.params.e)
|
||||
if (Number.isNaN(e)) {
|
||||
return ''
|
||||
}
|
||||
return {e}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1,22 +1,142 @@
|
||||
import { createStore } from 'vuex'
|
||||
import { getPhotoLogList } from '@/api'
|
||||
import {
|
||||
getPhotoLogList,
|
||||
deletePhotoLog,
|
||||
addNewPhotoLog,
|
||||
getPhotoLog,
|
||||
updatePhotoLog,
|
||||
getPhotoGroups,
|
||||
getPhotosByGroup
|
||||
} from '@/api'
|
||||
|
||||
export default createStore({
|
||||
state: {
|
||||
photoLogList: []
|
||||
photoLogList: [],
|
||||
photoLogs: [],
|
||||
photoGroups: [],
|
||||
photos: []
|
||||
},
|
||||
mutations: {
|
||||
SET_PHOTO_LOG_LIST(state, newPhotoLogList) {
|
||||
state.photoLogList = newPhotoLogList
|
||||
},
|
||||
SET_PHOTO_LOG(state, photoLog) {
|
||||
let log_index = state.photoLogs.findIndex(log => log.id === photoLog.id)
|
||||
if (log_index > -1) {
|
||||
state.photoLogs[log_index] = photoLog
|
||||
} else {
|
||||
state.photoLogs.push(photoLog)
|
||||
}
|
||||
},
|
||||
REMOVE_PHOTO_LOG(state, id) {
|
||||
let log_index = state.photoLogList.findIndex(log => log.id === id)
|
||||
state.photoLogList.splice(log_index, 1)
|
||||
},
|
||||
SET_PHOTO_GROUPS(state, groups) {
|
||||
state.photoGroups = groups
|
||||
},
|
||||
SET_PHOTOS_IN_GROUP(state, {group_id, photos}) {
|
||||
if (group_id in state.photos) {
|
||||
state.photos.group_id = photos
|
||||
} else {
|
||||
state.photos = {...state.photos, [group_id]: photos}
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
loadPhotoLogList({commit}) {
|
||||
getPhotoLogList().then((response) => {
|
||||
commit('SET_PHOTO_LOG_LIST', response.data)
|
||||
return new Promise((resolve, reject) => {
|
||||
getPhotoLogList().then((response) => {
|
||||
commit('SET_PHOTO_LOG_LIST', response.data)
|
||||
resolve()
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
loadPhotoLog({commit}, id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getPhotoLog(id).then((response) => {
|
||||
commit('SET_PHOTO_LOG', response.data)
|
||||
resolve()
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
deletePhotoLog({commit}, id) {
|
||||
deletePhotoLog(id).then(() => {
|
||||
commit('REMOVE_PHOTO_LOG', id)
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
addNewPhotoLog({dispatch}, {title, date}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
addNewPhotoLog(title, date).then((response) => {
|
||||
dispatch('loadPhotoLogList')
|
||||
resolve(response.data.id)
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
updatePhotoLogDetails({commit}, photolog) {
|
||||
if (photolog !== null) {
|
||||
commit('SET_PHOTO_LOG', photolog)
|
||||
return updatePhotoLog(photolog)
|
||||
}
|
||||
},
|
||||
loadPhotoGroups({commit}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getPhotoGroups().then((response) => {
|
||||
commit('SET_PHOTO_GROUPS', response.data)
|
||||
resolve(response.data)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
loadPhotosInGroup({commit}, group_id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getPhotosByGroup(group_id).then((response) => {
|
||||
commit('SET_PHOTOS_IN_GROUP', {group_id, photos: response.data})
|
||||
resolve(response.data)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
loadPhotosInAllGroups({dispatch, getters}) {
|
||||
for (const index in getters.photoGroups) {
|
||||
const group_id = getters.photoGroups[index].id
|
||||
dispatch('loadPhotosInGroup', group_id)
|
||||
}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
photoLogById: (state) => (id) => {
|
||||
let log = state.photoLogList.filter(log => log.id == id)
|
||||
if (log.length > 0) {
|
||||
return log[0]
|
||||
}
|
||||
return null
|
||||
},
|
||||
photoLogDetailsById: (state) => (id) => {
|
||||
let log = state.photoLogs.filter(log => log.id == id)
|
||||
if (log.length > 0) {
|
||||
return log[0]
|
||||
}
|
||||
return null
|
||||
},
|
||||
photoGroups (state) {
|
||||
return state.photoGroups
|
||||
},
|
||||
photos (state) {
|
||||
return state.photos
|
||||
}
|
||||
},
|
||||
modules: {},
|
||||
|
@ -1,14 +1,278 @@
|
||||
<template>
|
||||
<h1>Create Log</h1>
|
||||
<div>
|
||||
<n-space justify="space-between">
|
||||
<h1>Create Log</h1>
|
||||
<n-button type="primary">Generate</n-button>
|
||||
</n-space>
|
||||
{{start_slide_image}}
|
||||
{{slides}}
|
||||
|
||||
<n-space justify="space-around">
|
||||
<n-input size="large" round placeholder="Photo Log title" v-model:value="title" @change="updateServerData" />
|
||||
<n-date-picker v-model:value="date" type="date" @update:value="updateServerData" />
|
||||
</n-space>
|
||||
|
||||
<n-divider title-placement="center">Slides</n-divider>
|
||||
|
||||
<n-space vertical>
|
||||
<n-card
|
||||
style="width: 80%;"
|
||||
v-for="(slide, index) in editSlides" :key="index"
|
||||
:title="'#'+(index+1)" >
|
||||
|
||||
<n-image-group>
|
||||
<n-space>
|
||||
<n-image
|
||||
v-for="(photo_id, photoIndex) in slide" :key="photoIndex"
|
||||
width="100"
|
||||
:src="getPhotoSrcById(photo_id)"
|
||||
/>
|
||||
|
||||
<n-button round dashed type="info" @click="selectPhotosForSlide(index)"> Edit </n-button>
|
||||
</n-space>
|
||||
</n-image-group>
|
||||
|
||||
|
||||
</n-card>
|
||||
</n-space>
|
||||
|
||||
<PhotoSelectModal
|
||||
v-model:showSelection="selectPhotosModal"
|
||||
@closed="selectPhotosModal=false"
|
||||
@selected="addPhotosToSlide"
|
||||
:max_select=max_photos_per_slide :or_less=true
|
||||
:already-selected=editSlides[selectedSlide] />
|
||||
|
||||
<n-modal v-model:show="showCreateModal" :mask-closable=false>
|
||||
<n-spin :show="isCreateLoading">
|
||||
<n-card
|
||||
style="width: 600px;"
|
||||
title="Create a new Photo Log"
|
||||
:bordered="false"
|
||||
size="huge"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
|
||||
<n-form-item label="What's the name of the photo log?" path="title">
|
||||
<n-input v-model:value="title" type="text" placeholder="Photo Log title" />
|
||||
</n-form-item>
|
||||
<n-form-item label="When did the training take place?" path="date">
|
||||
<n-date-picker v-model:value="date" type="date" clearable />
|
||||
</n-form-item>
|
||||
|
||||
<template #footer>
|
||||
<n-space justify="end">
|
||||
<n-button @click="navigateBack">Cancel</n-button>
|
||||
<n-button @click="createNewPhotoLog" type="success">Create</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
</n-card>
|
||||
</n-spin>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useMeta } from 'vue-meta'
|
||||
import { useMessage } from 'naive-ui'
|
||||
|
||||
import PhotoSelectModal from '@/components/PhotoSelectModal'
|
||||
|
||||
export default {
|
||||
name: 'CreateLog',
|
||||
components: {
|
||||
PhotoSelectModal,
|
||||
},
|
||||
props: {
|
||||
e: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: -1,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: Number.parseInt(this.e),
|
||||
title: '',
|
||||
date: null,
|
||||
render_date: false,
|
||||
start_slide_image: null,
|
||||
slides: [],
|
||||
|
||||
selectPhotosModal: false,
|
||||
selectedSlide: null,
|
||||
max_photos_per_slide: 3,
|
||||
|
||||
isLoadingData: false,
|
||||
isCreateLoading: false,
|
||||
isSavingServer: false,
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
useMeta({ title: 'Create a new Photo Log' })
|
||||
const message = useMessage()
|
||||
return { message }
|
||||
},
|
||||
mounted() {
|
||||
if (this.isValidId()) {
|
||||
this.isLoadingData = true
|
||||
|
||||
this.$store.dispatch('loadPhotoGroups').then(() => {
|
||||
this.photoGroups = this.$store.getters.photoGroups
|
||||
this.$store.dispatch('loadPhotosInAllGroups')
|
||||
})
|
||||
|
||||
this.findPhotoLog().then(() => {
|
||||
this.updateLocalData()
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editSlides() {
|
||||
return [...this.slides, []]
|
||||
},
|
||||
photos() {
|
||||
return this.$store.getters.photos
|
||||
},
|
||||
showCreateModal () {
|
||||
return !this.isValidId()
|
||||
},
|
||||
dateStr () {
|
||||
if (this.date !== null) {
|
||||
let date_obj = new Date(this.date)
|
||||
let month = Number.parseInt(date_obj.getMonth())+1
|
||||
month = month < 10 ? '0' + month : month
|
||||
let day = Number.parseInt(date_obj.getDate())
|
||||
day = day < 10 ? '0' + day : day
|
||||
let date_str = date_obj.getFullYear() + '-' + month + '-' + day
|
||||
return date_str
|
||||
}
|
||||
return '1970-01-01'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectPhotosForSlide(slide_index) {
|
||||
this.selectedSlide = slide_index
|
||||
this.selectPhotosModal = true
|
||||
},
|
||||
getPhotoSrcById(photo_id){
|
||||
for (const index in this.photos) {
|
||||
let group = this.photos[index]
|
||||
let photo = group.filter((photo) => photo.id == photo_id)
|
||||
if (photo.length > 0) {
|
||||
photo = photo[0]
|
||||
return photo.cropped_image !== null ? photo.cropped_image : photo.original_image
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
addPhotosToSlide(selected_photos) {
|
||||
this.slides[this.selectedSlide] = selected_photos
|
||||
this.updateServerData()
|
||||
},
|
||||
navigateBack() {
|
||||
this.$router.go(-1)
|
||||
},
|
||||
createNewPhotoLog() {
|
||||
if (this.title.length > 0 && this.date !== null) {
|
||||
this.isCreateLoading = true
|
||||
this.$store.dispatch('addNewPhotoLog', {title:this.title, date:this.dateStr}).then(id => {
|
||||
if (id > -1 && id !== null) {
|
||||
this.id = id
|
||||
this.$router.push({name: 'CreateLog', params: {e: id}})
|
||||
} else {
|
||||
this.message.error('Something went wrong. Please try again later.')
|
||||
}
|
||||
}).finally(() => {
|
||||
this.isCreateLoading = false
|
||||
})
|
||||
} else {
|
||||
if (this.title.length <= 0)
|
||||
this.message.error('Please enter a title')
|
||||
if (this.date === null)
|
||||
this.message.error('Please enter a date')
|
||||
}
|
||||
},
|
||||
isValidId() {
|
||||
return !(
|
||||
this.id == null
|
||||
|| Number.isNaN(this.id)
|
||||
|| this.id <= 0
|
||||
|| this.id === undefined
|
||||
)
|
||||
},
|
||||
findPhotoLog() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let found_log = this.$store.getters.photoLogById(this.id)
|
||||
if (found_log === null) {
|
||||
this.$store.dispatch('loadPhotoLogList').then(() => {
|
||||
found_log = this.$store.getters.photoLogById(this.id)
|
||||
if (found_log === null) {
|
||||
this.message.error('Photo Log could not be found')
|
||||
reject()
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
}).catch(() => {
|
||||
reject()
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
updateLocalData() {
|
||||
let found_log = null
|
||||
this.$store.dispatch('loadPhotoLog', this.id).then(() => {
|
||||
found_log = this.$store.getters.photoLogDetailsById(this.id)
|
||||
if (found_log !== null) {
|
||||
this.title = found_log.title
|
||||
this.date = new Date(found_log.date).getTime()
|
||||
this.render_date = found_log.render_date
|
||||
this.start_slide_image = found_log.start_slide_image
|
||||
this.slides = found_log.slides
|
||||
this.isLoadingData = false
|
||||
} else {
|
||||
this.message.error('Photo Log could not be found')
|
||||
}
|
||||
})
|
||||
},
|
||||
updateServerData() {
|
||||
this.isSavingServer = true
|
||||
this.$store.dispatch('updatePhotoLogDetails', {
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
date: this.dateStr,
|
||||
render_date: this.render_date,
|
||||
start_slide_image: this.start_slide_image,
|
||||
slides: this.slides
|
||||
}).then(() => {
|
||||
this.message.success('Changes saved')
|
||||
}).finally(() => {
|
||||
this.isSavingServer = false
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeRouteUpdate (to) {
|
||||
this.id = Number.parseInt(to.params.e)
|
||||
if (this.isValidId()) {
|
||||
this.isLoadingData = true
|
||||
this.findPhotoLog().then(()=> {
|
||||
this.updateLocalData()
|
||||
})
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
beforeRouteLeave (to, from) {
|
||||
// prevent from leaving with unsaved changes
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.n-input {
|
||||
min-width: 30em;
|
||||
}
|
||||
</style>
|
@ -9,7 +9,9 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="photolog in photoLogList" :key="photolog.id">
|
||||
<td>{{ photolog.title }}</td>
|
||||
<router-link :to="{name: 'CreateLog', params: {e: photolog.id}}">
|
||||
<td>{{ photolog.title }}</td>
|
||||
</router-link>
|
||||
<td>{{ photolog.date }}</td>
|
||||
<td>
|
||||
<n-button type="error" @click="askDeleteLog(photolog.id)">Delete</n-button>
|
||||
@ -72,7 +74,10 @@ export default {
|
||||
this.deleteModalContent = 'Do you want to permanently delete "' + logtitle + '"?'
|
||||
},
|
||||
deleteLog() {
|
||||
console.log('delete ' + this.deleteId)
|
||||
if (this.deleteId !== null) {
|
||||
this.$store.dispatch('deletePhotoLog', this.deleteId)
|
||||
this.deleteId = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user