@christianriedl/media 1.0.183 → 1.0.185
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref } from 'vue';
|
|
2
|
+
import { ref, computed } from 'vue';
|
|
3
3
|
import { IBook } from '@christianriedl/media';
|
|
4
4
|
|
|
5
|
-
const props = defineProps<{ book: IBook, flags: string[], add?: boolean, readonly?: boolean, ismobile?: boolean, allbooks?: IBook[] }>();
|
|
5
|
+
const props = defineProps<{ book: IBook, flags: string[], add?: boolean, readonly?: boolean, selected?: boolean, ismobile?: boolean, allbooks?: IBook[] }>();
|
|
6
6
|
const book = props.book;
|
|
7
7
|
const emits = defineEmits<{
|
|
8
8
|
(e: 'selectbook', id: number, func: () => void): void,
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
}>();
|
|
12
12
|
|
|
13
13
|
const cls = props.add ? ["bg-climate"] : ["bg-office"];
|
|
14
|
+
const classObject = computed(() => ({
|
|
15
|
+
'bg-secondary': props.selected,
|
|
16
|
+
'bg-climate': props.add
|
|
17
|
+
}));
|
|
14
18
|
const showDelete = ref(!props.add);
|
|
15
19
|
const showSelect = ref(!props.add);
|
|
16
20
|
const showSave = ref(false);
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
</script>
|
|
54
58
|
|
|
55
59
|
<template>
|
|
56
|
-
<v-row v-if="props.ismobile" dense align="center" :class="
|
|
60
|
+
<v-row v-if="props.ismobile" dense align="center" :class="classObject" @click="onSelect" >
|
|
57
61
|
<v-col cols="9" >
|
|
58
62
|
<v-text-field v-model="book.title" disabled hide-details density="compact" ></v-text-field>
|
|
59
63
|
</v-col>
|
|
@@ -61,7 +65,7 @@
|
|
|
61
65
|
<v-text-field v-model="book.year" disabled hide-details density="compact" ></v-text-field>
|
|
62
66
|
</v-col>
|
|
63
67
|
</v-row>
|
|
64
|
-
<v-row v-else dense align="center" :class="
|
|
68
|
+
<v-row v-else dense align="center" :class="classObject" @click="onSelect" >
|
|
65
69
|
<v-col v-if="props.add" cols="6" >
|
|
66
70
|
<v-combobox v-model="selected" :items="props.allbooks" item-value="id" item-title="title" hide-details density="compact" single-line @update:modelValue="titleChanged"></v-combobox>
|
|
67
71
|
</v-col>
|
|
@@ -78,8 +82,9 @@
|
|
|
78
82
|
<v-select v-model="flags" :items="props.flags" multiple hide-details density="compact" single-line @update:modelValue="flagsChanged"></v-select>
|
|
79
83
|
</v-col>
|
|
80
84
|
<v-col cols="2">
|
|
81
|
-
<v-btn v-if="showSave" icon="$save" :disabled="props.readonly" @click="onSave"></v-btn>
|
|
82
|
-
<v-btn v-if="showDelete" icon="$delete" :disabled="props.readonly" @click="onDelete"></v-btn>
|
|
85
|
+
<v-btn v-if="showSave" icon="$save" :class="classObject" :disabled="props.readonly" @click="onSave"></v-btn>
|
|
86
|
+
<v-btn v-if="showDelete" icon="$delete" :class="classObject" :disabled="props.readonly" @click="onDelete"></v-btn>
|
|
83
87
|
</v-col>
|
|
84
88
|
</v-row>
|
|
89
|
+
<v-divider></v-divider>
|
|
85
90
|
</template>
|
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { ref, computed } from 'vue';
|
|
2
3
|
import { IFullBook } from '@christianriedl/media';
|
|
3
|
-
const props = defineProps<{ book: IFullBook, ismobile?: boolean }>();
|
|
4
|
+
const props = defineProps<{ book: IFullBook, selected?: boolean, ismobile?: boolean }>();
|
|
4
5
|
const emits = defineEmits<{
|
|
5
6
|
(e: 'selectbook'): void
|
|
6
7
|
}>();
|
|
7
8
|
const book = props.book;
|
|
8
|
-
|
|
9
|
+
const classObject = computed(() => ({
|
|
10
|
+
'bg-secondary': props.selected
|
|
11
|
+
}));
|
|
9
12
|
function onSelect () {
|
|
10
13
|
emits ("selectbook");
|
|
11
14
|
}
|
|
12
15
|
</script>
|
|
13
16
|
|
|
14
17
|
<template>
|
|
15
|
-
<v-row v-if="props.ismobile" dense align="center" class="
|
|
18
|
+
<v-row v-if="props.ismobile" dense align="center" :class="classObject" @click="onSelect">
|
|
16
19
|
<v-col cols="12" >
|
|
17
20
|
<p class="font-weight-bold">{{book.givenName + ' ' + book.surName}}</p>
|
|
18
21
|
</v-col>
|
|
19
22
|
<v-col cols="12" >
|
|
20
|
-
<p
|
|
23
|
+
<p>{{book.title}}</p>
|
|
21
24
|
</v-col>
|
|
22
25
|
</v-row>
|
|
23
|
-
<v-row v-else dense align="center" class="
|
|
24
|
-
<v-col cols="
|
|
26
|
+
<v-row v-else dense align="center" :class="classObject" @click="onSelect" >
|
|
27
|
+
<v-col cols="4" >
|
|
25
28
|
<p class="font-weight-bold">{{book.givenName + ' ' + book.surName}}</p>
|
|
26
29
|
</v-col>
|
|
27
|
-
<v-col cols="
|
|
28
|
-
<p
|
|
30
|
+
<v-col cols="8" >
|
|
31
|
+
<p>{{book.title}}</p>
|
|
29
32
|
</v-col>
|
|
30
33
|
</v-row>
|
|
34
|
+
<v-divider></v-divider>
|
|
31
35
|
</template>
|
package/src/views/BooksPage.vue
CHANGED
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
const getOpenAI = inject(getOpenAISymbol)!;
|
|
13
13
|
const openAI = getOpenAI();
|
|
14
14
|
const authors = reactive<IAuthorShort[]>([]);
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
15
|
+
const selectedAuthor = ref<IAuthorShort | string | undefined>();
|
|
16
|
+
const currentAuthor = reactive<IAuthor>({ id: 0, surName: "", givenName: "", yearOfBirth: 0, books: [] });
|
|
17
|
+
const selectedBook = ref<IBook>({ id: 0, authorId: 0, title: ""});
|
|
18
18
|
let newBook: IBook;
|
|
19
19
|
const allBooks = ref<IBook[]>([]);
|
|
20
20
|
const lastAllBooksId = ref(0);
|
|
21
21
|
const mustAddAuthor = ref(false);
|
|
22
22
|
const mustUpdateAuthor = ref(false);
|
|
23
23
|
const showAddBookLine = ref(false);
|
|
24
|
-
const
|
|
24
|
+
const showSelectedBook = ref(false);
|
|
25
25
|
let setBookChanged: () => void;
|
|
26
26
|
let readonly = !(appState.scopes & EScope.Admin);
|
|
27
27
|
let isMobile = appState.isMobile && (appState.device != EDevice.iPad);
|
|
@@ -34,65 +34,66 @@
|
|
|
34
34
|
if (authorsShort) {
|
|
35
35
|
authors.splice(0, authors.length, ...authorsShort);
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
if (booksService.selectedAuthorId) {
|
|
38
|
+
selectedAuthor.value = authors.find ((x) => x.id == booksService.selectedAuthorId);
|
|
38
39
|
getCurrentAuthor (booksService.selectedAuthorId, true)
|
|
39
40
|
booksService.selectedAuthorId = 0;
|
|
40
41
|
booksService.selectedBookId = 0;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
async function addAuthor() {
|
|
44
|
-
if (!checkAuthor(
|
|
45
|
+
if (!checkAuthor(currentAuthor))
|
|
45
46
|
return;
|
|
46
|
-
const id = await booksService.addAuthor(
|
|
47
|
+
const id = await booksService.addAuthor(currentAuthor);
|
|
47
48
|
if (id > 0) {
|
|
48
|
-
|
|
49
|
+
currentAuthor.id = id;
|
|
49
50
|
mustAddAuthor.value = false;
|
|
50
51
|
}
|
|
51
52
|
else
|
|
52
53
|
alert (`AddAuthor - error ${id}`);
|
|
53
54
|
}
|
|
54
55
|
async function updateAuthor() {
|
|
55
|
-
if (!checkAuthor(
|
|
56
|
+
if (!checkAuthor(currentAuthor))
|
|
56
57
|
return;
|
|
57
|
-
const rc = await booksService.updateAuthor(
|
|
58
|
+
const rc = await booksService.updateAuthor(currentAuthor);
|
|
58
59
|
if (rc)
|
|
59
60
|
mustUpdateAuthor.value = false;
|
|
60
61
|
else
|
|
61
62
|
alert ('UpdateAuthor - error');
|
|
62
63
|
}
|
|
63
64
|
async function deleteAuthor() {
|
|
64
|
-
if (!window.confirm(`Willst du ${
|
|
65
|
+
if (!window.confirm(`Willst du ${currentAuthor.surName} wirklich l�schen ?`))
|
|
65
66
|
return;
|
|
66
|
-
const rc = await booksService.deleteAuthor(
|
|
67
|
+
const rc = await booksService.deleteAuthor(currentAuthor.id);
|
|
67
68
|
if (rc) {
|
|
68
69
|
mustUpdateAuthor.value = false;
|
|
69
70
|
initAuthor ("");
|
|
70
71
|
}
|
|
71
72
|
else
|
|
72
|
-
alert (`DeleteAuthor ${
|
|
73
|
+
alert (`DeleteAuthor ${currentAuthor.id} - error`);
|
|
73
74
|
}
|
|
74
75
|
function initAuthor(surName: string) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
currentAuthor.id = 0;
|
|
77
|
+
currentAuthor.surName = surName;
|
|
78
|
+
currentAuthor.givenName = "";
|
|
79
|
+
currentAuthor.yearOfBirth = 0;
|
|
80
|
+
currentAuthor.yearOfDeath = undefined;
|
|
81
|
+
currentAuthor.category = undefined;
|
|
82
|
+
currentAuthor.country = undefined;
|
|
83
|
+
currentAuthor.books = [];
|
|
83
84
|
}
|
|
84
85
|
async function getCurrentAuthor (id: number, withBooks: boolean) : Promise<boolean> {
|
|
85
86
|
const authors = await booksService.getAuthors(undefined, undefined, withBooks, id);
|
|
86
87
|
if (authors && authors.length > 0) {
|
|
87
88
|
const a = authors[0];
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
currentAuthor.id = a.id;
|
|
90
|
+
currentAuthor.surName = a.surName;
|
|
91
|
+
currentAuthor.givenName = a.givenName;
|
|
92
|
+
currentAuthor.yearOfBirth = a.yearOfBirth;
|
|
93
|
+
currentAuthor.yearOfDeath = a.yearOfDeath;
|
|
94
|
+
currentAuthor.category = a.category;
|
|
95
|
+
currentAuthor.country = a.country;
|
|
96
|
+
currentAuthor.books = a.books ? a.books : [];
|
|
96
97
|
return true;
|
|
97
98
|
}
|
|
98
99
|
else {
|
|
@@ -101,14 +102,14 @@
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
async function authorNameChanged(arg: IAuthorShort | string) {
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
showSelectedBook.value = false;
|
|
106
|
+
selectedBook.value = { id: 0, authorId: 0, title: ""};
|
|
106
107
|
mustAddAuthor.value = typeof arg == 'string';
|
|
107
108
|
if (!mustAddAuthor.value) {
|
|
108
109
|
const authorShort = arg as IAuthorShort;
|
|
109
110
|
const rc = await getCurrentAuthor (authorShort.id, true);
|
|
110
|
-
if (rc && !
|
|
111
|
-
const rc = await getAuthorDataFromAI (
|
|
111
|
+
if (rc && !currentAuthor.country) {
|
|
112
|
+
const rc = await getAuthorDataFromAI (currentAuthor.surName, currentAuthor.givenName);
|
|
112
113
|
if (rc)
|
|
113
114
|
mustUpdateAuthor.value = true;
|
|
114
115
|
}
|
|
@@ -125,7 +126,7 @@
|
|
|
125
126
|
}
|
|
126
127
|
async function givenNameFocused(focus: boolean) {
|
|
127
128
|
if (!focus && mustAddAuthor.value) {
|
|
128
|
-
await getAuthorDataFromAI(
|
|
129
|
+
await getAuthorDataFromAI(currentAuthor.surName, currentAuthor.givenName);
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
function search () {
|
|
@@ -134,35 +135,35 @@
|
|
|
134
135
|
router.push({ path: 'booksearch' });
|
|
135
136
|
}
|
|
136
137
|
async function addNewBook() {
|
|
137
|
-
if (lastAllBooksId.value !=
|
|
138
|
-
allBooks.value = await getAuthorBooksFromAI (
|
|
139
|
-
lastAllBooksId.value =
|
|
138
|
+
if (lastAllBooksId.value != currentAuthor.id) {
|
|
139
|
+
allBooks.value = await getAuthorBooksFromAI (currentAuthor.surName, currentAuthor.givenName, currentAuthor.id);
|
|
140
|
+
lastAllBooksId.value = currentAuthor.id;
|
|
140
141
|
}
|
|
141
|
-
|
|
142
|
-
newBook = reactive<IBook>({ id: 0, authorId:
|
|
142
|
+
selectedBook.value = { id: 0, authorId: 0, title: ""};
|
|
143
|
+
newBook = reactive<IBook>({ id: 0, authorId: currentAuthor.id, title: "", rating: 0 });
|
|
143
144
|
showAddBookLine.value = true;
|
|
144
145
|
}
|
|
145
146
|
function cancelAddNewBook() {
|
|
146
147
|
showAddBookLine.value = false;
|
|
147
148
|
}
|
|
148
149
|
async function selectBook(id: number, func: () => void) {
|
|
149
|
-
if (
|
|
150
|
+
if (selectedBook.value.id == id) {
|
|
150
151
|
return;
|
|
151
152
|
}
|
|
152
153
|
setBookChanged = func;
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
if (
|
|
156
|
-
const books = await booksService.getBooks (
|
|
154
|
+
if (currentAuthor.books) {
|
|
155
|
+
selectedBook.value = currentAuthor.books.find (x => x.id == id) as IBook;
|
|
156
|
+
if (selectedBook.value && !selectedBook.value.description && !selectedBook.value.comment) {
|
|
157
|
+
const books = await booksService.getBooks (currentAuthor.id, selectedBook.value.id);
|
|
157
158
|
if (books && books.length > 0) {
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
selectedBook.value.description = books[0].description;
|
|
160
|
+
selectedBook.value.comment = books[0].comment;
|
|
160
161
|
}
|
|
161
|
-
|
|
162
|
-
if (!
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
162
|
+
showSelectedBook.value = true;
|
|
163
|
+
if (!selectedBook.value.description) {
|
|
164
|
+
selectedBook.value.description ="WAITING..."
|
|
165
|
+
selectedBook.value.description = await getBookDescriptionFromAI (currentAuthor.surName, currentAuthor.givenName, selectedBook.value.title);
|
|
166
|
+
if (selectedBook.value.description && setBookChanged)
|
|
166
167
|
setBookChanged();
|
|
167
168
|
}
|
|
168
169
|
}
|
|
@@ -180,10 +181,10 @@
|
|
|
180
181
|
const rc = await booksService.deleteBook (id);
|
|
181
182
|
if (!rc)
|
|
182
183
|
alert (`DeleteBook ${id}- error`);
|
|
183
|
-
if (rc &&
|
|
184
|
-
const idx =
|
|
184
|
+
if (rc && currentAuthor.books) {
|
|
185
|
+
const idx = currentAuthor.books.findIndex ((x) => x.id == id);
|
|
185
186
|
if (idx >= 0)
|
|
186
|
-
|
|
187
|
+
currentAuthor.books.splice (idx, 1);
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
async function saveBook(book: IBook) {
|
|
@@ -193,9 +194,9 @@
|
|
|
193
194
|
const id = await booksService.addBook (book);
|
|
194
195
|
if (id < 0)
|
|
195
196
|
alert (`AddBook - error ${id}`);
|
|
196
|
-
if (id > 0 &&
|
|
197
|
+
if (id > 0 && currentAuthor.books) {
|
|
197
198
|
book.id = id;
|
|
198
|
-
|
|
199
|
+
currentAuthor.books.splice (0, 0, book);
|
|
199
200
|
showAddBookLine.value = false;
|
|
200
201
|
}
|
|
201
202
|
}
|
|
@@ -269,14 +270,14 @@
|
|
|
269
270
|
const prompt = `Geburtstag, Sterbetag, Geburtsland von ${givenName} ${surName} ?`;
|
|
270
271
|
const result = await openAI.completeJson(prompt, schema) as any;
|
|
271
272
|
if (result) {
|
|
272
|
-
if (!
|
|
273
|
-
|
|
274
|
-
if (!
|
|
275
|
-
|
|
276
|
-
if (!
|
|
277
|
-
|
|
278
|
-
if (!
|
|
279
|
-
|
|
273
|
+
if (!currentAuthor.yearOfBirth)
|
|
274
|
+
currentAuthor.yearOfBirth = getYear(result.geburtstag);
|
|
275
|
+
if (!currentAuthor.yearOfDeath)
|
|
276
|
+
currentAuthor.yearOfDeath = result.sterbetag ? getYear(result.sterbetag) : undefined;
|
|
277
|
+
if (!currentAuthor.category)
|
|
278
|
+
currentAuthor.category = booksService.categories[0];
|
|
279
|
+
if (!currentAuthor.country)
|
|
280
|
+
currentAuthor.country = result.geburtsland;
|
|
280
281
|
return true;
|
|
281
282
|
}
|
|
282
283
|
else {
|
|
@@ -350,80 +351,80 @@
|
|
|
350
351
|
</script>
|
|
351
352
|
|
|
352
353
|
<template>
|
|
353
|
-
<v-container fluid
|
|
354
|
-
<v-defaults-provider :defaults="{'VBtn':{'size':'large','variant':'flat'
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
354
|
+
<v-container fluid :style="heightStyle">
|
|
355
|
+
<v-defaults-provider :defaults="{'VBtn':{'size':'large','variant':'flat'}}">
|
|
356
|
+
<v-row v-if="isMobile" dense align="center" class="bg-office" >
|
|
357
|
+
<v-col cols="6">Name</v-col>
|
|
358
|
+
<v-col cols="5">Vorname</v-col>
|
|
359
|
+
<v-col cols="1">
|
|
360
|
+
<v-btn icon="$search" class="bg-office" @click="search"></v-btn>
|
|
361
|
+
</v-col>
|
|
362
|
+
</v-row>
|
|
363
|
+
<v-row v-else dense align="center" class="bg-office" >
|
|
364
|
+
<v-col cols="2">Name</v-col>
|
|
365
|
+
<v-col cols="2">Vorname</v-col>
|
|
366
|
+
<v-col cols="1">Von</v-col>
|
|
367
|
+
<v-col cols="1">Bis</v-col>
|
|
368
|
+
<v-col cols="2">Kategorie</v-col>
|
|
369
|
+
<v-col cols="2">Land</v-col>
|
|
370
|
+
<v-col cols="2">
|
|
371
|
+
<v-btn prepend-icon="$search" class="bg-office" @click="search">Search</v-btn>
|
|
372
|
+
</v-col>
|
|
373
|
+
</v-row>
|
|
374
|
+
<v-row v-if="isMobile" dense align="center" class="bg-office" >
|
|
375
|
+
<v-col cols="6">
|
|
376
|
+
<v-combobox v-model="selectedAuthor" :items="authors" item-value="id" item-title="sN" hide-details density="compact" single-line @update:modelValue="authorNameChanged"></v-combobox>
|
|
377
|
+
</v-col>
|
|
378
|
+
<v-col cols="6">
|
|
379
|
+
<v-text-field v-model="currentAuthor.givenName" hide-details density="compact" @update:modelValue="fieldChanged" @update:focused="givenNameFocused"></v-text-field>
|
|
380
|
+
</v-col>
|
|
381
|
+
</v-row>
|
|
382
|
+
<v-row v-else dense align="center" class="bg-office" >
|
|
383
|
+
<v-col cols="2">
|
|
384
|
+
<v-combobox v-model="selectedAuthor" :items="authors" item-value="id" item-title="sN" hide-details density="compact" single-line @update:modelValue="authorNameChanged"></v-combobox>
|
|
385
|
+
</v-col>
|
|
386
|
+
<v-col cols="2">
|
|
387
|
+
<v-text-field v-model="currentAuthor.givenName" hide-details density="compact" @update:modelValue="fieldChanged" @update:focused="givenNameFocused"></v-text-field>
|
|
388
|
+
</v-col>
|
|
389
|
+
<v-col cols="1">
|
|
390
|
+
<v-text-field v-model="currentAuthor.yearOfBirth" hide-details density="compact" type="number" @update:modelValue="fieldChanged"></v-text-field>
|
|
391
|
+
</v-col>
|
|
392
|
+
<v-col cols="1">
|
|
393
|
+
<v-text-field v-model="currentAuthor.yearOfDeath" hide-details density="compact" type="number" @update:modelValue="fieldChanged"></v-text-field>
|
|
394
|
+
</v-col>
|
|
395
|
+
<v-col cols="2">
|
|
396
|
+
<v-select v-model="currentAuthor.category" :items="booksService.categories" hide-details density="compact" single-line @update:modelValue="fieldChanged"></v-select>
|
|
397
|
+
</v-col>
|
|
398
|
+
<v-col cols="2">
|
|
399
|
+
<v-text-field v-model="currentAuthor.country" hide-details density="compact" @update:modelValue="fieldChanged"></v-text-field>
|
|
400
|
+
</v-col>
|
|
401
|
+
<v-col cols="2">
|
|
402
|
+
<v-btn v-if="mustAddAuthor" class="bg-office" @click="addAuthor" :disabled="readonly" prepend-icon="$plus">AUTHOR</v-btn>
|
|
403
|
+
<v-btn v-if="mustUpdateAuthor" class="bg-office" @click="updateAuthor" :disabled="readonly" icon="$save"></v-btn>
|
|
404
|
+
<v-btn v-if="currentAuthor.id > 0" class="bg-office" @click="deleteAuthor" :disabled="readonly" icon="$delete"></v-btn>
|
|
405
|
+
</v-col>
|
|
406
|
+
</v-row>
|
|
407
|
+
<v-divider></v-divider>
|
|
408
|
+
<v-row v-if="isMobile" dense align="center" class="bg-office" >
|
|
409
|
+
<v-col cols="9">TITEL</v-col>
|
|
410
|
+
<v-col cols="3">JAHR</v-col>
|
|
411
|
+
</v-row>
|
|
412
|
+
<v-row v-else dense align="center" class="bg-office" >
|
|
413
|
+
<v-col cols="6">TITEL</v-col>
|
|
414
|
+
<v-col cols="1">JAHR</v-col>
|
|
415
|
+
<v-col cols="1">RATING</v-col>
|
|
416
|
+
<v-col cols="2">STATUS</v-col>
|
|
417
|
+
<v-col v-if="currentAuthor.id" cols="2">
|
|
418
|
+
<v-btn v-if="!showAddBookLine" class="bg-office" @click="addNewBook" :disabled="readonly" prepend-icon="$plus">BOOK</v-btn>
|
|
419
|
+
<v-btn v-if="showAddBookLine" class="bg-office" @click="cancelAddNewBook" :disabled="readonly" icon="$cancel"></v-btn>
|
|
420
|
+
</v-col>
|
|
421
|
+
</v-row>
|
|
422
|
+
<book-line v-if="showAddBookLine" :book="newBook" :flags="booksService.flags" :add="true" :allbooks="allBooks" :readonly="readonly" :ismobile="isMobile" @selectbook="selectBook" @deletebook="deleteBook" @savebook="saveBook"></book-line>
|
|
423
|
+
<book-line v-for="book in currentAuthor.books" :key="book.id" :book="book" :flags="booksService.flags" :readonly="readonly" :selected="selectedBook == book" :ismobile="isMobile" @selectbook="selectBook" @deletebook="deleteBook" @savebook="saveBook"></book-line>
|
|
424
|
+
<v-textarea v-if="showSelectedBook" clearable auto-grow variant="outlined" label="Beschreibung" :disabled="isMobile" class="bg-office pt-2" v-model="selectedBook.description" @update:modelValue="descriptionChanged">
|
|
425
|
+
</v-textarea>
|
|
426
|
+
<v-textarea v-if="showSelectedBook" clearable auto-grow variant="outlined" label="Kommentar" :disabled="isMobile" class="bg-office" v-model="selectedBook.comment" @update:modelValue="descriptionChanged">
|
|
427
|
+
</v-textarea>
|
|
427
428
|
</v-defaults-provider>
|
|
428
429
|
</v-container>
|
|
429
430
|
</template>
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
const booksService = getBooksService() as BooksService;
|
|
10
10
|
const authors = reactive<IAuthorShort[]>([]);
|
|
11
11
|
const books = ref<IFullBook[]>([]);
|
|
12
|
+
const selectedBook = ref<IFullBook|null>(null);
|
|
12
13
|
const selected = ref<IAuthorShort>({ id:0, gN: "", sN: "" });
|
|
13
14
|
const title = ref("");
|
|
14
15
|
const rating = ref(0);
|
|
@@ -31,6 +32,7 @@
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
function select (book: IFullBook) {
|
|
35
|
+
selectedBook.value = book;
|
|
34
36
|
booksService.selectedAuthorId = book.authorId;
|
|
35
37
|
booksService.selectedBookId = book.bookId;
|
|
36
38
|
}
|
|
@@ -80,7 +82,7 @@
|
|
|
80
82
|
</v-col>
|
|
81
83
|
</v-row>
|
|
82
84
|
<v-divider></v-divider>
|
|
83
|
-
<book-search-line v-for="book in books" :key="book.bookId" :book="book" :ismobile="isMobile" @selectbook="select(book)"></book-search-line>
|
|
85
|
+
<book-search-line v-for="book in books" :key="book.bookId" :book="book" :selected="selectedBook == book" :ismobile="isMobile" @selectbook="select(book)"></book-search-line>
|
|
84
86
|
</v-defaults-provider>
|
|
85
87
|
</v-container>
|
|
86
88
|
</template>
|