added recipe export

This commit is contained in:
vabene1111
2025-06-02 21:59:51 +02:00
parent db8d35e332
commit bad5ad1f1f
46 changed files with 2213 additions and 54 deletions

View File

@@ -1704,6 +1704,12 @@ class AiImportSerializer(serializers.Serializer):
text = serializers.CharField(allow_null=True, allow_blank=True)
class ExportRequestSerializer(serializers.Serializer):
type = serializers.CharField()
all = serializers.BooleanField(default=False)
recipes = RecipeFlatSerializer(many=True, default=[])
custom_filter = CustomFilterSerializer(many=False, default=None, allow_null=True)
class ImportOpenDataSerializer(serializers.Serializer):
selected_version = serializers.CharField()
selected_datatypes = serializers.ListField(child=serializers.CharField())
@@ -1717,6 +1723,7 @@ class ImportOpenDataResponseDetailSerializer(serializers.Serializer):
total_untouched = serializers.IntegerField(default=0)
total_errored = serializers.IntegerField(default=0)
class ImportOpenDataResponseSerializer(serializers.Serializer):
food = ImportOpenDataResponseDetailSerializer(required=False)
unit = ImportOpenDataResponseDetailSerializer(required=False)
@@ -1725,6 +1732,7 @@ class ImportOpenDataResponseSerializer(serializers.Serializer):
store = ImportOpenDataResponseDetailSerializer(required=False)
conversion = ImportOpenDataResponseDetailSerializer(required=False)
class ImportOpenDataVersionMetaDataSerializer(serializers.Serializer):
food = serializers.IntegerField()
unit = serializers.IntegerField()
@@ -1733,6 +1741,7 @@ class ImportOpenDataVersionMetaDataSerializer(serializers.Serializer):
store = serializers.IntegerField()
conversion = serializers.IntegerField()
class ImportOpenDataMetaDataSerializer(serializers.Serializer):
versions = serializers.ListField(child=serializers.CharField())
datatypes = serializers.ListField(child=serializers.CharField())

View File

@@ -111,6 +111,7 @@ urlpatterns = [
path('data/batch/import', data.batch_import, name='data_batch_import'),
path('data/sync/wait', data.sync_wait, name='data_sync_wait'),
path('api/import/', api.AppImportView.as_view(), name='view_import'),
path('api/export/', api.AppExportView.as_view(), name='api_export'),
path('data/import/url', data.import_url, name='data_import_url'),
path('api/get_external_file_link/<int:recipe_id>/', api.get_external_file_link, name='api_get_external_file_link'),
path('api/get_recipe_file/<int:recipe_id>/', api.get_recipe_file, name='api_get_recipe_file'),

View File

@@ -62,7 +62,7 @@ from rest_framework.serializers import CharField, IntegerField, UUIDField
from treebeard.exceptions import InvalidMoveToDescendant, InvalidPosition, PathOverflow
from cookbook.connectors.connector_manager import ConnectorManager, ActionType
from cookbook.forms import ImportForm
from cookbook.forms import ImportForm, ImportExportBase
from cookbook.helper import recipe_url_import as helper
from cookbook.helper.HelperFunctions import str2bool, validate_import_url
from cookbook.helper.image_processing import handle_image
@@ -109,7 +109,7 @@ from cookbook.serializer import (AccessTokenSerializer, AutomationSerializer, Au
UnitConversionSerializer, UnitSerializer, UserFileSerializer, UserPreferenceSerializer,
UserSerializer, UserSpaceSerializer, ViewLogSerializer,
LocalizationSerializer, ServerSettingsSerializer, RecipeFromSourceResponseSerializer, ShoppingListEntryBulkCreateSerializer, FdcQuerySerializer,
AiImportSerializer, ImportOpenDataSerializer, ImportOpenDataMetaDataSerializer, ImportOpenDataResponseSerializer
AiImportSerializer, ImportOpenDataSerializer, ImportOpenDataMetaDataSerializer, ImportOpenDataResponseSerializer, ExportRequestSerializer
)
from cookbook.version_info import TANDOOR_VERSION
from cookbook.views.import_export import get_integration
@@ -1952,6 +1952,38 @@ class AppImportView(APIView):
return Response({'error': True, 'msg': form.errors}, status=status.HTTP_400_BAD_REQUEST)
class AppExportView(APIView):
throttle_classes = [RecipeImportThrottle]
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]
@extend_schema(request=ExportRequestSerializer(many=False), responses=ExportLogSerializer(many=False))
def post(self, request, *args, **kwargs):
serializer = ExportRequestSerializer(data=request.data, partial=True)
if serializer.is_valid():
if serializer.validated_data['all']:
recipes = Recipe.objects.filter(space=request.space, internal=True).all()
elif serializer.validated_data['custom_filter']:
search = RecipeSearch(request, filter=serializer.initial_data['custom_filter']['id'])
recipes = search.get_queryset(Recipe.objects.filter(space=request.space, internal=True))
elif len(serializer.validated_data['recipes']) > 0:
recipes = Recipe.objects.filter(space=request.space, internal=True, id__in=[item['id'] for item in serializer.initial_data['recipes']]).all()
integration = get_integration(request, serializer.validated_data['type'])
if serializer.validated_data['type'] == ImportExportBase.PDF and not settings.ENABLE_PDF_EXPORT:
return JsonResponse({'error': _('The PDF Exporter is not enabled on this instance as it is still in an experimental state.')})
el = ExportLog.objects.create(type=serializer.validated_data['type'], created_by=request.user, space=request.space)
t = threading.Thread(target=integration.do_export, args=[recipes, el])
t.setDaemon(True)
t.start()
return Response(ExportLogSerializer(context={'request': request}).to_representation(el), status=status.HTTP_200_OK)
return Response({'error': True, 'msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
class FdcSearchView(APIView):
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]

View File

@@ -29,6 +29,7 @@ const routes = [
{path: 'space-members', component: () => import("@/components/settings/SpaceMemberSettings.vue"), name: 'SpaceMemberSettings'},
{path: 'user-space', component: () => import("@/components/settings/UserSpaceSettings.vue"), name: 'UserSpaceSettings'},
{path: 'open-data-import', component: () => import("@/components/settings/OpenDataImportSettings.vue"), name: 'OpenDataImportSettings'},
{path: 'export', component: () => import("@/components/settings/ExportDataSettings.vue"), name: 'ExportDataSettings'},
{path: 'api', component: () => import("@/components/settings/ApiSettings.vue"), name: 'ApiSettings'},
]
},

View File

@@ -0,0 +1,95 @@
<template>
<p class="text-h6">{{ $t('Export') }}</p>
<v-divider></v-divider>
<v-form class="mt-2">
<v-select :items="exportFormats" :label="$t('Type')" v-model="exportType"></v-select>
<v-checkbox :label="$t('AllRecipes')" v-model="allRecipes" :disabled="selectedRecipes.length > 0 || selectedFilter != null"></v-checkbox>
<ModelSelect model="Recipe" mode="tags" v-model="selectedRecipes" :disabled="allRecipes || selectedFilter != null"></ModelSelect>
<ModelSelect model="CustomFilter" mode="single" v-model="selectedFilter" :disabled="selectedRecipes.length > 0 || allRecipes"></ModelSelect>
<v-btn @click="doExport()" :loading="loading" :disabled="selectedRecipes.length == 0 && selectedFilter == null && !allRecipes">{{ $t('Export') }}</v-btn>
<template v-if="exportLog.id">
<v-divider class="mt-4 mb-4"></v-divider>
<h4>{{ $t('Export') }} #{{ exportLog.id }}</h4>
<p>
{{ $t('Recipes') }}: {{ exportLog.exportedRecipes }}
</p>
<v-btn color="success" :href="useDjangoUrls().getDjangoUrl(`export-file/${exportLog.id!}`)" class="mt-2" :disabled="exportLog.running">{{ $t('Download') }}</v-btn>
<v-textarea :label="$t('Messages')" auto-grow readonly max-rows="20" v-model="exportLog.msg" class="mt-2"></v-textarea>
</template>
</v-form>
</template>
<script setup lang="ts">
import {computed, ref} from "vue";
import {INTEGRATIONS} from "@/utils/integration_utils.ts";
import ModelSelect from "@/components/inputs/ModelSelect.vue";
import {ApiApi, CustomFilter, ExportLog, Recipe} from "@/openapi";
import {useDjangoUrls} from "@/composables/useDjangoUrls.ts";
import {ErrorMessageType, useMessageStore} from "@/stores/MessageStore.ts";
const exportType = ref('DEFAULT')
const allRecipes = ref(false)
const selectedRecipes = ref([] as Recipe[])
const selectedFilter = ref<null|CustomFilter>(null)
const exportLog = ref({} as ExportLog)
const loading = ref(false)
/**
* show export option for all types that have export marked as true in integration list
*/
const exportFormats = computed(() => {
let formats = []
INTEGRATIONS.forEach(integration => {
if (integration.export) {
formats.push({title: integration.name, value: integration.id})
}
})
return formats
})
function doExport() {
let api = new ApiApi()
exportLog.value = {} as ExportLog
loading.value = true
api.apiExportCreate({exportRequest: {all: allRecipes.value, type: exportType.value, recipes: selectedRecipes.value, customFilter: selectedFilter.value}}).then(r => {
exportLog.value = r
recRefreshExportLog()
}).catch(err => {
loading.value = false
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
}).finally(() => {
})
}
function recRefreshExportLog() {
let api = new ApiApi()
api.apiExportLogRetrieve({id: exportLog.value.id!}).then(r => {
exportLog.value = r
if (exportLog.value.running) {
setTimeout(() => recRefreshExportLog(), 1000)
} else {
loading.value = false
}
})
}
</script>
<style scoped>
</style>

View File

@@ -478,6 +478,7 @@
"filter_to_supermarket_desc": "",
"food_inherit_info": "",
"food_recipe_help": "",
"hours": "",
"ignore_shopping_help": "",
"import_duplicates": "",
"import_running": "",
@@ -536,6 +537,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -468,6 +468,7 @@
"filter_to_supermarket": "Филтрирайте до супермаркет",
"filter_to_supermarket_desc": "По подразбиране филтрирайте списъка за пазаруване, за да включва само категории за избран супермаркет.",
"food_recipe_help": "Свързването на рецепта тук ще включва свързаната рецепта във всяка друга рецепта, която използва тази храна",
"hours": "",
"ignore_shopping_help": "Никога не добавяйте храна към списъка за пазаруване (например вода)",
"import_duplicates": "За да се предотврати дублирането, рецептите със същото име като съществуващите се игнорират. Поставете отметка в това квадратче, за да импортирате всичко.",
"import_running": "Импортирането се изпълнява, моля, изчакайте!",
@@ -524,6 +525,7 @@
"search_import_help_text": "Импортирайте рецепта от външен уебсайт или приложение.",
"search_no_recipes": "Не можах да намеря никакви рецепти!",
"search_rank": "Ранг на търсене",
"seconds": "",
"select_file": "Избери файл",
"select_food": "Изберете Храна",
"select_keyword": "Изберете Ключова дума",

View File

@@ -581,6 +581,7 @@
"g": "",
"gallon": "",
"hide_step_ingredients": "",
"hours": "",
"ignore_shopping_help": "",
"imperial_fluid_ounce": "",
"imperial_gallon": "",
@@ -659,6 +660,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -574,6 +574,7 @@
"g": "gram [g] (metrický systém, hmotnost)",
"gallon": "galon [gal] (US, objem)",
"hide_step_ingredients": "Skrýt ingredience u kroku",
"hours": "",
"ignore_shopping_help": "Nikdy nepřidávat potravinu na nákupní seznam (např. voda)",
"imperial_fluid_ounce": "tekutá unce imperiální [imp fl oz] (UK, objem)",
"imperial_gallon": "galon imperiální [imp gal] (UK, objem)",
@@ -652,6 +653,7 @@
"search_import_help_text": "Importovat recept z externí webové stránky nebo aplikace.",
"search_no_recipes": "Nebyly nealezeny žádné recepty!",
"search_rank": "Skóre shody",
"seconds": "",
"select_file": "Vybrat soubor",
"select_food": "Vybrat potravinu",
"select_keyword": "Vybrat štítek",

View File

@@ -553,6 +553,7 @@
"g": "gram [g] (metrisk, vægt)",
"gallon": "gallon [gal] (US, volumen)",
"hide_step_ingredients": "Skjul trinnets ingredienser",
"hours": "",
"ignore_shopping_help": "Aldrig tilføj vare til indkøbslisten (f.eks. vand)",
"imperial_fluid_ounce": "imperial fluid ounce [imp fl oz] (UK, volumen)",
"imperial_gallon": "imperial gal [imp gal] (UK, volumen)",
@@ -630,6 +631,7 @@
"search_import_help_text": "Importer en opskrift fra en ekstern hjemmeside eller applikation.",
"search_no_recipes": "Kunne ikke finde nogen opskrifter!",
"search_rank": "Søg efter rang",
"seconds": "",
"select_file": "Vælg fil",
"select_food": "Vælg mad",
"select_keyword": "Vælg nøgleord",

View File

@@ -586,6 +586,7 @@
"g": "Gramm [g] (metrisch, Gewicht)",
"gallon": "Gallone",
"hide_step_ingredients": "Schritt Zutaten ausblenden",
"hours": "Stunden",
"ignore_shopping_help": "Zutat nie auf Einkaufsliste setzen (z.B. Wasser)",
"imperial_fluid_ounce": "Engl. \"Fluid Ounce\" [imp fl oz] (UK, Volumen)",
"imperial_gallon": "Engl. Gallone [imp gal] (UK, Volumen)",
@@ -665,6 +666,7 @@
"search_import_help_text": "Importiere ein Rezept von einer externen Webseite oder Anwendung.",
"search_no_recipes": "Keine Rezepte gefunden!",
"search_rank": "Such-Rang",
"seconds": "Sekunden",
"select_file": "Datei auswählen",
"select_food": "Zutat auswählen",
"select_keyword": "Stichwort auswählen",

View File

@@ -541,6 +541,7 @@
"food_recipe_help": "Η σύνδεση μιας συνταγής εδώ θα συμπεριλάβει τη συνταγή που συνδέεται σε κάθε άλλη συνταγή που χρησιμοποιεί αυτό το φαγητό",
"g": "γραμμάριο [g] (μετρικό, βάρος)",
"gallon": "γαλόνι [gal] (ΗΠΑ, όγκος)",
"hours": "",
"ignore_shopping_help": "Το φαγητό να μην προστίθεται στη λίστα αγορών (π.χ. νερό)",
"imperial_fluid_ounce": "αυτοκρατορική υγρή ουγγιά [imp fl oz] (Ηνωμένο Βασίλειο, όγκος)",
"imperial_gallon": "αυτοκρατορικό γαλόνι [imp gal] (Ηνωμένο Βασίλειο, όγκος)",
@@ -617,6 +618,7 @@
"search_import_help_text": "Εισαγωγή συνταγής από μια ιστοσελίδα ή εφαρμογή.",
"search_no_recipes": "Δεν βρέθηκαν συνταγές!",
"search_rank": "Σειρά αναζήτησης",
"seconds": "",
"select_file": "Επιλογή αρχείου",
"select_food": "Επιλογή φαγητού",
"select_keyword": "Επιλογή λέξης-κλειδί",

View File

@@ -583,6 +583,7 @@
"g": "gram [g] (metric, weight)",
"gallon": "gallon [gal] (US, volume)",
"hide_step_ingredients": "Hide Step Ingredients",
"hours": "hours",
"ignore_shopping_help": "Never add food to the shopping list (e.g. water)",
"imperial_fluid_ounce": "imperial fluid ounce [imp fl oz] (UK, volume)",
"imperial_gallon": "imperial gal [imp gal] (UK, volume)",
@@ -662,6 +663,7 @@
"search_import_help_text": "Import a recipe from an external website or application.",
"search_no_recipes": "Could not find any recipes!",
"search_rank": "Search Rank",
"seconds": "seconds",
"select_file": "Select File",
"select_food": "Select Food",
"select_keyword": "Select Keyword",

View File

@@ -581,6 +581,7 @@
"g": "gramo [g] (métrico, peso)",
"gallon": "galón [gal] (US, volumen)",
"hide_step_ingredients": "Ocultar Ingredientes por Pasos",
"hours": "",
"ignore_shopping_help": "No añadir nunca alimento a la lista de la compra (ej. agua)",
"imperial_fluid_ounce": "onza líquida imperial [imp fl oz] (Reino Unido, volumen)",
"imperial_gallon": "galón imperial [imp gal] (Reino Unido, volumen)",
@@ -659,6 +660,7 @@
"search_import_help_text": "Importar una receta de un sitio web externo o aplicación.",
"search_no_recipes": "¡No pudo encontrarse ninguna receta!",
"search_rank": "Buscar Rango",
"seconds": "",
"select_file": "Seleccionar Fichero",
"select_food": "Seleccionar Alimento",
"select_keyword": "Seleccionar Palabra Clave",

View File

@@ -348,6 +348,7 @@
"exact": "",
"exclude": "",
"file_upload_disabled": "Tiedoston lähetys ei ole käytössä tilassasi.",
"hours": "",
"import_running": "Tuonti käynnissä, odota!",
"merge_confirmation": "Korvaa <i>{source}</i> esiintymiset <i>{target}:lla</i>",
"merge_selection": "Korvaa kaikki {source} esiintymiset valitulla {type}:llä.",
@@ -364,6 +365,7 @@
"searchFilterObjectsAndHelp": "",
"searchFilterObjectsAndNotHelp": "",
"searchFilterObjectsOrNotHelp": "",
"seconds": "",
"show_only_internal": "Näytä vain sisäiset reseptit",
"show_split_screen": "Jaettu näkymä",
"step_time_minutes": "Askelaika minuutteina",

View File

@@ -579,6 +579,7 @@
"food_recipe_help": "Ajouter un lien vers la recette ici incluera cette recette dans n'importe qu'elle autre recette qui utilise cet ingrédient",
"g": "gramme [g] (métrique, poids)",
"hide_step_ingredients": "Cacher les ingrédients de l'étape",
"hours": "",
"ignore_shopping_help": "Ne jamais ajouter daliment à la liste de courses (ex. : eau)",
"import_duplicates": "Pour éviter les doublons, les recettes de même nom seront ignorées. Cocher la case pour tout importer.",
"import_running": "Importation en cours, veuillez patienter !",
@@ -648,6 +649,7 @@
"search_import_help_text": "Importer une recette depuis un site ou une application externe.",
"search_no_recipes": "Aucune recette trouvée !",
"search_rank": "Rechercher par note",
"seconds": "",
"select_file": "Sélectionner Fichier",
"select_food": "Sélectionner laliment",
"select_keyword": "Sélectionner Mot Clé",

View File

@@ -582,6 +582,7 @@
"g": "גרם (g)",
"gallon": "גלון [gal]",
"hide_step_ingredients": "הסתר חומרי גלם בשלבי המרשם",
"hours": "",
"ignore_shopping_help": "לעולם אל תוסיף מאכלים לרשימת הקניות (לדוגמא, מים)",
"imperial_fluid_ounce": "אונקיה אמפיריאלית",
"imperial_gallon": "גאלון אימפריאלי",
@@ -660,6 +661,7 @@
"search_import_help_text": "ייבא מתכון מאתר חיצוני או אפליקציה.",
"search_no_recipes": "לא נמצאו כל מתכונים!",
"search_rank": "חיפוש דירוג",
"seconds": "",
"select_file": "בחר קובץ",
"select_food": "בחר מאכל",
"select_keyword": "בחר מילת מפתח",

View File

@@ -544,6 +544,7 @@
"food_recipe_help": "Egy recept itt történő linkelése magában foglalja a linkelt receptet bármely más receptben, amely ezt az alapanyagot használja",
"g": "gramm [g] (metrikus, súly)",
"gallon": "gallon [gal] (USA, térfogat)",
"hours": "",
"ignore_shopping_help": "Soha ne adja hozzá az alapanyagot a bevásárlólistához (pl. víz)",
"imperial_fluid_ounce": "imperial folyadékuncia [imp fl oz] (Egyesült Királyság, térfogat)",
"imperial_gallon": "imperial galon [imp gal] (Egyesült Királyság, térfogat)",
@@ -619,6 +620,7 @@
"search_import_help_text": "Recept importálása külső webhelyről vagy alkalmazásból.",
"search_no_recipes": "Nem találtunk semmilyen receptet!",
"search_rank": "Keresési rangsor",
"seconds": "",
"select_file": "Fájl kiválasztása",
"select_food": "Étel kiválasztása",
"select_keyword": "Kulcsszó kiválasztása",

View File

@@ -268,6 +268,7 @@
"exact": "",
"exclude": "",
"file_upload_disabled": "Ջեր տարածությունում ֆայլերի վերբեռնումը միացված չէ։",
"hours": "",
"import_running": "Ներմուծվում է, խնդրում ենք սպասել։",
"min": "",
"on": "",
@@ -278,6 +279,7 @@
"searchFilterObjectsAndHelp": "",
"searchFilterObjectsAndNotHelp": "",
"searchFilterObjectsOrNotHelp": "",
"seconds": "",
"show_only_internal": "Ցույց տալ միայն ներքին բաղադրատոմսերը",
"step_time_minutes": "Քայլի տևողությունը րոպեներով",
"success_creating_resource": "Ռեսուրսը հաջողությամբ ստեղծվել է։",

View File

@@ -503,6 +503,7 @@
"filter_to_supermarket_desc": "",
"food_inherit_info": "Bidang pada makanan yang harus diwarisi secara default.",
"food_recipe_help": "",
"hours": "",
"ignore_shopping_help": "",
"import_duplicates": "",
"import_running": "Impor berjalan, harap tunggu!",
@@ -561,6 +562,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -580,6 +580,7 @@
"g": "",
"gallon": "",
"hide_step_ingredients": "",
"hours": "",
"ignore_shopping_help": "",
"imperial_fluid_ounce": "",
"imperial_gallon": "",
@@ -658,6 +659,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -520,6 +520,7 @@
"filter_to_supermarket_desc": "Per impostazione predefinita, filtra la lista della spesa per includere esclusivamente le categorie del supermercato selezionato.",
"food_inherit_info": "Campi di alimenti che devono essere ereditati per impostazione predefinita.",
"food_recipe_help": "Collegando qui una ricetta, includerà la stessa in ogni altra ricetta che usa questo alimento",
"hours": "",
"ignore_shopping_help": "Non aggiungere gli alimenti alla lista della spesa (es. acqua)",
"import_duplicates": "Per evitare duplicati, le ricette con lo stesso nome di quelle esistenti vengono ignorate. Selezionare questa casella per importare tutto.",
"import_running": "Importazione in corso, attendere prego!",
@@ -579,6 +580,7 @@
"search_import_help_text": "Importa una ricetta da un sito web o da una applicazione.",
"search_no_recipes": "Non sono state trovate ricette!",
"search_rank": "Posizione di ricerca",
"seconds": "",
"select_file": "Seleziona file",
"select_food": "Seleziona alimento",
"select_keyword": "Seleziona parola chiave",

View File

@@ -551,6 +551,7 @@
"g": "",
"gallon": "",
"hide_step_ingredients": "",
"hours": "",
"ignore_shopping_help": "",
"imperial_fluid_ounce": "",
"imperial_gallon": "",
@@ -628,6 +629,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -537,6 +537,7 @@
"filter_to_supermarket_desc": "Som standard, filtrerer handlelisten til å kun inkludere kategorier for den valgte butikken.",
"food_inherit_info": "Felter på matvarer som skal arves som standard.",
"food_recipe_help": "",
"hours": "",
"ignore_shopping_help": "",
"import_duplicates": "",
"import_running": "Importering pågår. Vennligst vent!",
@@ -600,6 +601,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "Søk etter vurdering",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -545,6 +545,7 @@
"food_recipe_help": "Hier een recept koppelen voegt het gekoppelde recept toe in elk ander recept dat dit ingrediënt gebruikt",
"g": "gram [g] (metrisch, gewicht)",
"gallon": "gallon [gal] (VS, volume)",
"hours": "",
"ignore_shopping_help": "Voeg ingrediënt nooit toe aan boodschappenlijstjes (bijv. water)",
"imperial_fluid_ounce": "imperial fluid ounce [imp fl oz] (Verenigd Koninkrijk, volume)",
"imperial_gallon": "imperial gal [imp gal] (Verenigd Koninkrijk, volume)",
@@ -621,6 +622,7 @@
"search_import_help_text": "Importeer een recept van een externe website of applicatie.",
"search_no_recipes": "Er zijn geen recepten gevonden!",
"search_rank": "Zoekrang",
"seconds": "",
"select_file": "Selecteer bestand",
"select_food": "Selecteer ingrediënt",
"select_keyword": "Selecteer etiket",

View File

@@ -584,6 +584,7 @@
"g": "gram [g] (metryczny, waga)",
"gallon": "galon [gal] (USA, objętość)",
"hide_step_ingredients": "Ukryj składniki kroku",
"hours": "",
"ignore_shopping_help": "Nigdy nie dodawaj żywności do listy zakupów (np. wody)",
"imperial_fluid_ounce": "imperialna uncja płynu [imp fl oz] (WB, objętość)",
"imperial_gallon": "imperialny galon [imp gal] (WB, objętość)",
@@ -662,6 +663,7 @@
"search_import_help_text": "Zaimportuj przepis z zewnętrznej strony internetowej lub aplikacji.",
"search_no_recipes": "Nie udało się znaleźć żadnych przepisów!",
"search_rank": "Szukaj w rankingu",
"seconds": "",
"select_file": "Wybierz plik",
"select_food": "Wybierz jedzenie/produkt",
"select_keyword": "Wybierz słowo kluczowe",

View File

@@ -462,6 +462,7 @@
"filter_to_supermarket_desc": "",
"food_inherit_info": "Campos no alimento que devem ser herdados por padrão.",
"food_recipe_help": "",
"hours": "",
"ignore_shopping_help": "",
"import_running": "Importação a decorrer, por favor aguarde!",
"in_shopping": "",
@@ -517,6 +518,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "Selecionar Ficheiro",
"select_food": "Selecionar Comida",
"select_keyword": "Selecionar Palavra Chave",

View File

@@ -557,6 +557,7 @@
"food_recipe_help": "",
"g": "grama [g] (métrico, peso)",
"hide_step_ingredients": "Ocultar Etapas de Ingredientes",
"hours": "",
"ignore_shopping_help": "",
"import_duplicates": "Para evitar duplicatas, as receitas com o mesmo nome das existentes são ignoradas. Marque esta caixa para importar tudo.",
"import_running": "Importação em execução, aguarde!",
@@ -624,6 +625,7 @@
"search_import_help_text": "Importe uma receita de um website externo ou aplicação.",
"search_no_recipes": "Não encontrou nenhuma receita!",
"search_rank": "Rank de Pesquisa",
"seconds": "",
"select_file": "Selecionar Arquivo",
"select_food": "Selecionar Alimento",
"select_keyword": "Selecionar Palavra-Chave",

View File

@@ -522,6 +522,7 @@
"filter_to_supermarket_desc": "În mod implicit, filtrați lista de cumpărături pentru a include numai categoriile pentru supermarketul selectat.",
"food_inherit_info": "Câmpuri pe alimente care ar trebui să fie moștenite în mod implicit.",
"food_recipe_help": "Legarea unei rețete aici va include rețeta legată în orice altă rețetă care utilizează acest aliment",
"hours": "",
"ignore_shopping_help": "Nu adăugați niciodată alimente pe lista de cumpărături (ex. apă)",
"import_duplicates": "Pentru a preveni duplicatele, rețetele cu același nume ca și cele existente sunt ignorate. Bifați această casetă pentru a importa totul.",
"import_running": "Import în desfășurare, așteptați!",
@@ -582,6 +583,7 @@
"search_import_help_text": "Importați o rețetă de pe un site web sau o aplicație externă.",
"search_no_recipes": "Nu a putut găsi nici o rețetă!",
"search_rank": "Rang de căutare",
"seconds": "",
"select_file": "Selectare fișier",
"select_food": "Selectare mâncare",
"select_keyword": "Selectați cuvânt cheie",

View File

@@ -426,6 +426,7 @@
"filter_to_supermarket": "Фильтр для супермаркета",
"food_inherit_info": "Поля для продуктов питания, которые должны наследоваться по умолчанию.",
"food_recipe_help": "Если вы разместите здесь ссылку на рецепт, то он будет включен в любой другой рецепт, в котором используется это блюдо",
"hours": "",
"import_running": "Идет загрузка, пожалуйста ждите!",
"ingredient_list": "Список ингредиентов",
"last_cooked": "Последнее приготовленое",
@@ -466,6 +467,7 @@
"searchFilterObjectsAndNotHelp": "",
"searchFilterObjectsOrNotHelp": "",
"search_rank": "Поисковый рейтинг",
"seconds": "",
"select_file": "Выбрать файл",
"select_food": "Выберите продукты питания",
"select_keyword": "Выбрать ключевое слово",

View File

@@ -413,6 +413,7 @@
"file_upload_disabled": "Nalaganje datoteke ni omogočeno za tvoj prostor.",
"filter_to_supermarket_desc": "Privzeto, razvrsti nakupovalni listek, da vključi samo označene trgovine.",
"food_inherit_info": "Polja za živila, ki so privzeto podedovana.",
"hours": "",
"import_running": "Uvoz poteka, prosim počakaj!",
"in_shopping": "V nakupovalnem listku",
"left_handed": "Način za levičarje",
@@ -447,6 +448,7 @@
"searchFilterObjectsAndHelp": "",
"searchFilterObjectsAndNotHelp": "",
"searchFilterObjectsOrNotHelp": "",
"seconds": "",
"shopping_add_onhand": "Avtomatsko v roki",
"shopping_auto_sync": "Avtomatska sinhronizacija",
"shopping_auto_sync_desc": "Nastavitev na 0 bo onemogoča avtomatsko sinhronizacijo. Pri ogledu nakupovalnega seznama se seznam posodablja vsakih nekaj sekund za sinhronizacijo sprememb, ki jih je morda naredil nekdo drug. Uporabno pri nakupovanju z več ljudmi, vendar bo uporabljalo mobilne podatke.",

View File

@@ -584,6 +584,7 @@
"g": "gram [g] (metriskt, vikt)",
"gallon": "gallon [gal] (US, volym)",
"hide_step_ingredients": "Dölj ingredienser för steget",
"hours": "",
"ignore_shopping_help": "Lägg aldrig till ingrediens på inköpslistan (t.ex. vatten)",
"imperial_fluid_ounce": "imperial flouid ounce [imp fl oz] (UK, volym)",
"imperial_gallon": "imperial gal [imp gal] (UK, volym)",
@@ -662,6 +663,7 @@
"search_import_help_text": "Importera ett recept från en extern webbplats eller applikation.",
"search_no_recipes": "Hittade inga recept!",
"search_rank": "Sök rank",
"seconds": "",
"select_file": "Välj fil",
"select_food": "Välj mat",
"select_keyword": "Välj nyckelord",

View File

@@ -582,6 +582,7 @@
"g": "gram [g] (metrik, ağırlık)",
"gallon": "galon [gal] (ABD, hacim)",
"hide_step_ingredients": "Adımdaki Malzemeleri Gizle",
"hours": "",
"ignore_shopping_help": "Alışveriş listesine asla eklenmeyecek yiyecek (örn. su)",
"imperial_fluid_ounce": "imperial fluid ounce [imp fl oz] (Birleşik Krallık, hacim)",
"imperial_gallon": "imperial gal [imp gal] (Birleşik Krallık, hacim)",
@@ -660,6 +661,7 @@
"search_import_help_text": "Harici bir web sitesinden veya uygulamadan bir tarifi içe aktarın.",
"search_no_recipes": "Herhangi bir tarif bulunamadı!",
"search_rank": "Arama Sıralaması",
"seconds": "",
"select_file": "Dosya Seç",
"select_food": "Yiyecek Seç",
"select_keyword": "Anahtar Kelimeyi Seç",

View File

@@ -486,6 +486,7 @@
"filter_to_supermarket": "",
"filter_to_supermarket_desc": "",
"food_recipe_help": "",
"hours": "",
"ignore_shopping_help": "",
"import_duplicates": "",
"import_running": "Імпортується, будь ласка зачекайте!",
@@ -543,6 +544,7 @@
"search_import_help_text": "",
"search_no_recipes": "",
"search_rank": "",
"seconds": "",
"select_file": "",
"select_food": "",
"select_keyword": "",

View File

@@ -574,6 +574,7 @@
"g": "克【g】公制重量",
"gallon": "加仑【gal】美制体积",
"hide_step_ingredients": "隐藏该步骤的成分",
"hours": "",
"ignore_shopping_help": "请不要将食物添加到购物列表中(例如水)",
"imperial_fluid_ounce": "英制液体盎司【imp fl oz】英制体积",
"imperial_gallon": "英制加仑【imp gal】英制体积",
@@ -652,6 +653,7 @@
"search_import_help_text": "从外部网站或应用程序导入食谱。",
"search_no_recipes": "找不到任何食谱!",
"search_rank": "搜索排行",
"seconds": "",
"select_file": "选择文件",
"select_food": "选择食物",
"select_keyword": "选择关键字",

View File

@@ -240,6 +240,7 @@
"exclude": "",
"file_upload_disabled": "您的空間未啟用檔案上傳功能。",
"food_inherit_info": "食物上應該預設繼承的欄位。",
"hours": "",
"import_running": "正在進行匯入,請稍候!",
"min": "",
"on": "",
@@ -252,6 +253,7 @@
"searchFilterObjectsAndHelp": "",
"searchFilterObjectsAndNotHelp": "",
"searchFilterObjectsOrNotHelp": "",
"seconds": "",
"show_only_internal": "僅顯示內部食譜",
"show_split_screen": "分割視圖",
"step_time_minutes": "步驟時間(以分鐘為單位)",

View File

@@ -6,6 +6,8 @@ models/AccessToken.ts
models/AuthToken.ts
models/AutoMealPlan.ts
models/Automation.ts
models/AutomationTypeEnum.ts
models/BaseUnitEnum.ts
models/BookmarkletImport.ts
models/BookmarkletImportList.ts
models/ConnectorConfigConfig.ts
@@ -14,6 +16,7 @@ models/CustomFilter.ts
models/DefaultPageEnum.ts
models/DeleteEnum.ts
models/ExportLog.ts
models/ExportRequest.ts
models/FdcQuery.ts
models/FdcQueryFoods.ts
models/Food.ts
@@ -37,6 +40,16 @@ models/MealPlan.ts
models/MealType.ts
models/MethodEnum.ts
models/NutritionInformation.ts
models/OpenDataCategory.ts
models/OpenDataConversion.ts
models/OpenDataFood.ts
models/OpenDataFoodProperty.ts
models/OpenDataProperty.ts
models/OpenDataStore.ts
models/OpenDataStoreCategory.ts
models/OpenDataUnit.ts
models/OpenDataUnitTypeEnum.ts
models/OpenDataVersion.ts
models/PaginatedAutomationList.ts
models/PaginatedBookmarkletImportListList.ts
models/PaginatedCookLogList.ts
@@ -83,6 +96,13 @@ models/PatchedInviteLink.ts
models/PatchedKeyword.ts
models/PatchedMealPlan.ts
models/PatchedMealType.ts
models/PatchedOpenDataCategory.ts
models/PatchedOpenDataConversion.ts
models/PatchedOpenDataFood.ts
models/PatchedOpenDataProperty.ts
models/PatchedOpenDataStore.ts
models/PatchedOpenDataUnit.ts
models/PatchedOpenDataVersion.ts
models/PatchedProperty.ts
models/PatchedPropertyType.ts
models/PatchedRecipe.ts
@@ -142,7 +162,6 @@ models/SupermarketCategoryRelation.ts
models/Sync.ts
models/SyncLog.ts
models/ThemeEnum.ts
models/TypeEnum.ts
models/Unit.ts
models/UnitConversion.ts
models/User.ts

File diff suppressed because it is too large Load Diff

View File

@@ -13,12 +13,12 @@
*/
import { mapValues } from '../runtime';
import type { TypeEnum } from './TypeEnum';
import type { AutomationTypeEnum } from './AutomationTypeEnum';
import {
TypeEnumFromJSON,
TypeEnumFromJSONTyped,
TypeEnumToJSON,
} from './TypeEnum';
AutomationTypeEnumFromJSON,
AutomationTypeEnumFromJSONTyped,
AutomationTypeEnumToJSON,
} from './AutomationTypeEnum';
/**
*
@@ -34,10 +34,10 @@ export interface Automation {
id?: number;
/**
*
* @type {TypeEnum}
* @type {AutomationTypeEnum}
* @memberof Automation
*/
type: TypeEnum;
type: AutomationTypeEnum;
/**
*
* @type {string}
@@ -108,7 +108,7 @@ export function AutomationFromJSONTyped(json: any, ignoreDiscriminator: boolean)
return {
'id': json['id'] == null ? undefined : json['id'],
'type': TypeEnumFromJSON(json['type']),
'type': AutomationTypeEnumFromJSON(json['type']),
'name': json['name'] == null ? undefined : json['name'],
'description': json['description'] == null ? undefined : json['description'],
'param1': json['param_1'] == null ? undefined : json['param_1'],
@@ -127,7 +127,7 @@ export function AutomationToJSON(value?: Omit<Automation, 'createdBy'> | null):
return {
'id': value['id'],
'type': TypeEnumToJSON(value['type']),
'type': AutomationTypeEnumToJSON(value['type']),
'name': value['name'],
'description': value['description'],
'param_1': value['param1'],

View File

@@ -0,0 +1,98 @@
/* tslint:disable */
/* eslint-disable */
/**
* Tandoor
* Tandoor API Docs
*
* The version of the OpenAPI document: 0.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { mapValues } from '../runtime';
import type { CustomFilter } from './CustomFilter';
import {
CustomFilterFromJSON,
CustomFilterFromJSONTyped,
CustomFilterToJSON,
} from './CustomFilter';
import type { RecipeFlat } from './RecipeFlat';
import {
RecipeFlatFromJSON,
RecipeFlatFromJSONTyped,
RecipeFlatToJSON,
} from './RecipeFlat';
/**
*
* @export
* @interface ExportRequest
*/
export interface ExportRequest {
/**
*
* @type {string}
* @memberof ExportRequest
*/
type: string;
/**
*
* @type {boolean}
* @memberof ExportRequest
*/
all?: boolean;
/**
*
* @type {Array<RecipeFlat>}
* @memberof ExportRequest
*/
recipes?: Array<RecipeFlat>;
/**
*
* @type {CustomFilter}
* @memberof ExportRequest
*/
customFilter?: CustomFilter;
}
/**
* Check if a given object implements the ExportRequest interface.
*/
export function instanceOfExportRequest(value: object): value is ExportRequest {
if (!('type' in value) || value['type'] === undefined) return false;
return true;
}
export function ExportRequestFromJSON(json: any): ExportRequest {
return ExportRequestFromJSONTyped(json, false);
}
export function ExportRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): ExportRequest {
if (json == null) {
return json;
}
return {
'type': json['type'],
'all': json['all'] == null ? undefined : json['all'],
'recipes': json['recipes'] == null ? undefined : ((json['recipes'] as Array<any>).map(RecipeFlatFromJSON)),
'customFilter': json['custom_filter'] == null ? undefined : CustomFilterFromJSON(json['custom_filter']),
};
}
export function ExportRequestToJSON(value?: ExportRequest | null): any {
if (value == null) {
return value;
}
return {
'type': value['type'],
'all': value['all'],
'recipes': value['recipes'] == null ? undefined : ((value['recipes'] as Array<any>).map(RecipeFlatToJSON)),
'custom_filter': CustomFilterToJSON(value['customFilter']),
};
}

View File

@@ -31,49 +31,43 @@ export interface ImportOpenDataResponse {
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
food: ImportOpenDataResponseDetail;
food?: ImportOpenDataResponseDetail;
/**
*
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
unit: ImportOpenDataResponseDetail;
unit?: ImportOpenDataResponseDetail;
/**
*
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
category: ImportOpenDataResponseDetail;
category?: ImportOpenDataResponseDetail;
/**
*
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
property: ImportOpenDataResponseDetail;
property?: ImportOpenDataResponseDetail;
/**
*
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
store: ImportOpenDataResponseDetail;
store?: ImportOpenDataResponseDetail;
/**
*
* @type {ImportOpenDataResponseDetail}
* @memberof ImportOpenDataResponse
*/
conversion: ImportOpenDataResponseDetail;
conversion?: ImportOpenDataResponseDetail;
}
/**
* Check if a given object implements the ImportOpenDataResponse interface.
*/
export function instanceOfImportOpenDataResponse(value: object): value is ImportOpenDataResponse {
if (!('food' in value) || value['food'] === undefined) return false;
if (!('unit' in value) || value['unit'] === undefined) return false;
if (!('category' in value) || value['category'] === undefined) return false;
if (!('property' in value) || value['property'] === undefined) return false;
if (!('store' in value) || value['store'] === undefined) return false;
if (!('conversion' in value) || value['conversion'] === undefined) return false;
return true;
}
@@ -87,12 +81,12 @@ export function ImportOpenDataResponseFromJSONTyped(json: any, ignoreDiscriminat
}
return {
'food': ImportOpenDataResponseDetailFromJSON(json['food']),
'unit': ImportOpenDataResponseDetailFromJSON(json['unit']),
'category': ImportOpenDataResponseDetailFromJSON(json['category']),
'property': ImportOpenDataResponseDetailFromJSON(json['property']),
'store': ImportOpenDataResponseDetailFromJSON(json['store']),
'conversion': ImportOpenDataResponseDetailFromJSON(json['conversion']),
'food': json['food'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['food']),
'unit': json['unit'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['unit']),
'category': json['category'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['category']),
'property': json['property'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['property']),
'store': json['store'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['store']),
'conversion': json['conversion'] == null ? undefined : ImportOpenDataResponseDetailFromJSON(json['conversion']),
};
}

View File

@@ -24,35 +24,31 @@ export interface ImportOpenDataResponseDetail {
* @type {number}
* @memberof ImportOpenDataResponseDetail
*/
totalCreated: number;
totalCreated?: number;
/**
*
* @type {number}
* @memberof ImportOpenDataResponseDetail
*/
totalUpdated: number;
totalUpdated?: number;
/**
*
* @type {number}
* @memberof ImportOpenDataResponseDetail
*/
totalUntouched: number;
totalUntouched?: number;
/**
*
* @type {number}
* @memberof ImportOpenDataResponseDetail
*/
totalErrored: number;
totalErrored?: number;
}
/**
* Check if a given object implements the ImportOpenDataResponseDetail interface.
*/
export function instanceOfImportOpenDataResponseDetail(value: object): value is ImportOpenDataResponseDetail {
if (!('totalCreated' in value) || value['totalCreated'] === undefined) return false;
if (!('totalUpdated' in value) || value['totalUpdated'] === undefined) return false;
if (!('totalUntouched' in value) || value['totalUntouched'] === undefined) return false;
if (!('totalErrored' in value) || value['totalErrored'] === undefined) return false;
return true;
}
@@ -66,10 +62,10 @@ export function ImportOpenDataResponseDetailFromJSONTyped(json: any, ignoreDiscr
}
return {
'totalCreated': json['total_created'],
'totalUpdated': json['total_updated'],
'totalUntouched': json['total_untouched'],
'totalErrored': json['total_errored'],
'totalCreated': json['total_created'] == null ? undefined : json['total_created'],
'totalUpdated': json['total_updated'] == null ? undefined : json['total_updated'],
'totalUntouched': json['total_untouched'] == null ? undefined : json['total_untouched'],
'totalErrored': json['total_errored'] == null ? undefined : json['total_errored'],
};
}

View File

@@ -13,12 +13,12 @@
*/
import { mapValues } from '../runtime';
import type { TypeEnum } from './TypeEnum';
import type { AutomationTypeEnum } from './AutomationTypeEnum';
import {
TypeEnumFromJSON,
TypeEnumFromJSONTyped,
TypeEnumToJSON,
} from './TypeEnum';
AutomationTypeEnumFromJSON,
AutomationTypeEnumFromJSONTyped,
AutomationTypeEnumToJSON,
} from './AutomationTypeEnum';
/**
*
@@ -34,10 +34,10 @@ export interface PatchedAutomation {
id?: number;
/**
*
* @type {TypeEnum}
* @type {AutomationTypeEnum}
* @memberof PatchedAutomation
*/
type?: TypeEnum;
type?: AutomationTypeEnum;
/**
*
* @type {string}
@@ -106,7 +106,7 @@ export function PatchedAutomationFromJSONTyped(json: any, ignoreDiscriminator: b
return {
'id': json['id'] == null ? undefined : json['id'],
'type': json['type'] == null ? undefined : TypeEnumFromJSON(json['type']),
'type': json['type'] == null ? undefined : AutomationTypeEnumFromJSON(json['type']),
'name': json['name'] == null ? undefined : json['name'],
'description': json['description'] == null ? undefined : json['description'],
'param1': json['param_1'] == null ? undefined : json['param_1'],
@@ -125,7 +125,7 @@ export function PatchedAutomationToJSON(value?: Omit<PatchedAutomation, 'created
return {
'id': value['id'],
'type': TypeEnumToJSON(value['type']),
'type': AutomationTypeEnumToJSON(value['type']),
'name': value['name'],
'description': value['description'],
'param_1': value['param1'],

View File

@@ -4,6 +4,8 @@ export * from './AccessToken';
export * from './AuthToken';
export * from './AutoMealPlan';
export * from './Automation';
export * from './AutomationTypeEnum';
export * from './BaseUnitEnum';
export * from './BookmarkletImport';
export * from './BookmarkletImportList';
export * from './ConnectorConfigConfig';
@@ -12,6 +14,7 @@ export * from './CustomFilter';
export * from './DefaultPageEnum';
export * from './DeleteEnum';
export * from './ExportLog';
export * from './ExportRequest';
export * from './FdcQuery';
export * from './FdcQueryFoods';
export * from './Food';
@@ -35,6 +38,16 @@ export * from './MealPlan';
export * from './MealType';
export * from './MethodEnum';
export * from './NutritionInformation';
export * from './OpenDataCategory';
export * from './OpenDataConversion';
export * from './OpenDataFood';
export * from './OpenDataFoodProperty';
export * from './OpenDataProperty';
export * from './OpenDataStore';
export * from './OpenDataStoreCategory';
export * from './OpenDataUnit';
export * from './OpenDataUnitTypeEnum';
export * from './OpenDataVersion';
export * from './PaginatedAutomationList';
export * from './PaginatedBookmarkletImportListList';
export * from './PaginatedCookLogList';
@@ -81,6 +94,13 @@ export * from './PatchedInviteLink';
export * from './PatchedKeyword';
export * from './PatchedMealPlan';
export * from './PatchedMealType';
export * from './PatchedOpenDataCategory';
export * from './PatchedOpenDataConversion';
export * from './PatchedOpenDataFood';
export * from './PatchedOpenDataProperty';
export * from './PatchedOpenDataStore';
export * from './PatchedOpenDataUnit';
export * from './PatchedOpenDataVersion';
export * from './PatchedProperty';
export * from './PatchedPropertyType';
export * from './PatchedRecipe';
@@ -140,7 +160,6 @@ export * from './SupermarketCategoryRelation';
export * from './Sync';
export * from './SyncLog';
export * from './ThemeEnum';
export * from './TypeEnum';
export * from './Unit';
export * from './UnitConversion';
export * from './User';

View File

@@ -17,6 +17,7 @@
<v-list-item :to="{name: 'SpaceSettings'}" prepend-icon="$settings">{{ $t('SpaceSettings') }}</v-list-item>
<v-list-item :to="{name: 'SpaceMemberSettings'}" prepend-icon="fa-solid fa-users">{{ $t('SpaceMembers') }}</v-list-item>
<v-list-item :to="{name: 'OpenDataImportSettings'}" prepend-icon="fa-solid fa-cloud-arrow-down">{{ $t('Open_Data_Import') }}</v-list-item>
<v-list-item :to="{name: 'ExportDataSettings'}" prepend-icon="fa-solid fa-file-export">{{ $t('Export') }}</v-list-item>
<v-divider></v-divider>
<v-list-subheader>Admin</v-list-subheader>
<v-list-item :to="{name: 'ApiSettings'}" prepend-icon="fa-solid fa-code">{{ $t('API') }}</v-list-item>

View File

@@ -20,7 +20,7 @@ export const INTEGRATIONS: Array<Integration> = [
{id: 'MEALIE', name: "Mealie", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#mealie'},
{id: 'MEALMASTER', name: "Mealmaster", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#mealmaster'},
{id: 'MELARECIPES', name: "Melarecipes", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#melarecipes'},
{id: 'NEXTCLOUD', name: "Nextcloud Cookbook", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#nextcloud'},
{id: 'NEXTCLOUD', name: "Nextcloud Cookbook", import: true, export: true, helpUrl: 'https://docs.tandoor.dev/features/import_export/#nextcloud'},
{id: 'OPENEATS', name: "Openeats", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#openeats'},
{id: 'PAPRIKA', name: "Paprika", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#paprika'},
{id: 'PEPPERPLATE', name: "Pepperplate", import: true, export: false, helpUrl: 'https://docs.tandoor.dev/features/import_export/#pepperplate'},