mirror of
https://github.com/MarcZierle/photo-log-frontend.git
synced 2025-04-09 22:04:38 +00:00
add subgroups
This commit is contained in:
parent
3db2070ef3
commit
f5148dd017
43
package-lock.json
generated
43
package-lock.json
generated
@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "zierle-training-online-tools",
|
"name": "zierle-training-online-tools",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "zierle-training-online-tools",
|
"name": "zierle-training-online-tools",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"autoprefixer": "^9.8.8",
|
"autoprefixer": "^9.8.8",
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
|
"lorem-ipsum": "^2.0.8",
|
||||||
"postcss": "^7.0.39",
|
"postcss": "^7.0.39",
|
||||||
"tailwind-children": "^0.5.0",
|
"tailwind-children": "^0.5.0",
|
||||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
|
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
|
||||||
@ -2542,6 +2543,29 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
|
||||||
"integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg=="
|
"integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lorem-ipsum": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/lorem-ipsum/-/lorem-ipsum-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^9.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"lorem-ipsum": "dist/bin/lorem-ipsum.bin.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.x",
|
||||||
|
"npm": ">= 5.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lorem-ipsum/node_modules/commander": {
|
||||||
|
"version": "9.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
||||||
|
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
@ -5890,6 +5914,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
|
||||||
"integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg=="
|
"integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg=="
|
||||||
},
|
},
|
||||||
|
"lorem-ipsum": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/lorem-ipsum/-/lorem-ipsum-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==",
|
||||||
|
"requires": {
|
||||||
|
"commander": "^9.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "9.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
|
||||||
|
"integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
@ -3,14 +3,15 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
|
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"autoprefixer": "^9.8.8",
|
"autoprefixer": "^9.8.8",
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
|
"lorem-ipsum": "^2.0.8",
|
||||||
"postcss": "^7.0.39",
|
"postcss": "^7.0.39",
|
||||||
"tailwind-children": "^0.5.0",
|
"tailwind-children": "^0.5.0",
|
||||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
|
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
const apiClient = axios.create({
|
const apiClient = axios.create({
|
||||||
baseURL: 'https://zierle-training-staging.riezel.com/api/v1',
|
baseURL: 'https://zierle-training.riezel.com/api/v1',
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="flex flex-row static">
|
<nav
|
||||||
|
class="flex flex-row fixed top-0 z-50 w-full transition-all bg-white"
|
||||||
|
:class="{
|
||||||
|
'bg-opacity-100' : showNavBg,
|
||||||
|
'bg-opacity-0' : !showNavBg,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<router-link :to="{name: 'Home'}">Home</router-link>
|
<router-link :to="{name: 'Home'}">Home</router-link>
|
||||||
<router-link :to="{name: 'ManagePhotos'}">Photos</router-link>
|
<router-link :to="{name: 'ManagePhotos'}">Photos</router-link>
|
||||||
<router-link :to="{name: 'LogsList'}">All Logs</router-link>
|
<router-link :to="{name: 'LogsList'}">All Logs</router-link>
|
||||||
@ -13,24 +19,37 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'NavBar',
|
name: 'NavBar',
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
}
|
scrollThreshold: 120,
|
||||||
|
scrollPosition: 0,
|
||||||
|
showNavBg: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
window.addEventListener('scroll', this.updateScrollPosition)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateScrollPosition() {
|
||||||
|
this.scrollPosition = window.scrollY
|
||||||
|
|
||||||
|
if (!this.showNavBg && this.scrollPosition >= this.scrollThreshold) {
|
||||||
|
this.showNavBg = true
|
||||||
|
} else if (this.showNavBg && this.scrollPosition <= 10) {
|
||||||
|
this.showNavBg = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
nav {
|
nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0px 0px 10px rgba(0,0,0,0.2);
|
|
||||||
margin-bottom: 1em;
|
|
||||||
background: rgba(255,255,255,0.2);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
padding: 0.75em;
|
padding: 0.75em;
|
||||||
transition: all 0.15s ease-in-out;
|
transition: all 0.15s ease-in-out;
|
||||||
border-right: 1px solid #eee;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.router-link-exact-active,
|
.router-link-exact-active,
|
||||||
|
48
src/components/ui/PrimaryButton.vue
Normal file
48
src/components/ui/PrimaryButton.vue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<button
|
||||||
|
@click="emit('click')"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
emits: ['click'],
|
||||||
|
setup () {
|
||||||
|
|
||||||
|
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
button {
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
height: 3.5rem;
|
||||||
|
padding: 0 26px;
|
||||||
|
line-height: 2;
|
||||||
|
color: rgb(250, 251, 252);
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(180deg,rgba(66,76,222,.2),transparent 100%,rgba(66,76,222,0) 0),linear-gradient(90deg,rgba(37,6,228,.8),rgba(54,126,255,.8) 80%,rgba(54,126,255,.8)),rgba(66,76,222,.8);
|
||||||
|
box-shadow: 0 4px 4px rgb(0 0 0 / 8%), 0 -1px 1px rgb(0 0 0 / 8%), 0 2px 2px rgb(0 0 0 / 16%), inset 0 1px 0 hsl(0deg 0% 100% / 16%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
background-position-x: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: Eina,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
|
||||||
|
font-size: .9375rem;
|
||||||
|
text-transform: none;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: .625rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-position-x: 98%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background-position-x: 0%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="banner-bg">
|
<div class="banner-bg opacity-50">
|
||||||
<div>
|
<div>
|
||||||
<n-gradient-text :size="40" type="success">
|
<n-gradient-text :size="40" type="success">
|
||||||
Zierle-Training
|
Zierle-Training
|
||||||
@ -17,7 +17,9 @@
|
|||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
<h2 class="font-bold text-xl mb-4">Documents</h2>
|
<h2 class="font-bold text-xl mb-4">Documents</h2>
|
||||||
<a target="_blank" href='https://dev.marczierle.com/zierle-training/generate_document/modify_document.php?selection=0'>
|
<a target="_blank" href='https://dev.marczierle.com/zierle-training/generate_document/modify_document.php?selection=0'>
|
||||||
<n-button type="primary">All Documents</n-button>
|
<PrimaryButton>
|
||||||
|
All Documents
|
||||||
|
</PrimaryButton>
|
||||||
</a>
|
</a>
|
||||||
</n-space>
|
</n-space>
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
@ -46,6 +48,8 @@
|
|||||||
<n-button @click='set_lang("en")'>EN</n-button>
|
<n-button @click='set_lang("en")'>EN</n-button>
|
||||||
<n-button @click='set_lang("de")'>DE</n-button>
|
<n-button @click='set_lang("de")'>DE</n-button>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
{{ lorem.generateParagraphs(20) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -54,10 +58,29 @@
|
|||||||
import CameraAdd20Filled from '@vicons/fluent/CameraAdd20Filled'
|
import CameraAdd20Filled from '@vicons/fluent/CameraAdd20Filled'
|
||||||
import { loadAndSetLocale } from '@/i18n.js'
|
import { loadAndSetLocale } from '@/i18n.js'
|
||||||
|
|
||||||
|
import PrimaryButton from '../components/ui/PrimaryButton.vue'
|
||||||
|
|
||||||
|
import { LoremIpsum } from "lorem-ipsum"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HomeView',
|
name: 'HomeView',
|
||||||
components: {
|
components: {
|
||||||
CameraAdd20Filled
|
CameraAdd20Filled,
|
||||||
|
PrimaryButton,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const lorem = new LoremIpsum({
|
||||||
|
sentencesPerParagraph: {
|
||||||
|
max: 8,
|
||||||
|
min: 4
|
||||||
|
},
|
||||||
|
wordsPerSentence: {
|
||||||
|
max: 16,
|
||||||
|
min: 4
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { lorem }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
set_lang(locale) {
|
set_lang(locale) {
|
||||||
|
@ -2,15 +2,50 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1 class="font-bold text-2xl m-4 my-6">Manage Photos</h1>
|
<h1 class="font-bold text-2xl m-4 my-6">Manage Photos</h1>
|
||||||
<n-collapse
|
<n-collapse
|
||||||
v-if="photoGroups && photoGroups.length > 0"
|
v-if="parentPhotoGroups && parentPhotoGroups.length > 0"
|
||||||
@item-header-click="loadPhotosInGroup"
|
@item-header-click="loadPhotosInGroup"
|
||||||
>
|
>
|
||||||
<n-collapse-item
|
<n-collapse-item
|
||||||
v-for="group in photoGroups" :key="group.id"
|
v-for="group in parentPhotoGroups" :key="group.id"
|
||||||
:title="group.name"
|
:title="group.name"
|
||||||
:name="group.id">
|
:name="group.id">
|
||||||
<template #header-extra>{{ group.date }}</template>
|
<template #header-extra>{{ group.date }}</template>
|
||||||
|
|
||||||
|
<n-space
|
||||||
|
v-if="groupsInPhotogroup(group.id).length > 0"
|
||||||
|
>
|
||||||
|
<n-collapse-item
|
||||||
|
v-for="group in groupsInPhotogroup(group.id)" :key="group.id"
|
||||||
|
:title="group.name"
|
||||||
|
:name="group.id"
|
||||||
|
>
|
||||||
|
<template #header-extra>{{ group.date }}</template>
|
||||||
|
|
||||||
|
<div style="text-align: center">
|
||||||
|
<p v-if="is_group_loading.get(group.id)">loading...</p>
|
||||||
|
<p v-else-if="!photos[group.id]">no photos in group found</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<n-space>
|
||||||
|
<PhotoItem
|
||||||
|
v-for="(photo, idx) in photos[group.id]" :key="idx"
|
||||||
|
:src="getPhotoSrcById(photo.id)"
|
||||||
|
:can_change_group="true"
|
||||||
|
:can_crop="true"
|
||||||
|
:can_change_ocr="true"
|
||||||
|
:can_change_tag="true"
|
||||||
|
:can_delete="true"
|
||||||
|
:loading="photosStatus[photo.id] === 'cropping'"
|
||||||
|
@update:group="change_group_modal(photo.id)"
|
||||||
|
@update:crop="change_crop_modal(photo.id)"
|
||||||
|
@update:ocr="change_ocr_modal(photo.id)"
|
||||||
|
@update:tag="change_tag_modal(photo.id)"
|
||||||
|
@update:delete="change_delete_modal(photo.id)"
|
||||||
|
/>
|
||||||
|
</n-space>
|
||||||
|
</n-collapse-item>
|
||||||
|
</n-space>
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<p v-if="is_group_loading.get(group.id)">loading...</p>
|
<p v-if="is_group_loading.get(group.id)">loading...</p>
|
||||||
<p v-else-if="!photos[group.id]">no photos in group found</p>
|
<p v-else-if="!photos[group.id]">no photos in group found</p>
|
||||||
@ -192,7 +227,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
photoGroups() {
|
allPhotoGroups() {
|
||||||
let groups = this.$store.state.photoGroups
|
let groups = this.$store.state.photoGroups
|
||||||
if (groups !== null && groups.length > 0) {
|
if (groups !== null && groups.length > 0) {
|
||||||
groups = [...groups].sort((a,b) => {
|
groups = [...groups].sort((a,b) => {
|
||||||
@ -207,6 +242,11 @@ export default {
|
|||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
},
|
},
|
||||||
|
parentPhotoGroups() {
|
||||||
|
let groups = this.allPhotoGroups
|
||||||
|
groups = groups.filter(group => group.parent === undefined || group.parent === null)
|
||||||
|
return groups
|
||||||
|
},
|
||||||
photoTags() {
|
photoTags() {
|
||||||
let tags = this.$store.state.photoTags
|
let tags = this.$store.state.photoTags
|
||||||
if (tags !== null && tags.length > 0) {
|
if (tags !== null && tags.length > 0) {
|
||||||
@ -221,12 +261,12 @@ export default {
|
|||||||
return this.$store.state.photosStatus
|
return this.$store.state.photosStatus
|
||||||
},
|
},
|
||||||
groups_select_options() {
|
groups_select_options() {
|
||||||
if (this.photoGroups.length > 0) {
|
if (this.allPhotoGroups.length > 0) {
|
||||||
let options = []
|
let options = []
|
||||||
for (const idx in this.photoGroups) {
|
for (const idx in this.allPhotoGroups) {
|
||||||
options.push({
|
options.push({
|
||||||
value: this.photoGroups[idx].id,
|
value: this.allPhotoGroups[idx].id,
|
||||||
label: this.photoGroups[idx].name,
|
label: this.allPhotoGroups[idx].name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return options
|
return options
|
||||||
@ -256,6 +296,11 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
groupsInPhotogroup(groupId) {
|
||||||
|
let groups = this.allPhotoGroups
|
||||||
|
groups = groups.filter(group => group.parent === groupId)
|
||||||
|
return groups
|
||||||
|
},
|
||||||
loadPhotosInGroup(group_data) {
|
loadPhotosInGroup(group_data) {
|
||||||
this.is_group_loading.set(group_data.name, true)
|
this.is_group_loading.set(group_data.name, true)
|
||||||
if (group_data.expanded)
|
if (group_data.expanded)
|
||||||
|
Loading…
Reference in New Issue
Block a user