@christianriedl/media 1.0.181 → 1.0.183
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/dist/booksService.d.ts +6 -1
- package/dist/booksService.js +12 -0
- package/dist/booksService.js.map +1 -1
- package/dist/iBooks.d.ts +15 -0
- package/package.json +1 -1
- package/src/components/BookLine.vue +12 -4
- package/src/components/BookSearchLine.vue +31 -0
- package/src/views/BooksPage.vue +26 -9
- package/src/views/BooksSearchPage.vue +86 -0
package/dist/booksService.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IRest } from '@christianriedl/rest';
|
|
2
2
|
import { ILogger, IStatistics, InjectionKey } from '@christianriedl/utils';
|
|
3
|
-
import { IBook, IAuthor, IAuthorShort, IBooksService } from "./iBooks";
|
|
3
|
+
import { IBook, IFullBook, IAuthor, IAuthorShort, IBooksService } from "./iBooks";
|
|
4
4
|
export declare const getBooksSymbol: InjectionKey<() => BooksService>;
|
|
5
5
|
export declare class BooksService implements IBooksService {
|
|
6
6
|
rest: IRest;
|
|
@@ -8,6 +8,10 @@ export declare class BooksService implements IBooksService {
|
|
|
8
8
|
user: string;
|
|
9
9
|
log: ILogger;
|
|
10
10
|
cachedAuthors?: IAuthorShort[];
|
|
11
|
+
categories: string[];
|
|
12
|
+
flags: string[];
|
|
13
|
+
selectedAuthorId: number;
|
|
14
|
+
selectedBookId: number;
|
|
11
15
|
constructor(rest: IRest, user: string, statistics: IStatistics, log: ILogger);
|
|
12
16
|
getAuthors(surName?: string, givenName?: string, withBooks?: boolean, id?: number): Promise<IAuthor[]>;
|
|
13
17
|
getAuthorsShort(): Promise<IAuthorShort[]>;
|
|
@@ -15,6 +19,7 @@ export declare class BooksService implements IBooksService {
|
|
|
15
19
|
updateAuthor(author: IAuthor): Promise<boolean>;
|
|
16
20
|
deleteAuthor(id: number): Promise<boolean>;
|
|
17
21
|
getBooks(authorId?: number, bookId?: number): Promise<IBook[]>;
|
|
22
|
+
getFullBooks(surName?: string, givenName?: string, title?: string, flags?: string, minRating?: number): Promise<IFullBook[]>;
|
|
18
23
|
addBook(book: IBook): Promise<number>;
|
|
19
24
|
updateBook(book: IBook): Promise<boolean>;
|
|
20
25
|
deleteBook(id: number): Promise<boolean>;
|
package/dist/booksService.js
CHANGED
|
@@ -5,11 +5,19 @@ export class BooksService {
|
|
|
5
5
|
user;
|
|
6
6
|
log;
|
|
7
7
|
cachedAuthors;
|
|
8
|
+
categories;
|
|
9
|
+
flags;
|
|
10
|
+
selectedAuthorId;
|
|
11
|
+
selectedBookId;
|
|
8
12
|
constructor(rest, user, statistics, log) {
|
|
9
13
|
this.log = log;
|
|
10
14
|
this.rest = rest;
|
|
11
15
|
this.user = user;
|
|
12
16
|
this.mediaUrl = rest.serviceUrl;
|
|
17
|
+
this.categories = ["Literatur", "Geschichte", "Philosophie", "Naturwissenschaft"];
|
|
18
|
+
this.flags = ["liesC", "liesH", "ausgeborgt"];
|
|
19
|
+
this.selectedAuthorId = 0;
|
|
20
|
+
this.selectedBookId = 0;
|
|
13
21
|
}
|
|
14
22
|
async getAuthors(surName, givenName, withBooks, id) {
|
|
15
23
|
const info = await this.rest.getData('apibooks/authors', { surName, givenName, withBooks, id });
|
|
@@ -49,6 +57,10 @@ export class BooksService {
|
|
|
49
57
|
const info = await this.rest.getData('apibooks/books', { authorId, bookId });
|
|
50
58
|
return info.result;
|
|
51
59
|
}
|
|
60
|
+
async getFullBooks(surName, givenName, title, flags, minRating) {
|
|
61
|
+
const info = await this.rest.getData('apibooks/books/full', { surName, givenName, title, flags, minRating });
|
|
62
|
+
return info.result;
|
|
63
|
+
}
|
|
52
64
|
async addBook(book) {
|
|
53
65
|
const url = `apibooks/books`;
|
|
54
66
|
const res = await this.rest.postDataEx(url, book);
|
package/dist/booksService.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booksService.js","sourceRoot":"","sources":["../src/booksService.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,cAAc,GAAqC,MAAM,CAAC,WAAW,CAAC,CAAC;AACpF,MAAM,OAAO,YAAY;IACrB,IAAI,CAAQ;IACZ,QAAQ,CAAS;IACjB,IAAI,CAAS;IACb,GAAG,CAAU;IACb,aAAa,CAAkB;IAC/B,YAAY,IAAW,EAAE,IAAY,EAAE,UAAuB,EAAE,GAAY;QACxE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"booksService.js","sourceRoot":"","sources":["../src/booksService.ts"],"names":[],"mappings":"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"}
|
package/dist/iBooks.d.ts
CHANGED
|
@@ -21,8 +21,22 @@ export interface IBook {
|
|
|
21
21
|
year?: number;
|
|
22
22
|
comment?: string;
|
|
23
23
|
rating?: number;
|
|
24
|
+
flags?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface IFullBook {
|
|
27
|
+
authorId: number;
|
|
28
|
+
surName: string;
|
|
29
|
+
givenName: string;
|
|
30
|
+
bookId: number;
|
|
31
|
+
title: string;
|
|
32
|
+
rating?: number;
|
|
33
|
+
flags?: string;
|
|
24
34
|
}
|
|
25
35
|
export interface IBooksService {
|
|
36
|
+
categories: string[];
|
|
37
|
+
flags: string[];
|
|
38
|
+
selectedAuthorId: number;
|
|
39
|
+
selectedBookId: number;
|
|
26
40
|
getAuthors(surName?: string, givenName?: string, withBooks?: boolean, id?: number): Promise<IAuthor[]>;
|
|
27
41
|
getAuthorsShort(): Promise<IAuthorShort[]>;
|
|
28
42
|
addAuthor(author: IAuthor): Promise<number>;
|
|
@@ -32,4 +46,5 @@ export interface IBooksService {
|
|
|
32
46
|
addBook(book: IBook): Promise<number>;
|
|
33
47
|
updateBook(book: IBook): Promise<boolean>;
|
|
34
48
|
deleteBook(id: number): Promise<boolean>;
|
|
49
|
+
getFullBooks(surName?: string, givenName?: string, title?: string, flags?: string, minRating?: number): Promise<IFullBook[]>;
|
|
35
50
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ref } from 'vue';
|
|
3
3
|
import { IBook } from '@christianriedl/media';
|
|
4
4
|
|
|
5
|
-
const props = defineProps<{ book: IBook, add?: boolean, readonly?: boolean, ismobile?: boolean, allbooks?: IBook[] }>();
|
|
5
|
+
const props = defineProps<{ book: IBook, flags: string[], add?: boolean, readonly?: 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,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
const showSelect = ref(!props.add);
|
|
16
16
|
const showSave = ref(false);
|
|
17
17
|
const selected = ref<IBook | string | undefined>();
|
|
18
|
+
const flags = ref<string[]>(book.flags ? book.flags.split(',') : []);
|
|
18
19
|
|
|
19
20
|
async function titleChanged(arg: IBook | string) {
|
|
20
21
|
if (typeof arg == 'string') {
|
|
@@ -45,6 +46,10 @@
|
|
|
45
46
|
function fieldChanged () {
|
|
46
47
|
showSave.value = true;
|
|
47
48
|
}
|
|
49
|
+
function flagsChanged () {
|
|
50
|
+
showSave.value = true;
|
|
51
|
+
book.flags = flags.value.join(',');
|
|
52
|
+
}
|
|
48
53
|
</script>
|
|
49
54
|
|
|
50
55
|
<template>
|
|
@@ -63,15 +68,18 @@
|
|
|
63
68
|
<v-col v-else cols="6" >
|
|
64
69
|
<v-text-field v-model="book.title" hide-details density="compact" @update:modelValue="fieldChanged"></v-text-field>
|
|
65
70
|
</v-col>
|
|
66
|
-
<v-col cols="
|
|
71
|
+
<v-col cols="1" >
|
|
67
72
|
<v-text-field v-model="book.year" hide-details density="compact" type="number" @update:modelValue="fieldChanged"></v-text-field>
|
|
68
73
|
</v-col>
|
|
69
|
-
<v-col cols="
|
|
74
|
+
<v-col cols="1" >
|
|
70
75
|
<v-rating hover clearable :length="5" :size="32" v-model="book.rating" active-color="primary" @update:modelValue="fieldChanged" />
|
|
71
76
|
</v-col>
|
|
72
77
|
<v-col cols="2">
|
|
73
|
-
|
|
78
|
+
<v-select v-model="flags" :items="props.flags" multiple hide-details density="compact" single-line @update:modelValue="flagsChanged"></v-select>
|
|
79
|
+
</v-col>
|
|
80
|
+
<v-col cols="2">
|
|
74
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>
|
|
75
83
|
</v-col>
|
|
76
84
|
</v-row>
|
|
77
85
|
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { IFullBook } from '@christianriedl/media';
|
|
3
|
+
const props = defineProps<{ book: IFullBook, ismobile?: boolean }>();
|
|
4
|
+
const emits = defineEmits<{
|
|
5
|
+
(e: 'selectbook'): void
|
|
6
|
+
}>();
|
|
7
|
+
const book = props.book;
|
|
8
|
+
|
|
9
|
+
function onSelect () {
|
|
10
|
+
emits ("selectbook");
|
|
11
|
+
}
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<v-row v-if="props.ismobile" dense align="center" class="bg-office" @click="onSelect">
|
|
16
|
+
<v-col cols="12" >
|
|
17
|
+
<p class="font-weight-bold">{{book.givenName + ' ' + book.surName}}</p>
|
|
18
|
+
</v-col>
|
|
19
|
+
<v-col cols="12" >
|
|
20
|
+
<p class="font-weight-medium">{{book.title}}</p>
|
|
21
|
+
</v-col>
|
|
22
|
+
</v-row>
|
|
23
|
+
<v-row v-else dense align="center" class="bg-office" @click="onSelect >
|
|
24
|
+
<v-col cols="6" >
|
|
25
|
+
<p class="font-weight-bold">{{book.givenName + ' ' + book.surName}}</p>
|
|
26
|
+
</v-col>
|
|
27
|
+
<v-col cols="6" >
|
|
28
|
+
<p class="font-weight-medium">{{book.title}}</p>
|
|
29
|
+
</v-col>
|
|
30
|
+
</v-row>
|
|
31
|
+
</template>
|
package/src/views/BooksPage.vue
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { inject, ref, reactive, onMounted, onUnmounted, computed, StyleValue } from 'vue';
|
|
3
|
+
import { useRouter } from 'vue-router';
|
|
3
4
|
import { IAppState, appStateSymbol, getOpenAISymbol, IOpenAIService, ICompleteData, EScope, EDevice } from '@christianriedl/utils';
|
|
4
5
|
import { BooksService, getBooksSymbol, IAuthorShort, IAuthor, IBook } from '@christianriedl/media';
|
|
5
6
|
import BookLine from '../components/BookLine.vue';
|
|
6
7
|
|
|
8
|
+
const router = useRouter();
|
|
7
9
|
const appState = inject(appStateSymbol)!;
|
|
8
10
|
const getBooksService = inject(getBooksSymbol)!;
|
|
9
11
|
const booksService = getBooksService() as BooksService;
|
|
@@ -24,7 +26,6 @@
|
|
|
24
26
|
let readonly = !(appState.scopes & EScope.Admin);
|
|
25
27
|
let isMobile = appState.isMobile && (appState.device != EDevice.iPad);
|
|
26
28
|
const heightStyle = computed<StyleValue>(() => { return { height: appState.bodyHeight.value + "px", overflowY: "auto" } });
|
|
27
|
-
const categories = ["Literatur", "Geschichte", "Philosophie", "Naturwissenschaft"];
|
|
28
29
|
|
|
29
30
|
start();
|
|
30
31
|
|
|
@@ -33,6 +34,11 @@
|
|
|
33
34
|
if (authorsShort) {
|
|
34
35
|
authors.splice(0, authors.length, ...authorsShort);
|
|
35
36
|
}
|
|
37
|
+
�f (booksService.selectedAuthorId) {
|
|
38
|
+
getCurrentAuthor (booksService.selectedAuthorId, true)
|
|
39
|
+
booksService.selectedAuthorId = 0;
|
|
40
|
+
booksService.selectedBookId = 0;
|
|
41
|
+
}
|
|
36
42
|
}
|
|
37
43
|
async function addAuthor() {
|
|
38
44
|
if (!checkAuthor(author))
|
|
@@ -122,6 +128,11 @@
|
|
|
122
128
|
await getAuthorDataFromAI(author.surName, author.givenName);
|
|
123
129
|
}
|
|
124
130
|
}
|
|
131
|
+
function search () {
|
|
132
|
+
booksService.selectedAuthorId = 0;
|
|
133
|
+
booksService.selectedBookId = 0;
|
|
134
|
+
router.push({ path: 'booksearch' });
|
|
135
|
+
}
|
|
125
136
|
async function addNewBook() {
|
|
126
137
|
if (lastAllBooksId.value != author.id) {
|
|
127
138
|
allBooks.value = await getAuthorBooksFromAI (author.surName, author.givenName, author.id);
|
|
@@ -263,7 +274,7 @@
|
|
|
263
274
|
if (!author.yearOfDeath)
|
|
264
275
|
author.yearOfDeath = result.sterbetag ? getYear(result.sterbetag) : undefined;
|
|
265
276
|
if (!author.category)
|
|
266
|
-
author.category = categories[0];
|
|
277
|
+
author.category = booksService.categories[0];
|
|
267
278
|
if (!author.country)
|
|
268
279
|
author.country = result.geburtsland;
|
|
269
280
|
return true;
|
|
@@ -343,7 +354,10 @@
|
|
|
343
354
|
<v-defaults-provider :defaults="{'VBtn':{'size':'large','variant':'flat','class':'bg-office'}}">
|
|
344
355
|
<v-row v-if="isMobile" dense align="center">
|
|
345
356
|
<v-col cols="6">Name</v-col>
|
|
346
|
-
<v-col cols="
|
|
357
|
+
<v-col cols="5">Vorname</v-col>
|
|
358
|
+
<v-col cols="1">
|
|
359
|
+
<v-btn icon="$search" @click="search"></v-btn>
|
|
360
|
+
</v-col>
|
|
347
361
|
</v-row>
|
|
348
362
|
<v-row v-else dense align="center">
|
|
349
363
|
<v-col cols="2">Name</v-col>
|
|
@@ -352,6 +366,9 @@
|
|
|
352
366
|
<v-col cols="1">Bis</v-col>
|
|
353
367
|
<v-col cols="2">Kategorie</v-col>
|
|
354
368
|
<v-col cols="2">Land</v-col>
|
|
369
|
+
<v-col cols="2">
|
|
370
|
+
<v-btn prepend-icon="$search" @click="search">Search</v-btn>
|
|
371
|
+
</v-col>
|
|
355
372
|
</v-row>
|
|
356
373
|
<v-row v-if="isMobile" dense align="center">
|
|
357
374
|
<v-col cols="6">
|
|
@@ -375,8 +392,7 @@
|
|
|
375
392
|
<v-text-field v-model="author.yearOfDeath" hide-details density="compact" type="number" @update:modelValue="fieldChanged"></v-text-field>
|
|
376
393
|
</v-col>
|
|
377
394
|
<v-col cols="2">
|
|
378
|
-
<v-select v-model="author.category" :items="categories" hide-details density="compact" single-line @update:modelValue="fieldChanged">
|
|
379
|
-
</v-select>
|
|
395
|
+
<v-select v-model="author.category" :items="booksService.categories" hide-details density="compact" single-line @update:modelValue="fieldChanged"></v-select>
|
|
380
396
|
</v-col>
|
|
381
397
|
<v-col cols="2">
|
|
382
398
|
<v-text-field v-model="author.country" hide-details density="compact" @update:modelValue="fieldChanged"></v-text-field>
|
|
@@ -394,15 +410,16 @@
|
|
|
394
410
|
</v-row>
|
|
395
411
|
<v-row v-else dense align="center">
|
|
396
412
|
<v-col cols="6">TITEL</v-col>
|
|
397
|
-
<v-col cols="
|
|
398
|
-
<v-col cols="
|
|
413
|
+
<v-col cols="1">JAHR</v-col>
|
|
414
|
+
<v-col cols="1">RATING</v-col>
|
|
415
|
+
<v-col cols="2">STATUS</v-col>
|
|
399
416
|
<v-col v-if="author.id" cols="2">
|
|
400
417
|
<v-btn v-if="!showAddBookLine" @click="addNewBook" :disabled="readonly" prepend-icon="$plus">BOOK</v-btn>
|
|
401
418
|
<v-btn v-if="showAddBookLine" @click="cancelAddNewBook" :disabled="readonly" icon="$cancel"></v-btn>
|
|
402
419
|
</v-col>
|
|
403
420
|
</v-row>
|
|
404
|
-
<book-line v-if="showAddBookLine" :book="newBook" :add="true" :allbooks="allBooks" :readonly="readonly" :ismobile="isMobile" @selectbook="selectBook" @deletebook="deleteBook" @savebook="saveBook"></book-line>
|
|
405
|
-
<book-line v-for="book in author.books" :key="book.id" :book="book" :readonly="readonly" :ismobile="isMobile" @selectbook="selectBook" @deletebook="deleteBook" @savebook="saveBook"></book-line>
|
|
421
|
+
<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>
|
|
422
|
+
<book-line v-for="book in author.books" :key="book.id" :book="book" :flags="booksService.flags" :readonly="readonly" :ismobile="isMobile" @selectbook="selectBook" @deletebook="deleteBook" @savebook="saveBook"></book-line>
|
|
406
423
|
<v-textarea v-if="showCurrentBook" clearable auto-grow variant="outlined" label="Beschreibung" :disabled="isMobile" class="pt-2" v-model="currentBook.description" @update:modelValue="descriptionChanged">
|
|
407
424
|
</v-textarea>
|
|
408
425
|
<v-textarea v-if="showCurrentBook" clearable auto-grow variant="outlined" label="Kommentar" :disabled="isMobile" v-model="currentBook.comment" @update:modelValue="descriptionChanged">
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { inject, ref, reactive, onMounted, onUnmounted, computed, StyleValue } from 'vue';
|
|
3
|
+
import { IAppState, appStateSymbol, getOpenAISymbol, IOpenAIService, ICompleteData, EScope, EDevice } from '@christianriedl/utils';
|
|
4
|
+
import { BooksService, getBooksSymbol, IAuthorShort, IAuthor, IFullBook } from '@christianriedl/media';
|
|
5
|
+
import BookSearchLine from '../components/BookSearchLine.vue';
|
|
6
|
+
|
|
7
|
+
const appState = inject(appStateSymbol)!;
|
|
8
|
+
const getBooksService = inject(getBooksSymbol)!;
|
|
9
|
+
const booksService = getBooksService() as BooksService;
|
|
10
|
+
const authors = reactive<IAuthorShort[]>([]);
|
|
11
|
+
const books = ref<IFullBook[]>([]);
|
|
12
|
+
const selected = ref<IAuthorShort>({ id:0, gN: "", sN: "" });
|
|
13
|
+
const title = ref("");
|
|
14
|
+
const rating = ref(0);
|
|
15
|
+
const flags = ref("");
|
|
16
|
+
let isMobile = appState.isMobile && (appState.device != EDevice.iPad);
|
|
17
|
+
const heightStyle = computed<StyleValue>(() => { return { height: appState.bodyHeight.value + "px", overflowY: "auto" } });
|
|
18
|
+
|
|
19
|
+
start();
|
|
20
|
+
|
|
21
|
+
async function start() {
|
|
22
|
+
const authorsShort = await booksService.getAuthorsShort();
|
|
23
|
+
if (authorsShort) {
|
|
24
|
+
authors.splice(0, authors.length, ...authorsShort);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function search() {
|
|
28
|
+
const sel = selected.value;
|
|
29
|
+
if (sel) {
|
|
30
|
+
books.value = await booksService.getFullBooks(sel.sN, sel.gN, title.value, flags.value, rating.value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function select (book: IFullBook) {
|
|
34
|
+
booksService.selectedAuthorId = book.authorId;
|
|
35
|
+
booksService.selectedBookId = book.bookId;
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<v-container fluid class="bg-office" :style="heightStyle">
|
|
41
|
+
<v-defaults-provider :defaults="{'VBtn':{'size':'large','variant':'flat','class':'bg-office'}}">
|
|
42
|
+
<v-row v-if="isMobile" dense align="center">
|
|
43
|
+
<v-col cols="6">
|
|
44
|
+
<v-select v-model="selected" :items="authors" label="Author" return-object item-value="id" item-title="sN" hide-details density="compact" single-line ></v-select>
|
|
45
|
+
</v-col>
|
|
46
|
+
<v-col cols="6">
|
|
47
|
+
<p>{{selected.gN}}</p>
|
|
48
|
+
</v-col>
|
|
49
|
+
<v-col cols="6">
|
|
50
|
+
<v-text-field label="Titel" v-model="title" hide-details density="compact"></v-text-field>
|
|
51
|
+
</v-col>
|
|
52
|
+
<v-col cols="2">
|
|
53
|
+
<v-select label="Status" v-model="flags" :items="booksService.flags" hide-details density="compact" single-line ></v-select>
|
|
54
|
+
</v-col>
|
|
55
|
+
<v-col cols="2">
|
|
56
|
+
<v-rating label="Rating" hover clearable :length="5" :size="16" v-model="rating" active-color="primary" />
|
|
57
|
+
</v-col>
|
|
58
|
+
<v-col cols="2">
|
|
59
|
+
<v-btn @click="search" icon="$search"></v-btn>
|
|
60
|
+
</v-col>
|
|
61
|
+
</v-row>
|
|
62
|
+
<v-row v-else dense align="center">
|
|
63
|
+
<v-col cols="2">
|
|
64
|
+
<v-select v-model="selected" :items="authors" label="Author" return-object item-value="id" item-title="sN" hide-details density="compact" single-line ></v-select>
|
|
65
|
+
</v-col>
|
|
66
|
+
<v-col cols="2">
|
|
67
|
+
<p>{{selected.gN}}</p>
|
|
68
|
+
</v-col>
|
|
69
|
+
<v-col cols="3">
|
|
70
|
+
<v-text-field label="Titel" v-model="title" hide-details density="compact"></v-text-field>
|
|
71
|
+
</v-col>
|
|
72
|
+
<v-col cols="2">
|
|
73
|
+
<v-select label="Status" v-model="flags" :items="booksService.flags" hide-details density="compact" single-line ></v-select>
|
|
74
|
+
</v-col>
|
|
75
|
+
<v-col cols="1">
|
|
76
|
+
<v-rating label="Rating" hover clearable :length="5" :size="32" v-model="rating" active-color="primary" />
|
|
77
|
+
</v-col>
|
|
78
|
+
<v-col cols="2">
|
|
79
|
+
<v-btn @click="search" prepend-icon="$search">Search</v-btn>
|
|
80
|
+
</v-col>
|
|
81
|
+
</v-row>
|
|
82
|
+
<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>
|
|
84
|
+
</v-defaults-provider>
|
|
85
|
+
</v-container>
|
|
86
|
+
</template>
|