diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 79c61aca13842af150e089297cf3049876d11b5d..9872db38359a951199911ab881e4aa3305ffe4c7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,8 @@ and this project adheres to `Semantic Versioning`_. Unreleased ---------- +Changes +======= The "managed models" feature is mandatory for all models derived from `ExtensibleModel` and requires creating a migration for all downstream models to add the respective field. @@ -17,10 +19,14 @@ Added ~~~~~ * Frontend for managing rooms. +* Global calendar system +* Calendar for birthdays of persons +* Holiday model to track information about holidays. * [Dev] Components for implementing standard CRUD operations in new frontend. * [Dev] Options for filtering and sorting of GraphQL queries at the server. * [Dev] Managed models for instances handled by other apps. * [Dev] Upload slot sytem for out-of-band uploads in GraphQL clients +* Generic endpoint for retrieving objects as JSON Changed ~~~~~~~ @@ -33,6 +39,8 @@ Fixed * [Docker] The build could silently continue even if frontend bundling failed, resulting in an incomplete AlekSIS frontend app. * GraphQL mutations did not return errors in case of exceptions. +* Rendering of "simple" PDF templates failed when used with S3 storage. +* Log messages on some loggers did not contain log message `3.1.2`_ - 2023-07-05 --------------------- diff --git a/aleksis/core/frontend/app/dateTimeFormats.js b/aleksis/core/frontend/app/dateTimeFormats.js index 567f9a196f61052ff0481c1f975a6c0d2433964e..2cea6431fa0714ebd4fd303adab620bcda94da92 100644 --- a/aleksis/core/frontend/app/dateTimeFormats.js +++ b/aleksis/core/frontend/app/dateTimeFormats.js @@ -6,6 +6,13 @@ const dateTimeFormats = { month: "short", day: "numeric", }, + shortDateTime: { + year: "numeric", + month: "short", + day: "numeric", + hour: "numeric", + minute: "numeric", + }, long: { year: "numeric", month: "long", @@ -37,6 +44,13 @@ const dateTimeFormats = { month: "short", day: "numeric", }, + shortDateTime: { + year: "numeric", + month: "short", + day: "numeric", + hour: "numeric", + minute: "numeric", + }, long: { year: "numeric", month: "long", diff --git a/aleksis/core/frontend/components/calendar/BaseCalendarFeedDetails.vue b/aleksis/core/frontend/components/calendar/BaseCalendarFeedDetails.vue new file mode 100644 index 0000000000000000000000000000000000000000..6b50ee5ba208b225709e6963ec679e826ceead82 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/BaseCalendarFeedDetails.vue @@ -0,0 +1,94 @@ +<template> + <v-menu + v-model="model" + :close-on-content-click="false" + :activator="selectedElement" + :offset-x="calendarType !== 'day'" + min-width="350px" + :offset-y="calendarType === 'day'" + > + <v-card min-width="350px" flat> + <v-toolbar :color="color || selectedEvent.color" dark dense> + <v-toolbar-title> + <slot name="title" :selected-event="selectedEvent">{{ + selectedEvent.name + }}</slot> + </v-toolbar-title> + <v-spacer></v-spacer> + <slot name="badge" :selected-event="selectedEvent"> + <cancelled-calendar-status-chip + v-if="selectedEvent.status === 'CANCELLED' && !withoutBadge" + /> + </slot> + </v-toolbar> + <slot name="time" :selected-event="selectedEvent"> + <v-list-item v-if="!withoutTime"> + <v-list-item-icon> + <v-icon color="primary">mdi-calendar-today-outline</v-icon> + </v-list-item-icon> + <v-list-item-content> + <v-list-item-title> + <span + v-if=" + selectedEvent.allDay && + selectedEvent.start.getTime() === selectedEvent.end.getTime() + " + > + {{ $d(selectedEvent.start, "short") }} + </span> + <span v-else-if="selectedEvent.allDay"> + {{ $d(selectedEvent.start, "short") }} – + {{ $d(selectedEvent.end, "short") }} + </span> + <span + v-else-if=" + dateWithoutTime(selectedEvent.start).getTime() === + dateWithoutTime(selectedEvent.end).getTime() + " + > + {{ $d(selectedEvent.start, "shortDateTime") }} – + {{ $d(selectedEvent.end, "shortTime") }} + </span> + <span v-else> + {{ $d(selectedEvent.start, "shortDateTime") }} – + {{ $d(selectedEvent.end, "shortDateTime") }} + </span> + </v-list-item-title> + </v-list-item-content> + </v-list-item> + </slot> + <slot name="description" :selected-event="selectedEvent"> + <v-divider + inset + v-if="selectedEvent.description && !withoutDescription" + /> + <v-list-item v-if="selectedEvent.description && !withoutDescription"> + <v-list-item-icon> + <v-icon color="primary">mdi-card-text-outline</v-icon> + </v-list-item-icon> + <v-list-item-content style="white-space: pre-line"> + {{ selectedEvent.description }} + </v-list-item-content> + </v-list-item> + </slot> + </v-card> + </v-menu> +</template> + +<script> +import calendarFeedDetailsMixin from "../../mixins/calendarFeedDetails.js"; +import CancelledCalendarStatusChip from "./CancelledCalendarStatusChip.vue"; + +export default { + name: "BaseCalendarFeedDetails", + components: { CancelledCalendarStatusChip }, + mixins: [calendarFeedDetailsMixin], + methods: { + dateWithoutTime(d) { + d = new Date(d); + d.setHours(0, 0, 0, 0); + return d; + }, + }, +}; +</script> diff --git a/aleksis/core/frontend/components/calendar/BaseCalendarFeedEventBar.vue b/aleksis/core/frontend/components/calendar/BaseCalendarFeedEventBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..1e1d1436897ad17a1875f0bf8a9cf20d20033310 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/BaseCalendarFeedEventBar.vue @@ -0,0 +1,56 @@ +<template> + <div + class="text-truncate" + :class="{ + 'text-decoration-line-through': event.status === 'CANCELLED', + 'mx-1': withPadding, + }" + :style="{ height: '100%' }" + > + <slot name="time" v-bind="$props"> + <span + v-if=" + calendarType === 'month' && eventParsed.start.hasTime && !withoutTime + " + class="mr-1 font-weight-bold ml-1" + > + {{ eventParsed.start.time }} + </span> + </slot> + <slot name="icon" v-bind="$props"> + <v-icon v-if="icon" x-small color="white" class="mx-1 left"> + {{ icon }} + </v-icon> + </slot> + + <slot name="title" v-bind="$props"> + {{ event.name }} + </slot> + </div> +</template> + +<script> +import calendarFeedEventBarMixin from "../../mixins/calendarFeedEventBar.js"; + +export default { + name: "BaseCalendarFeedEventBar", + mixins: [calendarFeedEventBarMixin], + props: { + withPadding: { + required: false, + type: Boolean, + default: true, + }, + icon: { + required: false, + type: String, + default: "", + }, + withoutTime: { + required: false, + type: Boolean, + default: false, + }, + }, +}; +</script> diff --git a/aleksis/core/frontend/components/calendar/CalendarControlBar.vue b/aleksis/core/frontend/components/calendar/CalendarControlBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..c3f9c45c424aa73c0178ea15882e4e6783a73e43 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CalendarControlBar.vue @@ -0,0 +1,21 @@ +<script> +export default { + name: "CalendarControlBar", + emits: ["prev", "next", "today"], +}; +</script> + +<template> + <div class="d-flex justify-center"> + <v-btn icon class="mx-2" @click="$emit('prev')"> + <v-icon>mdi-chevron-left</v-icon> + </v-btn> + <v-btn outlined text class="mx-2" @click="$emit('today')"> + <v-icon left>mdi-calendar-today-outline</v-icon> + {{ $t("calendar.today") }} + </v-btn> + <v-btn icon class="mx-2" @click="$emit('next')"> + <v-icon>mdi-chevron-right</v-icon> + </v-btn> + </div> +</template> diff --git a/aleksis/core/frontend/components/calendar/CalendarOverview.vue b/aleksis/core/frontend/components/calendar/CalendarOverview.vue new file mode 100644 index 0000000000000000000000000000000000000000..7153b8e1e8dce599fc00527d28bc327a713e4ed4 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CalendarOverview.vue @@ -0,0 +1,329 @@ +<template> + <div class="mt-4 mb-4"> + <v-skeleton-loader + v-if=" + $apollo.queries.calendar.loading && calendar.calendarFeeds.length === 0 + " + type="date-picker-options, actions" + /> + <div v-else> + <h1 + class="mb-4 mx-4" + v-if="$vuetify.breakpoint.mdAndDown && $refs.calendar" + > + {{ $refs.calendar.title }} + </h1> + <v-row align="stretch"> + <!-- Control bar with prev, next and today buttons --> + <v-col cols="12" sm="4" lg="3" xl="2" align-self="center"> + <calendar-control-bar + @prev="$refs.calendar.prev()" + @next="$refs.calendar.next()" + @today="calendarFocus = new Date()" + /> + </v-col> + + <!-- Calendar title with current calendar time range --> + <v-col v-if="$vuetify.breakpoint.lgAndUp" align-self="center"> + <h1 class="mx-2" v-if="$refs.calendar">{{ $refs.calendar.title }}</h1> + </v-col> + + <!-- Button menu for selecting currently active calendars (only tablets/mobile) --> + <v-col + v-if="$vuetify.breakpoint.mdAndDown" + cols="12" + sm="4" + align-self="center" + class="d-flex justify-center" + > + <button-menu + icon="mdi-calendar-check-outline" + text-translation-key="calendar.select" + > + <calendar-select + v-model="selectedCalendarFeedNames" + :calendar-feeds="calendar.calendarFeeds" + @input="storeActivatedCalendars" + /> + </button-menu> + </v-col> + + <v-spacer v-if="$vuetify.breakpoint.lgAndUp" /> + + <!-- Calendar type select (month, week, day) --> + <v-col + cols="12" + sm="4" + lg="3" + align-self="center" + :align="$vuetify.breakpoint.smAndUp ? 'right' : 'center'" + > + <calendar-type-select v-model="currentCalendarType" /> + </v-col> + </v-row> + <v-row> + <v-col v-if="$vuetify.breakpoint.lgAndUp" lg="3" xl="2"> + <!-- Mini date picker --> + <v-date-picker + no-title + v-model="calendarFocus" + :style="{ margin: '0px -8px' }" + :first-day-of-week="1" + ></v-date-picker> + + <!-- Calendar select (only desktop) --> + <v-list flat subheader> + <v-subheader> + {{ $t("calendar.my_calendars") }} + </v-subheader> + <calendar-select + class="mb-4" + v-model="selectedCalendarFeedNames" + :calendar-feeds="calendar.calendarFeeds" + @input="storeActivatedCalendars" + /> + <v-btn depressed block v-if="calendar" :href="calendar.allFeedsUrl"> + <v-icon left>mdi-download-outline</v-icon> + {{ $t("calendar.download_all") }} + </v-btn> + </v-list> + </v-col> + + <!-- Actual calendar --> + <v-col lg="9" xl="10"> + <v-sheet height="600"> + <v-expand-transition> + <v-progress-linear + v-if="$apollo.queries.calendar.loading" + indeterminate + /> + </v-expand-transition> + <v-calendar + ref="calendar" + v-model="calendarFocus" + show-week + :events="events" + :type="currentCalendarType" + :event_color="getColorForEvent" + @click:date="viewDay" + @click:day="viewDay" + @click:more="viewDay" + @click:event="viewEvent" + @change="fetchMoreCalendarEvents" + > + <template #event="{ event, eventParsed, timed }"> + <component + :is="eventBarComponentForFeed(event.calendarFeedName)" + :event="event" + :event-parsed="eventParsed" + :calendar-type="currentCalendarType" + /> + </template> + </v-calendar> + <component + v-if="calendar && calendar.calendarFeeds && selectedEvent" + :is="detailComponentForFeed(selectedEvent.calendarFeedName)" + v-model="selectedOpen" + :selected-element="selectedElement" + :selected-event="selectedEvent" + :calendar-type="currentCalendarType" + /> + </v-sheet> + </v-col> + </v-row> + </div> + </div> +</template> + +<script> +import ButtonMenu from "../generic/ButtonMenu.vue"; +import CalendarSelect from "./CalendarSelect.vue"; +import GenericCalendarFeedDetails from "./GenericCalendarFeedDetails.vue"; +import GenericCalendarFeedEventBar from "./GenericCalendarFeedEventBar.vue"; + +import { + calendarFeedDetailComponents, + calendarFeedEventBarComponents, +} from "aleksisAppImporter"; + +import gqlCalendarOverview from "./calendarOverview.graphql"; +import gqlSetCalendarStatus from "./setCalendarStatus.graphql"; +import CalendarControlBar from "./CalendarControlBar.vue"; +import CalendarTypeSelect from "./CalendarTypeSelect.vue"; + +export default { + name: "CalendarOverview", + components: { + CalendarTypeSelect, + CalendarControlBar, + ButtonMenu, + CalendarSelect, + }, + data() { + return { + calendarFocus: "", + calendar: { + calendarFeeds: [], + }, + selectedCalendarFeedNames: [], + currentCalendarType: "week", + selectedEvent: {}, + selectedElement: null, + selectedOpen: false, + fetchedDateRange: { start: null, end: null }, + }; + }, + apollo: { + calendar: { + query: gqlCalendarOverview, + skip: true, + result({ data }) { + this.selectedCalendarFeedNames = data.calendar.calendarFeeds + .filter((c) => c.activated) + .map((c) => c.name); + }, + }, + }, + computed: { + events() { + return this.calendar.calendarFeeds + .filter((c) => this.selectedCalendarFeedNames.includes(c.name)) + .flatMap((cf) => + cf.feed.events.map((event) => ({ + ...event, + category: cf.verboseName, + calendarFeedName: cf.name, + start: new Date(event.start), + end: new Date(event.end), + color: event.color ? event.color : cf.color, + timed: !event.allDay, + meta: JSON.parse(event.meta), + })) + ); + }, + }, + methods: { + viewDay({ date }) { + this.calendarFocus = date; + this.currentCalendarType = "day"; + }, + viewEvent({ nativeEvent, event }) { + const open = () => { + this.selectedEvent = event; + this.selectedElement = nativeEvent.target; + requestAnimationFrame(() => + requestAnimationFrame(() => (this.selectedOpen = true)) + ); + }; + + if (this.selectedOpen) { + this.selectedOpen = false; + requestAnimationFrame(() => requestAnimationFrame(() => open())); + } else { + open(); + } + + nativeEvent.stopPropagation(); + }, + detailComponentForFeed(feedName) { + if ( + this.calendar.calendarFeeds && + feedName && + Object.keys(calendarFeedDetailComponents).includes(feedName + "details") + ) { + return calendarFeedDetailComponents[feedName + "details"]; + } + return GenericCalendarFeedDetails; + }, + eventBarComponentForFeed(feedName) { + if ( + this.calendar.calendarFeeds && + feedName && + Object.keys(calendarFeedEventBarComponents).includes( + feedName + "eventbar" + ) + ) { + return calendarFeedEventBarComponents[feedName + "eventbar"]; + } + return GenericCalendarFeedEventBar; + }, + getColorForEvent(event) { + return event.color; + }, + storeActivatedCalendars() { + // Store currently activated calendars in the backend + this.$apollo.mutate({ + mutation: gqlSetCalendarStatus, + variables: { + calendars: this.selectedCalendarFeedNames, + }, + }); + }, + fetchMoreCalendarEvents({ start, end }) { + // Get the start and end dates of the current date range shown in the calendar + let extendedStart = this.$refs.calendar.getStartOfWeek(start).date; + let extendedEnd = this.$refs.calendar.getEndOfWeek(end).date; + + let olderStart = extendedStart < this.fetchedDateRange.start; + let youngerEnd = extendedEnd > this.fetchedDateRange.end; + + if (this.calendar.calendarFeeds.length === 0) { + // No calendar feeds have been fetched yet, + // so fetch all events in the current date range + + this.$apollo.queries.calendar.setVariables({ + start: extendedStart, + end: extendedEnd, + }); + this.$apollo.queries.calendar.skip = false; + this.fetchedDateRange = { start: extendedStart, end: extendedEnd }; + } else if (olderStart || youngerEnd) { + // Define newly fetched date range + let newStart = olderStart ? extendedStart : this.fetchedDateRange.start; + let newEnd = youngerEnd ? extendedEnd : this.fetchedDateRange.end; + + // Define date range to fetch + let fetchStart = olderStart ? extendedStart : this.fetchedDateRange.end; + let fetchEnd = youngerEnd ? extendedEnd : this.fetchedDateRange.start; + + this.$apollo.queries.calendar.fetchMore({ + variables: { + start: fetchStart, + end: fetchEnd, + }, + updateQuery: (previousResult, { fetchMoreResult }) => { + let previousCalendarFeeds = previousResult.calendar.calendarFeeds; + let newCalendarFeeds = fetchMoreResult.calendar.calendarFeeds; + + previousCalendarFeeds.forEach((calendarFeed, i, calendarFeeds) => { + // Get all events except those that are updated + let keepEvents = calendarFeed.feed.events.filter( + (event) => event.end < fetchStart || event.start > fetchEnd + ); + + /// Update the events of the calendar feed + calendarFeeds[i].feed.events = [ + ...keepEvents, + ...newCalendarFeeds[i].feed.events, + ]; + }); + return { + calendar: { + ...previousResult.calendar, + calendarFeeds: previousCalendarFeeds, + }, + }; + }, + }); + + this.fetchedDateRange = { start: newStart, end: newEnd }; + } + }, + }, + mounted() { + this.$refs.calendar.move(0); + }, +}; +</script> + +<style scoped></style> diff --git a/aleksis/core/frontend/components/calendar/CalendarSelect.vue b/aleksis/core/frontend/components/calendar/CalendarSelect.vue new file mode 100644 index 0000000000000000000000000000000000000000..5748b1d5755b961ca901f075b4aac152f3874634 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CalendarSelect.vue @@ -0,0 +1,85 @@ +<template> + <v-list-item-group multiple v-model="model"> + <v-list-item + v-for="calendarFeed in calendarFeeds" + :key="calendarFeed.name" + :value="calendarFeed.name" + > + <template #default="{ active }"> + <v-list-item-action> + <v-checkbox + :input-value="active" + :color="calendarFeed.color" + ></v-checkbox> + </v-list-item-action> + + <v-list-item-content> + <v-list-item-title> + {{ calendarFeed.verboseName }} + </v-list-item-title> + </v-list-item-content> + + <v-list-item-action> + <v-menu bottom> + <template v-slot:activator="{ on, attrs }"> + <v-btn fab x-small icon v-bind="attrs" v-on="on"> + <v-icon>mdi-dots-vertical</v-icon> + </v-btn> + </template> + <v-list dense> + <v-list-item :href="calendarFeed.url"> + <v-list-item-icon> + <v-icon>mdi-calendar-export</v-icon> + </v-list-item-icon> + <v-list-item-title> + {{ $t("calendar.download_ics") }} + </v-list-item-title> + </v-list-item> + </v-list> + </v-menu> + </v-list-item-action> + </template> + </v-list-item> + </v-list-item-group> +</template> + +<script> +export default { + name: "CalendarSelect", + props: { + calendarFeeds: { + type: Array, + required: true, + }, + value: { + type: Array, + required: true, + }, + }, + computed: { + model: { + get() { + return this.value; + }, + set(value) { + this.$emit("input", value); + }, + }, + someSelected() { + return this.model.length > 0 && !this.allSelected; + }, + allSelected() { + return this.model.length === this.calendarFeeds.length; + }, + }, + methods: { + toggleAll(newValue) { + if (newValue) { + this.model = this.calendarFeeds.map((feed) => feed.name); + } else { + this.model = []; + } + }, + }, +}; +</script> diff --git a/aleksis/core/frontend/components/calendar/CalendarStatusChip.vue b/aleksis/core/frontend/components/calendar/CalendarStatusChip.vue new file mode 100644 index 0000000000000000000000000000000000000000..679749135dd12e302f18a797af4d8fb169a44470 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CalendarStatusChip.vue @@ -0,0 +1,24 @@ +<script> +export default { + name: "CalendarStatusChip", + props: { + color: { + type: String, + required: true, + }, + icon: { + type: String, + required: true, + }, + }, +}; +</script> + +<template> + <v-chip :color="color" label> + <v-avatar left> + <v-icon>{{ icon }}</v-icon> + </v-avatar> + <slot></slot> + </v-chip> +</template> diff --git a/aleksis/core/frontend/components/calendar/CalendarTypeSelect.vue b/aleksis/core/frontend/components/calendar/CalendarTypeSelect.vue new file mode 100644 index 0000000000000000000000000000000000000000..1868b314a1af1106fe30b54571f629f2a577995f --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CalendarTypeSelect.vue @@ -0,0 +1,61 @@ +<script> +export default { + name: "CalendarTypeSelect", + props: { + value: { + type: String, + required: true, + }, + }, + data() { + return { + innerValue: this.value, + availableCalendarTypes: [ + { + type: "month", + translationKey: "calendar.month", + icon: "calendar-month-outline", + }, + { + type: "week", + translationKey: "calendar.week", + icon: "calendar-week-outline", + }, + { + type: "day", + translationKey: "calendar.day", + icon: "calendar-today-outline", + }, + ], + }; + }, + watch: { + value(val) { + this.innerValue = val; + }, + innerValue(val) { + this.$emit("input", val); + }, + }, + methods: { + nameForMenu(item) { + return this.$t(item.translationKey); + }, + }, +}; +</script> + +<template> + <v-btn-toggle dense v-model="innerValue" class="mx-2"> + <v-btn + v-for="calendarType in availableCalendarTypes" + :value="calendarType.type" + :key="calendarType.type" + > + <v-icon v-if="$vuetify.breakpoint.smAndDown">{{ + "mdi-" + calendarType.icon + }}</v-icon> + <span class="hidden-sm-and-down">{{ nameForMenu(calendarType) }}</span> + </v-btn> + </v-btn-toggle> +</template> diff --git a/aleksis/core/frontend/components/calendar/CancelledCalendarStatusChip.vue b/aleksis/core/frontend/components/calendar/CancelledCalendarStatusChip.vue new file mode 100644 index 0000000000000000000000000000000000000000..00b816943654453690f32da1db95e14f57b7dce7 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/CancelledCalendarStatusChip.vue @@ -0,0 +1,14 @@ +<script> +import CalendarStatusChip from "./CalendarStatusChip.vue"; + +export default { + name: "CancelledCalendarStatusChip", + components: { CalendarStatusChip }, +}; +</script> + +<template> + <calendar-status-chip icon="mdi-cancel" color="error"> + {{ $t("calendar.cancelled") }} + </calendar-status-chip> +</template> diff --git a/aleksis/core/frontend/components/calendar/GenericCalendarFeedDetails.vue b/aleksis/core/frontend/components/calendar/GenericCalendarFeedDetails.vue new file mode 100644 index 0000000000000000000000000000000000000000..2b6f8fa1e5833260196f97a4e939187f87c80c3f --- /dev/null +++ b/aleksis/core/frontend/components/calendar/GenericCalendarFeedDetails.vue @@ -0,0 +1,25 @@ +<template> + <div> + <base-calendar-feed-details v-bind="$props" /> + <v-divider inset v-if="selectedEvent.location" /> + <v-list-item v-if="selectedEvent.location"> + <v-list-item-icon> + <v-icon color="primary">mdi-map-marker-outline</v-icon> + </v-list-item-icon> + <v-list-item-content> + {{ selectedEvent.location }} + </v-list-item-content> + </v-list-item> + </div> +</template> + +<script> +import calendarFeedDetailsMixin from "../../mixins/calendarFeedDetails.js"; +import BaseCalendarFeedDetails from "./BaseCalendarFeedDetails.vue"; + +export default { + name: "GenericCalendarFeedDetails", + components: { BaseCalendarFeedDetails }, + mixins: [calendarFeedDetailsMixin], +}; +</script> diff --git a/aleksis/core/frontend/components/calendar/GenericCalendarFeedEventBar.vue b/aleksis/core/frontend/components/calendar/GenericCalendarFeedEventBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..251b7a8b929f3b67ada0e4a207aefef16d500149 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/GenericCalendarFeedEventBar.vue @@ -0,0 +1,14 @@ +<template> + <base-calendar-feed-event-bar v-bind="$props" /> +</template> + +<script> +import calendarFeedEventBarMixin from "../../mixins/calendarFeedEventBar.js"; +import BaseCalendarFeedEventBar from "./BaseCalendarFeedEventBar.vue"; + +export default { + name: "GenericCalendarFeedEventBar", + components: { BaseCalendarFeedEventBar }, + mixins: [calendarFeedEventBarMixin], +}; +</script> diff --git a/aleksis/core/frontend/components/calendar/calendarOverview.graphql b/aleksis/core/frontend/components/calendar/calendarOverview.graphql new file mode 100644 index 0000000000000000000000000000000000000000..f277ef4bbffcf9cf68532a5e1ba9ce3ecd2c813b --- /dev/null +++ b/aleksis/core/frontend/components/calendar/calendarOverview.graphql @@ -0,0 +1,27 @@ +query ($start: Date, $end: Date) { + calendar { + allFeedsUrl + calendarFeeds { + name + verboseName + description + url + color + activated + feed { + events(start: $start, end: $end) { + name + start + end + color + description + location + uid + allDay + status + meta + } + } + } + } +} diff --git a/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql b/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql new file mode 100644 index 0000000000000000000000000000000000000000..633f0791c3e00f0c82886779366704086871c484 --- /dev/null +++ b/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql @@ -0,0 +1,5 @@ +mutation ($calendars: [String]!) { + setCalendarStatus(calendars: $calendars) { + ok + } +} diff --git a/aleksis/core/frontend/components/calendar_feeds/details/BirthdaysDetails.vue b/aleksis/core/frontend/components/calendar_feeds/details/BirthdaysDetails.vue new file mode 100644 index 0000000000000000000000000000000000000000..f651ff2d11fa189b057b1adc6a613b288ae84604 --- /dev/null +++ b/aleksis/core/frontend/components/calendar_feeds/details/BirthdaysDetails.vue @@ -0,0 +1,24 @@ +<template> + <base-calendar-feed-details v-bind="$props" without-time> + <template #description="{ selectedEvent }"> + <v-divider /> + <v-card-text> + <span> + <v-icon class="mr-2">mdi-cake-variant-outline</v-icon> + {{ $d(selectedEvent.start) }} + </span> + </v-card-text> + </template> + </base-calendar-feed-details> +</template> + +<script> +import calendarFeedDetailsMixin from "../../../mixins/calendarFeedDetails.js"; +import BaseCalendarFeedDetails from "../../calendar/BaseCalendarFeedDetails.vue"; + +export default { + name: "BirthdaysDetails", + components: { BaseCalendarFeedDetails }, + mixins: [calendarFeedDetailsMixin], +}; +</script> diff --git a/aleksis/core/frontend/components/calendar_feeds/event_bar/BirthdaysEventBar.vue b/aleksis/core/frontend/components/calendar_feeds/event_bar/BirthdaysEventBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..d0f89cfae0695cba0033722dda8d66d5686205a6 --- /dev/null +++ b/aleksis/core/frontend/components/calendar_feeds/event_bar/BirthdaysEventBar.vue @@ -0,0 +1,17 @@ +<template> + <base-calendar-feed-event-bar + v-bind="$props" + icon="mdi-cake-variant-outline" + /> +</template> + +<script> +import calendarFeedEventBarMixin from "../../../mixins/calendarFeedEventBar.js"; +import BaseCalendarFeedEventBar from "../../calendar/BaseCalendarFeedEventBar.vue"; + +export default { + name: "BirthdaysEventBar", + components: { BaseCalendarFeedEventBar }, + mixins: [calendarFeedEventBarMixin], +}; +</script> diff --git a/aleksis/core/frontend/components/generic/ButtonMenu.vue b/aleksis/core/frontend/components/generic/ButtonMenu.vue index b105f84a8e1254f90bb1d78a2903c42f60cec29e..acc0990d050815c8bef8967aed93729c212f6f24 100644 --- a/aleksis/core/frontend/components/generic/ButtonMenu.vue +++ b/aleksis/core/frontend/components/generic/ButtonMenu.vue @@ -6,6 +6,7 @@ <v-icon center> {{ icon }} </v-icon> + <span v-if="textTranslationKey">{{ $t(textTranslationKey) }}</span> </v-btn> </slot> </template> @@ -25,6 +26,11 @@ export default { required: false, default: "mdi-dots-horizontal", }, + textTranslationKey: { + type: String, + required: false, + default: "", + }, }, }; </script> diff --git a/aleksis/core/frontend/components/generic/CopyToClipboardButton.vue b/aleksis/core/frontend/components/generic/CopyToClipboardButton.vue new file mode 100644 index 0000000000000000000000000000000000000000..f4c167229bb53e444696522e2643e73540536e99 --- /dev/null +++ b/aleksis/core/frontend/components/generic/CopyToClipboardButton.vue @@ -0,0 +1,67 @@ +<template> + <v-tooltip bottom :open-on-hover="hover" v-model="tooltipModel"> + <template #activator="{ on, attrs }"> + <v-layout wrap v-on="on" v-bind="attrs"> + <v-btn fab x-small icon @click.stop="copyToClipboard(text)"> + <v-scroll-x-transition mode="out-in"> + <v-icon :key="clipboardIcon"> + {{ clipboardIcon }} + </v-icon> + </v-scroll-x-transition> + </v-btn> + </v-layout> + </template> + <span>{{ tooltipText }}</span> + </v-tooltip> +</template> + +<script> +export default { + name: "CopyToClipboardButton", + data() { + return { + copied: false, + tooltipModel: false, + hover: true, + }; + }, + props: { + text: { + type: String, + required: true, + }, + tooltipHelpText: { + type: String, + default: "", + }, + }, + computed: { + tooltipText() { + return this.copied + ? this.$t("actions.copied") + : this.tooltipHelpText + ? this.tooltipHelpText + : this.$t("actions.copy"); + }, + clipboardIcon() { + return this.copied + ? "mdi-clipboard-check-outline" + : "mdi-clipboard-outline"; + }, + }, + methods: { + copyToClipboard(text) { + navigator.clipboard.writeText(text); + this.tooltipModel = false; + setTimeout(() => { + this.tooltipModel = this.copied = true; + this.hover = false; + setTimeout(() => { + this.tooltipModel = this.copied = false; + this.hover = true; + }, 1000); + }, 100); + }, + }, +}; +</script> diff --git a/aleksis/core/frontend/messages/de.json b/aleksis/core/frontend/messages/de.json index 207db33feb3d4b49edb79ebae96230df241fa8fd..dd143b42332ea754758c581b844eb1d44db74d9a 100644 --- a/aleksis/core/frontend/messages/de.json +++ b/aleksis/core/frontend/messages/de.json @@ -74,15 +74,20 @@ "actions": { "back": "Zurück", "cancel": "Abbrechen", + "clear_filters": "Filter zurücksetzen", "close": "Schließen", - "confirm_deletion": "Sind Sie sicher, dass sie dieses Objekt löschen wollen?", + "confirm_deletion": "Sind Sie sicher, dass Sie dieses Objekt löschen wollen?", + "confirm_deletion_multiple": "Sind Sie sicher, dass Sie diese Objekte löschen wollen?", + "create": "Hinzufügen", "delete": "Löschen", "edit": "Bearbeiten", + "filter": "Filter", "save": "Speichern", "search": "Suchen", + "select_action": "Aktion auswählen", "stop_editing": "Bearbeiten beenden", - "filter": "Filter", - "clear_filters": "Filter zurücksetzen" + "title": "Aktionen", + "update": "Aktualisieren" }, "administration": { "backend_admin": { @@ -135,8 +140,25 @@ "notice": "Wenn der Download nicht automatisch beginnt, klicken Sie bitte auf den Button unten.", "title": "PDF-Datei wird heruntergeladen ..." }, + "forms": { + "date_time": { + "date": "Datum", + "time": "Zeit" + }, + "errors": { + "invalid_color": "Dies ist keine gültige Farbe.", + "invalid_date": "Dies ist kein gültiges Datum.", + "invalid_time": "Dies ist keine gültige Zeit.", + "not_a_number": "Keine gültige Nummer", + "not_a_whole_number": "Bitte geben Sie eine ganze Zahl ein", + "number_too_big": "Bitte geben Sie eine kleinere Zahl ein.", + "number_too_small": "Bitte geben Sie eine größere Zahl ein.", + "required": "Dieses Feld ist verpflichtend." + } + }, "graphql": { - "snackbar_error_message": "Beim Abrufen der Seitendaten ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut." + "snackbar_error_message": "Beim Abrufen der Seitendaten ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.", + "snackbar_success_message": "Der Vorgang wurde erfolgreich beendet." }, "group": { "additional_field": { @@ -234,11 +256,27 @@ "menu_title": "Konfiguration" } }, + "rooms": { + "create_room": "Neuen Raum erstellen", + "menu_title": "Räume", + "name": "Name", + "short_name": "Kurzname", + "title_plural": "Räume" + }, "school_term": { + "after": "Endet nach", + "before": "Beginnt vor", + "create_school_term": "Schuljahr erstellen", + "date_end": "Enddatum", + "date_start": "Startdatum", "menu_title": "Schuljahre", + "name": "Name", "title": "Schuljahr", "title_plural": "Schuljahre" }, + "selection": { + "num_items_selected": "Keine Objekte ausgewählt | 1 Objekt ausgewählt | {n} Objekte ausgewählt" + }, "service_worker": { "dismiss": "Verwerfen", "new_version_available": "Es ist eine neue Version der App verfügbar", @@ -247,7 +285,20 @@ "status": { "changes": "Sie haben nicht gespeicherte Änderungen.", "error": "Beim Speichern der letzten Änderungen ist ein Fehler aufgetreten.", + "object_create_success": "Das Objekt wurde erfolgreich erstellt.", + "object_delete_success": "Das Objekt wurde erfolgreich gelöscht.", + "object_edit_success": "Das Objekt wurde erfolgreich bearbeitet.", + "objects_delete_success": "Die Objekte wurden erfolgreich gelöscht.", "saved": "Alle Änderungen sind gespeichert.", "updating": "Änderungen werden synchronisiert." + }, + "weekdays": { + "A_0": "Montag", + "A_1": "Dienstag", + "A_2": "Mittwoch", + "A_3": "Donnerstag", + "A_4": "Freitag", + "A_5": "Samstag", + "A_6": "Sonntag" } } diff --git a/aleksis/core/frontend/messages/en.json b/aleksis/core/frontend/messages/en.json index ceda00c3994bccf4fc2c7b5e9cb83fe5ec2d00d9..a477736639405a1005f8799ce09b6c88f45a95de 100644 --- a/aleksis/core/frontend/messages/en.json +++ b/aleksis/core/frontend/messages/en.json @@ -81,6 +81,10 @@ "confirm_deletion_multiple": "Are you sure you want to delete these items?", "delete": "Delete", "edit": "Edit", + "close": "Close", + "select_all": "Select all", + "copy": "Copy", + "copied": "Copied", "save": "Save", "search": "Search", "stop_editing": "Stop editing", @@ -252,6 +256,19 @@ "new_version_available": "A new version of the app is available", "update": "Update" }, + "calendar": { + "menu_title": "Calendar", + "month": "Month", + "week": "Week", + "day": "Day", + "today": "Today", + "select": "Select calendars", + "ics_to_clipboard": "Copy link to calendar ICS to clipboard", + "cancelled": "Cancelled", + "download_ics": "Download ICS", + "my_calendars": "My Calendars", + "download_all": "Download all" + }, "graphql": { "snackbar_error_message": "There was an error retrieving the page data. Please try again.", "snackbar_success_message": "The operation has been finished successfully." diff --git a/aleksis/core/frontend/messages/ru.json b/aleksis/core/frontend/messages/ru.json index 161a4efd7b2dafb90d0785a3a69b224dbe6827dd..ae08b69dc0fb154702bbceb2d87a2147497d5fd6 100644 --- a/aleksis/core/frontend/messages/ru.json +++ b/aleksis/core/frontend/messages/ru.json @@ -61,15 +61,26 @@ "email": "Мы отправим Вам одноразовые коды на Ñл.почту.", "generator": "Ð’Ñ‹ генерируете одноразовые коды Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ генератора кодов.", "sms": "Мы отправим Вам одноразовые коды на Ваш мобильный.", - "webauthn": "Ð’Ñ‹ иÑпользуете ключ безопаÑноÑти (как внешнее уÑтройÑтво или вÑтроенное в Ваше переноÑное уÑтройÑтво)." - } + "webauthn": "Ð’Ñ‹ иÑпользуете ключ безопаÑноÑти (как внешнее уÑтройÑтво или вÑтроенное в Ваше переноÑное уÑтройÑтво).", + "yubikey": "Ð’Ñ‹ иÑпользуете YubiKey Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ñ€Ð°Ð·Ð¾Ð²Ñ‹Ñ… кодов." + }, + "other_devices_description": "ЕÑли Ваш оÑновное уÑтройÑтво аутентификации будет недоÑтупно во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ…Ð¾Ð´Ð°, Ð’Ñ‹ можете воÑпользоватьÑÑ Ð¾Ð´Ð½Ð¸Ð¼ из Ñтих уÑтройÑтв:", + "other_devices_title": "Другие уÑтройÑтва аутентификации", + "primary_device_description": "Во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ…Ð¾Ð´Ð° в ÑиÑтему AlekSIS попроÑит Ð’Ð°Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚ÑŒ вход Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ñледующего уÑтройÑтва. ЕÑли Ñто уÑтройÑтво будет недоÑтупно, Ð’Ñ‹ Ñможете воÑпользоватьÑÑ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ñ‹Ð¼ уÑтройÑтвом.", + "primary_device_title": "ОÑновное уÑтройÑтво Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸", + "title": "Ð”Ð²ÑƒÑ…Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð°Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ" } }, "actions": { "back": "Ðазад", + "cancel": "Отменить", "close": "Закрыть", + "confirm_deletion": "Ð’Ñ‹ дейÑтвительно хотите удалить Ñтот объект?", + "delete": "Удалить", "edit": "Редактировать", - "search": "ПоиÑк" + "save": "Сохранить", + "search": "ПоиÑк", + "stop_editing": "Завершить редактирование" }, "administration": { "backend_admin": { @@ -167,6 +178,17 @@ "title": "Приложение OAuth2", "title_plural": "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ OAuth2" }, + "authorized_application": { + "access_since": "ДоÑтуп Ñ {date}", + "description": "У упомÑнутых Ñторонних приложений еÑÑ‚ÑŒ доÑтуп к Вашей учётной запиÑи. ДоÑтуп, в котором больше нет необходимоÑти или которому больше не доверÑете, можете отозвать в любой момент.", + "has_access_to": "Имеет доÑтуп к:", + "menu_title": "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¸Ñ… Ñторон", + "revoke": "Отозвать доÑтуп", + "revoke_question": "Ð’Ñ‹ дейÑтвительно хотите отозвать доÑтуп Ð´Ð»Ñ Ñтого приложениÑ?", + "subtitle": "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¸Ñ… Ñторон Ñ Ð´Ð¾Ñтупом к Вашему аккаунту", + "title": "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¸Ñ… Ñторон", + "valid_until": "ДейÑтвует до {date}" + }, "authorized_token": { "menu_title": "Ðвторизованные приложениÑ" } @@ -219,5 +241,11 @@ "dismiss": "ОтказатьÑÑ", "new_version_available": "ДоÑтупна Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹", "update": "Обновить" + }, + "status": { + "changes": "У Ð’Ð°Ñ ÐµÑÑ‚ÑŒ неÑохранённые изменениÑ.", + "error": "Во Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñледних изменений возникла ошибка.", + "saved": "Ð’Ñе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñохранены.", + "updating": "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑинхронизуютÑÑ." } } diff --git a/aleksis/core/frontend/mixins/calendarFeedDetails.js b/aleksis/core/frontend/mixins/calendarFeedDetails.js new file mode 100644 index 0000000000000000000000000000000000000000..0f729ba18355f7742d9080ea0188e8f3ba73e193 --- /dev/null +++ b/aleksis/core/frontend/mixins/calendarFeedDetails.js @@ -0,0 +1,52 @@ +/** + * Mixin for use with adaptable components showing details for calendar feeds. + */ +const calendarFeedDetailsMixin = { + props: { + selectedElement: { + required: false, + default: null, + }, + selectedEvent: { + required: true, + type: Object, + }, + value: { type: Boolean, required: true }, + withoutTime: { + required: false, + type: Boolean, + default: false, + }, + withoutDescription: { + required: false, + type: Boolean, + default: false, + }, + withoutBadge: { + required: false, + type: Boolean, + default: false, + }, + color: { + required: false, + type: String, + default: null, + }, + calendarType: { + required: true, + type: String, + }, + }, + computed: { + model: { + get() { + return this.value; + }, + set(value) { + this.$emit("input", value); + }, + }, + }, +}; + +export default calendarFeedDetailsMixin; diff --git a/aleksis/core/frontend/mixins/calendarFeedEventBar.js b/aleksis/core/frontend/mixins/calendarFeedEventBar.js new file mode 100644 index 0000000000000000000000000000000000000000..3b6590b0f68e75090b200bd0aa0fcc747cfdef51 --- /dev/null +++ b/aleksis/core/frontend/mixins/calendarFeedEventBar.js @@ -0,0 +1,21 @@ +/** + * Mixin for use with adaptable components showing event bar for calendar feeds. + */ +const calendarFeedEventBarMixin = { + props: { + event: { + required: true, + type: Object, + }, + eventParsed: { + required: true, + type: Object, + }, + calendarType: { + required: true, + type: String, + }, + }, +}; + +export default calendarFeedEventBarMixin; diff --git a/aleksis/core/frontend/routes.js b/aleksis/core/frontend/routes.js index 84b3612f33510940b97dd57fec5370e49c768d4c..b14cb40e77c84230a1555b296eda94d245df9cfb 100644 --- a/aleksis/core/frontend/routes.js +++ b/aleksis/core/frontend/routes.js @@ -8,7 +8,7 @@ // aleksisAppImporter is a virtual module defined in Vite config import { appObjects } from "aleksisAppImporter"; -import { notLoggedInValidator } from "./routeValidators"; +import { hasPersonValidator, notLoggedInValidator } from "./routeValidators"; const routes = [ { @@ -1049,6 +1049,18 @@ const routes = [ }, name: "invitations.accept_invite", }, + { + path: "/calendar/", + component: () => import("./components/calendar/CalendarOverview.vue"), + name: "core.calendar_overview", + meta: { + inMenu: true, + icon: "mdi-calendar", + titleKey: "calendar.menu_title", + toolbarTitle: "calendar.menu_title", + permission: "core.view_calendar_feed_rule", + }, + }, ]; // This imports all known AlekSIS app entrypoints diff --git a/aleksis/core/locale/ar/LC_MESSAGES/django.po b/aleksis/core/locale/ar/LC_MESSAGES/django.po index 7c475008f800e2ab26d51154f5050eb6a6e1dc32..bdff10b2b611efda26d4f27b80141942c30b1fa3 100644 --- a/aleksis/core/locale/ar/LC_MESSAGES/django.po +++ b/aleksis/core/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -42,8 +42,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 msgid "Groups" msgstr "" @@ -102,172 +102,172 @@ msgstr "" msgid "Content type" msgstr "" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 msgid "Address" msgstr "" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "" @@ -291,697 +291,744 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 msgid "Help text / description" msgstr "" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 msgid "Additional fields" msgstr "" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +msgid "Start date and time" +msgstr "" + +#: aleksis/core/models.py:1530 +msgid "End date and time" +msgstr "" + +#: aleksis/core/models.py:1531 +msgid "Timezone" +msgstr "" + +#: aleksis/core/models.py:1534 +msgid "Recurrences" +msgstr "" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +msgid "Calendar Event" +msgstr "" + +#: aleksis/core/models.py:1644 +msgid "Calendar Events" +msgstr "" + +#: aleksis/core/models.py:1670 +msgid "Birthdays" +msgstr "" + +#: aleksis/core/models.py:1674 +msgid "{}'s birthday" +msgstr "" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 msgid "Accounts" msgstr "" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 msgid "Authentication" msgstr "" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "" +#: aleksis/core/preferences.py:33 +msgid "Calendar" +msgstr "" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "" @@ -1155,7 +1202,15 @@ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" +msgid "Birthday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Activated calendars" msgstr "" #: aleksis/core/settings.py:551 @@ -1170,22 +1225,9 @@ msgstr "" msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" -msgstr "" - -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 -#: aleksis/core/templates/core/announcement/list.html:22 -msgid "Actions" -msgstr "" - -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 @@ -1193,6 +1235,11 @@ msgstr "" msgid "Delete" msgstr "" +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 +#: aleksis/core/templates/core/announcement/list.html:22 +msgid "Actions" +msgstr "" + #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1263,6 +1310,13 @@ msgstr "" msgid "Your AlekSIS team" msgstr "" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1495,6 +1549,12 @@ msgstr "" msgid "Recipients" msgstr "" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "" + #: aleksis/core/templates/core/announcement/list.html:50 msgid "There are no announcements." msgstr "" @@ -2043,17 +2103,6 @@ msgstr "" msgid "Selected persons" msgstr "" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -msgid "Create school term" -msgstr "" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "" @@ -2813,156 +2862,148 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "" - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "" - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "" -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "" -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "" -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "" -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "" -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "" -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1382 +#: aleksis/core/views.py:1352 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1465 +#: aleksis/core/views.py:1435 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "" diff --git a/aleksis/core/locale/de_DE/LC_MESSAGES/django.po b/aleksis/core/locale/de_DE/LC_MESSAGES/django.po index 549daede5b7b831b5f13648b3caa45f69e391e1b..672dca25a0db9d61b2e3f1fbab98f31ee96203ad 100644 --- a/aleksis/core/locale/de_DE/LC_MESSAGES/django.po +++ b/aleksis/core/locale/de_DE/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: 2023-05-09 18:45+0200\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" "Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-core/de/>\n" @@ -42,8 +42,8 @@ msgstr "E-Mail-Adresse" msgid "Home and mobile phone" msgstr "Festnetz- und Mobilfunknummer" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 msgid "Groups" msgstr "Gruppen" @@ -102,187 +102,172 @@ msgstr "Berechtigung" msgid "Content type" msgstr "Inhaltstyp" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "Benutzer" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "Gruppe" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "Basisdaten" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 msgid "Address" msgstr "Adresse" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 msgid "Contact data" msgstr "Kontaktdaten" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "Zusätzliche persönliche Daten" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "Neuer Benutzer" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "Create a new account" msgstr "Neues Benutzerkonto erstellen" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." -msgstr "" -"Sie können keine neuen Benutzer erstellen, wenn Sie gleichzeitig einen " -"existierenden Benutzer auswählen." +msgstr "Sie können keine neuen Benutzer erstellen, wenn Sie gleichzeitig einen existierenden Benutzer auswählen." -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Dieser Benutzername wird bereits genutzt." -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "Schuljahr" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "Allgemeine Daten" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 msgid "Persons" msgstr "Personen" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 msgid "Additional data" msgstr "Zusätzliche Daten" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "Foto" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "Datum" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "Zeit" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "Von wann bis wann soll die Ankündigung angezeigt werden?" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "Wer soll die Ankündigung sehen?" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "Schreiben Sie ihre Ankündigung:" -#: aleksis/core/forms.py:277 -msgid "" -"You are not allowed to create announcements which are only valid in the past." -msgstr "" -"Sie dürfen keine Ankündigungen erstellen, die nur für die Vergangenheit " -"gültig sind." +#: aleksis/core/forms.py:287 +msgid "You are not allowed to create announcements which are only valid in the past." +msgstr "Sie dürfen keine Ankündigungen erstellen, die nur für die Vergangenheit gültig sind." -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." -msgstr "" -"Das Startdatum und die Startzeit müssen vor dem Enddatum und der Endzeit " -"sein." +msgstr "Das Startdatum und die Startzeit müssen vor dem Enddatum und der Endzeit sein." -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "Sie benötigen mindestens einen Empfänger." -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "Einladungscode" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "Bitte geben Sie Ihren Einladungscode ein." -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "Vorname" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "Nachname" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "Eine Person nutzt diese E-Mail-Adresse" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "Wer soll die Berechtigung erhalten?" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "Auf was?" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" -msgstr "" -"Wählen Sie die Objekte aus, für welche die Berechtigung vergeben werden soll:" +msgstr "Wählen Sie die Objekte aus, für welche die Berechtigung vergeben werden soll:" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "Vergebe die Berechtigung für alle Objekte" -#: aleksis/core/forms.py:495 -msgid "" -"You must select at least one group or person which should get the permission." -msgstr "" -"Sie müssen mindestens eine Gruppe oder Person auswählen, welche die " -"Berechtigung erhalten soll." +#: aleksis/core/forms.py:504 +msgid "You must select at least one group or person which should get the permission." +msgstr "Sie müssen mindestens eine Gruppe oder Person auswählen, welche die Berechtigung erhalten soll." -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." -msgstr "" -"Sie müssen die Berechtigung auf alle Objekte oder für spezifische Objekte " -"vergeben." +msgstr "Sie müssen die Berechtigung auf alle Objekte oder für spezifische Objekte vergeben." -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "Adressdaten" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 msgid "Account data" msgstr "Kontodaten" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "Passwort" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "Passwort wiederholen" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "Die ausgewählte Aktion existiert nicht." -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." -msgstr "" -"Sie haben nicht die Berechtigung, {} auf alle ausgewählten Objekte " -"auszuführen." +msgstr "Sie haben nicht die Berechtigung, {} auf alle ausgewählten Objekte auszuführen." -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "Keine gültige Auswahl." @@ -306,706 +291,762 @@ msgstr "Kein Backup gefunden!" msgid "No backup result found!" msgstr "Kein Backupergebnis gefunden!" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "Zugeordnetes Schuljahr" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "Boolean (Ja/Nein)" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "Text (eine Zeile)" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "Datum und Uhrzeit" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "Dezimalzahl" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "E-Mail-Adresse" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "Ganze Zahl" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "IP-Adresse" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Boolean oder leer (Ja/Nein/weder)" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "Text (mehrzeilig)" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "URL / Link" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "Name" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "Startdatum" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "Enddatum" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "Das Startdatum muss vor dem Enddatum liegen." -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." -msgstr "" -"Es gibt bereits ein Schuljahr für diesen Zeitraum oder einen Teilzeitraum." +msgstr "Es gibt bereits ein Schuljahr für diesen Zeitraum oder einen Teilzeitraum." -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "Schuljahre" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "Person" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 msgid "Can view address" msgstr "Kann Adresse sehen" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 msgid "Can view contact details" msgstr "Kann Kontaktdetails sehen" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 msgid "Can view photo" msgstr "Kann Foto sehen" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "Kann Avatar-Bild sehen" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "Kann Gruppen einer Person sehen" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 msgid "Can view personal details" msgstr "Kann persönliche Daten sehen" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "weiblich" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "männlich" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "andere" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "Verknüpfter Benutzer" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "Zusätzliche Namen" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "Kurzname" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "Straße" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "Hausnummer" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "Postleitzahl" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "Ort" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "Festnetz" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "Handy" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "Geburtsdatum" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 msgid "Place of birth" msgstr "Geburtsort" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "Geschlecht" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 -msgid "" -"This is an official photo, used for official documents and for internal use " -"cases." -msgstr "" -"Dies ist ein offizielles Foto, genutzt für offizielle Dokumente und interne " -"Zwecke." +#: aleksis/core/models.py:234 aleksis/core/models.py:573 +msgid "This is an official photo, used for official documents and for internal use cases." +msgstr "Dies ist ein offizielles Foto, genutzt für offizielle Dokumente und interne Zwecke." -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "Bild/Avatar anzeigen" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "Dies ist ein Bild oder ein Avatar für die öffentliche Darstellung." -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "Erziehungsberechtigte / Eltern" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "Primärgruppe" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "Beschreibung" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "Feldtitel" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "Feldtyp" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "Pflichtfeld" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 msgid "Help text / description" msgstr "Hilfetext/Beschreibung" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "Zusätzliche Felder für Gruppen" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "Zusätzliche Felder für Gruppen" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "Kann Kindgruppen zu Gruppen zuordnen" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "Kann Statistiken über Gruppen sehen." -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "Langname" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "Mitglieder" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "Leiter/-innen" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "Ãœbergeordnete Gruppen" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "Gruppentyp" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 msgid "Additional fields" msgstr "Zusätzliche Felder" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Titel" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "Anwendung" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "Aktivität" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "Aktivitäten" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "Absender" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "Empfänger" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "Link" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Symbol" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "Benachrichtigung schicken am" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "Gelesen" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "Versandt" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "Benachrichtigung" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "Benachrichtigungen" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "Link zur detaillierten Ansicht" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "Datum und Uhrzeit des Anzeigestarts" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "Anzeigezeitraum" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "Ankündigung" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "Ankündigungen" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "Empfänger der Ankündigung" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "Empfänger der Ankündigung" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "Widget-Titel" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "Widget aktivieren" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "Widget ist kaputt" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "Größe auf Mobilgeräten" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "<= 600 px, 12 Spalten" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "Größe auf Tablets" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "> 600px, 12 Spalten" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "Größe auf Desktopgeräten" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "> 992 px, 12 Spalten" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "Größe auf großen Desktopgeräten" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "> 1200 px, 12 Spalten" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "Kann Standarddashboard bearbeiten" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "Dashboard-Widget" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "Dashboard-Widgets" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "URL" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "Symbol-URL" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "Externer-Link-Widget" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "Externer-Link-Widgets" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "Inhalt" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "Statischer-Inhalt-Widget" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "Statischer-Inhalt-Widgets" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "Dashboard-Widget" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "Reihenfolge" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "Teil des Standarddashboards" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "Reihenfolge der Dashboard-Widgets" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "Reihenfolgen der Dashboard-Widgets" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "Menü-ID" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "Benutzerdefiniertes Menü" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "Benutzerdefinierte Menüs" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "Menü" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "Benutzerdefiniertes Menüelement" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "Benutzerdefinierte Menüelemente" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "Titel des Typs" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 msgid "Group type" msgstr "Gruppentyp" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 msgid "Group types" msgstr "Gruppentypen" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 msgid "Can view system status" msgstr "Kann Systemstatus sehen" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "Kann Daten verwalten" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "Kann sich verkleiden" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "Kann Suche benutzen" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "Kann Konfiguration ändern" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "Kann Einstellungen einer Person verändern" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "Kann Einstellungen einer Gruppe verändern" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "Kann die PDF-Generierung testen" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "Kann Personen einladen" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "Zugehörige Datenprüfungsaufgabe" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "Problem gelöst" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "Benachrichtigung gesendet" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "Datenprüfungsergebnis" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "Datenprüfungsergebnisse" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "Kann Datenprüfungen ausführen" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "Kann Datenprüfungsprobleme lösen" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "E-Mail-Adresse" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "Leiter" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "Datei abgelaufen am" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "Generierte HTML-Datei" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "Generierte PDF-Datei" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "PDF-Datei" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "PDF-Dateien" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "Task-Ergebnis" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "Task-Benutzer" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "Zurück-URL" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "Fortschritt-Titel" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "Fehlernachricht" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "Erfolgsnachricht" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "URL, auf die bei Erfolg weitergeleitet wird" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 msgid "Additional button title" msgstr "Titel des zusätzlichen Buttons" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "URL des zusätzlichen Buttons" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "Symbol des zusätzlichen Buttons" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "Ergebnis abgerufen" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "Hintergrundaufgabe erfolgreich fertiggestellt" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "Die Hintergrundaufgabe '{}' wurde erfolgreich fertiggestellt." -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "Hintergrundaufgabe fehlgeschlagen" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "Die Hintergrundaufgabe '{}' ist fehlgeschlagen." -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "Hintergrundaufgabe" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "Task-Benutzer-Zuordnung" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "Task-Benutzer-Zuordnungen" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "Zusätzliche Attribute" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "Erlaubte Scopes, die ein Client anfordern kann" -#: aleksis/core/models.py:1433 -msgid "" -"This image will be shown as icon in the authorization flow. It should be " -"squared." -msgstr "" -"Dieses Bild wird im Autorisierungs-Vorgang als Symbol angezeigt werden. Es " -"sollte rechteckig sein." +#: aleksis/core/models.py:1455 +msgid "This image will be shown as icon in the authorization flow. It should be squared." +msgstr "Dieses Bild wird im Autorisierungs-Vorgang als Symbol angezeigt werden. Es sollte rechteckig sein." -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "Kann Raum-Stundenplan sehen" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "Raum" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "Räume" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +#, fuzzy +#| msgid "Date and time" +msgid "Start date and time" +msgstr "Datum und Uhrzeit" + +#: aleksis/core/models.py:1530 +#, fuzzy +#| msgid "Date and time" +msgid "End date and time" +msgstr "Datum und Uhrzeit" + +#: aleksis/core/models.py:1531 +#, fuzzy +#| msgid "Time" +msgid "Timezone" +msgstr "Zeit" + +#: aleksis/core/models.py:1534 +#, fuzzy +#| msgid "Preferences" +msgid "Recurrences" +msgstr "Einstellungen" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +#, fuzzy +#| msgid "Calendar Feeds" +msgid "Calendar Event" +msgstr "Kalender-Feeds" + +#: aleksis/core/models.py:1644 +#, fuzzy +#| msgid "Calendar Feeds" +msgid "Calendar Events" +msgstr "Kalender-Feeds" + +#: aleksis/core/models.py:1670 +#, fuzzy +#| msgid "Birthday Calendar" +msgid "Birthdays" +msgstr "Geburtstagskalender" + +#: aleksis/core/models.py:1674 +#, fuzzy +#| msgid "%(name)s's birthday" +msgid "{}'s birthday" +msgstr "%(name)ss Geburtstag" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "Allgemein" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "Schule" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "Theme" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "E-Mail" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "Fußbereich" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 msgid "Accounts" msgstr "Konten" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 msgid "Authentication" msgstr "Authentifizierung" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "Internationalisierung" +#: aleksis/core/preferences.py:33 +#, fuzzy +#| msgid "Calendar Feeds" +msgid "Calendar" +msgstr "Kalender-Feeds" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "Seitentitel" @@ -1083,11 +1124,8 @@ msgid "Automatically create new persons for new users" msgstr "Erstelle automatisch neue Personen für neue Benutzer" #: aleksis/core/preferences.py:256 -msgid "" -"Automatically link existing persons to new users by their e-mail address" -msgstr "" -"Verknüpfe existierende Personen automatisch mit neuen Personen anhand ihrer " -"E-Mail-Adresse" +msgid "Automatically link existing persons to new users by their e-mail address" +msgstr "Verknüpfe existierende Personen automatisch mit neuen Personen anhand ihrer E-Mail-Adresse" #: aleksis/core/preferences.py:267 msgid "Display name of the school" @@ -1095,8 +1133,7 @@ msgstr "Sichtbarer Name der Schule" #: aleksis/core/preferences.py:278 msgid "Official name of the school, e.g. as given by supervisory authority" -msgstr "" -"Offizieller Name der Schule, wie er z.B. von der Behörde vorgegeben ist" +msgstr "Offizieller Name der Schule, wie er z.B. von der Behörde vorgegeben ist" #: aleksis/core/preferences.py:286 msgid "Allow users to change their passwords" @@ -1155,11 +1192,8 @@ msgid "Fields on person model which are editable by themselves." msgstr "Felder des Personen-Models welche von ihnen selbst editierbar sind." #: aleksis/core/preferences.py:424 -msgid "" -"Editable fields on person model which should trigger a notification on change" -msgstr "" -"Editierbare Felder des Personen-Models welche eine Benachrichtigung für " -"Änderungen auslösen soll" +msgid "Editable fields on person model which should trigger a notification on change" +msgstr "Editierbare Felder des Personen-Models welche eine Benachrichtigung für Änderungen auslösen soll" #: aleksis/core/preferences.py:438 msgid "Contact for notification if a person changes their data" @@ -1183,13 +1217,23 @@ msgstr "Automatisch das Dashboard und seine Widgets aktualisieren" #: aleksis/core/preferences.py:480 msgid "Automatically update the dashboard and its widgets sitewide" -msgstr "" -"Automatisch das Dashboard und seine Widgets aktualisieren (auf der ganzen " -"Seite)" +msgstr "Automatisch das Dashboard und seine Widgets aktualisieren (auf der ganzen Seite)" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" -msgstr "Land für das Einlesen von Telefonnummern" +#, fuzzy +#| msgid "Birthday Calendar" +msgid "Birthday calendar feed color" +msgstr "Geburtstagskalender" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +#, fuzzy +#| msgid "Birthday Calendar" +msgid "Activated calendars" +msgstr "Geburtstagskalender" #: aleksis/core/settings.py:551 msgid "English" @@ -1203,22 +1247,9 @@ msgstr "Deutsch" msgid "Ukrainian" msgstr "Ukrainisch" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" -msgstr "Bearbeiten" - -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 -#: aleksis/core/templates/core/announcement/list.html:22 -msgid "Actions" -msgstr "Aktionen" - -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 @@ -1226,6 +1257,11 @@ msgstr "Aktionen" msgid "Delete" msgstr "Löschen" +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 +#: aleksis/core/templates/core/announcement/list.html:22 +msgid "Actions" +msgstr "Aktionen" + #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1242,14 +1278,12 @@ msgstr "" #: aleksis/core/templates/403.html:19 aleksis/core/templates/404.html:16 msgid "" "\n" -" If you think this is an error in AlekSIS, please contact your " -"site\n" +" If you think this is an error in AlekSIS, please contact your site\n" " administrators:\n" " " msgstr "" "\n" -" Wenn Sie der Meinung sind, dass es sich um einen Fehler in " -"AlekSIS handelt, kontaktieren Sie bitte einen Ihrer\n" +" Wenn Sie der Meinung sind, dass es sich um einen Fehler in AlekSIS handelt, kontaktieren Sie bitte einen Ihrer\n" " Systemadministratoren:\n" " " @@ -1261,8 +1295,7 @@ msgid "" " " msgstr "" "\n" -" Wenn Sie über einen Link auf einer externen Seite hierher " -"gelangt sind,\n" +" Wenn Sie über einen Link auf einer externen Seite hierher gelangt sind,\n" " ist es möglich, dass dieser veraltet war.\n" " " @@ -1277,14 +1310,12 @@ msgstr "" #: aleksis/core/templates/500.html:13 msgid "" "\n" -" Your site administrators will automatically be notified about " -"this\n" +" Your site administrators will automatically be notified about this\n" " error. You can also contact them directly:\n" " " msgstr "" "\n" -" Ihre Administratoren werden automatisch über diesen Fehler " -"informiert.\n" +" Ihre Administratoren werden automatisch über diesen Fehler informiert.\n" " Sie können diese auch direkt kontaktieren:\n" " " @@ -1321,6 +1352,13 @@ msgstr "Hallo!" msgid "Your AlekSIS team" msgstr "Ihr AlekSIS-Team" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1330,21 +1368,13 @@ msgstr "Bestätigen" #: aleksis/core/templates/account/email_confirm.html:12 #, python-format -msgid "" -"Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail " -"address for user %(user_display)s." -msgstr "" -"Bitte bestätigen Sie, dass <a href=\"mailto:%(email)s\">%(email)s</a> eine E-" -"Mail-Adresse für den Benutzer %(user_display)s ist." +msgid "Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail address for user %(user_display)s." +msgstr "Bitte bestätigen Sie, dass <a href=\"mailto:%(email)s\">%(email)s</a> eine E-Mail-Adresse für den Benutzer %(user_display)s ist." #: aleksis/core/templates/account/email_confirm.html:25 #, python-format -msgid "" -"This e-mail confirmation link expired or is invalid. Please <a " -"href=\"%(email_url)s\">issue a new e-mail confirmation request</a>." -msgstr "" -"Dieser E-Mail-Bestätigungslink ist abgelaufen oder nicht gültig. Bitte <a " -"href=\"%(email_url)s\">fragen Sie eine neue E-Mail-Bestätigung an</a>." +msgid "This e-mail confirmation link expired or is invalid. Please <a href=\"%(email_url)s\">issue a new e-mail confirmation request</a>." +msgstr "Dieser E-Mail-Bestätigungslink ist abgelaufen oder nicht gültig. Bitte <a href=\"%(email_url)s\">fragen Sie eine neue E-Mail-Bestätigung an</a>." #: aleksis/core/templates/account/password_change.html:5 #: aleksis/core/templates/account/password_change.html:6 @@ -1359,9 +1389,7 @@ msgstr "Passwort ändern" #: aleksis/core/templates/account/password_change.html:12 msgid "Forgot your current password? Click here to reset it:" -msgstr "" -"Haben Sie Ihr aktuelles Passwort vergessen? Klicken Sie hier, um es " -"zurückzusetzen:" +msgstr "Haben Sie Ihr aktuelles Passwort vergessen? Klicken Sie hier, um es zurückzusetzen:" #: aleksis/core/templates/account/password_change.html:12 msgid "Forgot Password?" @@ -1380,13 +1408,11 @@ msgstr "Passwortänderung deaktiviert." msgid "" "\n" " Users are not allowed to edit their own passwords. If you think\n" -" this is an error please contact one of your site " -"administrators.\n" +" this is an error please contact one of your site administrators.\n" " " msgstr "" "\n" -" Benutzer dürfen ihre eigenen Passwörter nicht ändern. Wenn Sie " -"denken, \n" +" Benutzer dürfen ihre eigenen Passwörter nicht ändern. Wenn Sie denken, \n" "dass dies ein Fehler ist, kontaktieren Sie bitte einen der Administratoren:\n" " " @@ -1401,12 +1427,8 @@ msgid "Reset password" msgstr "Passwort zurücksetzen" #: aleksis/core/templates/account/password_reset.html:17 -msgid "" -"Forgotten your password? Enter your e-mail address below, and we'll send you " -"an e-mail allowing you to reset it." -msgstr "" -"Passwort vergessen? Geben Sie Ihre E-Mail-Adresse hier ein und wir werden " -"Ihnen eine E-Mail zum Zurücksetzen des Passwortes schicken." +msgid "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." +msgstr "Passwort vergessen? Geben Sie Ihre E-Mail-Adresse hier ein und wir werden Ihnen eine E-Mail zum Zurücksetzen des Passwortes schicken." #: aleksis/core/templates/account/password_reset.html:30 msgid "" @@ -1429,8 +1451,7 @@ msgid "" " " msgstr "" "\n" -" Wir haben Ihnen eine E-Mail gesendet. Bitte kontaktieren Sie " -"einen der Administratoren,\n" +" Wir haben Ihnen eine E-Mail gesendet. Bitte kontaktieren Sie einen der Administratoren,\n" "wenn Sie diese nicht innerhalb weniger Minuten erhalten.\n" " " @@ -1442,16 +1463,12 @@ msgstr "Ungültiges Token" #, python-format msgid "" "\n" -" The password reset link was invalid, possibly because it has " -"already been used. Please request a <a href=\"%(passwd_reset_url)s\"\n" +" The password reset link was invalid, possibly because it has already been used. Please request a <a href=\"%(passwd_reset_url)s\"\n" " class=\"blue-text text-lighten-2\">new password reset</a>.\n" " " msgstr "" "\n" -" Der Link zum Zurücksetzen des Passwortes war falsch, " -"wahrscheinlich, weil er bereits benutzt wurde. Bitte starten Sie eine neue " -"Anfrage <a href=\"%(passwd_reset_url)s\" class=\"blue-text text-" -"lighten-2\">zum Zurücksetzen des Passwortes</a>.\n" +" Der Link zum Zurücksetzen des Passwortes war falsch, wahrscheinlich, weil er bereits benutzt wurde. Bitte starten Sie eine neue Anfrage <a href=\"%(passwd_reset_url)s\" class=\"blue-text text-lighten-2\">zum Zurücksetzen des Passwortes</a>.\n" " " #: aleksis/core/templates/account/password_reset_from_key.html:25 @@ -1500,11 +1517,8 @@ msgstr "Registrierung" #: aleksis/core/templates/account/signup.html:12 #, python-format -msgid "" -"Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>." -msgstr "" -"Haben Sie bereits ein Konto? Dann <a href=\"%(login_url)s\">melden Sie sich " -"bitte an</a>." +msgid "Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>." +msgstr "Haben Sie bereits ein Konto? Dann <a href=\"%(login_url)s\">melden Sie sich bitte an</a>." #: aleksis/core/templates/account/signup.html:22 #: aleksis/core/templates/socialaccount/signup.html:23 @@ -1528,8 +1542,7 @@ msgid "" " " msgstr "" "\n" -" Die Registrierung ist aktuell geschlossen. Wenn Sie denken, dass " -"dies ein Fehler ist,\n" +" Die Registrierung ist aktuell geschlossen. Wenn Sie denken, dass dies ein Fehler ist,\n" " kontaktieren Sie bitte einen Ihrer Systemadministratoren.\n" " " @@ -1549,17 +1562,13 @@ msgstr "Verifizieren Sie Ihre E-Mail!" #: aleksis/core/templates/account/verification_sent.html:16 msgid "" "\n" -" This part of the site requires us to verify that you are who you " -"claim to be.\n" -" For this purpose, we require that you verify ownership of your e-" -"mail address.\n" +" This part of the site requires us to verify that you are who you claim to be.\n" +" For this purpose, we require that you verify ownership of your e-mail address.\n" " " msgstr "" "\n" -" Dieser Teil der Anwendung setzt voraus, dass wir verifizieren, " -"dass Sie die Person sind, die sie vorgeben, zu sein.\n" -"Zu diesem Zweck setzen wir voraus, dass Sie die Inhaberschaft Ihrer E-Mail-" -"Adresse bestätigen.\n" +" Dieser Teil der Anwendung setzt voraus, dass wir verifizieren, dass Sie die Person sind, die sie vorgeben, zu sein.\n" +"Zu diesem Zweck setzen wir voraus, dass Sie die Inhaberschaft Ihrer E-Mail-Adresse bestätigen.\n" " " #: aleksis/core/templates/account/verification_sent.html:22 @@ -1573,8 +1582,7 @@ msgstr "" "\n" " Wir haben Ihnen eine E-Mail zur Verifizierung geschickt.\n" "Bitte klicken Sie auf den Link in dieser E-Mail.\n" -"Bitte kontaktieren Sie uns, wenn Sie diese nicht binnen weniger Minuten " -"erhalten.\n" +"Bitte kontaktieren Sie uns, wenn Sie diese nicht binnen weniger Minuten erhalten.\n" " " #: aleksis/core/templates/core/additional_field/edit.html:6 @@ -1616,6 +1624,12 @@ msgstr "Gültig bis" msgid "Recipients" msgstr "Empfänger" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "Bearbeiten" + #: aleksis/core/templates/core/announcement/list.html:50 msgid "There are no announcements." msgstr "Es gibt aktuell keine Ankündigungen." @@ -1643,8 +1657,7 @@ msgid "" " " msgstr "" "\n" -" Es ist ein Problem dabei aufgetreten, das Widget \"%(title)s\" " -"zu laden.\n" +" Es ist ein Problem dabei aufgetreten, das Widget \"%(title)s\" zu laden.\n" "Sie brauchen nichts weiter machen.\n" " " @@ -1750,42 +1763,29 @@ msgstr "Dashboard bearbeiten" #: aleksis/core/templates/core/edit_dashboard.html:24 msgid "" "\n" -" On this page you can arrange your personal dashboard. You can drag " -"any items from \"Available widgets\" to \"Your\n" -" Dashboard\" or change the order by moving the widgets. After you " -"have finished, please don't forget to click on\n" +" On this page you can arrange your personal dashboard. You can drag any items from \"Available widgets\" to \"Your\n" +" Dashboard\" or change the order by moving the widgets. After you have finished, please don't forget to click on\n" " \"Save\".\n" " " msgstr "" "\n" -" Auf dieser Seite können Sie Ihr persönliches Dashboard " -"zusammenstallen. Sie können beliebige Elemente von den \"Verfügbaren " -"Widgets\" \n" -"in \"Ihr Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die " -"Widgets bewegen. Wenn Sie fertig sind, vergessen Sie bitte nicht, \n" +" Auf dieser Seite können Sie Ihr persönliches Dashboard zusammenstallen. Sie können beliebige Elemente von den \"Verfügbaren Widgets\" \n" +"in \"Ihr Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die Widgets bewegen. Wenn Sie fertig sind, vergessen Sie bitte nicht, \n" "auf \"Speichern\" zu drücken.\n" " " #: aleksis/core/templates/core/edit_dashboard.html:30 msgid "" "\n" -" On this page you can arrange the default dashboard which is shown " -"when a user doesn't arrange his own\n" -" dashboard. You can drag any items from \"Available widgets\" to " -"\"Default Dashboard\" or change the order\n" -" by moving the widgets. After you have finished, please don't " -"forget to click on \"Save\".\n" +" On this page you can arrange the default dashboard which is shown when a user doesn't arrange his own\n" +" dashboard. You can drag any items from \"Available widgets\" to \"Default Dashboard\" or change the order\n" +" by moving the widgets. After you have finished, please don't forget to click on \"Save\".\n" " " msgstr "" "\n" -" Auf dieser Seite können Sie Ihr das Standard-Dashboard " -"zusammenstallen, welches angezeigt wird, wenn ein Benutzer kein eigenes " -"definiert. \n" -"Sie können beliebige Elemente von den \"Verfügbaren Widgets\" in \"Standard-" -"Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die Widgets " -"bewegen. \n" -"Wenn Sie fertig sind, vergessen Sie bitte nicht, auf \"Speichern\" zu " -"drücken.\n" +" Auf dieser Seite können Sie Ihr das Standard-Dashboard zusammenstallen, welches angezeigt wird, wenn ein Benutzer kein eigenes definiert. \n" +"Sie können beliebige Elemente von den \"Verfügbaren Widgets\" in \"Standard-Dashboard\" ziehen oder die Reihenfolge verändern, indem Sie die Widgets bewegen. \n" +"Wenn Sie fertig sind, vergessen Sie bitte nicht, auf \"Speichern\" zu drücken.\n" " " #: aleksis/core/templates/core/edit_dashboard.html:48 @@ -1808,15 +1808,12 @@ msgstr "Kindgruppen zu Gruppen zuordnen" #: aleksis/core/templates/core/group/child_groups.html:18 msgid "" "\n" -" You can use this to assign child groups to groups. Please use the " -"filters below to select groups you want to\n" +" You can use this to assign child groups to groups. Please use the filters below to select groups you want to\n" " change and click \"Next\".\n" " " msgstr "" "\n" -" Sie können diese Seite verwenden, um Kindgruppen zu Gruppen " -"zuzuordnen. Bitte nutzen Sie die folgenden Filter, um die Gruppen " -"auszuwählen, die Sie \n" +" Sie können diese Seite verwenden, um Kindgruppen zu Gruppen zuzuordnen. Bitte nutzen Sie die folgenden Filter, um die Gruppen auszuwählen, die Sie \n" " ändern möchten und klicken auf \"Weiter\".\n" " " @@ -1857,18 +1854,14 @@ msgstr "Bitte seien Sie vorsichtig!" #: aleksis/core/templates/core/group/child_groups.html:79 msgid "" "\n" -" If you click \"Back\" or \"Next\" the current group assignments " -"are not saved.\n" -" If you click \"Save\", you will overwrite all existing child " -"group relations for this group with what you\n" +" If you click \"Back\" or \"Next\" the current group assignments are not saved.\n" +" If you click \"Save\", you will overwrite all existing child group relations for this group with what you\n" " selected on this page.\n" " " msgstr "" "\n" -" Wenn Sie auf \"Zurück\" oder \"Weiter\" klicken, werden die " -"aktuellen Gruppenzuordnungen nicht gespeichert.\n" -"Wenn Sie auf \"Speichern\" klicken, werden alle existierenden Zuordnungen " -"von Kindgruppen für diese Gruppe\n" +" Wenn Sie auf \"Zurück\" oder \"Weiter\" klicken, werden die aktuellen Gruppenzuordnungen nicht gespeichert.\n" +"Wenn Sie auf \"Speichern\" klicken, werden alle existierenden Zuordnungen von Kindgruppen für diese Gruppe\n" "mit dem überschrieben, was Sie auf dieser Seite ausgewählt haben.\n" " " @@ -1966,16 +1959,13 @@ msgstr "Startseite" #: aleksis/core/templates/core/index.html:34 msgid "" "\n" -" You didn't customise your dashboard so that you see the system " -"default. Please click on \"Edit dashboard\" to\n" +" You didn't customise your dashboard so that you see the system default. Please click on \"Edit dashboard\" to\n" " customise your personal dashboard.\n" " " msgstr "" "\n" -" Sie haben Ihr Dashboard nicht angepasst, sodass Sie das Standard-" -"Dashboard sehen.\n" -"Bitte klicken Sie auf \"Dashboard bearbeiten\", um Ihr persönliches " -"Dashboard anzupassen.\n" +" Sie haben Ihr Dashboard nicht angepasst, sodass Sie das Standard-Dashboard sehen.\n" +"Bitte klicken Sie auf \"Dashboard bearbeiten\", um Ihr persönliches Dashboard anzupassen.\n" " " #: aleksis/core/templates/core/index.html:44 @@ -2018,13 +2008,11 @@ msgstr "Wartungsmodus aktiviert" #: aleksis/core/templates/core/pages/system_status.html:28 msgid "" "\n" -" Only admin and visitors from internal IPs can access the " -"site.\n" +" Only admin and visitors from internal IPs can access the site.\n" " " msgstr "" "\n" -" Nur Administratoren und Besucher von internen IP-Adressen " -"können die Seite aufrufen.\n" +" Nur Administratoren und Besucher von internen IP-Adressen können die Seite aufrufen.\n" " " #: aleksis/core/templates/core/pages/system_status.html:39 @@ -2042,13 +2030,11 @@ msgstr "Debug-Modus aktiviert" #: aleksis/core/templates/core/pages/system_status.html:53 msgid "" "\n" -" The web server throws back debug information on errors. Do " -"not use in production!\n" +" The web server throws back debug information on errors. Do not use in production!\n" " " msgstr "" "\n" -" Der Server gibt Debug-Informationen bei Fehlern zurück. " -"Nicht im Produktivbetrieb nutzen!\n" +" Der Server gibt Debug-Informationen bei Fehlern zurück. Nicht im Produktivbetrieb nutzen!\n" " " #: aleksis/core/templates/core/pages/system_status.html:60 @@ -2058,13 +2044,11 @@ msgstr "Debug-Modus deaktivert" #: aleksis/core/templates/core/pages/system_status.html:62 msgid "" "\n" -" Debug mode is disabled. Default error pages are displayed on " -"errors.\n" +" Debug mode is disabled. Default error pages are displayed on errors.\n" " " msgstr "" "\n" -" Debug-Modus ist deaktiviert. Standard-Fehlerseiten werden " -"bei Fehlern angezeigt.\n" +" Debug-Modus ist deaktiviert. Standard-Fehlerseiten werden bei Fehlern angezeigt.\n" " " #: aleksis/core/templates/core/pages/system_status.html:75 @@ -2114,13 +2098,11 @@ msgstr "PDF-Generierung testen" #: aleksis/core/templates/core/pages/test_pdf.html:14 msgid "" "\n" -" This simple view can be used to ensure the correct function of the " -"built-in PDF generation system.\n" +" This simple view can be used to ensure the correct function of the built-in PDF generation system.\n" " " msgstr "" "\n" -" Diese einfache Seite kann genutzt werden, um die korrekte " -"Funktionalität des eingebauten PDF-Generierungssystem zu testen.\n" +" Diese einfache Seite kann genutzt werden, um die korrekte Funktionalität des eingebauten PDF-Generierungssystem zu testen.\n" " " #: aleksis/core/templates/core/partials/announcements.html:8 @@ -2178,13 +2160,11 @@ msgstr "Unbekannt" #: aleksis/core/templates/core/partials/splash_screen.html:11 msgid "" "\n" -" This webbrowser doesn't support JavaScript, or its execution is " -"blocked. Please use another browser to continue.\n" +" This webbrowser doesn't support JavaScript, or its execution is blocked. Please use another browser to continue.\n" " " msgstr "" "\n" -" Dieser Webbrowser unterstützt kein JavaScript oder die Ausführung " -"wurde blockiert. Bitte nutzen Sie einen anderen Browser, um fortzufahren.\n" +" Dieser Webbrowser unterstützt kein JavaScript oder die Ausführung wurde blockiert. Bitte nutzen Sie einen anderen Browser, um fortzufahren.\n" " " #: aleksis/core/templates/core/partials/splash_screen.html:17 @@ -2194,8 +2174,7 @@ msgid "" " " msgstr "" "\n" -" Der Wartungsmodus ist aktuell aktiviert. Bitte versuchen Sie es später " -"erneut.\n" +" Der Wartungsmodus ist aktuell aktiviert. Bitte versuchen Sie es später erneut.\n" " " #: aleksis/core/templates/core/perms/assign.html:12 @@ -2267,17 +2246,6 @@ msgstr "Personen filtern" msgid "Selected persons" msgstr "Ausgewählte Personen" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -msgid "Create school term" -msgstr "Schuljahr erstellen" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "Schuljahr bearbeiten" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "Einstellungen" @@ -2308,12 +2276,8 @@ msgid "The invite feature is disabled." msgstr "Die Einladungsfunktion ist deaktiviert." #: aleksis/core/templates/invitations/disabled.html:15 -msgid "" -"To enable it, switch on the corresponding checkbox in the authentication " -"section of the " -msgstr "" -"Um sie zu aktivieren, nutzen Sie die Checkbox im Abschnitt " -"\"Authentifikation\" der " +msgid "To enable it, switch on the corresponding checkbox in the authentication section of the " +msgstr "Um sie zu aktivieren, nutzen Sie die Checkbox im Abschnitt \"Authentifikation\" der " #: aleksis/core/templates/invitations/disabled.html:16 msgid "site preferences page" @@ -2461,17 +2425,13 @@ msgstr "Keine Verbindung zum Server." #: aleksis/core/templates/offline.html:14 msgid "" "\n" -" This page is not available without a connection to the server. Please " -"check your internet connection and try again.\n" -" If you are connected and the error persists, please contact the system " -"administrators:\n" +" This page is not available without a connection to the server. Please check your internet connection and try again.\n" +" If you are connected and the error persists, please contact the system administrators:\n" " " msgstr "" "\n" -" Diese Seite ist ohne eine Verbindung zum Server nicht verfügbar. Bitte " -"prüfen Sie Ihre Internetverbindung und probieren Sie es erneut.\n" -" Wenn Sie verbunden sind und der Fehler weiterhin auftritt, " -"kontaktieren Sie bitte die Systemadministratoren:\n" +" Diese Seite ist ohne eine Verbindung zum Server nicht verfügbar. Bitte prüfen Sie Ihre Internetverbindung und probieren Sie es erneut.\n" +" Wenn Sie verbunden sind und der Fehler weiterhin auftritt, kontaktieren Sie bitte die Systemadministratoren:\n" " " #: aleksis/core/templates/search/search.html:8 @@ -2506,14 +2466,12 @@ msgstr "Anmeldung über Drittanbieter-Konto fehlgeschlagen." #: aleksis/core/templates/socialaccount/authentication_error.html:15 msgid "" "\n" -" An error occurred while attempting to login via your third-party " -"account.\n" +" An error occurred while attempting to login via your third-party account.\n" " Please contact one of your site administrators.\n" " " msgstr "" "\n" -" Beim dem Versuch, die Anmeldung über Ihr Drittanbieter-Konto " -"durchzuführen, ist ein Fehler aufgetreten.\n" +" Beim dem Versuch, die Anmeldung über Ihr Drittanbieter-Konto durchzuführen, ist ein Fehler aufgetreten.\n" " Kontaktieren Sie bitte einen Ihrer Systemadministratoren:\n" " " @@ -2528,8 +2486,7 @@ msgstr "Löschen" #: aleksis/core/templates/socialaccount/connections.html:34 msgid "You currently have no third-party accounts connected to this account." -msgstr "" -"Sie haben aktuell keine Drittanbieter-Konten mit Ihrem Konto verbunden." +msgstr "Sie haben aktuell keine Drittanbieter-Konten mit Ihrem Konto verbunden." #: aleksis/core/templates/socialaccount/connections.html:37 msgid "Add a Third-party Account" @@ -2538,15 +2495,12 @@ msgstr "Ein Drittanbieter-Konto hinzufügen" #: aleksis/core/templates/socialaccount/login.html:12 #, python-format msgid "You are about to connect a new third party account from %(provider)s." -msgstr "" -"Sie sind dabei, ein neues Drittanbieterkonto von %(provider)s zu verbinden." +msgstr "Sie sind dabei, ein neues Drittanbieterkonto von %(provider)s zu verbinden." #: aleksis/core/templates/socialaccount/login.html:23 #, python-format msgid "You are about to sign in using a third party account from %(provider)s." -msgstr "" -"Sie sind dabei, sich mit einem Drittanbieterkonto von %(provider)s " -"anzumelden." +msgstr "Sie sind dabei, sich mit einem Drittanbieterkonto von %(provider)s anzumelden." #: aleksis/core/templates/socialaccount/login.html:28 msgid "Continue" @@ -2562,15 +2516,11 @@ msgstr "Login abgebrochen" #, python-format msgid "" "\n" -" You decided to cancel logging in to our site using one of your " -"existing accounts. If this was a mistake, please proceed to <a " -"href=\"%(login_url)s\">sign in</a>.\n" +" You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to <a href=\"%(login_url)s\">sign in</a>.\n" " " msgstr "" "\n" -" Sie haben sich entschieden, die Anmeldung mit einem Ihrer " -"bestehenden Konten bei uns abzubrechen. Wenn dies ein Fehler war, <a " -"href=\"%(login_url)s\">fahren Sie bitte mit dem Login fort</a>.\n" +" Sie haben sich entschieden, die Anmeldung mit einem Ihrer bestehenden Konten bei uns abzubrechen. Wenn dies ein Fehler war, <a href=\"%(login_url)s\">fahren Sie bitte mit dem Login fort</a>.\n" " " #: aleksis/core/templates/socialaccount/signup.html:12 @@ -2579,8 +2529,7 @@ msgid "" "You are about to use your %(provider_name)s account to login to\n" " %(site_name)s. As a final step, please complete the following form:" msgstr "" -"Sie sind dabei, Ihr %(provider_name)s-Konto zur Anmeldung bei %(site_name)s " -"zu nutzen. \n" +"Sie sind dabei, Ihr %(provider_name)s-Konto zur Anmeldung bei %(site_name)s zu nutzen. \n" "Als ein letzter Schritt vervollständigen Sie bitte das folgende Formular:" #: aleksis/core/templates/socialaccount/snippets/provider_list.html:12 @@ -2630,8 +2579,7 @@ msgstr "Celery-Task %(task_name)s fehlgeschlagen!" #: aleksis/core/templates/templated_email/celery_failure.email:7 #, python-format msgid "the celery task %(task_name)s failed with following information:" -msgstr "" -"der Celery-Task %(task_name)s ist mit folgenden Informationen fehlgeschlagen:" +msgstr "der Celery-Task %(task_name)s ist mit folgenden Informationen fehlgeschlagen:" #: aleksis/core/templates/templated_email/celery_failure.email:10 #: aleksis/core/templates/templated_email/celery_failure.email:29 @@ -2661,8 +2609,7 @@ msgid "" " " msgstr "" "\n" -" der Celery-Task %(task_name)s ist mit folgenden Informationen " -"fehlgeschlagen:\n" +" der Celery-Task %(task_name)s ist mit folgenden Informationen fehlgeschlagen:\n" " " #: aleksis/core/templates/templated_email/data_checks.email:3 @@ -2672,25 +2619,21 @@ msgstr "Das System hat einige neue Probleme mit Ihren Daten entdeckt." #: aleksis/core/templates/templated_email/data_checks.email:6 msgid "" "the system detected some new problems with your data.\n" -"Please take some time to inspect them and solve the issues or mark them as " -"ignored." +"Please take some time to inspect them and solve the issues or mark them as ignored." msgstr "" "das System hat einige neue Probleme mit Ihren Daten entdeckt.\n" -"Bitte nehmen Sie sich etwas Zeit, diese zu überprüfen und sie zu lösen oder " -"als ignoriert zu markieren." +"Bitte nehmen Sie sich etwas Zeit, diese zu überprüfen und sie zu lösen oder als ignoriert zu markieren." #: aleksis/core/templates/templated_email/data_checks.email:15 msgid "" "\n" " the system detected some new problems with your data.\n" -" Please take some time to inspect them and solve the issues or mark them " -"as ignored.\n" +" Please take some time to inspect them and solve the issues or mark them as ignored.\n" " " msgstr "" "\n" " das System hat einige neue Probleme mit Ihren Daten entdeckt.\n" -"Bitte nehmen Sie sich etwas Zeit, diese zu überprüfen und sie zu lösen oder " -"als ignoriert zu markieren.\n" +"Bitte nehmen Sie sich etwas Zeit, diese zu überprüfen und sie zu lösen oder als ignoriert zu markieren.\n" " " #: aleksis/core/templates/templated_email/data_checks.email:23 @@ -2715,12 +2658,8 @@ msgstr "Hallo %(person)s" #: aleksis/core/templates/templated_email/invitation.email:9 #: aleksis/core/templates/templated_email/invitation.email:18 #, python-format -msgid "" -"you have been invited to register on %(site)s. If you would like to accept " -"this invitation, please click on the following link:" -msgstr "" -"Sie wurden eingeladen, sich auf %(site)s zu registrieren. Wenn Sie diese " -"Einladung annehmen möchten, klicken Sie bitte auf folgenden Link:" +msgid "you have been invited to register on %(site)s. If you would like to accept this invitation, please click on the following link:" +msgstr "Sie wurden eingeladen, sich auf %(site)s zu registrieren. Wenn Sie diese Einladung annehmen möchten, klicken Sie bitte auf folgenden Link:" #: aleksis/core/templates/templated_email/notification.email:4 msgid "New notification for" @@ -2794,21 +2733,16 @@ msgid "" "\n" " Backup tokens can be used when your primary and backup\n" " phone numbers aren't available. The backup tokens below can be used\n" -" for login verification. If you've used up all your backup tokens, " -"you\n" -" can generate a new set of backup tokens. Only the backup tokens " -"shown\n" +" for login verification. If you've used up all your backup tokens, you\n" +" can generate a new set of backup tokens. Only the backup tokens shown\n" " below will be valid.\n" " " msgstr "" "\n" " Backup-Token können genutzt werden, wenn Ihre primären und Backup-\n" -" Telefonnummern nicht verfügbar sind. Die Backup-Tokens unten können " -"für\n" -" die Anmeldungsverifizierung genutzt werden. Wenn Sie alle Backup-" -"Tokens genutzt haben,\n" -" müssen Sie neue generieren. Nur gültige Backup-Tokens werden " -"angezeigt.\n" +" Telefonnummern nicht verfügbar sind. Die Backup-Tokens unten können für\n" +" die Anmeldungsverifizierung genutzt werden. Wenn Sie alle Backup-Tokens genutzt haben,\n" +" müssen Sie neue generieren. Nur gültige Backup-Tokens werden angezeigt.\n" " " #: aleksis/core/templates/two_factor/core/backup_tokens.html:33 @@ -2858,9 +2792,7 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:51 msgid "Please login with your account to use the external application." -msgstr "" -"Bitte melden Sie sich mit Ihrem Konto an, um die externe Anwendung zu " -"benutzen." +msgstr "Bitte melden Sie sich mit Ihrem Konto an, um die externe Anwendung zu benutzen." #: aleksis/core/templates/two_factor/core/login.html:58 msgid "Please login to see this page." @@ -2869,8 +2801,7 @@ msgstr "Bitte melden Sie sich an, um diese Seite zu sehen." #: aleksis/core/templates/two_factor/core/login.html:69 msgid "" "\n" -" We are calling your phone right now, please enter " -"the\n" +" We are calling your phone right now, please enter the\n" " digits you hear.\n" " " msgstr "" @@ -2882,8 +2813,7 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:74 msgid "" "\n" -" We sent you a text message, please enter the code we " -"sent.\n" +" We sent you a text message, please enter the code we sent.\n" " " msgstr "" "\n" @@ -2894,8 +2824,7 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:78 msgid "" "\n" -" We sent you an email, please enter the code we " -"sent.\n" +" We sent you an email, please enter the code we sent.\n" " " msgstr "" "\n" @@ -2906,20 +2835,17 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:82 msgid "" "\n" -" Please use your Webauthn-compatible device to " -"authenticate.\n" +" Please use your Webauthn-compatible device to authenticate.\n" " " msgstr "" "\n" -" Bitte nutzen Sie Ihr Webauthn-kompatibles Gerät, um " -"sich zu authentifizieren.\n" +" Bitte nutzen Sie Ihr Webauthn-kompatibles Gerät, um sich zu authentifizieren.\n" " " #: aleksis/core/templates/two_factor/core/login.html:86 msgid "" "\n" -" Please enter the code generated by your code " -"generator.\n" +" Please enter the code generated by your code generator.\n" " " msgstr "" "\n" @@ -2930,19 +2856,14 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:91 msgid "" "\n" -" Use this form for entering backup tokens for logging " -"in.\n" -" These tokens have been generated for you to print and " -"keep safe. Please\n" -" enter one of these backup tokens to login to your " -"account.\n" +" Use this form for entering backup tokens for logging in.\n" +" These tokens have been generated for you to print and keep safe. Please\n" +" enter one of these backup tokens to login to your account.\n" " " msgstr "" "\n" -" Nutzen Sie dieses Formular um Ihre Backup-Tokens zum " -"Anmelden einzugeben.\n" -" Diese Tokens wurden für Sie generiert, um diese gut " -"aufzubewahren. Bitte\n" +" Nutzen Sie dieses Formular um Ihre Backup-Tokens zum Anmelden einzugeben.\n" +" Diese Tokens wurden für Sie generiert, um diese gut aufzubewahren. Bitte\n" " geben Sie einen dieser Tokens ein, um sich einzuloggen.\n" " " @@ -2973,13 +2894,11 @@ msgstr "Zugriff verwehrt" #: aleksis/core/templates/two_factor/core/otp_required.html:10 msgid "" "The page you requested enforces users to verify using\n" -" two-factor authentication for security reasons. You need to enable " -"this\n" +" two-factor authentication for security reasons. You need to enable this\n" " security feature in order to access this page." msgstr "" "Die von Ihnen gewünschte Seite erfordert aus Sicherheitsgründen\n" -" eine Verifizierung durch Zwei-Faktor-Authentifizierung. Sie müssen " -"diese\n" +" eine Verifizierung durch Zwei-Faktor-Authentifizierung. Sie müssen diese\n" " Sicherheitsfunktion aktivieren, um die Seite aufzurufen." #: aleksis/core/templates/two_factor/core/otp_required.html:16 @@ -3023,8 +2942,7 @@ msgid "" msgstr "" "\n" " Sie sind dabei, Ihre Kontosicherheit auf das\n" -" nächste Level zu erhöhen. Bitte folgen Sie den Schritten im " -"Assistenten, um eine\n" +" nächste Level zu erhöhen. Bitte folgen Sie den Schritten im Assistenten, um eine\n" " Zwei-Faktor-Authentifizierungs-Methode zu Ihrem Konto hinzuzufügen.\n" " " @@ -3035,22 +2953,19 @@ msgid "" " " msgstr "" "\n" -" Bitte wählen Sie aus, welche Authentifikationsmethode Sie nutzen " -"wollen:\n" +" Bitte wählen Sie aus, welche Authentifikationsmethode Sie nutzen wollen:\n" " " #: aleksis/core/templates/two_factor/core/setup.html:27 msgid "" "\n" " To start using a code generator, please use your\n" -" favourite two-factor authentication (TOTP) app to scan the QR code " -"below.\n" +" favourite two-factor authentication (TOTP) app to scan the QR code below.\n" " Then enter the token generated by the app.\n" " " msgstr "" "\n" -" Um mit dem Code-Generator zu starten, benutzen Sie bitte Ihre " -"favorisierte\n" +" Um mit dem Code-Generator zu starten, benutzen Sie bitte Ihre favorisierte\n" "App für Zwei-Faktor-Authentifizierung (TOTP), um diesen QR-Code zu scannen.\n" "Dann geben Sie den in der App angezeigten Code ein:\n" " " @@ -3064,8 +2979,7 @@ msgid "" msgstr "" "\n" " Bitte geben Sie die Telefonnummer des Gerätes an,\n" -" an die die SMS-Nachrichten geschickt werden sollen. Diese Nummer " -"wird im nächsten Schritt überprüft.\n" +" an die die SMS-Nachrichten geschickt werden sollen. Diese Nummer wird im nächsten Schritt überprüft.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:45 @@ -3087,20 +3001,17 @@ msgid "" " " msgstr "" "\n" -" Wir haben Ihnen eine E-Mail geschickt, bitte geben Sie den Code ein, " -"den wir geschickt haben.\n" +" Wir haben Ihnen eine E-Mail geschickt, bitte geben Sie den Code ein, den wir geschickt haben.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:60 msgid "" "\n" -" We are calling your phone right now, please enter the digits you " -"hear.\n" +" We are calling your phone right now, please enter the digits you hear.\n" " " msgstr "" "\n" -" Wir rufen Ihr Telefon jetzt an, bitte geben Sie die Zahlen ein, " -"die Sie hören.\n" +" Wir rufen Ihr Telefon jetzt an, bitte geben Sie die Zahlen ein, die Sie hören.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:66 @@ -3110,30 +3021,23 @@ msgid "" " " msgstr "" "\n" -" Wir haben Ihnen eine SMS geschickt, bitte geben Sie den Code " -"ein, den wir geschickt haben.\n" +" Wir haben Ihnen eine SMS geschickt, bitte geben Sie den Code ein, den wir geschickt haben.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:73 msgid "" "\n" -" We've encountered an issue with the selected authentication " -"method. Please\n" -" go back and verify that you entered your information correctly, " -"try\n" -" again, or use a different authentication method instead. If the " -"issue\n" +" We've encountered an issue with the selected authentication method. Please\n" +" go back and verify that you entered your information correctly, try\n" +" again, or use a different authentication method instead. If the issue\n" " persists, contact the site administrator.\n" " " msgstr "" "\n" -" Mit der ausgewählten Authentifizierungsmethode ist ein Fehler " -"aufgetreten. \n" -"Bitte gehen Sie zurück und überprüfen, dass Sie die Informationen korrekt " -"eingegeben haben, versuchen Sie es erneut,\n" +" Mit der ausgewählten Authentifizierungsmethode ist ein Fehler aufgetreten. \n" +"Bitte gehen Sie zurück und überprüfen, dass Sie die Informationen korrekt eingegeben haben, versuchen Sie es erneut,\n" "oder benutzen Sie stattdessen eine andere Authentifizierungsmethode. \n" -"Wenn der Fehler bestehen bleibt, kontaktieren Sie bitte einen der " -"Administratoren.\n" +"Wenn der Fehler bestehen bleibt, kontaktieren Sie bitte einen der Administratoren.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:83 @@ -3158,13 +3062,11 @@ msgstr "Zwei-Faktor-Authentifizierung erfolgreich aktiviert" #: aleksis/core/templates/two_factor/core/setup_complete.html:13 msgid "" "\n" -" Congratulations, you've successfully enabled two-factor " -"authentication.\n" +" Congratulations, you've successfully enabled two-factor authentication.\n" " " msgstr "" "\n" -" Gratulation, Sie haben die Zwei-Faktor-Authentifizierung erfolgreich " -"aktiviert.\n" +" Gratulation, Sie haben die Zwei-Faktor-Authentifizierung erfolgreich aktiviert.\n" " " #: aleksis/core/templates/two_factor/core/setup_complete.html:22 @@ -3181,17 +3083,14 @@ msgstr "Backup-Codes generieren" msgid "" "\n" " However, it might happen that you don't have access to\n" -" your primary device. To enable account recovery, generate backup " -"codes\n" +" your primary device. To enable account recovery, generate backup codes\n" " or add other authentication methods.\n" " " msgstr "" "\n" -" Es kann passieren, dass Sie keinen Zugriff auf Ihr primäres Gerät " -"haben. \n" +" Es kann passieren, dass Sie keinen Zugriff auf Ihr primäres Gerät haben. \n" "Um die Konto-Wiederherstellung zu aktivieren,\n" -"generieren Sie Backup-Codes oder fügen Sie eine andere Authentifizierungs-" -"Methode hinzu.\n" +"generieren Sie Backup-Codes oder fügen Sie eine andere Authentifizierungs-Methode hinzu.\n" " " #: aleksis/core/templates/two_factor/core/setup_complete.html:48 @@ -3204,12 +3103,8 @@ msgid "Disable Two-Factor Authentication" msgstr "Zwei-Faktor-Authentifizierung deaktiveren" #: aleksis/core/templates/two_factor/profile/disable.html:12 -msgid "" -"You are about to disable two-factor authentication. This weakens your " -"account security, are you sure?" -msgstr "" -"Sie sind dabei, Zwei-Faktor-Authentifizierung zu deaktivieren. Das " -"verschlechtert Ihre Kontosicherheit. Sind Sie sicher?" +msgid "You are about to disable two-factor authentication. This weakens your account security, are you sure?" +msgstr "Sie sind dabei, Zwei-Faktor-Authentifizierung zu deaktivieren. Das verschlechtert Ihre Kontosicherheit. Sind Sie sicher?" #: aleksis/core/templates/two_factor/profile/disable.html:26 msgid "Disable" @@ -3243,177 +3138,172 @@ msgstr "Es ist ein Fehler beim Generieren der PDF-Datei aufgetreten." msgid "Download PDF" msgstr "PDF herunterladen" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "Das Schuljahr wurde erstellt." - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "Das Schuljahr wurde gespeichert." - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "Die Untergruppen wurden gespeichert." -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "Die Person wurde gespeichert." -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "Die Gruppe wurde gespeichert." -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "Der Wartungsmodus wurde erfolgreich angeschaltet." -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "Der Wartungsmodus wurde erfolgreich ausgeschaltet." -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "Die Ankündigung wurde gespeichert." -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "Ankündigung wurde gelöscht." -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "Das angeforderte Einstellungsregister existiert nicht" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "Die Einstellungen wurde gespeichert." -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "Die Person wurde gelöscht." -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "Die Gruppe wurde gelöscht." -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "Das zusätzliche Feld wurde gespeichert." -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "Das zusätzliche Feld wurde gelöscht." -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "Der Gruppentyp wurde gespeichert." -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "Der Gruppentyp wurde gelöscht." -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "Fortschritt: Datenprüfungen ausführen" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 msgid "Run data checks …" msgstr "Datenprüfungen laufen …" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "Die Datenprüfungen wurden erfolgreich ausgeführt." -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "Es gab ein Problem beim Ausführen der Datenprüfungen." -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "Die Lösungsoption \"{solve_option_obj.verbose_name}\" " -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "Die angeforderte Lösungsoption existiert nicht" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "Das Dashboard-Widget wurde gespeichert." -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "Das Dashboard-Widget wurde erstellt." -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "Das Dashboard-Widget wurde gelöscht." -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "Ihre Dashboardkonfiguration wurde erfolgreich gespeichert." -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." -msgstr "" -"Die Konfiguration des Standard-Dashboardes wurde erfolgreich gespeichert." +msgstr "Die Konfiguration des Standard-Dashboardes wurde erfolgreich gespeichert." -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" -msgstr "" -"Die Einladung wurde erfolgreich erstellt. Der Einladungscode ist {code}" +msgstr "Die Einladung wurde erfolgreich erstellt. Der Einladungscode ist {code}" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "Wir haben die Berechtigungen erfolgreich zugewiesen." -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "Die globale Benutzerberechtigung wurde gelöscht." -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "Die globale Gruppenberechtigung wurde gelöscht." -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "Die Objekt-Benutzerberechtigung wurde gelöscht." -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "Die Objekt-Gruppenberechtigung wurde gelöscht." -#: aleksis/core/views.py:1382 -msgid "" -"The third-party account could not be disconnected because it is the only " -"login method available." -msgstr "" -"Das Drittanbieter-Konto konnte nicht deaktiviert werden, weil es die einzige " -"verfügbare Anmeldeoption ist." +#: aleksis/core/views.py:1352 +msgid "The third-party account could not be disconnected because it is the only login method available." +msgstr "Das Drittanbieter-Konto konnte nicht deaktiviert werden, weil es die einzige verfügbare Anmeldeoption ist." -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt." -#: aleksis/core/views.py:1465 -msgid "" -"Person was invited successfully and an email with further instructions has " -"been send to them." -msgstr "" -"Die Person wurde erfolgreich eingeladen und eine E-Mail mit weiteren " -"Anweisungen wurde an sie verschickt." +#: aleksis/core/views.py:1435 +msgid "Person was invited successfully and an email with further instructions has been send to them." +msgstr "Die Person wurde erfolgreich eingeladen und eine E-Mail mit weiteren Anweisungen wurde an sie verschickt." -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "Person wurde bereits eingeladen." +#~ msgid "Country for phone number parsing" +#~ msgstr "Land für das Einlesen von Telefonnummern" + +#~ msgid "Create school term" +#~ msgstr "Schuljahr erstellen" + +#~ msgid "Edit school term" +#~ msgstr "Schuljahr bearbeiten" + +#~ msgid "The school term has been created." +#~ msgstr "Das Schuljahr wurde erstellt." + +#~ msgid "The school term has been saved." +#~ msgstr "Das Schuljahr wurde gespeichert." + #~ msgid "Revoke access" #~ msgstr "Zugriff zurückziehen" #~ msgid "Are you sure to revoke the access for this application?" -#~ msgstr "" -#~ "Sind Sie sicher, dass Sie den Zugriff für diese Anwendung zurückziehen " -#~ "möchten?" +#~ msgstr "Sind Sie sicher, dass Sie den Zugriff für diese Anwendung zurückziehen möchten?" #~ msgid "Revoke" #~ msgstr "Zurückziehen" @@ -3436,14 +3326,11 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " This page is currently unavailable. If this error persists, " -#~ "contact your site administrators:\n" +#~ " This page is currently unavailable. If this error persists, contact your site administrators:\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Diese Seite ist aktuell nicht erreichbar. Wenn dieser Fehler " -#~ "bestehen bleibt, kontaktieren Sie bitte einen Ihrer " -#~ "Systemadministratoren:\n" +#~ " Diese Seite ist aktuell nicht erreichbar. Wenn dieser Fehler bestehen bleibt, kontaktieren Sie bitte einen Ihrer Systemadministratoren:\n" #~ " " #~ msgid "" @@ -3452,8 +3339,7 @@ msgstr "Person wurde bereits eingeladen." #~ " security." #~ msgstr "" #~ "Die Zwei-Faktor-Authentifizierung ist nicht für Ihren Account aktiviert.\n" -#~ " Aktivieren Sie Zwei-Faktor-Authentifizierung für eine " -#~ "verbesserte\n" +#~ " Aktivieren Sie Zwei-Faktor-Authentifizierung für eine verbesserte\n" #~ " Accountsicherheit." #~ msgid "Add Phone Number" @@ -3480,8 +3366,7 @@ msgstr "Person wurde bereits eingeladen." #~ " send backup tokens to the phone numbers listed below." #~ msgstr "" #~ "Wenn Ihre primäre Methode nicht verfügbar ist, sind wir in der Lage,\n" -#~ " Backup-Tokens zu den unten aufgelisteten Telefonnummern zu " -#~ "schicken." +#~ " Backup-Tokens zu den unten aufgelisteten Telefonnummern zu schicken." #~ msgid "Unregister" #~ msgstr "Abmelden" @@ -3522,8 +3407,7 @@ msgstr "Person wurde bereits eingeladen." #~ msgstr "" #~ "\n" #~ " Wir raten Ihnen jedoch dringend davon ab.\n" -#~ " Sie können jedoch auch die Zwei-Faktor-Authentifizierung für Ihr " -#~ "Konto deaktivieren.\n" +#~ " Sie können jedoch auch die Zwei-Faktor-Authentifizierung für Ihr Konto deaktivieren.\n" #~ " " #~ msgid "" @@ -3534,31 +3418,20 @@ msgstr "Person wurde bereits eingeladen." #~ " " #~ msgstr "" #~ "\n" -#~ " Die Zwei-Faktor-Authentifizierung ist nicht für Ihren Account " -#~ "aktiviert.\n" -#~ " Aktivieren Sie Zwei-Faktor-Authentifizierung für eine " -#~ "verbesserte\n" +#~ " Die Zwei-Faktor-Authentifizierung ist nicht für Ihren Account aktiviert.\n" +#~ " Aktivieren Sie Zwei-Faktor-Authentifizierung für eine verbesserte\n" #~ " Accountsicherheit.\n" #~ " " -#~ msgid "Birthday Calendar" -#~ msgstr "Geburtstagskalender" - #~ msgid "A Calendar of Birthdays" #~ msgstr "Ein Kalender mit Geburtstagen" -#, python-format -#~ msgid "%(name)s's birthday" -#~ msgstr "%(name)ss Geburtstag" - #, python-format #~ msgid "%(name)s was born on %(birthday)s" #~ msgstr "%(name)s wurde am %(birthday)s geboren" #~ msgid "You must grant the permission to all objects and/or to some objects." -#~ msgstr "" -#~ "Sie müssen die Berechtigung auf alle Objekte und/oder für einige Objekte " -#~ "vergeben." +#~ msgstr "Sie müssen die Berechtigung auf alle Objekte und/oder für einige Objekte vergeben." #~ msgid "Dashboard" #~ msgstr "Dashboard" @@ -3596,9 +3469,6 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "Third-party accounts" #~ msgstr "Drittanbieter-Konten" -#~ msgid "Calendar Feeds" -#~ msgstr "Kalender-Feeds" - #~ msgid "Logout" #~ msgstr "Abmelden" @@ -3649,14 +3519,8 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "ICal Feeds" #~ msgstr "iCal-Feeds" -#~ msgid "" -#~ "These are URLs for different Calendar Feeds in the iCal (.ics) format. " -#~ "You can create as many as you want and import them in your calendar " -#~ "software." -#~ msgstr "" -#~ "Dies sind URLs für verschiedene Kalender-Feeds im iCal-Format (.ics). Sie " -#~ "können so viele erstellen, wie sie wollen, und in Ihre Kalender-Software " -#~ "importieren." +#~ msgid "These are URLs for different Calendar Feeds in the iCal (.ics) format. You can create as many as you want and import them in your calendar software." +#~ msgstr "Dies sind URLs für verschiedene Kalender-Feeds im iCal-Format (.ics). Sie können so viele erstellen, wie sie wollen, und in Ihre Kalender-Software importieren." #~ msgid "Your iCal URLs" #~ msgstr "Deine iCal-URLs" @@ -3681,30 +3545,24 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " This platform is powered by AlekSIS®, a web-based school " -#~ "information system (SIS) which can be used\n" -#~ " to manage and/or publish organisational artifacts of " -#~ "educational institutions. AlekSIS is free software and\n" +#~ " This platform is powered by AlekSIS®, a web-based school information system (SIS) which can be used\n" +#~ " to manage and/or publish organisational artifacts of educational institutions. AlekSIS is free software and\n" #~ " can be used by anyone.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Diese Plattform wird mit AlekSIS®, einem webbasierten " -#~ "Schulinformationssystem (SIS), \n" -#~ "welches für die Verwaltung und/oder Veröffentlichung von " -#~ "Bildungseinrichtungen verwendet werden kann.\n" +#~ " Diese Plattform wird mit AlekSIS®, einem webbasierten Schulinformationssystem (SIS), \n" +#~ "welches für die Verwaltung und/oder Veröffentlichung von Bildungseinrichtungen verwendet werden kann.\n" #~ "AlekSIS ist freie Software und kann von jedem benutzt werden.\n" #~ " " #~ msgid "" #~ "\n" -#~ " AlekSIS® is a registered trademark of the AlekSIS open " -#~ "source project, represented by Teckids e.V.\n" +#~ " AlekSIS® is a registered trademark of the AlekSIS open source project, represented by Teckids e.V.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " AlekSIS® ist eine eingetragene Wortmarke des Open-Source-" -#~ "Projektes AlekSIS, vertreten durch den Teckids e.V.\n" +#~ " AlekSIS® ist eine eingetragene Wortmarke des Open-Source-Projektes AlekSIS, vertreten durch den Teckids e.V.\n" #~ " " #~ msgid "Website of AlekSIS" @@ -3718,18 +3576,14 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " The core and the official apps of AlekSIS are licenced " -#~ "under the EUPL, version 1.2 or later. For licence\n" -#~ " information from third-party apps, if installed, refer to " -#~ "the respective components below. The\n" +#~ " The core and the official apps of AlekSIS are licenced under the EUPL, version 1.2 or later. For licence\n" +#~ " information from third-party apps, if installed, refer to the respective components below. The\n" #~ " licences are marked like this:\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Der Core und die offiziellen Apps von AlekSIS sind unter " -#~ "der EUPL, Version 1.2 oder später, lizenziert. Für Lizenzinformationen\n" -#~ "zu Apps von Drittanbietern, wenn installiert, siehe direkt bei der " -#~ "jeweiligen App weiter unten auf dieser Seite. Die Lizenzen\n" +#~ " Der Core und die offiziellen Apps von AlekSIS sind unter der EUPL, Version 1.2 oder später, lizenziert. Für Lizenzinformationen\n" +#~ "zu Apps von Drittanbietern, wenn installiert, siehe direkt bei der jeweiligen App weiter unten auf dieser Seite. Die Lizenzen\n" #~ "sind wie folgt markiert:\n" #~ " " @@ -3747,24 +3601,20 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " Without activated JavaScript the progress status can't be " -#~ "updated.\n" +#~ " Without activated JavaScript the progress status can't be updated.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ohne aktiviertes JavaScript kann der Fortschritt leider " -#~ "nicht aktualisiert werden.\n" +#~ " Ohne aktiviertes JavaScript kann der Fortschritt leider nicht aktualisiert werden.\n" #~ " " #~ msgid "" #~ "\n" -#~ " Only admin and visitors from internal IPs can access " -#~ "thesite.\n" +#~ " Only admin and visitors from internal IPs can access thesite.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Nur Administratoren und Besucher von internen IP-Adressen " -#~ "können die Seite aufrufen.\n" +#~ " Nur Administratoren und Besucher von internen IP-Adressen können die Seite aufrufen.\n" #~ " " #~ msgid "Language" @@ -3775,14 +3625,12 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " Your administrator account is not linked to any person. " -#~ "Therefore,\n" +#~ " Your administrator account is not linked to any person. Therefore,\n" #~ " a dummy person has been linked to your account.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ihr Administratorenkonto ist mit keiner Person verknüpft. " -#~ "Deshalb\n" +#~ " Ihr Administratorenkonto ist mit keiner Person verknüpft. Deshalb\n" #~ " wurde Ihr Konto mit einer Dummyperson verknüpft.\n" #~ " " @@ -3794,10 +3642,8 @@ msgstr "Person wurde bereits eingeladen." #~ " " #~ msgstr "" #~ "\n" -#~ " Ihr Benutzerkonto ist nicht mit einer Person verknüpft. Das " -#~ "bedeutet, dass Sie\n" -#~ " keine schulbezogenen Informationen aufrufen können. Bitte wenden " -#~ "Sie sich an\n" +#~ " Ihr Benutzerkonto ist nicht mit einer Person verknüpft. Das bedeutet, dass Sie\n" +#~ " keine schulbezogenen Informationen aufrufen können. Bitte wenden Sie sich an\n" #~ " die Verwaltenden von AlekSIS an Ihrer Schule.\n" #~ " " @@ -3820,27 +3666,21 @@ msgstr "Person wurde bereits eingeladen." #~ msgstr "Erfolg!" #~ msgid "Please return to your application and enter this code:" -#~ msgstr "" -#~ "Bitte gehen Sie zurück in Ihre Anwendung und geben Sie diesen Code ein:" +#~ msgstr "Bitte gehen Sie zurück in Ihre Anwendung und geben Sie diesen Code ein:" #~ msgid "No internet connection." #~ msgstr "Keine Internetverbindung." #~ msgid "" #~ "\n" -#~ " There was an error accessing this page. You probably don't have an " -#~ "internet connection. Check to see if your WiFi\n" -#~ " or mobile data is turned on and try again. If you think you are " -#~ "connected, please contact the system\n" +#~ " There was an error accessing this page. You probably don't have an internet connection. Check to see if your WiFi\n" +#~ " or mobile data is turned on and try again. If you think you are connected, please contact the system\n" #~ " administrators:\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Es ist ein Fehler beim Aufrufen der Seite aufgetreten. Eventuell " -#~ "haben Sie keine Internetverbindung. Bitte prüfen Sie, ob WLAN oder mobile " -#~ "Daten aktiv sind, \n" -#~ " und probieren Sie es erneut. Wenn Sie der Meinung sind, dass Sie " -#~ "mit dem Internet verbunden sind, kontaktieren Sie bitte einen Ihrer \n" +#~ " Es ist ein Fehler beim Aufrufen der Seite aufgetreten. Eventuell haben Sie keine Internetverbindung. Bitte prüfen Sie, ob WLAN oder mobile Daten aktiv sind, \n" +#~ " und probieren Sie es erneut. Wenn Sie der Meinung sind, dass Sie mit dem Internet verbunden sind, kontaktieren Sie bitte einen Ihrer \n" #~ " Systemadministratoren:\n" #~ " " @@ -3936,8 +3776,7 @@ msgstr "Person wurde bereits eingeladen." #~ " <li>ID des Tasks: %(task_id)s</li>\n" #~ " <li>Aufgetretene Exception: %(exception)s</li>\n" #~ " <li>Argumente, mit denen der Task aufgerufen wurde: %(args)s</li>\n" -#~ " <li>Keyword-Argumente, mit denen der Task aufgerufen wurde: " -#~ "%(kwargs)s</li>\n" +#~ " <li>Keyword-Argumente, mit denen der Task aufgerufen wurde: %(kwargs)s</li>\n" #~ " <li>Stacktrace: %(traceback)s</li>\n" #~ " </ul>\n" #~ " " @@ -3956,12 +3795,8 @@ msgstr "Person wurde bereits eingeladen." #~ msgstr "Zustimmungen" #, python-brace-format -#~ msgid "" -#~ "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree " -#~ "with them." -#~ msgstr "" -#~ "Ich habe die <a href='{privacy_policy}'>Datenschutzerklärung</a> gelesen " -#~ "und stimme ihr zu." +#~ msgid "I have read the <a href='{privacy_policy}'>Privacy policy</a> and agree with them." +#~ msgstr "Ich habe die <a href='{privacy_policy}'>Datenschutzerklärung</a> gelesen und stimme ihr zu." #~ msgid "You must type the same password each time." #~ msgstr "Sie müssen zweimal das gleiche Passwort eingeben." @@ -3970,12 +3805,8 @@ msgstr "Person wurde bereits eingeladen." #~ msgstr "Verkleidung" #, python-format -#~ msgid "" -#~ "<strong>Note:</strong> you can still <a href=\"%(email_url)s\">change " -#~ "your e-mail address</a>" -#~ msgstr "" -#~ "<strong>Hinweis:</strong> Sie können immer noch <a " -#~ "href=\"%(email_url)s\"> Ihre E-Mail-Adresse ändern</a>" +#~ msgid "<strong>Note:</strong> you can still <a href=\"%(email_url)s\">change your e-mail address</a>" +#~ msgstr "<strong>Hinweis:</strong> Sie können immer noch <a href=\"%(email_url)s\"> Ihre E-Mail-Adresse ändern</a>" #~ msgid "Impress" #~ msgstr "Impressum" @@ -3997,9 +3828,7 @@ msgstr "Person wurde bereits eingeladen." #, python-format #~ msgid "Are you sure to delete the application %(application_name)s?" -#~ msgstr "" -#~ "Sind Sie sicher, dass Sie die Anwendung %(application_name)s löschen " -#~ "möchten?" +#~ msgstr "Sind Sie sicher, dass Sie die Anwendung %(application_name)s löschen möchten?" #~ msgid "Authorization Grant Type" #~ msgstr "Authorization Grant-Typ" @@ -4024,23 +3853,17 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "" #~ "\n" -#~ " You can use this form to assign user accounts to persons. Use " -#~ "the\n" -#~ " dropdowns to select existing accounts; use the text fields to " -#~ "create new\n" -#~ " accounts on-the-fly. The latter will create a new account with " -#~ "the\n" +#~ " You can use this form to assign user accounts to persons. Use the\n" +#~ " dropdowns to select existing accounts; use the text fields to create new\n" +#~ " accounts on-the-fly. The latter will create a new account with the\n" #~ " entered username and copy all other details from the person.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Sie können dieses Formular nutzen, um Benutzerkonten Personen " -#~ "zuzuweisen. Nutzen Sie das\n" -#~ " Auswahlfeld um ein existierendes Benutzerkonto auszuwählen; nutzen " -#~ "Sie das Textfeld, um einen neuen Benutzer zu\n" +#~ " Sie können dieses Formular nutzen, um Benutzerkonten Personen zuzuweisen. Nutzen Sie das\n" +#~ " Auswahlfeld um ein existierendes Benutzerkonto auszuwählen; nutzen Sie das Textfeld, um einen neuen Benutzer zu\n" #~ " erstellen. Letzteres erstellt ein neues Benutzerkonto mit dem\n" -#~ " eingegebenen Benutzernamen und kopiert alle anderen Daten der " -#~ "Person.\n" +#~ " eingegebenen Benutzernamen und kopiert alle anderen Daten der Person.\n" #~ " " #~ msgid "Existing account" @@ -4066,8 +3889,7 @@ msgstr "Person wurde bereits eingeladen." #~ "We sent you a text message, please enter the tokens we\n" #~ " sent." #~ msgstr "" -#~ "Wir haben Ihnen eine Textnachricht geschickt. Bitte geben Sie die Tokens " -#~ "ein,\n" +#~ "Wir haben Ihnen eine Textnachricht geschickt. Bitte geben Sie die Tokens ein,\n" #~ " die wir Ihnen geschickt haben." #~ msgid "French" @@ -4076,12 +3898,8 @@ msgstr "Person wurde bereits eingeladen." #~ msgid "Norwegian (bokmÃ¥l)" #~ msgstr "Norwegisch (bokmÃ¥l)" -#~ msgid "" -#~ "The data check has been started. Please note that it may take a while " -#~ "before you are able to fetch the data on this page." -#~ msgstr "" -#~ "Die Datenüberprüfung wurde gestartet. Bitte beachten Sie, dass es eine " -#~ "Weile dauern kann, bevor Sie auf dieser Seite Ergebnisse abrufen können." +#~ msgid "The data check has been started. Please note that it may take a while before you are able to fetch the data on this page." +#~ msgstr "Die Datenüberprüfung wurde gestartet. Bitte beachten Sie, dass es eine Weile dauern kann, bevor Sie auf dieser Seite Ergebnisse abrufen können." #~ msgid "The data check has finished." #~ msgstr "Die Datenüberprüfung wurde beendet." @@ -4135,8 +3953,7 @@ msgstr "Person wurde bereits eingeladen." #~ " " #~ msgstr "" #~ "\n" -#~ " Wenn Sie der Meinung sind, dass es sich um einen Fehler in AlekSIS " -#~ "handelt, kontaktieren Sie bitte einen Ihrer\n" +#~ " Wenn Sie der Meinung sind, dass es sich um einen Fehler in AlekSIS handelt, kontaktieren Sie bitte einen Ihrer\n" #~ " Systemadministratoren:\n" #~ " " @@ -4210,9 +4027,7 @@ msgstr "Person wurde bereits eingeladen." #~ msgstr "Markdown-Anleitung (Hilfe)" #~ msgid "You are not allowed to mark notifications from other users as read!" -#~ msgstr "" -#~ "Es ist Ihnen nicht erlaubt, Benachrichtigungen von anderen Benutzern als " -#~ "gelesen zu markieren!" +#~ msgstr "Es ist Ihnen nicht erlaubt, Benachrichtigungen von anderen Benutzern als gelesen zu markieren!" #, fuzzy #~ msgid "School name" diff --git a/aleksis/core/locale/fr/LC_MESSAGES/django.po b/aleksis/core/locale/fr/LC_MESSAGES/django.po index 2b3c3874af650baf3f812cf740ee2a3f1a9af29e..d1852c66e3212133747a28ce3c53e1fd98e676ce 100644 --- a/aleksis/core/locale/fr/LC_MESSAGES/django.po +++ b/aleksis/core/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: 2021-06-16 12:00+0000\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis/fr/>\n" @@ -44,8 +44,8 @@ msgstr "Détails de contact" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 #, fuzzy #| msgid "Group" @@ -108,184 +108,184 @@ msgstr "" msgid "Content type" msgstr "" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "groupe" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 msgid "Address" msgstr "" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 #, fuzzy #| msgid "Contact details" msgid "Contact data" msgstr "Détails de contact" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 #, fuzzy #| msgid "Contact details" msgid "Advanced personal data" msgstr "Détails de contact" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Cet nom est deja en utilisation." -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 #, fuzzy #| msgid "Contact details" msgid "Common data" msgstr "Détails de contact" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 #, fuzzy #| msgid "Person" msgid "Persons" msgstr "Personne" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 #, fuzzy #| msgid "Contact details" msgid "Additional data" msgstr "Détails de contact" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "Date" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "Prénom" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "Nom de famille" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 #, fuzzy #| msgid "Contact details" msgid "Account data" msgstr "Détails de contact" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "" @@ -309,498 +309,497 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 #, fuzzy #| msgid "Contact details" msgid "Start date" msgstr "Détails de contact" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "Personne" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 #, fuzzy #| msgid "Contact details" msgid "Can view address" msgstr "Détails de contact" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 #, fuzzy #| msgid "Contact details" msgid "Can view contact details" msgstr "Détails de contact" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 #, fuzzy #| msgid "Contact details" msgid "Can view photo" msgstr "Détails de contact" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 #, fuzzy #| msgid "Contact details" msgid "Can view avatar image" msgstr "Détails de contact" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 #, fuzzy #| msgid "Contact details" msgid "Can view persons groups" msgstr "Détails de contact" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 #, fuzzy #| msgid "Contact details" msgid "Can view personal details" msgstr "Détails de contact" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 #, fuzzy #| msgid "First name" msgid "Short name" msgstr "Prénom" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "Date d'anniversaire" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 #, fuzzy #| msgid "Date of birth" msgid "Place of birth" msgstr "Date d'anniversaire" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "Sexe" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "Description" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 #, fuzzy #| msgid "Description" msgid "Help text / description" msgstr "Description" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 #, fuzzy #| msgid "Contact details" msgid "Can view statistics about group." msgstr "Détails de contact" -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 #, fuzzy #| msgid "Last name" msgid "Long name" msgstr "Nom de famille" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "Propriétaires" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 msgid "Additional fields" msgstr "" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 #, fuzzy #| msgid "Group" msgid "Group type" msgstr "Groupe" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 #, fuzzy @@ -808,248 +807,298 @@ msgstr "Groupe" msgid "Group types" msgstr "Groupe" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 #, fuzzy #| msgid "Contact details" msgid "Can view system status" msgstr "Détails de contact" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 #, fuzzy #| msgid "Contact details" msgid "Can impersonate" msgstr "Détails de contact" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 #, fuzzy #| msgid "Contact details" msgid "Can invite persons" msgstr "Détails de contact" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 #, fuzzy #| msgid "Contact details" msgid "E-Mail address" msgstr "Détails de contact" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 #, fuzzy #| msgid "Owners" msgid "Owner" msgstr "Propriétaires" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 #, fuzzy #| msgid "Contact details" msgid "Additional button title" msgstr "Détails de contact" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 #, fuzzy #| msgid "Contact details" msgid "Additional button URL" msgstr "Détails de contact" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 #, fuzzy #| msgid "Contact details" msgid "Additional button icon" msgstr "Détails de contact" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 #, fuzzy #| msgid "Contact details" msgid "Additional attributes" msgstr "Détails de contact" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 #, fuzzy #| msgid "Contact details" msgid "Can view room timetable" msgstr "Détails de contact" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +#, fuzzy +#| msgid "Contact details" +msgid "Start date and time" +msgstr "Détails de contact" + +#: aleksis/core/models.py:1530 +msgid "End date and time" +msgstr "" + +#: aleksis/core/models.py:1531 +msgid "Timezone" +msgstr "" + +#: aleksis/core/models.py:1534 +msgid "Recurrences" +msgstr "" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +msgid "Calendar Event" +msgstr "" + +#: aleksis/core/models.py:1644 +msgid "Calendar Events" +msgstr "" + +#: aleksis/core/models.py:1670 +msgid "Birthdays" +msgstr "" + +#: aleksis/core/models.py:1674 +msgid "{}'s birthday" +msgstr "" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 #, fuzzy #| msgid "Contact details" msgid "Accounts" msgstr "Détails de contact" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 msgid "Authentication" msgstr "" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "" +#: aleksis/core/preferences.py:33 +msgid "Calendar" +msgstr "" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "" @@ -1231,7 +1280,15 @@ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" +msgid "Birthday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Activated calendars" msgstr "" #: aleksis/core/settings.py:551 @@ -1246,22 +1303,9 @@ msgstr "" msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" -msgstr "" - -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 -#: aleksis/core/templates/core/announcement/list.html:22 -msgid "Actions" -msgstr "" - -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 @@ -1269,6 +1313,11 @@ msgstr "" msgid "Delete" msgstr "" +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 +#: aleksis/core/templates/core/announcement/list.html:22 +msgid "Actions" +msgstr "" + #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1339,6 +1388,13 @@ msgstr "" msgid "Your AlekSIS team" msgstr "" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1571,6 +1627,12 @@ msgstr "" msgid "Recipients" msgstr "" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "" + #: aleksis/core/templates/core/announcement/list.html:50 msgid "There are no announcements." msgstr "" @@ -2135,17 +2197,6 @@ msgstr "" msgid "Selected persons" msgstr "" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -msgid "Create school term" -msgstr "" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "" @@ -2921,157 +2972,149 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "" - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "" - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "" -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "" -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "" -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "" -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "" -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "" -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1382 +#: aleksis/core/views.py:1352 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1465 +#: aleksis/core/views.py:1435 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 #, fuzzy #| msgid "This username is already in use." msgid "Person was already invited." diff --git a/aleksis/core/locale/la/LC_MESSAGES/django.po b/aleksis/core/locale/la/LC_MESSAGES/django.po index 1b6172ee3bd421884b89c300b56ff44c0edd5683..6289dae461dda33a7e1a1c07aebec1ca2bc6cac8 100644 --- a/aleksis/core/locale/la/LC_MESSAGES/django.po +++ b/aleksis/core/locale/la/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: 2020-12-19 12:57+0000\n" "Last-Translator: Julian <leuckerj@gmail.com>\n" "Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis/la/>\n" @@ -48,8 +48,8 @@ msgstr "Inscriptio electronica" msgid "Home and mobile phone" msgstr "Numerus telephoni mobilis" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 msgid "Groups" msgstr "Greges" @@ -112,188 +112,188 @@ msgstr "" msgid "Content type" msgstr "" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "Grex" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 #, fuzzy #| msgid "E-mail address" msgid "Address" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 #, fuzzy #| msgid "Persons and accounts" msgid "Create a new account" msgstr "Personae et computi" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "Anus scolae" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 #, fuzzy #| msgid "Data management" msgid "Common data" msgstr "Adminstratio datarum" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 msgid "Persons" msgstr "personae" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 #, fuzzy #| msgid "Additional name(s)" msgid "Additional data" msgstr "addita nomines" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "Photographia" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "dies" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "tempus" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "Quis nuntium videatne?" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "Scribe nuntium:" -#: aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "Primus nomen" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "Secondus nomen" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 #, fuzzy #| msgid "E-mail address" msgid "A person is using this e-mail address" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 #, fuzzy #| msgid "Who should see the announcement?" msgid "Who should get the permission?" msgstr "Quis nuntium videatne?" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 #, fuzzy #| msgid "E-mail address" msgid "Address data" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 #, fuzzy #| msgid "Data management" msgid "Account data" msgstr "Adminstratio datarum" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "" @@ -319,272 +319,271 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 #, fuzzy #| msgid "Edit school term" msgid "Linked school term" msgstr "Muta anum scolae" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "Dies et hora" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 #, fuzzy #| msgid "E-mail address" msgid "IP address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "Nomen" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "ani scolae" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "Persona" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 #, fuzzy #| msgid "E-mail address" msgid "Can view address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 #, fuzzy #| msgid "E-mail address" msgid "Can view contact details" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 #, fuzzy #| msgid "E-mail address" msgid "Can view photo" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 #, fuzzy #| msgid "E-mail address" msgid "Can view avatar image" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 #, fuzzy #| msgid "Persons and accounts" msgid "Can view persons groups" msgstr "Personae et computi" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 #, fuzzy #| msgid "Stop impersonation" msgid "Can view personal details" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "femininum" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "maskulinum" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "addita nomines" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "Breve nomen" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "Via" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "Numerus domini" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "Numerus directorius" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "Urbs" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "Numerus telephoni domi" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "Numerus telephoni mobilis" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "Dies natalis" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 #, fuzzy #| msgid "Date of birth" msgid "Place of birth" msgstr "Dies natalis" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "Genus" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "Parentes" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "Descriptio" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 #, fuzzy #| msgid "Site description" msgid "Help text / description" msgstr "Descriptio paginae" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 #, fuzzy #| msgid "Additional name(s)" msgid "Addtitional field for groups" msgstr "addita nomines" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 #, fuzzy #| msgid "Additional name(s)" msgid "Addtitional fields for groups" msgstr "addita nomines" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 #, fuzzy #| msgid "Persons and accounts" msgid "Can view statistics about group." msgstr "Personae et computi" -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 #, fuzzy #| msgid "Last name" msgid "Long name" msgstr "Secondus nomen" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 #, fuzzy @@ -592,259 +591,259 @@ msgstr "" msgid "Additional fields" msgstr "addita nomines" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Titulus" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "Mittens" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Nota" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 #, fuzzy #| msgid "Notification" msgid "Send notification at" msgstr "Nuntius" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 #, fuzzy #| msgid "Notifications" msgid "Notification" msgstr "Nuntii" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "Nuntii" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 #, fuzzy #| msgid "Announcements" msgid "Announcement" msgstr "Nuntii" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "Nuntii" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 #, fuzzy #| msgid "Announcements" msgid "Announcement recipient" msgstr "Nuntii" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 #, fuzzy #| msgid "Announcements" msgid "Announcement recipients" msgstr "Nuntii" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 #, fuzzy #| msgid "Site title" msgid "Widget Title" msgstr "Titulus paginae" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 #, fuzzy #| msgid "Site title" msgid "Widget is broken" msgstr "Titulus paginae" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 #, fuzzy #| msgid "Dashboard" msgid "Can edit default dashboard" msgstr "Forum" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 #, fuzzy #| msgid "Dashboard" msgid "Dashboard Widget" msgstr "Forum" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 #, fuzzy #| msgid "Dashboard" msgid "Dashboard Widgets" msgstr "Forum" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 #, fuzzy #| msgid "Icon" msgid "Icon URL" msgstr "Nota" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget" msgstr "Forum" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget order" msgstr "Forum" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget orders" msgstr "Forum" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 #, fuzzy #| msgid "Group" msgid "Group type" msgstr "Grex" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 #, fuzzy @@ -852,256 +851,310 @@ msgstr "Grex" msgid "Group types" msgstr "Greges" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 #, fuzzy #| msgid "System status" msgid "Can view system status" msgstr "Status systemae" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 #, fuzzy #| msgid "Data management" msgid "Can manage data" msgstr "Adminstratio datarum" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 #, fuzzy #| msgid "Stop impersonation" msgid "Can impersonate" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 #, fuzzy #| msgid "Stop impersonation" msgid "Can invite persons" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 #, fuzzy #| msgid "Notifications" msgid "Notification sent" msgstr "Nuntii" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 #, fuzzy #| msgid "E-mail address" msgid "E-Mail address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 #, fuzzy #| msgid "Icon" msgid "Back URL" msgstr "Nota" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button title" msgstr "addita nomines" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button URL" msgstr "addita nomines" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button icon" msgstr "addita nomines" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 #, fuzzy #| msgid "Additional name(s)" msgid "Additional attributes" msgstr "addita nomines" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 #, fuzzy #| msgid "E-mail address" msgid "Can view room timetable" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +#, fuzzy +#| msgid "Date and time" +msgid "Start date and time" +msgstr "Dies et hora" + +#: aleksis/core/models.py:1530 +#, fuzzy +#| msgid "Date and time" +msgid "End date and time" +msgstr "Dies et hora" + +#: aleksis/core/models.py:1531 +#, fuzzy +#| msgid "Time" +msgid "Timezone" +msgstr "tempus" + +#: aleksis/core/models.py:1534 +msgid "Recurrences" +msgstr "" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +msgid "Calendar Event" +msgstr "" + +#: aleksis/core/models.py:1644 +msgid "Calendar Events" +msgstr "" + +#: aleksis/core/models.py:1670 +msgid "Birthdays" +msgstr "" + +#: aleksis/core/models.py:1674 +msgid "{}'s birthday" +msgstr "" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "Scola" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 #, fuzzy #| msgid "Data management" msgid "Accounts" msgstr "Adminstratio datarum" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 #, fuzzy #| msgid "Notifications" msgid "Authentication" msgstr "Nuntii" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 #, fuzzy #| msgid "Impersonation" msgid "Internationalisation" msgstr "Simulare aliquem" +#: aleksis/core/preferences.py:33 +msgid "Calendar" +msgstr "" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "Titulus paginae" @@ -1287,7 +1340,15 @@ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" +msgid "Birthday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Activated calendars" msgstr "" #: aleksis/core/settings.py:551 @@ -1302,31 +1363,23 @@ msgstr "Germanus" msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 +#: aleksis/core/templates/core/announcement/list.html:42 +#: aleksis/core/templates/core/group/full.html:33 +#: aleksis/core/templates/core/pages/delete.html:22 +#: aleksis/core/templates/oauth2_provider/application/detail.html:21 +msgid "Delete" msgstr "" -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 #: aleksis/core/templates/core/announcement/list.html:22 #, fuzzy #| msgid "Notifications" msgid "Actions" msgstr "Nuntii" -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 -#: aleksis/core/templates/core/announcement/list.html:42 -#: aleksis/core/templates/core/group/full.html:33 -#: aleksis/core/templates/core/pages/delete.html:22 -#: aleksis/core/templates/oauth2_provider/application/detail.html:21 -msgid "Delete" -msgstr "" - #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1397,6 +1450,13 @@ msgstr "" msgid "Your AlekSIS team" msgstr "" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1645,6 +1705,12 @@ msgstr "" msgid "Recipients" msgstr "" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "" + #: aleksis/core/templates/core/announcement/list.html:50 #, fuzzy #| msgid "Write your announcement:" @@ -2233,19 +2299,6 @@ msgstr "" msgid "Selected persons" msgstr "" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -#, fuzzy -#| msgid "Edit school term" -msgid "Create school term" -msgstr "Muta anum scolae" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "Muta anum scolae" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "" @@ -3038,164 +3091,164 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "" - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "" - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "" -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "" -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 #, fuzzy #| msgid "Additional name(s)" msgid "The additional field has been saved." msgstr "addita nomines" -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "" -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "" -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "" -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 #, fuzzy #| msgid "System status" msgid "Run data checks …" msgstr "Status systemae" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1382 +#: aleksis/core/views.py:1352 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1465 +#: aleksis/core/views.py:1435 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "" +#, fuzzy +#~| msgid "Edit school term" +#~ msgid "Create school term" +#~ msgstr "Muta anum scolae" + +#~ msgid "Edit school term" +#~ msgstr "Muta anum scolae" + #, fuzzy #~| msgid "Notifications" #~ msgid "Authorized applications" diff --git a/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po index fb8bc425d974f814c8bf58710d9b1b06d975be5a..7a97f88fbc6d45c07ee2ca84806b8fcf28a4ef53 100644 --- a/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po +++ b/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -41,8 +41,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 msgid "Groups" msgstr "" @@ -101,172 +101,172 @@ msgstr "" msgid "Content type" msgstr "" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 msgid "Address" msgstr "" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "" @@ -290,697 +290,744 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 msgid "Help text / description" msgstr "" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 msgid "Additional fields" msgstr "" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +msgid "Start date and time" +msgstr "" + +#: aleksis/core/models.py:1530 +msgid "End date and time" +msgstr "" + +#: aleksis/core/models.py:1531 +msgid "Timezone" +msgstr "" + +#: aleksis/core/models.py:1534 +msgid "Recurrences" +msgstr "" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +msgid "Calendar Event" +msgstr "" + +#: aleksis/core/models.py:1644 +msgid "Calendar Events" +msgstr "" + +#: aleksis/core/models.py:1670 +msgid "Birthdays" +msgstr "" + +#: aleksis/core/models.py:1674 +msgid "{}'s birthday" +msgstr "" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 msgid "Accounts" msgstr "" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 msgid "Authentication" msgstr "" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "" +#: aleksis/core/preferences.py:33 +msgid "Calendar" +msgstr "" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "" @@ -1154,7 +1201,15 @@ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" +msgid "Birthday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Activated calendars" msgstr "" #: aleksis/core/settings.py:551 @@ -1169,22 +1224,9 @@ msgstr "" msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" -msgstr "" - -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 -#: aleksis/core/templates/core/announcement/list.html:22 -msgid "Actions" -msgstr "" - -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 @@ -1192,6 +1234,11 @@ msgstr "" msgid "Delete" msgstr "" +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 +#: aleksis/core/templates/core/announcement/list.html:22 +msgid "Actions" +msgstr "" + #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1262,6 +1309,13 @@ msgstr "" msgid "Your AlekSIS team" msgstr "" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1494,6 +1548,12 @@ msgstr "" msgid "Recipients" msgstr "" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "" + #: aleksis/core/templates/core/announcement/list.html:50 msgid "There are no announcements." msgstr "" @@ -2042,17 +2102,6 @@ msgstr "" msgid "Selected persons" msgstr "" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -msgid "Create school term" -msgstr "" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "" @@ -2812,157 +2861,149 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "" - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "" - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "" -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "" -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "" -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "" -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "" -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "" -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1382 +#: aleksis/core/views.py:1352 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1465 +#: aleksis/core/views.py:1435 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "" diff --git a/aleksis/core/locale/ru/LC_MESSAGES/django.po b/aleksis/core/locale/ru/LC_MESSAGES/django.po index 58e9f027cf610161dc14ee829e2669b2319f8299..8c9d34c43cd5a5152fe2e1a21f861d009f85c4d9 100644 --- a/aleksis/core/locale/ru/LC_MESSAGES/django.po +++ b/aleksis/core/locale/ru/LC_MESSAGES/django.po @@ -10,12 +10,15 @@ msgstr "" "POT-Creation-Date: 2023-02-27 13:23+0100\n" "PO-Revision-Date: 2023-07-04 04:21+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" -"Language-Team: Russian <https://translate.edugit.org/projects/aleksis/aleksis-core/ru/>\n" +"Language-Team: Russian <https://translate.edugit.org/projects/aleksis/" +"aleksis-core/ru/>\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" +"%100>=11 && n%100<=14)? 2 : 3);\n" "X-Generator: Weblate 4.12.1\n" #: aleksis/core/apps.py:155 aleksis/core/apps.py:161 @@ -42,6 +45,7 @@ msgstr "Домашний и мобильный телефоны" #: aleksis/core/models.py:494 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 aleksis/core/apps.py:166 #: aleksis/core/forms.py:221 aleksis/core/models.py:495 +#: aleksis/core/forms.py:231 aleksis/core/models.py:517 msgid "Groups" msgstr "Группы" @@ -100,26 +104,27 @@ msgid "Content type" msgstr "Тип Ñодержимого" #: aleksis/core/filters.py:113 aleksis/core/models.py:720 -#: aleksis/core/models.py:721 +#: aleksis/core/models.py:721 aleksis/core/models.py:743 msgid "User" msgstr "Пользователь" #: aleksis/core/filters.py:135 aleksis/core/models.py:493 -#: aleksis/core/models.py:494 +#: aleksis/core/models.py:494 aleksis/core/models.py:516 msgid "Group" msgstr "Группа" #: aleksis/core/forms.py:50 aleksis/core/forms.py:581 aleksis/core/forms.py:51 -#: aleksis/core/forms.py:582 +#: aleksis/core/forms.py:582 aleksis/core/forms.py:591 msgid "Base data" msgstr "ОÑновные данные" #: aleksis/core/forms.py:55 aleksis/core/tables.py:47 aleksis/core/forms.py:56 +#: aleksis/core/tables.py:29 msgid "Address" msgstr "ÐдреÑ" #: aleksis/core/forms.py:56 aleksis/core/forms.py:590 aleksis/core/forms.py:57 -#: aleksis/core/forms.py:591 +#: aleksis/core/forms.py:591 aleksis/core/forms.py:600 msgid "Contact data" msgstr "Контактные данные" @@ -145,6 +150,7 @@ msgstr "Ðтот логин уже занÑÑ‚." #: aleksis/core/forms.py:153 aleksis/core/models.py:141 #: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/models.py:154 msgid "School term" msgstr "Учебный год" @@ -156,130 +162,161 @@ msgstr "Общие данные" #: aleksis/core/models.py:164 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 aleksis/core/forms.py:156 #: aleksis/core/forms.py:208 aleksis/core/models.py:165 +#: aleksis/core/forms.py:218 aleksis/core/models.py:177 msgid "Persons" msgstr "Люди" #: aleksis/core/forms.py:156 aleksis/core/forms.py:592 #: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:602 msgid "Additional data" msgstr "Дополнительные данные" #: aleksis/core/forms.py:157 aleksis/core/models.py:217 #: aleksis/core/models.py:546 aleksis/core/tables.py:46 #: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 +#: aleksis/core/models.py:547 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "Фото" #: aleksis/core/forms.py:199 aleksis/core/forms.py:202 #: aleksis/core/models.py:84 aleksis/core/forms.py:200 #: aleksis/core/forms.py:203 aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "Дата" #: aleksis/core/forms.py:200 aleksis/core/forms.py:203 #: aleksis/core/models.py:92 aleksis/core/forms.py:201 #: aleksis/core/forms.py:204 aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "ВремÑ" #: aleksis/core/forms.py:233 aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "С какого и по какое Ð²Ñ€ÐµÐ¼Ñ Ñто объÑвление должно отображатьÑÑ?" #: aleksis/core/forms.py:236 aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "Кто должен видеть Ñто объÑвление?" #: aleksis/core/forms.py:237 aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "Ðапишите Ñвое объÑвление:" #: aleksis/core/forms.py:276 aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "" "You are not allowed to create announcements which are only valid in the past." msgstr "ОбъÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð¾Ð³Ð¾ Вам Ñоздавать не разрешено." #: aleksis/core/forms.py:280 aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "Дата и Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° должны быть до даты и времени окончаниÑ." #: aleksis/core/forms.py:289 aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "Ðужен Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один получатель." #: aleksis/core/forms.py:398 aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "Код приглашениÑ" #: aleksis/core/forms.py:399 aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "Укажите, пожалуйÑта, код приглашениÑ." #: aleksis/core/forms.py:418 aleksis/core/models.py:192 #: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "ИмÑ" #: aleksis/core/forms.py:419 aleksis/core/models.py:193 #: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "ФамилиÑ" #: aleksis/core/forms.py:428 aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "Ðтот Ñл.Ð°Ð´Ñ€ÐµÑ ÐºÐµÐ¼-то иÑпользуетÑÑ" #: aleksis/core/forms.py:456 aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "Кто должен получить такое разрешение?" #: aleksis/core/forms.py:457 aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "Ð’ Ñлучае чего?" #: aleksis/core/forms.py:483 aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "Отметьте объекты, к которым будет предоÑтавлен доÑтуп:" #: aleksis/core/forms.py:486 aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "ПредоÑтавить доÑтуп ко вÑем объектам" #: aleksis/core/forms.py:494 aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "" "You must select at least one group or person which should get the permission." msgstr "Вам нужно выбрать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одну группу или физлицо, кто получит доÑтуп." #: aleksis/core/forms.py:499 aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "Ð’Ñ‹ должны предоÑтавить доÑтуп ко вÑем или к конкретным объектам." #: aleksis/core/forms.py:586 aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "ПодробноÑти адреÑа" #: aleksis/core/forms.py:598 aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 msgid "Account data" msgstr "Данные учётной запиÑи" #: aleksis/core/forms.py:605 aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "Пароль" #: aleksis/core/forms.py:608 aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "Пароль (ещё раз)" #: aleksis/core/forms.py:761 aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "Выбранное дейÑтвие не ÑущеÑтвует." #: aleksis/core/forms.py:772 aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "У Ð’Ð°Ñ Ð½ÐµÑ‚ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° запуÑк {} на вÑех выбранных объектах." #: aleksis/core/forms.py:828 aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "Ðеправильный выбор." @@ -303,173 +340,213 @@ msgstr "Ð ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð½Ðµ найдена!" msgid "No backup result found!" msgstr "Результат резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ найден!" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:511 aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "СвÑзанный учебный год" #: aleksis/core/models.py:82 aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "Булево (Да/Ðет)" #: aleksis/core/models.py:83 aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "ТекÑÑ‚ (одна Ñтрока)" #: aleksis/core/models.py:85 aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "Дата и времÑ" #: aleksis/core/models.py:86 aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "ДеÑÑтичное чиÑло" #: aleksis/core/models.py:87 aleksis/core/models.py:210 #: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "ÐÐ´Ñ€ÐµÑ Ñл.почты" #: aleksis/core/models.py:88 aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "Целое" #: aleksis/core/models.py:89 aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "IP адреÑ" #: aleksis/core/models.py:90 aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Булево или пуÑтое (Да/Ðет/Ðичего)" #: aleksis/core/models.py:91 aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "ТекÑÑ‚ (многоÑтрочный)" #: aleksis/core/models.py:93 aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "URL / СÑылка" #: aleksis/core/models.py:105 aleksis/core/models.py:1077 #: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "Полное имÑ" #: aleksis/core/models.py:107 aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "Дата начала" #: aleksis/core/models.py:108 aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "Дата окончаниÑ" #: aleksis/core/models.py:127 aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "Дата начала должна быть ранее даты окончаниÑ." #: aleksis/core/models.py:134 aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "Ðа Ñто Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð»Ð¸ на его чаÑÑ‚ÑŒ уже запланирован учебный год." #: aleksis/core/models.py:142 #: aleksis/core/templates/core/school_term/list.html:8 #: aleksis/core/templates/core/school_term/list.html:9 -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:143 aleksis/core/models.py:155 msgid "School terms" msgstr "Учебный год" #: aleksis/core/models.py:163 aleksis/core/models.py:1026 #: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "Физлицо" #: aleksis/core/models.py:166 aleksis/core/models.py:167 +#: aleksis/core/models.py:179 msgid "Can view address" msgstr "Может видеть адреÑ" #: aleksis/core/models.py:167 aleksis/core/models.py:168 +#: aleksis/core/models.py:180 msgid "Can view contact details" msgstr "Может видеть контактные данные" #: aleksis/core/models.py:168 aleksis/core/models.py:169 +#: aleksis/core/models.py:181 msgid "Can view photo" msgstr "Может видеть фото" #: aleksis/core/models.py:169 aleksis/core/models.py:170 +#: aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "Может видеть аватар" #: aleksis/core/models.py:170 aleksis/core/models.py:171 +#: aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "Может видеть группы лиц" #: aleksis/core/models.py:171 aleksis/core/models.py:172 +#: aleksis/core/models.py:184 msgid "Can view personal details" msgstr "Может видеть личные данные" #: aleksis/core/models.py:181 aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "жен" #: aleksis/core/models.py:181 aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "муж" #: aleksis/core/models.py:181 aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "другой" #: aleksis/core/models.py:189 aleksis/core/models.py:1353 #: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "СвÑзанный пользователь" #: aleksis/core/models.py:195 aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "Дополнительные имена" #: aleksis/core/models.py:199 aleksis/core/models.py:511 #: aleksis/core/models.py:1439 aleksis/core/models.py:200 #: aleksis/core/models.py:512 aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "Короткое имÑ" #: aleksis/core/models.py:202 aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "Улица" #: aleksis/core/models.py:203 aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "Ðомер дома" #: aleksis/core/models.py:204 aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "Почтовый индекÑ" #: aleksis/core/models.py:205 aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "Город/меÑто" #: aleksis/core/models.py:207 aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "Домашний телефон" #: aleksis/core/models.py:208 aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "Мобильный телефон" #: aleksis/core/models.py:212 aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "Дата рождениÑ" #: aleksis/core/models.py:213 aleksis/core/models.py:214 +#: aleksis/core/models.py:226 msgid "Place of birth" msgstr "МеÑто рождениÑ" #: aleksis/core/models.py:214 aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "Пол" #: aleksis/core/models.py:221 aleksis/core/models.py:550 #: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "" "This is an official photo, used for official documents and for internal use " "cases." @@ -478,19 +555,23 @@ msgstr "" #: aleksis/core/models.py:226 aleksis/core/models.py:554 #: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "Отобразить фото/аватар" #: aleksis/core/models.py:229 aleksis/core/models.py:557 #: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "Ðто фото или аватар Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ отображениÑ." #: aleksis/core/models.py:234 aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "Опекуны / Родители" #: aleksis/core/models.py:241 aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°" @@ -499,69 +580,82 @@ msgstr "ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°" #: aleksis/core/models.py:1112 aleksis/core/models.py:245 #: aleksis/core/models.py:725 aleksis/core/models.py:749 #: aleksis/core/models.py:844 aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "ОпиÑание" #: aleksis/core/models.py:464 aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "Ðазвание полÑ" #: aleksis/core/models.py:466 aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "Тип полÑ" #: aleksis/core/models.py:468 aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "Ðеобходимое" #: aleksis/core/models.py:469 aleksis/core/models.py:470 +#: aleksis/core/models.py:492 msgid "Help text / description" msgstr "Ð’Ñпомогательный текÑÑ‚ / опиÑание" #: aleksis/core/models.py:475 aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "Дополнительное поле Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿" #: aleksis/core/models.py:476 aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "Дополнительные Ð¿Ð¾Ð»Ñ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿" #: aleksis/core/models.py:496 aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "Может определÑÑ‚ÑŒ дочерние группы в группы" #: aleksis/core/models.py:497 aleksis/core/models.py:498 +#: aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "Может видеть ÑтатиÑтику группы." #: aleksis/core/models.py:509 aleksis/core/models.py:1440 #: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "Длинное имÑ" #: aleksis/core/models.py:519 aleksis/core/templates/core/group/full.html:105 -#: aleksis/core/models.py:520 +#: aleksis/core/models.py:520 aleksis/core/models.py:542 msgid "Members" msgstr "УчаÑтники" #: aleksis/core/models.py:522 aleksis/core/templates/core/group/full.html:102 -#: aleksis/core/models.py:523 +#: aleksis/core/models.py:523 aleksis/core/models.py:545 msgid "Owners" msgstr "Владельцы" #: aleksis/core/models.py:529 aleksis/core/templates/core/group/full.html:59 -#: aleksis/core/models.py:530 +#: aleksis/core/models.py:530 aleksis/core/models.py:552 msgid "Parent groups" msgstr "РодительÑкие группы" #: aleksis/core/models.py:537 aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "Тип группы" #: aleksis/core/models.py:542 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:543 aleksis/core/models.py:565 msgid "Additional fields" msgstr "Дополнительные полÑ" @@ -570,31 +664,39 @@ msgstr "Дополнительные полÑ" #: aleksis/core/templates/core/announcement/list.html:18 #: aleksis/core/models.py:724 aleksis/core/models.py:748 #: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 msgid "Title" msgstr "Ðазвание" #: aleksis/core/models.py:726 aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "Приложение" #: aleksis/core/models.py:732 aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "ÐктивноÑÑ‚ÑŒ" #: aleksis/core/models.py:733 aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "ÐктивноÑти" #: aleksis/core/models.py:739 aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "Отправитель" #: aleksis/core/models.py:744 aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "Получатель" #: aleksis/core/models.py:749 aleksis/core/models.py:1078 #: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "СÑылка" @@ -602,379 +704,468 @@ msgstr "СÑылка" #: aleksis/core/models.py:1400 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 #: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:1429 aleksis/core/models.py:775 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1451 msgid "Icon" msgstr "Иконка" #: aleksis/core/models.py:755 aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "Отправить уведомление в" #: aleksis/core/models.py:757 aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "Читать" #: aleksis/core/models.py:758 aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "Отправлено" #: aleksis/core/models.py:775 aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "Уведомление" #: aleksis/core/models.py:776 aleksis/core/preferences.py:29 -#: aleksis/core/models.py:777 +#: aleksis/core/models.py:777 aleksis/core/models.py:799 +#: aleksis/core/preferences.py:28 msgid "Notifications" msgstr "УведомлениÑ" #: aleksis/core/models.py:844 aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "СÑылка на подробный обзор" #: aleksis/core/models.py:847 aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "Дата и времÑ, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ показывать" #: aleksis/core/models.py:850 aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "Дата и времÑ, по какое показывать" #: aleksis/core/models.py:875 aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "ОбъÑвление" #: aleksis/core/models.py:876 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:877 aleksis/core/models.py:899 msgid "Announcements" msgstr "ОбъÑвление" #: aleksis/core/models.py:913 aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "Получатель объÑвлениÑ" #: aleksis/core/models.py:914 aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "Получатели объÑвлениÑ" #: aleksis/core/models.py:934 aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "Ðазвание виджета" #: aleksis/core/models.py:935 aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "Ðктивировать виджет" #: aleksis/core/models.py:936 aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "Виджет поломалÑÑ" #: aleksis/core/models.py:939 aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "Размер на мобильных" #: aleksis/core/models.py:940 aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "<= 600 пикÑ, 12 Ñтолбцов" #: aleksis/core/models.py:945 aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "Размер на планшетах" #: aleksis/core/models.py:946 aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "> 600 пикÑ, 12 Ñтолбцов" #: aleksis/core/models.py:951 aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "Размер на ПК" #: aleksis/core/models.py:952 aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "> 992 пикÑ, 12 Ñтолбцов" #: aleksis/core/models.py:957 aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "Размер Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… Ñкранов" #: aleksis/core/models.py:958 aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "> 1200 пикÑ, 12 Ñтолбцов" #: aleksis/core/models.py:989 aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "Может редактировать типовую/Ñтандартную информпанель" #: aleksis/core/models.py:990 aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "Виджет информпанели" #: aleksis/core/models.py:991 aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "Виджеты информпанели" #: aleksis/core/models.py:997 aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "URL" #: aleksis/core/models.py:998 aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "Иконка URL" #: aleksis/core/models.py:1004 aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "ВнешнÑÑ ÑÑылка на виджет" #: aleksis/core/models.py:1005 aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "Внешние ÑÑылки на виджеты" #: aleksis/core/models.py:1011 aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "Содержимое" #: aleksis/core/models.py:1017 aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "Виджет Ñ Ð¿Ð¾ÑтоÑнным Ñодержимым" #: aleksis/core/models.py:1018 aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "Виджеты Ñ Ð¿Ð¾ÑтоÑнным Ñодержимым" #: aleksis/core/models.py:1023 aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "Виджет информпанели" #: aleksis/core/models.py:1028 aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "ПорÑдок" #: aleksis/core/models.py:1029 aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "ЧаÑÑ‚ÑŒ типовой информпанели" #: aleksis/core/models.py:1044 aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "ПорÑдок виджета на информпанели" #: aleksis/core/models.py:1045 aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "ПорÑдок виджетов на информпанели" #: aleksis/core/models.py:1051 aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "Меню ID" #: aleksis/core/models.py:1064 aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "ПользовательÑкое меню" #: aleksis/core/models.py:1065 aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "ПользовательÑкие меню" #: aleksis/core/models.py:1075 aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "Меню" #: aleksis/core/models.py:1085 aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "Пункт пользовательÑкого меню" #: aleksis/core/models.py:1086 aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "Пункты пользовательÑкого меню" #: aleksis/core/models.py:1111 aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "Ðазвание типа" #: aleksis/core/models.py:1118 aleksis/core/templates/core/group/full.html:50 -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1119 aleksis/core/models.py:1141 msgid "Group type" msgstr "Тип группы" #: aleksis/core/models.py:1119 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1120 aleksis/core/models.py:1142 msgid "Group types" msgstr "Типы групп" #: aleksis/core/models.py:1132 aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 msgid "Can view system status" msgstr "Может проÑматривать ÑоÑтоÑние ÑиÑтемы" #: aleksis/core/models.py:1133 aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "Может управлÑÑ‚ÑŒ данными" #: aleksis/core/models.py:1134 aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "Может маÑкироватьÑÑ" #: aleksis/core/models.py:1135 aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "Может иÑпользовать поиÑк" #: aleksis/core/models.py:1136 aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "Может менÑÑ‚ÑŒ ÑвойÑтва Ñайта" #: aleksis/core/models.py:1137 aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "Может менÑÑ‚ÑŒ перÑональные ÑвойÑтва" #: aleksis/core/models.py:1138 aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "Может менÑÑ‚ÑŒ ÑвойÑтва группы" #: aleksis/core/models.py:1139 aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "Может генерировать теÑтовые PDF" #: aleksis/core/models.py:1140 aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "Может приглашать других" #: aleksis/core/models.py:1176 aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "Задание проверки ÑвÑзанных данных" #: aleksis/core/models.py:1184 aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "Проблема решена" #: aleksis/core/models.py:1185 aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "Уведомление отправлено" #: aleksis/core/models.py:1198 aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "Результат проверки данных" #: aleksis/core/models.py:1199 aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "Результаты проверки данных" #: aleksis/core/models.py:1201 aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "Может запуÑкать проверки данных" #: aleksis/core/models.py:1202 aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "Может решать проблемы проверки данных" #: aleksis/core/models.py:1209 aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "ÐÐ´Ñ€ÐµÑ Ñл.почты" #: aleksis/core/models.py:1241 aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "Владелец" #: aleksis/core/models.py:1245 aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "Файл дейÑтвителен до" #: aleksis/core/models.py:1248 aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "Сгенерированный файл HTML" #: aleksis/core/models.py:1251 aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "Сгенерированный файл PDF" #: aleksis/core/models.py:1258 aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "Файл PDF" #: aleksis/core/models.py:1259 aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "Файлы PDF" #: aleksis/core/models.py:1264 aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "Результат заданиÑ" #: aleksis/core/models.py:1267 aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "Пользователь заданиÑ" #: aleksis/core/models.py:1271 aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "URL Ð´Ð»Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‚Ð°" #: aleksis/core/models.py:1272 aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "Ðазвание процеÑÑа" #: aleksis/core/models.py:1273 aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "Сообщение об ошибке" #: aleksis/core/models.py:1274 aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "Сообщение об уÑпехе" #: aleksis/core/models.py:1275 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "URL Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² Ñлучае уÑпеха" #: aleksis/core/models.py:1277 aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 msgid "Additional button title" msgstr "Ðазвание дополнительной кнопки" #: aleksis/core/models.py:1279 aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "URL дополнительной кнопки" #: aleksis/core/models.py:1281 aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "Иконка дополнительной кнопки" #: aleksis/core/models.py:1283 aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "Полученный результат" #: aleksis/core/models.py:1308 aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "Фоновое задание уÑпешно завершено" #: aleksis/core/models.py:1309 aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "Фоновое задание \"{}\" уÑпешно завершено." #: aleksis/core/models.py:1315 aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "Ошибка фонового заданиÑ" #: aleksis/core/models.py:1316 aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "Ошибка фонового Ð·Ð°Ð´Ð°Ð½Ð¸Ñ \"{}\"." #: aleksis/core/models.py:1325 aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "Фоновое задание" #: aleksis/core/models.py:1339 aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "Ðазначение Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ" #: aleksis/core/models.py:1340 aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ заданиÑ" #: aleksis/core/models.py:1356 aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "Дополнительные атрибуты" #: aleksis/core/models.py:1394 aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "Разрешённые пределы дейÑтвиÑ, которые могут запрашивать клиенты" #: aleksis/core/models.py:1404 aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "" "This image will be shown as icon in the authorization flow. It should be " "squared." @@ -983,46 +1174,49 @@ msgstr "" "Должно быть квадратным." #: aleksis/core/models.py:1449 aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "Может проÑмативать раÑпиÑание комнаты" #: aleksis/core/models.py:1451 aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "Комната" #: aleksis/core/models.py:1452 aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "Комнаты" -#: aleksis/core/preferences.py:25 +#: aleksis/core/preferences.py:25 aleksis/core/preferences.py:24 msgid "General" msgstr "Общее" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:26 aleksis/core/preferences.py:25 msgid "School" msgstr "Школа / уч.заведение" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:27 aleksis/core/preferences.py:26 msgid "Theme" msgstr "Тема" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:28 aleksis/core/preferences.py:27 msgid "Mail" msgstr "Почта" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:30 aleksis/core/preferences.py:29 msgid "Footer" msgstr "Ðижний колонтитул (подвал)" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:31 aleksis/core/preferences.py:30 msgid "Accounts" msgstr "Учётные запиÑи" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:32 aleksis/core/preferences.py:31 msgid "Authentication" msgstr "ÐвторизациÑ" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:33 aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "ИнтернационализациÑ" @@ -1232,7 +1426,8 @@ msgstr "Редактировать" #: aleksis/core/tables.py:27 aleksis/core/tables.py:148 #: aleksis/core/tables.py:192 #: aleksis/core/templates/core/announcement/list.html:22 -#: aleksis/core/tables.py:185 +#: aleksis/core/tables.py:185 aleksis/core/tables.py:130 +#: aleksis/core/tables.py:167 msgid "Actions" msgstr "ДейÑтвиÑ" @@ -1243,7 +1438,9 @@ msgstr "ДейÑтвиÑ" #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:183 aleksis/core/tables.py:97 +#: aleksis/core/tables.py:98 aleksis/core/tables.py:112 +#: aleksis/core/tables.py:128 aleksis/core/tables.py:165 msgid "Delete" msgstr "Удалить" @@ -3304,15 +3501,18 @@ msgid "The school term has been saved." msgstr "Учебный год Ñохранён." #: aleksis/core/views.py:396 aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "Дочерние группы Ñохранены." #: aleksis/core/views.py:415 aleksis/core/views.py:425 #: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "Физлицо Ñохранено." #: aleksis/core/views.py:475 aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "Группа Ñохранена." @@ -3462,7 +3662,8 @@ msgid "" " " msgstr "" "\n" -" ДоÑтуп к Ñайту имеют только админиÑтратор и пользователи Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½Ð¸Ð¼Ð¸ IP-адреÑами.\n" +" ДоÑтуп к Ñайту имеют только админиÑтратор и пользователи Ñ " +"внутренними IP-адреÑами.\n" " " #: aleksis/core/templates/offline.html:10 @@ -3479,8 +3680,10 @@ msgid "" " " msgstr "" "\n" -" Ðта Ñтраница без ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ñервером недоÑтупна. Проверьте наличие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº интернету и повторите попытку.\n" -" ЕÑли интернет работает и ошибка вÑÑ‘ равно приÑутÑтвует, обратитеÑÑŒ, пожалуйÑта, к ÑиÑтемным админиÑтраторам:\n" +" Ðта Ñтраница без ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ñервером недоÑтупна. Проверьте наличие " +"Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº интернету и повторите попытку.\n" +" ЕÑли интернет работает и ошибка вÑÑ‘ равно приÑутÑтвует, обратитеÑÑŒ, " +"пожалуйÑта, к ÑиÑтемным админиÑтраторам:\n" " " #: aleksis/core/templates/templated_email/invitation.email:4 @@ -3500,7 +3703,9 @@ msgstr "Привет, %(person)s" msgid "" "you have been invited to register on %(site)s. If you would like to accept " "this invitation, please click on the following link:" -msgstr "Ð’Ñ‹ приглашены зарегиÑтрироватьÑÑ Ð½Ð° %(site)s. ЕÑли хотите принÑÑ‚ÑŒ приглашение, перейдите по указанной ÑÑылке:" +msgstr "" +"Ð’Ñ‹ приглашены зарегиÑтрироватьÑÑ Ð½Ð° %(site)s. ЕÑли хотите принÑÑ‚ÑŒ " +"приглашение, перейдите по указанной ÑÑылке:" #: aleksis/core/views.py:528 msgid "Maintenance mode was turned on successfully." @@ -3510,6 +3715,86 @@ msgstr "Режим обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑƒÑпешно активирова msgid "Maintenance mode was turned off successfully." msgstr "Режим обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑƒÑпешно выключен." +#: aleksis/core/models.py:1528 +#, fuzzy +msgid "Start date and time" +msgstr "Дата и времÑ" + +#: aleksis/core/models.py:1530 +#, fuzzy +msgid "End date and time" +msgstr "Дата и времÑ" + +#: aleksis/core/models.py:1531 +#, fuzzy +msgid "Timezone" +msgstr "ВремÑ" + +#: aleksis/core/models.py:1534 +#, fuzzy +msgid "Recurrences" +msgstr "СвойÑтва" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +#, fuzzy +msgid "Calendar Event" +msgstr "Ленты календарей" + +#: aleksis/core/models.py:1644 +#, fuzzy +msgid "Calendar Events" +msgstr "Ленты календарей" + +#: aleksis/core/models.py:1670 +#, fuzzy +msgid "Birthdays" +msgstr "Календарь Дней РождениÑ" + +#: aleksis/core/models.py:1674 +#, fuzzy +msgid "{}'s birthday" +msgstr "%(name)s отмечает День РождениÑ" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:33 +#, fuzzy +msgid "Calendar" +msgstr "Ленты календарей" + +#: aleksis/core/preferences.py:490 +#, fuzzy +msgid "Birthday calendar feed color" +msgstr "Календарь Дней РождениÑ" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +#, fuzzy +msgid "Activated calendars" +msgstr "Календарь Дней РождениÑ" + +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and " +"your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following " +"link:" +msgstr "" + #~ msgid "" #~ "\n" #~ " This page is currently unavailable. If this error persists, " diff --git a/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po index 1b5c47ccd08980e07aac8228d3be70924eca2ede..1e24c46a4d2b614b7cfd792269a18fc6b606a37e 100644 --- a/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po +++ b/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-09 18:40+0200\n" +"POT-Creation-Date: 2023-07-23 13:39+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -41,8 +41,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:166 aleksis/core/forms.py:221 -#: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 +#: aleksis/core/apps.py:166 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 aleksis/core/templates/core/group/list.html:8 #: aleksis/core/templates/core/group/list.html:9 msgid "Groups" msgstr "" @@ -101,172 +101,172 @@ msgstr "" msgid "Content type" msgstr "" -#: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/filters.py:113 aleksis/core/models.py:743 msgid "User" msgstr "" -#: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/filters.py:135 aleksis/core/models.py:516 msgid "Group" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:50 aleksis/core/forms.py:591 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:55 aleksis/core/tables.py:29 msgid "Address" msgstr "" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:56 aleksis/core/forms.py:600 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "New user" msgstr "" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:106 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:156 aleksis/core/forms.py:208 -#: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:218 +#: aleksis/core/models.py:177 aleksis/core/templates/core/person/list.html:8 #: aleksis/core/templates/core/person/list.html:9 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:158 aleksis/core/models.py:218 -#: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/forms.py:210 aleksis/core/forms.py:213 +#: aleksis/core/models.py:97 msgid "Date" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:211 aleksis/core/forms.py:214 +#: aleksis/core/models.py:105 msgid "Time" msgstr "" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:277 +#: aleksis/core/forms.py:287 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:408 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "" -#: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:467 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:495 +#: aleksis/core/forms.py:504 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:596 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:608 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:615 msgid "Password" msgstr "" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:618 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:838 msgid "No valid selection." msgstr "" @@ -290,697 +290,744 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:96 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:98 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:99 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:101 msgid "Integer" msgstr "" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:102 msgid "IP address" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:106 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:120 aleksis/core/models.py:1532 msgid "Start date" msgstr "" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:121 aleksis/core/models.py:1533 msgid "End date" msgstr "" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:140 aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:147 aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:143 -#: aleksis/core/templates/core/school_term/list.html:8 -#: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "" -#: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:179 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:180 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:181 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:184 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "female" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "male" msgstr "" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:194 msgid "other" msgstr "" -#: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:212 aleksis/core/models.py:534 +#: aleksis/core/models.py:1490 msgid "Short name" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:215 msgid "Street" msgstr "" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:216 msgid "Street number" msgstr "" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:217 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:218 msgid "Place" msgstr "" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:220 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:221 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:225 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:226 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:227 msgid "Sex" msgstr "" -#: aleksis/core/models.py:222 aleksis/core/models.py:551 +#: aleksis/core/models.py:234 aleksis/core/models.py:573 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:254 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:245 aleksis/core/models.py:725 -#: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:257 aleksis/core/models.py:747 +#: aleksis/core/models.py:771 aleksis/core/models.py:866 +#: aleksis/core/models.py:1135 msgid "Description" msgstr "" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:487 msgid "Title of field" msgstr "" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:489 msgid "Type of field" msgstr "" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:491 msgid "Required" msgstr "" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:492 msgid "Help text / description" msgstr "" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "" -#: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 aleksis/core/templates/core/group/full.html:105 msgid "Members" msgstr "" -#: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 aleksis/core/templates/core/group/full.html:102 msgid "Owners" msgstr "" -#: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 aleksis/core/templates/core/group/full.html:59 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:560 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:543 +#: aleksis/core/models.py:565 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 msgid "Additional fields" msgstr "" -#: aleksis/core/models.py:724 aleksis/core/models.py:748 -#: aleksis/core/models.py:843 aleksis/core/models.py:1299 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:749 msgid "Application" msgstr "" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:755 msgid "Activity" msgstr "" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:756 msgid "Activities" msgstr "" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:762 msgid "Sender" msgstr "" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:767 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "" -#: aleksis/core/models.py:753 aleksis/core/models.py:1080 -#: aleksis/core/models.py:1429 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:778 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:780 msgid "Read" msgstr "" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:781 msgid "Sent" msgstr "" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:798 msgid "Notification" msgstr "" -#: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:898 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:877 +#: aleksis/core/models.py:899 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:957 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:958 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:959 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:1020 msgid "URL" msgstr "" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:1021 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1027 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1028 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1034 msgid "Content" msgstr "" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1040 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1051 msgid "Order" msgstr "" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1074 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1087 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1088 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1098 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1134 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 aleksis/core/templates/core/group/full.html:50 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1142 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1155 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1156 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1158 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1199 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1207 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1208 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1221 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1222 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1292 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1296 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1309 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1310 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1315 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1318 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1322 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1323 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1324 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1325 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1328 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1334 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1366 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1376 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1433 +#: aleksis/core/models.py:1455 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1502 msgid "Room" msgstr "" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1503 msgid "Rooms" msgstr "" -#: aleksis/core/preferences.py:25 +#: aleksis/core/models.py:1528 +msgid "Start date and time" +msgstr "" + +#: aleksis/core/models.py:1530 +msgid "End date and time" +msgstr "" + +#: aleksis/core/models.py:1531 +msgid "Timezone" +msgstr "" + +#: aleksis/core/models.py:1534 +msgid "Recurrences" +msgstr "" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +msgid "Calendar Event" +msgstr "" + +#: aleksis/core/models.py:1644 +msgid "Calendar Events" +msgstr "" + +#: aleksis/core/models.py:1670 +msgid "Birthdays" +msgstr "" + +#: aleksis/core/models.py:1674 +msgid "{}'s birthday" +msgstr "" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:24 msgid "General" msgstr "" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:25 msgid "School" msgstr "" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:26 msgid "Theme" msgstr "" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:27 msgid "Mail" msgstr "" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:29 msgid "Footer" msgstr "" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:30 msgid "Accounts" msgstr "" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:31 msgid "Authentication" msgstr "" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "" +#: aleksis/core/preferences.py:33 +msgid "Calendar" +msgstr "" + #: aleksis/core/preferences.py:43 msgid "Site title" msgstr "" @@ -1154,7 +1201,15 @@ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" #: aleksis/core/preferences.py:490 -msgid "Country for phone number parsing" +msgid "Birthday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Activated calendars" msgstr "" #: aleksis/core/settings.py:551 @@ -1169,22 +1224,9 @@ msgstr "" msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:25 -#: aleksis/core/templates/core/announcement/list.html:36 -#: aleksis/core/templates/core/group/full.html:26 -#: aleksis/core/templates/oauth2_provider/application/detail.html:17 -msgid "Edit" -msgstr "" - -#: aleksis/core/tables.py:27 aleksis/core/tables.py:148 -#: aleksis/core/tables.py:185 -#: aleksis/core/templates/core/announcement/list.html:22 -msgid "Actions" -msgstr "" - -#: aleksis/core/tables.py:115 aleksis/core/tables.py:116 -#: aleksis/core/tables.py:130 aleksis/core/tables.py:146 -#: aleksis/core/tables.py:183 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 @@ -1192,6 +1234,11 @@ msgstr "" msgid "Delete" msgstr "" +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 +#: aleksis/core/templates/core/announcement/list.html:22 +msgid "Actions" +msgstr "" + #: aleksis/core/templates/403.html:14 aleksis/core/templates/500.html:10 #: aleksis/core/templates/oauth2_provider/authorize.html:54 msgid "Error" @@ -1262,6 +1309,13 @@ msgstr "" msgid "Your AlekSIS team" msgstr "" +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following link:" +msgstr "" + #: aleksis/core/templates/account/email_confirm.html:5 #: aleksis/core/templates/account/email_confirm.html:6 #: aleksis/core/templates/account/email_confirm.html:17 @@ -1494,6 +1548,12 @@ msgstr "" msgid "Recipients" msgstr "" +#: aleksis/core/templates/core/announcement/list.html:36 +#: aleksis/core/templates/core/group/full.html:26 +#: aleksis/core/templates/oauth2_provider/application/detail.html:17 +msgid "Edit" +msgstr "" + #: aleksis/core/templates/core/announcement/list.html:50 msgid "There are no announcements." msgstr "" @@ -2042,17 +2102,6 @@ msgstr "" msgid "Selected persons" msgstr "" -#: aleksis/core/templates/core/school_term/create.html:6 -#: aleksis/core/templates/core/school_term/create.html:7 -#: aleksis/core/templates/core/school_term/list.html:14 -msgid "Create school term" -msgstr "" - -#: aleksis/core/templates/core/school_term/edit.html:6 -#: aleksis/core/templates/core/school_term/edit.html:7 -msgid "Edit school term" -msgstr "" - #: aleksis/core/templates/dynamic_preferences/form.html:5 msgid "Preferences" msgstr "" @@ -2812,156 +2861,148 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:285 -msgid "The school term has been created." -msgstr "" - -#: aleksis/core/views.py:297 -msgid "The school term has been saved." -msgstr "" - -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "" -#: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:450 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:528 +#: aleksis/core/views.py:498 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:530 +#: aleksis/core/views.py:500 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "" -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "" -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "" -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "" -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "" -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:859 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1382 +#: aleksis/core/views.py:1352 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1465 +#: aleksis/core/views.py:1435 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "" diff --git a/aleksis/core/locale/uk/LC_MESSAGES/django.po b/aleksis/core/locale/uk/LC_MESSAGES/django.po index 1df9b63ac1233d19055d59ba64c7b081ccd1b70f..5cd5dc251e9a975a8cec68dee5e656ba8c081e8e 100644 --- a/aleksis/core/locale/uk/LC_MESSAGES/django.po +++ b/aleksis/core/locale/uk/LC_MESSAGES/django.po @@ -10,12 +10,16 @@ msgstr "" "POT-Creation-Date: 2023-02-27 13:23+0100\n" "PO-Revision-Date: 2023-07-04 04:21+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" -"Language-Team: Ukrainian <https://translate.edugit.org/projects/aleksis/aleksis-core/uk/>\n" +"Language-Team: Ukrainian <https://translate.edugit.org/projects/aleksis/" +"aleksis-core/uk/>\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" +"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != " +"11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % " +"100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || " +"(n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" "X-Generator: Weblate 4.12.1\n" #: aleksis/core/apps.py:151 @@ -44,7 +48,8 @@ msgstr "Домашній та мобільний телефони" #: aleksis/core/apps.py:166 aleksis/core/forms.py:221 #: aleksis/core/models.py:495 aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/templates/core/group/list.html:9 aleksis/core/forms.py:231 +#: aleksis/core/models.py:517 msgid "Groups" msgstr "Групи" @@ -103,171 +108,188 @@ msgid "Content type" msgstr "Тип зміÑту" #: aleksis/core/filters.py:113 aleksis/core/models.py:721 +#: aleksis/core/models.py:743 msgid "User" msgstr "КориÑтувач" #: aleksis/core/filters.py:135 aleksis/core/models.py:494 +#: aleksis/core/models.py:516 msgid "Group" msgstr "Група" -#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 +#: aleksis/core/forms.py:51 aleksis/core/forms.py:582 aleksis/core/forms.py:50 +#: aleksis/core/forms.py:591 msgid "Base data" msgstr "ОÑновні дані" -#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 +#: aleksis/core/forms.py:56 aleksis/core/tables.py:47 aleksis/core/forms.py:55 +#: aleksis/core/tables.py:29 msgid "Address" msgstr "ÐдреÑа" -#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 +#: aleksis/core/forms.py:57 aleksis/core/forms.py:591 aleksis/core/forms.py:56 +#: aleksis/core/forms.py:600 msgid "Contact data" msgstr "Контактні дані" -#: aleksis/core/forms.py:59 +#: aleksis/core/forms.py:59 aleksis/core/forms.py:58 msgid "Advanced personal data" msgstr "Додаткові оÑобиÑÑ‚Ñ– дані" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:107 aleksis/core/forms.py:106 msgid "New user" msgstr "Ðовий кориÑтувач" -#: aleksis/core/forms.py:107 +#: aleksis/core/forms.py:107 aleksis/core/forms.py:106 msgid "Create a new account" msgstr "Створити новий обліковий запиÑ" -#: aleksis/core/forms.py:133 +#: aleksis/core/forms.py:133 aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "Обравши вже Ñ–Ñнуючого кориÑтувача неможливо Ñтворити новий логін." -#: aleksis/core/forms.py:137 +#: aleksis/core/forms.py:137 aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Такий логін вже зайнÑтий." #: aleksis/core/forms.py:154 aleksis/core/models.py:142 +#: aleksis/core/forms.py:153 aleksis/core/models.py:154 msgid "School term" msgstr "Ðавчальний рік" -#: aleksis/core/forms.py:155 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:154 msgid "Common data" msgstr "Загальні дані" #: aleksis/core/forms.py:156 aleksis/core/forms.py:208 #: aleksis/core/models.py:165 aleksis/core/templates/core/person/list.html:8 -#: aleksis/core/templates/core/person/list.html:9 +#: aleksis/core/templates/core/person/list.html:9 aleksis/core/forms.py:155 +#: aleksis/core/forms.py:218 aleksis/core/models.py:177 msgid "Persons" msgstr "ОÑоби" #: aleksis/core/forms.py:157 aleksis/core/forms.py:593 +#: aleksis/core/forms.py:156 aleksis/core/forms.py:602 msgid "Additional data" msgstr "Додаткові дані" #: aleksis/core/forms.py:158 aleksis/core/models.py:218 #: aleksis/core/models.py:547 aleksis/core/tables.py:46 +#: aleksis/core/forms.py:157 aleksis/core/models.py:230 +#: aleksis/core/models.py:569 aleksis/core/tables.py:28 msgid "Photo" msgstr "Фото" #: aleksis/core/forms.py:200 aleksis/core/forms.py:203 -#: aleksis/core/models.py:85 +#: aleksis/core/models.py:85 aleksis/core/forms.py:210 +#: aleksis/core/forms.py:213 aleksis/core/models.py:97 msgid "Date" msgstr "Дата" #: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/models.py:93 aleksis/core/forms.py:211 +#: aleksis/core/forms.py:214 aleksis/core/models.py:105 msgid "Time" msgstr "ЧаÑ" -#: aleksis/core/forms.py:234 +#: aleksis/core/forms.py:234 aleksis/core/forms.py:244 msgid "From when until when should the announcement be displayed?" msgstr "З Ñкого по Ñкий Ñ‡Ð°Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð¾ відображатиÑÑ Ñ†Ðµ оголошеннÑ?" -#: aleksis/core/forms.py:237 +#: aleksis/core/forms.py:237 aleksis/core/forms.py:247 msgid "Who should see the announcement?" msgstr "Хто повинен бачити це оголошеннÑ?" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:238 aleksis/core/forms.py:248 msgid "Write your announcement:" msgstr "Складіть Ñвоє оголошенÑ:" -#: aleksis/core/forms.py:277 -msgid "You are not allowed to create announcements which are only valid in the past." +#: aleksis/core/forms.py:277 aleksis/core/forms.py:287 +msgid "" +"You are not allowed to create announcements which are only valid in the past." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¼Ð¸Ð½ÑƒÐ»Ð¾Ð³Ð¾ Вам Ñтворювати не дозволено." -#: aleksis/core/forms.py:281 +#: aleksis/core/forms.py:281 aleksis/core/forms.py:291 msgid "The from date and time must be earlier then the until date and time." msgstr "Дата Ñ– Ñ‡Ð°Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ повинні бути раніше за дату Ñ– Ñ‡Ð°Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ." -#: aleksis/core/forms.py:290 +#: aleksis/core/forms.py:290 aleksis/core/forms.py:300 msgid "You need at least one recipient." msgstr "Вам потрібен принаймні один отримувач." -#: aleksis/core/forms.py:399 +#: aleksis/core/forms.py:399 aleksis/core/forms.py:408 msgid "Invitation code" msgstr "Код запрошеннÑ" -#: aleksis/core/forms.py:400 +#: aleksis/core/forms.py:400 aleksis/core/forms.py:409 msgid "Please enter your invitation code." msgstr "Ðапишіть, будь лаÑка, Ñвій код запрошеннÑ." #: aleksis/core/forms.py:419 aleksis/core/models.py:193 +#: aleksis/core/forms.py:428 aleksis/core/models.py:205 msgid "First name" msgstr "Ім'Ñ" #: aleksis/core/forms.py:420 aleksis/core/models.py:194 +#: aleksis/core/forms.py:429 aleksis/core/models.py:206 msgid "Last name" msgstr "Прізвище" -#: aleksis/core/forms.py:429 +#: aleksis/core/forms.py:429 aleksis/core/forms.py:438 msgid "A person is using this e-mail address" msgstr "Цією ел.адреÑою хтоÑÑŒ кориÑтуєтьÑÑ" -#: aleksis/core/forms.py:457 +#: aleksis/core/forms.py:457 aleksis/core/forms.py:466 msgid "Who should get the permission?" msgstr "Хто повинен отримати такий дозвіл?" -#: aleksis/core/forms.py:458 +#: aleksis/core/forms.py:458 aleksis/core/forms.py:467 msgid "On what?" msgstr "Ð’ разі чого?" -#: aleksis/core/forms.py:484 +#: aleksis/core/forms.py:484 aleksis/core/forms.py:493 msgid "Select objects which the permission should be granted for:" msgstr "Оберіть об'єкти, до Ñких буде наданий дозвіл:" -#: aleksis/core/forms.py:487 +#: aleksis/core/forms.py:487 aleksis/core/forms.py:496 msgid "Grant the permission for all objects" msgstr "Ðадати дозвіл до вÑÑ–Ñ… об'єктів" -#: aleksis/core/forms.py:495 -msgid "You must select at least one group or person which should get the permission." -msgstr "Ви повинні обрати принаймні одну групу або оÑобу, хто буде мати дозвіл." +#: aleksis/core/forms.py:495 aleksis/core/forms.py:504 +msgid "" +"You must select at least one group or person which should get the permission." +msgstr "" +"Ви повинні обрати принаймні одну групу або оÑобу, хто буде мати дозвіл." -#: aleksis/core/forms.py:500 +#: aleksis/core/forms.py:500 aleksis/core/forms.py:509 msgid "You must grant the permission to all objects or to specific objects." msgstr "Ви повинні надати дозвіл до вÑÑ–Ñ… або до конкретних об'єктів." -#: aleksis/core/forms.py:587 +#: aleksis/core/forms.py:587 aleksis/core/forms.py:596 msgid "Address data" msgstr "Дані адреÑи" -#: aleksis/core/forms.py:599 +#: aleksis/core/forms.py:599 aleksis/core/forms.py:608 msgid "Account data" msgstr "Дані облікового запиÑу" -#: aleksis/core/forms.py:606 +#: aleksis/core/forms.py:606 aleksis/core/forms.py:615 msgid "Password" msgstr "Пароль" -#: aleksis/core/forms.py:609 +#: aleksis/core/forms.py:609 aleksis/core/forms.py:618 msgid "Password (again)" msgstr "Пароль (ще раз)" -#: aleksis/core/forms.py:762 +#: aleksis/core/forms.py:762 aleksis/core/forms.py:771 msgid "The selected action does not exist." msgstr "Обрана Ð´Ñ–Ñ Ð½Ðµ Ñ–Ñнує." -#: aleksis/core/forms.py:773 +#: aleksis/core/forms.py:773 aleksis/core/forms.py:782 msgid "You do not have permission to run {} on all selected objects." msgstr "У Ð’Ð°Ñ Ð²Ñ–Ð´Ñутній дозвіл на запуÑк {} на уÑÑ–Ñ… обраних об'єктах." -#: aleksis/core/forms.py:829 +#: aleksis/core/forms.py:829 aleksis/core/forms.py:838 msgid "No valid selection." msgstr "Ðеправильний вибір." @@ -291,694 +313,730 @@ msgstr "Резервна ÐºÐ¾Ð¿Ñ–Ñ Ð½Ðµ знайдена!" msgid "No backup result found!" msgstr "Результат резервного ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð½Ðµ знайдений!" -#: aleksis/core/mixins.py:511 +#: aleksis/core/mixins.py:511 aleksis/core/mixins.py:539 msgid "Linked school term" msgstr "Пов'Ñзаний навчальний рік" -#: aleksis/core/models.py:83 +#: aleksis/core/models.py:83 aleksis/core/models.py:95 msgid "Boolean (Yes/No)" msgstr "Логічне (Так/ÐÑ–)" -#: aleksis/core/models.py:84 +#: aleksis/core/models.py:84 aleksis/core/models.py:96 msgid "Text (one line)" msgstr "ТекÑÑ‚ (один Ñ€Ñдок)" -#: aleksis/core/models.py:86 +#: aleksis/core/models.py:86 aleksis/core/models.py:98 msgid "Date and time" msgstr "Дата Ñ– чаÑ" -#: aleksis/core/models.py:87 +#: aleksis/core/models.py:87 aleksis/core/models.py:99 msgid "Decimal number" msgstr "ДеÑÑтичне чиÑло" #: aleksis/core/models.py:88 aleksis/core/models.py:211 +#: aleksis/core/models.py:100 aleksis/core/models.py:223 msgid "E-mail address" msgstr "ÐдреÑа ел.пошти" -#: aleksis/core/models.py:89 +#: aleksis/core/models.py:89 aleksis/core/models.py:101 msgid "Integer" msgstr "Ціле" -#: aleksis/core/models.py:90 +#: aleksis/core/models.py:90 aleksis/core/models.py:102 msgid "IP address" msgstr "IP адреÑа" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:91 aleksis/core/models.py:103 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Логічне або порожнє (Так/ÐÑ–/Ðічого)" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:92 aleksis/core/models.py:104 msgid "Text (multi-line)" msgstr "ТекÑÑ‚ (багаторÑдковий)" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:94 aleksis/core/models.py:106 msgid "URL / Link" msgstr "URL / ПоÑиланнÑ" #: aleksis/core/models.py:106 aleksis/core/models.py:1078 +#: aleksis/core/models.py:118 aleksis/core/models.py:1100 +#: aleksis/core/models.py:1729 msgid "Name" msgstr "Повне ім'Ñ" -#: aleksis/core/models.py:108 +#: aleksis/core/models.py:108 aleksis/core/models.py:120 +#: aleksis/core/models.py:1532 msgid "Start date" msgstr "Дата початку" -#: aleksis/core/models.py:109 +#: aleksis/core/models.py:109 aleksis/core/models.py:121 +#: aleksis/core/models.py:1533 msgid "End date" msgstr "Дата закінченнÑ" -#: aleksis/core/models.py:128 +#: aleksis/core/models.py:128 aleksis/core/models.py:140 +#: aleksis/core/schema/school_term.py:48 msgid "The start date must be earlier than the end date." msgstr "Початкова дата повинна бути раніше кінцевої." -#: aleksis/core/models.py:135 +#: aleksis/core/models.py:135 aleksis/core/models.py:147 +#: aleksis/core/schema/school_term.py:53 msgid "There is already a school term for this time or a part of this time." msgstr "Ðа цей Ñ‡Ð°Ñ Ð°Ð±Ð¾ на чаÑтину цього чаÑу вже припадає навчальний рік." #: aleksis/core/models.py:143 #: aleksis/core/templates/core/school_term/list.html:8 #: aleksis/core/templates/core/school_term/list.html:9 +#: aleksis/core/models.py:155 msgid "School terms" msgstr "Ðавчальний рік" #: aleksis/core/models.py:164 aleksis/core/models.py:1027 +#: aleksis/core/models.py:176 aleksis/core/models.py:1049 msgid "Person" msgstr "ОÑоба" -#: aleksis/core/models.py:167 +#: aleksis/core/models.py:167 aleksis/core/models.py:179 msgid "Can view address" msgstr "Може бачити адреÑу" -#: aleksis/core/models.py:168 +#: aleksis/core/models.py:168 aleksis/core/models.py:180 msgid "Can view contact details" msgstr "Може бачити контактні дані" -#: aleksis/core/models.py:169 +#: aleksis/core/models.py:169 aleksis/core/models.py:181 msgid "Can view photo" msgstr "Може бачити фото" -#: aleksis/core/models.py:170 +#: aleksis/core/models.py:170 aleksis/core/models.py:182 msgid "Can view avatar image" msgstr "Може бачити аватар" -#: aleksis/core/models.py:171 +#: aleksis/core/models.py:171 aleksis/core/models.py:183 msgid "Can view persons groups" msgstr "Може бачити групи оÑоби" -#: aleksis/core/models.py:172 +#: aleksis/core/models.py:172 aleksis/core/models.py:184 msgid "Can view personal details" msgstr "Може бачити оÑобиÑÑ‚Ñ– дані" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:182 aleksis/core/models.py:194 msgid "female" msgstr "жін" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:182 aleksis/core/models.py:194 msgid "male" msgstr "чол" -#: aleksis/core/models.py:182 +#: aleksis/core/models.py:182 aleksis/core/models.py:194 msgid "other" msgstr "інший" #: aleksis/core/models.py:190 aleksis/core/models.py:1382 +#: aleksis/core/models.py:202 aleksis/core/models.py:1404 msgid "Linked user" msgstr "Пов'Ñзаний кориÑтувач" -#: aleksis/core/models.py:196 +#: aleksis/core/models.py:196 aleksis/core/models.py:208 msgid "Additional name(s)" msgstr "Додаткові імена" #: aleksis/core/models.py:200 aleksis/core/models.py:512 -#: aleksis/core/models.py:1468 +#: aleksis/core/models.py:1468 aleksis/core/models.py:212 +#: aleksis/core/models.py:534 aleksis/core/models.py:1490 msgid "Short name" msgstr "Коротке ім'Ñ" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:203 aleksis/core/models.py:215 msgid "Street" msgstr "ВулицÑ" -#: aleksis/core/models.py:204 +#: aleksis/core/models.py:204 aleksis/core/models.py:216 msgid "Street number" msgstr "Ðомер будинку" -#: aleksis/core/models.py:205 +#: aleksis/core/models.py:205 aleksis/core/models.py:217 msgid "Postal code" msgstr "Поштовий індекÑ" -#: aleksis/core/models.py:206 +#: aleksis/core/models.py:206 aleksis/core/models.py:218 msgid "Place" msgstr "МіÑто" -#: aleksis/core/models.py:208 +#: aleksis/core/models.py:208 aleksis/core/models.py:220 msgid "Home phone" msgstr "Домашній телефон" -#: aleksis/core/models.py:209 +#: aleksis/core/models.py:209 aleksis/core/models.py:221 msgid "Mobile phone" msgstr "Мобільний телефон" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:213 aleksis/core/models.py:225 msgid "Date of birth" msgstr "Дата народженнÑ" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:214 aleksis/core/models.py:226 msgid "Place of birth" msgstr "МіÑце народженнÑ" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:215 aleksis/core/models.py:227 msgid "Sex" msgstr "Стать" #: aleksis/core/models.py:222 aleksis/core/models.py:551 -msgid "This is an official photo, used for official documents and for internal use cases." -msgstr "Це офіційне фото, Ñке викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð² та внутрішніх потреб." +#: aleksis/core/models.py:234 aleksis/core/models.py:573 +msgid "" +"This is an official photo, used for official documents and for internal use " +"cases." +msgstr "" +"Це офіційне фото, Ñке викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð² та внутрішніх потреб." #: aleksis/core/models.py:227 aleksis/core/models.py:555 +#: aleksis/core/models.py:239 aleksis/core/models.py:577 msgid "Display picture / Avatar" msgstr "Відобразити фото/аватар" #: aleksis/core/models.py:230 aleksis/core/models.py:558 +#: aleksis/core/models.py:242 aleksis/core/models.py:580 msgid "This is a picture or an avatar for public display." msgstr "Це фото або аватар Ð´Ð»Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ відображеннÑ." -#: aleksis/core/models.py:235 +#: aleksis/core/models.py:235 aleksis/core/models.py:247 msgid "Guardians / Parents" msgstr "Опікуни / батьки" -#: aleksis/core/models.py:242 +#: aleksis/core/models.py:242 aleksis/core/models.py:254 msgid "Primary group" msgstr "ОÑновна група" #: aleksis/core/models.py:245 aleksis/core/models.py:725 #: aleksis/core/models.py:749 aleksis/core/models.py:844 -#: aleksis/core/models.py:1113 +#: aleksis/core/models.py:1113 aleksis/core/models.py:257 +#: aleksis/core/models.py:747 aleksis/core/models.py:771 +#: aleksis/core/models.py:866 aleksis/core/models.py:1135 msgid "Description" msgstr "ОпиÑ" -#: aleksis/core/models.py:465 +#: aleksis/core/models.py:465 aleksis/core/models.py:487 msgid "Title of field" msgstr "Ðазва полÑ" -#: aleksis/core/models.py:467 +#: aleksis/core/models.py:467 aleksis/core/models.py:489 msgid "Type of field" msgstr "Тип полÑ" -#: aleksis/core/models.py:469 +#: aleksis/core/models.py:469 aleksis/core/models.py:491 msgid "Required" msgstr "Ðеобхідне" -#: aleksis/core/models.py:470 +#: aleksis/core/models.py:470 aleksis/core/models.py:492 msgid "Help text / description" msgstr "Допоміжний текÑÑ‚/опиÑ" -#: aleksis/core/models.py:476 +#: aleksis/core/models.py:476 aleksis/core/models.py:498 msgid "Addtitional field for groups" msgstr "Додаткове поле Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿" -#: aleksis/core/models.py:477 +#: aleksis/core/models.py:477 aleksis/core/models.py:499 msgid "Addtitional fields for groups" msgstr "Додаткові Ð¿Ð¾Ð»Ñ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿" -#: aleksis/core/models.py:497 +#: aleksis/core/models.py:497 aleksis/core/models.py:519 msgid "Can assign child groups to groups" msgstr "Може призначати підлеглі групи до груп" -#: aleksis/core/models.py:498 +#: aleksis/core/models.py:498 aleksis/core/models.py:520 msgid "Can view statistics about group." msgstr "Може бачити ÑтатиÑтику групи." #: aleksis/core/models.py:510 aleksis/core/models.py:1469 +#: aleksis/core/models.py:532 aleksis/core/models.py:1491 msgid "Long name" msgstr "Довге ім'Ñ" #: aleksis/core/models.py:520 aleksis/core/templates/core/group/full.html:105 +#: aleksis/core/models.py:542 msgid "Members" msgstr "УчаÑники" #: aleksis/core/models.py:523 aleksis/core/templates/core/group/full.html:102 +#: aleksis/core/models.py:545 msgid "Owners" msgstr "ВлаÑники" #: aleksis/core/models.py:530 aleksis/core/templates/core/group/full.html:59 +#: aleksis/core/models.py:552 msgid "Parent groups" msgstr "БатьківÑькі групи" -#: aleksis/core/models.py:538 +#: aleksis/core/models.py:538 aleksis/core/models.py:560 msgid "Type of group" msgstr "Тип групи" #: aleksis/core/models.py:543 #: aleksis/core/templates/core/additional_field/list.html:8 #: aleksis/core/templates/core/additional_field/list.html:9 +#: aleksis/core/models.py:565 msgid "Additional fields" msgstr "Додаткові полÑ" #: aleksis/core/models.py:724 aleksis/core/models.py:748 #: aleksis/core/models.py:843 aleksis/core/models.py:1299 #: aleksis/core/templates/core/announcement/list.html:18 +#: aleksis/core/models.py:746 aleksis/core/models.py:770 +#: aleksis/core/models.py:865 aleksis/core/models.py:1321 msgid "Title" msgstr "Ðазва" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:727 aleksis/core/models.py:749 msgid "Application" msgstr "Додаток" -#: aleksis/core/models.py:733 +#: aleksis/core/models.py:733 aleksis/core/models.py:755 msgid "Activity" msgstr "ÐктивніÑÑ‚ÑŒ" -#: aleksis/core/models.py:734 +#: aleksis/core/models.py:734 aleksis/core/models.py:756 msgid "Activities" msgstr "ÐктивноÑÑ‚Ñ–" -#: aleksis/core/models.py:740 +#: aleksis/core/models.py:740 aleksis/core/models.py:762 msgid "Sender" msgstr "Відправник" -#: aleksis/core/models.py:745 +#: aleksis/core/models.py:745 aleksis/core/models.py:767 msgid "Recipient" msgstr "Отримувач" #: aleksis/core/models.py:750 aleksis/core/models.py:1079 +#: aleksis/core/models.py:772 aleksis/core/models.py:1101 msgid "Link" msgstr "ПоÑиланнÑ" #: aleksis/core/models.py:753 aleksis/core/models.py:1080 #: aleksis/core/models.py:1429 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 +#: aleksis/core/models.py:775 aleksis/core/models.py:1102 +#: aleksis/core/models.py:1451 msgid "Icon" msgstr "Піктограма" -#: aleksis/core/models.py:756 +#: aleksis/core/models.py:756 aleksis/core/models.py:778 msgid "Send notification at" msgstr "ÐадіÑлати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾" -#: aleksis/core/models.py:758 +#: aleksis/core/models.py:758 aleksis/core/models.py:780 msgid "Read" msgstr "Читати" -#: aleksis/core/models.py:759 +#: aleksis/core/models.py:759 aleksis/core/models.py:781 msgid "Sent" msgstr "ÐадіÑлано" -#: aleksis/core/models.py:776 +#: aleksis/core/models.py:776 aleksis/core/models.py:798 msgid "Notification" msgstr "СповіщеннÑ" #: aleksis/core/models.py:777 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:799 aleksis/core/preferences.py:28 msgid "Notifications" msgstr "СповіщеннÑ" -#: aleksis/core/models.py:845 +#: aleksis/core/models.py:845 aleksis/core/models.py:867 msgid "Link to detailed view" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° детальний переглÑд" -#: aleksis/core/models.py:848 +#: aleksis/core/models.py:848 aleksis/core/models.py:870 msgid "Date and time from when to show" msgstr "Дата Ñ– чаÑ, з Ñкого показувати" -#: aleksis/core/models.py:851 +#: aleksis/core/models.py:851 aleksis/core/models.py:873 msgid "Date and time until when to show" msgstr "Дата Ñ– чаÑ, до Ñкого показувати" -#: aleksis/core/models.py:876 +#: aleksis/core/models.py:876 aleksis/core/models.py:898 msgid "Announcement" msgstr "ОголошеннÑ" #: aleksis/core/models.py:877 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 +#: aleksis/core/models.py:899 msgid "Announcements" msgstr "ОголошеннÑ" -#: aleksis/core/models.py:914 +#: aleksis/core/models.py:914 aleksis/core/models.py:936 msgid "Announcement recipient" msgstr "Отримувач оголошеннÑ" -#: aleksis/core/models.py:915 +#: aleksis/core/models.py:915 aleksis/core/models.py:937 msgid "Announcement recipients" msgstr "Отримувачі оголошеннÑ" -#: aleksis/core/models.py:935 +#: aleksis/core/models.py:935 aleksis/core/models.py:957 msgid "Widget Title" msgstr "Ðазва віджета" -#: aleksis/core/models.py:936 +#: aleksis/core/models.py:936 aleksis/core/models.py:958 msgid "Activate Widget" msgstr "Ðктивувати віджет" -#: aleksis/core/models.py:937 +#: aleksis/core/models.py:937 aleksis/core/models.py:959 msgid "Widget is broken" msgstr "Віджет зламавÑÑ" -#: aleksis/core/models.py:940 +#: aleksis/core/models.py:940 aleksis/core/models.py:962 msgid "Size on mobile devices" msgstr "Розмір на мобільних" -#: aleksis/core/models.py:941 +#: aleksis/core/models.py:941 aleksis/core/models.py:963 msgid "<= 600 px, 12 columns" msgstr "<= 600 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:946 +#: aleksis/core/models.py:946 aleksis/core/models.py:968 msgid "Size on tablet devices" msgstr "Розмір на планшетах" -#: aleksis/core/models.py:947 +#: aleksis/core/models.py:947 aleksis/core/models.py:969 msgid "> 600 px, 12 columns" msgstr "> 600 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:952 +#: aleksis/core/models.py:952 aleksis/core/models.py:974 msgid "Size on desktop devices" msgstr "Розмір на ПК" -#: aleksis/core/models.py:953 +#: aleksis/core/models.py:953 aleksis/core/models.py:975 msgid "> 992 px, 12 columns" msgstr "> 992 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:958 +#: aleksis/core/models.py:958 aleksis/core/models.py:980 msgid "Size on large desktop devices" msgstr "Розмір на великих екранах" -#: aleksis/core/models.py:959 +#: aleksis/core/models.py:959 aleksis/core/models.py:981 msgid "> 1200 px>, 12 columns" msgstr "> 1200 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:990 +#: aleksis/core/models.py:990 aleksis/core/models.py:1012 msgid "Can edit default dashboard" msgstr "Може редагувати типову/Ñтандартну інформпанель" -#: aleksis/core/models.py:991 +#: aleksis/core/models.py:991 aleksis/core/models.py:1013 msgid "Dashboard Widget" msgstr "Віджет інформпанелі" -#: aleksis/core/models.py:992 +#: aleksis/core/models.py:992 aleksis/core/models.py:1014 msgid "Dashboard Widgets" msgstr "Віджети інформпанелі" -#: aleksis/core/models.py:998 +#: aleksis/core/models.py:998 aleksis/core/models.py:1020 msgid "URL" msgstr "URL" -#: aleksis/core/models.py:999 +#: aleksis/core/models.py:999 aleksis/core/models.py:1021 msgid "Icon URL" msgstr "Піктограма URL" -#: aleksis/core/models.py:1005 +#: aleksis/core/models.py:1005 aleksis/core/models.py:1027 msgid "External link widget" msgstr "Зовнішнє поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° віджет" -#: aleksis/core/models.py:1006 +#: aleksis/core/models.py:1006 aleksis/core/models.py:1028 msgid "External link widgets" msgstr "Зовнішні поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° віджети" -#: aleksis/core/models.py:1012 +#: aleksis/core/models.py:1012 aleksis/core/models.py:1034 msgid "Content" msgstr "ЗміÑÑ‚" -#: aleksis/core/models.py:1018 +#: aleksis/core/models.py:1018 aleksis/core/models.py:1040 msgid "Static content widget" msgstr "Віджет з поÑтійним зміÑтом" -#: aleksis/core/models.py:1019 +#: aleksis/core/models.py:1019 aleksis/core/models.py:1041 msgid "Static content widgets" msgstr "Віджети з поÑтійним зміÑтом" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1024 aleksis/core/models.py:1046 msgid "Dashboard widget" msgstr "Віджет інформпанелі" -#: aleksis/core/models.py:1029 +#: aleksis/core/models.py:1029 aleksis/core/models.py:1051 msgid "Order" msgstr "ПорÑдок" -#: aleksis/core/models.py:1030 +#: aleksis/core/models.py:1030 aleksis/core/models.py:1052 msgid "Part of the default dashboard" msgstr "ЧаÑтина типової інформпанелі" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1045 aleksis/core/models.py:1067 msgid "Dashboard widget order" msgstr "ПорÑдок віджету на інформпанелі" -#: aleksis/core/models.py:1046 +#: aleksis/core/models.py:1046 aleksis/core/models.py:1068 msgid "Dashboard widget orders" msgstr "ПорÑдок віджетів на інформпанелі" -#: aleksis/core/models.py:1052 +#: aleksis/core/models.py:1052 aleksis/core/models.py:1074 msgid "Menu ID" msgstr "Меню ID" -#: aleksis/core/models.py:1065 +#: aleksis/core/models.py:1065 aleksis/core/models.py:1087 msgid "Custom menu" msgstr "КориÑтувацьке меню" -#: aleksis/core/models.py:1066 +#: aleksis/core/models.py:1066 aleksis/core/models.py:1088 msgid "Custom menus" msgstr "КориÑтувацькі меню" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1076 aleksis/core/models.py:1098 msgid "Menu" msgstr "Меню" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1086 aleksis/core/models.py:1108 msgid "Custom menu item" msgstr "Пункт кориÑтувацького меню" -#: aleksis/core/models.py:1087 +#: aleksis/core/models.py:1087 aleksis/core/models.py:1109 msgid "Custom menu items" msgstr "Пункти кориÑтувацького меню" -#: aleksis/core/models.py:1112 +#: aleksis/core/models.py:1112 aleksis/core/models.py:1134 msgid "Title of type" msgstr "Ðазва типу" #: aleksis/core/models.py:1119 aleksis/core/templates/core/group/full.html:50 +#: aleksis/core/models.py:1141 msgid "Group type" msgstr "Тип групи" #: aleksis/core/models.py:1120 #: aleksis/core/templates/core/group_type/list.html:8 #: aleksis/core/templates/core/group_type/list.html:9 +#: aleksis/core/models.py:1142 msgid "Group types" msgstr "Типи груп" -#: aleksis/core/models.py:1133 +#: aleksis/core/models.py:1133 aleksis/core/models.py:1155 msgid "Can view system status" msgstr "Може переглÑдати Ñтан ÑиÑтеми" -#: aleksis/core/models.py:1134 +#: aleksis/core/models.py:1134 aleksis/core/models.py:1156 msgid "Can manage data" msgstr "Може керувати даними" -#: aleksis/core/models.py:1135 +#: aleksis/core/models.py:1135 aleksis/core/models.py:1157 msgid "Can impersonate" msgstr "Може маÑкуватиÑÑ" -#: aleksis/core/models.py:1136 +#: aleksis/core/models.py:1136 aleksis/core/models.py:1158 msgid "Can use search" msgstr "Може шукати" -#: aleksis/core/models.py:1137 +#: aleksis/core/models.py:1137 aleksis/core/models.py:1159 msgid "Can change site preferences" msgstr "Може змінювати влаÑтивоÑÑ‚Ñ– Ñайту" -#: aleksis/core/models.py:1138 +#: aleksis/core/models.py:1138 aleksis/core/models.py:1160 msgid "Can change person preferences" msgstr "Може змінювати влаÑтивоÑÑ‚Ñ– оÑоби" -#: aleksis/core/models.py:1139 +#: aleksis/core/models.py:1139 aleksis/core/models.py:1161 msgid "Can change group preferences" msgstr "Може змінювати влаÑтивоÑÑ‚Ñ– групи" -#: aleksis/core/models.py:1140 +#: aleksis/core/models.py:1140 aleksis/core/models.py:1162 msgid "Can test PDF generation" msgstr "Може генерувати теÑтові PDF" -#: aleksis/core/models.py:1141 +#: aleksis/core/models.py:1141 aleksis/core/models.py:1163 msgid "Can invite persons" msgstr "Може запрошувати оÑіб" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1177 aleksis/core/models.py:1199 msgid "Related data check task" msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ пов'Ñзаних даних" -#: aleksis/core/models.py:1185 +#: aleksis/core/models.py:1185 aleksis/core/models.py:1207 msgid "Issue solved" msgstr "Проблема вирішена" -#: aleksis/core/models.py:1186 +#: aleksis/core/models.py:1186 aleksis/core/models.py:1208 msgid "Notification sent" msgstr "Ð¡Ð¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð°Ð´Ñ–Ñлане" -#: aleksis/core/models.py:1199 +#: aleksis/core/models.py:1199 aleksis/core/models.py:1221 msgid "Data check result" msgstr "Результат перевірки даних" -#: aleksis/core/models.py:1200 +#: aleksis/core/models.py:1200 aleksis/core/models.py:1222 msgid "Data check results" msgstr "Результати перевірки даних" -#: aleksis/core/models.py:1202 +#: aleksis/core/models.py:1202 aleksis/core/models.py:1224 msgid "Can run data checks" msgstr "Може запуÑкати перевірки даних" -#: aleksis/core/models.py:1203 +#: aleksis/core/models.py:1203 aleksis/core/models.py:1225 msgid "Can solve data check problems" msgstr "Може розв'Ñзувати проблеми перевірки даних" -#: aleksis/core/models.py:1210 +#: aleksis/core/models.py:1210 aleksis/core/models.py:1232 msgid "E-Mail address" msgstr "ÐдреÑа ел.пошти" -#: aleksis/core/models.py:1270 +#: aleksis/core/models.py:1270 aleksis/core/models.py:1292 msgid "Owner" msgstr "ВлаÑник" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1274 aleksis/core/models.py:1296 msgid "File expires at" msgstr "Файл дійÑний до" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1277 aleksis/core/models.py:1299 msgid "Generated HTML file" msgstr "Згенерований файл HTML" -#: aleksis/core/models.py:1280 +#: aleksis/core/models.py:1280 aleksis/core/models.py:1302 msgid "Generated PDF file" msgstr "Згенерований файл PDF" -#: aleksis/core/models.py:1287 +#: aleksis/core/models.py:1287 aleksis/core/models.py:1309 msgid "PDF file" msgstr "Файл PDF" -#: aleksis/core/models.py:1288 +#: aleksis/core/models.py:1288 aleksis/core/models.py:1310 msgid "PDF files" msgstr "Файли PDF" -#: aleksis/core/models.py:1293 +#: aleksis/core/models.py:1293 aleksis/core/models.py:1315 msgid "Task result" msgstr "Результат завданнÑ" -#: aleksis/core/models.py:1296 +#: aleksis/core/models.py:1296 aleksis/core/models.py:1318 msgid "Task user" msgstr "КориÑтувач завданнÑ" -#: aleksis/core/models.py:1300 +#: aleksis/core/models.py:1300 aleksis/core/models.py:1322 msgid "Back URL" msgstr "URL Ð´Ð»Ñ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ" -#: aleksis/core/models.py:1301 +#: aleksis/core/models.py:1301 aleksis/core/models.py:1323 msgid "Progress title" msgstr "Ðазва процеÑу" -#: aleksis/core/models.py:1302 +#: aleksis/core/models.py:1302 aleksis/core/models.py:1324 msgid "Error message" msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку" -#: aleksis/core/models.py:1303 +#: aleksis/core/models.py:1303 aleksis/core/models.py:1325 msgid "Success message" msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ уÑпіх" -#: aleksis/core/models.py:1304 +#: aleksis/core/models.py:1304 aleksis/core/models.py:1326 msgid "Redirect on success URL" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð² разі уÑпіху" -#: aleksis/core/models.py:1306 +#: aleksis/core/models.py:1306 aleksis/core/models.py:1328 msgid "Additional button title" msgstr "Ðазва додаткової кнопки" -#: aleksis/core/models.py:1308 +#: aleksis/core/models.py:1308 aleksis/core/models.py:1330 msgid "Additional button URL" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— кнопки" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1310 aleksis/core/models.py:1332 msgid "Additional button icon" msgstr "Піктограма додаткової кнопки" -#: aleksis/core/models.py:1312 +#: aleksis/core/models.py:1312 aleksis/core/models.py:1334 msgid "Result fetched" msgstr "Отриманий результат" -#: aleksis/core/models.py:1337 +#: aleksis/core/models.py:1337 aleksis/core/models.py:1359 msgid "Background task completed successfully" msgstr "Фонове Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ ÑƒÑпішно завершене" -#: aleksis/core/models.py:1338 +#: aleksis/core/models.py:1338 aleksis/core/models.py:1360 msgid "The background task '{}' has been completed successfully." msgstr "Фонове Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ '{}' було уÑпішно завершене." -#: aleksis/core/models.py:1344 +#: aleksis/core/models.py:1344 aleksis/core/models.py:1366 msgid "Background task failed" msgstr "Збій фонового завданнÑ" -#: aleksis/core/models.py:1345 +#: aleksis/core/models.py:1345 aleksis/core/models.py:1367 msgid "The background task '{}' has failed." msgstr "У фонового Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ '{}' ÑтавÑÑ Ð·Ð±Ñ–Ð¹." -#: aleksis/core/models.py:1354 +#: aleksis/core/models.py:1354 aleksis/core/models.py:1376 msgid "Background task" msgstr "Фонове завданнÑ" -#: aleksis/core/models.py:1368 +#: aleksis/core/models.py:1368 aleksis/core/models.py:1390 msgid "Task user assignment" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача завданнÑ" -#: aleksis/core/models.py:1369 +#: aleksis/core/models.py:1369 aleksis/core/models.py:1391 msgid "Task user assignments" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів завданнÑ" -#: aleksis/core/models.py:1385 +#: aleksis/core/models.py:1385 aleksis/core/models.py:1407 msgid "Additional attributes" msgstr "Додаткові атрибути" -#: aleksis/core/models.py:1423 +#: aleksis/core/models.py:1423 aleksis/core/models.py:1445 msgid "Allowed scopes that clients can request" msgstr "Дозволені межі дії, Ñкі можуть запитувати клієнти" -#: aleksis/core/models.py:1433 -msgid "This image will be shown as icon in the authorization flow. It should be squared." -msgstr "Це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ іконкою під Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ—. Воно повинне бути квадратним." +#: aleksis/core/models.py:1433 aleksis/core/models.py:1455 +msgid "" +"This image will be shown as icon in the authorization flow. It should be " +"squared." +msgstr "" +"Це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ іконкою під Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ—. Воно повинне бути квадратним." -#: aleksis/core/models.py:1478 +#: aleksis/core/models.py:1478 aleksis/core/models.py:1500 msgid "Can view room timetable" msgstr "Може переглÑдати розклад кімнати" -#: aleksis/core/models.py:1480 +#: aleksis/core/models.py:1480 aleksis/core/models.py:1502 msgid "Room" msgstr "Кімната" -#: aleksis/core/models.py:1481 +#: aleksis/core/models.py:1481 aleksis/core/models.py:1503 msgid "Rooms" msgstr "Кімнати" -#: aleksis/core/preferences.py:25 +#: aleksis/core/preferences.py:25 aleksis/core/preferences.py:24 msgid "General" msgstr "Загальне" -#: aleksis/core/preferences.py:26 +#: aleksis/core/preferences.py:26 aleksis/core/preferences.py:25 msgid "School" msgstr "Школа / навч.заклад" -#: aleksis/core/preferences.py:27 +#: aleksis/core/preferences.py:27 aleksis/core/preferences.py:26 msgid "Theme" msgstr "Тема" -#: aleksis/core/preferences.py:28 +#: aleksis/core/preferences.py:28 aleksis/core/preferences.py:27 msgid "Mail" msgstr "Пошта" -#: aleksis/core/preferences.py:30 +#: aleksis/core/preferences.py:30 aleksis/core/preferences.py:29 msgid "Footer" msgstr "Ðижній колонтитул (footer)" -#: aleksis/core/preferences.py:31 +#: aleksis/core/preferences.py:31 aleksis/core/preferences.py:30 msgid "Accounts" msgstr "Облікові запиÑи" -#: aleksis/core/preferences.py:32 +#: aleksis/core/preferences.py:32 aleksis/core/preferences.py:31 msgid "Authentication" msgstr "ÐвторизаціÑ" -#: aleksis/core/preferences.py:33 +#: aleksis/core/preferences.py:33 aleksis/core/preferences.py:32 msgid "Internationalisation" msgstr "ІнтернаціоналізаціÑ" @@ -1059,8 +1117,10 @@ msgid "Automatically create new persons for new users" msgstr "Ðові оÑоби Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… кориÑтувачів Ñтворювати автоматично" #: aleksis/core/preferences.py:256 -msgid "Automatically link existing persons to new users by their e-mail address" -msgstr "Пов'Ñзувати Ñ–Ñнуючих оÑіб з новими кориÑтувачами автоматично за ел.адреÑами" +msgid "" +"Automatically link existing persons to new users by their e-mail address" +msgstr "" +"Пов'Ñзувати Ñ–Ñнуючих оÑіб з новими кориÑтувачами автоматично за ел.адреÑами" #: aleksis/core/preferences.py:267 msgid "Display name of the school" @@ -1127,7 +1187,8 @@ msgid "Fields on person model which are editable by themselves." msgstr "ÐŸÐ¾Ð»Ñ Ð· опиÑом оÑоби, Ñкі можна редагувати ÑамоÑтійно." #: aleksis/core/preferences.py:424 -msgid "Editable fields on person model which should trigger a notification on change" +msgid "" +"Editable fields on person model which should trigger a notification on change" msgstr "Змінювані Ð¿Ð¾Ð»Ñ Ð· опиÑом оÑоби, Ñкі повинні Ñповіщати щодо редагуваннÑ" #: aleksis/core/preferences.py:438 @@ -1180,6 +1241,7 @@ msgstr "Редагувати" #: aleksis/core/tables.py:27 aleksis/core/tables.py:148 #: aleksis/core/tables.py:185 #: aleksis/core/templates/core/announcement/list.html:22 +#: aleksis/core/tables.py:130 aleksis/core/tables.py:167 msgid "Actions" msgstr "Дії" @@ -1190,6 +1252,9 @@ msgstr "Дії" #: aleksis/core/templates/core/group/full.html:33 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 +#: aleksis/core/tables.py:97 aleksis/core/tables.py:98 +#: aleksis/core/tables.py:112 aleksis/core/tables.py:128 +#: aleksis/core/tables.py:165 msgid "Delete" msgstr "Видалити" @@ -1209,7 +1274,8 @@ msgstr "" #: aleksis/core/templates/403.html:19 aleksis/core/templates/404.html:16 msgid "" "\n" -" If you think this is an error in AlekSIS, please contact your site\n" +" If you think this is an error in AlekSIS, please contact your " +"site\n" " administrators:\n" " " msgstr "" @@ -1241,12 +1307,14 @@ msgstr "" #: aleksis/core/templates/500.html:13 msgid "" "\n" -" Your site administrators will automatically be notified about this\n" +" Your site administrators will automatically be notified about " +"this\n" " error. You can also contact them directly:\n" " " msgstr "" "\n" -" ÐдмініÑтратори Ñайту будуть Ñповіщені щодо цієї помилки автоматично.\n" +" ÐдмініÑтратори Ñайту будуть Ñповіщені щодо цієї помилки " +"автоматично.\n" " Ви також можете звернутиÑÑ Ð´Ð¾ них безпоÑередньо:\n" " " @@ -1292,13 +1360,22 @@ msgstr "Підтвердити" #: aleksis/core/templates/account/email_confirm.html:12 #, python-format -msgid "Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail address for user %(user_display)s." -msgstr "Підтвердіть, будь лаÑка, що <a href=\"mailto:%(email)s\">%(email)s</a> Ñ” адреÑою ел.пошти Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(user_display)s." +msgid "" +"Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail " +"address for user %(user_display)s." +msgstr "" +"Підтвердіть, будь лаÑка, що <a href=\"mailto:%(email)s\">%(email)s</a> Ñ” " +"адреÑою ел.пошти Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача %(user_display)s." #: aleksis/core/templates/account/email_confirm.html:25 #, python-format -msgid "This e-mail confirmation link expired or is invalid. Please <a href=\"%(email_url)s\">issue a new e-mail confirmation request</a>." -msgstr "Це поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ».пошти протерміноване або недійÑне. Зробіть, будь лаÑка, Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ <a href=\"%(email_url)s\">новий запит</a>." +msgid "" +"This e-mail confirmation link expired or is invalid. Please <a href=" +"\"%(email_url)s\">issue a new e-mail confirmation request</a>." +msgstr "" +"Це поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ».пошти протерміноване або недійÑне. " +"Зробіть, будь лаÑка, Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ <a href=\"%(email_url)s\">новий " +"запит</a>." #: aleksis/core/templates/account/password_change.html:5 #: aleksis/core/templates/account/password_change.html:6 @@ -1332,12 +1409,14 @@ msgstr "Зміна паролю вимкнена." msgid "" "\n" " Users are not allowed to edit their own passwords. If you think\n" -" this is an error please contact one of your site administrators.\n" +" this is an error please contact one of your site " +"administrators.\n" " " msgstr "" "\n" " КориÑтувачам не дозволÑєтьÑÑ Ð·Ð¼Ñ–Ð½ÑŽÐ²Ð°Ñ‚Ð¸ Ñвої паролі.\n" -" Якщо Ви думаєте, що це помилка, звернітьÑÑ Ð´Ð¾ адмініÑтраторів Ñайту.\n" +" Якщо Ви думаєте, що це помилка, звернітьÑÑ Ð´Ð¾ адмініÑтраторів " +"Ñайту.\n" " " #: aleksis/core/templates/account/password_reset.html:5 @@ -1351,8 +1430,12 @@ msgid "Reset password" msgstr "Скинути пароль" #: aleksis/core/templates/account/password_reset.html:17 -msgid "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." -msgstr "Забули пароль? Вкажіть нижче Ñвою ел.пошту Ñ– ми надішлемо Вам лиÑта Ð´Ð»Ñ ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ." +msgid "" +"Forgotten your password? Enter your e-mail address below, and we'll send you " +"an e-mail allowing you to reset it." +msgstr "" +"Забули пароль? Вкажіть нижче Ñвою ел.пошту Ñ– ми надішлемо Вам лиÑта Ð´Ð»Ñ " +"ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ." #: aleksis/core/templates/account/password_reset.html:30 msgid "" @@ -1376,7 +1459,8 @@ msgid "" msgstr "" "\n" " Ми надіÑлали Вам ел.лиÑта. Якщо Ви його не отримаєте протÑгом\n" -" декількох хвилин, звернітьÑÑ, будь лаÑка, до адмініÑтраторів Ñайту.\n" +" декількох хвилин, звернітьÑÑ, будь лаÑка, до адмініÑтраторів " +"Ñайту.\n" " " #: aleksis/core/templates/account/password_reset_from_key.html:15 @@ -1387,13 +1471,16 @@ msgstr "ÐеÑправний токен" #, python-format msgid "" "\n" -" The password reset link was invalid, possibly because it has already been used. Please request a <a href=\"%(passwd_reset_url)s\"\n" +" The password reset link was invalid, possibly because it has " +"already been used. Please request a <a href=\"%(passwd_reset_url)s\"\n" " class=\"blue-text text-lighten-2\">new password reset</a>.\n" " " msgstr "" "\n" -" ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½ÐµÐ´Ñ–Ð¹Ñне або, ймовірно, вже викориÑтане. Зробіть, будь лаÑка, <a href=\"%(passwd_reset_url)s\"\n" -" class=\"blue-text text-lighten-2\">новий запит на ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ</a>.\n" +" ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½ÐµÐ´Ñ–Ð¹Ñне або, ймовірно, вже " +"викориÑтане. Зробіть, будь лаÑка, <a href=\"%(passwd_reset_url)s\"\n" +" class=\"blue-text text-lighten-2\">новий запит на ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ " +"паролÑ</a>.\n" " " #: aleksis/core/templates/account/password_reset_from_key.html:25 @@ -1442,8 +1529,10 @@ msgstr "РеєÑтраціÑ" #: aleksis/core/templates/account/signup.html:12 #, python-format -msgid "Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>." -msgstr "Вже маєте обліковий запиÑ? Тоді можете <a href=\"%(login_url)s\">увіти</a>." +msgid "" +"Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>." +msgstr "" +"Вже маєте обліковий запиÑ? Тоді можете <a href=\"%(login_url)s\">увіти</a>." #: aleksis/core/templates/account/signup.html:22 #: aleksis/core/templates/socialaccount/signup.html:23 @@ -1487,13 +1576,17 @@ msgstr "Перевірте Ñвою ел.пошту!" #: aleksis/core/templates/account/verification_sent.html:16 msgid "" "\n" -" This part of the site requires us to verify that you are who you claim to be.\n" -" For this purpose, we require that you verify ownership of your e-mail address.\n" +" This part of the site requires us to verify that you are who you " +"claim to be.\n" +" For this purpose, we require that you verify ownership of your e-" +"mail address.\n" " " msgstr "" "\n" -" Ð¦Ñ Ñ‡Ð°Ñтина Ñайту вимагає перевірки, що Ви - Ñаме той/та, хто має бути.\n" -" Саме Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ нам необхідно перевірити, що адреÑа ел.пошти належить Ñаме Вам.\n" +" Ð¦Ñ Ñ‡Ð°Ñтина Ñайту вимагає перевірки, що Ви - Ñаме той/та, хто має " +"бути.\n" +" Саме Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ нам необхідно перевірити, що адреÑа ел.пошти " +"належить Ñаме Вам.\n" " " #: aleksis/core/templates/account/verification_sent.html:22 @@ -1506,8 +1599,10 @@ msgid "" msgstr "" "\n" " Ми надіÑлали Вам Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ ел.лиÑта.\n" -" Будь лаÑка, перейдіть за вказаним там поÑиланнÑм. Якщо Ви не отримаєте\n" -" лиÑта протÑгом декількох хвилин, звернітьÑÑ, будь лаÑка, до наÑ.\n" +" Будь лаÑка, перейдіть за вказаним там поÑиланнÑм. Якщо Ви не " +"отримаєте\n" +" лиÑта протÑгом декількох хвилин, звернітьÑÑ, будь лаÑка, до " +"наÑ.\n" " " #: aleksis/core/templates/core/additional_field/edit.html:6 @@ -1682,29 +1777,39 @@ msgstr "Редагувати інформпанель" #: aleksis/core/templates/core/edit_dashboard.html:24 msgid "" "\n" -" On this page you can arrange your personal dashboard. You can drag any items from \"Available widgets\" to \"Your\n" -" Dashboard\" or change the order by moving the widgets. After you have finished, please don't forget to click on\n" +" On this page you can arrange your personal dashboard. You can drag " +"any items from \"Available widgets\" to \"Your\n" +" Dashboard\" or change the order by moving the widgets. After you " +"have finished, please don't forget to click on\n" " \"Save\".\n" " " msgstr "" "\n" -" Ðа цій Ñторінці Ви можете впорÑдкувати Ñвою інформпанель. ПеретÑгуйте будь-Ñкі елементи з \"ДоÑтупних віджетів\"\n" -" до \"Своєї інформпанелі\" або змінюйте порÑдок, перетÑгуючи віджети. ПіÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ забудьте натиÑнути\n" +" Ðа цій Ñторінці Ви можете впорÑдкувати Ñвою інформпанель. " +"ПеретÑгуйте будь-Ñкі елементи з \"ДоÑтупних віджетів\"\n" +" до \"Своєї інформпанелі\" або змінюйте порÑдок, перетÑгуючи " +"віджети. ПіÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ забудьте натиÑнути\n" " \"Зберегти\".\n" " " #: aleksis/core/templates/core/edit_dashboard.html:30 msgid "" "\n" -" On this page you can arrange the default dashboard which is shown when a user doesn't arrange his own\n" -" dashboard. You can drag any items from \"Available widgets\" to \"Default Dashboard\" or change the order\n" -" by moving the widgets. After you have finished, please don't forget to click on \"Save\".\n" +" On this page you can arrange the default dashboard which is shown " +"when a user doesn't arrange his own\n" +" dashboard. You can drag any items from \"Available widgets\" to " +"\"Default Dashboard\" or change the order\n" +" by moving the widgets. After you have finished, please don't " +"forget to click on \"Save\".\n" " " msgstr "" "\n" -" Ðа цій Ñторінці Ви можете впорÑдкувати типову/Ñтандартну інформпанель, Ñка відображаєтьÑÑ, Ñкщо кориÑтувач\n" -" не впорÑдкував влаÑну. ПеретÑгуйте будь-Ñкі елементи з \"ДоÑтупних віджетів\" до \"Типової інформпанелі\" або змінюйте \n" -" порÑдок, перетÑгуючи віджети. ПіÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ забудьте натиÑнути \"Зберегти\".\n" +" Ðа цій Ñторінці Ви можете впорÑдкувати типову/Ñтандартну " +"інформпанель, Ñка відображаєтьÑÑ, Ñкщо кориÑтувач\n" +" не впорÑдкував влаÑну. ПеретÑгуйте будь-Ñкі елементи з \"ДоÑтупних " +"віджетів\" до \"Типової інформпанелі\" або змінюйте \n" +" порÑдок, перетÑгуючи віджети. ПіÑÐ»Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ забудьте " +"натиÑнути \"Зберегти\".\n" " " #: aleksis/core/templates/core/edit_dashboard.html:48 @@ -1727,13 +1832,16 @@ msgstr "Призначити підлеглі групи до груп" #: aleksis/core/templates/core/group/child_groups.html:18 msgid "" "\n" -" You can use this to assign child groups to groups. Please use the filters below to select groups you want to\n" +" You can use this to assign child groups to groups. Please use the " +"filters below to select groups you want to\n" " change and click \"Next\".\n" " " msgstr "" "\n" -" Ви можете ÑкориÑтатиÑÑ Ñ†Ð¸Ð¼ Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð»ÐµÐ³Ð»Ð¸Ñ… груп до оÑновних. Ð”Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿,\n" -" Ñкі хочете змінити, ÑкориÑтайтеÑÑ, будь лаÑка, фільтрами, що нижче та натиÑніÑÑ‚ÑŒ \"Далі\".\n" +" Ви можете ÑкориÑтатиÑÑ Ñ†Ð¸Ð¼ Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ð»ÐµÐ³Ð»Ð¸Ñ… груп до " +"оÑновних. Ð”Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿,\n" +" Ñкі хочете змінити, ÑкориÑтайтеÑÑ, будь лаÑка, фільтрами, що нижче " +"та натиÑніÑÑ‚ÑŒ \"Далі\".\n" " " #: aleksis/core/templates/core/group/child_groups.html:31 @@ -1759,7 +1867,8 @@ msgid "" " " msgstr "" "\n" -" Оберіть, будь лаÑка, декілька груп у порÑдку, за Ñким призначати.\n" +" Оберіть, будь лаÑка, декілька груп у порÑдку, за Ñким " +"призначати.\n" " " #: aleksis/core/templates/core/group/child_groups.html:72 @@ -1773,14 +1882,18 @@ msgstr "Обережно, будь лаÑка!" #: aleksis/core/templates/core/group/child_groups.html:79 msgid "" "\n" -" If you click \"Back\" or \"Next\" the current group assignments are not saved.\n" -" If you click \"Save\", you will overwrite all existing child group relations for this group with what you\n" +" If you click \"Back\" or \"Next\" the current group assignments " +"are not saved.\n" +" If you click \"Save\", you will overwrite all existing child " +"group relations for this group with what you\n" " selected on this page.\n" " " msgstr "" "\n" -" Якщо натиÑнете \"Ðазад\" або \"Далі\" Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— групи не збережутьÑÑ.\n" -" Якщо натиÑнете \"Зберегти\", уÑÑ– Ñ–Ñнуючі зв'Ñзки підлеглої групи з цією групою будуть замінені на\n" +" Якщо натиÑнете \"Ðазад\" або \"Далі\" Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ†Ñ–Ñ”Ñ— групи не " +"збережутьÑÑ.\n" +" Якщо натиÑнете \"Зберегти\", уÑÑ– Ñ–Ñнуючі зв'Ñзки підлеглої групи " +"з цією групою будуть замінені на\n" " обрані на цій Ñторінці.\n" " " @@ -1878,12 +1991,14 @@ msgstr "Додому" #: aleksis/core/templates/core/index.html:34 msgid "" "\n" -" You didn't customise your dashboard so that you see the system default. Please click on \"Edit dashboard\" to\n" +" You didn't customise your dashboard so that you see the system " +"default. Please click on \"Edit dashboard\" to\n" " customise your personal dashboard.\n" " " msgstr "" "\n" -" Ви ще не налаштували Ñвою інформпанель, тож поки що бачите типову/Ñтандартну. Ð”Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ \n" +" Ви ще не налаштували Ñвою інформпанель, тож поки що бачите типову/" +"Ñтандартну. Ð”Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ \n" " влаÑної інформпанелі клацніть \"Редагувати інформпанель\".\n" " " @@ -1927,11 +2042,13 @@ msgstr "Ðктивований режим обÑлуговуваннÑ" #: aleksis/core/templates/core/pages/system_status.html:28 msgid "" "\n" -" Only admin and visitors from internal IPs can access the site.\n" +" Only admin and visitors from internal IPs can access the " +"site.\n" " " msgstr "" "\n" -" ДоÑтуп до Ñайту мають лише адмініÑтратор та відвідувачі з внутрішніми IP-адреÑами.\n" +" ДоÑтуп до Ñайту мають лише адмініÑтратор та відвідувачі з " +"внутрішніми IP-адреÑами.\n" " " #: aleksis/core/templates/core/pages/system_status.html:39 @@ -1949,11 +2066,13 @@ msgstr "Ðктивований режим налагодженнÑ" #: aleksis/core/templates/core/pages/system_status.html:53 msgid "" "\n" -" The web server throws back debug information on errors. Do not use in production!\n" +" The web server throws back debug information on errors. Do " +"not use in production!\n" " " msgstr "" "\n" -" Веб-Ñервер кидає під Ñ‡Ð°Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº інформацію щодо налагодженнÑ. Ðе викориÑтовуйте в продакшені!\n" +" Веб-Ñервер кидає під Ñ‡Ð°Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº інформацію щодо " +"налагодженнÑ. Ðе викориÑтовуйте в продакшені!\n" " " #: aleksis/core/templates/core/pages/system_status.html:60 @@ -1963,11 +2082,13 @@ msgstr "Режим Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÐ°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¸Ð¹" #: aleksis/core/templates/core/pages/system_status.html:62 msgid "" "\n" -" Debug mode is disabled. Default error pages are displayed on errors.\n" +" Debug mode is disabled. Default error pages are displayed on " +"errors.\n" " " msgstr "" "\n" -" Режим Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÐ°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¸Ð¹. Ð’ разі збоїв відображатимутьÑÑ Ñ‚Ð¸Ð¿Ð¾Ð²Ñ– Ñторінки помилок.\n" +" Режим Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð´ÐµÐ°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¸Ð¹. Ð’ разі збоїв " +"відображатимутьÑÑ Ñ‚Ð¸Ð¿Ð¾Ð²Ñ– Ñторінки помилок.\n" " " #: aleksis/core/templates/core/pages/system_status.html:75 @@ -2017,11 +2138,13 @@ msgstr "Спроба генерації PDF" #: aleksis/core/templates/core/pages/test_pdf.html:14 msgid "" "\n" -" This simple view can be used to ensure the correct function of the built-in PDF generation system.\n" +" This simple view can be used to ensure the correct function of the " +"built-in PDF generation system.\n" " " msgstr "" "\n" -" Цей проÑтий виглÑд допоможе перевірити коректніÑÑ‚ÑŒ налаштувань вбудованої ÑиÑтеми генерації PDF.\n" +" Цей проÑтий виглÑд допоможе перевірити коректніÑÑ‚ÑŒ налаштувань " +"вбудованої ÑиÑтеми генерації PDF.\n" " " #: aleksis/core/templates/core/partials/announcements.html:8 @@ -2079,11 +2202,13 @@ msgstr "Ðевідомо" #: aleksis/core/templates/core/partials/splash_screen.html:11 msgid "" "\n" -" This webbrowser doesn't support JavaScript, or its execution is blocked. Please use another browser to continue.\n" +" This webbrowser doesn't support JavaScript, or its execution is " +"blocked. Please use another browser to continue.\n" " " msgstr "" "\n" -" Цей веб-браузер не підтримує JavaScript або його обробка заблокована. Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ ÑкориÑтайтеÑÑ, будь лаÑка, іншим браузером.\n" +" Цей веб-браузер не підтримує JavaScript або його обробка заблокована. " +"Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ ÑкориÑтайтеÑÑ, будь лаÑка, іншим браузером.\n" " " #: aleksis/core/templates/core/partials/splash_screen.html:17 @@ -2206,7 +2331,9 @@ msgid "The invite feature is disabled." msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ Ð´ÐµÐ°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð°." #: aleksis/core/templates/invitations/disabled.html:15 -msgid "To enable it, switch on the corresponding checkbox in the authentication section of the " +msgid "" +"To enable it, switch on the corresponding checkbox in the authentication " +"section of the " msgstr "Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— увімкніть відповідний Ñ‡ÐµÐºÐ±Ð¾ÐºÑ Ð² розділі авторизації на " #: aleksis/core/templates/invitations/disabled.html:16 @@ -2355,13 +2482,17 @@ msgstr "Ðемає з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером." #: aleksis/core/templates/offline.html:14 msgid "" "\n" -" This page is not available without a connection to the server. Please check your internet connection and try again.\n" -" If you are connected and the error persists, please contact the system administrators:\n" +" This page is not available without a connection to the server. Please " +"check your internet connection and try again.\n" +" If you are connected and the error persists, please contact the system " +"administrators:\n" " " msgstr "" "\n" -" Ð¦Ñ Ñторінка без з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером не доÑтупна. Перевірте наÑвніÑÑ‚ÑŒ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ інтернету та повторіть Ñпробу.\n" -" Якщо інтернет працює Ñ– помилка вÑе одно приÑутнÑ, звернітьÑÑ Ð´Ð¾ ÑиÑтемних адмініÑтраторів:\n" +" Ð¦Ñ Ñторінка без з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером не доÑтупна. Перевірте наÑвніÑÑ‚ÑŒ " +"Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ інтернету та повторіть Ñпробу.\n" +" Якщо інтернет працює Ñ– помилка вÑе одно приÑутнÑ, звернітьÑÑ Ð´Ð¾ " +"ÑиÑтемних адмініÑтраторів:\n" " " #: aleksis/core/templates/search/search.html:8 @@ -2396,12 +2527,14 @@ msgstr "Помилка входу облікового запиÑу третьо #: aleksis/core/templates/socialaccount/authentication_error.html:15 msgid "" "\n" -" An error occurred while attempting to login via your third-party account.\n" +" An error occurred while attempting to login via your third-party " +"account.\n" " Please contact one of your site administrators.\n" " " msgstr "" "\n" -" Під Ñ‡Ð°Ñ Ñпроби входу з Вашим Ñтороннім обліковим запиÑом виникла помилка входу.\n" +" Під Ñ‡Ð°Ñ Ñпроби входу з Вашим Ñтороннім обліковим запиÑом виникла " +"помилка входу.\n" " ЗвернітьÑÑ, будь лаÑка, до адмініÑтратора Ñайту.\n" " " @@ -2416,7 +2549,9 @@ msgstr "Видалити" #: aleksis/core/templates/socialaccount/connections.html:34 msgid "You currently have no third-party accounts connected to this account." -msgstr "Зараз у Ð’Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” облікових запиÑів третіх Ñторін, з'єднаних з цим обліковим запиÑом." +msgstr "" +"Зараз у Ð’Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” облікових запиÑів третіх Ñторін, з'єднаних з цим обліковим " +"запиÑом." #: aleksis/core/templates/socialaccount/connections.html:37 msgid "Add a Third-party Account" @@ -2430,7 +2565,8 @@ msgstr "Ви приєднуєте новий обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ #: aleksis/core/templates/socialaccount/login.html:23 #, python-format msgid "You are about to sign in using a third party account from %(provider)s." -msgstr "Ви авторизуєтеÑÑ Ð·Ð° допомогою Ñтороннього облікового запиÑу від %(provider)s." +msgstr "" +"Ви авторизуєтеÑÑ Ð·Ð° допомогою Ñтороннього облікового запиÑу від %(provider)s." #: aleksis/core/templates/socialaccount/login.html:28 msgid "Continue" @@ -2446,11 +2582,15 @@ msgstr "Вхід ÑкаÑований" #, python-format msgid "" "\n" -" You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to <a href=\"%(login_url)s\">sign in</a>.\n" +" You decided to cancel logging in to our site using one of your " +"existing accounts. If this was a mistake, please proceed to <a href=" +"\"%(login_url)s\">sign in</a>.\n" " " msgstr "" "\n" -" Схоже, що Ви ÑкаÑували вхід до нашого Ñайту з одним із Ваших облікових запиÑів. Якщо це ÑталоÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ð²Ð¾, Ви можете <a href=\"%(login_url)s\">продовжити вхід тут</a>.\n" +" Схоже, що Ви ÑкаÑували вхід до нашого Ñайту з одним із Ваших " +"облікових запиÑів. Якщо це ÑталоÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ð²Ð¾, Ви можете <a href=" +"\"%(login_url)s\">продовжити вхід тут</a>.\n" " " #: aleksis/core/templates/socialaccount/signup.html:12 @@ -2460,7 +2600,8 @@ msgid "" " %(site_name)s. As a final step, please complete the following form:" msgstr "" "Ви на шлÑху до викориÑÑ‚Ð°Ð½Ð½Ñ Ñвого облікового запиÑу у %(provider_name)s\n" -" Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ на %(site_name)s. Заповніть, будь лаÑка, Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ†ÑŽ форму:" +" Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ на %(site_name)s. Заповніть, будь лаÑка, Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ†ÑŽ " +"форму:" #: aleksis/core/templates/socialaccount/snippets/provider_list.html:12 #, python-format @@ -2549,21 +2690,25 @@ msgstr "СиÑтема виÑвила деÑкі нові проблеми з Ð’ #: aleksis/core/templates/templated_email/data_checks.email:6 msgid "" "the system detected some new problems with your data.\n" -"Please take some time to inspect them and solve the issues or mark them as ignored." +"Please take some time to inspect them and solve the issues or mark them as " +"ignored." msgstr "" "ÑиÑтема виÑвила деÑкі нові проблеми з Вашими даними.\n" -"Приділіть, будь лаÑка, трохи чаÑу Ð´Ð»Ñ Ñ—Ñ… перевірки та Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ або позначте Ñ—Ñ… Ð´Ð»Ñ Ñ–Ð³Ð½Ð¾Ñ€Ñƒ." +"Приділіть, будь лаÑка, трохи чаÑу Ð´Ð»Ñ Ñ—Ñ… перевірки та Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ або " +"позначте Ñ—Ñ… Ð´Ð»Ñ Ñ–Ð³Ð½Ð¾Ñ€Ñƒ." #: aleksis/core/templates/templated_email/data_checks.email:15 msgid "" "\n" " the system detected some new problems with your data.\n" -" Please take some time to inspect them and solve the issues or mark them as ignored.\n" +" Please take some time to inspect them and solve the issues or mark them " +"as ignored.\n" " " msgstr "" "\n" " ÑиÑтема виÑвила деÑкі нові проблеми з Вашими даними.\n" -" Приділіть, будь лаÑка, трохи чаÑу Ð´Ð»Ñ Ñ—Ñ… перевірки та Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ або позначте Ñ—Ñ… Ð´Ð»Ñ Ñ–Ð³Ð½Ð¾Ñ€Ñƒ.\n" +" Приділіть, будь лаÑка, трохи чаÑу Ð´Ð»Ñ Ñ—Ñ… перевірки та Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ " +"або позначте Ñ—Ñ… Ð´Ð»Ñ Ñ–Ð³Ð½Ð¾Ñ€Ñƒ.\n" " " #: aleksis/core/templates/templated_email/data_checks.email:23 @@ -2588,8 +2733,12 @@ msgstr "Привіт, %(person)s" #: aleksis/core/templates/templated_email/invitation.email:9 #: aleksis/core/templates/templated_email/invitation.email:18 #, python-format -msgid "you have been invited to register on %(site)s. If you would like to accept this invitation, please click on the following link:" -msgstr "Ви запрошені зареєÑтруватиÑÑ Ð½Ð° %(site)s. Якщо хочете прийнÑти запрошеннÑ, перейдіть за поÑиланнÑм:" +msgid "" +"you have been invited to register on %(site)s. If you would like to accept " +"this invitation, please click on the following link:" +msgstr "" +"Ви запрошені зареєÑтруватиÑÑ Ð½Ð° %(site)s. Якщо хочете прийнÑти запрошеннÑ, " +"перейдіть за поÑиланнÑм:" #: aleksis/core/templates/templated_email/notification.email:4 msgid "New notification for" @@ -2663,16 +2812,22 @@ msgid "" "\n" " Backup tokens can be used when your primary and backup\n" " phone numbers aren't available. The backup tokens below can be used\n" -" for login verification. If you've used up all your backup tokens, you\n" -" can generate a new set of backup tokens. Only the backup tokens shown\n" +" for login verification. If you've used up all your backup tokens, " +"you\n" +" can generate a new set of backup tokens. Only the backup tokens " +"shown\n" " below will be valid.\n" " " msgstr "" "\n" -" Резервні токени можуть бути викориÑтані коли Ваші оÑновний та резервний\n" -" телефонні номери не доÑтупні. Резервні токени, що нижче, можуть бути викориÑтані\n" -" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ на вході. Коли Ви викориÑтаєте уÑÑ– резервні токени, Ви\n" -" зможете згенерувати новий набір резервних токенів. ДійÑними будуть лише токени,\n" +" Резервні токени можуть бути викориÑтані коли Ваші оÑновний та " +"резервний\n" +" телефонні номери не доÑтупні. Резервні токени, що нижче, можуть бути " +"викориÑтані\n" +" Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ на вході. Коли Ви викориÑтаєте уÑÑ– резервні токени, " +"Ви\n" +" зможете згенерувати новий набір резервних токенів. ДійÑними будуть " +"лише токени,\n" " що нижче.\n" " " @@ -2723,7 +2878,9 @@ msgstr "" #: aleksis/core/templates/two_factor/core/login.html:51 msgid "Please login with your account to use the external application." -msgstr "Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ додатку увійдіть, будь лаÑка, у Ñвій обліковий запиÑ." +msgstr "" +"Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ додатку увійдіть, будь лаÑка, у Ñвій обліковий " +"запиÑ." #: aleksis/core/templates/two_factor/core/login.html:58 msgid "Please login to see this page." @@ -2732,67 +2889,83 @@ msgstr "Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду цієї Ñторінки, будь лаÑка #: aleksis/core/templates/two_factor/core/login.html:69 msgid "" "\n" -" We are calling your phone right now, please enter the\n" +" We are calling your phone right now, please enter " +"the\n" " digits you hear.\n" " " msgstr "" "\n" -" Ми зателефонуємо зараз на Ваш номер. Ðапишіть, будь лаÑка, цифри,\n" +" Ми зателефонуємо зараз на Ваш номер. Ðапишіть, будь " +"лаÑка, цифри,\n" " Ñкі Ви почуєте.\n" " " #: aleksis/core/templates/two_factor/core/login.html:74 msgid "" "\n" -" We sent you a text message, please enter the code we sent.\n" +" We sent you a text message, please enter the code we " +"sent.\n" " " msgstr "" "\n" -" Ми надіÑлали Вам текÑтове повідомленнÑ. Ðапишіть, будь лаÑка, отриманий код.\n" +" Ми надіÑлали Вам текÑтове повідомленнÑ. Ðапишіть, " +"будь лаÑка, отриманий код.\n" " " #: aleksis/core/templates/two_factor/core/login.html:78 msgid "" "\n" -" We sent you an email, please enter the code we sent.\n" +" We sent you an email, please enter the code we " +"sent.\n" " " msgstr "" "\n" -" Ми надіÑлали Вам ел.лиÑта. Ðапишіть, будь лаÑка, отриманий код.\n" +" Ми надіÑлали Вам ел.лиÑта. Ðапишіть, будь лаÑка, " +"отриманий код.\n" " " #: aleksis/core/templates/two_factor/core/login.html:82 msgid "" "\n" -" Please use your Webauthn-compatible device to authenticate.\n" +" Please use your Webauthn-compatible device to " +"authenticate.\n" " " msgstr "" "\n" -" Будь лаÑка, Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— кориÑтуйтеÑÑ Ð¿Ñ€Ð¸Ñтроєм, ÑуміÑним з Webauthn.\n" +" Будь лаÑка, Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— кориÑтуйтеÑÑ " +"приÑтроєм, ÑуміÑним з Webauthn.\n" " " #: aleksis/core/templates/two_factor/core/login.html:86 msgid "" "\n" -" Please enter the code generated by your code generator.\n" +" Please enter the code generated by your code " +"generator.\n" " " msgstr "" "\n" -" Ðапишіть, будь лаÑка, код з Вашого генератора кодів.\n" +" Ðапишіть, будь лаÑка, код з Вашого генератора " +"кодів.\n" " " #: aleksis/core/templates/two_factor/core/login.html:91 msgid "" "\n" -" Use this form for entering backup tokens for logging in.\n" -" These tokens have been generated for you to print and keep safe. Please\n" -" enter one of these backup tokens to login to your account.\n" +" Use this form for entering backup tokens for logging " +"in.\n" +" These tokens have been generated for you to print and " +"keep safe. Please\n" +" enter one of these backup tokens to login to your " +"account.\n" " " msgstr "" "\n" -" Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ ÑкориÑтайтеÑÑ Ñ„Ð¾Ñ€Ð¼Ð¾ÑŽ Ð´Ð»Ñ Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¸Ñ… токенів.\n" -" Ці токени були згенеровані, щоб Ви Ñ—Ñ… роздрукували та зберігали у надійному міÑці.\n" -" Щоб увійти напишіть, будь лаÑка, один з резервних токенів.\n" +" Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ ÑкориÑтайтеÑÑ Ñ„Ð¾Ñ€Ð¼Ð¾ÑŽ Ð´Ð»Ñ Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¸Ñ… " +"токенів.\n" +" Ці токени були згенеровані, щоб Ви Ñ—Ñ… роздрукували та " +"зберігали у надійному міÑці.\n" +" Щоб увійти напишіть, будь лаÑка, один з резервних " +"токенів.\n" " " #: aleksis/core/templates/two_factor/core/login.html:119 @@ -2822,12 +2995,16 @@ msgstr "Дозвіл відÑутній" #: aleksis/core/templates/two_factor/core/otp_required.html:10 msgid "" "The page you requested enforces users to verify using\n" -" two-factor authentication for security reasons. You need to enable this\n" +" two-factor authentication for security reasons. You need to enable " +"this\n" " security feature in order to access this page." msgstr "" -"Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду запитуваної Ñторінки, з оглÑду на безпеку, необхідна додаткова\n" -" перевірка кориÑтувача з викориÑтаннÑм двофакторної аутентифікації.\n" -" Ð”Ð»Ñ Ð´Ð¾Ñтупу до цієї Ñторінки Вам потрібно увімкнути ці функції безпеки." +"Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду запитуваної Ñторінки, з оглÑду на безпеку, необхідна " +"додаткова\n" +" перевірка кориÑтувача з викориÑтаннÑм двофакторної " +"аутентифікації.\n" +" Ð”Ð»Ñ Ð´Ð¾Ñтупу до цієї Ñторінки Вам потрібно увімкнути ці функції " +"безпеки." #: aleksis/core/templates/two_factor/core/otp_required.html:16 msgid "Go back" @@ -2881,20 +3058,24 @@ msgid "" " " msgstr "" "\n" -" Оберіть, будь лаÑка, метод автентифікації, Ñкий Ви хочете викориÑтовувати:\n" +" Оберіть, будь лаÑка, метод автентифікації, Ñкий Ви хочете " +"викориÑтовувати:\n" " " #: aleksis/core/templates/two_factor/core/setup.html:27 msgid "" "\n" " To start using a code generator, please use your\n" -" favourite two-factor authentication (TOTP) app to scan the QR code below.\n" +" favourite two-factor authentication (TOTP) app to scan the QR code " +"below.\n" " Then enter the token generated by the app.\n" " " msgstr "" "\n" -" Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоби почати кориÑтуватиÑÑ Ð³ÐµÐ½ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼ кодів, ÑкориÑтайтеÑÑ, будь лаÑка, Ñвоїм\n" -" улюбленим додатком Ð´Ð»Ñ Ð´Ð²Ð¾Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— аутентифікації (TOTP) та проÑкануйте QR-код, що нижче.\n" +" Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоби почати кориÑтуватиÑÑ Ð³ÐµÐ½ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼ кодів, " +"ÑкориÑтайтеÑÑ, будь лаÑка, Ñвоїм\n" +" улюбленим додатком Ð´Ð»Ñ Ð´Ð²Ð¾Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— аутентифікації (TOTP) та " +"проÑкануйте QR-код, що нижче.\n" " ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ напишіть отриманий генератором токен.\n" " " @@ -2907,7 +3088,8 @@ msgid "" msgstr "" "\n" " Ðапишіть, будь лаÑка, номер телефону, на Ñкий Ви хочете\n" -" отримувати текÑтові повідомленнÑ. Ðа наÑтупному кроці він буде перевірений.\n" +" отримувати текÑтові повідомленнÑ. Ðа наÑтупному кроці він буде " +"перевірений.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:45 @@ -2935,11 +3117,13 @@ msgstr "" #: aleksis/core/templates/two_factor/core/setup.html:60 msgid "" "\n" -" We are calling your phone right now, please enter the digits you hear.\n" +" We are calling your phone right now, please enter the digits you " +"hear.\n" " " msgstr "" "\n" -" Ми зараз телефонуємо на Ваш номер, – напишіть, будь лаÑка, цифри, Ñкі Ви почуєте.\n" +" Ми зараз телефонуємо на Ваш номер, – напишіть, будь лаÑка, " +"цифри, Ñкі Ви почуєте.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:66 @@ -2949,22 +3133,29 @@ msgid "" " " msgstr "" "\n" -" Ми надіÑлали Вам текÑтове повідомленнÑ. Ðапишіть, будь лаÑка, отриманий код.\n" +" Ми надіÑлали Вам текÑтове повідомленнÑ. Ðапишіть, будь лаÑка, " +"отриманий код.\n" " " #: aleksis/core/templates/two_factor/core/setup.html:73 msgid "" "\n" -" We've encountered an issue with the selected authentication method. Please\n" -" go back and verify that you entered your information correctly, try\n" -" again, or use a different authentication method instead. If the issue\n" +" We've encountered an issue with the selected authentication " +"method. Please\n" +" go back and verify that you entered your information correctly, " +"try\n" +" again, or use a different authentication method instead. If the " +"issue\n" " persists, contact the site administrator.\n" " " msgstr "" "\n" -" Ми помітили, що Ñ–Ñнує проблема з викориÑтаннÑм обраного методу авторизації. ПовернітьÑÑ,\n" -" будь лаÑка, назад, та переконайтеÑÑ, що необхідні дані вказані правильно\n" -" Ñ– Ñпробуйте увійте ще раз, або ж ÑкориÑтайтеÑÑ Ñ–Ð½ÑˆÐ¸Ð¼ варіантом входу. Якщо ж\n" +" Ми помітили, що Ñ–Ñнує проблема з викориÑтаннÑм обраного методу " +"авторизації. ПовернітьÑÑ,\n" +" будь лаÑка, назад, та переконайтеÑÑ, що необхідні дані вказані " +"правильно\n" +" Ñ– Ñпробуйте увійте ще раз, або ж ÑкориÑтайтеÑÑ Ñ–Ð½ÑˆÐ¸Ð¼ варіантом " +"входу. Якщо ж\n" " проблема залишаєтьÑÑ, звернітьÑÑ Ð´Ð¾ адмініÑтратора Ñайту.\n" " " @@ -2990,7 +3181,8 @@ msgstr "Двохфакторна Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ ÑƒÑпішно у #: aleksis/core/templates/two_factor/core/setup_complete.html:13 msgid "" "\n" -" Congratulations, you've successfully enabled two-factor authentication.\n" +" Congratulations, you've successfully enabled two-factor " +"authentication.\n" " " msgstr "" "\n" @@ -3011,13 +3203,16 @@ msgstr "Створити резервні коди" msgid "" "\n" " However, it might happen that you don't have access to\n" -" your primary device. To enable account recovery, generate backup codes\n" +" your primary device. To enable account recovery, generate backup " +"codes\n" " or add other authentication methods.\n" " " msgstr "" "\n" -" Між іншим, може так ÑтатиÑÑ, що Ви не матимете доÑтупу до Ñвого оÑновного\n" -" приÑтрою. Ð”Ð»Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑ‚Ñ– Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу Ñтворіть резервні коди\n" +" Між іншим, може так ÑтатиÑÑ, що Ви не матимете доÑтупу до Ñвого " +"оÑновного\n" +" приÑтрою. Ð”Ð»Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑ‚Ñ– Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу " +"Ñтворіть резервні коди\n" " або додайте інші методи аутентифікації.\n" " " @@ -3031,8 +3226,12 @@ msgid "Disable Two-Factor Authentication" msgstr "Вимкнути двохфакторну автентифікацію" #: aleksis/core/templates/two_factor/profile/disable.html:12 -msgid "You are about to disable two-factor authentication. This weakens your account security, are you sure?" -msgstr "Ви вимикаєте двохфакторну автентифікацію. Це знизить захиÑÑ‚ Вашого облікового запиÑу. Ви впевнені?" +msgid "" +"You are about to disable two-factor authentication. This weakens your " +"account security, are you sure?" +msgstr "" +"Ви вимикаєте двохфакторну автентифікацію. Це знизить захиÑÑ‚ Вашого " +"облікового запиÑу. Ви впевнені?" #: aleksis/core/templates/two_factor/profile/disable.html:26 msgid "Disable" @@ -3074,15 +3273,16 @@ msgstr "Ðавчальний рік Ñтворений." msgid "The school term has been saved." msgstr "Ðавчальний рік збережений." -#: aleksis/core/views.py:401 +#: aleksis/core/views.py:401 aleksis/core/views.py:371 msgid "The child groups were successfully saved." msgstr "Підлеглі групи збережені." #: aleksis/core/views.py:420 aleksis/core/views.py:430 +#: aleksis/core/views.py:390 aleksis/core/views.py:400 msgid "The person has been saved." msgstr "ОÑоба збережена." -#: aleksis/core/views.py:480 +#: aleksis/core/views.py:480 aleksis/core/views.py:450 msgid "The group has been saved." msgstr "Група збережена." @@ -3094,132 +3294,220 @@ msgstr "Режим обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¹ уÑпіш msgid "Maintenance mode was turned off successfully." msgstr "Режим обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÑпішно вимкнений." -#: aleksis/core/views.py:588 +#: aleksis/core/views.py:588 aleksis/core/views.py:558 msgid "The announcement has been saved." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ðµ." -#: aleksis/core/views.py:604 +#: aleksis/core/views.py:604 aleksis/core/views.py:574 msgid "The announcement has been deleted." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ðµ." -#: aleksis/core/views.py:673 +#: aleksis/core/views.py:673 aleksis/core/views.py:643 msgid "The requested preference registry does not exist" msgstr "Журналу із запитаними влаÑтивоÑÑ‚Ñми не Ñ–Ñнує" -#: aleksis/core/views.py:692 +#: aleksis/core/views.py:692 aleksis/core/views.py:662 msgid "The preferences have been saved successfully." msgstr "ВлаÑтивоÑÑ‚Ñ– збережені." -#: aleksis/core/views.py:716 +#: aleksis/core/views.py:716 aleksis/core/views.py:686 msgid "The person has been deleted." msgstr "ОÑоба видалена." -#: aleksis/core/views.py:730 +#: aleksis/core/views.py:730 aleksis/core/views.py:700 msgid "The group has been deleted." msgstr "Група видалена." -#: aleksis/core/views.py:762 +#: aleksis/core/views.py:762 aleksis/core/views.py:732 msgid "The additional field has been saved." msgstr "Додаткове поле збережене." -#: aleksis/core/views.py:797 +#: aleksis/core/views.py:797 aleksis/core/views.py:767 msgid "The additional field has been deleted." msgstr "Додаткове поле видалене." -#: aleksis/core/views.py:822 +#: aleksis/core/views.py:822 aleksis/core/views.py:792 msgid "The group type has been saved." msgstr "Тип групи збережений." -#: aleksis/core/views.py:853 +#: aleksis/core/views.py:853 aleksis/core/views.py:823 msgid "The group type has been deleted." msgstr "Тип групи видалений." -#: aleksis/core/views.py:888 +#: aleksis/core/views.py:888 aleksis/core/views.py:858 msgid "Progress: Run data checks" msgstr "Перебіг: ЗапуÑк перевірки даних" -#: aleksis/core/views.py:889 +#: aleksis/core/views.py:889 aleksis/core/views.py:859 msgid "Run data checks …" msgstr "ЗапуÑкаєтьÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ° даних …" -#: aleksis/core/views.py:890 +#: aleksis/core/views.py:890 aleksis/core/views.py:860 msgid "The data checks were run successfully." msgstr "Перевірка даних уÑпішно запущена." -#: aleksis/core/views.py:891 +#: aleksis/core/views.py:891 aleksis/core/views.py:861 msgid "There was a problem while running data checks." msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку перевірки даних виникла проблема." -#: aleksis/core/views.py:908 +#: aleksis/core/views.py:908 aleksis/core/views.py:878 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "Варіант розв'ÑÐ·Ð°Ð½Ð½Ñ \"{solve_option_obj.verbose_name}\" " -#: aleksis/core/views.py:918 +#: aleksis/core/views.py:918 aleksis/core/views.py:888 msgid "The requested solve option does not exist" msgstr "Запитаний варіант розв'ÑÐ·Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує" -#: aleksis/core/views.py:951 +#: aleksis/core/views.py:951 aleksis/core/views.py:921 msgid "The dashboard widget has been saved." msgstr "Віджет інформпанелі збережений." -#: aleksis/core/views.py:981 +#: aleksis/core/views.py:981 aleksis/core/views.py:951 msgid "The dashboard widget has been created." msgstr "Віджет інформпанелі Ñтворений." -#: aleksis/core/views.py:991 +#: aleksis/core/views.py:991 aleksis/core/views.py:961 msgid "The dashboard widget has been deleted." msgstr "Віджет інформпанелі видалений." -#: aleksis/core/views.py:1063 +#: aleksis/core/views.py:1063 aleksis/core/views.py:1033 msgid "Your dashboard configuration has been saved successfully." msgstr "Ваша ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð¿Ð°Ð½ÐµÐ»Ñ– збережена." -#: aleksis/core/views.py:1065 +#: aleksis/core/views.py:1065 aleksis/core/views.py:1035 msgid "The configuration of the default dashboard has been saved successfully." msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ñ—/Ñтандартної інформпанелі збережена." -#: aleksis/core/views.py:1136 +#: aleksis/core/views.py:1136 aleksis/core/views.py:1106 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "Ð—Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ ÑƒÑпішно Ñтворене. Код запрошеннÑ: {code}" -#: aleksis/core/views.py:1233 +#: aleksis/core/views.py:1233 aleksis/core/views.py:1203 msgid "We have successfully assigned the permissions." msgstr "Ми уÑпішно призначили дозволи." -#: aleksis/core/views.py:1243 +#: aleksis/core/views.py:1243 aleksis/core/views.py:1213 msgid "The global user permission has been deleted." msgstr "Глобальний кориÑтувацький дозвіл видалений." -#: aleksis/core/views.py:1253 +#: aleksis/core/views.py:1253 aleksis/core/views.py:1223 msgid "The global group permission has been deleted." msgstr "Глобальний груповий дозвіл видалений." -#: aleksis/core/views.py:1263 +#: aleksis/core/views.py:1263 aleksis/core/views.py:1233 msgid "The object user permission has been deleted." msgstr "Об'єктний кориÑтувацький дозвіл видалений." -#: aleksis/core/views.py:1273 +#: aleksis/core/views.py:1273 aleksis/core/views.py:1243 msgid "The object group permission has been deleted." msgstr "Об'єктний груповий дозвіл видалений." -#: aleksis/core/views.py:1382 -msgid "The third-party account could not be disconnected because it is the only login method available." -msgstr "Обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони не можна від'єднати оÑкільки він єдиний ÑпоÑіб Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ." +#: aleksis/core/views.py:1382 aleksis/core/views.py:1352 +msgid "" +"The third-party account could not be disconnected because it is the only " +"login method available." +msgstr "" +"Обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони не можна від'єднати оÑкільки він єдиний " +"ÑпоÑіб Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ." -#: aleksis/core/views.py:1389 +#: aleksis/core/views.py:1389 aleksis/core/views.py:1359 msgid "The third-party account has been successfully disconnected." msgstr "Обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони уÑпішно від'єднаний." -#: aleksis/core/views.py:1465 -msgid "Person was invited successfully and an email with further instructions has been send to them." -msgstr "ОÑоба уÑпішно запрошена. ЛиÑÑ‚ з інÑтрукціÑми щодо наÑтупних дій надіÑланий на Ñ—Ñ— ел.пошту." +#: aleksis/core/views.py:1465 aleksis/core/views.py:1435 +msgid "" +"Person was invited successfully and an email with further instructions has " +"been send to them." +msgstr "" +"ОÑоба уÑпішно запрошена. ЛиÑÑ‚ з інÑтрукціÑми щодо наÑтупних дій надіÑланий " +"на Ñ—Ñ— ел.пошту." -#: aleksis/core/views.py:1476 +#: aleksis/core/views.py:1476 aleksis/core/views.py:1446 msgid "Person was already invited." msgstr "ОÑоба вже була запрошена." +#: aleksis/core/models.py:1528 +#, fuzzy +msgid "Start date and time" +msgstr "Дата Ñ– чаÑ" + +#: aleksis/core/models.py:1530 +#, fuzzy +msgid "End date and time" +msgstr "Дата Ñ– чаÑ" + +#: aleksis/core/models.py:1531 +#, fuzzy +msgid "Timezone" +msgstr "ЧаÑ" + +#: aleksis/core/models.py:1534 +#, fuzzy +msgid "Recurrences" +msgstr "ВлаÑтивоÑÑ‚Ñ–" + +#: aleksis/core/models.py:1540 +msgid "Amended base event" +msgstr "" + +#: aleksis/core/models.py:1643 +#, fuzzy +msgid "Calendar Event" +msgstr "Канали календарів" + +#: aleksis/core/models.py:1644 +#, fuzzy +msgid "Calendar Events" +msgstr "Канали календарів" + +#: aleksis/core/models.py:1670 +#, fuzzy +msgid "Birthdays" +msgstr "Календар Днів ÐародженнÑ" + +#: aleksis/core/models.py:1674 +#, fuzzy +msgid "{}'s birthday" +msgstr "%(name)s має День ÐародженнÑ" + +#: aleksis/core/models.py:1713 aleksis/core/models.py:1775 +msgid "Holidays" +msgstr "" + +#: aleksis/core/models.py:1774 +msgid "Holiday" +msgstr "" + +#: aleksis/core/preferences.py:33 +#, fuzzy +msgid "Calendar" +msgstr "Канали календарів" + +#: aleksis/core/preferences.py:490 +#, fuzzy +msgid "Birthday calendar feed color" +msgstr "Календар Днів ÐародженнÑ" + +#: aleksis/core/preferences.py:502 +msgid "Holiday calendar feed color" +msgstr "" + +#: aleksis/core/preferences.py:515 +#, fuzzy +msgid "Activated calendars" +msgstr "Календар Днів ÐародженнÑ" + +#: aleksis/core/templates/account/email/email_confirmation_message.txt:6 +#, python-format +msgid "" +"Someone tried to register an account with the username %(user_display)s and " +"your e-mail address on %(site_domain)s.\n" +"If it was you, please confirm the registration by clicking on the following " +"link:" +msgstr "" + #~ msgid "Revoke access" #~ msgstr "Відкликати доÑтуп" @@ -3240,11 +3528,13 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "" #~ "\n" -#~ " This page is currently unavailable. If this error persists, contact your site administrators:\n" +#~ " This page is currently unavailable. If this error persists, " +#~ "contact your site administrators:\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ð¦Ñ Ñторінка наразі недоÑтупна. Якщо Ñ†Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° виникне знову, звернітьÑÑ Ð´Ð¾ адмініÑтраторів Ñайту:\n" +#~ " Ð¦Ñ Ñторінка наразі недоÑтупна. Якщо Ñ†Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° виникне знову, " +#~ "звернітьÑÑ Ð´Ð¾ адмініÑтраторів Ñайту:\n" #~ " " #~ msgid "" @@ -3253,7 +3543,8 @@ msgstr "ОÑоба вже була запрошена." #~ " security." #~ msgstr "" #~ "Двохфакторна Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ñƒ Вашому обліковому запиÑÑ–\n" -#~ " вимкнена. Ð”Ð»Ñ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ обліковки увімкніть двохфакторну\n" +#~ " вимкнена. Ð”Ð»Ñ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ обліковки увімкніть " +#~ "двохфакторну\n" #~ " автентифікацію." #~ msgid "Add Phone Number" @@ -3329,7 +3620,8 @@ msgstr "ОÑоба вже була запрошена." #~ msgstr "" #~ "\n" #~ " Хоча ми рішуче заÑтерігаємо Ð’Ð°Ñ Ñ†Ðµ не робити, Ви можете \n" -#~ " також вимкнути двохфакторну автентифікацію Ð´Ð»Ñ Ñвого облікового запиÑу.\n" +#~ " також вимкнути двохфакторну автентифікацію Ð´Ð»Ñ Ñвого облікового " +#~ "запиÑу.\n" #~ " " #~ msgid "" @@ -3341,7 +3633,8 @@ msgstr "ОÑоба вже була запрошена." #~ msgstr "" #~ "\n" #~ " Двохфакторна Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð´Ð»Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ облікового запиÑу\n" -#~ " не активована. Ð”Ð»Ñ Ð¿Ñ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ облікового запиÑу увімкніть\n" +#~ " не активована. Ð”Ð»Ñ Ð¿Ñ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ облікового запиÑу " +#~ "увімкніть\n" #~ " двохфакторну автентифікацію.\n" #~ " " @@ -3448,8 +3741,14 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "ICal Feeds" #~ msgstr "iCal-Ñтрічки" -#~ msgid "These are URLs for different Calendar Feeds in the iCal (.ics) format. You can create as many as you want and import them in your calendar software." -#~ msgstr "Тут міÑÑ‚ÑÑ‚ÑŒÑÑ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° різні Ñтрічки календарів у форматі iCal (.ics). Ви можете Ñтворити Ñ—Ñ… Ñтільки, Ñкільки Вам необхідно та імпортувати Ñ—Ñ… у ПЗ Ð´Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ з календарÑми." +#~ msgid "" +#~ "These are URLs for different Calendar Feeds in the iCal (.ics) format. " +#~ "You can create as many as you want and import them in your calendar " +#~ "software." +#~ msgstr "" +#~ "Тут міÑÑ‚ÑÑ‚ÑŒÑÑ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° різні Ñтрічки календарів у форматі iCal (." +#~ "ics). Ви можете Ñтворити Ñ—Ñ… Ñтільки, Ñкільки Вам необхідно та імпортувати " +#~ "Ñ—Ñ… у ПЗ Ð´Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ з календарÑми." #~ msgid "Your iCal URLs" #~ msgstr "Ваші поÑÐ¸Ð»Ð°Ð½Ð½Ñ iCal" @@ -3474,24 +3773,30 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "" #~ "\n" -#~ " This platform is powered by AlekSIS®, a web-based school information system (SIS) which can be used\n" -#~ " to manage and/or publish organisational artifacts of educational institutions. AlekSIS is free software and\n" +#~ " This platform is powered by AlekSIS®, a web-based school " +#~ "information system (SIS) which can be used\n" +#~ " to manage and/or publish organisational artifacts of " +#~ "educational institutions. AlekSIS is free software and\n" #~ " can be used by anyone.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ð¦Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° базуєтьÑÑ Ð½Ð° AlekSIS®, веб-інÑтрументі інформаційної ÑиÑтеми Ð´Ð»Ñ Ð½Ð°Ð²Ñ‡Ð°Ð½Ð½Ñ (SIS) за допомогою Ñкої\n" -#~ " можна керувати та/або виÑвітлювати організаційні елементи навчальних закладів. AlekSIS - безплатне ПЗ\n" +#~ " Ð¦Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° базуєтьÑÑ Ð½Ð° AlekSIS®, веб-інÑтрументі " +#~ "інформаційної ÑиÑтеми Ð´Ð»Ñ Ð½Ð°Ð²Ñ‡Ð°Ð½Ð½Ñ (SIS) за допомогою Ñкої\n" +#~ " можна керувати та/або виÑвітлювати організаційні елементи " +#~ "навчальних закладів. AlekSIS - безплатне ПЗ\n" #~ " Ñ– ним може кориÑтуватиÑÑ Ð±ÑƒÐ´ÑŒ-хто.\n" #~ " " #~ msgid "" #~ "\n" -#~ " AlekSIS® is a registered trademark of the AlekSIS open source project, represented by Teckids e.V.\n" +#~ " AlekSIS® is a registered trademark of the AlekSIS open " +#~ "source project, represented by Teckids e.V.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " AlekSIS® – зареєÑтрована торгова марка проекту з відкритим програмним кодом AlekSIS, що предÑтавлена Teckids e.V.\n" +#~ " AlekSIS® – зареєÑтрована торгова марка проекту з відкритим " +#~ "програмним кодом AlekSIS, що предÑтавлена Teckids e.V.\n" #~ " " #~ msgid "Website of AlekSIS" @@ -3505,14 +3810,18 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "" #~ "\n" -#~ " The core and the official apps of AlekSIS are licenced under the EUPL, version 1.2 or later. For licence\n" -#~ " information from third-party apps, if installed, refer to the respective components below. The\n" +#~ " The core and the official apps of AlekSIS are licenced " +#~ "under the EUPL, version 1.2 or later. For licence\n" +#~ " information from third-party apps, if installed, refer to " +#~ "the respective components below. The\n" #~ " licences are marked like this:\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ядро та офіційні додатки AlekSIS ліцензовані EUPL, верÑÑ–Ñ— 1.2 та новіше. Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—\n" -#~ " щодо додатків третіх Ñторін, Ñкщо такі вÑтановлені, перейдіть до відповідних компонентів нижче.\n" +#~ " Ядро та офіційні додатки AlekSIS ліцензовані EUPL, верÑÑ–Ñ— " +#~ "1.2 та новіше. Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—\n" +#~ " щодо додатків третіх Ñторін, Ñкщо такі вÑтановлені, " +#~ "перейдіть до відповідних компонентів нижче.\n" #~ " Ці ліцензії мають таку позначку:\n" #~ " " @@ -3530,11 +3839,13 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "" #~ "\n" -#~ " Without activated JavaScript the progress status can't be updated.\n" +#~ " Without activated JavaScript the progress status can't be " +#~ "updated.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Без активованого JavaScript ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð½Ðµ зможе оновлюватиÑÑ.\n" +#~ " Без активованого JavaScript ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð½Ðµ зможе " +#~ "оновлюватиÑÑ.\n" #~ " " #~ msgid "Language" @@ -3545,12 +3856,14 @@ msgstr "ОÑоба вже була запрошена." #~ msgid "" #~ "\n" -#~ " Your administrator account is not linked to any person. Therefore,\n" +#~ " Your administrator account is not linked to any person. " +#~ "Therefore,\n" #~ " a dummy person has been linked to your account.\n" #~ " " #~ msgstr "" #~ "\n" -#~ " Ваш адмініÑтративний обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ поєднаний з жодною оÑобою. Через це\n" +#~ " Ваш адмініÑтративний обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ поєднаний з жодною " +#~ "оÑобою. Через це\n" #~ " до Вашого облікового запиÑу приєднана фейкова оÑоба.\n" #~ " " @@ -3563,8 +3876,10 @@ msgstr "ОÑоба вже була запрошена." #~ msgstr "" #~ "\n" #~ " Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ðµ пов'Ñзаний з фізоÑобою. Це означає,\n" -#~ " що Ви не маєте жодного доÑтупу до навчальної інформації. ЗвернітьÑÑ,\n" -#~ " будь лаÑка, до адмініÑтраторів AlekSIS у Вашому навчальному закладі.\n" +#~ " що Ви не маєте жодного доÑтупу до навчальної інформації. " +#~ "ЗвернітьÑÑ,\n" +#~ " будь лаÑка, до адмініÑтраторів AlekSIS у Вашому навчальному " +#~ "закладі.\n" #~ " " #~ msgid "Impersonate" diff --git a/aleksis/core/managers.py b/aleksis/core/managers.py index c79e756f509ea428359c95617e3e84d573985cf2..07237fdac02af7750a2000f89167cb9bbc217a5c 100644 --- a/aleksis/core/managers.py +++ b/aleksis/core/managers.py @@ -8,7 +8,7 @@ from django.db.models.manager import Manager from calendarweek import CalendarWeek from django_cte import CTEManager, CTEQuerySet -from polymorphic.managers import PolymorphicManager +from polymorphic.managers import PolymorphicManager, PolymorphicQuerySet class AlekSISBaseManager(_CurrentSiteManager): @@ -141,3 +141,14 @@ class InstalledWidgetsDashboardWidgetOrderManager(Manager): class PolymorphicCurrentSiteManager(AlekSISBaseManager, PolymorphicManager): """Default manager for extensible, polymorphic models.""" + + +class HolidayQuerySet(DateRangeQuerySetMixin, PolymorphicQuerySet): + """QuerySet with custom query methods for holidays.""" + + def get_all_days(self) -> list[date]: + """Get all days included in the selected holidays.""" + holiday_days = [] + for holiday in self: + holiday_days += list(holiday.get_days()) + return holiday_days diff --git a/aleksis/core/migrations/0051_calendarevent_and_holiday.py b/aleksis/core/migrations/0051_calendarevent_and_holiday.py new file mode 100644 index 0000000000000000000000000000000000000000..28e5294027d766f64d6cb644696e84f7a9c2a6ac --- /dev/null +++ b/aleksis/core/migrations/0051_calendarevent_and_holiday.py @@ -0,0 +1,164 @@ +# Generated by Django 4.1.10 on 2023-07-11 19:01 + +import aleksis.core.managers +import aleksis.core.mixins +from django.db import migrations, models +import django.db.models.deletion +import recurrence.fields +import timezone_field.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ("contenttypes", "0002_remove_content_type_name"), + ("sites", "0002_alter_domain_unique"), + ("core", "0050_managed_by_app_label"), + ] + + operations = [ + migrations.CreateModel( + name="CalendarEvent", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "managed_by_app_label", + models.CharField( + blank=True, + editable=False, + max_length=255, + verbose_name="App label of app responsible for managing this instance", + ), + ), + ("extended_data", models.JSONField(default=dict, editable=False)), + ( + "datetime_start", + models.DateTimeField(blank=True, null=True, verbose_name="Start date and time"), + ), + ( + "datetime_end", + models.DateTimeField(blank=True, null=True, verbose_name="End date and time"), + ), + ( + "timezone", + timezone_field.fields.TimeZoneField( + blank=True, null=True, verbose_name="Timezone" + ), + ), + ("date_start", models.DateField(blank=True, null=True, verbose_name="Start date")), + ("date_end", models.DateField(blank=True, null=True, verbose_name="End date")), + ( + "recurrences", + recurrence.fields.RecurrenceField( + blank=True, null=True, verbose_name="Recurrences" + ), + ), + ( + "amends", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="amended_by", + to="core.calendarevent", + verbose_name="Amended base event", + ), + ), + ( + "polymorphic_ctype", + models.ForeignKey( + editable=False, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="polymorphic_%(app_label)s.%(class)s_set+", + to="contenttypes.contenttype", + ), + ), + ( + "site", + models.ForeignKey( + default=1, + editable=False, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="sites.site", + ), + ), + ], + options={ + "verbose_name": "Calendar Event", + "verbose_name_plural": "Calendar Events", + "ordering": ["datetime_start", "date_start", "datetime_end", "date_end"], + }, + bases=(aleksis.core.mixins.CalendarEventMixin, models.Model), + managers=[ + ("objects", aleksis.core.managers.PolymorphicCurrentSiteManager()), + ], + ), + migrations.CreateModel( + name="Holiday", + fields=[ + ( + "calendarevent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.calendarevent", + ), + ), + ("holiday_name", models.CharField(max_length=255, verbose_name="Name")), + ], + options={ + "verbose_name": "Holiday", + "verbose_name_plural": "Holidays", + }, + bases=("core.calendarevent",), + managers=[ + ("objects", aleksis.core.managers.PolymorphicCurrentSiteManager()), + ], + ), + migrations.AddConstraint( + model_name="calendarevent", + constraint=models.CheckConstraint( + check=models.Q( + ("date_start__isnull", True), ("datetime_start__isnull", True), _negated=True + ), + name="datetime_start_or_date_start", + ), + ), + migrations.AddConstraint( + model_name="calendarevent", + constraint=models.CheckConstraint( + check=models.Q( + ("date_end__isnull", True), ("datetime_end__isnull", True), _negated=True + ), + name="datetime_end_or_date_end", + ), + ), + migrations.AddConstraint( + model_name="calendarevent", + constraint=models.CheckConstraint( + check=models.Q( + ("datetime_start__isnull", False), ("timezone__isnull", True), _negated=True + ), + name="timezone_if_datetime_start", + ), + ), + migrations.AddConstraint( + model_name="calendarevent", + constraint=models.CheckConstraint( + check=models.Q( + ("datetime_end__isnull", False), ("timezone__isnull", True), _negated=True + ), + name="timezone_if_datetime_end", + ), + ), + ] diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index b55a700db5390895c2c827a9ec13931bc55dbac9..c6c19af0a5f58a105377bb2a36502b562056739d 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -2,7 +2,7 @@ import os from datetime import datetime -from typing import Any, Callable, ClassVar, List, Optional, Union +from typing import Any, Callable, ClassVar, Iterable, List, Optional, Union from django.conf import settings from django.contrib import messages @@ -14,18 +14,21 @@ from django.db import models from django.db.models import JSONField, QuerySet from django.db.models.fields import CharField, TextField from django.forms.forms import BaseForm -from django.forms.models import ModelForm, ModelFormMetaclass -from django.http import HttpResponse +from django.forms.models import ModelForm, ModelFormMetaclass, fields_for_model +from django.http import HttpRequest, HttpResponse from django.utils.functional import classproperty, lazy from django.utils.translation import gettext as _ from django.views.generic import CreateView, UpdateView from django.views.generic.edit import DeleteView, ModelFormMixin +import recurring_ical_events import reversion +from django_ical.feedgenerator import ITEM_ELEMENT_FIELD_MAP from dynamic_preferences.settings import preferences_settings from dynamic_preferences.types import FilePreference from guardian.admin import GuardedModelAdmin from guardian.core import ObjectPermissionChecker +from icalendar import Calendar from jsonstore.fields import IntegerField, JSONFieldMixin from material.base import Fieldset, Layout, LayoutNode from polymorphic.base import PolymorphicModelBase @@ -40,6 +43,8 @@ from aleksis.core.managers import ( SchoolTermRelatedQuerySet, ) +from .util.core_helpers import ExtendedICal20Feed + class _ExtensibleModelBase(models.base.ModelBase): """Ensure predefined behaviour on model creation. @@ -571,7 +576,7 @@ class PublicFilePreferenceMixin(FilePreference): class RegistryObject: """Generic registry to allow registration of subclasses over all apps.""" - _registry: ClassVar[Optional[dict[str, "RegistryObject"]]] = None + _registry: ClassVar[Optional[dict[str, type["RegistryObject"]]]] = None name: ClassVar[str] = "" def __init_subclass__(cls): @@ -583,18 +588,178 @@ class RegistryObject: cls._register() @classmethod - def _register(cls): + def _register(cls: type["RegistryObject"]): if cls.name and cls.name not in cls._registry: cls._registry[cls.name] = cls @classproperty - def registered_objects_dict(cls): + def registered_objects_dict(cls) -> dict[str, type["RegistryObject"]]: + """Get dict of registered objects.""" return cls._registry @classproperty - def registered_objects_list(cls): + def registered_objects_list(cls) -> list[type["RegistryObject"]]: + """Get list of registered objects.""" return list(cls._registry.values()) @classmethod + def get_object_by_name(cls, name: str) -> Optional[type["RegistryObject"]]: + """Get registered object by name.""" + return cls.registered_objects_dict.get(name) + + +class ObjectAuthenticator(RegistryObject): + def authenticate(self, request, obj): + raise NotImplementedError() + + +class CalendarEventMixin(RegistryObject): + """Mixin for calendar feeds. + + This mixin can be used to create calendar feeds for objects. It can be used + by adding it to a model or another object. The basic attributes of the calendar + can be set by either setting the attributes of the class or by implementing + the corresponding class methods. Please notice that the class methods are + overriding the attributes. The following attributes are mandatory: + + - name: Unique name for the calendar feed + - verbose_name: Shown name of the feed + + The respective class methods have a `get_` prefix and are called without any arguments. + There are also some more attributes. Please refer to the class signature for more + information. + + The list of objects used to create the calendar feed have to be provided by + the method `get_objects` class method. It's mandatory to implement this method. + + To provide the data for the events, a certain set of class methods can be implemented. + The following iCal attributes are supported: + + guid, title, description, link, class, created, updateddate, start_datetime, end_datetime, + location, geolocation, transparency, organizer, attendee, rrule, rdate, exdate, valarm, status + + To implement a method for a certain attribute, the name of the method has to be + `value_<your_attribute>`. For example, to implement the `title` attribute, the + method `value_title` has to be implemented. The method has to return the value + for the attribute. The method is called with the reference object as argument. + """ + + name: str = "" # Unique name for the calendar feed + verbose_name: str = "" # Shown name of the feed + link: str = "" # Link for the feed, optional + description: str = "" # Description of the feed, optional + color: str = "#222222" # Color of the feed, optional + + @classmethod + def get_verbose_name(cls, request) -> str: + """Return the verbose name of the calendar feed.""" + return cls.verbose_name + + @classmethod + def get_link(cls, request) -> str: + """Return the link of the calendar feed.""" + return cls.link + + @classmethod + def get_description(cls, request) -> str: + """Return the description of the calendar feed.""" + return cls.description + + @classmethod + def get_language(cls, request) -> str: + """Return the language of the calendar feed.""" + return "en" # FIXME + + @classmethod + def get_color(cls, request) -> str: + """Return the color of the calendar feed.""" + return cls.color + + @classmethod + def create_event(cls, reference_object, feed: ExtendedICal20Feed, request) -> dict[str, Any]: + """Create an event for the given reference object and add it to the feed.""" + values = {} + for field in cls.get_event_field_names(): + field_value = cls.get_event_field_value(reference_object, field, request) + if field_value is not None: + values[field] = field_value + feed.add_item(**values) + return values + + @classmethod + def start_feed(cls, request) -> ExtendedICal20Feed: + """Start the feed and return it.""" + feed = ExtendedICal20Feed( + title=cls.get_verbose_name(request), + link=cls.get_link(request), + description=cls.get_description(request), + language=cls.get_language(request), + color=cls.get_color(request), + ) + return feed + + @classmethod + def get_objects(cls, request: HttpRequest) -> Iterable: + """Return the objects to create the calendar feed for.""" + raise NotImplementedError + + @classmethod + def create_feed(cls, request: HttpRequest) -> ExtendedICal20Feed: + """Create the calendar feed with all events.""" + feed = cls.start_feed(request) + + for reference_object in cls.get_objects(request): + cls.create_event(reference_object, feed, request) + + return feed + + @classmethod + def get_calendar_object(cls, request: HttpRequest) -> Calendar: + """Return the calendar object.""" + feed = cls.create_feed(request) + return feed.get_calendar_object() + + @classmethod + def get_single_events(cls, request: HttpRequest, start=None, end=None): + """Get single events for this calendar feed.""" + feed = cls.create_feed(request) + return feed.get_single_events(start, end) + + @classmethod + def get_event_field_names(cls) -> list[str]: + """Return the names of the fields to be used for the feed.""" + return [field_map[0] for field_map in ITEM_ELEMENT_FIELD_MAP] + + @classmethod + def get_event_field_value(cls, reference_object, field_name: str, request): + """Return the value for the given field name.""" + method_name = f"value_{field_name}" + if hasattr(cls, method_name) and callable(getattr(cls, method_name)): + return getattr(cls, method_name)(reference_object, request) + return None + + @classmethod + def value_link(cls, reference_object, request) -> str: + return "" + + @classmethod + def value_color(cls, reference_object, request) -> str: + return cls.get_color(request) + + @classproperty + def valid_feed(cls): + """Return if the feed is valid.""" + return cls.name != cls.__name__ + + @classproperty + def valid_feeds(cls): + """Return a list of valid feeds.""" + return [feed for feed in cls.registered_objects_list if feed.valid_feed] + + @classproperty + def valid_feed_names(cls): + """Return a list of valid feed names.""" + return [feed.name for feed in cls.valid_feeds] + def get_object_by_name(cls, name): - cls.registered_objects_dict.get(name) + return cls.registered_objects_dict.get(name) diff --git a/aleksis/core/models.py b/aleksis/core/models.py index d90790427fb3c22531ec0cda50e9c48eb615e196..4151d51b39d4cafac8ba91250a5ed64b8d4af50e 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -3,7 +3,7 @@ import base64 import hmac import uuid from datetime import date, datetime, timedelta -from typing import Any, Iterable, List, Optional, Sequence, Union +from typing import Any, Iterable, Iterator, List, Optional, Sequence, Union from urllib.parse import urljoin, urlparse from django.conf import settings @@ -23,6 +23,7 @@ from django.dispatch import receiver from django.forms.widgets import Media from django.urls import reverse from django.utils import timezone +from django.utils.formats import date_format from django.utils.functional import classproperty from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ @@ -31,12 +32,17 @@ import customidenticon import jsonstore from cachalot.api import cachalot_disabled from cache_memoize import cache_memoize +from calendarweek import CalendarWeek from celery.result import AsyncResult from celery_progress.backend import Progress from ckeditor.fields import RichTextField from django_celery_results.models import TaskResult from django_cte import CTEQuerySet, With +from django_ical.utils import build_rrule_from_recurrences_rrule, build_rrule_from_text from dynamic_preferences.models import PerInstancePreferenceModel +from guardian.shortcuts import get_objects_for_user +from icalendar import vCalAddress, vText +from icalendar.prop import vRecur from invitations import signals from invitations.adapters import get_invitations_adapter from invitations.base_invitation import AbstractBaseInvitation @@ -52,6 +58,8 @@ from oauth2_provider.models import ( ) from phonenumber_field.modelfields import PhoneNumberField from polymorphic.models import PolymorphicModel +from recurrence.fields import RecurrenceField +from timezone_field import TimeZoneField from aleksis.core.data_checks import ( BrokenDashboardWidgetDataCheck, @@ -63,12 +71,16 @@ from .managers import ( CurrentSiteManagerWithoutMigrations, GroupManager, GroupQuerySet, + HolidayQuerySet, InstalledWidgetsDashboardWidgetOrderManager, + PolymorphicCurrentSiteManager, SchoolTermQuerySet, UninstallRenitentPolymorphicManager, ) from .mixins import ( + CalendarEventMixin, ExtensibleModel, + ExtensiblePolymorphicModel, GlobalPermissionModel, PureDjangoModel, RegistryObject, @@ -365,6 +377,16 @@ class Person(ExtensibleModel): else: return self.identicon_url + def get_vcal_address(self, role: str = "REQ-PARTICIPANT") -> Optional[vCalAddress]: + """Return a vCalAddress object for this person.""" + if not self.email: + # vCalAddress requires an email address + return None + vcal = vCalAddress(f"MAILTO:{self.email}") + vcal.params["cn"] = vText(self.full_name) + vcal.params["ROLE"] = vText(role) + return vcal + def save(self, *args, **kwargs): # Determine all fields that were changed since last load changed = self.user_info_tracker.changed() @@ -1484,3 +1506,270 @@ class Room(ExtensibleModel): fields=["site_id", "short_name"], name="unique_room_short_name_per_site" ), ] + + +class CalendarEvent(CalendarEventMixin, ExtensiblePolymorphicModel): + """A planned event in a calendar. + + To make use of this model, you need to inherit from this model. + Every subclass of this model represents a certain calendar (feed). + It therefore needs to set the basic attributes of the calendar like + described in the documentation of `CalendarEventMixin`. + + Furthermore, every `value_*` method from `CalendarEventMixin` + can be implemented to provide additional data (either static or dynamic). + Some like start and end date are pre-implemented in this model. Others, like + `value_title` need to be implemented in the subclass. Some methods are + also optional, like `value_location` or `value_description`. + Please refer to the documentation of `CalendarEventMixin` for more information. + """ + + datetime_start = models.DateTimeField( + verbose_name=_("Start date and time"), null=True, blank=True + ) + datetime_end = models.DateTimeField(verbose_name=_("End date and time"), null=True, blank=True) + timezone = TimeZoneField(verbose_name=_("Timezone"), null=True, blank=True) + date_start = models.DateField(verbose_name=_("Start date"), null=True, blank=True) + date_end = models.DateField(verbose_name=_("End date"), null=True, blank=True) + recurrences = RecurrenceField(verbose_name=_("Recurrences"), null=True, blank=True) + amends = models.ForeignKey( + "self", + on_delete=models.CASCADE, + null=True, + blank=True, + verbose_name=_("Amended base event"), + related_name="amended_by", + ) + + def provide_list_in_timezone(self, seq): + """Provide a list of datetimes in the saved timezone.""" + return [dt.astimezone(self.timezone) if isinstance(dt, datetime) else dt for dt in seq] + + @classmethod + def value_title(cls, reference_object: "CalendarEvent", request) -> str: + """Return the title of the calendar event.""" + raise NotImplementedError() + + @classmethod + def value_start_datetime( + cls, reference_object: "CalendarEvent", request + ) -> Union[datetime, date]: + """Return the start datetime of the calendar event.""" + if reference_object.datetime_start: + return reference_object.datetime_start.astimezone(reference_object.timezone) + return reference_object.date_start + + @classmethod + def value_end_datetime( + cls, reference_object: "CalendarEvent", request + ) -> Union[datetime, date, None]: + """Return the end datetime of the calendar event.""" + if reference_object.datetime_end: + return reference_object.datetime_end.astimezone(reference_object.timezone) + if reference_object.date_end == reference_object.date_start: + # Rule for all day events: If the event is only one day long, + # the end date has to be empty + return None + return reference_object.date_end + + @classmethod + def value_rrule(cls, reference_object: "CalendarEvent", request) -> Optional[vRecur]: + """Return the rrule of the calendar event.""" + if not reference_object.recurrences or not reference_object.recurrences.rrules: + return None + # iCal only supports one RRULE per event as per RFC 5545 (change to older RFC 2445) + return build_rrule_from_recurrences_rrule(reference_object.recurrences.rrules[0]) + + @classmethod + def value_rdate(cls, reference_object: "CalendarEvent", request) -> Optional[list[datetime]]: + """Return the rdate of the calendar event.""" + if not reference_object.recurrences: + return None + return reference_object.provide_list_in_timezone(reference_object.recurrences.rdates) + + @classmethod + def value_exrule(cls, reference_object: "CalendarEvent", request) -> Optional[vRecur]: + """Return the exrule of the calendar event.""" + if not reference_object.recurrences or not reference_object.recurrences.exrules: + return None + return [build_rrule_from_recurrences_rrule(r) for r in reference_object.recurrences.exrules] + + @classmethod + def value_exdate(cls, reference_object: "CalendarEvent", request) -> Optional[list[datetime]]: + """Return the exdate of the calendar event.""" + if not reference_object.recurrences: + return None + # return reference_object.recurrences.exdates + return reference_object.provide_list_in_timezone(reference_object.recurrences.exdates) + + @classmethod + def value_unique_id(cls, reference_object: "CalendarEvent", request) -> str: + """Return an unique identifier for an event.""" + if reference_object.amends: + return cls.value_unique_id(reference_object.amends, request) + return f"{cls.name}-{reference_object.id}" + + @classmethod + def value_recurrence_id( + cls, reference_object: "CalendarEvent", request + ) -> Optional[Union[datetime, date]]: + """Return the recurrence id of the calendar event.""" + if reference_object.amends: + return reference_object.amends.value_start_datetime(reference_object, request) + return None + + @classmethod + def value_color(cls, reference_object: "CalendarEvent", request) -> str: + """Return the color of the calendar.""" + return cls.get_color(request) + + @classmethod + def get_objects(cls, request) -> Iterable: + """Return all objects that should be included in the calendar.""" + return cls.objects.instance_of(cls) + + def save(self, *args, **kwargs): + if ( + self.datetime_start + and self.datetime_end + and self.datetime_start.tzinfo != self.datetime_end.tzinfo + ): + self.datetime_end = self.datetime_end.astimezone(self.datetime_start.tzinfo) + if self.datetime_start and self.datetime_end: + self.timezone = self.datetime_start.tzinfo + super().save(*args, **kwargs) + + class Meta: + verbose_name = _("Calendar Event") + verbose_name_plural = _("Calendar Events") + constraints = [ + models.CheckConstraint( + check=~Q(datetime_start__isnull=True, date_start__isnull=True), + name="datetime_start_or_date_start", + ), + models.CheckConstraint( + check=~Q(datetime_end__isnull=True, date_end__isnull=True), + name="datetime_end_or_date_end", + ), + models.CheckConstraint( + check=~Q(datetime_start__isnull=False, timezone__isnull=True), + name="timezone_if_datetime_start", + ), + models.CheckConstraint( + check=~Q(datetime_end__isnull=False, timezone__isnull=True), + name="timezone_if_datetime_end", + ), + ] + ordering = ["datetime_start", "date_start", "datetime_end", "date_end"] + + +class BirthdayEvent(CalendarEventMixin): + """A calendar feed with all birthdays.""" + + name = "birthdays" + verbose_name = _("Birthdays") + + @classmethod + def value_title(cls, reference_object: Person, request) -> str: + return _("{}'s birthday").format(reference_object.addressing_name) + + @classmethod + def value_description(cls, reference_object: Person, request) -> str: + return ("{name} was born on {birthday}.").format( + name=reference_object.addressing_name, + birthday=date_format(reference_object.date_of_birth), + ) + + @classmethod + def value_start_datetime(cls, reference_object: Person, request) -> date: + return reference_object.date_of_birth + + @classmethod + def value_rrule(cls, reference_object: Person, request) -> vRecur: + return build_rrule_from_text("FREQ=YEARLY") + + @classmethod + def value_unique_id(cls, reference_object: Person, request) -> str: + return f"birthday-{reference_object.id}" + + @classmethod + def get_color(cls, request) -> str: + return get_site_preferences()["calendar__birthday_color"] + + @classmethod + def get_objects(cls, request) -> QuerySet: + qs = Person.objects.filter(date_of_birth__isnull=False) + qs = qs.filter( + Q(pk=request.user.person.pk) + | Q(pk__in=get_objects_for_user(request.user, "core.view_personal_details", qs)) + ) + return qs + + +class Holiday(CalendarEvent): + """Holiday model for keeping track of school holidays.""" + + name = "holidays" + verbose_name = _("Holidays") + + @classmethod + def value_title(cls, reference_object: "Holiday", request) -> str: + return reference_object.holiday_name + + @classmethod + def value_description(cls, reference_object: "Holiday", request) -> str: + return "" + + @classmethod + def get_color(cls, request) -> str: + return get_site_preferences()["calendar__holiday_color"] + + objects = PolymorphicCurrentSiteManager.from_queryset(HolidayQuerySet)() + + holiday_name = models.CharField(verbose_name=_("Name"), max_length=255) + + def get_days(self) -> Iterator[date]: + """Get all days included in the holiday.""" + delta = self.date_end - self.date_start + for i in range(delta.days + 1): + yield self.date_start + timedelta(days=i) + + @classmethod + def in_week(cls, week: CalendarWeek) -> dict[int, Optional["Holiday"]]: + """Get the holidays that are active in a given week.""" + per_weekday = {} + holidays = Holiday.objects.in_week(week) + + for weekday in range(0, 7): + holiday_date = week[weekday] + filtered_holidays = list( + filter( + lambda h: holiday_date >= h.date_start and holiday_date <= h.date_end, + holidays, + ) + ) + if filtered_holidays: + per_weekday[weekday] = filtered_holidays[0] + + return per_weekday + + @classmethod + def get_ex_dates(cls, datetime_start, datetime_end, recurrence): + """Get the dates to exclude for holidays.""" + recurrence.dtstart = recurrence.dtstart.astimezone(timezone.get_current_timezone()) + holiday_dates = [ + h["DTSTART"].dt for h in Holiday.get_single_events(datetime_start, datetime_end) + ] + exdates = [ + h.astimezone(timezone.utc) + for h in recurrence.occurrences() + if h.date() in holiday_dates + ] + return exdates + + def __str__(self) -> str: + return self.holiday_name + + class Meta: + verbose_name = _("Holiday") + verbose_name_plural = _("Holidays") diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py index 7d10c2ae5c4a7b2538ad907c227033ea6a0ef0f2..a3be1ac89770a89c2d3ea82b64aee7adc3913c9f 100644 --- a/aleksis/core/preferences.py +++ b/aleksis/core/preferences.py @@ -16,7 +16,7 @@ from dynamic_preferences.types import ( ) from oauth2_provider.models import AbstractApplication -from .mixins import PublicFilePreferenceMixin +from .mixins import CalendarEventMixin, PublicFilePreferenceMixin from .models import Group, Person from .registries import person_preferences_registry, site_preferences_registry from .util.notifications import get_notification_choices_lazy @@ -30,6 +30,7 @@ footer = Section("footer", verbose_name=_("Footer")) account = Section("account", verbose_name=_("Accounts")) auth = Section("auth", verbose_name=_("Authentication")) internationalisation = Section("internationalisation", verbose_name=_("Internationalisation")) +calendar = Section("calendar", verbose_name=_("Calendar")) @site_preferences_registry.register @@ -477,3 +478,42 @@ class AutoUpdatingDashboardSite(BooleanPreference): name = "automatically_update_dashboard_site" default = True verbose_name = _("Automatically update the dashboard and its widgets sitewide") + + +@site_preferences_registry.register +class BirthdayFeedColor(StringPreference): + """Color for the birthdays calendar feed.""" + + section = calendar + name = "birthday_color" + default = "#0d5eaf" + verbose_name = _("Birthday calendar feed color") + widget = ColorWidget + required = True + + +@site_preferences_registry.register +class HolidayFeedColor(StringPreference): + """Color for the holidays calendar feed.""" + + section = calendar + name = "holiday_color" + default = "#0d5eaf" + verbose_name = _("Holiday calendar feed color") + widget = ColorWidget + required = True + + +@person_preferences_registry.register +class ActivatedCalendars(MultipleChoicePreference): + """Calendars that are activated for a person.""" + + section = calendar + name = "activated_calendars" + default = [] + widget = SelectMultiple + verbose_name = _("Activated calendars") + required = False + + field_attribute = {"initial": []} + choices = [(feed.name, feed.verbose_name) for feed in CalendarEventMixin.valid_feeds] diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py index 6d77fcd70fb32712c4358a9bcec5a03e306140d5..ae2f12129cd8193cb0f5fba9887a6a45c2c92785 100644 --- a/aleksis/core/rules.py +++ b/aleksis/core/rules.py @@ -409,3 +409,6 @@ rules.add_perm("core.test_pdf_rule", test_pdf_generation_predicate) view_progress_predicate = has_person & is_own_celery_task rules.add_perm("core.view_progress_rule", view_progress_predicate) + +view_calendar_feed_predicate = has_person +rules.add_perm("core.view_calendar_feed_rule", view_calendar_feed_predicate) diff --git a/aleksis/core/schema/__init__.py b/aleksis/core/schema/__init__.py index ae137be9da07fb643e17e00fd2111892802cd24b..604e0d6cbb4b1f5c08c244c42ddc42b3e4084bbb 100644 --- a/aleksis/core/schema/__init__.py +++ b/aleksis/core/schema/__init__.py @@ -23,6 +23,7 @@ from ..models import ( from ..util.apps import AppConfig from ..util.core_helpers import get_allowed_object_ids, get_app_module, get_app_packages, has_person from .base import FilterOrderList +from .calendar import CalendarBaseType, SetCalendarStatusMutation from .celery_progress import CeleryProgressFetchedMutation, CeleryProgressType from .custom_menu import CustomMenuType from .dynamic_routes import DynamicRouteType @@ -93,6 +94,8 @@ class Query(graphene.ObjectType): school_terms = FilterOrderList(SchoolTermType) + calendar = graphene.Field(CalendarBaseType) + def resolve_ping(root, info, payload) -> str: return payload @@ -209,6 +212,10 @@ class Query(graphene.ObjectType): return room_object + @staticmethod + def resolve_calendar(root, info, **kwargs): + return True + class Mutation(graphene.ObjectType): update_person = PersonMutation.Field() @@ -229,6 +236,8 @@ class Mutation(graphene.ObjectType): delete_school_terms = SchoolTermBatchDeleteMutation.Field() update_school_terms = SchoolTermBatchPatchMutation.Field() + set_calendar_status = SetCalendarStatusMutation.Field() + def build_global_schema(): """Build global GraphQL schema from all apps.""" diff --git a/aleksis/core/schema/calendar.py b/aleksis/core/schema/calendar.py new file mode 100644 index 0000000000000000000000000000000000000000..110e2cf826f26314b278bf293724712473a61ba8 --- /dev/null +++ b/aleksis/core/schema/calendar.py @@ -0,0 +1,127 @@ +from datetime import datetime + +from django.core.exceptions import PermissionDenied +from django.urls import reverse + +import graphene +from graphene import ObjectType + +from aleksis.core.mixins import CalendarEventMixin +from aleksis.core.util.core_helpers import has_person + + +class CalendarEventType(ObjectType): + name = graphene.String() + description = graphene.String() + location = graphene.String(required=False) + start = graphene.String() + end = graphene.String() + color = graphene.String() + uid = graphene.String() + all_day = graphene.Boolean() + status = graphene.String() + meta = graphene.String() + + def resolve_name(root, info, **kwargs): + return root["SUMMARY"] + + def resolve_description(root, info, **kwargs): + return root["DESCRIPTION"] + + def resolve_location(root, info, **kwargs): + return root.get("LOCATION", "") + + def resolve_start(root, info, **kwargs): + return root["DTSTART"].dt + + def resolve_end(root, info, **kwargs): + return root["DTEND"].dt + + def resolve_color(root, info, **kwargs): + return root["COLOR"] + + def resolve_uid(root, info, **kwargs): + return root["UID"] + + def resolve_all_day(root, info, **kwargs): + return not isinstance(root["DTSTART"].dt, datetime) + + def resolve_status(root, info, **kwargs): + return root.get("STATUS", "") + + def resolve_meta(root, info, **kwargs): + return root.get("X-META", "{}") + + +class CalendarFeedType(ObjectType): + events = graphene.List( + CalendarEventType, + start=graphene.Date(required=False), + end=graphene.Date(required=False), + ) + + def resolve_events(root, info, start=None, end=None, **kwargs): + return root.get_single_events(start, end) + + +class CalendarType(ObjectType): + name = graphene.String(required=True) + verbose_name = graphene.String(required=True) + description = graphene.String() + feed = graphene.Field(CalendarFeedType) + color = graphene.String() + + url = graphene.String() + + activated = graphene.Boolean() + + def resolve_verbose_name(root, info, **kwargs): + return root.get_verbose_name(info.context) + + def resolve_description(root, info, **kwargs): + return root.get_description(info.context) + + def resolve_feed(root, info, **kwargs): + return root.create_feed(info.context) + + def resolve_url(root, info, **kwargs): + return info.context.build_absolute_uri(reverse("calendar_feed", args=[root.name])) + + def resolve_color(root, info, **kwargs): + return root.get_color(info.context) + + def resolve_activated(root, info, **kwargs): + return root.name in info.context.user.person.preferences["calendar__activated_calendars"] + + +class SetCalendarStatusMutation(graphene.Mutation): + """Mutation to change the status of a calendar.""" + + class Arguments: + calendars = graphene.List(graphene.String) + + ok = graphene.Boolean() + + def mutate(root, info, calendars, **kwargs): + if not has_person(info.context): + raise PermissionDenied + calendar_feeds = [cal for cal in calendars if cal in CalendarEventMixin.valid_feed_names] + info.context.user.person.preferences["calendar__activated_calendars"] = calendar_feeds + return SetCalendarStatusMutation(ok=True) + + +class CalendarBaseType(ObjectType): + calendar_feeds = graphene.List(CalendarType) + + calendar_feeds_by_names = graphene.List(CalendarType, names=graphene.List(graphene.String)) + + all_feeds_url = graphene.String() + + def resolve_calendar_feeds(root, info, **kwargs): + return CalendarEventMixin.valid_feeds + + def resolve_calendar_feeds_by_names(root, info, names, **kwargs): + return [CalendarEventMixin.get_object_by_name(name) for name in names] + + def resolve_all_feeds_url(root, info, **kwargs): + return info.context.build_absolute_uri(reverse("all_calendar_feeds")) diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index 77cda4ee58ed24e8f3df6bab2196643023b3b5f7..8307ae9c16e65073b2fcc890d7aeeac4cb9bf408 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -156,6 +156,7 @@ INSTALLED_APPS = [ "rest_framework", "graphene_django", "dj_iconify.apps.DjIconifyConfig", + "recurrence", ] merge_app_settings("INSTALLED_APPS", INSTALLED_APPS, True) @@ -937,7 +938,7 @@ LOGGING["root"] = { } # Configure global log Format LOGGING["formatters"]["verbose"] = { - "format": "{asctime} {levelname} {name}[{process}]: {msg}", + "format": "{asctime} {levelname} {name}[{process}]: {message}", "style": "{", } # Add null handler for selective silencing diff --git a/aleksis/core/templates/core/base_simple_print.html b/aleksis/core/templates/core/base_simple_print.html index 6e66e28983679acebdd2df0993ae7b5fdf64e621..abb01712a5f52d4ec9a44e34a31b11b8a29f9ef1 100644 --- a/aleksis/core/templates/core/base_simple_print.html +++ b/aleksis/core/templates/core/base_simple_print.html @@ -4,6 +4,8 @@ <!DOCTYPE html> <html lang="{{ LANGUAGE_CODE }}"> <head> + <base href="{{ BASE_URL }}" /> + {% include "core/partials/meta.html" %} <title> diff --git a/aleksis/core/tests/mixins/test_registry_object.py b/aleksis/core/tests/mixins/test_registry_object.py new file mode 100644 index 0000000000000000000000000000000000000000..d872e4a7078d27fd176a4b3f557bef3b55467fbb --- /dev/null +++ b/aleksis/core/tests/mixins/test_registry_object.py @@ -0,0 +1,57 @@ +import pytest + +from aleksis.core.mixins import RegistryObject + + +def test_registry_object_name(): + class ExampleRegistry(RegistryObject): + pass + + class ExampleWithManualName(ExampleRegistry): + name = "example_a" + + class ExampleWithAutomaticName(ExampleRegistry): + pass + + class ExampleWithOverridenAutomaticName(ExampleWithManualName): + name = "example_b" + + class ExampleWithOverridenManualName(ExampleWithAutomaticName): + name = "example_bb" + + assert ExampleRegistry.name == "" + assert ExampleWithManualName.name == "example_a" + assert ExampleWithAutomaticName.name == "ExampleWithAutomaticName" + assert ExampleWithOverridenAutomaticName.name == "example_b" + assert ExampleWithOverridenManualName.name == "example_bb" + + +def test_registry_object_registry(): + class ExampleRegistry(RegistryObject): + pass + + class ExampleA(ExampleRegistry): + pass + + class ExampleB(ExampleRegistry): + pass + + class ExampleAA(ExampleA): + name = "example_aa" + + assert ExampleRegistry.registered_objects_dict == { + "ExampleA": ExampleA, + "ExampleB": ExampleB, + "example_aa": ExampleAA, + } + assert ExampleRegistry.registered_objects_dict == ExampleRegistry._registry + + assert ExampleRegistry.registered_objects_list == [ + ExampleA, + ExampleB, + ExampleAA, + ] + + assert ExampleRegistry.get_object_by_name("ExampleA") == ExampleA + assert ExampleRegistry.get_object_by_name("ExampleB") == ExampleB + assert ExampleRegistry.get_object_by_name("example_aa") == ExampleAA diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py index a79562f9b19a311abc6eac48760b18169885d1b6..339a4bc2fee1c0546e62ca452793dfc7682e3aea 100644 --- a/aleksis/core/urls.py +++ b/aleksis/core/urls.py @@ -42,6 +42,21 @@ urlpatterns = [ ), path("oauth/", include("oauth2_provider.urls", namespace="oauth2_provider")), path("system_status/", views.SystemStatusAPIView.as_view(), name="system_status_api"), + path( + "o/<str:app_label>/<str:model>/<int:pk>/", + views.ObjectRepresentationView.as_view(), + name="object_representation_with_pk", + ), + path( + "o/<str:app_label>/<str:model>/", + views.ObjectRepresentationView.as_view(), + name="object_representation_with_model", + ), + path( + "o/", + views.ObjectRepresentationView.as_view(), + name="object_representation_anonymous", + ), path("", include("django_prometheus.urls")), path( "django/", @@ -386,6 +401,8 @@ urlpatterns = [ views.AssignPermissionView.as_view(), name="assign_permission", ), + path("feeds/<str:name>.ics", views.ICalFeedView.as_view(), name="calendar_feed"), + path("feeds.ics", views.ICalAllFeedsView.as_view(), name="all_calendar_feeds"), ] ), ), diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py index c7f89fb5badfbca1e5014b78a150129afd990669..9329dda6192b554efa5e546a0160b5225e09da17 100644 --- a/aleksis/core/util/core_helpers.py +++ b/aleksis/core/util/core_helpers.py @@ -1,3 +1,4 @@ +import json import os from datetime import datetime, timedelta from importlib import import_module, metadata @@ -19,9 +20,12 @@ from django.utils.crypto import get_random_string from django.utils.functional import lazy from django.utils.module_loading import import_string +import django_ical.feedgenerator as feedgenerator +import recurring_ical_events from cachalot.api import invalidate from cachalot.signals import post_invalidation from cache_memoize import cache_memoize +from icalendar import Calendar, Event, Todo def copyright_years(years: Sequence[int], separator: str = ", ", joiner: str = "–") -> str: @@ -489,3 +493,69 @@ def get_ip(*args, **kwargs): from ipware.ip import get_client_ip # noqa return get_client_ip(*args, **kwargs)[0] + + +feedgenerator.FEED_FIELD_MAP = feedgenerator.FEED_FIELD_MAP + (("color", "color"),) +feedgenerator.ITEM_ELEMENT_FIELD_MAP = feedgenerator.ITEM_ELEMENT_FIELD_MAP + ( + ("color", "color"), + ("meta", "x-meta"), +) + + +class ExtendedICal20Feed(feedgenerator.ICal20Feed): + """Extends the ICal20Feed class from django-ical. + + Adds a method to return the actual calendar object. + """ + + def get_calendar_object(self, with_meta=True): + cal = Calendar() + cal.add("version", "2.0") + cal.add("calscale", "GREGORIAN") + + for ifield, efield in feedgenerator.FEED_FIELD_MAP: + val = self.feed.get(ifield) + if val is not None: + cal.add(efield, val) + + self.write_items(cal, with_meta=with_meta) + + return cal + + def write(self, outfile, encoding): + cal = self.get_calendar_object(with_meta=False) + + to_ical = getattr(cal, "as_string", None) + if not to_ical: + to_ical = cal.to_ical + outfile.write(to_ical()) + + def write_items(self, calendar, with_meta=True): + for item in self.items: + component_type = item.get("component_type") + if component_type == "todo": + element = Todo() + else: + element = Event() + for ifield, efield in feedgenerator.ITEM_ELEMENT_FIELD_MAP: + val = item.get(ifield) + if val is not None: + if ifield == "attendee": + for list_item in val: + element.add(efield, list_item) + elif ifield == "valarm": + for list_item in val: + element.add_component(list_item) + elif ifield == "meta": + if with_meta: + element.add(efield, json.dumps(val)) + else: + element.add(efield, val) + calendar.add_component(element) + + def get_single_events(self, start=None, end=None): + """Get single event objects for this feed.""" + events = recurring_ical_events.of(self.get_calendar_object()) + if start and end: + return events.between(start, end) + return events.all() diff --git a/aleksis/core/views.py b/aleksis/core/views.py index 442a3d4d9e86f1ecba128e87f556f959dbfe06fb..f9e21e5b57472664e96bded0ebb471a11aff014b 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -96,7 +96,14 @@ from .forms import ( SelectPermissionForm, SitePreferenceForm, ) -from .mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView, SuccessNextMixin +from .mixins import ( + AdvancedCreateView, + AdvancedDeleteView, + AdvancedEditView, + CalendarEventMixin, + ObjectAuthenticator, + SuccessNextMixin, +) from .models import ( AdditionalField, Announcement, @@ -1548,3 +1555,103 @@ class LoggingGraphQLView(GraphQLView): if not isinstance(error.original_error, GraphQLError): raise error return result + + +class ObjectRepresentationView(View): + """View with unique URL to get a JSON representation of an object.""" + + def get_model(self, request: HttpRequest, app_label: str, model: str): + """Get the model by app label and model name.""" + try: + return apps.get_model(app_label, model) + except LookupError: + raise Http404() + + def get_object(self, request: HttpRequest, app_label: str, model: str, pk: int): + """Get the object by app label, model name and primary key.""" + if getattr(self, "model", None) is None: + self.model = self.get_model(request, app_label, model) + + try: + return self.model.objects.get(pk=pk) + except self.model.DoesNotExist: + raise Http404() + + def get( + self, + request: HttpRequest, + app_label: Optional[str] = None, + model: Optional[str] = None, + pk: Optional[int] = None, + *args, + **kwargs, + ) -> HttpResponse: + if app_label and model: + self.model = self.get_model(request, app_label, model) + else: + self.model = None + + if app_label and model and pk: + self.object = self.get_object(request, app_label, model, pk) + else: + self.object = None + + authenticators = request.GET.get("authenticators", "").split(",") + if authenticators == [""]: + authenticators = list(ObjectAuthenticator.registered_objects_dict.keys()) + self.authenticate(request, authenticators) + + if hasattr(self.object, "get_json"): + res = self.object.get_json(request) + else: + res = {"id": self.object.id} + res["_meta"] = { + "model": self.object._meta.model_name, + "app": self.object._meta.app_label, + } + + return JsonResponse(res) + + def authenticate(self, request: HttpRequest, authenticators: list[str]) -> bool: + """Authenticate the request against the given authenticators.""" + for authenticator in authenticators: + authenticator_class = ObjectAuthenticator.get_object_by_name(authenticator) + if not authenticator_class: + continue + obj = authenticator_class().authenticate(request, self.object) + if obj: + if self.object is None: + self.object = obj + elif obj != self.object: + raise BadRequest("Ambiguous objects identified") + return True + + raise PermissionDenied() + + +class ICalFeedView(PermissionRequiredMixin, View): + """View to generate an iCal feed for a calendar.""" + + permission_required = "core.view_calendar_feed_rule" + + def get(self, request, name, *args, **kwargs): + if name in CalendarEventMixin.registered_objects_dict: + calendar = CalendarEventMixin.registered_objects_dict[name] + feed = calendar.create_feed(request) + response = HttpResponse(content_type="text/calendar") + feed.write(response, "utf-8") + return response + raise Http404 + + +class ICalAllFeedsView(PermissionRequiredMixin, View): + """View to generate an iCal feed for all calendars.""" + + permission_required = "core.view_calendar_feed_rule" + + def get(self, request, *args, **kwargs): + response = HttpResponse(content_type="text/calendar") + for calendar in CalendarEventMixin.valid_feeds: + feed = calendar.create_feed(request) + feed.write(response, "utf-8") + return response diff --git a/aleksis/core/vite.config.js b/aleksis/core/vite.config.js index 415d12aa00f6b8a2bf2747e47d5cc3e32fd7aaa3..772fa5f27eccf8f93f1051cd51f8aaeb6e60535c 100644 --- a/aleksis/core/vite.config.js +++ b/aleksis/core/vite.config.js @@ -60,6 +60,28 @@ function generateMessageImportCode(assetDir, name, importAppName) { return code; } +/** + * Generate code to import all components from a specified directory of a single AlekSIS app. + */ +function generateComponentsImportCode( + assetDir, + componentsDir, + name, + exportName +) { + let code = ""; + let componentsPath = assetDir + "/components" + componentsDir; + if (fs.existsSync(componentsPath)) { + const files = fs.readdirSync(componentsPath); + for (file of files) { + let componentName = file.split(".")[0]; + code += `import ${componentName} from '${componentsPath + file}';\n`; + code += `${exportName}["${componentName.toLowerCase()}"] = ${componentName};\n`; + } + } + return code; +} + /** * Generate a virtual module that helps the AlekSIS-Core frontend code import other apps. * @@ -69,6 +91,8 @@ function generateMessageImportCode(assetDir, name, importAppName) { function generateAppImporter(appDetails) { let code = "let appObjects = {};\n"; code += "let appMessages = {};\n"; + code += "let calendarFeedDetailComponents = {};\n"; + code += "let calendarFeedEventBarComponents = {};\n"; for (const [appPackage, appMeta] of Object.entries(appDetails)) { let indexPath = appMeta.assetDir + "/index.js"; @@ -86,13 +110,46 @@ function generateAppImporter(appDetails) { importAppName ); } + + // Include calendar feed detail components from all apps + code += generateComponentsImportCode( + appMeta.assetDir, + "/calendar_feeds/details/", + appMeta.name, + "calendarFeedDetailComponents" + ); + + // Include calendar feed event bar components from all apps + code += generateComponentsImportCode( + appMeta.assetDir, + "/calendar_feeds/event_bar/", + appMeta.name, + "calendarFeedEventBarComponents" + ); } // Include core messages code += generateMessageImportCode(django_values.coreAssetDir, "core", "Core"); + // Include core calendar feed detail components + code += generateComponentsImportCode( + django_values.coreAssetDir, + "/calendar_feeds/details/", + "core", + "calendarFeedDetailComponents" + ); + + // Include core calendar feed event bar components + code += generateComponentsImportCode( + django_values.coreAssetDir, + "/calendar_feeds/event_bar/", + "core", + "calendarFeedEventBarComponents" + ); + code += "export default appObjects;\n"; - code += "export { appObjects, appMessages };\n"; + code += + "export { appObjects, appMessages, calendarFeedDetailComponents, calendarFeedEventBarComponents };\n"; return code; } @@ -202,7 +259,7 @@ export default defineConfig({ directoryIndex: null, navigateFallbackAllowlist: [ new RegExp( - "^/(?!(django|admin|graphql|__icons__|oauth/authorize))[^.]*$" + "^/(?!(django|admin|graphql|__icons__|oauth/authorize|o))[^.]*$" ), ], additionalManifestEntries: [ @@ -217,7 +274,7 @@ export default defineConfig({ runtimeCaching: [ { urlPattern: new RegExp( - "^/(?!(django|admin|graphql|__icons__|oauth/authorize))[^.]*$" + "^/(?!(django|admin|graphql|__icons__|oauth/authorize|o))[^.]*$" ), handler: "CacheFirst", }, diff --git a/docs/admin/10_install.rst b/docs/admin/10_install.rst index b829cd2c92710efa6050f068319ef052e9b4138e..98597a251ef3f8fb05c5130687df1f447a59c1d3 100644 --- a/docs/admin/10_install.rst +++ b/docs/admin/10_install.rst @@ -57,6 +57,7 @@ Install some packages from the Debian package system. chromium \ chromium-driver \ redis-server \ + pkg-config \ postgresql \ locales-all \ celery diff --git a/pyproject.toml b/pyproject.toml index 2a38377509bcb52ce50fc57917a19d209d863618..73fd5c29b41fcb4d64940a4c4f43a296e807e4e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,11 +124,15 @@ django-cte = "^1.1.5" pycountry = "^22.0.0" django-iconify = "^0.3" customidenticon = "^0.1.5" -graphene-django = ">=3.0.0, <=3.1.2" +graphene-django = ">=3.0.0, <=3.1.3" selenium = "^4.4.3" django-vite = "^2.0.2" -graphene-django-cud = "^0.10.0" +graphene-django-cud = "^0.11.0" uwsgi = "^2.0.21" +django-ical = "^1.9.2" +django-recurrence = "^1.11.1" +recurring-ical-events = "^2.0.2" +django-timezone-field = "^5.0" [tool.poetry.extras] ldap = ["django-auth-ldap"]