Merge branch 'develop' into feature/custom_filters

This commit is contained in:
vabene1111
2022-02-18 17:25:15 +01:00
committed by GitHub
7 changed files with 44 additions and 24 deletions

View File

@ -29,11 +29,3 @@ body:
attributes: attributes:
label: "Additional context" label: "Additional context"
description: "Add any other context or screenshots about the feature request here." description: "Add any other context or screenshots about the feature request here."
- type: checkboxes
attributes:
label: "Contribute"
description: "Are you willing and able to help develop this feature?"
options:
- label: "Yes"
- label: "Partly"
- label: "No"

View File

@ -108,6 +108,7 @@ class ExtendedRecipeMixin():
''' '''
ExtendedRecipe annotates a queryset with recipe_image and recipe_count values ExtendedRecipe annotates a queryset with recipe_image and recipe_count values
''' '''
@classmethod @classmethod
def annotate_recipe(self, queryset=None, request=None, serializer=None, tree=False): def annotate_recipe(self, queryset=None, request=None, serializer=None, tree=False):
extended = str2bool(request.query_params.get('extended', None)) extended = str2bool(request.query_params.get('extended', None))
@ -182,8 +183,8 @@ class FuzzyFilterMixin(ViewSetMixin, ExtendedRecipeMixin):
class MergeMixin(ViewSetMixin): class MergeMixin(ViewSetMixin):
@ decorators.action(detail=True, url_path='merge/(?P<target>[^/.]+)', methods=['PUT'], ) @decorators.action(detail=True, url_path='merge/(?P<target>[^/.]+)', methods=['PUT'], )
@ decorators.renderer_classes((TemplateHTMLRenderer, JSONRenderer)) @decorators.renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def merge(self, request, pk, target): def merge(self, request, pk, target):
self.description = f"Merge {self.basename} onto target {self.basename} with ID of [int]." self.description = f"Merge {self.basename} onto target {self.basename} with ID of [int]."
@ -279,8 +280,8 @@ class TreeMixin(MergeMixin, FuzzyFilterMixin, ExtendedRecipeMixin):
return self.annotate_recipe(queryset=self.queryset, request=self.request, serializer=self.serializer_class, tree=True) return self.annotate_recipe(queryset=self.queryset, request=self.request, serializer=self.serializer_class, tree=True)
@ decorators.action(detail=True, url_path='move/(?P<parent>[^/.]+)', methods=['PUT'], ) @decorators.action(detail=True, url_path='move/(?P<parent>[^/.]+)', methods=['PUT'], )
@ decorators.renderer_classes((TemplateHTMLRenderer, JSONRenderer)) @decorators.renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def move(self, request, pk, parent): def move(self, request, pk, parent):
self.description = f"Move {self.basename} to be a child of {self.basename} with ID of [int]. Use ID: 0 to move {self.basename} to the root." self.description = f"Move {self.basename} to be a child of {self.basename} with ID of [int]. Use ID: 0 to move {self.basename} to the root."
if self.model.node_order_by: if self.model.node_order_by:
@ -460,7 +461,7 @@ class FoodViewSet(viewsets.ModelViewSet, TreeMixin):
# onhand_status = self.queryset.annotate(onhand_status=Exists(onhand_users_set__in=[shared_users])) # onhand_status = self.queryset.annotate(onhand_status=Exists(onhand_users_set__in=[shared_users]))
return self.queryset.annotate(shopping_status=Exists(shopping_status)).prefetch_related('onhand_users', 'inherit_fields').select_related('recipe', 'supermarket_category') return self.queryset.annotate(shopping_status=Exists(shopping_status)).prefetch_related('onhand_users', 'inherit_fields').select_related('recipe', 'supermarket_category')
@ decorators.action(detail=True, methods=['PUT'], serializer_class=FoodShoppingUpdateSerializer,) @decorators.action(detail=True, methods=['PUT'], serializer_class=FoodShoppingUpdateSerializer, )
# TODO DRF only allows one action in a decorator action without overriding get_operation_id_base() this should be PUT and DELETE probably # TODO DRF only allows one action in a decorator action without overriding get_operation_id_base() this should be PUT and DELETE probably
def shopping(self, request, pk): def shopping(self, request, pk):
if self.request.space.demo: if self.request.space.demo:
@ -538,7 +539,7 @@ class MealPlanViewSet(viewsets.ModelViewSet):
""" """
queryset = MealPlan.objects queryset = MealPlan.objects
serializer_class = MealPlanSerializer serializer_class = MealPlanSerializer
permission_classes = [CustomIsOwner] permission_classes = [CustomIsOwner | CustomIsShared]
def get_queryset(self): def get_queryset(self):
queryset = self.queryset.filter( queryset = self.queryset.filter(

View File

@ -354,7 +354,7 @@ follow these instructions:
If hosting under a sub-path you might want to change the default nginx config (which gets mounted through the named volume from the application container into the nginx container) If hosting under a sub-path you might want to change the default nginx config (which gets mounted through the named volume from the application container into the nginx container)
with the following config. with the following config.
``` ```nginx
location /my_app { # change to subfolder name location /my_app { # change to subfolder name
include /config/nginx/proxy.conf; include /config/nginx/proxy.conf;
proxy_pass https://mywebapp.com/; # change to your host name:port proxy_pass https://mywebapp.com/; # change to your host name:port
@ -371,7 +371,6 @@ location /media/ {
} }
location /static/ { location /static/ {
include /config/nginx/proxy.conf; include /config/nginx/proxy.conf;
alias /staticfiles/; alias /staticfiles/;

View File

@ -12,5 +12,12 @@ server {
location / { location / {
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_pass http://web_recipes:8080; proxy_pass http://web_recipes:8080;
error_page 502 /errors/http502.html;
}
location /errors/ {
alias /etc/nginx/conf.d/errorpages/;
internal;
} }
} }

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Simple HttpErrorPages | MIT License | https://github.com/HttpErrorPages -->
<meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>502 - Webservice currently unavailable</title>
<style type="text/css">/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}/*! Simple HttpErrorPages | MIT X11 License | https://github.com/AndiDittrich/HttpErrorPages */body,html{width:100%;height:100%;background-color:#21232a}body{color:#fff;text-align:center;text-shadow:0 2px 4px rgba(0,0,0,.5);padding:0;min-height:100%;-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,.8);box-shadow:inset 0 0 100px rgba(0,0,0,.8);display:table;font-family:"Open Sans",Arial,sans-serif}h1{font-family:inherit;font-weight:500;line-height:1.1;color:inherit;font-size:36px}h1 small{font-size:68%;font-weight:400;line-height:1;color:#777}a{text-decoration:none;color:#fff;font-size:inherit;border-bottom:dotted 1px #707070}.lead{color:silver;font-size:21px;line-height:1.4}.cover{display:table-cell;vertical-align:middle;padding:0 20px}footer{position:fixed;width:100%;height:40px;left:0;bottom:0;color:#a0a0a0;font-size:14px}</style>
</head>
<body>
<div class="cover"><h1>Tandoor Recipes is not yet available <small>502</small></h1>
<p class="lead">
Services are still trying to start.<br>
Please allow up to 3 minutes after you started the application on your server.<br><br>
If this status persists, check the application or docker logs for further information.<br>
After checking and trying everything mentioned in the <a href="https://docs.tandoor.dev/" target="_blank">docs</a>, you can request help on the project's <a href="https://github.com/TandoorRecipes/recipes/issues/new?assignees=&amp;labels=setup+issue&amp;template=help_request.yml" target="_blank">GitHub</a> page.
</p>
</div>
</body>
</html>

View File

@ -656,8 +656,8 @@ export default {
}, },
warnPageLeave: function (event) { warnPageLeave: function (event) {
if (this.recipe_changed) { if (this.recipe_changed) {
event.returnValue = "" event.returnValue = "this_string_cant_be_empty_because_of_firefox"
return "" return "this_string_cant_be_empty_because_of_firefox"
} }
}, },
loadRecipe: function () { loadRecipe: function () {
@ -672,8 +672,8 @@ export default {
// set default visibility style for each component of the step // set default visibility style for each component of the step
this.recipe.steps.forEach((s) => { this.recipe.steps.forEach((s) => {
this.$set(s, "time_visible", s.time !== 0) this.$set(s, "time_visible", s.time !== 0)
this.$set(s, "ingredients_visible", s.ingredients.length > 0) this.$set(s, "ingredients_visible", s.ingredients.length > 0 || this.recipe.steps.length === 1)
this.$set(s, "instruction_visible", s.instruction !== "") this.$set(s, "instruction_visible", s.instruction !== "" || this.recipe.steps.length === 1)
this.$set(s, "step_recipe_visible", s.step_recipe !== null) this.$set(s, "step_recipe_visible", s.step_recipe !== null)
this.$set(s, "file_visible", s.file !== null) this.$set(s, "file_visible", s.file !== null)
}) })

View File

@ -32,15 +32,16 @@
<div class="row"> <div class="row">
<!-- ingredients table --> <!-- ingredients table -->
<div class="col col-md-4" v-if="step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)"> <div class="col col-md-4"
<table class="table table-sm" > v-if="step.ingredients.length > 0 && (recipe.steps.length > 1 || force_ingredients)">
<table class="table table-sm">
<ingredients-card :steps="[step]" :ingredient_factor="ingredient_factor" <ingredients-card :steps="[step]" :ingredient_factor="ingredient_factor"
@checked-state-changed="$emit('checked-state-changed', $event)"/> @checked-state-changed="$emit('checked-state-changed', $event)"/>
</table> </table>
</div> </div>
<div class="col" <div class="col"
:class="{ 'col-md-8': recipe.steps.length > 1, 'col-md-12': recipe.steps.length <= 1 }"> :class="{ 'col-md-8 col-12': recipe.steps.length > 1, 'col-md-12 col-12': recipe.steps.length <= 1 }">
<!-- step text --> <!-- step text -->
<div class="row"> <div class="row">
<div class="col col-md-12"> <div class="col col-md-12">