Merge branch 'develop' into deprecate_settings_form
This commit is contained in:
commit
1883da5e49
@ -983,6 +983,8 @@ class RecipeBook(ExportModelOperationsMixin('book'), models.Model, PermissionMod
|
|||||||
shared = models.ManyToManyField(User, blank=True, related_name='shared_with')
|
shared = models.ManyToManyField(User, blank=True, related_name='shared_with')
|
||||||
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
filter = models.ForeignKey('cookbook.CustomFilter', null=True, blank=True, on_delete=models.SET_NULL)
|
filter = models.ForeignKey('cookbook.CustomFilter', null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
|
order = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
|
||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
@ -979,7 +979,7 @@ class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer)
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RecipeBook
|
model = RecipeBook
|
||||||
fields = ('id', 'name', 'description', 'shared', 'created_by', 'filter')
|
fields = ('id', 'name', 'description', 'shared', 'created_by', 'filter', 'order')
|
||||||
read_only_fields = ('created_by',)
|
read_only_fields = ('created_by',)
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@
|
|||||||
|
|
||||||
window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}'
|
window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}'
|
||||||
window.RECIPE_ID = {{recipe.pk}};
|
window.RECIPE_ID = {{recipe.pk}};
|
||||||
|
window.RECIPE_SERVINGS = '{{ servings }}'
|
||||||
window.SHARE_UID = '{{ share }}';
|
window.SHARE_UID = '{{ share }}';
|
||||||
window.USER_PREF = {
|
window.USER_PREF = {
|
||||||
'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %},
|
'use_fractions': {% if request.user.userpreference.use_fractions %} true {% else %} false {% endif %},
|
||||||
|
@ -662,8 +662,16 @@ class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin):
|
|||||||
permission_classes = [(CustomIsOwner | CustomIsShared) & CustomTokenHasReadWriteScope]
|
permission_classes = [(CustomIsOwner | CustomIsShared) & CustomTokenHasReadWriteScope]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
order_field = self.request.GET.get('order_field')
|
||||||
|
order_direction = self.request.GET.get('order_direction')
|
||||||
|
|
||||||
|
if not order_field:
|
||||||
|
order_field = 'id'
|
||||||
|
|
||||||
|
ordering = f"{'' if order_direction == 'asc' else '-'}{order_field}"
|
||||||
|
|
||||||
self.queryset = self.queryset.filter(Q(created_by=self.request.user) | Q(shared=self.request.user)).filter(
|
self.queryset = self.queryset.filter(Q(created_by=self.request.user) | Q(shared=self.request.user)).filter(
|
||||||
space=self.request.space).distinct()
|
space=self.request.space).distinct().order_by(ordering)
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +157,11 @@ def recipe_view(request, pk, share=None):
|
|||||||
if not ViewLog.objects.filter(recipe=recipe, created_by=request.user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)), space=request.space).exists():
|
if not ViewLog.objects.filter(recipe=recipe, created_by=request.user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)), space=request.space).exists():
|
||||||
ViewLog.objects.create(recipe=recipe, created_by=request.user, space=request.space)
|
ViewLog.objects.create(recipe=recipe, created_by=request.user, space=request.space)
|
||||||
|
|
||||||
return render(request, 'recipe_view.html', {'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, })
|
if request.method == "GET":
|
||||||
|
servings = request.GET.get("servings")
|
||||||
|
return render(request, 'recipe_view.html',
|
||||||
|
{'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, 'servings': servings })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@group_required('user')
|
@group_required('user')
|
||||||
|
@ -5,7 +5,7 @@ django-autocomplete-light==3.9.7
|
|||||||
django-cleanup==8.0.0
|
django-cleanup==8.0.0
|
||||||
django-crispy-forms==2.0
|
django-crispy-forms==2.0
|
||||||
crispy-bootstrap4==2022.1
|
crispy-bootstrap4==2022.1
|
||||||
django-tables2==2.5.3
|
django-tables2==2.7.0
|
||||||
djangorestframework==3.14.0
|
djangorestframework==3.14.0
|
||||||
drf-writable-nested==0.7.0
|
drf-writable-nested==0.7.0
|
||||||
django-oauth-toolkit==2.3.0
|
django-oauth-toolkit==2.3.0
|
||||||
@ -40,8 +40,8 @@ django-storages==1.14.2
|
|||||||
boto3==1.28.75
|
boto3==1.28.75
|
||||||
django-prometheus==2.2.0
|
django-prometheus==2.2.0
|
||||||
django-hCaptcha==0.2.0
|
django-hCaptcha==0.2.0
|
||||||
python-ldap==3.4.3
|
python-ldap==3.4.4
|
||||||
django-auth-ldap==4.4.0
|
django-auth-ldap==4.6.0
|
||||||
pytest-factoryboy==2.6.0
|
pytest-factoryboy==2.6.0
|
||||||
pyppeteer==1.0.2
|
pyppeteer==1.0.2
|
||||||
validators==0.20.0
|
validators==0.20.0
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
"@codemirror/commands": "^6.3.2",
|
"@codemirror/commands": "^6.3.2",
|
||||||
"@codemirror/lang-markdown": "^6.2.3",
|
"@codemirror/lang-markdown": "^6.2.3",
|
||||||
"@codemirror/state": "^6.3.3",
|
"@codemirror/state": "^6.3.3",
|
||||||
"@codemirror/view": "^6.22.2",
|
"@codemirror/view": "^6.23.1",
|
||||||
"@popperjs/core": "^2.11.7",
|
"@popperjs/core": "^2.11.7",
|
||||||
"@vue/cli": "^5.0.8",
|
"@vue/cli": "^5.0.8",
|
||||||
"@vue/composition-api": "1.7.1",
|
"@vue/composition-api": "1.7.1",
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.7",
|
||||||
"babel": "^6.23.0",
|
"babel": "^6.23.0",
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
"babel-loader": "^9.1.0",
|
"babel-loader": "^9.1.0",
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mavon-editor": "^2.10.4",
|
"mavon-editor": "^2.10.4",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"pinia": "^2.0.30",
|
"pinia": "^2.1.7",
|
||||||
"prismjs": "^1.29.0",
|
"prismjs": "^1.29.0",
|
||||||
"string-similarity": "^4.0.4",
|
"string-similarity": "^4.0.4",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
@ -61,9 +61,9 @@
|
|||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^8.46.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint-plugin-vue": "^8.7.1",
|
"eslint-plugin-vue": "^8.7.1",
|
||||||
"typescript": "~5.1.6",
|
"typescript": "~5.3.3",
|
||||||
"vue-cli-plugin-i18n": "^2.3.2",
|
"vue-cli-plugin-i18n": "^2.3.2",
|
||||||
"webpack-bundle-tracker": "1.8.1",
|
"webpack-bundle-tracker": "3.0.1",
|
||||||
"workbox-background-sync": "^7.0.0",
|
"workbox-background-sync": "^7.0.0",
|
||||||
"workbox-expiration": "^6.5.4",
|
"workbox-expiration": "^6.5.4",
|
||||||
"workbox-navigation-preload": "^7.0.0",
|
"workbox-navigation-preload": "^7.0.0",
|
||||||
|
@ -11,50 +11,90 @@
|
|||||||
<b-button variant="primary" v-b-tooltip.hover :title="$t('Create')" @click="createNew">
|
<b-button variant="primary" v-b-tooltip.hover :title="$t('Create')" @click="createNew">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
</b-button>
|
</b-button>
|
||||||
|
<b-dropdown variant="primary" id="sortDropDown" text="Order By" class="border-left">
|
||||||
|
<b-dropdown-item @click = "orderBy('id','asc')" :disabled= "isActiveSort('id','asc')">oldest to newest</b-dropdown-item>
|
||||||
|
<b-dropdown-item @click = "orderBy('id','desc')" :disabled= "isActiveSort('id','desc')">newest to oldest</b-dropdown-item>
|
||||||
|
<b-dropdown-item @click = "orderBy('name','asc')" :disabled= "isActiveSort('name','asc')">alphabetical order</b-dropdown-item>
|
||||||
|
<b-dropdown-item @click = "orderBy('order','asc')" :disabled= "isActiveSort('order','asc')" >manually</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
</b-input-group-append>
|
</b-input-group-append>
|
||||||
|
<b-button class= "ml-2" variant="primary" v-if="isActiveSort('order','asc')" @click="handleEditButton" >
|
||||||
|
{{submitText}}
|
||||||
|
</b-button>
|
||||||
</b-input-group>
|
</b-input-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-bottom: 55px">
|
<div v-if="!isActiveSort('order','asc') || !manSubmitted">
|
||||||
<div class="mb-3" v-for="book in filteredBooks" :key="book.id">
|
<div style="padding-bottom: 55px">
|
||||||
<div class="row">
|
<div class="mb-3" v-for="(book) in filteredBooks" :key="book.id">
|
||||||
<div class="col-md-12">
|
<div class="row">
|
||||||
<b-card class="d-flex flex-column" v-hover v-on:click="openBook(book.id)">
|
<div class="col-md-12">
|
||||||
<b-row no-gutters style="height: inherit">
|
<b-card class="d-flex flex-column" v-hover >
|
||||||
<b-col no-gutters md="10" style="height: inherit">
|
<b-row no-gutters style="height: inherit" class="d-flex align-items-center">
|
||||||
<b-card-body class="m-0 py-0" style="height: inherit">
|
<b-col no-gutters style="height: inherit">
|
||||||
<b-card-text class="h-100 my-0 d-flex flex-column" style="text-overflow: ellipsis">
|
<b-card-body class="m-0 py-0" style="height: inherit">
|
||||||
<h5 class="m-0 mt-1 text-truncate">
|
<b-card-text class="h-100 my-0 d-flex flex-column" style="text-overflow: ellipsis">
|
||||||
{{ book.name }} <span class="float-right"><i class="fa fa-book"></i></span>
|
<b-button v-on:click="openBook(book.id)" style="color: #000; background-color: white" variant="primary">
|
||||||
</h5>
|
<h5 class="m-0 mt-1 text-truncate" >
|
||||||
<div class="m-0 text-truncate">{{ book.description }}</div>
|
{{ book.name }} <span class="float-right"><i class="fa fa-book"></i></span>
|
||||||
<div class="mt-auto mb-1 d-flex flex-row justify-content-end"></div>
|
</h5></b-button>
|
||||||
</b-card-text>
|
<div class="m-0 text-truncate">{{ book.description }}</div>
|
||||||
</b-card-body>
|
<div class="mt-auto mb-1 d-flex flex-row justify-content-end"></div>
|
||||||
</b-col>
|
</b-card-text>
|
||||||
</b-row>
|
</b-card-body>
|
||||||
</b-card>
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<loading-spinner v-if="current_book === book.id && loading"></loading-spinner>
|
||||||
|
<transition name="slide-fade">
|
||||||
|
<cookbook-slider
|
||||||
|
:recipes="recipes"
|
||||||
|
:book="book"
|
||||||
|
:key="`slider_${book.id}`"
|
||||||
|
v-if="current_book === book.id && !loading"
|
||||||
|
v-on:refresh="refreshData"
|
||||||
|
@reload="openBook(current_book, true)"
|
||||||
|
></cookbook-slider>
|
||||||
|
</transition>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<loading-spinner v-if="current_book === book.id && loading"></loading-spinner>
|
<div v-else>
|
||||||
<transition name="slide-fade">
|
<draggable
|
||||||
<cookbook-slider
|
@change="updateManualSorting"
|
||||||
:recipes="recipes"
|
:list="cookbooks" ghost-class="ghost">
|
||||||
:book="book"
|
<b-card no-body class="mt-1 list-group-item p-2"
|
||||||
:key="`slider_${book.id}`"
|
style="cursor: move"
|
||||||
v-if="current_book === book.id && !loading"
|
v-for=" (book,index) in filteredBooks"
|
||||||
v-on:refresh="refreshData"
|
v-hover
|
||||||
@reload="openBook(current_book, true)"
|
:key="book.id">
|
||||||
></cookbook-slider>
|
<b-card-header class="p-2 border-0">
|
||||||
</transition>
|
<div class="row">
|
||||||
|
<div class="col-2">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-lg shadow-none"><i
|
||||||
|
class="fas fa-arrows-alt-v"></i></button>
|
||||||
|
</div>
|
||||||
|
<div class="col-10">
|
||||||
|
<h5 class="mt-1 mb-1">
|
||||||
|
<b-badge class="float-left text-white mr-2">
|
||||||
|
#{{ index + 1 }}
|
||||||
|
</b-badge>
|
||||||
|
{{ book.name }}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-card-header>
|
||||||
|
</b-card>
|
||||||
|
</draggable>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<bottom-navigation-bar active-view="view_books">
|
<bottom-navigation-bar active-view="view_books">
|
||||||
<template #custom_create_functions>
|
<template #custom_create_functions>
|
||||||
@ -72,7 +112,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Vue from "vue"
|
import Vue from "vue"
|
||||||
import { BootstrapVue } from "bootstrap-vue"
|
import { BootstrapVue } from "bootstrap-vue"
|
||||||
|
import draggable from "vuedraggable"
|
||||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||||
import { ApiApiFactory } from "@/utils/openapi/api"
|
import { ApiApiFactory } from "@/utils/openapi/api"
|
||||||
import CookbookSlider from "@/components/CookbookSlider"
|
import CookbookSlider from "@/components/CookbookSlider"
|
||||||
@ -85,7 +125,7 @@ Vue.use(BootstrapVue)
|
|||||||
export default {
|
export default {
|
||||||
name: "CookbookView",
|
name: "CookbookView",
|
||||||
mixins: [ApiMixin],
|
mixins: [ApiMixin],
|
||||||
components: { LoadingSpinner, CookbookSlider, BottomNavigationBar },
|
components: { LoadingSpinner, CookbookSlider, BottomNavigationBar, draggable },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
cookbooks: [],
|
cookbooks: [],
|
||||||
@ -94,6 +134,11 @@ export default {
|
|||||||
current_book: undefined,
|
current_book: undefined,
|
||||||
loading: false,
|
loading: false,
|
||||||
search: "",
|
search: "",
|
||||||
|
activeSortField : 'id',
|
||||||
|
activeSortDirection: 'desc',
|
||||||
|
inputValue: "",
|
||||||
|
manSubmitted : false,
|
||||||
|
submitText: "Edit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -110,7 +155,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
refreshData: function () {
|
refreshData: function () {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
|
|
||||||
apiClient.listRecipeBooks().then((result) => {
|
apiClient.listRecipeBooks().then((result) => {
|
||||||
this.cookbooks = result.data
|
this.cookbooks = result.data
|
||||||
})
|
})
|
||||||
@ -168,7 +213,45 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
orderBy: function(order_field,order_direction){
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
const options = {
|
||||||
|
order_field: order_field,
|
||||||
|
order_direction: order_direction
|
||||||
|
}
|
||||||
|
this.activeSortField = order_field
|
||||||
|
this.activeSortDirection = order_direction
|
||||||
|
apiClient.listRecipeBooks(options).then((result) => {
|
||||||
|
this.cookbooks = result.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
isActiveSort: function(field, direction) {
|
||||||
|
// Check if the current item is the active sorting option
|
||||||
|
return this.activeSortField === field && this.activeSortDirection === direction;
|
||||||
|
},
|
||||||
|
handleEditButton: function(){
|
||||||
|
if (!this.manSubmitted){
|
||||||
|
this.submitText = "Back"
|
||||||
|
this.manSubmitted = true
|
||||||
|
} else {
|
||||||
|
this.submitText = "Edit"
|
||||||
|
this.manSubmitted = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateManualSorting: function(){
|
||||||
|
let old_order = Object.assign({}, this.cookbooks);
|
||||||
|
let promises = []
|
||||||
|
this.cookbooks.forEach((element, index) => {
|
||||||
|
let apiClient = new ApiApiFactory()
|
||||||
|
promises.push(apiClient.partialUpdateManualOrderBooks(element.id, {order: index}))
|
||||||
|
})
|
||||||
|
return Promise.all(promises).then(() => {
|
||||||
|
}).catch((err) => {
|
||||||
|
this.cookbooks = old_order
|
||||||
|
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
directives: {
|
directives: {
|
||||||
hover: {
|
hover: {
|
||||||
inserted: function (el) {
|
inserted: function (el) {
|
||||||
|
@ -126,7 +126,7 @@
|
|||||||
<div class="flex-grow-1 ml-2"
|
<div class="flex-grow-1 ml-2"
|
||||||
style="text-overflow: ellipsis; overflow-wrap: anywhere;">
|
style="text-overflow: ellipsis; overflow-wrap: anywhere;">
|
||||||
<span class="two-row-text">
|
<span class="two-row-text">
|
||||||
<a :href="resolveDjangoUrl('view_recipe', plan.entry.recipe.id)" v-if="plan.entry.recipe">{{ plan.entry.recipe.name }}</a>
|
<a :href="getRecipeURL(plan.entry.recipe, plan.entry.servings)" v-if="plan.entry.recipe">{{ plan.entry.recipe.name }}</a>
|
||||||
<span v-else>{{ plan.entry.title }}</span> <br/>
|
<span v-else>{{ plan.entry.title }}</span> <br/>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="plan.entry.note" class="two-row-text">
|
<span v-if="plan.entry.note" class="two-row-text">
|
||||||
@ -169,7 +169,7 @@
|
|||||||
v-if="contextData && contextData.originalItem && contextData.originalItem.entry.recipe != null"
|
v-if="contextData && contextData.originalItem && contextData.originalItem.entry.recipe != null"
|
||||||
@click="
|
@click="
|
||||||
$refs.menu.close()
|
$refs.menu.close()
|
||||||
openRecipe(contextData.originalItem.entry.recipe)
|
openRecipe(contextData.originalItem.entry.recipe, contextData.originalItem.entry.servings)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<a class="dropdown-item p-2" href="javascript:void(0)"><i class="fas fa-pizza-slice"></i>
|
<a class="dropdown-item p-2" href="javascript:void(0)"><i class="fas fa-pizza-slice"></i>
|
||||||
@ -392,8 +392,13 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openRecipe: function (recipe) {
|
|
||||||
window.open(this.resolveDjangoUrl("view_recipe", recipe.id))
|
getRecipeURL: function (recipe, servings) {
|
||||||
|
return this.resolveDjangoUrl("view_recipe",`${recipe.id}?servings=${servings}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
openRecipe: function (recipe, servings) {
|
||||||
|
window.open(this.getRecipeURL(recipe, servings))
|
||||||
},
|
},
|
||||||
setStartingDay(days) {
|
setStartingDay(days) {
|
||||||
if (this.settings.startingDayOfWeek + days < 0) {
|
if (this.settings.startingDayOfWeek + days < 0) {
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1>EDITOR</h1>
|
<h1>EDITOR</h1>
|
||||||
|
|
||||||
<b-button @click="toolbarTest()">Test</b-button>
|
<b-button @click="toolbarTest()">Heading</b-button>
|
||||||
|
<b-button @click="bold()">B</b-button>
|
||||||
<div id="editor" style="background-color: #fff; border: solid 1px">
|
<div id="editor" style="background-color: #fff; border: solid 1px">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -176,6 +177,33 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.editor_view.dispatch(transaction)
|
this.editor_view.dispatch(transaction)
|
||||||
|
},
|
||||||
|
bold() {
|
||||||
|
const transaction = this.editor_view.state.changeByRange((range) => {
|
||||||
|
|
||||||
|
if (range.anchor === range.head) {
|
||||||
|
console.log('nothing selected --> nothing bold')
|
||||||
|
} else {
|
||||||
|
let selected_text = this.editor_view.state.sliceDoc(range.from, range.to)
|
||||||
|
|
||||||
|
let new_text = `**${selected_text}**`
|
||||||
|
|
||||||
|
const changes = {
|
||||||
|
from: range.from,
|
||||||
|
to: range.to,
|
||||||
|
insert: new_text,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {changes, range: EditorSelection.range(range.anchor + 2, range.head + 2)}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
this.editor_view.dispatch(transaction)
|
||||||
|
},
|
||||||
|
heading(editor, heading_size) {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,7 @@ export default {
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
recipe_id: Number,
|
recipe_id: Number,
|
||||||
|
def_servings: Number,
|
||||||
recipe_obj: {type: Object, default: null},
|
recipe_obj: {type: Object, default: null},
|
||||||
show_context_menu: {type: Boolean, default: true},
|
show_context_menu: {type: Boolean, default: true},
|
||||||
enable_keyword_links: {type: Boolean, default: true},
|
enable_keyword_links: {type: Boolean, default: true},
|
||||||
@ -320,8 +321,13 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
if (this.recipe.image === null) this.printReady()
|
if (this.recipe.image === null) this.printReady()
|
||||||
|
window.RECIPE_SERVINGS = Number(window.RECIPE_SERVINGS)
|
||||||
this.servings = this.servings_cache[this.rootrecipe.id] = this.recipe.servings
|
if (window.RECIPE_SERVINGS && ! isNaN(window.RECIPE_SERVINGS)) {
|
||||||
|
//I am not sure this is the best way. This overwrites our servings cache, which may not be intended?
|
||||||
|
this.servings = window.RECIPE_SERVINGS
|
||||||
|
} else {
|
||||||
|
this.servings = this.servings_cache[this.rootrecipe.id] = this.recipe.servings
|
||||||
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -9172,6 +9172,13 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
|
|||||||
const localVarQueryParameter = {} as any;
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
|
||||||
|
if (options.order_field !== undefined) {
|
||||||
|
localVarQueryParameter['order_field'] = options.order_field;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.order_direction!== undefined) {
|
||||||
|
localVarQueryParameter['order_direction'] = options.order_direction;
|
||||||
|
}
|
||||||
|
|
||||||
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
|
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
|
||||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||||
@ -10263,6 +10270,40 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
|
|||||||
options: localVarRequestOptions,
|
options: localVarRequestOptions,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} id A unique integer value identifying the book.
|
||||||
|
* @param {RecipeBook} [recipeBook]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
partialUpdateManualOrderBooks: async (id: string, recipeBook?: RecipeBook , options: any = {}): Promise<RequestArgs> => {
|
||||||
|
const localVarPath = `/api/recipe-book/{id}/`
|
||||||
|
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||||
|
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||||
|
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||||
|
|
||||||
|
setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
|
||||||
|
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||||
|
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||||
|
localVarRequestOptions.data = serializeDataIfNeeded(recipeBook , localVarRequestOptions, configuration)
|
||||||
|
return {
|
||||||
|
url: toPathString(localVarUrlObj),
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id A unique integer value identifying this access token.
|
* @param {string} id A unique integer value identifying this access token.
|
||||||
@ -16430,6 +16471,17 @@ export const ApiApiFp = function(configuration?: Configuration) {
|
|||||||
const localVarAxiosArgs = await localVarAxiosParamCreator.moveKeyword(id, parent, keyword, options);
|
const localVarAxiosArgs = await localVarAxiosParamCreator.moveKeyword(id, parent, keyword, options);
|
||||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} id A unique integer value identifying this supermarket category relation.
|
||||||
|
* @param {RecipeBook} [recipeBook]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
async partialUpdateManualOrderBooks(id: string, recipeBook?: RecipeBook, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SupermarketCategoryRelation>> {
|
||||||
|
const localVarAxiosArgs = await localVarAxiosParamCreator.partialUpdateManualOrderBooks(id, recipeBook, options);
|
||||||
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id A unique integer value identifying this access token.
|
* @param {string} id A unique integer value identifying this access token.
|
||||||
@ -19121,6 +19173,16 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
|
|||||||
moveKeyword(id: string, parent: string, keyword?: Keyword, options?: any): AxiosPromise<Keyword> {
|
moveKeyword(id: string, parent: string, keyword?: Keyword, options?: any): AxiosPromise<Keyword> {
|
||||||
return localVarFp.moveKeyword(id, parent, keyword, options).then((request) => request(axios, basePath));
|
return localVarFp.moveKeyword(id, parent, keyword, options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} id A unique integer value identifying this supermarket category relation.
|
||||||
|
* @param {RecipeBook} [recipeBook]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
partialUpdateManualOrderBooks(id: string, recipeBook?: RecipeBook, options?: any): AxiosPromise<SupermarketCategoryRelation> {
|
||||||
|
return localVarFp.partialUpdateManualOrderBooks(id, recipeBook, options).then((request) => request(axios, basePath));
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id A unique integer value identifying this access token.
|
* @param {string} id A unique integer value identifying this access token.
|
||||||
@ -20707,7 +20769,6 @@ export class ApiApi extends BaseAPI {
|
|||||||
public createRecipeBookEntry(recipeBookEntry?: RecipeBookEntry, options?: any) {
|
public createRecipeBookEntry(recipeBookEntry?: RecipeBookEntry, options?: any) {
|
||||||
return ApiApiFp(this.configuration).createRecipeBookEntry(recipeBookEntry, options).then((request) => request(this.axios, this.basePath));
|
return ApiApiFp(this.configuration).createRecipeBookEntry(recipeBookEntry, options).then((request) => request(this.axios, this.basePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function to retrieve a recipe from a given url or source string :param request: standard request with additional post parameters - url: url to use for importing recipe - data: if no url is given recipe is imported from provided source data - (optional) bookmarklet: id of bookmarklet import to use, overrides URL and data attributes :return: JsonResponse containing the parsed json and images
|
* function to retrieve a recipe from a given url or source string :param request: standard request with additional post parameters - url: url to use for importing recipe - data: if no url is given recipe is imported from provided source data - (optional) bookmarklet: id of bookmarklet import to use, overrides URL and data attributes :return: JsonResponse containing the parsed json and images
|
||||||
* @param {any} [body]
|
* @param {any} [body]
|
||||||
@ -21951,7 +22012,16 @@ export class ApiApi extends BaseAPI {
|
|||||||
public moveKeyword(id: string, parent: string, keyword?: Keyword, options?: any) {
|
public moveKeyword(id: string, parent: string, keyword?: Keyword, options?: any) {
|
||||||
return ApiApiFp(this.configuration).moveKeyword(id, parent, keyword, options).then((request) => request(this.axios, this.basePath));
|
return ApiApiFp(this.configuration).moveKeyword(id, parent, keyword, options).then((request) => request(this.axios, this.basePath));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} id A unique integer value identifying this supermarket category relation.
|
||||||
|
* @param {RecipeBook} [recipeBook]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
public partialUpdateManualOrderBooks(id: string, recipeBook?: RecipeBook, options?: any) {
|
||||||
|
return ApiApiFp(this.configuration).partialUpdateManualOrderBooks(id, recipeBook, options).then((request) => request(this.axios, this.basePath));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} id A unique integer value identifying this access token.
|
* @param {string} id A unique integer value identifying this access token.
|
||||||
|
@ -1341,17 +1341,17 @@
|
|||||||
"@codemirror/view" "^6.0.0"
|
"@codemirror/view" "^6.0.0"
|
||||||
crelt "^1.0.5"
|
crelt "^1.0.5"
|
||||||
|
|
||||||
"@codemirror/state@^6.0.0", "@codemirror/state@^6.1.4", "@codemirror/state@^6.2.0", "@codemirror/state@^6.3.3":
|
"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.0", "@codemirror/state@^6.3.3", "@codemirror/state@^6.4.0":
|
||||||
version "6.3.3"
|
version "6.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.3.3.tgz#6a647c2fa62b68604187152de497e91aabf43f82"
|
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.0.tgz#8bc3e096c84360b34525a84696a84f86b305363a"
|
||||||
integrity sha512-0wufKcTw2dEwEaADajjHf6hBy1sh3M6V0e+q4JKIhLuiMSe5td5HOWpUdvKth1fT1M9VYOboajoBHpkCd7PG7A==
|
integrity sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==
|
||||||
|
|
||||||
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.22.2":
|
"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.1":
|
||||||
version "6.22.2"
|
version "6.23.1"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.22.2.tgz#79a4b87f5bb3f057cb046295b102eb04fd31a50d"
|
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.23.1.tgz#1ce3039a588d6b93f153b7c4c035c2075ede34a6"
|
||||||
integrity sha512-cJp64cPXm7QfSBWEXK+76+hsZCGHupUgy8JAbSzMG6Lr0rfK73c1CaWITVW6hZVkOnAFxJTxd0PIuynNbzxYPw==
|
integrity sha512-J2Xnn5lFYT1ZN/5ewEoMBCmLlL71lZ3mBdb7cUEuHhX2ESoSrNEucpsDXpX22EuTGm9LOgC9v4Z0wx+Ez8QmGA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@codemirror/state" "^6.1.4"
|
"@codemirror/state" "^6.4.0"
|
||||||
style-mod "^4.1.0"
|
style-mod "^4.1.0"
|
||||||
w3c-keyname "^2.2.4"
|
w3c-keyname "^2.2.4"
|
||||||
|
|
||||||
@ -3405,12 +3405,12 @@ available-typed-arrays@^1.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
||||||
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
||||||
|
|
||||||
axios@^1.6.0:
|
axios@^1.6.7:
|
||||||
version "1.6.0"
|
version "1.6.7"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7"
|
||||||
integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==
|
integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "^1.15.0"
|
follow-redirects "^1.15.4"
|
||||||
form-data "^4.0.0"
|
form-data "^4.0.0"
|
||||||
proxy-from-env "^1.1.0"
|
proxy-from-env "^1.1.0"
|
||||||
|
|
||||||
@ -5997,10 +5997,10 @@ flush-write-stream@^1.0.0:
|
|||||||
inherits "^2.0.3"
|
inherits "^2.0.3"
|
||||||
readable-stream "^2.3.6"
|
readable-stream "^2.3.6"
|
||||||
|
|
||||||
follow-redirects@^1.0.0, follow-redirects@^1.15.0:
|
follow-redirects@^1.0.0, follow-redirects@^1.15.4:
|
||||||
version "1.15.4"
|
version "1.15.5"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020"
|
||||||
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
|
integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==
|
||||||
|
|
||||||
for-each@^0.3.3:
|
for-each@^0.3.3:
|
||||||
version "0.3.3"
|
version "0.3.3"
|
||||||
@ -8798,10 +8798,10 @@ pify@^4.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
||||||
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
||||||
|
|
||||||
pinia@^2.0.30:
|
pinia@^2.1.7:
|
||||||
version "2.1.6"
|
version "2.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.6.tgz#e88959f14b61c4debd9c42d0c9944e2875cbe0fa"
|
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
|
||||||
integrity sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==
|
integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/devtools-api" "^6.5.0"
|
"@vue/devtools-api" "^6.5.0"
|
||||||
vue-demi ">=0.14.5"
|
vue-demi ">=0.14.5"
|
||||||
@ -10982,10 +10982,10 @@ typescript@~4.5.5:
|
|||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
|
||||||
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
|
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
|
||||||
|
|
||||||
typescript@~5.1.6:
|
typescript@~5.3.3:
|
||||||
version "5.1.6"
|
version "5.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
|
||||||
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
|
integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
|
||||||
|
|
||||||
unbox-primitive@^1.0.2:
|
unbox-primitive@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@ -11477,10 +11477,10 @@ webpack-bundle-analyzer@^4.4.0:
|
|||||||
sirv "^2.0.3"
|
sirv "^2.0.3"
|
||||||
ws "^7.3.1"
|
ws "^7.3.1"
|
||||||
|
|
||||||
webpack-bundle-tracker@1.8.1:
|
webpack-bundle-tracker@3.0.1:
|
||||||
version "1.8.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-bundle-tracker/-/webpack-bundle-tracker-1.8.1.tgz#d1cdbd62da622abe1243f099657af86a6ca2656d"
|
resolved "https://registry.yarnpkg.com/webpack-bundle-tracker/-/webpack-bundle-tracker-3.0.1.tgz#dd4809cd22b231b296dfef5634353d875b1502f2"
|
||||||
integrity sha512-X1qtXG4ue92gjWQO2VhLVq8HDEf9GzUWE0OQyAQObVEZsFB1SUtSQ7o47agF5WZIaHfJUTKak4jEErU0gzoPcQ==
|
integrity sha512-q0/19A1gpP74oBC3rgveDBh09D1RGpLvREEOmen9eonTbcuhNAyLkfmfoQeOm+j4k26f+Q2mJSzEXoPu42gBFg==
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.assign "^4.2.0"
|
lodash.assign "^4.2.0"
|
||||||
lodash.defaults "^4.2.0"
|
lodash.defaults "^4.2.0"
|
||||||
@ -11488,7 +11488,6 @@ webpack-bundle-tracker@1.8.1:
|
|||||||
lodash.frompairs "^4.0.1"
|
lodash.frompairs "^4.0.1"
|
||||||
lodash.get "^4.4.2"
|
lodash.get "^4.4.2"
|
||||||
lodash.topairs "^4.3.0"
|
lodash.topairs "^4.3.0"
|
||||||
strip-ansi "^6.0.0"
|
|
||||||
|
|
||||||
webpack-chain@^6.5.1:
|
webpack-chain@^6.5.1:
|
||||||
version "6.5.1"
|
version "6.5.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user