mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-23 18:29:23 -05:00
tweaks and changes
This commit is contained in:
@@ -1689,6 +1689,7 @@ class SourceImportDuplicateSerializer(serializers.Serializer):
|
||||
|
||||
class RecipeFromSourceResponseSerializer(serializers.Serializer):
|
||||
recipe = SourceImportRecipeSerializer(default=None)
|
||||
recipe_id = serializers.IntegerField(default=None)
|
||||
images = serializers.ListField(child=serializers.CharField(), default=[], allow_null=False)
|
||||
error = serializers.BooleanField(default=False)
|
||||
msg = serializers.CharField(max_length=1024, default='')
|
||||
|
||||
@@ -1713,27 +1713,35 @@ class RecipeUrlImportView(APIView):
|
||||
elif url and not data:
|
||||
if re.match('^(https?://)?(www\\.youtube\\.com|youtu\\.be)/.+$', url):
|
||||
if validate_import_url(url):
|
||||
# TODO new serializer
|
||||
return Response({'recipe_json': get_from_youtube_scraper(url, request), 'recipe_images': []}, status=status.HTTP_200_OK)
|
||||
if re.match('^(.)*/recipe/[0-9]+/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$', url):
|
||||
recipe_json = requests.get(
|
||||
url.replace('/recipe/', '/api/recipe/').replace(re.split('/recipe/[0-9]+', url)[1],
|
||||
'') + '?share='
|
||||
+ re.split('/recipe/[0-9]+', url)[1].replace('/', '')).json()
|
||||
response['recipe'] = get_from_youtube_scraper(url, request)
|
||||
if url and url.strip() != '':
|
||||
response['duplicates'] = Recipe.objects.filter(space=request.space, source_url=url.strip()).values('id', 'name').all()
|
||||
return Response(RecipeFromSourceResponseSerializer(context={'request': request}).to_representation(response), status=status.HTTP_200_OK)
|
||||
|
||||
tandoor_url = None
|
||||
if re.match('^(.)*/recipe/[0-9]+/\?share=[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$', url):
|
||||
tandoor_url = url.replace('/recipe/', '/api/recipe/')
|
||||
elif re.match('^(.)*/view/recipe/[0-9]+/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$', url):
|
||||
tandoor_url = (url.replace('/view/recipe/', '/api/recipe/').replace(re.split('/recipe/[0-9]+', url)[1], '') + '?share=' +
|
||||
re.split('/recipe/[0-9]+', url)[1].replace('/', ''))
|
||||
if tandoor_url and validate_import_url(tandoor_url):
|
||||
recipe_json = requests.get(tandoor_url).json()
|
||||
recipe_json = clean_dict(recipe_json, 'id')
|
||||
serialized_recipe = RecipeExportSerializer(data=recipe_json, context={'request': request})
|
||||
if serialized_recipe.is_valid():
|
||||
recipe = serialized_recipe.save()
|
||||
if validate_import_url(recipe_json['image']):
|
||||
if '?' in recipe_json['image']:
|
||||
filetype = pathlib.Path(recipe_json['image'].split('?')[0]).suffix
|
||||
else:
|
||||
filetype = pathlib.Path(recipe_json["image"]).suffix
|
||||
recipe.image = File(handle_image(request,
|
||||
File(
|
||||
io.BytesIO(requests.get(recipe_json['image']).content),
|
||||
name='image'),
|
||||
filetype=pathlib.Path(recipe_json['image']).suffix),
|
||||
name=f'{uuid.uuid4()}_{recipe.pk}{pathlib.Path(recipe_json["image"]).suffix}')
|
||||
File( io.BytesIO(requests.get(recipe_json['image']).content), name='image'),
|
||||
filetype=filetype),
|
||||
name=f'{uuid.uuid4()}_{recipe.pk}.{filetype}')
|
||||
recipe.save()
|
||||
# TODO new serializer
|
||||
return Response({'link': request.build_absolute_uri('recipe/' + recipe.pk)}, status=status.HTTP_201_CREATED)
|
||||
response['recipe_id'] = recipe.pk
|
||||
return Response(RecipeFromSourceResponseSerializer(context={'request': request}).to_representation(response), status=status.HTTP_200_OK)
|
||||
else:
|
||||
try:
|
||||
if validate_import_url(url):
|
||||
|
||||
@@ -7,7 +7,7 @@ from urllib.request import urlretrieve
|
||||
os.chdir('vue3/src/openapi')
|
||||
|
||||
# generate base API client for all models
|
||||
os.system('openapi-generator-cli generate -g typescript-fetch -i http://127.0.0.1:8000/openapi/')
|
||||
os.system('openapi-generator-cli generate -g typescript-fetch -t templates -i http://127.0.0.1:8000/openapi/')
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<v-app-bar color="tandoor" flat density="comfortable" v-if="!useUserPreferenceStore().isAuthenticated">
|
||||
|
||||
</v-app-bar>
|
||||
<v-app-bar color="tandoor" flat density="comfortable" v-if="useUserPreferenceStore().isAuthenticated">
|
||||
<v-app-bar :color="useUserPreferenceStore().userSettings.navBgColor" flat density="comfortable" v-if="useUserPreferenceStore().isAuthenticated">
|
||||
<router-link :to="{ name: 'view_home', params: {} }">
|
||||
<v-img src="../../assets/brand_logo.svg" width="140px" class="ms-2"></v-img>
|
||||
<v-img src="../../assets/brand_logo.svg" width="140px" class="ms-2" v-if="useUserPreferenceStore().userSettings.navShowLogo"></v-img>
|
||||
</router-link>
|
||||
<v-spacer></v-spacer>
|
||||
<global-search-dialog></global-search-dialog>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<slot name="activator">
|
||||
<v-btn @click="dialog = true" variant="plain" density="default" :icon="mobile">
|
||||
<v-btn @click="dialog = true" variant="plain" icon="fa-solid fa-search" class="mr-1 fa-fw" v-if="mobile"></v-btn>
|
||||
<v-btn @click="dialog = true" variant="plain" v-else>
|
||||
<v-icon icon="fa-solid fa-search" class="mr-1 fa-fw"></v-icon>
|
||||
<span class="d-none d-sm-block">{{ $t('Search') }}</span>
|
||||
<v-chip size="x-small" variant="tonal" class="d-none d-md-flex ml-1" label>{{ $t('Ctrl+K') }}</v-chip>
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
<v-label>{{$t('Nav_Color')}}</v-label>
|
||||
<v-color-picker v-model="useUserPreferenceStore().userSettings.navBgColor" mode="hex" :modes="['hex']" show-swatches :swatches="[['#ddbf86'],['#b98766'],['#b55e4f'],['#82aa8b'],['#385f84']]"></v-color-picker>
|
||||
|
||||
<v-select :label="$t('Theme')" class="mt-4" v-model="useUserPreferenceStore().userSettings.theme" :items="[{title: 'Tandoor', value: 'TANDOOR'}, {title: 'Tandoor Dark', value: 'TANDOOR_DARK'}, ]">
|
||||
</v-select>
|
||||
|
||||
<v-checkbox :label="$t('Show_Logo')" :hint="$t('Show_Logo_Help')" persistent-hint v-model="useUserPreferenceStore().userSettings.navShowLogo"></v-checkbox>
|
||||
<v-checkbox :label="$t('Sticky_Nav')" :hint="$t('Sticky_Nav_Help')" persistent-hint v-model="useUserPreferenceStore().userSettings.navSticky"></v-checkbox>
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ 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
|
||||
@@ -35,16 +33,6 @@ 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
|
||||
@@ -91,13 +79,6 @@ 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
|
||||
@@ -157,6 +138,7 @@ 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
@@ -13,12 +13,12 @@
|
||||
*/
|
||||
|
||||
import { mapValues } from '../runtime';
|
||||
import type { AutomationTypeEnum } from './AutomationTypeEnum';
|
||||
import type { TypeEnum } from './TypeEnum';
|
||||
import {
|
||||
AutomationTypeEnumFromJSON,
|
||||
AutomationTypeEnumFromJSONTyped,
|
||||
AutomationTypeEnumToJSON,
|
||||
} from './AutomationTypeEnum';
|
||||
TypeEnumFromJSON,
|
||||
TypeEnumFromJSONTyped,
|
||||
TypeEnumToJSON,
|
||||
} from './TypeEnum';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,10 +34,10 @@ export interface Automation {
|
||||
id?: number;
|
||||
/**
|
||||
*
|
||||
* @type {AutomationTypeEnum}
|
||||
* @type {TypeEnum}
|
||||
* @memberof Automation
|
||||
*/
|
||||
type: AutomationTypeEnum;
|
||||
type: TypeEnum;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
@@ -108,7 +108,7 @@ export function AutomationFromJSONTyped(json: any, ignoreDiscriminator: boolean)
|
||||
return {
|
||||
|
||||
'id': json['id'] == null ? undefined : json['id'],
|
||||
'type': AutomationTypeEnumFromJSON(json['type']),
|
||||
'type': TypeEnumFromJSON(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': AutomationTypeEnumToJSON(value['type']),
|
||||
'type': TypeEnumToJSON(value['type']),
|
||||
'name': value['name'],
|
||||
'description': value['description'],
|
||||
'param_1': value['param1'],
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
*/
|
||||
|
||||
import { mapValues } from '../runtime';
|
||||
import type { AutomationTypeEnum } from './AutomationTypeEnum';
|
||||
import type { TypeEnum } from './TypeEnum';
|
||||
import {
|
||||
AutomationTypeEnumFromJSON,
|
||||
AutomationTypeEnumFromJSONTyped,
|
||||
AutomationTypeEnumToJSON,
|
||||
} from './AutomationTypeEnum';
|
||||
TypeEnumFromJSON,
|
||||
TypeEnumFromJSONTyped,
|
||||
TypeEnumToJSON,
|
||||
} from './TypeEnum';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,10 +34,10 @@ export interface PatchedAutomation {
|
||||
id?: number;
|
||||
/**
|
||||
*
|
||||
* @type {AutomationTypeEnum}
|
||||
* @type {TypeEnum}
|
||||
* @memberof PatchedAutomation
|
||||
*/
|
||||
type?: AutomationTypeEnum;
|
||||
type?: TypeEnum;
|
||||
/**
|
||||
*
|
||||
* @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 : AutomationTypeEnumFromJSON(json['type']),
|
||||
'type': json['type'] == null ? undefined : TypeEnumFromJSON(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': AutomationTypeEnumToJSON(value['type']),
|
||||
'type': TypeEnumToJSON(value['type']),
|
||||
'name': value['name'],
|
||||
'description': value['description'],
|
||||
'param_1': value['param1'],
|
||||
|
||||
@@ -38,6 +38,12 @@ export interface RecipeFromSourceResponse {
|
||||
* @memberof RecipeFromSourceResponse
|
||||
*/
|
||||
recipe?: SourceImportRecipe;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof RecipeFromSourceResponse
|
||||
*/
|
||||
recipeId?: number;
|
||||
/**
|
||||
*
|
||||
* @type {Array<string>}
|
||||
@@ -82,6 +88,7 @@ export function RecipeFromSourceResponseFromJSONTyped(json: any, ignoreDiscrimin
|
||||
return {
|
||||
|
||||
'recipe': json['recipe'] == null ? undefined : SourceImportRecipeFromJSON(json['recipe']),
|
||||
'recipeId': json['recipe_id'] == null ? undefined : json['recipe_id'],
|
||||
'images': json['images'] == null ? undefined : json['images'],
|
||||
'error': json['error'] == null ? undefined : json['error'],
|
||||
'msg': json['msg'] == null ? undefined : json['msg'],
|
||||
@@ -96,6 +103,7 @@ export function RecipeFromSourceResponseToJSON(value?: RecipeFromSourceResponse
|
||||
return {
|
||||
|
||||
'recipe': SourceImportRecipeToJSON(value['recipe']),
|
||||
'recipe_id': value['recipeId'],
|
||||
'images': value['images'],
|
||||
'error': value['error'],
|
||||
'msg': value['msg'],
|
||||
|
||||
@@ -44,7 +44,7 @@ export type TypeEnum = typeof TypeEnum[keyof typeof TypeEnum];
|
||||
export function instanceOfTypeEnum(value: any): boolean {
|
||||
for (const key in TypeEnum) {
|
||||
if (Object.prototype.hasOwnProperty.call(TypeEnum, key)) {
|
||||
if (TypeEnum[key as keyof typeof TypeEnum] === value) {
|
||||
if (TypeEnum[key] === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,3 @@ export function TypeEnumToJSON(value?: TypeEnum | null): any {
|
||||
return value as any;
|
||||
}
|
||||
|
||||
export function TypeEnumToJSONTyped(value: any, ignoreDiscriminator: boolean): TypeEnum {
|
||||
return value as TypeEnum;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ 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';
|
||||
@@ -32,16 +30,6 @@ 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';
|
||||
@@ -88,13 +76,6 @@ 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';
|
||||
@@ -154,6 +135,7 @@ export * from './SupermarketCategoryRelation';
|
||||
export * from './Sync';
|
||||
export * from './SyncLog';
|
||||
export * from './ThemeEnum';
|
||||
export * from './TypeEnum';
|
||||
export * from './Unit';
|
||||
export * from './UnitConversion';
|
||||
export * from './User';
|
||||
|
||||
@@ -115,19 +115,30 @@
|
||||
<!-- ------------ -->
|
||||
|
||||
<v-stepper-window-item value="url">
|
||||
<v-text-field :label="$t('Website') + ' (https://...)'" v-model="importUrl" v-if="importType == 'url'" :loading="loading"></v-text-field>
|
||||
<v-text-field :label="$t('Website') + ' (https://...)'" v-model="importUrl" v-if="importType == 'url'" :loading="loading" autofocus
|
||||
@keydown.enter="loadRecipeFromUrl({url: importUrl})"></v-text-field>
|
||||
|
||||
<v-file-input v-model="image" :label="$t('Image')" v-if="importType == 'ai'" :loading="loading"></v-file-input>
|
||||
|
||||
<v-textarea v-model="sourceImportText" label="JSON/HTML" :loading="loading" v-if="importType == 'source'" :hint="$t('SourceImportHelp')" persistent-hint></v-textarea>
|
||||
<v-textarea v-model="sourceImportText" label="JSON/HTML" :loading="loading" v-if="importType == 'source'" :hint="$t('SourceImportHelp')"
|
||||
persistent-hint autofocus @keydown.enter="loadRecipeFromUrl({data: sourceImportText})"></v-textarea>
|
||||
|
||||
<v-alert v-if="importResponse.error" :title="$t('Error')" :text="importResponse.msg" color="warning">
|
||||
|
||||
</v-alert>
|
||||
|
||||
<v-stepper-actions>
|
||||
<template #prev>
|
||||
<v-btn @click="stepper = 'type'">{{ $t('Back') }}</v-btn>
|
||||
</template>
|
||||
<template #next>
|
||||
<v-btn @click="loadRecipeFromUrl({url: importUrl})" v-if="importType == 'url'" :disabled="importUrl == ''" :loading="loading">{{ $t('Load') }}</v-btn>
|
||||
<v-btn @click="loadRecipeFromUrl({data: sourceImportText})" v-if="importType == 'source'" :disabled="sourceImportText == ''" :loading="loading">{{ $t('Load') }}</v-btn>
|
||||
<v-btn @click="loadRecipeFromUrl({url: importUrl})" v-if="importType == 'url'" :disabled="importUrl == ''" :loading="loading">{{
|
||||
$t('Load')
|
||||
}}
|
||||
</v-btn>
|
||||
<v-btn @click="loadRecipeFromUrl({data: sourceImportText})" v-if="importType == 'source'" :disabled="sourceImportText == ''"
|
||||
:loading="loading">{{ $t('Load') }}
|
||||
</v-btn>
|
||||
<v-btn @click="uploadAndConvertImage()" v-if="importType == 'ai'" :disabled="image == null" :loading="loading">{{ $t('Load') }}</v-btn>
|
||||
</template>
|
||||
</v-stepper-actions>
|
||||
@@ -387,13 +398,15 @@
|
||||
<!-- Bookmarklet -->
|
||||
<!-- ------------ -->
|
||||
<v-stepper-window-item value="bookmarklet">
|
||||
{{$t('BookmarkletImportSubtitle')}}
|
||||
{{ $t('BookmarkletImportSubtitle') }}
|
||||
|
||||
<ol>
|
||||
<li>1. {{$t('BookmarkletHelp1')}}</li>
|
||||
<li> <v-btn :href="bookmarkletContent" color="primary">{{$t('ImportIntoTandoor')}}</v-btn></li>
|
||||
<li>2. {{$t('BookmarkletHelp2')}}</li>
|
||||
<li>3. {{$t('BookmarkletHelp3')}}</li>
|
||||
<li>1. {{ $t('BookmarkletHelp1') }}</li>
|
||||
<li>
|
||||
<v-btn :href="bookmarkletContent" color="primary">{{ $t('ImportIntoTandoor') }}</v-btn>
|
||||
</li>
|
||||
<li>2. {{ $t('BookmarkletHelp2') }}</li>
|
||||
<li>3. {{ $t('BookmarkletHelp3') }}</li>
|
||||
</ol>
|
||||
|
||||
<v-stepper-actions>
|
||||
@@ -499,7 +512,14 @@ onMounted(() => {
|
||||
function loadRecipeFromUrl(recipeFromSourceRequest: RecipeFromSource) {
|
||||
let api = new ApiApi()
|
||||
loading.value = true
|
||||
importResponse.value = {} as RecipeFromSourceResponse
|
||||
|
||||
api.apiRecipeFromSourceCreate({recipeFromSource: recipeFromSourceRequest}).then(r => {
|
||||
if (r.recipeId != null) {
|
||||
router.push({name: 'RecipeViewPage', params: {id: r.recipeId}})
|
||||
return
|
||||
}
|
||||
|
||||
importResponse.value = r
|
||||
|
||||
if (importResponse.value.duplicates && importResponse.value.duplicates.length > 0) {
|
||||
@@ -508,7 +528,13 @@ function loadRecipeFromUrl(recipeFromSourceRequest: RecipeFromSource) {
|
||||
stepper.value = 'image_chooser'
|
||||
}
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
|
||||
err.response.json().then(r => {
|
||||
if (r.error) {
|
||||
importResponse.value = r
|
||||
} else {
|
||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, r)
|
||||
}
|
||||
})
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@@ -5,6 +5,7 @@ import {ApiApi, ServerSettings, Space, Supermarket, UserPreference, UserSpace} f
|
||||
import {ShoppingGroupingOptions} from "@/types/Shopping";
|
||||
import {computed, ComputedRef, ref} from "vue";
|
||||
import {DeviceSettings} from "@/types/settings";
|
||||
import {useTheme} from "vuetify";
|
||||
|
||||
const DEVICE_SETTINGS_KEY = 'TANDOOR_DEVICE_SETTINGS'
|
||||
const USER_PREFERENCE_KEY = 'TANDOOR_USER_PREFERENCE'
|
||||
@@ -43,6 +44,8 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
*/
|
||||
let isAuthenticated = ref(false)
|
||||
|
||||
let theme = useTheme()
|
||||
|
||||
/**
|
||||
* holds the active user space if there is one or null if not
|
||||
*/
|
||||
@@ -66,6 +69,7 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
if (r.length == 1) {
|
||||
userSettings.value = r[0]
|
||||
isAuthenticated.value = true
|
||||
updateTheme()
|
||||
} else {
|
||||
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, r)
|
||||
}
|
||||
@@ -84,6 +88,7 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
|
||||
api.apiUserPreferencePartialUpdate({user: userSettings.value.user.id!, patchedUserPreference: userSettings.value}).then(r => {
|
||||
userSettings.value = r
|
||||
updateTheme()
|
||||
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
|
||||
}).catch(err => {
|
||||
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
|
||||
@@ -196,12 +201,24 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* applies user settings regarding themes/styling
|
||||
*/
|
||||
function updateTheme() {
|
||||
if (userSettings.value.theme == 'TANDOOR') {
|
||||
theme.global.name.value = 'light'
|
||||
} else if (userSettings.value.theme == 'TANDOOR_DARK') {
|
||||
theme.global.name.value = 'dark'
|
||||
}
|
||||
}
|
||||
|
||||
// always load settings on first initialization of store
|
||||
loadUserSettings()
|
||||
loadServerSettings()
|
||||
loadActiveSpace()
|
||||
loadUserSpaces()
|
||||
loadSpaces()
|
||||
updateTheme()
|
||||
|
||||
return {
|
||||
deviceSettings,
|
||||
@@ -216,7 +233,8 @@ export const useUserPreferenceStore = defineStore('user_preference_store', () =>
|
||||
loadServerSettings,
|
||||
updateUserSettings,
|
||||
switchSpace,
|
||||
resetDeviceSettings
|
||||
resetDeviceSettings,
|
||||
updateTheme,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -179,6 +179,72 @@
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@napi-rs/canvas-android-arm64@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.68.tgz#505e788487776a146a45f1923fc38d01b2d676a2"
|
||||
integrity sha512-h1KcSR4LKLfRfzeBH65xMxbWOGa1OtMFQbCMVlxPCkN1Zr+2gK+70pXO5ktojIYcUrP6KDcOwoc8clho5ccM/w==
|
||||
|
||||
"@napi-rs/canvas-darwin-arm64@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.68.tgz#525e389971ce66c53e27fef1457a4970ed5cc7f2"
|
||||
integrity sha512-/VURlrAD4gDoxW1GT/b0nP3fRz/fhxmHI/xznTq2FTwkQLPOlLkDLCvTmQ7v6LtGKdc2Ed6rvYpRan+JXThInQ==
|
||||
|
||||
"@napi-rs/canvas-darwin-x64@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.68.tgz#97f91b6a6f2b765ee47e69edf68e822cfed649e7"
|
||||
integrity sha512-tEpvGR6vCLTo1Tx9wmDnoOKROpw57wiCWwCpDOuVlj/7rqEJOUYr9ixW4aRJgmeGBrZHgevI0EURys2ER6whmg==
|
||||
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.68.tgz#28566dfe9e3728b31ff08031035bf534f9f2f8d9"
|
||||
integrity sha512-U9xbJsumPOiAYeAFZMlHf62b9dGs2HJ6Q5xt7xTB0uEyPeurwhgYBWGgabdsEidyj38YuzI/c3LGBbSQB3vagw==
|
||||
|
||||
"@napi-rs/canvas-linux-arm64-gnu@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.68.tgz#80cc5356edb0e15f82bf44929f27b91e95be8aae"
|
||||
integrity sha512-KFkn8wEm3mPnWD4l8+OUUkxylSJuN5q9PnJRZJgv15RtCA1bgxIwTkBhI/+xuyVMcHqON9sXq7cDkEJtHm35dg==
|
||||
|
||||
"@napi-rs/canvas-linux-arm64-musl@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.68.tgz#7f0d6dfa7508e37ba9d52867e6c6e1448dec238f"
|
||||
integrity sha512-IQzts91rCdOALXBWQxLZRCEDrfFTGDtNRJMNu+2SKZ1uT8cmPQkPwVk5rycvFpvgAcmiFiOSCp1aRrlfU8KPpQ==
|
||||
|
||||
"@napi-rs/canvas-linux-riscv64-gnu@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.68.tgz#050ea7e7f6cb57bc8b8310235e066a0ffd50d385"
|
||||
integrity sha512-e9AS5UttoIKqXSmBzKZdd3NErSVyOEYzJfNOCGtafGk1//gibTwQXGlSXmAKuErqMp09pyk9aqQRSYzm1AQfBw==
|
||||
|
||||
"@napi-rs/canvas-linux-x64-gnu@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.68.tgz#fa8361125da2a0a914a234a626b0f28b27332b8f"
|
||||
integrity sha512-Pa/I36VE3j57I3Obhrr+J48KGFfkZk2cJN/2NmW/vCgmoF7kCP6aTVq5n+cGdGWLd/cN9CJ9JvNwEoMRDghu0g==
|
||||
|
||||
"@napi-rs/canvas-linux-x64-musl@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.68.tgz#a9eefc4e82189dca64f400c921b0387acf990f6f"
|
||||
integrity sha512-9c6rkc5195wNxuUHJdf4/mmnq433OQey9TNvQ9LspJazvHbfSkTij8wtKjASVQsJyPDva4fkWOeV/OQ7cLw0GQ==
|
||||
|
||||
"@napi-rs/canvas-win32-x64-msvc@0.1.68":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.68.tgz#07e879f1c1759a31724871cc6202aba6a3b580f2"
|
||||
integrity sha512-Fc5Dez23u0FoSATurT6/w1oMytiRnKWEinHivdMvXpge6nG4YvhrASrtqMk8dGJMVQpHr8QJYF45rOrx2YU2Aw==
|
||||
|
||||
"@napi-rs/canvas@^0.1.67":
|
||||
version "0.1.68"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/canvas/-/canvas-0.1.68.tgz#265af2971aafcfeb60dbb591c7dc03c3f6e247f1"
|
||||
integrity sha512-LQESrePLEBLvhuFkXx9jjBXRC2ClYsO5mqQ1m/puth5z9SOuM3N/B3vDuqnC3RJFktDktyK9khGvo7dTkqO9uQ==
|
||||
optionalDependencies:
|
||||
"@napi-rs/canvas-android-arm64" "0.1.68"
|
||||
"@napi-rs/canvas-darwin-arm64" "0.1.68"
|
||||
"@napi-rs/canvas-darwin-x64" "0.1.68"
|
||||
"@napi-rs/canvas-linux-arm-gnueabihf" "0.1.68"
|
||||
"@napi-rs/canvas-linux-arm64-gnu" "0.1.68"
|
||||
"@napi-rs/canvas-linux-arm64-musl" "0.1.68"
|
||||
"@napi-rs/canvas-linux-riscv64-gnu" "0.1.68"
|
||||
"@napi-rs/canvas-linux-x64-gnu" "0.1.68"
|
||||
"@napi-rs/canvas-linux-x64-musl" "0.1.68"
|
||||
"@napi-rs/canvas-win32-x64-msvc" "0.1.68"
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.22.4":
|
||||
version "4.22.4"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
|
||||
@@ -860,6 +926,13 @@ path-browserify@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||
|
||||
pdfjs-dist@^5.1.91:
|
||||
version "5.1.91"
|
||||
resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-5.1.91.tgz#d5d90efacaf17d1c8d12310740eb7070322886d8"
|
||||
integrity sha512-qSIADdagooJB4wWCBnrBJjRvASevmxL0BwafvOuKJG5uTQdYoFBrhrRYnucKNiSc9qS6JIk0hC5y1yktFljXkA==
|
||||
optionalDependencies:
|
||||
"@napi-rs/canvas" "^0.1.67"
|
||||
|
||||
perfect-debounce@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
|
||||
|
||||
Reference in New Issue
Block a user