From c227040c1b72a367a14d644129287da2e3e5c7d6 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Tue, 10 Jan 2023 20:28:42 +0100 Subject: [PATCH] Reformat and fix lint --- aleksis/core/assets/App.vue | 95 +++++---- aleksis/core/assets/app.js | 45 +++-- .../BroadcastChannelNotification.vue | 2 +- aleksis/core/assets/components/Error404.vue | 22 +- .../assets/components/LegacyBaseTemplate.vue | 6 +- .../core/assets/components/SnackbarItem.vue | 14 +- .../assets/components/group/GroupList.vue | 22 +- .../notifications/NotificationList.vue | 6 +- .../components/person/AdditionalImage.vue | 48 ++--- .../components/person/AvatarClickBox.vue | 36 ++-- .../components/person/AvatarContent.vue | 49 ++--- .../components/person/PersonActions.vue | 86 ++++---- .../assets/components/person/PersonList.vue | 26 +-- .../components/person/PersonOverview.vue | 190 ++++++++---------- .../components/person/personOverview.graphql | 2 +- aleksis/core/assets/mixins/useRegisterSW.js | 65 +++--- aleksis/core/decorators.py | 4 +- aleksis/core/schema/__init__.py | 2 +- aleksis/core/schema/pdf.py | 1 - aleksis/core/schema/person.py | 10 +- aleksis/core/schema/user.py | 2 +- aleksis/core/static/js/main.js | 1 - aleksis/core/vite.config.js | 50 +++-- 23 files changed, 390 insertions(+), 394 deletions(-) diff --git a/aleksis/core/assets/App.vue b/aleksis/core/assets/App.vue index f2aeff3a8..f52d74e0d 100644 --- a/aleksis/core/assets/App.vue +++ b/aleksis/core/assets/App.vue @@ -1,14 +1,15 @@ <template> <v-app v-cloak> - <loading - v-if="$apollo.loading && !systemProperties" - > - </loading> + <loading v-if="$apollo.loading && !systemProperties"> </loading> <div v-else> <v-navigation-drawer app v-model="drawer"> <v-list nav dense shaped> <v-list-item class="logo"> - <a id="logo-container" @click="$router.push({ name: 'dashboard'})" class="brand-logo"> + <a + id="logo-container" + @click="$router.push({ name: 'dashboard' })" + class="brand-logo" + > <brand-logo :site-preferences="systemProperties.sitePreferences" /> @@ -79,13 +80,16 @@ </div> </template> </v-navigation-drawer> - <v-app-bar app :color="$vuetify.theme.dark ? undefined : 'primary white--text'"> + <v-app-bar + app + :color="$vuetify.theme.dark ? undefined : 'primary white--text'" + > <v-app-bar-nav-icon @click="drawer = !drawer" color="white" /> <v-toolbar-title tag="a" class="white--text text-decoration-none" - @click="$router.push({ name: 'dashboard'})" + @click="$router.push({ name: 'dashboard' })" > {{ systemProperties.sitePreferences.generalTitle }} </v-toolbar-title> @@ -99,7 +103,12 @@ ></v-progress-linear> <v-spacer /> - <v-btn icon color="white" v-if="needRefresh && refreshDismissed" @click="refreshDismissed = false"> + <v-btn + icon + color="white" + v-if="needRefresh && refreshDismissed" + @click="refreshDismissed = false" + > <v-icon>mdi-update</v-icon> </v-btn> <div v-if="whoAmI && whoAmI.isAuthenticated" class="d-flex"> @@ -120,25 +129,37 @@ <img v-else-if="whoAmI.person.avatarUrl" :src="whoAmI.person.avatarUrl" - :alt="whoAmI.person.fullName + '(' + $t('person.avatar') + ')'" - :title="whoAmI.person.fullName + '(' + $t('person.avatar') + ')'" + :alt=" + whoAmI.person.fullName + '(' + $t('person.avatar') + ')' + " + :title=" + whoAmI.person.fullName + '(' + $t('person.avatar') + ')' + " /> <v-icon v-else>mdi-person</v-icon> </v-avatar> </template> <v-list> <v-subheader> - {{ $t(whoAmI && whoAmI.isImpersonate ? "person.impersonation.impersonating" : "person.logged_in_as") }} - {{ whoAmI.person.fullName ? whoAmI.person.fullName : whoAmI.username }} + {{ + $t( + whoAmI && whoAmI.isImpersonate + ? "person.impersonation.impersonating" + : "person.logged_in_as" + ) + }} + {{ + whoAmI.person.fullName + ? whoAmI.person.fullName + : whoAmI.username + }} </v-subheader> <v-list-item - v-if="whoAmI && whoAmI.isImpersonate" - :to="{ name: 'impersonate.stop', query: { next: $route.path } }" + v-if="whoAmI && whoAmI.isImpersonate" + :to="{ name: 'impersonate.stop', query: { next: $route.path } }" > <v-list-item-icon> - <v-icon> - mdi-stop - </v-icon> + <v-icon> mdi-stop </v-icon> </v-list-item-icon> <v-list-item-title> {{ $t("person.impersonation.stop") }} @@ -167,7 +188,10 @@ <broadcast-channel-notification channel-name="cache-or-not" /> <broadcast-channel-notification channel-name="offline-fallback" /> - <message-box type="error" v-if="whoAmI && whoAmI.person && whoAmI.person.isDummy"> + <message-box + type="error" + v-if="whoAmI && whoAmI.person && whoAmI.person.isDummy" + > {{ $t("base.person_is_dummy") }} </message-box> <message-box @@ -292,31 +316,21 @@ </v-card> </v-footer> </div> - <snackbar-item - v-if="snackbarItems" - v-for="item in snackbarItems" - :key="item.id" - :snackbar-item="item" - /> - <v-snackbar - v-model="needRefresh" - v-if="!refreshDismissed" - > + <div v-if="snackbarItems"> + <snackbar-item + v-for="item in snackbarItems" + :key="item.id" + :snackbar-item="item" + /> + </div> + <v-snackbar v-model="needRefresh" v-if="!refreshDismissed"> {{ $t("service_worker.new_version_available") }} - <template v-slot:action="{ attrs }"> - <v-btn - color="primary" - text - @click="updateServiceWorker()" - > + <template #action="{ attrs }"> + <v-btn color="primary" text @click="updateServiceWorker()"> {{ $t("service_worker.update") }} </v-btn> - <v-btn - color="primary" - text - @click="refreshDismissed = true" - > + <v-btn color="primary" text @click="refreshDismissed = true"> {{ $t("service_worker.dismiss") }} </v-btn> </template> @@ -477,7 +491,8 @@ export default { newProperties.sitePreferences.themeSecondary; }, whoAmI: function (user) { - this.$vuetify.theme.dark = user.person && user.person.preferences.themeDesignMode === "dark"; + this.$vuetify.theme.dark = + user.person && user.person.preferences.themeDesignMode === "dark"; this.$apollo.queries.permissionResults.refetch(); }, permissionResults: { diff --git a/aleksis/core/assets/app.js b/aleksis/core/assets/app.js index 9277686d6..01c0b672d 100644 --- a/aleksis/core/assets/app.js +++ b/aleksis/core/assets/app.js @@ -12,7 +12,7 @@ import { onError } from "@/apollo-link-error"; import { RetryLink } from "@/apollo-link-retry"; import { persistCache, LocalStorageWrapper } from "@/apollo3-cache-persist"; -import gql from '@/graphql-tag'; +import gql from "@/graphql-tag"; import gqlSnackbarItems from "./snackbarItems.graphql"; @@ -39,7 +39,7 @@ const vuetify = new Vuetify({ checkboxOn: "mdi-checkbox-marked-outline", checkboxIndeterminate: "mdi-minus-box-outline", edit: "mdi-pencil-outline", - preferences: "mdi-cog-outline" + preferences: "mdi-cog-outline", }, }, }); @@ -86,20 +86,22 @@ const cache = new InMemoryCache(); const resolvers = { Mutation: { - checkSnackbarItem: (_, {id}, {cache}) => { - const data = cache.readQuery({query: gqlSnackbarItems}); - const currentItem = data.snackbarItems.find(item => item.id === id); + // eslint-disable-next-line no-unused-vars + checkSnackbarItem: (_, { id }, { cache }) => { + const data = cache.readQuery({ query: gqlSnackbarItems }); + const currentItem = data.snackbarItems.find((item) => item.id === id); currentItem.read = !currentItem.read; - cache.writeQuery({query: gqlSnackbarItems, data}); + cache.writeQuery({ query: gqlSnackbarItems, data }); return currentItem.read; }, - setLoading: (_, {state}, {}) => { + // eslint-disable-next-line + setLoading: (_, { state }, {}) => { return true; - } + }, }, }; -function addErrorSnackbarItem (messageKey) { +function addErrorSnackbarItem(messageKey) { let uuid = crypto.randomUUID(); cache.writeQuery({ query: gqlSnackbarItems, @@ -110,26 +112,27 @@ function addErrorSnackbarItem (messageKey) { id: uuid, messageKey: messageKey, color: "red", - read: false + read: false, }, - ] + ], }, variables: { - id: uuid - } + id: uuid, + }, }); -}; +} const retryLink = new RetryLink(); const errorLink = onError(({ graphQLErrors, networkError }) => { - if (graphQLErrors) addErrorSnackbarItem("graphql.snackbar_error_message") + if (graphQLErrors) addErrorSnackbarItem("graphql.snackbar_error_message"); - if (networkError) addErrorSnackbarItem("network_errors.snackbar_error_message") + if (networkError) + addErrorSnackbarItem("network_errors.snackbar_error_message"); }); const httpLink = new HttpLink({ - uri: window.location.origin + "/graphql/" + uri: window.location.origin + "/graphql/", }); // FIXME: has to be async to guarantee that no entries are cached before the cache is persisted. @@ -195,16 +198,18 @@ const app = new Vue({ i18n, }); +// eslint-disable-next-line no-unused-vars router.beforeEach((to, from, next) => { app.contentLoading = true; next(); -}) +}); +// eslint-disable-next-line no-unused-vars router.afterEach((to, from) => { - Vue.nextTick( () => { + Vue.nextTick(() => { app.contentLoading = false; }); -}) +}); window.app = app; window.router = router; diff --git a/aleksis/core/assets/components/BroadcastChannelNotification.vue b/aleksis/core/assets/components/BroadcastChannelNotification.vue index fe602bc49..1dbad032d 100644 --- a/aleksis/core/assets/components/BroadcastChannelNotification.vue +++ b/aleksis/core/assets/components/BroadcastChannelNotification.vue @@ -10,7 +10,7 @@ export default { props: { channelName: { type: String, - required: true + required: true, }, }, data() { diff --git a/aleksis/core/assets/components/Error404.vue b/aleksis/core/assets/components/Error404.vue index c72480378..79160f5d4 100644 --- a/aleksis/core/assets/components/Error404.vue +++ b/aleksis/core/assets/components/Error404.vue @@ -1,11 +1,13 @@ <template> - <div class="d-flex justify-center align-center flex-column text-center" id="wrapper"> + <div + class="d-flex justify-center align-center flex-column text-center" + id="wrapper" + > <h1 class="text-h2">{{ $t("network_errors.error_404") }}</h1> - <div>{{ $t("network_errors.page_not_found")}}</div> - <v-btn - color="secondary" - :to="{ name: 'dashboard' }" - >{{ $t("network_errors.take_me_back") }}</v-btn> + <div>{{ $t("network_errors.page_not_found") }}</div> + <v-btn color="secondary" :to="{ name: 'dashboard' }">{{ + $t("network_errors.take_me_back") + }}</v-btn> </div> </template> @@ -16,8 +18,8 @@ export default { </script> <style scoped> - #wrapper { - min-height: 70vh; - gap: 1em; - } +#wrapper { + min-height: 70vh; + gap: 1em; +} </style> diff --git a/aleksis/core/assets/components/LegacyBaseTemplate.vue b/aleksis/core/assets/components/LegacyBaseTemplate.vue index 90f60e3a7..be51d148b 100644 --- a/aleksis/core/assets/components/LegacyBaseTemplate.vue +++ b/aleksis/core/assets/components/LegacyBaseTemplate.vue @@ -49,9 +49,9 @@ export default { } // Show loader if iframe starts to change it's content, even if the $route stays the same - this.$refs.contentIFrame.contentWindow.onpagehide = (e) => { + this.$refs.contentIFrame.contentWindow.onpagehide = () => { this.$root.contentLoading = true; - } + }; const title = this.$refs.contentIFrame.contentWindow.document.title; document.title = title; }, @@ -76,6 +76,6 @@ export default { .iframe-fullsize { border: 0; width: calc(100% + 24px); - margin: -12px + margin: -12px; } </style> diff --git a/aleksis/core/assets/components/SnackbarItem.vue b/aleksis/core/assets/components/SnackbarItem.vue index f80fb4cc7..9213e542d 100644 --- a/aleksis/core/assets/components/SnackbarItem.vue +++ b/aleksis/core/assets/components/SnackbarItem.vue @@ -1,14 +1,16 @@ <template> - <v-snackbar v-model="!snackbarItem.read" :color="snackbarItem.color"> + <v-snackbar :value="!snackbarItem.read" :color="snackbarItem.color"> {{ $t(snackbarItem.messageKey) }} - <template v-slot:action="{ attrs }"> - <v-btn icon @click="checkSnackbarItem(snackbarItem.id)" ><v-icon>mdi-close</v-icon></v-btn> + <template #action="{ attrs }"> + <v-btn icon @click="checkSnackbarItem(snackbarItem.id)" + ><v-icon>mdi-close</v-icon> + </v-btn> </template> </v-snackbar> </template> <script> -import gqlCheckSnackbarItem from "../checkSnackbarItem.graphql" +import gqlCheckSnackbarItem from "../checkSnackbarItem.graphql"; export default { name: "SnackbarItem", @@ -22,9 +24,9 @@ export default { checkSnackbarItem(id) { this.$apollo.mutate({ mutation: gqlCheckSnackbarItem, - variables: { id } + variables: { id }, }); }, }, -} +}; </script> diff --git a/aleksis/core/assets/components/group/GroupList.vue b/aleksis/core/assets/components/group/GroupList.vue index b61037853..05e7afb25 100644 --- a/aleksis/core/assets/components/group/GroupList.vue +++ b/aleksis/core/assets/components/group/GroupList.vue @@ -1,11 +1,9 @@ <template> - <v-list - v-if="groups.length" - > + <v-list v-if="groups.length"> <v-list-item - v-for="group in groups" - :key="group.id" - :to="{ name: 'core.group', params: { id: group.id }}" + v-for="group in groups" + :key="group.id" + :to="{ name: 'core.group', params: { id: group.id } }" > <v-list-item-content> <v-list-item-title> @@ -18,7 +16,7 @@ </v-list-item> </v-list> <p v-else> - {{ $t("person.no_persons")}} + {{ $t("person.no_persons") }} </p> </template> @@ -29,11 +27,9 @@ export default { groups: { type: Array, required: true, - } - } -} + }, + }, +}; </script> -<style scoped> - -</style> +<style scoped></style> diff --git a/aleksis/core/assets/components/notifications/NotificationList.vue b/aleksis/core/assets/components/notifications/NotificationList.vue index 5b469f2db..c290cbef2 100644 --- a/aleksis/core/assets/components/notifications/NotificationList.vue +++ b/aleksis/core/assets/components/notifications/NotificationList.vue @@ -22,7 +22,11 @@ > <v-icon color="white" - v-if="data && data.myNotifications.person && data.myNotifications.person.unreadNotificationsCount > 0" + v-if=" + data && + data.myNotifications.person && + data.myNotifications.person.unreadNotificationsCount > 0 + " > mdi-bell-badge-outline </v-icon> diff --git a/aleksis/core/assets/components/person/AdditionalImage.vue b/aleksis/core/assets/components/person/AdditionalImage.vue index a69d3ccda..5ea3479bb 100644 --- a/aleksis/core/assets/components/person/AdditionalImage.vue +++ b/aleksis/core/assets/components/person/AdditionalImage.vue @@ -1,30 +1,25 @@ <template> - <v-dialog - v-model="popup" - max-width="fit-content" - v-if="src" - > - <template v-slot:activator="{ on, attrs }"> - <v-card - v-bind="attrs" - v-on="on" - > + <v-dialog v-model="popup" max-width="fit-content" v-if="src"> + <template #activator="{ on, attrs }"> + <v-card v-bind="attrs" v-on="on"> <v-img - :src="src" - :alt="$t('person.additional_image')" - class="white--text align-end" - gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)" + :src="src" + :alt="$t('person.additional_image')" + class="white--text align-end" + gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)" > - <v-card-title v-text="$t('person.additional_image')"></v-card-title> + <v-card-title>{{ $t("person.additional_image") }}</v-card-title> </v-img> </v-card> </template> - <v-sheet class="d-flex justify-center align-center flex-column text-center transparent"> + <v-sheet + class="d-flex justify-center align-center flex-column text-center transparent" + > <v-img - :src="src" - :alt="$t('person.additional_image')" - width="80vmin" - max-height="80vmin" + :src="src" + :alt="$t('person.additional_image')" + width="80vmin" + max-height="80vmin" /> </v-sheet> </v-dialog> @@ -32,9 +27,7 @@ <v-list> <v-list-item> <v-list-item-icon> - <v-icon> - mdi-image-off-outline - </v-icon> + <v-icon> mdi-image-off-outline </v-icon> </v-list-item-icon> <v-list-item-content> @@ -53,14 +46,13 @@ export default { props: { src: { type: [String, Object], - } + required: true, + }, }, data: () => ({ popup: false, }), -} +}; </script> -<style scoped> - -</style> +<style scoped></style> diff --git a/aleksis/core/assets/components/person/AvatarClickBox.vue b/aleksis/core/assets/components/person/AvatarClickBox.vue index af0b8b980..fc60bd301 100644 --- a/aleksis/core/assets/components/person/AvatarClickBox.vue +++ b/aleksis/core/assets/components/person/AvatarClickBox.vue @@ -1,20 +1,13 @@ <template> - <v-dialog - v-model="overlay" - max-width="fit-content" - max-height="fit-content" - > - <template v-slot:activator="{ on, attrs }"> + <v-dialog v-model="overlay" max-width="fit-content" max-height="fit-content"> + <template #activator="{ on, attrs }"> <v-card class="rounded-circle"> - <v-responsive - :aspect-ratio="1" - v-bind="attrs" - v-on="on"> - <avatar-content :id="id" class="rounded-circle"/> + <v-responsive :aspect-ratio="1" v-bind="attrs" v-on="on"> + <avatar-content :id="id" class="rounded-circle" /> </v-responsive> </v-card> </template> - <AvatarContent :id="id" contain class="inDialog"/> + <avatar-content :id="id" contain class="inDialog" /> </v-dialog> </template> @@ -23,7 +16,7 @@ import AvatarContent from "./AvatarContent.vue"; export default { name: "AvatarClickBox", - components: {AvatarContent}, + components: { AvatarContent }, data: () => ({ overlay: false, }), @@ -31,15 +24,16 @@ export default { id: { type: String, required: false, - } - } -} + default: "", + }, + }, +}; </script> <style scoped> - .inDialog { - /* FIXME: find a way to enlarge image */ - max-height: 80vmin; - width: 80vmin; - } +.inDialog { + /* FIXME: find a way to enlarge image */ + max-height: 80vmin; + width: 80vmin; +} </style> diff --git a/aleksis/core/assets/components/person/AvatarContent.vue b/aleksis/core/assets/components/person/AvatarContent.vue index a4e8e1a5b..5ca894ac8 100644 --- a/aleksis/core/assets/components/person/AvatarContent.vue +++ b/aleksis/core/assets/components/person/AvatarContent.vue @@ -1,40 +1,32 @@ <template> <ApolloQuery - :query="require('./avatarContent.graphql')" - :variables="{id}" - class="fullsize" + v-if="id" + :query="require('./avatarContent.graphql')" + :variables="{ id }" + class="fullsize" > <template #default="{ result: { error, data, loading } }"> <template v-if="loading"> - <v-row - class="fill-height ma-0" - align="center" - justify="center" - > + <v-row class="fill-height ma-0" align="center" justify="center"> <v-progress-circular - indeterminate - color="grey lighten-5" + indeterminate + color="grey lighten-5" ></v-progress-circular> </v-row> </template> <v-img - v-if="data && data.person && data.person.image" - :src="data.person.image" - :alt="$t('person.avatar')" - max-width="100%" - max-height="100%" - :contain="contain" - class="fullsize" + v-if="data && data.person && data.person.image" + :src="data.person.image" + :alt="$t('person.avatar')" + max-width="100%" + max-height="100%" + :contain="contain" + class="fullsize" /> - <v-icon - class="grey lighten-1" - dark - v-else - > - mdi-folder - </v-icon> + <v-icon class="grey lighten-1" dark v-else>mdi-folder</v-icon> </template> </ApolloQuery> + <v-icon class="grey lighten-1" dark v-else>mdi-folder</v-icon> </template> <script> @@ -44,14 +36,15 @@ export default { id: { type: String, required: false, + default: "", }, contain: { type: Boolean, required: false, - default: false - } - } -} + default: false, + }, + }, +}; </script> <style scoped></style> diff --git a/aleksis/core/assets/components/person/PersonActions.vue b/aleksis/core/assets/components/person/PersonActions.vue index 4175dda89..d042cf7cd 100644 --- a/aleksis/core/assets/components/person/PersonActions.vue +++ b/aleksis/core/assets/components/person/PersonActions.vue @@ -1,84 +1,90 @@ <template> - <ApolloQuery - :query="require('./personActions.graphql')" - :variables="{id}" - > + <ApolloQuery :query="require('./personActions.graphql')" :variables="{ id }"> <template #default="{ result: { error, data, loading } }"> <div - class="d-flex gap justify-md-end flex-column-reverse flex-md-row align-end align-md-center" + class="d-flex gap justify-md-end flex-column-reverse flex-md-row align-end align-md-center" > - <v-skeleton-loader - v-if="loading" - type="actions" - /> - <template - v-else-if="data && data.person && data.person.id" - > + <v-skeleton-loader v-if="loading" type="actions" /> + <template v-else-if="data && data.person && data.person.id"> <v-btn - v-if="data.person.canEditPerson" - color="primary" - :to="{ name: 'core.editPerson', params: { id: data.person.id }}" + v-if="data.person.canEditPerson" + color="primary" + :to="{ name: 'core.editPerson', params: { id: data.person.id } }" > <v-icon left>$edit</v-icon> {{ $t("actions.edit") }} </v-btn> <v-btn - v-if="data.person.canChangePersonPreferences" - color="secondary" - outlined - text - :to="{ name: 'core.preferencesPersonByPk', params: { pk: data.person.id }}" + v-if="data.person.canChangePersonPreferences" + color="secondary" + outlined + text + :to="{ + name: 'core.preferencesPersonByPk', + params: { pk: data.person.id }, + }" > <v-icon left>$preferences</v-icon> {{ $t("preferences.person.change_preferences") }} </v-btn> <v-menu> - <template v-slot:activator="{ on, attrs }"> - <v-btn - outlined - text - v-bind="attrs" - v-on="on" - > + <template #activator="{ on, attrs }"> + <v-btn outlined text v-bind="attrs" v-on="on"> <v-icon center>mdi-dots-horizontal</v-icon> </v-btn> </template> <v-list> <v-list-item - v-if="data.person.canImpersonatePerson" - :to="{ name: 'impersonate.impersonateByUserPk', params: { uid: data.person.userid }, query: { next: $route.path }}" + v-if="data.person.canImpersonatePerson" + :to="{ + name: 'impersonate.impersonateByUserPk', + params: { uid: data.person.userid }, + query: { next: $route.path }, + }" > <v-list-item-icon> <v-icon>mdi-account-box-outline</v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ $t("person.impersonation.impersonate") }}</v-list-item-title> + <v-list-item-title>{{ + $t("person.impersonation.impersonate") + }}</v-list-item-title> </v-list-item-content> </v-list-item> <v-list-item v-if="data.person.canInvitePerson" - :to="{ name: 'core.invitePerson', params: { id: data.person.id }}" + :to="{ + name: 'core.invitePerson', + params: { id: data.person.id }, + }" > <v-list-item-icon> <v-icon>mdi-account-plus-outline</v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ $t("person.invite") }}</v-list-item-title> + <v-list-item-title>{{ + $t("person.invite") + }}</v-list-item-title> </v-list-item-content> </v-list-item> <v-list-item v-if="data.person.canDeletePerson" - :to="{ name: 'core.deletePerson', params: { id: data.person.id }}" + :to="{ + name: 'core.deletePerson', + params: { id: data.person.id }, + }" class="error--text" > <v-list-item-icon> <v-icon color="error">mdi-delete</v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ $t("person.delete") }}</v-list-item-title> + <v-list-item-title>{{ + $t("person.delete") + }}</v-list-item-title> </v-list-item-content> </v-list-item> </v-list> @@ -96,13 +102,13 @@ export default { id: { type: String, required: true, - } - } -} + }, + }, +}; </script> <style scoped> - .gap { - gap: .5rem; - } +.gap { + gap: 0.5rem; +} </style> diff --git a/aleksis/core/assets/components/person/PersonList.vue b/aleksis/core/assets/components/person/PersonList.vue index 129920b74..ad0e4ddad 100644 --- a/aleksis/core/assets/components/person/PersonList.vue +++ b/aleksis/core/assets/components/person/PersonList.vue @@ -1,23 +1,21 @@ <template> - <v-list - v-if="persons.length" - > + <v-list v-if="persons.length"> <v-list-item - v-for="person in persons" - :key="person.id" - :to="{ name: 'core.personById', params: { id: person.id }}" + v-for="person in persons" + :key="person.id" + :to="{ name: 'core.personById', params: { id: person.id } }" > <v-list-item-avatar> <avatar-content :id="person.id" /> </v-list-item-avatar> <v-list-item-content> - <v-list-item-title v-text="person.fullName"></v-list-item-title> + <v-list-item-title>{{ person.fullName }}</v-list-item-title> </v-list-item-content> </v-list-item> </v-list> <p v-else> - {{ $t("person.no_persons")}} + {{ $t("person.no_persons") }} </p> </template> @@ -26,16 +24,14 @@ import AvatarContent from "./AvatarContent.vue"; export default { name: "PersonList", - components: {AvatarContent}, + components: { AvatarContent }, props: { persons: { type: Array, required: true, - } - } -} + }, + }, +}; </script> -<style scoped> - -</style> +<style scoped></style> diff --git a/aleksis/core/assets/components/person/PersonOverview.vue b/aleksis/core/assets/components/person/PersonOverview.vue index 2975f1f30..dd55ed718 100644 --- a/aleksis/core/assets/components/person/PersonOverview.vue +++ b/aleksis/core/assets/components/person/PersonOverview.vue @@ -1,18 +1,12 @@ <template> - <ApolloQuery - :query="require('./personOverview.graphql')" - :variables="{id}" - > + <ApolloQuery :query="require('./personOverview.graphql')" :variables="{ id }"> <template #default="{ result: { error, data, loading } }"> <template v-if="loading"> - <v-skeleton-loader type="article"/> + <v-skeleton-loader type="article" /> <v-row> - <v-col - cols="12" - lg="4" - v-for="_ in 3"> - <v-skeleton-loader type="card"/> + <v-col cols="12" lg="4" v-for="idx in 3" :key="idx"> + <v-skeleton-loader type="card" /> </v-col> </v-row> </template> @@ -27,27 +21,19 @@ order="first" max-width="220px" > - <avatar-click-box :id="id"/> + <avatar-click-box :id="id" /> </v-col> - <v-col - order="last" - order-sm="1" - cols="12" - sm="" - > - <h1> - {{ data.person.firstName }} {{ data.person.lastName }} - </h1> - <div v-if="data.person.username" class="text-h5 grey--text text--darken-2"> + <v-col order="last" order-sm="1" cols="12" sm=""> + <h1>{{ data.person.firstName }} {{ data.person.lastName }}</h1> + <div + v-if="data.person.username" + class="text-h5 grey--text text--darken-2" + > {{ data.person.username }} </div> </v-col> - <v-col - order="1" - order-sm="last" - class="ms-5" - > + <v-col order="1" order-sm="last" class="ms-5"> <person-actions :id="data.person.id" /> </v-col> </v-row> @@ -55,34 +41,29 @@ <div class="text-center my-5" v-text="data.person.description"></div> <v-row> - <v-col - cols="12" - lg="4" - > + <v-col cols="12" lg="4"> <v-card class="mb-6"> <v-card-title>{{ $t("person.details") }}</v-card-title> <v-list two-line> <v-list-item> <v-list-item-icon> - <v-icon> - mdi-account-outline - </v-icon> + <v-icon> mdi-account-outline </v-icon> </v-list-item-icon> <v-list-item-content> <v-list-item-title> - {{ data.person.firstName }} {{ data.person.additionalName }} {{ data.person.lastName }} + {{ data.person.firstName }} + {{ data.person.additionalName }} + {{ data.person.lastName }} </v-list-item-title> </v-list-item-content> </v-list-item> - <v-divider inset/> + <v-divider inset /> <v-list-item> <v-list-item-icon> - <v-icon> - mdi-human-non-binary - </v-icon> + <v-icon> mdi-human-non-binary </v-icon> </v-list-item-icon> <v-list-item-content> @@ -91,76 +72,82 @@ </v-list-item-title> </v-list-item-content> </v-list-item> - <v-divider inset/> + <v-divider inset /> <v-list-item> <v-list-item-icon> - <v-icon> - mdi-map-marker-outline - </v-icon> + <v-icon> mdi-map-marker-outline </v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ data.person.street || "–" }} {{ data.person.housenumber }}</v-list-item-title> - <v-list-item-subtitle>{{ data.person.postalCode }} {{ data.person.place }}</v-list-item-subtitle> + <v-list-item-title + >{{ data.person.street || "–" }} + {{ data.person.housenumber }}</v-list-item-title + > + <v-list-item-subtitle + >{{ data.person.postalCode }} + {{ data.person.place }}</v-list-item-subtitle + > </v-list-item-content> </v-list-item> - <v-divider inset/> + <v-divider inset /> - <v-list-item - :href="'tel:' + data.person.phoneNumber" - > + <v-list-item :href="'tel:' + data.person.phoneNumber"> <v-list-item-icon> - <v-icon> - mdi-phone-outline - </v-icon> + <v-icon> mdi-phone-outline </v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ data.person.phoneNumber || "–" }}</v-list-item-title> - <v-list-item-subtitle>{{ $t("person.home") }}</v-list-item-subtitle> + <v-list-item-title>{{ + data.person.phoneNumber || "–" + }}</v-list-item-title> + <v-list-item-subtitle>{{ + $t("person.home") + }}</v-list-item-subtitle> </v-list-item-content> </v-list-item> - <v-list-item - :href="'tel:' + data.person.mobileNumber" - > + <v-list-item :href="'tel:' + data.person.mobileNumber"> <v-list-item-action></v-list-item-action> <v-list-item-content> - <v-list-item-title>{{ data.person.mobileNumber || "–" }}</v-list-item-title> - <v-list-item-subtitle>{{ $t("person.mobile") }}</v-list-item-subtitle> + <v-list-item-title>{{ + data.person.mobileNumber || "–" + }}</v-list-item-title> + <v-list-item-subtitle>{{ + $t("person.mobile") + }}</v-list-item-subtitle> </v-list-item-content> </v-list-item> - <v-divider inset/> + <v-divider inset /> - <v-list-item - :href="'mailto:' + data.person.email" - > + <v-list-item :href="'mailto:' + data.person.email"> <v-list-item-icon> - <v-icon> - mdi-email-outline - </v-icon> + <v-icon> mdi-email-outline </v-icon> </v-list-item-icon> <v-list-item-content> <v-list-item-title> - {{ data.person.email || "–" }} + {{ data.person.email || "–" }} </v-list-item-title> </v-list-item-content> </v-list-item> - <v-divider inset/> + <v-divider inset /> <v-list-item> <v-list-item-icon> - <v-icon> - mdi-cake-variant-outline - </v-icon> + <v-icon> mdi-cake-variant-outline </v-icon> </v-list-item-icon> <v-list-item-content> - <v-list-item-title>{{ !!data.person.dateOfBirth ? $d(new Date(data.person.dateOfBirth), "short") : "–" }}</v-list-item-title> - <v-list-item-subtitle>{{ data.person.placeOfBirth }}</v-list-item-subtitle> + <v-list-item-title>{{ + !!data.person.dateOfBirth + ? $d(new Date(data.person.dateOfBirth), "short") + : "–" + }}</v-list-item-title> + <v-list-item-subtitle>{{ + data.person.placeOfBirth + }}</v-list-item-subtitle> </v-list-item-content> </v-list-item> </v-list> @@ -170,40 +157,35 @@ </v-col> <v-col - cols="12" - md="6" - lg="4" - v-if="data.person.children.length || data.person.guardians.length" + cols="12" + md="6" + lg="4" + v-if="data.person.children.length || data.person.guardians.length" > <v-card v-if="data.person.children.length" class="mb-6"> <v-card-title>{{ $t("person.children") }}</v-card-title> - <person-list :persons="data.person.children"/> + <person-list :persons="data.person.children" /> </v-card> <v-card v-if="data.person.guardians.length"> <v-card-title>{{ $t("person.guardians") }}</v-card-title> - <person-list :persons="data.person.guardians"/> + <person-list :persons="data.person.guardians" /> </v-card> </v-col> <v-col - cols="12" - md="6" - lg="4" - v-if="data.person.memberOf.length || data.person.ownerOf.length" + cols="12" + md="6" + lg="4" + v-if="data.person.memberOf.length || data.person.ownerOf.length" > - <v-card - v-if="data.person.memberOf.length" - class="mb-6" - > - <v-card-title>{{ $t("group.title_plural") }}</v-card-title> - <group-list :groups="data.person.memberOf"/> - </v-card> - <v-card - v-if="data.person.ownerOf.length" - > - <v-card-title>{{ $t("group.ownership") }}</v-card-title> - <group-list :groups="data.person.ownerOf"/> - </v-card> + <v-card v-if="data.person.memberOf.length" class="mb-6"> + <v-card-title>{{ $t("group.title_plural") }}</v-card-title> + <group-list :groups="data.person.memberOf" /> + </v-card> + <v-card v-if="data.person.ownerOf.length"> + <v-card-title>{{ $t("group.ownership") }}</v-card-title> + <group-list :groups="data.person.ownerOf" /> + </v-card> </v-col> </v-row> </template> @@ -220,17 +202,21 @@ import PersonList from "./PersonList.vue"; export default { name: "PersonOverview", - components: {AdditionalImage, AvatarClickBox, GroupList, PersonActions, PersonList}, + components: { + AdditionalImage, + AvatarClickBox, + GroupList, + PersonActions, + PersonList, + }, props: { id: { type: String, required: false, default: null, - } - } -} + }, + }, +}; </script> -<style scoped> - -</style> +<style scoped></style> diff --git a/aleksis/core/assets/components/person/personOverview.graphql b/aleksis/core/assets/components/person/personOverview.graphql index 311d5009e..1d2de79d9 100644 --- a/aleksis/core/assets/components/person/personOverview.graphql +++ b/aleksis/core/assets/components/person/personOverview.graphql @@ -1,5 +1,5 @@ query person($id: ID) { - person: personByIdOrMe(id:$id) { + person: personByIdOrMe(id: $id) { id username firstName diff --git a/aleksis/core/assets/mixins/useRegisterSW.js b/aleksis/core/assets/mixins/useRegisterSW.js index 1f5064ff3..1034799fa 100644 --- a/aleksis/core/assets/mixins/useRegisterSW.js +++ b/aleksis/core/assets/mixins/useRegisterSW.js @@ -6,55 +6,52 @@ export default { offlineReady: false, needRefresh: false, refreshDismissed: false, - } + }; }, async mounted() { try { - const { registerSW } = await import('virtual:pwa-register') - const vm = this + const { registerSW } = await import("virtual:pwa-register"); + const vm = this; this.updateSW = registerSW({ onOfflineReady() { - vm.offlineReady = true - console.log("PWA is offline-ready.") + vm.offlineReady = true; + console.log("PWA is offline-ready."); }, onNeedRefresh() { - vm.needRefresh = true - console.log("PWA needs to be refreshed.") + vm.needRefresh = true; + console.log("PWA needs to be refreshed."); }, onRegisteredSW(swUrl, r) { - r && setInterval(async () => { - if (!(!r.installing && navigator)) - return + r && + setInterval(async () => { + if (!(!r.installing && navigator)) return; - if (("connection" in navigator) && !navigator.onLine) - return + if ("connection" in navigator && !navigator.onLine) return; - const resp = await fetch(swUrl, { - cache: "no-store", - headers: { - "cache": "no-store", - "cache-control": "no-cache", - }, - }) + const resp = await fetch(swUrl, { + cache: "no-store", + headers: { + cache: "no-store", + "cache-control": "no-cache", + }, + }); - if (resp?.status === 200) - await r.update() - }, 60 * 60 * 1000) + if (resp?.status === 200) await r.update(); + }, 60 * 60 * 1000); }, onRegisterError(e) { - console.log("Error while installing PWA: " + e) - } - }) - } - catch { - console.log('PWA disabled.') + console.log("Error while installing PWA: " + e); + }, + }); + } catch { + console.log("PWA disabled."); } }, methods: { updateServiceWorker() { - this.offlineReady = false - this.needRefresh = false - this.updateSW && this.updateSW(true) - } - } -} + this.offlineReady = false; + this.needRefresh = false; + this.updateSW && this.updateSW(true); + }, + }, +}; diff --git a/aleksis/core/decorators.py b/aleksis/core/decorators.py index 510070f48..b12bf1942 100644 --- a/aleksis/core/decorators.py +++ b/aleksis/core/decorators.py @@ -2,9 +2,7 @@ from functools import wraps def pwa_cache(view_func): - """ - Decorator that adds headers to a response so that the PWA will recognize it as cacheable. - """ + """Add headers to a response so that the PWA will recognize it as cacheable.""" @wraps(view_func) def _wrapped_view_func(request, *args, **kwargs): diff --git a/aleksis/core/schema/__init__.py b/aleksis/core/schema/__init__.py index 71543acf5..66dab3788 100644 --- a/aleksis/core/schema/__init__.py +++ b/aleksis/core/schema/__init__.py @@ -77,7 +77,7 @@ class Query(graphene.ObjectType): raise PermissionDenied() return person - def resolve_person_by_id_or_me(root, info, id): # noqa + def resolve_person_by_id_or_me(root, info, id): # noqa # Returns person associated with current user if id is None, else the person with the id if id is None: return info.context.user.person if has_person(info.context.user) else None diff --git a/aleksis/core/schema/pdf.py b/aleksis/core/schema/pdf.py index 1a3a3689b..a87eabf7b 100644 --- a/aleksis/core/schema/pdf.py +++ b/aleksis/core/schema/pdf.py @@ -1,4 +1,3 @@ - import graphene from graphene_django import DjangoObjectType diff --git a/aleksis/core/schema/person.py b/aleksis/core/schema/person.py index e64082f68..b51fa08c2 100644 --- a/aleksis/core/schema/person.py +++ b/aleksis/core/schema/person.py @@ -47,10 +47,10 @@ class PersonType(DjangoObjectType): can_impersonate_person = graphene.Boolean() can_invite_person = graphene.Boolean() - def resolve_username(root, info, **kwargs): # noqa + def resolve_username(root, info, **kwargs): # noqa return root.user.username if root.user else None - def resolve_userid(root, info, **kwargs): # noqa + def resolve_userid(root, info, **kwargs): # noqa return root.user.id if root.user else None def resolve_unread_notifications_count(root, info, **kwargs): # noqa @@ -89,7 +89,8 @@ class PersonType(DjangoObjectType): return root.identicon_url def resolve_secondary_image_url(root, info, **kwargs): # noqa - # returns either the photo url or the avatar url, depending on the one returned by avatar_content_url + # returns either the photo url or the avatar url, + # depending on the one returned by avatar_content_url if get_site_preferences()["account__person_prefer_photo"]: if info.context.user.has_perm("core.view_avatar_rule", root) and root.avatar: @@ -98,8 +99,6 @@ class PersonType(DjangoObjectType): return root.photo.url return None - - def resolve_is_dummy(root: Union[Person, DummyPerson], info, **kwargs): return root.is_dummy if hasattr(root, "is_dummy") else False @@ -109,7 +108,6 @@ class PersonType(DjangoObjectType): def resolve_notifications(root: Person, info, **kwargs): return root.notifications.filter(send_at__lte=timezone.now()).order_by("read", "-created") - def resolve_can_edit_person(root, info, **kwargs): # noqa return info.context.user.has_perm("core.edit_person_rule", root) diff --git a/aleksis/core/schema/user.py b/aleksis/core/schema/user.py index a532da4cf..33547acf8 100644 --- a/aleksis/core/schema/user.py +++ b/aleksis/core/schema/user.py @@ -4,7 +4,7 @@ from .person import PersonType class UserType(graphene.ObjectType): - id = graphene.ID() + id = graphene.ID() # noqa username = graphene.String() first_name = graphene.String() last_name = graphene.String() diff --git a/aleksis/core/static/js/main.js b/aleksis/core/static/js/main.js index 87f9660e2..66d3afdee 100644 --- a/aleksis/core/static/js/main.js +++ b/aleksis/core/static/js/main.js @@ -174,4 +174,3 @@ $(document).ready(function () { el.addClass("closed").removeClass("opened"); }); }); - diff --git a/aleksis/core/vite.config.js b/aleksis/core/vite.config.js index b572c9f3c..f33c3d631 100644 --- a/aleksis/core/vite.config.js +++ b/aleksis/core/vite.config.js @@ -6,7 +6,7 @@ import vue from "@vitejs/plugin-vue2"; import { nodeResolve } from "@rollup/plugin-node-resolve"; import graphql from "@rollup/plugin-graphql"; import virtual from "@rollup/plugin-virtual"; -import { VitePWA } from 'vite-plugin-pwa'; +import { VitePWA } from "vite-plugin-pwa"; const license = require("rollup-plugin-license"); const django_values = JSON.parse(fs.readFileSync("./django-vite-values.json")); @@ -18,9 +18,11 @@ function generateMessageImportCode(assetDir, name, importAppName) { const files = fs.readdirSync(messagesPath); for (file of files) { let lang = file.split(".")[0]; - code += `import ${importAppName}Messages_${lang} from '${messagesPath + file}';\n`; + code += `import ${importAppName}Messages_${lang} from '${ + messagesPath + file + }';\n`; code += `appMessages["${name}"]["${lang}"] = ${importAppName}Messages_${lang};\n`; - }; + } return code; } @@ -38,7 +40,11 @@ function generateAppImporter(appDetails) { code += `appObjects["${appMeta.name}"] = ${importAppName};\n`; if (appMeta.hasMessages) { - code += generateMessageImportCode(appMeta.assetDir, appMeta.name, importAppName); + code += generateMessageImportCode( + appMeta.assetDir, + appMeta.name, + importAppName + ); } } @@ -129,13 +135,13 @@ export default defineConfig({ VitePWA({ injectRegister: "null", devOptions: { - enabled: true + enabled: true, }, scope: "/", base: "/", workbox: { navigateFallback: "/", - navigateFallbackAllowlist: [new RegExp("^\/(?!django)[^.]*$")], + navigateFallbackAllowlist: [new RegExp("^/(?!django)[^.]*$")], additionalManifestEntries: ["/", "/django/offline/"], inlineWorkboxRuntime: true, modifyURLPrefix: { @@ -144,20 +150,20 @@ export default defineConfig({ globPatterns: ["**/*.{js,css,eot,woff,woff2,ttf}"], runtimeCaching: [ { - urlPattern: new RegExp("\/django\/.*"), + urlPattern: new RegExp("/django/.*"), handler: "NetworkFirst", options: { cacheName: "aleksis-legacy-cache", networkTimeoutSeconds: 5, expiration: { - maxAgeSeconds: 60 * 60 * 24 + maxAgeSeconds: 60 * 60 * 24, }, broadcastUpdate: { channelName: "cache-or-not", // TODO: Check whether this actually works options: {}, }, precacheFallback: { - fallbackURL: "/django/offline/" + fallbackURL: "/django/offline/", }, cacheableResponse: { headers: { @@ -167,42 +173,50 @@ export default defineConfig({ }, }, { - urlPattern: ({request, sameOrigin}) => {return sameOrigin && request.destination === "image";}, + urlPattern: ({ request, sameOrigin }) => { + return sameOrigin && request.destination === "image"; + }, handler: "StaleWhileRevalidate", options: { cacheName: "aleksis-image-cache", expiration: { - maxAgeSeconds: 60 * 60 * 24 + maxAgeSeconds: 60 * 60 * 24, }, }, }, { - urlPattern: ({request, sameOrigin}) => {return sameOrigin && request.destination === "style";}, + urlPattern: ({ request, sameOrigin }) => { + return sameOrigin && request.destination === "style"; + }, handler: "StaleWhileRevalidate", options: { cacheName: "aleksis-style-cache", expiration: { - maxAgeSeconds: 60 * 60 * 24 * 30 + maxAgeSeconds: 60 * 60 * 24 * 30, }, }, }, { - urlPattern: ({request, sameOrigin}) => {return sameOrigin && request.destination === "script";}, + urlPattern: ({ request, sameOrigin }) => { + return sameOrigin && request.destination === "script"; + }, handler: "StaleWhileRevalidate", options: { cacheName: "aleksis-script-cache", expiration: { - maxAgeSeconds: 60 * 60 * 24 * 30 + maxAgeSeconds: 60 * 60 * 24 * 30, }, }, }, { - urlPattern: ({request, sameOrigin}) => {return sameOrigin && request.destination === "font";}, + urlPattern: ({ request, sameOrigin }) => { + return sameOrigin && request.destination === "font"; + }, handler: "CacheFirst", options: { cacheName: "aleksis-font-cache", expiration: { - maxAgeSeconds: 60 * 60 * 24 * 90 + maxAgeSeconds: 60 * 60 * 24 * 90, }, }, }, @@ -213,7 +227,7 @@ export default defineConfig({ resolve: { alias: { "@": path.resolve("./node_modules"), - "vue": path.resolve("./node_modules/vue/dist/vue.esm.js"), + vue: path.resolve("./node_modules/vue/dist/vue.esm.js"), }, }, }); -- GitLab