delete and create added for books

This commit is contained in:
Kaibu 2021-09-13 20:49:25 +02:00
parent 9efc60232a
commit 22bde0424c
17 changed files with 222 additions and 130 deletions

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="css/cookbook_view.css" rel="preload" as="style"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="js/cookbook_view.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Recipes"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><div id="app"></div><script src="js/chunk-vendors.js"></script></body></html>

View File

@ -0,0 +1 @@
.flip-enter-active[data-v-8633bda0]{-webkit-animation-name:bounceUp-data-v-8633bda0;animation-name:bounceUp-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite}.bounceleft[data-v-8633bda0]{-webkit-animation-name:bounceLeft-data-v-8633bda0;animation-name:bounceLeft-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}.bounceright[data-v-8633bda0]{-webkit-animation-name:bounceRight-data-v-8633bda0;animation-name:bounceRight-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}@-webkit-keyframes bounceUp-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateY(-7px)}}@keyframes bounceUp-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateY(-7px)}}@-webkit-keyframes bounceLeft-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(-10px)}}@keyframes bounceLeft-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(-10px)}}@-webkit-keyframes bounceRight-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(10px)}}@keyframes bounceRight-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(10px)}}.slide-fade-enter-active{transition:all .6s ease}.slide-fade-enter,.slide-fade-leave-to{transform:translateX(10px);opacity:0}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,32 +1,55 @@
<template>
<div id="app" class="col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1 offset">
<div class="mb-3" v-for="book in cookbooks" v-bind:key="book.id">
<div class="col-12 col-xl-8 col-lg-10 offset-xl-2 offset-lg-1">
<div class="row">
<div class="col col-md-12">
<div class="row justify-content-center">
<div class="col-12 col-lg-10 col-xl-8 mt-3 mb-3">
<b-input-group>
<b-input class="form-control form-control-lg form-control-borderless form-control-search"
v-model="search"
v-bind:placeholder="$t('Search')"></b-input>
<b-input-group-append>
<b-button variant="primary"
v-b-tooltip.hover :title="$t('Create')"
@click="createNew">
<i class="fas fa-plus"></i>
</b-button>
</b-input-group-append>
</b-input-group>
</div>
</div>
</div>
</div>
</div>
<div class="mb-3" v-for="book in filteredBooks" v-bind:key="book.id">
<div class="row">
<div class="col-md-12">
<b-card class="d-flex flex-column" v-hover
v-on:click="openBook(book.id)">
<b-row no-gutters style="height:inherit;">
<b-col no-gutters md="2" style="height:inherit;">
<h3>{{book.icon}}</h3>
</b-col>
<b-col no-gutters md="10" style="height:inherit;">
<b-card-body class="m-0 py-0" style="height:inherit;">
<b-card-text class="h-100 my-0 d-flex flex-column" style="text-overflow: ellipsis">
<h5 class="m-0 mt-1 text-truncate">{{ book.name }} <span class="float-right"><i class="fa fa-book"></i></span> </h5>
<div class="m-0 text-truncate">{{ book.description }}</div>
<div class="mt-auto mb-1 d-flex flex-row justify-content-end">
</div>
</b-card-text>
</b-card-body>
</b-col>
</b-row>
</b-card>
v-on:click="openBook(book.id)">
<b-row no-gutters style="height:inherit;">
<b-col no-gutters md="2" style="height:inherit;">
<h3>{{ book.icon }}</h3>
</b-col>
<b-col no-gutters md="10" style="height:inherit;">
<b-card-body class="m-0 py-0" style="height:inherit;">
<b-card-text class="h-100 my-0 d-flex flex-column" style="text-overflow: ellipsis">
<h5 class="m-0 mt-1 text-truncate">{{ book.name }} <span class="float-right"><i
class="fa fa-book"></i></span></h5>
<div class="m-0 text-truncate">{{ book.description }}</div>
<div class="mt-auto mb-1 d-flex flex-row justify-content-end">
</div>
</b-card-text>
</b-card-body>
</b-col>
</b-row>
</b-card>
</div>
</div>
<loading-spinner v-if="current_book === book.id && loading" ></loading-spinner>
<loading-spinner v-if="current_book === book.id && loading"></loading-spinner>
<transition name="slide-fade">
<cookbook-slider :recipes="recipes" :book="book" v-if="current_book === book.id && !loading"></cookbook-slider>
<cookbook-slider :recipes="recipes" :book="book" v-if="current_book === book.id && !loading" v-on:refresh="refreshData"></cookbook-slider>
</transition>
</div>
</div>
@ -40,6 +63,7 @@ import 'bootstrap-vue/dist/bootstrap-vue.css'
import {ApiApiFactory} from "../../utils/openapi/api";
import CookbookSlider from "../../components/CookbookSlider";
import LoadingSpinner from "../../components/LoadingSpinner";
import {StandardToasts} from "../../utils/utils";
Vue.use(BootstrapVue)
@ -54,6 +78,14 @@ export default {
recipes: [],
current_book: undefined,
loading: false,
search: ''
}
},
computed: {
filteredBooks: function () {
return this.cookbooks.filter(book => {
return book.name.toLowerCase().includes(this.search.toLowerCase())
})
}
},
mounted() {
@ -69,7 +101,7 @@ export default {
})
},
openBook: function (book) {
if(book === this.current_book) {
if (book === this.current_book) {
this.current_book = undefined
this.recipes = []
return
@ -82,6 +114,17 @@ export default {
this.recipes = result.data
this.loading = false
})
},
createNew: function () {
let apiClient = new ApiApiFactory()
apiClient.createRecipeBook({name: 'New Book', description: '', icon: '', shared: []}).then(result => {
let new_book = result.data
this.refreshData()
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE)
}).catch(error => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_CREATE)
})
}
},
directives: {

View File

@ -2,7 +2,7 @@
<b-card no-body v-hover>
<b-card-header class="p-4">
<h5>{{ book_copy.icon }}&nbsp;{{ book_copy.name }}
<span class="float-right" @click="editOrSave"><i
<span class="float-right text-primary" @click="editOrSave"><i
class="fa" v-bind:class="{ 'fa-pen': !editing, 'fa-save': editing }"
aria-hidden="true"></i></span></h5>
</b-card-header>
@ -24,6 +24,8 @@
</textarea>
</div>
<button v-if="editing" class="btn btn-danger" @click="deleteBook">{{$t('Delete')}}</button>
<button v-if="editing" class="btn btn-primary float-right" @click="editOrSave">{{$t('Save')}}</button>
<b-card-text style="text-overflow: ellipsis;" v-if="!editing">
{{ book_copy.description }}
</b-card-text>
@ -97,6 +99,18 @@ export default {
this.users = result.data
})
},
deleteBook: function () {
if (confirm(this.$t('delete_confirmation', {source: this.book.name}))) {
let apiClient = new ApiApiFactory()
apiClient.destroyRecipeBook(this.book.id).then(result => {
this.$emit('refresh')
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_DELETE)
}).catch(error => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_DELETE)
})
}
}
}
}
</script>

View File

@ -19,7 +19,7 @@
<div class="col-md-5">
<transition name="flip" mode="out-in">
<cookbook-edit-card :book="book" v-if="current_page === 1"
v-on:editing="cookbook_editing = $event"></cookbook-edit-card>
v-on:editing="cookbook_editing = $event" v-on:refresh="$emit('refresh')"></cookbook-edit-card>
</transition>
<transition name="flip" mode="out-in">
<recipe-card :recipe="display_recipes[0].recipe_content"

View File

@ -22,7 +22,7 @@ export class Models {
'operator': 'not_exist',
'true': 0,
'false': undefined
}
}
},
'tree': {'default': undefined},
},
@ -34,10 +34,10 @@ export class Models {
'type': 'instruction',
'function': 'translate',
'phrase': "del_confimation_tree",
'params':[
'params': [
{
'token': 'source',
'from':'item1',
'from': 'item1',
'attribute': "name"
}
]
@ -51,7 +51,7 @@ export class Models {
'type': 'lookup',
'field': 'target',
'list': 'self',
'sticky_options': [{'id': 0,'name': i18n.t('tree_root')}]
'sticky_options': [{'id': 0, 'name': i18n.t('tree_root')}]
}
}
}
@ -111,7 +111,7 @@ export class Models {
}
static KEYWORD = {
'name': i18n.t('Keyword'), // *OPTIONAL: parameters will be built model -> model_type -> default
'apiName': 'Keyword',
'apiName': 'Keyword',
'model_type': this.TREE,
'badges': {
'icon': true
@ -145,7 +145,7 @@ export class Models {
}
static UNIT = {
'name': i18n.t('Unit'),
'apiName': 'Unit',
'apiName': 'Unit',
'create': {
'params': [['name', 'description']],
'form': {
@ -170,7 +170,32 @@ export class Models {
static SHOPPING_LIST = {}
static RECIPE_BOOK = {
'name': i18n.t('Recipe_Book'),
'apiName': 'RecipeBook',
'apiName': 'RecipeBook',
'create': {
'params': [['name', 'description', 'icon']],
'form': {
'name': {
'form_field': true,
'type': 'text',
'field': 'name',
'label': i18n.t('Name'),
'placeholder': ''
},
'description': {
'form_field': true,
'type': 'text',
'field': 'description',
'label': i18n.t('Description'),
'placeholder': ''
},
'icon': {
'form_field': true,
'type': 'emoji',
'field': 'icon',
'label': i18n.t('Icon')
},
}
},
}
static SHOPPING_CATEGORY = {
'name': i18n.t('Shopping_Category'),
@ -195,14 +220,14 @@ export class Models {
}
},
}
static RECIPE = {
'name': i18n.t('Recipe'),
'apiName': 'Recipe',
'list': {
'params': ['query', 'keywords', 'foods', 'units', 'rating', 'books', 'keywordsOr', 'foodsOr', 'booksOr', 'internal', 'random', '_new', 'page', 'pageSize', 'options'],
'config': {
'foods': {'type':'string'},
'foods': {'type': 'string'},
'keywords': {'type': 'string'},
'books': {'type': 'string'},
}
@ -228,11 +253,11 @@ export class Actions {
'title': {
'function': 'translate',
'phrase': 'create_title',
'params' : [
'params': [
{
'token': 'type',
'from': 'model',
'attribute':'name'
'attribute': 'name'
}
],
},
@ -245,11 +270,11 @@ export class Actions {
"form_title": {
'function': 'translate',
'phrase': 'edit_title',
'params' : [
'params': [
{
'token': 'type',
'from': 'model',
'attribute':'name'
'attribute': 'name'
}
],
},
@ -261,11 +286,11 @@ export class Actions {
'title': {
'function': 'translate',
'phrase': 'delete_title',
'params' : [
'params': [
{
'token': 'type',
'from': 'model',
'attribute':'name'
'attribute': 'name'
}
],
},
@ -276,10 +301,10 @@ export class Actions {
'label': {
'function': 'translate',
'phrase': "delete_confirmation",
'params':[
'params': [
{
'token': 'source',
'from':'item1',
'from': 'item1',
'attribute': "name"
}
]
@ -312,11 +337,11 @@ export class Actions {
'title': {
'function': 'translate',
'phrase': 'merge_title',
'params' : [
'params': [
{
'token': 'type',
'from': 'model',
'attribute':'name'
'attribute': 'name'
}
],
},
@ -327,15 +352,15 @@ export class Actions {
'label': {
'function': 'translate',
'phrase': "merge_selection",
'params':[
'params': [
{
'token': 'source',
'from':'item1',
'from': 'item1',
'attribute': "name"
},
{
'token': 'type',
'from':'model',
'from': 'model',
'attribute': "name"
},
]
@ -360,11 +385,11 @@ export class Actions {
'title': {
'function': 'translate',
'phrase': 'move_title',
'params' : [
'params': [
{
'token': 'type',
'from': 'model',
'attribute':'name'
'attribute': 'name'
}
],
},
@ -375,20 +400,20 @@ export class Actions {
'label': {
'function': 'translate',
'phrase': "move_selection",
'params':[
'params': [
{
'token': 'source',
'from':'item1',
'from': 'item1',
'attribute': "name"
},
{
'token': 'type',
'from':'model',
'from': 'model',
'attribute': "name"
},
]
}
},
'target': {
'form_field': true,
@ -397,6 +422,6 @@ export class Actions {
'list': 'self'
}
}
}
}

View File

@ -3,47 +3,55 @@
"assets": {
"../../templates/sw.js": {
"name": "../../templates/sw.js",
"path": "../../templates/sw.js"
"path": "..\\..\\templates\\sw.js"
},
"css/chunk-vendors.css": {
"name": "css/chunk-vendors.css",
"path": "css/chunk-vendors.css"
"path": "css\\chunk-vendors.css"
},
"js/chunk-vendors.js": {
"name": "js/chunk-vendors.js",
"path": "js/chunk-vendors.js"
"path": "js\\chunk-vendors.js"
},
"css/cookbook_view.css": {
"name": "css/cookbook_view.css",
"path": "css\\cookbook_view.css"
},
"js/cookbook_view.js": {
"name": "js/cookbook_view.js",
"path": "js\\cookbook_view.js"
},
"js/import_response_view.js": {
"name": "js/import_response_view.js",
"path": "js/import_response_view.js"
"path": "js\\import_response_view.js"
},
"css/model_list_view.css": {
"name": "css/model_list_view.css",
"path": "css/model_list_view.css"
"path": "css\\model_list_view.css"
},
"js/model_list_view.js": {
"name": "js/model_list_view.js",
"path": "js/model_list_view.js"
"path": "js\\model_list_view.js"
},
"js/offline_view.js": {
"name": "js/offline_view.js",
"path": "js/offline_view.js"
"path": "js\\offline_view.js"
},
"js/recipe_search_view.js": {
"name": "js/recipe_search_view.js",
"path": "js/recipe_search_view.js"
"path": "js\\recipe_search_view.js"
},
"js/recipe_view.js": {
"name": "js/recipe_view.js",
"path": "js/recipe_view.js"
"path": "js\\recipe_view.js"
},
"js/supermarket_view.js": {
"name": "js/supermarket_view.js",
"path": "js/supermarket_view.js"
"path": "js\\supermarket_view.js"
},
"js/user_file_view.js": {
"name": "js/user_file_view.js",
"path": "js/user_file_view.js"
"path": "js\\user_file_view.js"
},
"recipe_search_view.html": {
"name": "recipe_search_view.html",
@ -73,6 +81,10 @@
"name": "model_list_view.html",
"path": "model_list_view.html"
},
"cookbook_view.html": {
"name": "cookbook_view.html",
"path": "cookbook_view.html"
},
"manifest.json": {
"name": "manifest.json",
"path": "manifest.json"
@ -114,6 +126,12 @@
"js/chunk-vendors.js",
"css/model_list_view.css",
"js/model_list_view.js"
],
"cookbook_view": [
"css/chunk-vendors.css",
"js/chunk-vendors.js",
"css/cookbook_view.css",
"js/cookbook_view.js"
]
}
}