Bug/misc bug fixes (#400)

* potentiall fix #329

* typo

* auto purge events

* image error

* update import dialog

* fix scheduler interval time

* adjust icon position

* check for property

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden 2021-05-08 21:31:19 -08:00 committed by GitHub
parent 145eb9f1ee
commit a1dd6c941b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 99 additions and 71 deletions

View File

@ -8,7 +8,9 @@
:loading="loading" :loading="loading"
> >
<template v-slot:open="{ open }"> <template v-slot:open="{ open }">
<v-btn @click="open" class="mx-2" small :color="color"> <v-icon left> mdi-plus </v-icon> {{$t('general.custom')}} </v-btn> <v-btn @click="open" class="mx-2" small :color="color">
<v-icon left> mdi-plus </v-icon> {{ $t("general.custom") }}
</v-btn>
</template> </template>
<v-card-text class="mt-6"> <v-card-text class="mt-6">
<v-text-field dense :label="$t('settings.backup.backup-tag')" v-model="tag"></v-text-field> <v-text-field dense :label="$t('settings.backup.backup-tag')" v-model="tag"></v-text-field>

View File

@ -1,7 +1,12 @@
<template> <template>
<div> <div>
<slot name="open" v-bind="{ open }"> </slot> <slot name="open" v-bind="{ open }"> </slot>
<v-dialog v-model="dialog" :width="modalWidth + 'px'" :content-class="top ? 'top-dialog' : undefined"> <v-dialog
v-model="dialog"
:width="modalWidth + 'px'"
:content-class="top ? 'top-dialog' : undefined"
:fullscreen="$vuetify.breakpoint.xsOnly"
>
<v-card height="100%"> <v-card height="100%">
<v-app-bar dark :color="color" class="mt-n1 mb-0"> <v-app-bar dark :color="color" class="mt-n1 mb-0">
<v-icon large left> <v-icon large left>
@ -24,6 +29,7 @@
<v-btn color="error" text @click="deleteEvent" v-if="$listeners.delete"> <v-btn color="error" text @click="deleteEvent" v-if="$listeners.delete">
{{ $t("general.delete") }} {{ $t("general.delete") }}
</v-btn> </v-btn>
<slot name="extra-buttons"> </slot>
<v-btn color="success" type="submit" @click="submitEvent"> <v-btn color="success" type="submit" @click="submitEvent">
{{ submitText }} {{ submitText }}
</v-btn> </v-btn>

View File

@ -1,21 +1,14 @@
<template> <template>
<div class="text-center"> <div class="text-center">
<v-dialog v-model="dialog" width="500" :fullscreen="$vuetify.breakpoint.xsOnly"> <BaseDialog
<v-card> :title="name"
<v-toolbar dark color="primary" v-show="$vuetify.breakpoint.xsOnly"> titleIcon="mdi-database"
<v-btn icon dark @click="dialog = false"> :submit-text="$t('general.import')"
<v-icon>mdi-close</v-icon> :loading="loading"
</v-btn> ref="baseDialog"
<v-toolbar-title></v-toolbar-title> @submit="raiseEvent"
<v-spacer></v-spacer> >
<v-toolbar-items> <v-card-subtitle class="mb-n3 mt-3" v-if="date"> {{ $d(new Date(date), "medium") }} </v-card-subtitle>
<v-btn dark text @click="raiseEvent('import')">
{{ $t("general.import") }}
</v-btn>
</v-toolbar-items>
</v-toolbar>
<v-card-title> {{ name }} </v-card-title>
<v-card-subtitle class="mb-n3" v-if="date"> {{ $d(new Date(date), "medium") }} </v-card-subtitle>
<v-divider></v-divider> <v-divider></v-divider>
<v-card-text> <v-card-text>
@ -31,28 +24,29 @@
</v-card-text> </v-card-text>
<v-divider></v-divider> <v-divider></v-divider>
<template v-slot:extra-buttons>
<v-card-actions> <TheDownloadBtn :download-url="downloadUrl">
<TheDownloadBtn :download-url="downloadUrl" /> <template v-slot:default="{ downloadFile }">
<v-spacer></v-spacer> <v-btn class="mr-1" color="info" @click="downloadFile">
<v-btn color="error" text @click="raiseEvent('delete')"> <v-icon left> mdi-download </v-icon>
{{ $t("general.delete") }} {{ $t("general.download") }}
</v-btn> </v-btn>
<v-btn color="success" outlined @click="raiseEvent('import')" v-show="$vuetify.breakpoint.smAndUp"> </template>
{{ $t("general.import") }} </TheDownloadBtn>
</v-btn> </template>
</v-card-actions> </BaseDialog>
</v-card>
</v-dialog>
</div> </div>
</template> </template>
<script> <script>
const IMPORT_EVENT = "import";
import { api } from "@/api";
import BaseDialog from "./BaseDialog";
import ImportOptions from "@/components/FormHelpers/ImportOptions"; import ImportOptions from "@/components/FormHelpers/ImportOptions";
import TheDownloadBtn from "@/components/UI/Buttons/TheDownloadBtn.vue"; import TheDownloadBtn from "@/components/UI/Buttons/TheDownloadBtn.vue";
import { backupURLs } from "@/api/backup"; import { backupURLs } from "@/api/backup";
export default { export default {
components: { ImportOptions, TheDownloadBtn }, components: { ImportOptions, TheDownloadBtn, BaseDialog },
props: { props: {
name: { name: {
default: "Backup Name", default: "Backup Name",
@ -63,6 +57,7 @@ export default {
}, },
data() { data() {
return { return {
loading: false,
options: { options: {
recipes: true, recipes: true,
settings: true, settings: true,
@ -87,12 +82,13 @@ export default {
}, },
open() { open() {
this.dialog = true; this.dialog = true;
this.$refs.baseDialog.open();
}, },
close() { close() {
this.dialog = false; this.dialog = false;
}, },
raiseEvent(event) { async raiseEvent() {
let eventData = { const eventData = {
name: this.name, name: this.name,
force: this.forceImport, force: this.forceImport,
rebase: this.rebaseImport, rebase: this.rebaseImport,
@ -102,8 +98,18 @@ export default {
users: this.options.users, users: this.options.users,
groups: this.options.groups, groups: this.options.groups,
}; };
this.close(); this.loading = true;
this.$emit(event, eventData); const importData = await this.importBackup(eventData);
this.$emit(IMPORT_EVENT, importData);
this.loading = false;
},
async importBackup(data) {
this.loading = true;
const response = await api.backups.import(data.name, data);
if (response) {
return response.data;
}
}, },
}, },
}; };

View File

@ -12,7 +12,7 @@
<v-list-item-content> <v-list-item-content>
<v-list-item-title> {{ user.fullName }}</v-list-item-title> <v-list-item-title> {{ user.fullName }}</v-list-item-title>
<v-list-item-subtitle> {{ user.admin ? $t('user.admin') : $t('user.user') }}</v-list-item-subtitle> <v-list-item-subtitle> {{ user.admin ? $t("user.admin") : $t("user.user") }}</v-list-item-subtitle>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
</template> </template>
@ -77,6 +77,11 @@ export default {
this.getVersion(); this.getVersion();
this.resetView(); this.resetView();
}, },
watch: {
user() {
this.hideImage = false;
},
},
computed: { computed: {
isMain() { isMain() {

View File

@ -1,6 +1,7 @@
export const initials = { export const initials = {
computed: { computed: {
initials() { initials() {
if (!this.user.fullName) return "00"
const allNames = this.user.fullName.trim().split(" "); const allNames = this.user.fullName.trim().split(" ");
const initials = allNames.reduce( const initials = allNames.reduce(
(acc, curr, index) => { (acc, curr, index) => {

View File

@ -112,13 +112,7 @@ export default {
}, },
async importBackup(data) { async importBackup(data) {
this.loading = true; this.$refs.report.open(data);
const response = await api.backups.import(data.name, data);
if (response) {
const importData = response.data;
this.$refs.report.open(importData);
}
this.loading = false;
}, },
async createBackup() { async createBackup() {

View File

@ -123,19 +123,12 @@ export default {
}, },
showPassword: false, showPassword: false,
loading: false, loading: false,
user: { user: {},
fullName: "",
email: "",
group: "",
admin: false,
id: 0,
},
}; };
}, },
computed: { computed: {
userProfileImage() { userProfileImage() {
this.resetImage();
return `api/users/${this.user.id}/image`; return `api/users/${this.user.id}/image`;
}, },
}, },
@ -144,10 +137,13 @@ export default {
this.refreshProfile(); this.refreshProfile();
}, },
methods: { watch: {
resetImage() { user() {
this.hideImage = false; this.hideImage = false;
}, },
},
methods: {
async refreshProfile() { async refreshProfile() {
this.user = await api.users.self(); this.user = await api.users.self();
}, },

View File

@ -38,7 +38,7 @@ class _Recipes(BaseDocument):
return f"{slug}.{extension}" return f"{slug}.{extension}"
def count_uncategorized(self, session: Session, count=True, override_schema=None) -> int: def count_uncategorized(self, session: Session, count=True, override_schema=None) -> int:
return self._countr_attribute( return self._count_attribute(
session, session,
attribute_name=RecipeModel.recipe_category, attribute_name=RecipeModel.recipe_category,
attr_match=None, attr_match=None,
@ -47,7 +47,7 @@ class _Recipes(BaseDocument):
) )
def count_untagged(self, session: Session, count=True, override_schema=None) -> int: def count_untagged(self, session: Session, count=True, override_schema=None) -> int:
return self._countr_attribute( return self._count_attribute(
session, attribute_name=RecipeModel.tags, attr_match=None, count=count, override_schema=override_schema session, attribute_name=RecipeModel.tags, attr_match=None, count=count, override_schema=override_schema
) )

View File

@ -178,7 +178,7 @@ class BaseDocument:
else: else:
return session.query(self.sql_model).filter_by(**{match_key: match_value}).count() return session.query(self.sql_model).filter_by(**{match_key: match_value}).count()
def _countr_attribute( def _count_attribute(
self, session: Session, attribute_name: str, attr_match: str = None, count=True, override_schema=None self, session: Session, attribute_name: str, attr_match: str = None, count=True, override_schema=None
) -> Union[int, BaseModel]: ) -> Union[int, BaseModel]:
eff_schema = override_schema or self.schema eff_schema = override_schema or self.schema

View File

@ -1,7 +1,10 @@
import datetime
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from mealie.core import root_logger from mealie.core import root_logger
from mealie.db.database import db from mealie.db.database import db
from mealie.db.db_setup import create_session from mealie.db.db_setup import create_session
from mealie.db.models.event import Event
from mealie.schema.user import GroupInDB from mealie.schema.user import GroupInDB
from mealie.services.backups.exports import auto_backup_job from mealie.services.backups.exports import auto_backup_job
from mealie.services.scheduler.global_scheduler import scheduler from mealie.services.scheduler.global_scheduler import scheduler
@ -13,6 +16,21 @@ logger = root_logger.get_logger()
# TODO Fix Scheduler # TODO Fix Scheduler
@scheduler.scheduled_job(trigger="interval", minutes=1440)
def purge_events_database():
"""
Ran daily. Purges all events after 100
"""
logger.info("Purging Events in Database")
expiration_days = 7
limit = datetime.datetime.now() - datetime.timedelta(days=expiration_days)
session = create_session()
session.query(Event).filter(Event.time_stamp <= limit).delete()
session.commit()
session.close()
logger.info("Events Purges")
@scheduler.scheduled_job(trigger="interval", minutes=30) @scheduler.scheduled_job(trigger="interval", minutes=30)
def update_webhook_schedule(): def update_webhook_schedule():
""" """