Skip to content

Commit

Permalink
feat: allow multiple series per book
Browse files Browse the repository at this point in the history
As usual : BACKUP YOUR DATABASE FIRST
It should be now possible to set multiple series for each book.
Each series is now its own entity in DB which should allow
multiple distinct series with the same name.
  • Loading branch information
bayang committed Nov 1, 2023
1 parent 96d8f12 commit a9c5979
Show file tree
Hide file tree
Showing 55 changed files with 1,917 additions and 294 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ dependencies {

implementation("org.xerial:sqlite-jdbc")
implementation("org.liquibase:liquibase-core")
val exposedVersion = "0.41.1"
val exposedVersion = "0.43.0"
implementation("org.jetbrains.exposed:exposed-spring-boot-starter:$exposedVersion")
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
// implementation("org.nuvito.spring.data:sqlite-dialect:1.0-SNAPSHOT")
Expand Down
17 changes: 16 additions & 1 deletion src/jelu-ui/src/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
@apply radio radio-primary radio-sm bg-none;
}


.o-pag__link {
@apply btn text-neutral-content !important;
}
Expand Down Expand Up @@ -141,6 +140,18 @@
@apply text-gray-700;
}

.o-ctrl-input > input[type="number"] {
@apply w-24;
}

.o-acp .o-ctrl-input .o-input {
@apply w-fit sm:w-full bg-base-100 text-base-content border-base-200 focus:input-accent grow;
}

.o-acp {
@apply grow !important;
}

/* end oruga customization with daisyui */

.swal2-container {
Expand Down Expand Up @@ -346,3 +357,7 @@
.jelu-cursor-text {
@apply cursor-text !important;
}

.jl-formkit .o-input {
@apply w-fit sm:w-full bg-base-100 text-base-content border-primary focus:input-accent;
}
94 changes: 64 additions & 30 deletions src/jelu-ui/src/components/AddBook.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { key } from '../store';
import { ObjectUtils } from "../utils/ObjectUtils";
import { StringUtils } from "../utils/StringUtils";
import AutoImportFormModalVue from "./AutoImportFormModal.vue";
import { SeriesOrder } from "../model/Series";
import SeriesInput from "./SeriesInput.vue";
const { t } = useI18n({
inheritLocale: true,
Expand All @@ -37,9 +39,6 @@ const form = reactive({
isbn13: "",
publisher: "",
pageCount: null,
// publishedDate: <Date> null,
series: "",
numberInSeries: null,
personalNotes: "",
owned: null,
borrowed: null,
Expand Down Expand Up @@ -94,9 +93,11 @@ let tags: Ref<Array<Tag>> = ref([]);
let translators: Ref<Array<Author>> = ref([]);
let filteredTranslators: Ref<Array<Author>> = ref([]);
let seriesCopy: Ref<Array<SeriesOrder>> = ref([])
const showModal: Ref<boolean> = ref(false)
const metadata: Ref<Metadata | null> = ref(null)
// let hasImage: Ref<boolean> = ref(metadata?.value?.image != null)
let hasImage = computed(() => {
return StringUtils.isNotBlank(metadata.value?.image)
})
Expand Down Expand Up @@ -136,10 +137,16 @@ const importBook = async () => {
authors.value.forEach((a) => userBook.book.authors?.push(a));
tags.value.forEach((t) => userBook.book.tags?.push(t));
translators.value.forEach((tr) => userBook.book.translators?.push(tr));
seriesCopy.value.forEach((s) => {
if (s.name.trim().length > 0) {
userBook.book.series?.push(s)
}
})
if (StringUtils.isNotBlank(imageUrl.value)) {
userBook.book.image = imageUrl.value;
}
else if (!deleteImage.value
&& metadata.value != null
&& metadata.value?.image != null
&& StringUtils.isNotBlank(metadata.value.image)) {
userBook.book.image = metadata.value.image
Expand Down Expand Up @@ -171,7 +178,6 @@ const importBook = async () => {
await router.push({name: 'my-books'})
} catch (error: any) {
progress.value = false
// errorMessage.value = error.message
ObjectUtils.toast(oruga, "danger", t('labels.error_message', {msg : error.message}), 4000)
}
} else {
Expand All @@ -190,8 +196,7 @@ const fillBook = (formdata: any, publishedDate: Date | null): UserBook => {
image: formdata.image,
pageCount: formdata.pageCount,
publishedDate: publishedDate?.toISOString(),
series: formdata.series,
numberInSeries: formdata.numberInSeries,
series: [],
googleId: formdata.googleId,
amazonId: formdata.amazonId,
goodreadsId: formdata.goodreadsId,
Expand Down Expand Up @@ -225,11 +230,9 @@ const clearForm = () => {
form.isbn13 = "";
form.publisher = "";
form.pageCount = null;
// form.publishedDate = null;
publishedDate.value = null
form.series = ""
seriesCopy.value = []
form.language = ""
form.numberInSeries = null
form.owned = null
form.personalNotes = ""
form.amazonId = ""
Expand All @@ -241,7 +244,6 @@ const clearForm = () => {
const clearDatePicker = () => {
// close datepicker on reset
// form.publishedDate = null;
publishedDate.value = null
};
Expand Down Expand Up @@ -382,6 +384,8 @@ function modalClosed() {
const mergeMetadata = () => {
for (let key in metadata.value) {
console.log("key")
console.log(key)
if (key in form) {
let castKey = key as (keyof typeof metadata.value & keyof typeof form);
(form[castKey] as any) = metadata.value[castKey];
Expand All @@ -400,6 +404,12 @@ const mergeMetadata = () => {
if (metadata.value?.publishedDate && StringUtils.isNotBlank(metadata.value?.publishedDate)) {
publishedDate.value = new Date(metadata.value?.publishedDate)
}
if (metadata.value?.series != null && metadata.value?.series?.length > 0) {
seriesCopy.value.push({
"name": metadata.value?.series,
"numberInSeries" : metadata.value.numberInSeries
})
}
}
const isbn10ValidationMessage = ref("")
Expand Down Expand Up @@ -452,10 +462,10 @@ let displayDatepicker = computed(() => {

<template>
<section>
<div class="grid columns is-multiline is-centered">
<div class="grid sm:grid-cols-3 mb-4 sm:w-10/12 justify-center justify-items-center justify-self-center column is-centered is-offset-one-fifth is-three-fifths">
<div class="grid columns is-multiline">
<div class="grid sm:grid-cols-3 mb-4 sm:w-10/12 justify-center justify-items-center justify-self-center column is-offset-one-fifth is-three-fifths">
<div />
<h1 class="text-2xl title has-text-weight-normal typewriter capitalize">
<h1 class="text-2xl typewriter capitalize">
{{ t('nav.add_book') }}
</h1>
<div class="flex">
Expand Down Expand Up @@ -486,7 +496,7 @@ let displayDatepicker = computed(() => {
</svg>
</div>
</div>
<div class="form-control sm:w-8/12 justify-center justify-items-center justify-self-center column is-two-thirds">
<div class="form-control sm:w-8/12 justify-self-center column is-two-thirds">
<div class="field mb-3">
<o-field
horizontal
Expand All @@ -510,7 +520,7 @@ let displayDatepicker = computed(() => {
v-model="authors"
:data="filteredAuthors"
:allow-autocomplete="true"
:autocomplete="true"
autocomplete="off"
:allow-new="true"
:allow-duplicates="false"
:open-on-focus="true"
Expand All @@ -534,7 +544,7 @@ let displayDatepicker = computed(() => {
v-model="tags"
:data="filteredTags"
:allow-autocomplete="true"
:autocomplete="true"
autocomplete="off"
:allow-new="true"
:allow-duplicates="false"
:open-on-focus="true"
Expand All @@ -558,7 +568,7 @@ let displayDatepicker = computed(() => {
v-model="translators"
:data="filteredTranslators"
:allow-autocomplete="true"
:autocomplete="true"
autocomplete="off"
:allow-new="true"
:allow-duplicates="false"
:open-on-focus="true"
Expand Down Expand Up @@ -714,21 +724,45 @@ let displayDatepicker = computed(() => {
</div>
<div class="field mb-3">
<o-field
horizontal
:label="t('book.series')"
horizontal
class="capitalize"
>
<o-input
v-model="form.series"
class="input focus:input-accent"
/>
<o-input
v-model="form.numberInSeries"
type="number"
min="0"
step="0.1"
class="input focus:input-accent"
/>
<div
v-for="seriesItem,idx in seriesCopy"
:key="seriesItem.seriesId"
class="flex flex-col sm:flex-row items-center grow w-full pb-2"
>
<SeriesInput
:series="seriesItem"
:parent-series="seriesCopy"
@update-series="(series: SeriesOrder) => seriesCopy[idx] = series"
/>
<button
class="btn btn-error btn-outline sm:btn-sm px-1 sm:border-none"
@click="seriesCopy.splice(idx, 1)"
>
<span class="icon">
<i class="mdi mdi-delete mdi-18px" />
</span>
</button>
</div>
</o-field>
</div>
<div class="field mb-3">
<o-field
label=""
horizontal
class="capitalize"
>
<button
class="btn btn-primary btn-circle p-2 btn-sm"
@click="seriesCopy.push({'name' : ''})"
>
<span class="icon">
<i class="mdi mdi-plus mdi-18px" />
</span>
</button>
</o-field>
</div>
<div class="block">
Expand Down
6 changes: 1 addition & 5 deletions src/jelu-ui/src/components/AdminAuthors.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<script setup lang="ts">
import { useProgrammatic } from "@oruga-ui/oruga-next"
import { useTitle } from '@vueuse/core'
import { computed, onMounted, Ref, ref } from 'vue'
import { computed, Ref, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { Author } from "../model/Author"
import dataService from "../services/DataService"
import { key } from '../store'
import { StringUtils } from "../utils/StringUtils"
import dayjs from "dayjs";
import useDates from '../composables/dates'
Expand All @@ -20,7 +18,6 @@ const { t, locale, availableLocales } = useI18n({
useScope: 'global'
})
const store = useStore(key)
const router = useRouter()
const { oruga } = useProgrammatic();
Expand Down Expand Up @@ -179,7 +176,6 @@ const rightDoD = computed(() => {
</o-field>
</div>
</div>
<!-- <div class=""> -->
<div class="justify-self-center col-span-2 sm:col-span-1 w-11/12 sm:w-8/12">
<div class="field">
<o-field
Expand Down
2 changes: 1 addition & 1 deletion src/jelu-ui/src/components/AdminBase.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { useTitle } from '@vueuse/core'
import { onMounted, ref } from 'vue'
import { ref } from 'vue'
import { useStore } from 'vuex'
import { key } from '../store'
import { useI18n } from 'vue-i18n'
Expand Down
9 changes: 3 additions & 6 deletions src/jelu-ui/src/components/AdminUsers.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<script setup lang="ts">
import { setErrors } from '@formkit/vue'
import { useProgrammatic } from "@oruga-ui/oruga-next"
import { useTitle } from '@vueuse/core'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
import dataService from "../services/DataService"
import { key } from '../store'
import { setErrors } from '@formkit/vue'
import { ObjectUtils } from "../utils/ObjectUtils";
import { useProgrammatic } from "@oruga-ui/oruga-next";
import { ObjectUtils } from "../utils/ObjectUtils"
const { t } = useI18n({
inheritLocale: true,
Expand All @@ -16,7 +14,6 @@ const { t } = useI18n({
useTitle('Jelu | Users admin')
const store = useStore(key)
const { oruga } = useProgrammatic()
const form = ref({'login' : '', 'password' : '', 'admin': false})
Expand Down
2 changes: 1 addition & 1 deletion src/jelu-ui/src/components/AuthorBooks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ getBooks()
<div class="grid items-center justify-center justify-items-center justify-self-center sm:grid-cols-3 mb-4 sm:w-10/12 column is-full">
<div />
<div class="level-item">
<h2 class="text-2xl inline mr-2 title has-text-weight-normal typewriter">
<h2 class="text-2xl inline mr-2 typewriter">
{{ author.name }}
</h2>
<button
Expand Down
2 changes: 1 addition & 1 deletion src/jelu-ui/src/components/AutoImportFormModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function pluginsModalClosed() {
<section class="edit-modal">
<div class="grid justify-center justify-items-center columns is-centered is-multiline">
<div class="mb-2">
<h1 class="text-2xl title has-text-weight-normal typewriter capitalize">
<h1 class="text-2xl typewriter capitalize">
{{ t('labels.import_book') }}
</h1>
</div>
Expand Down
7 changes: 3 additions & 4 deletions src/jelu-ui/src/components/BookCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ const toggleEdit = (book: UserBook) => {
watch(checked, (newVal, oldVal) => {
console.log(props.book.id + " " + checked.value)
// console.log(newVal + " " + oldVal)
emit("update:checked", props.book.id != null ? props.book.id : null , checked.value)
})
Expand Down Expand Up @@ -225,11 +224,11 @@ watch(checked, (newVal, oldVal) => {
>{{ eventText }}</span>
<div class="flex">
<span
v-if="book.book.numberInSeries"
v-tooltip="book.book.series"
v-if="book.book.series && book.book.series.length > 0"
v-tooltip="book.book.series[0].name"
class="badge is-family-sans-serif mx-1"
>
#{{ book.book.numberInSeries }}
#{{ book.book.series[0].numberInSeries }}
</span>
<span
v-if="book.owned"
Expand Down
Loading

0 comments on commit a9c5979

Please sign in to comment.