mirror of
https://github.com/MarcZierle/photo-log-frontend.git
synced 2025-04-07 21:14: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 charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<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>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -12,4 +12,40 @@ const apiClient = axios.create({
|
|||||||
|
|
||||||
export function getPhotoLogList() {
|
export function getPhotoLogList() {
|
||||||
return apiClient.get('/photologs/')
|
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
|
component: LogsList
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/logs/create',
|
path: '/logs/create/:e?',
|
||||||
name: 'CreateLog',
|
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 { createStore } from 'vuex'
|
||||||
import { getPhotoLogList } from '@/api'
|
import {
|
||||||
|
getPhotoLogList,
|
||||||
|
deletePhotoLog,
|
||||||
|
addNewPhotoLog,
|
||||||
|
getPhotoLog,
|
||||||
|
updatePhotoLog,
|
||||||
|
getPhotoGroups,
|
||||||
|
getPhotosByGroup
|
||||||
|
} from '@/api'
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
state: {
|
state: {
|
||||||
photoLogList: []
|
photoLogList: [],
|
||||||
|
photoLogs: [],
|
||||||
|
photoGroups: [],
|
||||||
|
photos: []
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_PHOTO_LOG_LIST(state, newPhotoLogList) {
|
SET_PHOTO_LOG_LIST(state, newPhotoLogList) {
|
||||||
state.photoLogList = 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: {
|
actions: {
|
||||||
loadPhotoLogList({commit}) {
|
loadPhotoLogList({commit}) {
|
||||||
getPhotoLogList().then((response) => {
|
return new Promise((resolve, reject) => {
|
||||||
commit('SET_PHOTO_LOG_LIST', response.data)
|
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) => {
|
}).catch((error) => {
|
||||||
console.log(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: {},
|
modules: {},
|
||||||
|
@ -1,14 +1,278 @@
|
|||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { useMeta } from 'vue-meta'
|
import { useMeta } from 'vue-meta'
|
||||||
|
import { useMessage } from 'naive-ui'
|
||||||
|
|
||||||
|
import PhotoSelectModal from '@/components/PhotoSelectModal'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreateLog',
|
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() {
|
setup() {
|
||||||
useMeta({ title: 'Create a new Photo Log' })
|
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>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="photolog in photoLogList" :key="photolog.id">
|
<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>{{ photolog.date }}</td>
|
||||||
<td>
|
<td>
|
||||||
<n-button type="error" @click="askDeleteLog(photolog.id)">Delete</n-button>
|
<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 + '"?'
|
this.deleteModalContent = 'Do you want to permanently delete "' + logtitle + '"?'
|
||||||
},
|
},
|
||||||
deleteLog() {
|
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