diff --git a/.dev-js/.eslintrc.js b/.dev-js/.eslintrc.js new file mode 100644 index 0000000000000000000000000000000000000000..40571d02f4c429d79d9ec85a4f37ba8c78f74b4c --- /dev/null +++ b/.dev-js/.eslintrc.js @@ -0,0 +1,252 @@ +module.exports = { + root: true, + overrides: [ + { + files: ["*.js", "*.vue"], + // parser: "vue-eslint-parser", + //processor: "@graphql-eslint/graphql", + extends: [ + "eslint:recommended", + "plugin:vue/strongly-recommended", + "plugin:@intlify/vue-i18n/recommended", + ], + rules: { + "no-unused-vars": "warn", + "vue/no-unused-vars": "off", + "vue/multi-word-component-names": "off", + "vue/attribute-hyphenation": "error", + "vue/v-slot-style": "error", + "@intlify/vue-i18n/key-format-style": [ + "error", + "snake_case", + { + splitByDots: false, + }, + ], + // "@intlify/vue-i18n/no-unused-keys": ["warn", {}], + "@intlify/vue-i18n/no-raw-text": [ + "error", + { + ignoreNodes: ["v-icon"], + ignorePattern: "^[-–—·#:()\\[\\]&\\.\\s]+$", + }, + ], + "@intlify/vue-i18n/no-deprecated-tc": "off", + // Fixes for prettier (avoid eslint-config-prettier) + // The following rules can be used in some cases. See the README for more + // information. (These are marked with `0` instead of `"off"` so that a + // script can distinguish them.) + curly: 0, + "lines-around-comment": 0, + "max-len": 0, + "no-confusing-arrow": 0, + "no-mixed-operators": 0, + "no-tabs": 0, + "no-unexpected-multiline": 0, + quotes: 0, + "@typescript-eslint/quotes": 0, + "babel/quotes": 0, + "vue/html-self-closing": 0, + "vue/max-len": 0, + + // The rest are rules that you never need to enable when using Prettier. + "array-bracket-newline": "off", + "array-bracket-spacing": "off", + "array-element-newline": "off", + "arrow-parens": "off", + "arrow-spacing": "off", + "block-spacing": "off", + "brace-style": "off", + "comma-dangle": "off", + "comma-spacing": "off", + "comma-style": "off", + "computed-property-spacing": "off", + "dot-location": "off", + "eol-last": "off", + "func-call-spacing": "off", + "function-call-argument-newline": "off", + "function-paren-newline": "off", + "generator-star": "off", + "generator-star-spacing": "off", + "implicit-arrow-linebreak": "off", + indent: "off", + "jsx-quotes": "off", + "key-spacing": "off", + "keyword-spacing": "off", + "linebreak-style": "off", + "multiline-ternary": "off", + "newline-per-chained-call": "off", + "new-parens": "off", + "no-arrow-condition": "off", + "no-comma-dangle": "off", + "no-extra-parens": "off", + "no-extra-semi": "off", + "no-floating-decimal": "off", + "no-mixed-spaces-and-tabs": "off", + "no-multi-spaces": "off", + "no-multiple-empty-lines": "off", + "no-reserved-keys": "off", + "no-space-before-semi": "off", + "no-trailing-spaces": "off", + "no-whitespace-before-property": "off", + "no-wrap-func": "off", + "nonblock-statement-body-position": "off", + "object-curly-newline": "off", + "object-curly-spacing": "off", + "object-property-newline": "off", + "one-var-declaration-per-line": "off", + "operator-linebreak": "off", + "padded-blocks": "off", + "quote-props": "off", + "rest-spread-spacing": "off", + semi: "off", + "semi-spacing": "off", + "semi-style": "off", + "space-after-function-name": "off", + "space-after-keywords": "off", + "space-before-blocks": "off", + "space-before-function-paren": "off", + "space-before-function-parentheses": "off", + "space-before-keywords": "off", + "space-in-brackets": "off", + "space-in-parens": "off", + "space-infix-ops": "off", + "space-return-throw-case": "off", + "space-unary-ops": "off", + "space-unary-word-ops": "off", + "switch-colon-spacing": "off", + "template-curly-spacing": "off", + "template-tag-spacing": "off", + "unicode-bom": "off", + "wrap-iife": "off", + "wrap-regex": "off", + "yield-star-spacing": "off", + "@babel/object-curly-spacing": "off", + "@babel/semi": "off", + "@typescript-eslint/brace-style": "off", + "@typescript-eslint/comma-dangle": "off", + "@typescript-eslint/comma-spacing": "off", + "@typescript-eslint/func-call-spacing": "off", + "@typescript-eslint/indent": "off", + "@typescript-eslint/keyword-spacing": "off", + "@typescript-eslint/member-delimiter-style": "off", + "@typescript-eslint/no-extra-parens": "off", + "@typescript-eslint/no-extra-semi": "off", + "@typescript-eslint/object-curly-spacing": "off", + "@typescript-eslint/semi": "off", + "@typescript-eslint/space-before-blocks": "off", + "@typescript-eslint/space-before-function-paren": "off", + "@typescript-eslint/space-infix-ops": "off", + "@typescript-eslint/type-annotation-spacing": "off", + "babel/object-curly-spacing": "off", + "babel/semi": "off", + "flowtype/boolean-style": "off", + "flowtype/delimiter-dangle": "off", + "flowtype/generic-spacing": "off", + "flowtype/object-type-curly-spacing": "off", + "flowtype/object-type-delimiter": "off", + "flowtype/quotes": "off", + "flowtype/semi": "off", + "flowtype/space-after-type-colon": "off", + "flowtype/space-before-generic-bracket": "off", + "flowtype/space-before-type-colon": "off", + "flowtype/union-intersection-spacing": "off", + "react/jsx-child-element-spacing": "off", + "react/jsx-closing-bracket-location": "off", + "react/jsx-closing-tag-location": "off", + "react/jsx-curly-newline": "off", + "react/jsx-curly-spacing": "off", + "react/jsx-equals-spacing": "off", + "react/jsx-first-prop-new-line": "off", + "react/jsx-indent": "off", + "react/jsx-indent-props": "off", + "react/jsx-max-props-per-line": "off", + "react/jsx-newline": "off", + "react/jsx-one-expression-per-line": "off", + "react/jsx-props-no-multi-spaces": "off", + "react/jsx-tag-spacing": "off", + "react/jsx-wrap-multilines": "off", + "standard/array-bracket-even-spacing": "off", + "standard/computed-property-even-spacing": "off", + "standard/object-curly-even-spacing": "off", + "unicorn/empty-brace-spaces": "off", + "unicorn/no-nested-ternary": "off", + "unicorn/number-literal-case": "off", + "vue/array-bracket-newline": "off", + "vue/array-bracket-spacing": "off", + "vue/arrow-spacing": "off", + "vue/block-spacing": "off", + "vue/block-tag-newline": "off", + "vue/brace-style": "off", + "vue/comma-dangle": "off", + "vue/comma-spacing": "off", + "vue/comma-style": "off", + "vue/dot-location": "off", + "vue/func-call-spacing": "off", + "vue/html-closing-bracket-newline": "off", + "vue/html-closing-bracket-spacing": "off", + "vue/html-end-tags": "off", + "vue/html-indent": "off", + "vue/html-quotes": "off", + "vue/key-spacing": "off", + "vue/keyword-spacing": "off", + "vue/max-attributes-per-line": "off", + "vue/multiline-html-element-content-newline": "off", + "vue/multiline-ternary": "off", + "vue/mustache-interpolation-spacing": "off", + "vue/no-extra-parens": "off", + "vue/no-multi-spaces": "off", + "vue/no-spaces-around-equal-signs-in-attribute": "off", + "vue/object-curly-newline": "off", + "vue/object-curly-spacing": "off", + "vue/object-property-newline": "off", + "vue/operator-linebreak": "off", + "vue/quote-props": "off", + "vue/script-indent": "off", + "vue/singleline-html-element-content-newline": "off", + "vue/space-in-parens": "off", + "vue/space-infix-ops": "off", + "vue/space-unary-ops": "off", + "vue/template-curly-spacing": "off", + }, + settings: { + "vue-i18n": { + localeDir: "./aleksis/core/frontend/messages/*.{json}", + messageSyntaxVersion: "^8.0.0", + }, + }, + env: { + es2021: true, + }, + parserOptions: { + ecmaVersion: "latest", + }, + }, + { + files: ["*.graphql"], + parser: "@graphql-eslint/eslint-plugin", + plugins: ["@graphql-eslint"], + extends: "plugin:@graphql-eslint/operations-recommended", + parserOptions: { + graphQLConfig: { + schema: "./schema.json", + documents: "../aleksis/**/*/frontend/**/*.graphql", + }, + }, + rules: { + "@graphql-eslint/no-anonymous-operations": "error", + "@graphql-eslint/no-duplicate-fields": "error", + "@graphql-eslint/naming-convention": [ + "error", + { + OperationDefinition: { + style: "camelCase", + forbiddenPrefixes: ["Query", "Mutation", "Subscription", "Get"], + forbiddenSuffixes: ["Query", "Mutation", "Subscription"], + }, + }, + ], + }, + }, + ], +}; diff --git a/.dev-js/package.json b/.dev-js/package.json index 5c1f550ce1732d21180fa22481010331304be36e..298e6c130173b7870174169d5968bf58e2a41050 100644 --- a/.dev-js/package.json +++ b/.dev-js/package.json @@ -2,11 +2,13 @@ "name": "aleksis-builddeps", "version": "1.0.0", "dependencies": { + "@graphql-eslint/eslint-plugin": "^4.3.0", "@intlify/eslint-plugin-vue-i18n": "^3.0.0", "eslint": "^8.26.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-vue": "^9.7.0", - "prettier": "^3.0.0", + "graphql": "^16.10.0", + "prettier": "^3.4.0", "stylelint": "^16.0.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-standard": "^34.0.0" diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 60317f4987d885fc380d731c6dd8792325342f44..0000000000000000000000000000000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,215 +0,0 @@ -module.exports = { - extends: [ - "eslint:recommended", - "plugin:vue/strongly-recommended", - "plugin:@intlify/vue-i18n/recommended", - ], - rules: { - "no-unused-vars": "warn", - "vue/no-unused-vars": "off", - "vue/multi-word-component-names": "off", - "@intlify/vue-i18n/key-format-style": [ - "error", - "snake_case", - { - splitByDots: false, - }, - ], - // "@intlify/vue-i18n/no-unused-keys": ["warn", {}], - "@intlify/vue-i18n/no-raw-text": [ - "error", - { - ignoreNodes: ["v-icon"], - ignorePattern: "^[-–—·#:()\\[\\]&\\.\\s]+$", - }, - ], - // Fixes for prettier (avoid eslint-config-prettier) - // The following rules can be used in some cases. See the README for more - // information. (These are marked with `0` instead of `"off"` so that a - // script can distinguish them.) - curly: 0, - "lines-around-comment": 0, - "max-len": 0, - "no-confusing-arrow": 0, - "no-mixed-operators": 0, - "no-tabs": 0, - "no-unexpected-multiline": 0, - quotes: 0, - "@typescript-eslint/quotes": 0, - "babel/quotes": 0, - "vue/html-self-closing": 0, - "vue/max-len": 0, - - // The rest are rules that you never need to enable when using Prettier. - "array-bracket-newline": "off", - "array-bracket-spacing": "off", - "array-element-newline": "off", - "arrow-parens": "off", - "arrow-spacing": "off", - "block-spacing": "off", - "brace-style": "off", - "comma-dangle": "off", - "comma-spacing": "off", - "comma-style": "off", - "computed-property-spacing": "off", - "dot-location": "off", - "eol-last": "off", - "func-call-spacing": "off", - "function-call-argument-newline": "off", - "function-paren-newline": "off", - "generator-star": "off", - "generator-star-spacing": "off", - "implicit-arrow-linebreak": "off", - indent: "off", - "jsx-quotes": "off", - "key-spacing": "off", - "keyword-spacing": "off", - "linebreak-style": "off", - "multiline-ternary": "off", - "newline-per-chained-call": "off", - "new-parens": "off", - "no-arrow-condition": "off", - "no-comma-dangle": "off", - "no-extra-parens": "off", - "no-extra-semi": "off", - "no-floating-decimal": "off", - "no-mixed-spaces-and-tabs": "off", - "no-multi-spaces": "off", - "no-multiple-empty-lines": "off", - "no-reserved-keys": "off", - "no-space-before-semi": "off", - "no-trailing-spaces": "off", - "no-whitespace-before-property": "off", - "no-wrap-func": "off", - "nonblock-statement-body-position": "off", - "object-curly-newline": "off", - "object-curly-spacing": "off", - "object-property-newline": "off", - "one-var-declaration-per-line": "off", - "operator-linebreak": "off", - "padded-blocks": "off", - "quote-props": "off", - "rest-spread-spacing": "off", - semi: "off", - "semi-spacing": "off", - "semi-style": "off", - "space-after-function-name": "off", - "space-after-keywords": "off", - "space-before-blocks": "off", - "space-before-function-paren": "off", - "space-before-function-parentheses": "off", - "space-before-keywords": "off", - "space-in-brackets": "off", - "space-in-parens": "off", - "space-infix-ops": "off", - "space-return-throw-case": "off", - "space-unary-ops": "off", - "space-unary-word-ops": "off", - "switch-colon-spacing": "off", - "template-curly-spacing": "off", - "template-tag-spacing": "off", - "unicode-bom": "off", - "wrap-iife": "off", - "wrap-regex": "off", - "yield-star-spacing": "off", - "@babel/object-curly-spacing": "off", - "@babel/semi": "off", - "@typescript-eslint/brace-style": "off", - "@typescript-eslint/comma-dangle": "off", - "@typescript-eslint/comma-spacing": "off", - "@typescript-eslint/func-call-spacing": "off", - "@typescript-eslint/indent": "off", - "@typescript-eslint/keyword-spacing": "off", - "@typescript-eslint/member-delimiter-style": "off", - "@typescript-eslint/no-extra-parens": "off", - "@typescript-eslint/no-extra-semi": "off", - "@typescript-eslint/object-curly-spacing": "off", - "@typescript-eslint/semi": "off", - "@typescript-eslint/space-before-blocks": "off", - "@typescript-eslint/space-before-function-paren": "off", - "@typescript-eslint/space-infix-ops": "off", - "@typescript-eslint/type-annotation-spacing": "off", - "babel/object-curly-spacing": "off", - "babel/semi": "off", - "flowtype/boolean-style": "off", - "flowtype/delimiter-dangle": "off", - "flowtype/generic-spacing": "off", - "flowtype/object-type-curly-spacing": "off", - "flowtype/object-type-delimiter": "off", - "flowtype/quotes": "off", - "flowtype/semi": "off", - "flowtype/space-after-type-colon": "off", - "flowtype/space-before-generic-bracket": "off", - "flowtype/space-before-type-colon": "off", - "flowtype/union-intersection-spacing": "off", - "react/jsx-child-element-spacing": "off", - "react/jsx-closing-bracket-location": "off", - "react/jsx-closing-tag-location": "off", - "react/jsx-curly-newline": "off", - "react/jsx-curly-spacing": "off", - "react/jsx-equals-spacing": "off", - "react/jsx-first-prop-new-line": "off", - "react/jsx-indent": "off", - "react/jsx-indent-props": "off", - "react/jsx-max-props-per-line": "off", - "react/jsx-newline": "off", - "react/jsx-one-expression-per-line": "off", - "react/jsx-props-no-multi-spaces": "off", - "react/jsx-tag-spacing": "off", - "react/jsx-wrap-multilines": "off", - "standard/array-bracket-even-spacing": "off", - "standard/computed-property-even-spacing": "off", - "standard/object-curly-even-spacing": "off", - "unicorn/empty-brace-spaces": "off", - "unicorn/no-nested-ternary": "off", - "unicorn/number-literal-case": "off", - "vue/array-bracket-newline": "off", - "vue/array-bracket-spacing": "off", - "vue/arrow-spacing": "off", - "vue/block-spacing": "off", - "vue/block-tag-newline": "off", - "vue/brace-style": "off", - "vue/comma-dangle": "off", - "vue/comma-spacing": "off", - "vue/comma-style": "off", - "vue/dot-location": "off", - "vue/func-call-spacing": "off", - "vue/html-closing-bracket-newline": "off", - "vue/html-closing-bracket-spacing": "off", - "vue/html-end-tags": "off", - "vue/html-indent": "off", - "vue/html-quotes": "off", - "vue/key-spacing": "off", - "vue/keyword-spacing": "off", - "vue/max-attributes-per-line": "off", - "vue/multiline-html-element-content-newline": "off", - "vue/multiline-ternary": "off", - "vue/mustache-interpolation-spacing": "off", - "vue/no-extra-parens": "off", - "vue/no-multi-spaces": "off", - "vue/no-spaces-around-equal-signs-in-attribute": "off", - "vue/object-curly-newline": "off", - "vue/object-curly-spacing": "off", - "vue/object-property-newline": "off", - "vue/operator-linebreak": "off", - "vue/quote-props": "off", - "vue/script-indent": "off", - "vue/singleline-html-element-content-newline": "off", - "vue/space-in-parens": "off", - "vue/space-infix-ops": "off", - "vue/space-unary-ops": "off", - "vue/template-curly-spacing": "off", - }, - settings: { - "vue-i18n": { - localeDir: "./aleksis/core/frontend/messages/*.{json}", - messageSyntaxVersion: "^8.0.0", - }, - }, - env: { - es2021: true, - }, - parserOptions: { - ecmaVersion: "latest", - }, -}; diff --git a/.gitignore b/.gitignore index fc620d9045075bdec195fc0bd15702daa2b3e408..613db10966de0e5b57a87f57c6fd586925ade0b7 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,8 @@ docs/_build/ .dev-js/.yarn .dev-js/.pnp.cjs .dev-js/.pnp.loader.mjs +.dev-js/.yarnrc.yml +.dev-js/schema.json # Lock files poetry.lock diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4278359d4b0bcb41001dc4ff155816db45beb0eb..aacf652dcdd8f9eeed1b7c5b9624548d6a84a5a4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,7 +23,7 @@ and need a replacement, please contact the development team. The special assignment page for groups and child groups has been removed. For the calendar system, AlekSIS now needs an extension for the PostgreSQL database. -Please check the docs for instructions how to setup the ``pg_rrule`` extension +Please check the docs for instructions how to setup the ``pg_rrule`` extension for PostgreSQL. AlekSIS now uses Valkey as a drop-in replacement for Redis. Please update your configuration @@ -61,6 +61,7 @@ Added * Make configurable which weekdays appear in the calendar * Introduce .well-known urlpatterns for apps * Global school term select for limiting data to a specific school term. +* [Dev] Notifications based on calendar alarms. Changed ~~~~~~~ @@ -74,7 +75,8 @@ Changed * Move "Invite person" to persons page * Replace all mentions of Redis with Valkey where possible * Show avatars of groups in all places. -* Use new auth rate limiting settings +* Use new auth rate limiting settings +* Bump Python version to 3.10 Fixed ~~~~~ @@ -91,6 +93,10 @@ Fixed * [Dev] Integrate model validation mechanisms into GraphQL queries. * [Container] Database backup failed with postgres versions 15 and 16. * Setting images for groups did not work +* Update and fix URLs for 3rdparty login. +* The OpenID Connect Discovery endpoint now returns the issuer data directly + under the URI without a trailing `/`. +* Not-logged in users were able to access all PDF files. Removed ~~~~~~~ @@ -101,7 +107,15 @@ Removed * [Dev] Extended fields mechanism on top of django-jsonstore. * Additional fields. * Legacy pages are no longer themed. +* Batching of GraphQL queries. +`3.2.2`_ - 2025-01-18 +--------------------- + +Fixed +~~~~~ + +* Not-logged in users were able to access all PDF files. `3.2.1`_ - 2024-06-27 --------------------- @@ -151,6 +165,14 @@ This release deprecates some features in preparation for the 4.0 release. need to account for recursion themselves. * [Dev] Extended fields mechanism on top of django-jsonstore. +`3.1.7`_ - 2025-01-18 +--------------------- + +Fixed +~~~~~ + +* Not-logged in users were able to access all PDF files. + `3.1.6`_ - 2024-06-27 --------------------- @@ -1391,5 +1413,7 @@ Fixed .. _3.1.4: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.1.4 .. _3.1.5: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.1.5 .. _3.1.6: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.1.6 +.. _3.1.7: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.1.7 .. _3.2.0: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.0 .. _3.2.1: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.1 +.. _3.2.2: https://edugit.org/AlekSIS/official/AlekSIS-Core/-/tags/3.2.2 diff --git a/Dockerfile b/Dockerfile index 44cb3eec27c4eadc5de78328be22926011a875f1..38dec3ced173a8329f8e7e57e25d34351021f844 100644 --- a/Dockerfile +++ b/Dockerfile @@ -73,7 +73,6 @@ RUN set -e; \ # Define entrypoint, volumes and uWSGI running on port 8000 EXPOSE 8000 -VOLUME ${ALEKSIS_media__root} ${ALEKSIS_backup__location} COPY docker-startup.sh /usr/local/bin/aleksis-docker-startup ENTRYPOINT ["/usr/bin/dumb-init", "--"] CMD ["/usr/local/bin/aleksis-docker-startup"] @@ -111,6 +110,7 @@ RUN chown -R www-data:www-data \ ${ALEKSIS_media__root} \ ${ALEKSIS_backup__location} USER 33:33 +VOLUME ${ALEKSIS_media__root} ${ALEKSIS_backup__location} # Additional steps ONBUILD ARG APPS diff --git a/aleksis/core/filters.py b/aleksis/core/filters.py index c8699dab872827a863a0e6c26502117b75ac8285..1009d15f7d3746efa0008fd9833a1b077293e93c 100644 --- a/aleksis/core/filters.py +++ b/aleksis/core/filters.py @@ -1,4 +1,4 @@ -from typing import Sequence +from collections.abc import Sequence from django.contrib.auth.models import Group as DjangoGroup from django.contrib.auth.models import Permission, User diff --git a/aleksis/core/forms.py b/aleksis/core/forms.py index 3e046dd44011297cbca740ed28e1b161b686f068..914f130492bbd79827f67abeb9599569dab0fc81 100644 --- a/aleksis/core/forms.py +++ b/aleksis/core/forms.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from datetime import datetime, time -from typing import Any, Callable, Dict, Sequence +from typing import Any, Callable from django import forms from django.conf import settings @@ -462,7 +463,7 @@ class AssignPermissionForm(forms.Form): required=False, label=_("Grant the permission for all objects") ) - def clean(self) -> Dict[str, Any]: + def clean(self) -> dict[str, Any]: """Clean form to ensure that at least one target and one type is selected.""" cleaned_data = super().clean() if not cleaned_data.get("persons") and not cleaned_data.get("groups"): diff --git a/aleksis/core/frontend/app/apollo.js b/aleksis/core/frontend/app/apollo.js index 7ebde2fe407008137ae6248261db9d2f36e0cf59..4652c386e9b02f6cc2d8a9f27a6b78f3b8a41f48 100644 --- a/aleksis/core/frontend/app/apollo.js +++ b/aleksis/core/frontend/app/apollo.js @@ -2,12 +2,10 @@ * Configuration for Apollo provider, client, and caches. */ -import { ApolloClient, from } from "@/apollo-boost"; +import { ApolloClient, from, HttpLink } from "@/apollo-boost"; -import { RetryLink } from "@/apollo-link-retry"; import { persistCache, LocalStorageWrapper } from "@/apollo3-cache-persist"; import { InMemoryCache } from "@/apollo-cache-inmemory"; -import { BatchHttpLink } from "@/apollo-link-batch-http"; import errorCodes from "../errorCodes"; @@ -33,20 +31,15 @@ function getGraphqlURL() { // Define Apollo links for handling query operations. const links = [ - // Automatically retry failed queries - // new RetryLink(), - // Finally, the HTTP link to the real backend (Django) - new BatchHttpLink({ + // HTTP link to the real backend (Django) + new HttpLink({ uri: getGraphqlURL(), - batchInterval: 200, - batchDebounce: true, }), ]; /** Upstream Apollo GraphQL client */ const apolloClient = new ApolloClient({ cache, - shouldBatch: true, link: from(links), }); diff --git a/aleksis/core/frontend/app/vuetify.js b/aleksis/core/frontend/app/vuetify.js index 4cccdd2978ed417ea1dd62f1da9ee3770013b733..1511760ae0011e4332e1f1ba00c4f874d2a51107 100644 --- a/aleksis/core/frontend/app/vuetify.js +++ b/aleksis/core/frontend/app/vuetify.js @@ -33,6 +33,7 @@ const vuetifyOpts = { groupType: "mdi-shape-outline", print: "mdi-printer-outline", schoolTerm: "mdi-calendar-range-outline", + updatePwa: "mdi-update", }, }, }; diff --git a/aleksis/core/frontend/components/about/installedApps.graphql b/aleksis/core/frontend/components/about/installedApps.graphql index 01ceaf99eb8d79d44ee7014d9f582d7dfeb54ace..be2a7d1995f8107a3588f62d9d08c3e35c5aeec6 100644 --- a/aleksis/core/frontend/components/about/installedApps.graphql +++ b/aleksis/core/frontend/components/about/installedApps.graphql @@ -1,4 +1,4 @@ -{ +query installedApps { installedApps { name verboseName diff --git a/aleksis/core/frontend/components/app/App.vue b/aleksis/core/frontend/components/app/App.vue index d522d33fc65106b853a07e4e8285b632858fc84c..d48aff1a9c50adf60e531bb4f8f30c1ceeedff9b 100644 --- a/aleksis/core/frontend/components/app/App.vue +++ b/aleksis/core/frontend/components/app/App.vue @@ -192,8 +192,7 @@ class="white--text text-decoration-none" >{{ $t("base.about_aleksis") }} </router-link> - <!-- eslint-disable-next-line --> - <span>© The AlekSIS Team</span> + <span>{{ $t("base.about_copyright") }}</span> </div> </v-col> <v-col class="d-flex justify-end"> @@ -227,18 +226,30 @@ :key="item.id" :snackbar-item="item" /> - <v-snackbar v-model="needRefresh" v-if="!refreshDismissed" timeout="-1"> - {{ $t("service_worker.new_version_available") }} + <v-dialog :value="needRefresh" persistent max-width="400px"> + <v-card> + <v-card-title> + {{ $t("service_worker.new_version_available.header") }} + </v-card-title> - <template #action="{ attrs }"> - <v-btn color="primary" text @click="updateServiceWorker()"> - {{ $t("service_worker.update") }} - </v-btn> - <v-btn color="primary" text @click="refreshDismissed = true"> - {{ $t("service_worker.dismiss") }} - </v-btn> - </template> - </v-snackbar> + <v-card-text> + {{ + $t("service_worker.new_version_available.body", { + instance: $getBaseTitle(), + }) + }} + </v-card-text> + + <v-card-actions> + <v-spacer /> + + <v-btn color="primary" text @click="updateServiceWorker()"> + <v-icon left>$updatePwa</v-icon> + {{ $t("service_worker.update") }} + </v-btn> + </v-card-actions> + </v-card> + </v-dialog> </v-app> </template> diff --git a/aleksis/core/frontend/components/app/customMenu.graphql b/aleksis/core/frontend/components/app/customMenu.graphql index 9591126f8226a590355969d643a5db9257c2b4e6..20fed201f1270c47a9afadb9fa96ddb73f9ca6fc 100644 --- a/aleksis/core/frontend/components/app/customMenu.graphql +++ b/aleksis/core/frontend/components/app/customMenu.graphql @@ -1,7 +1,9 @@ -query ($name: String!) { +query customMenu($name: String!) { customMenuByName(name: $name) { + id name items { + id name url icon diff --git a/aleksis/core/frontend/components/app/dynamicRoutes.graphql b/aleksis/core/frontend/components/app/dynamicRoutes.graphql index 49c208b729f4185b0053e8bfbff13fd3ca8c78f5..433a1ca753a8d16ce1281575301bb700329a6d46 100644 --- a/aleksis/core/frontend/components/app/dynamicRoutes.graphql +++ b/aleksis/core/frontend/components/app/dynamicRoutes.graphql @@ -1,4 +1,4 @@ -{ +query dynamicRoutes { dynamicRoutes { parentRouteName diff --git a/aleksis/core/frontend/components/app/messages.graphql b/aleksis/core/frontend/components/app/messages.graphql index 96c09c62c90962b103fae88dc53bc4c96e1a2b49..ffbdd6e40ad308d30a13e561efcbd5dc4e747941 100644 --- a/aleksis/core/frontend/components/app/messages.graphql +++ b/aleksis/core/frontend/components/app/messages.graphql @@ -1,4 +1,4 @@ -{ +query messages { messages { tags message diff --git a/aleksis/core/frontend/components/app/ping.graphql b/aleksis/core/frontend/components/app/ping.graphql index 1775ef4a61beab635ff199bd454e328cd02c3304..83101ecfc0a7c223607a9ff9e24504d5c77a6d1c 100644 --- a/aleksis/core/frontend/components/app/ping.graphql +++ b/aleksis/core/frontend/components/app/ping.graphql @@ -1,3 +1,3 @@ -query Ping($payload: String) { +query ping($payload: String) { ping(payload: $payload) } diff --git a/aleksis/core/frontend/components/app/systemProperties.graphql b/aleksis/core/frontend/components/app/systemProperties.graphql index b8ec991bda2b1b689c97f2fb339dafce9d0e1175..eec69756e5857ecc4fa3ec6d8c0b19aa6afe49f2 100644 --- a/aleksis/core/frontend/components/app/systemProperties.graphql +++ b/aleksis/core/frontend/components/app/systemProperties.graphql @@ -1,4 +1,4 @@ -{ +query systemProperties { systemProperties { availableLanguages { code diff --git a/aleksis/core/frontend/components/app/whoAmI.graphql b/aleksis/core/frontend/components/app/whoAmI.graphql index 159e4c088e1ba1327130711f9fac9e8d1645b607..1af27f4aeb41dcbe1e2722895de0019806762e45 100644 --- a/aleksis/core/frontend/components/app/whoAmI.graphql +++ b/aleksis/core/frontend/components/app/whoAmI.graphql @@ -6,6 +6,7 @@ query whoAmI($permissions: [String]!) { isAnonymous isImpersonate person { + id photo { url } diff --git a/aleksis/core/frontend/components/authorized_oauth_applications/accessTokens.graphql b/aleksis/core/frontend/components/authorized_oauth_applications/accessTokens.graphql index 68ab08b05d479b8149b3772406a81dd0673c3169..b143296677bd0d96453f98a2adb1378a4eff17f4 100644 --- a/aleksis/core/frontend/components/authorized_oauth_applications/accessTokens.graphql +++ b/aleksis/core/frontend/components/authorized_oauth_applications/accessTokens.graphql @@ -1,4 +1,4 @@ -{ +query oauthAccessTokens { accessTokens: oauthAccessTokens { id created diff --git a/aleksis/core/frontend/components/authorized_oauth_applications/revokeOauthToken.graphql b/aleksis/core/frontend/components/authorized_oauth_applications/revokeOauthToken.graphql index 232f231cc531453dc47d14f4715985772ed3d3fb..8a48c410a6dfec246b755688591fbee047aae170 100644 --- a/aleksis/core/frontend/components/authorized_oauth_applications/revokeOauthToken.graphql +++ b/aleksis/core/frontend/components/authorized_oauth_applications/revokeOauthToken.graphql @@ -1,5 +1,5 @@ -mutation ($ids: [ID]!) { +mutation revokeOauthTokens($ids: [ID]!) { revokeOauthTokens(ids: $ids) { - revokationCount + ok } } diff --git a/aleksis/core/frontend/components/calendar/Calendar.vue b/aleksis/core/frontend/components/calendar/Calendar.vue index 5f5c44c9ced529606f9d621294a30d42cf47e5d4..d8fcdfe39a6e5f46568315c94c5b32cd3bdaf112 100644 --- a/aleksis/core/frontend/components/calendar/Calendar.vue +++ b/aleksis/core/frontend/components/calendar/Calendar.vue @@ -40,6 +40,44 @@ :calendar-type="internalCalendarType" /> </template> + <template + v-if="Object.keys(daysWithHiddenEvents).length" + #interval-header + > + <div + v-if=" + !internalCalendarType === 'day' || + Object.keys(daysWithHiddenEvents).includes(internalCalendarFocus) + " + class="d-flex justify-center align-end" + :style="{ height: '100%' }" + > + <v-btn + icon + class="ma-2" + @click="showAllAllDayEvents = !showAllAllDayEvents" + > + <v-icon>{{ showAllAllDayEventsButtonIcon }}</v-icon> + </v-btn> + </div> + </template> + <template #day-header="{ date }"> + <template + v-if=" + Object.keys(daysWithHiddenEvents).includes(date) && + !showAllAllDayEvents + " + > + <v-spacer /> + <div + class="v-event-more ml-1" + v-ripple + @click="showAllAllDayEvents = true" + > + {{ $tc("calendar.more_events", daysWithHiddenEvents[date]) }} + </div> + </template> + </template> </v-calendar> <component v-if="selectedEvent" @@ -65,6 +103,8 @@ import { import { gqlCalendar, calendarDaysPreference } from "./calendar.graphql"; +import { Interval } from "luxon"; + export default { name: "Calendar", props: { @@ -104,6 +144,11 @@ export default { required: false, default: "current", }, + maxAllDayEvents: { + type: Number, + required: false, + default: 5, + }, }, data() { return { @@ -139,6 +184,9 @@ export default { daysOfWeek: [1, 2, 3, 4, 5, 6, 0], }, }, + + showAllAllDayEvents: false, + daysWithHiddenEvents: {}, }; }, emits: ["changeCalendarType", "changeCalendarFocus", "selectEvent"], @@ -164,7 +212,7 @@ export default { }; }, events() { - return this.calendar.calendarFeeds + let events = this.calendar.calendarFeeds .filter((c) => this.calendarFeeds.map((cf) => cf.name).includes(c.name)) .flatMap((cf) => cf.events.map((event) => { @@ -184,6 +232,34 @@ export default { }; }), ); + if (this.internalCalendarType === "month" || this.showAllAllDayEvents) { + return events; + } + + let dateFullEventCount = {}; + this.clearDaysWithHiddenEvents(); + + return events.filter((event) => { + if (!event.allDay) { + return true; + } + const start = event.startDateTime; + dateFullEventCount[start] = (dateFullEventCount[start] || 0) + 1; + const show = dateFullEventCount[start] <= this.maxAllDayEvents; + if (!show) { + const dateInterval = Interval.fromDateTimes( + start, + event.endDateTime.endOf("day"), + ) + .splitBy({ day: 1 }) + .map((date) => date.start.toISODate()); + for (const date of dateInterval) { + this.daysWithHiddenEvents[date] = + (this.daysWithHiddenEvents[date] || 0) + 1; + } + } + return show; + }); }, paramsForSend() { if (this.params !== null) { @@ -251,6 +327,9 @@ export default { return this.personByIdOrMe.preferences.daysOfWeek; }, + showAllAllDayEventsButtonIcon() { + return this.showAllAllDayEvents ? "mdi-chevron-up" : "mdi-chevron-down"; + }, }, watch: { params(newParams) { @@ -526,6 +605,9 @@ export default { // TODO: is this destroyed when unloading? setInterval(() => this.cal.updateTimes(), 60 * 1000); }, + clearDaysWithHiddenEvents() { + this.daysWithHiddenEvents = {}; + }, }, mounted() { this.ready = true; diff --git a/aleksis/core/frontend/components/calendar/calendarFeeds.graphql b/aleksis/core/frontend/components/calendar/calendarFeeds.graphql index 917cf386965d820bc634583a1af6339e8500c0cc..f49deafb6a0f2bfd45cc8fa762fde98f81eb680d 100644 --- a/aleksis/core/frontend/components/calendar/calendarFeeds.graphql +++ b/aleksis/core/frontend/components/calendar/calendarFeeds.graphql @@ -1,4 +1,4 @@ -query { +query calendarFeeds { calendar { allFeedsUrl calendarFeeds { diff --git a/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql b/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql index 633f0791c3e00f0c82886779366704086871c484..3a2c8a72ad9aff66d7d6f8c8f88f628892f546e1 100644 --- a/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql +++ b/aleksis/core/frontend/components/calendar/setCalendarStatus.graphql @@ -1,4 +1,4 @@ -mutation ($calendars: [String]!) { +mutation setCalendarStatus($calendars: [String]!) { setCalendarStatus(calendars: $calendars) { ok } diff --git a/aleksis/core/frontend/components/celery_progress/celeryProgress.graphql b/aleksis/core/frontend/components/celery_progress/celeryProgress.graphql index 557e33517d4f3536e043ba0e64cb8c3f622741d2..985c12c713ab480926e67ff27355b8f1eec43a1b 100644 --- a/aleksis/core/frontend/components/celery_progress/celeryProgress.graphql +++ b/aleksis/core/frontend/components/celery_progress/celeryProgress.graphql @@ -1,4 +1,4 @@ -query ($taskId: String!) { +query celeryProgress($taskId: String!) { celeryProgressByTaskId(taskId: $taskId) { state success diff --git a/aleksis/core/frontend/components/celery_progress/celeryProgressBottom.graphql b/aleksis/core/frontend/components/celery_progress/celeryProgressBottom.graphql index 5cae8f3baa46b14b4cf1031dc248d2dd7757b576..17392bb390a31e287dfc9d8b2be26b6dfe44587a 100644 --- a/aleksis/core/frontend/components/celery_progress/celeryProgressBottom.graphql +++ b/aleksis/core/frontend/components/celery_progress/celeryProgressBottom.graphql @@ -1,4 +1,4 @@ -{ +query celeryProgressByUser { celeryProgressByUser { state success diff --git a/aleksis/core/frontend/components/celery_progress/celeryProgressFetched.graphql b/aleksis/core/frontend/components/celery_progress/celeryProgressFetched.graphql index b3fedc916e6a3851677f0fe7a3c322c9311a33e4..4556d69113e6970b33254eb36bf8dd401c245e70 100644 --- a/aleksis/core/frontend/components/celery_progress/celeryProgressFetched.graphql +++ b/aleksis/core/frontend/components/celery_progress/celeryProgressFetched.graphql @@ -1,4 +1,4 @@ -mutation ($taskId: String!) { +mutation celeryProgressFetched($taskId: String!) { celeryProgressFetched(taskId: $taskId) { celeryProgress { state diff --git a/aleksis/core/frontend/components/generic/InfiniteScrollingDateSortedCRUDIterator.vue b/aleksis/core/frontend/components/generic/InfiniteScrollingDateSortedCRUDIterator.vue index e67168a8e23eb87f0f4cb9c1a34227f1fb24ee5a..6322e58fcc8e563af5edefbaa2d6f5947fc77a46 100644 --- a/aleksis/core/frontend/components/generic/InfiniteScrollingDateSortedCRUDIterator.vue +++ b/aleksis/core/frontend/components/generic/InfiniteScrollingDateSortedCRUDIterator.vue @@ -59,9 +59,12 @@ import { DateTime } from "luxon"; ref="days" > <v-list-item-content> - <v-subheader class="text-h6">{{ - $d(date, "dateWithWeekday") - }}</v-subheader> + <v-subheader + class="text-h5 px-2 hover-hash" + @click="gotoDate(date.toISODate())" + > + {{ $d(date, "dateWithWeekday") }} + </v-subheader> <v-list max-width="100%" class="pt-0 mt-n1"> <v-list-item class="px-1" @@ -126,6 +129,13 @@ import { DateTime } from "luxon"; }} </CRUDIteratorEmptyMessage> </slot> + + <date-select-footer + :value="currentDate" + @input="gotoDate" + @prev="gotoPrev" + @next="gotoNext" + /> </template> <template #no-results> @@ -577,12 +587,11 @@ export default { this.gotoDate(next.toISODate()); } }, - focus(element, how) { + focus(element, how = "smooth") { // Helper function used to scroll to day group. - element.$el.scrollIntoView({ - behavior: how, - block: "start", - inline: "nearest", + this.$vuetify.goTo(element, { + duration: how === "instant" ? 0 : 400, + offset: this.topMargin, }); }, }, @@ -601,3 +610,11 @@ export default { }, }; </script> + +<style scoped> +.hover-hash:hover::before { + position: absolute; + left: -1ch; + content: "#"; +} +</style> diff --git a/aleksis/core/frontend/components/generic/forms/DateField.vue b/aleksis/core/frontend/components/generic/forms/DateField.vue index 37f39dbfe27f3244939c147e07029fc6b3390b82..517bddc8e579c91e582d61162c376743fe2d50a6 100644 --- a/aleksis/core/frontend/components/generic/forms/DateField.vue +++ b/aleksis/core/frontend/components/generic/forms/DateField.vue @@ -10,7 +10,7 @@ > <template #activator="{ on, attrs }"> <v-text-field - v-model="date" + :value="date" v-bind="{ ...$attrs, ...attrs }" @click="handleClick" @focusin="handleFocusIn" @@ -27,8 +27,8 @@ ref="picker" no-title scrollable - :min="min" - :max="max" + :min="limitSelectableRange ? min : ''" + :max="limitSelectableRange ? max : ''" :locale="$i18n.locale" first-day-of-week="1" show-adjacent-months @@ -69,6 +69,11 @@ export default { required: false, default: () => [], }, + limitSelectableRange: { + type: Boolean, + required: false, + default: true, + }, }, computed: { date: { @@ -112,8 +117,9 @@ export default { this.openDueToFocus = true; this.menu = true; }, - handleFocusOut() { + handleFocusOut(event) { if (this.openDueToFocus) this.menu = false; + this.date = event.target.value; }, }, watch: { diff --git a/aleksis/core/frontend/components/generic/forms/GroupField.vue b/aleksis/core/frontend/components/generic/forms/GroupField.vue index 3433c5c3fb0695cfd5842ad0a461ab5cfb6aa765..736425d59cfc3e49cad459cd94ca50ff77cc4952 100644 --- a/aleksis/core/frontend/components/generic/forms/GroupField.vue +++ b/aleksis/core/frontend/components/generic/forms/GroupField.vue @@ -13,7 +13,7 @@ <script> import queryMixin from "../../../mixins/queryMixin.js"; -import { groups } from "./group.graphql"; +import { formGroups } from "./group.graphql"; export default { name: "GroupField", @@ -26,7 +26,7 @@ export default { gqlQuery: { type: Object, required: false, - default: () => groups, + default: () => formGroups, }, }, }; diff --git a/aleksis/core/frontend/components/generic/forms/PersonField.vue b/aleksis/core/frontend/components/generic/forms/PersonField.vue index 44479c3f66b29c244919f06f54b0b1a71f28c7dc..4df1df64d9a33c0d1203af62df7be6e841f3d54d 100644 --- a/aleksis/core/frontend/components/generic/forms/PersonField.vue +++ b/aleksis/core/frontend/components/generic/forms/PersonField.vue @@ -4,7 +4,7 @@ v-on="$listeners" hide-no-data :items="items" - :item-text="(person) => `${person.fullName} (${person.shortName})`" + :item-text="getItemText" item-value="id" :loading="loading" /> @@ -12,7 +12,7 @@ <script> import queryMixin from "../../../mixins/queryMixin.js"; -import { persons } from "./person.graphql"; +import { formPersons } from "./person.graphql"; export default { name: "PersonField", @@ -25,7 +25,15 @@ export default { gqlQuery: { type: Object, required: false, - default: () => persons, + default: () => formPersons, + }, + }, + methods: { + getItemText(person) { + if (person?.shortName) { + return `${person.fullName} (${person.shortName})`; + } + return person.fullName; }, }, }; diff --git a/aleksis/core/frontend/components/generic/forms/TimeField.vue b/aleksis/core/frontend/components/generic/forms/TimeField.vue index 9d6fbd154a13870b25a14f45924242030630d7f1..7ed63015aaa5e7865ff602e89613952c60caa752 100644 --- a/aleksis/core/frontend/components/generic/forms/TimeField.vue +++ b/aleksis/core/frontend/components/generic/forms/TimeField.vue @@ -10,7 +10,7 @@ > <template #activator="{ on, attrs }"> <v-text-field - v-model="time" + :value="time" v-bind="{ ...$attrs, ...attrs }" @click="handleClick" @focusin="handleFocusIn" @@ -26,8 +26,8 @@ <v-time-picker v-model="time" ref="picker" - :min="min" - :max="max" + :min="limitSelectableRange ? min : ''" + :max="limitSelectableRange ? max : ''" full-width format="24hr" @click:minute="menu = false" @@ -72,6 +72,11 @@ export default { required: false, default: () => [], }, + limitSelectableRange: { + type: Boolean, + required: false, + default: true, + }, }, computed: { time: { @@ -107,8 +112,9 @@ export default { this.openDueToFocus = true; this.menu = true; }, - handleFocusOut() { + handleFocusOut(event) { if (this.openDueToFocus) this.menu = false; + this.time = event.target.value; }, }, watch: { diff --git a/aleksis/core/frontend/components/generic/forms/group.graphql b/aleksis/core/frontend/components/generic/forms/group.graphql index 5a4906b549225bab5e2ba98e2ad681fb03d3583e..fcd97f2b49c19ca765b5d5d91b77c36c838bcf89 100644 --- a/aleksis/core/frontend/components/generic/forms/group.graphql +++ b/aleksis/core/frontend/components/generic/forms/group.graphql @@ -1,4 +1,4 @@ -query groups { +query formGroups { items: groups { id shortName diff --git a/aleksis/core/frontend/components/generic/forms/person.graphql b/aleksis/core/frontend/components/generic/forms/person.graphql index 6985dc9428b9c171706e170a35d2bd38e038a7ff..b7aaae4f2e3a8ccc4c54e8f0962ed518d75c5317 100644 --- a/aleksis/core/frontend/components/generic/forms/person.graphql +++ b/aleksis/core/frontend/components/generic/forms/person.graphql @@ -1,4 +1,4 @@ -query persons { +query formPersons { items: persons { id shortName diff --git a/aleksis/core/frontend/components/group/GroupAvatarClickbox.vue b/aleksis/core/frontend/components/group/GroupAvatarClickbox.vue index 160a07501b5d12433fed1d1ac1720e16ca7b0d7a..d78e68ba09bc0b1555fb0d980f555b4ef45fb566 100644 --- a/aleksis/core/frontend/components/group/GroupAvatarClickbox.vue +++ b/aleksis/core/frontend/components/group/GroupAvatarClickbox.vue @@ -1,9 +1,9 @@ <template> <avatar-clickbox> <template #activator> - <avatar-content :imageUrl="url" class="rounded-circle" /> + <avatar-content :image-url="url" class="rounded-circle" /> </template> - <avatar-content :imageUrl="url" contain /> + <avatar-content :image-url="url" contain /> </avatar-clickbox> </template> diff --git a/aleksis/core/frontend/components/group/GroupList.vue b/aleksis/core/frontend/components/group/GroupList.vue index 0b7b5ac115d63a0d04bacaa3f6567786898d2048..cbe3c49dd09e2a16513e9574c81ee03bbf95cfa6 100644 --- a/aleksis/core/frontend/components/group/GroupList.vue +++ b/aleksis/core/frontend/components/group/GroupList.vue @@ -1,7 +1,7 @@ <script> import CRUDList from "../generic/CRUDList.vue"; -import { deleteGroups, groups } from "./groupList.graphql"; +import { deleteGroups, groups } from "./groups.graphql"; import CreateButton from "../generic/buttons/CreateButton.vue"; import TableLink from "../generic/TableLink.vue"; import AvatarContent from "../person/AvatarContent.vue"; @@ -73,7 +73,7 @@ export default { <template #avatarUrl="{ item }"> <table-link :to="{ name: 'core.group', params: { id: item.id } }"> <v-avatar class="my-1 me-2"> - <avatar-content :imageUrl="item.avatarUrl" contain /> + <avatar-content :image-url="item.avatarUrl" contain /> </v-avatar> </table-link> </template> diff --git a/aleksis/core/frontend/components/group/GroupMembers.vue b/aleksis/core/frontend/components/group/GroupMembers.vue index d0dc18a3de9925e40ab2dedaf6bef59c201fb212..b841283bb7bf312ff654b234edb575130f3bf838 100644 --- a/aleksis/core/frontend/components/group/GroupMembers.vue +++ b/aleksis/core/frontend/components/group/GroupMembers.vue @@ -76,7 +76,7 @@ export default { <!-- eslint-disable-next-line vue/valid-v-slot --> <template #item.id="{ item }"> <v-tooltip bottom> - <template v-slot:activator="{ on, attrs }"> + <template #activator="{ on, attrs }"> <secondary-action-button v-bind="attrs" v-on="on" diff --git a/aleksis/core/frontend/components/group/groupList.graphql b/aleksis/core/frontend/components/group/groupList.graphql deleted file mode 100644 index 7df6604b94608301147eec994d6f0add1b5d9013..0000000000000000000000000000000000000000 --- a/aleksis/core/frontend/components/group/groupList.graphql +++ /dev/null @@ -1,24 +0,0 @@ -query groups($orderBy: [String], $filters: JSONString) { - items: groups(orderBy: $orderBy, filters: $filters) { - id - shortName - name - avatarUrl - schoolTerm { - id - name - } - groupType { - id - name - } - canEdit - canDelete - } -} - -mutation deleteGroups($ids: [ID]!) { - deleteGroups(ids: $ids) { - deletionCount - } -} diff --git a/aleksis/core/frontend/components/group/groups.graphql b/aleksis/core/frontend/components/group/groups.graphql index 701ecde468d517da81410cb35faba0022c91fa09..cc5e716216d05589f05f2ea65a1655cbf07abb3e 100644 --- a/aleksis/core/frontend/components/group/groups.graphql +++ b/aleksis/core/frontend/components/group/groups.graphql @@ -1,3 +1,22 @@ +query groups($orderBy: [String], $filters: JSONString) { + items: groups(orderBy: $orderBy, filters: $filters) { + id + shortName + name + avatarUrl + schoolTerm { + id + name + } + groupType { + id + name + } + canEdit + canDelete + } +} + query groupById($id: ID) { object: groupById(id: $id) { id diff --git a/aleksis/core/frontend/components/notifications/markNotificationRead.graphql b/aleksis/core/frontend/components/notifications/markNotificationRead.graphql index 8cc7bed4325857b3407701900a356150d3614b68..689d3c1e44172efabd8c62b03488dd5e71f6d695 100644 --- a/aleksis/core/frontend/components/notifications/markNotificationRead.graphql +++ b/aleksis/core/frontend/components/notifications/markNotificationRead.graphql @@ -1,4 +1,4 @@ -mutation ($id: ID!) { +mutation markNotificationRead($id: ID!) { markNotificationRead(id: $id) { notification { id diff --git a/aleksis/core/frontend/components/notifications/myNotifications.graphql b/aleksis/core/frontend/components/notifications/myNotifications.graphql index 5c430731b0e3993e2c4b0872c4a44b5d8639a0bf..d51ef53f22a4724d33d97bd223281ff3e3d1a705 100644 --- a/aleksis/core/frontend/components/notifications/myNotifications.graphql +++ b/aleksis/core/frontend/components/notifications/myNotifications.graphql @@ -1,7 +1,8 @@ -{ +query myNotifications { myNotifications: whoAmI { id person { + id notifications { id title diff --git a/aleksis/core/frontend/components/pdf/pdf.graphql b/aleksis/core/frontend/components/pdf/pdf.graphql index aac3228d75c3c77ab131500b5e0d5e2ae1b8f503..e469aaaf5ffd4c5005eb603ce387f9f82cae15d0 100644 --- a/aleksis/core/frontend/components/pdf/pdf.graphql +++ b/aleksis/core/frontend/components/pdf/pdf.graphql @@ -1,5 +1,6 @@ -query ($id: ID!) { +query pdf($id: ID!) { pdf: pdfById(id: $id) { + id file { url } diff --git a/aleksis/core/frontend/components/person/PersonActions.vue b/aleksis/core/frontend/components/person/PersonActions.vue index afa3b04efd549910a7197a44af3d859af04935f8..5bc9c70558462c10ee76507a94eb2118e76cf66c 100644 --- a/aleksis/core/frontend/components/person/PersonActions.vue +++ b/aleksis/core/frontend/components/person/PersonActions.vue @@ -101,7 +101,8 @@ </template> <script> -import { actions, deletePersons } from "./personActions.graphql"; +import { personActions } from "./personActions.graphql"; +import { deletePersons } from "./personList.graphql"; import DeleteDialog from "../generic/dialogs/DeleteDialog.vue"; export default { @@ -115,7 +116,7 @@ export default { }, apollo: { person: { - query: actions, + query: personActions, variables() { return { id: this.id, diff --git a/aleksis/core/frontend/components/person/personActions.graphql b/aleksis/core/frontend/components/person/personActions.graphql index ebfbb0fcd137be8a35114f60a39d99da1be1436e..be1b9209a9a6a6b3938423e8ccb20eed016b9398 100644 --- a/aleksis/core/frontend/components/person/personActions.graphql +++ b/aleksis/core/frontend/components/person/personActions.graphql @@ -1,4 +1,4 @@ -query actions($id: ID!) { +query personActions($id: ID!) { person: personById(id: $id) { id userid @@ -10,9 +10,3 @@ query actions($id: ID!) { canImpersonatePerson } } - -mutation deletePersons($ids: [ID]!) { - deletePersons(ids: $ids) { - deletionCount - } -} diff --git a/aleksis/core/frontend/components/room/RoomChip.vue b/aleksis/core/frontend/components/room/RoomChip.vue new file mode 100644 index 0000000000000000000000000000000000000000..6aa70777d217a3a54b1a6292f2df6d30d817e8ff --- /dev/null +++ b/aleksis/core/frontend/components/room/RoomChip.vue @@ -0,0 +1,25 @@ +<script> +export default { + name: "RoomChip", + props: { + room: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <v-tooltip bottom> + <template #activator="{ on, attrs }"> + <v-chip v-bind="{ ...attrs, ...$attrs }" v-on="{ ...on, ...$listeners }"> + <v-avatar> + <v-icon> mdi-door </v-icon> + </v-avatar> + {{ room.shortName }} + </v-chip> + </template> + <span>{{ room.name }}</span> + </v-tooltip> +</template> diff --git a/aleksis/core/frontend/components/school_term/ActiveSchoolTermSelect.vue b/aleksis/core/frontend/components/school_term/ActiveSchoolTermSelect.vue index 3de29edcf36b0661ee5a4dba6a59bee48c565183..e9c0543837faf74b89c6f314bc11c8079bdc70a6 100644 --- a/aleksis/core/frontend/components/school_term/ActiveSchoolTermSelect.vue +++ b/aleksis/core/frontend/components/school_term/ActiveSchoolTermSelect.vue @@ -1,7 +1,7 @@ <script> import { activeSchoolTerm, - schoolTerms, + schoolTermsForActiveSchoolTerm, setActiveSchoolTerm, } from "./activeSchoolTerm.graphql"; import loadingMixin from "../../mixins/loadingMixin"; @@ -10,7 +10,7 @@ export default { mixins: [loadingMixin], apollo: { schoolTerms: { - query: schoolTerms, + query: schoolTermsForActiveSchoolTerm, }, activeSchoolTerm: { query: activeSchoolTerm, diff --git a/aleksis/core/frontend/components/school_term/activeSchoolTerm.graphql b/aleksis/core/frontend/components/school_term/activeSchoolTerm.graphql index 95b5fc170064e4dea9a24a17f3b10ad4bccb5af8..f005e1488979c348af957b4f09710cff9c254032 100644 --- a/aleksis/core/frontend/components/school_term/activeSchoolTerm.graphql +++ b/aleksis/core/frontend/components/school_term/activeSchoolTerm.graphql @@ -10,7 +10,7 @@ query activeSchoolTerm { } } -query schoolTerms { +query schoolTermsForActiveSchoolTerm { schoolTerms { id name diff --git a/aleksis/core/frontend/components/two_factor/twoFactor.graphql b/aleksis/core/frontend/components/two_factor/twoFactor.graphql index 431215ed1840f9ad06e61e1c8c63cf6fe0af35b7..bd0837e2437a1708739efb2f1554af86825d9649 100644 --- a/aleksis/core/frontend/components/two_factor/twoFactor.graphql +++ b/aleksis/core/frontend/components/two_factor/twoFactor.graphql @@ -1,4 +1,4 @@ -{ +query twoFactor { twoFactor { activated backupTokensCount diff --git a/aleksis/core/frontend/css/global.scss b/aleksis/core/frontend/css/global.scss index 6bbdf6e47d9cef354efcb3fa46eedca16e0b9483..135927a8572c1c38f805eab2027ad7a9bc58224d 100644 --- a/aleksis/core/frontend/css/global.scss +++ b/aleksis/core/frontend/css/global.scss @@ -39,3 +39,8 @@ h6, .full-width { width: 100%; } + +.v-calendar-daily_head-day { + display: flex; + flex-direction: column; +} diff --git a/aleksis/core/frontend/messages/ar.json b/aleksis/core/frontend/messages/ar.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/aleksis/core/frontend/messages/ar.json @@ -0,0 +1 @@ +{} diff --git a/aleksis/core/frontend/messages/de.json b/aleksis/core/frontend/messages/de.json index 70c4b17328c9d85fc97ad8307a0601c578545bd2..54b0bc72769e3892de46a4660adc49b0a87b380e 100644 --- a/aleksis/core/frontend/messages/de.json +++ b/aleksis/core/frontend/messages/de.json @@ -116,6 +116,7 @@ }, "base": { "about_aleksis": "Über AlekSIS® — The Free School Information System", + "about_copyright": "© Das AlekSIS-Team", "imprint": "Impressum", "logo": "Logo", "no_permission": "Keine Berechtigung", @@ -230,25 +231,43 @@ "snackbar_success_message": "Der Vorgang wurde erfolgreich beendet." }, "group": { + "avatar": "Avatar", "child_groups": "Kind-Gruppen", "child_groups_n": "Keine Kindgruppen | {n} Kindgruppe | {n} Kindgruppen", + "confirm_delete": "Möchten Sie diese Gruppe wirklich löschen?", "group_type": { + "additional_attributes": "Zusätzliche Attribute", + "allowed_information": { + "address": "Adresse", + "avatar": "Avatar", + "contact_details": "Kontaktdetails", + "groups": "Gruppen", + "personal_details": "Persönliche Details", + "photo": "Foto" + }, "create": "Gruppentyp erstellen", "description": "Beschreibung", "menu_title": "Gruppentypen", "name": "Name", "no_group_type": "Kein Gruppentyp", + "owners_can_see_groups": "Besitzer von Gruppen mit diesem Gruppentyp können die Gruppen sehen", + "owners_can_see_members": "Besitzer von Gruppen mit diesem Gruppentyp können die Gruppenmitglieder sehen", + "owners_can_see_members_allowed_information": "Informationen, die Besitzer von Gruppen mit diesem Gruppentyp über die Gruppenmitglieder sehen können", + "owners_can_see_members_including": "(einschließlich {allowedInformation})", "title": "Gruppentyp", "title_plural": "Gruppentypen" }, "groups_and_child_groups": "Gruppen und Kindgruppen", + "member_of_n": "Keine Gruppenmitgliedschaften | Mitglied in einer Gruppe | Mitglied in {n} Gruppen", "menu_title": "Gruppen", + "name": "Name", + "no_groups": "Keine Gruppen", + "owner_of_n": "Keine Gruppeneigentümerschaften | Besitzt eine Gruppe | Besitzt {n} Gruppen", "ownership": "Gruppen-Eigentümerschaft", "parent_groups": "Übergeordnete Gruppen", "parent_groups_n": "Keine übergeordneten Gruppen | {n} übergeordnete Gruppe | {n} übergeordnete Gruppen", - "member_of_n": "Keine Gruppenmitgliedschaften | Mitglied in einer Gruppe | Mitglied in {n} Gruppen", - "owner_of_n": "Keine Gruppeneigentümerschaften | Besitzt eine Gruppe | Besitzt {n} Gruppen", "properties": "Eigenschaften", + "school_term": "Schuljahr", "short_name": "Kurzname", "statistics": { "age_average": "Durchschnittsalter", @@ -284,6 +303,7 @@ "error_404": "404", "offline_notification": "Sie sind offline. Einige Funktionen werden nicht funktionieren und einige Daten werden nicht aktuell sein.", "page_not_found": "Die aufgerufene Seite oder Ressource konnte nicht gefunden werden.", + "service_unavailable": "Der Server ist aktuell im Wartungsmodus und daher temporär nicht erreichbar.", "snackbar_error_message": "Es ist ein Netzwerkfehler aufgetreten. Bitte versuchen Sie es erneut." }, "notifications": { @@ -399,30 +419,32 @@ "title_plural": "Räume" }, "school_term": { + "active_school_term": { + "select_action": "Aktuelles auswählen", + "subtitle": "Die Auswahl wird auf allen Seiten in AlekSIS berücksichtigt.", + "title": "Aktives Schuljahr", + "warning": "Hinweis: Sie sehen aktuell Daten aus einem anderen Schuljahr ({termName}). Informationen können daher veraltet sein und entsprechen möglicherweise nicht dem aktuellen Stand." + }, "after": "Endet nach", "before": "Beginnt vor", "create_school_term": "Schuljahr erstellen", + "current": "Aktuell", "date_end": "Enddatum", "date_start": "Startdatum", "menu_title": "Schuljahre", "name": "Name", "title": "Schuljahr", - "title_plural": "Schuljahre", - "current": "Aktuell", - "active_school_term": { - "title": "Aktives Schuljahr", - "subtitle": "Die Auswahl wird auf allen Seiten in AlekSIS berücksichtigt.", - "warning": "Hinweis: Sie sehen aktuell Daten aus einem anderen Schuljahr ({termName}). Informationen können daher veraltet sein und entsprechen möglicherweise nicht dem aktuellen Stand.", - "select_action": "Aktuelles auswählen" - } + "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", - "update": "Aktualisieren" + "new_version_available": { + "body": "AlekSIS® wurde im Hintergrund aktualisiert. Um {instance} weiterhin zu verwenden, muss die Aktualisierung jetzt eingespielt werden.", + "header": "Neue Version verfügbar" + }, + "update": "Fertigstellen" }, "status": { "changes": "Sie haben nicht gespeicherte Änderungen.", diff --git a/aleksis/core/frontend/messages/en.json b/aleksis/core/frontend/messages/en.json index dda331d9ae8105f1ac43b7bdf8c011859597271d..ac23c920d6f0075565a8bd4da58216f1a928e841 100644 --- a/aleksis/core/frontend/messages/en.json +++ b/aleksis/core/frontend/messages/en.json @@ -113,6 +113,7 @@ }, "base": { "about_aleksis": "About AlekSIS® — The Free School Information System", + "about_copyright": "© The AlekSIS Team", "imprint": "Imprint", "logo": "Logo", "no_permission": "No Permission", @@ -134,7 +135,8 @@ "my_calendars": "My Calendars", "select": "Select calendars", "today": "Today", - "week": "Week" + "week": "Week", + "more_events": "{n} more" }, "celery_progress": { "error_message": "The operation couldn't be finished successfully.", @@ -361,9 +363,11 @@ "num_items_selected": "No items selected | 1 item selected | {n} items selected" }, "service_worker": { - "dismiss": "Dismiss", - "new_version_available": "A new version of the app is available", - "update": "Update" + "new_version_available": { + "header": "New version available", + "body": "AlekSIS® has been updated in the background. Refresh your version to keep using {instance}." + }, + "update": "Refresh" }, "status": { "changes": "You have unsaved changes.", diff --git a/aleksis/core/frontend/messages/fr.json b/aleksis/core/frontend/messages/fr.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/aleksis/core/frontend/messages/fr.json @@ -0,0 +1 @@ +{} diff --git a/aleksis/core/frontend/messages/la.json b/aleksis/core/frontend/messages/la.json new file mode 100644 index 0000000000000000000000000000000000000000..5c0ddcc9576185d24aadc606bcdb0d244b138d5e --- /dev/null +++ b/aleksis/core/frontend/messages/la.json @@ -0,0 +1,72 @@ +{ + "accounts": { + "login": { + "menu_title": "nomen profiteri" + }, + "logout": { + "menu_title": "nomen retractare" + } + }, + "actions": { + "search": "Quaerere" + }, + "announcement": { + "menu_title": "Nuntii", + "title_plural": "Nuntii" + }, + "forms": { + "date_time": { + "date": "dies", + "time": "tempus" + }, + "labels": { + "persons": "personae" + } + }, + "group": { + "group_type": { + "allowed_information": { + "groups": "Greges", + "photo": "Photographia" + }, + "description": "Descriptio", + "name": "Nomen" + }, + "menu_title": "Greges", + "name": "Nomen", + "short_name": "Breve nomen", + "title": "Grex", + "title_plural": "Greges" + }, + "holidays": { + "holiday_name": "Nomen" + }, + "notifications": { + "notifications": "Nuntii" + }, + "person": { + "birth_date": "Dies natalis", + "guardians": "Parentes", + "home": "Numerus telephoni domi", + "menu_title": "personae", + "mobile": "Numerus telephoni mobilis", + "name": "Nomen", + "page_title": "Persona", + "sex": { + "field": "Genus" + }, + "sex_description": "Genus", + "title": "Persona", + "title_plural": "personae" + }, + "personal_events": { + "description": "Descriptio", + "title": "Titulus" + }, + "rooms": { + "name": "Nomen" + }, + "school_term": { + "name": "Nomen" + } +} diff --git a/aleksis/core/frontend/messages/nb_NO.json b/aleksis/core/frontend/messages/nb_NO.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/aleksis/core/frontend/messages/nb_NO.json @@ -0,0 +1 @@ +{} diff --git a/aleksis/core/frontend/messages/ru.json b/aleksis/core/frontend/messages/ru.json index 55b38b268ae7e64e1769ee0b32edd92782eb52a6..50ab11618d55a474ff37afc585066748f33aede4 100644 --- a/aleksis/core/frontend/messages/ru.json +++ b/aleksis/core/frontend/messages/ru.json @@ -194,6 +194,7 @@ }, "groups_and_child_groups": "Группы и дочерние группы", "menu_title": "Группы", + "name": "ИмÑ", "ownership": "Владельцы группы", "title": "Группа", "title_plural": "Группы" diff --git a/aleksis/core/frontend/messages/tr.json b/aleksis/core/frontend/messages/tr.json new file mode 100644 index 0000000000000000000000000000000000000000..0967ef424bce6791893e9a57bb952f80fd536e93 --- /dev/null +++ b/aleksis/core/frontend/messages/tr.json @@ -0,0 +1 @@ +{} diff --git a/aleksis/core/frontend/messages/uk.json b/aleksis/core/frontend/messages/uk.json index 49d74190628e145aa9ab324c5eb0ccf2e13f66e0..3d0aa93fe3acf06181bf4ffb4a5be4d5e2f0e827 100644 --- a/aleksis/core/frontend/messages/uk.json +++ b/aleksis/core/frontend/messages/uk.json @@ -187,6 +187,12 @@ }, "group": { "group_type": { + "allowed_information": { + "address": "ÐдреÑа", + "contact_details": "Контактні дані", + "groups": "Групи", + "photo": "Фото" + }, "description": "ОпиÑ", "menu_title": "Типи груп", "name": "Ðазва", @@ -195,6 +201,7 @@ }, "groups_and_child_groups": "Групи та підлеглі групи", "menu_title": "Групи", + "name": "Ðазва", "ownership": "ВлаÑніÑть групи", "short_name": "Коротка назва", "title": "Група", diff --git a/aleksis/core/frontend/plugins/aleksis.js b/aleksis/core/frontend/plugins/aleksis.js index 4f2b3a17db5428237fd0b89f8d12af9419751ea3..22bf3e16551989d60c26e76ca9e2043d353d22bb 100644 --- a/aleksis/core/frontend/plugins/aleksis.js +++ b/aleksis/core/frontend/plugins/aleksis.js @@ -144,6 +144,14 @@ AleksisVue.install = function (Vue) { this.$root.toolbarTitle = newTitle; }; + /** + * Get base title defined by current Instance + * @return {string} Title as defined in site preferences + */ + Vue.prototype.$getBaseTitle = function () { + return Vue.$pageBaseTitle; + }; + /** * Load i18n messages from all known AlekSIS apps. */ diff --git a/aleksis/core/frontend/routes.js b/aleksis/core/frontend/routes.js index c90c3facf230c73ec0685610b22663433ab21eeb..b4164c69db163ab1211301e60a7ab813cd5ba7ad 100644 --- a/aleksis/core/frontend/routes.js +++ b/aleksis/core/frontend/routes.js @@ -840,7 +840,7 @@ const routes = [ name: "core.accounts.confirmEmailKey", }, { - path: "/accounts/social/login/cancelled/", + path: "/accounts/3rdparty/login/cancelled/", component: () => import("./components/LegacyBaseTemplate.vue"), props: { byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, @@ -848,7 +848,7 @@ const routes = [ name: "core.accounts.socialLoginCancelled", }, { - path: "/accounts/social/login/error/", + path: "/accounts/3rdparty/login/error/", component: () => import("./components/LegacyBaseTemplate.vue"), props: { byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, @@ -856,7 +856,7 @@ const routes = [ name: "core.accounts.socialLoginError", }, { - path: "/accounts/social/signup/", + path: "/accounts/3rdparty/signup/", component: () => import("./components/LegacyBaseTemplate.vue"), props: { byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, @@ -864,7 +864,7 @@ const routes = [ name: "core.accounts.socialSignup", }, { - path: "/accounts/social/connections/", + path: "/accounts/3rdparty/", component: () => import("./components/LegacyBaseTemplate.vue"), props: { byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, @@ -877,6 +877,14 @@ const routes = [ permission: "core.manage_social_connections_rule", }, }, + { + path: "/accounts/3rdparty/:pk(\\d+)/delete", + component: () => import("./components/LegacyBaseTemplate.vue"), + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + name: "core.accounts.deleteSocialConnection", + }, { path: "/oauth/authorized_tokens/", component: () => diff --git a/aleksis/core/locale/ar/LC_MESSAGES/django.po b/aleksis/core/locale/ar/LC_MESSAGES/django.po index 10f93edc4f11e009839a4fccceb3a32a0c041675..00243818489006421cb014b86cde008d050a54cf 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: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\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,10 +42,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "" @@ -99,199 +97,191 @@ msgstr "" msgid "There was a non-unique email address." msgstr "" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "" @@ -315,739 +305,779 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 msgid "Personal details" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 msgid "Personal events" msgstr "" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 msgid "Related group" msgstr "" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +msgid "Action" +msgstr "" + +#: aleksis/core/models.py:2017 +msgid "Send notifications" +msgstr "" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "" + +#: aleksis/core/models.py:2140 +msgid "Personal event alarm" +msgstr "" + +#: aleksis/core/models.py:2141 +msgid "Personal event alarms" +msgstr "" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "" @@ -1256,46 +1286,82 @@ msgstr "" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "" @@ -1742,22 +1808,6 @@ msgstr "" msgid "Edit group" msgstr "" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "" @@ -2209,6 +2259,11 @@ msgid "" " " msgstr "" +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "" @@ -2759,11 +2814,11 @@ msgstr "" msgid "This username is not allowed." msgstr "" -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "" @@ -2787,128 +2842,128 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 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 d6b2946b27a272a155b663f80a73142db675994c..5917cef914a3b477b1ccccaa6e0a4cb958c0f57f 100644 --- a/aleksis/core/locale/de_DE/LC_MESSAGES/django.po +++ b/aleksis/core/locale/de_DE/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: AlekSIS (School Information System) 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-15 15:50+0200\n" -"PO-Revision-Date: 2024-08-19 16:45+0000\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\n" +"PO-Revision-Date: 2025-01-14 17:21+0000\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" "Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-core/de/>\n" "Language: de_DE\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.0.2\n" +"X-Generator: Weblate 5.8.4\n" #: aleksis/core/apps.py:167 msgid "You have been logged out successfully." @@ -42,10 +42,8 @@ msgstr "E-Mail-Adresse" msgid "Home and mobile phone" msgstr "Festnetz- und Mobilfunknummer" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "Gruppen" @@ -99,199 +97,191 @@ msgstr "Sicherstellen, dass E-Mail-Adressen unter allen Personen eindeutig sind" msgid "There was a non-unique email address." msgstr "Es wurde eine nicht-eindeutige E-Mail-Adresse gefunden." -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "Suchen" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "Nach Namen suchen" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "Nach Kontaktdetails suchen" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "Berechtigung" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "Inhaltstyp" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "Benutzer" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "Gruppe" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "Basisdaten" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "Adresse" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "Kontaktdaten" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "Zusätzliche persönliche Daten" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "Neuer Benutzer" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "Neues Benutzerkonto erstellen" -#: aleksis/core/forms.py:131 +#: 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." -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Dieser Benutzername wird bereits genutzt." -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "Schuljahr" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "Allgemeine Daten" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "Personen" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "Foto" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "Datum" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "Zeit" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 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:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "Wer soll die Ankündigung sehen?" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "Schreiben Sie ihre Ankündigung:" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" -msgstr "" +msgstr "Eine Priorität setzen" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 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:283 +#: aleksis/core/forms.py:284 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." -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "Sie benötigen mindestens einen Empfänger." -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "Einladungscode" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "Bitte geben Sie Ihren Einladungscode ein." -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "Vorname" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "Nachname" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "Eine Person nutzt diese E-Mail-Adresse" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "Wer soll die Berechtigung erhalten?" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "Auf was?" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 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:" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "Vergebe die Berechtigung für alle Objekte" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 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:475 +#: aleksis/core/forms.py:476 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." -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "Adressdaten" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "Zusätzliche Daten" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "Kontodaten" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "Passwort" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "Passwort wiederholen" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "Die ausgewählte Aktion existiert nicht." -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 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." -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "Keine gültige Auswahl." @@ -315,741 +305,779 @@ msgstr "Kein Backup gefunden!" msgid "No backup result found!" msgstr "Kein Backupergebnis gefunden!" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "Zugeordnetes Schuljahr" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "Boolean (Ja/Nein)" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "Text (eine Zeile)" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "Datum und Uhrzeit" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "Dezimalzahl" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "E-Mail-Adresse" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "Ganze Zahl" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "IP-Adresse" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Boolean oder leer (Ja/Nein/weder)" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "Text (mehrzeilig)" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "URL / Link" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "Name" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "Startdatum" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "Enddatum" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "Das Startdatum muss vor dem Enddatum liegen." -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 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." -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "Schuljahre" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "Person" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "Kann Adresse sehen" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "Kann Kontaktdetails sehen" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "Kann Foto sehen" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "Kann Avatar-Bild sehen" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "Kann Gruppen einer Person sehen" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "Kann persönliche Daten sehen" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "weiblich" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "männlich" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "andere" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "Verknüpfter Benutzer" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "Zusätzliche Namen" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "Kurzname" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "Straße" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "Hausnummer" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "Postleitzahl" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "Ort" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "Festnetz" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "Handy" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "Geburtsdatum" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "Geburtsort" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "Geschlecht" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 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:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "Bild/Avatar anzeigen" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 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:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "Erziehungsberechtigte / Eltern" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "Primärgruppe" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "Beschreibung" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "Kann Kindgruppen zu Gruppen zuordnen" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "Kann Statistiken über Gruppen sehen." -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "Langname" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "Mitglieder" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "Leiter/-innen" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "Übergeordnete Gruppen" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "Gruppentyp" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Titel" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "Anwendung" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "Aktivität" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "Aktivitäten" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "Absender" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "Empfänger" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "Link" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Symbol" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "Benachrichtigung schicken am" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "Gelesen" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "Versandt" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "Kalenderalarm" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "Benachrichtigung" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "Benachrichtigungen" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "Link zur detaillierten Ansicht" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" -msgstr "" +msgstr "Priorität" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "Datum und Uhrzeit des Anzeigestarts" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "Anzeigezeitraum" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "Ankündigung" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: 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:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "Empfänger der Ankündigung" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "Empfänger der Ankündigung" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "Widget-Titel" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "Widget aktivieren" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "Widget ist kaputt" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "Größe auf Mobilgeräten" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "<= 600 px, 12 Spalten" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "Größe auf Tablets" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "> 600px, 12 Spalten" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "Größe auf Desktopgeräten" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "> 992 px, 12 Spalten" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "Größe auf großen Desktopgeräten" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "> 1200 px, 12 Spalten" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "Kann Standarddashboard bearbeiten" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "Dashboard-Widget" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "Dashboard-Widgets" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "URL" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "Symbol-URL" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "Externer-Link-Widget" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "Externer-Link-Widgets" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "Inhalt" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "Statischer-Inhalt-Widget" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "Statischer-Inhalt-Widgets" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "Dashboard-Widget" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "Reihenfolge" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "Teil des Standarddashboards" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "Reihenfolge der Dashboard-Widgets" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "Reihenfolgen der Dashboard-Widgets" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "Menü-ID" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "Benutzerdefiniertes Menü" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "Benutzerdefinierte Menüs" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "Menü" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "Benutzerdefiniertes Menüelement" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "Benutzerdefinierte Menüelemente" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "Titel des Typs" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" -msgstr "" +msgstr "Besitzer von Gruppen mit diesem Gruppentyp können die Gruppen sehen" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" -msgstr "" +msgstr "Besitzer von Gruppen mit diesem Gruppentyp können die Gruppenmitglieder sehen" -#: aleksis/core/models.py:1084 -#, fuzzy -#| msgid "Personal events" +#: aleksis/core/models.py:1116 msgid "Personal details" -msgstr "Persönliche Veranstaltungen" +msgstr "Persönliche Details" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "Kontaktdetails" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "Avatar" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" -msgstr "" +msgstr "Informationen die Besitzer von Gruppen mit diesem Gruppentyp über die Gruppenmitglieder sehen können" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "Gruppentyp" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "Gruppentypen" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "Kann Systemstatus sehen" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "Kann Daten verwalten" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "Kann sich verkleiden" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "Kann Suche benutzen" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "Kann Konfiguration ändern" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "Kann Einstellungen einer Person verändern" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "Kann Einstellungen einer Gruppe verändern" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "Kann die PDF-Generierung testen" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "Kann Personen einladen" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "Kann Geburtstagskalender sehen" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "Zugehörige Datenprüfungsaufgabe" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "Problem gelöst" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "Benachrichtigung gesendet" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "Datenprüfungsergebnis" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "Datenprüfungsergebnisse" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "Kann Datenprüfungen ausführen" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "Kann Datenprüfungsprobleme lösen" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "E-Mail-Adresse" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "Leiter" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "Datei abgelaufen am" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "Generierte HTML-Datei" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "Generierte PDF-Datei" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "PDF-Datei" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "PDF-Dateien" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "Task-Ergebnis" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "Task-Benutzer" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "Zurück-URL" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "Fortschritt-Titel" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "Fehlernachricht" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "Erfolgsnachricht" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "URL, auf die bei Erfolg weitergeleitet wird" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "Titel des zusätzlichen Buttons" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "URL des zusätzlichen Buttons" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "Symbol des zusätzlichen Buttons" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "Ergebnis abgerufen" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "Hintergrundaufgabe erfolgreich fertiggestellt" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "Die Hintergrundaufgabe '{}' wurde erfolgreich fertiggestellt." -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "Hintergrundaufgabe fehlgeschlagen" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "Die Hintergrundaufgabe '{}' ist fehlgeschlagen." -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "Hintergrundaufgabe" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "Task-Benutzer-Zuordnung" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "Task-Benutzer-Zuordnungen" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "Zusätzliche Attribute" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "Erlaubte Scopes, die ein Client anfordern kann" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 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:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "Kann Raum-Stundenplan sehen" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "Raum" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "Räume" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "Startdatum und -uhrzeit" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "Enddatum und -uhrzeit" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "Zeitzone" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "Wiederholungen" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "Ergänztes Basis-Ereignis" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "Kalender-Ereignis" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "Kalender-Ereignisse" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "Geburtstage" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "Geburtstag von {}" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "Ferien" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "Ferien" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "Kann Ferienkalender sehen" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 msgid "Personal events" msgstr "Persönliche Veranstaltungen" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "Ort" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "E-Mail" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 msgid "Related group" msgstr "Zugehörige Gruppe" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "Organisation" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "Organisationen" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "Audio" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "Anzeige" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "Prozedur" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "Veranstaltung" + +#: aleksis/core/models.py:2014 +msgid "Action" +msgstr "Aktion" + +#: aleksis/core/models.py:2017 +msgid "Send notifications" +msgstr "Benachrichtigungen schicken" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "Kalenderalarme" + +#: aleksis/core/models.py:2140 +msgid "Personal event alarm" +msgstr "Persönlicher Kalenderalarm" + +#: aleksis/core/models.py:2141 +msgid "Personal event alarms" +msgstr "Persönliche Kalenderalarme" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "Allgemein" @@ -1258,46 +1286,82 @@ msgstr "Automatisch das Dashboard und seine Widgets aktualisieren" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "Automatisch das Dashboard und seine Widgets aktualisieren (auf der ganzen Seite)" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "Erster Tag, der im Kalender erscheint" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "Montag" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "Dienstag" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "Mittwoch" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "Donnerstag" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "Freitag" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "Samstag" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "Sonntag" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "Seitenstandard benutzen" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "Geburtstagskalender-Farbe" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "Ferienkalender-Farbe" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "Persönliche-Veranstaltungen-Farbe" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "Aktivierte Kalender" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "Komma-getrennte Liste von verbotenen Benutzernamen" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "Englisch" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "Deutsch" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "Ukrainisch" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "Löschen" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "Aktionen" @@ -1814,22 +1878,6 @@ msgstr "Standard-Dashboard" msgid "Edit group" msgstr "Gruppe editieren" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "Gruppe erstellen" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "Gruppen filtern" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "Zurücksetzen" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "Ausgewählte Gruppen" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "Startseite" @@ -2291,15 +2339,13 @@ msgstr "Verbieten" #: aleksis/core/templates/oauth2_provider/logout_confirm.html:5 #: aleksis/core/templates/oauth2_provider/logout_confirm.html:29 -#, fuzzy -#| msgid "Confirm" msgid "Confirm Logout" -msgstr "Bestätigen" +msgstr "Abmeldung bestätigen" #: aleksis/core/templates/oauth2_provider/logout_confirm.html:27 #, python-format msgid "Confirm Logout requested by %(name)s" -msgstr "" +msgstr "Bestätigen Sie die von %(name)s angefragte Abmeldung" #: aleksis/core/templates/oauth2_provider/logout_confirm.html:44 msgid "Logout" @@ -2325,6 +2371,11 @@ msgstr "" " Wenn Sie verbunden sind und der Fehler weiterhin auftritt, kontaktieren Sie bitte die Systemadministratoren:\n" " " +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "Suchen" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "Globale Suche" @@ -2995,11 +3046,11 @@ msgstr "Deaktivieren" msgid "This username is not allowed." msgstr "Der Benutzername ist verboten." -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "E-Mail" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "SMS" @@ -3023,132 +3074,144 @@ msgstr "Es ist ein Fehler beim Generieren der PDF-Datei aufgetreten." msgid "Download PDF" msgstr "PDF herunterladen" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "Die Person wurde gespeichert." -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "Die Gruppe wurde gespeichert." -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "Der Wartungsmodus wurde erfolgreich angeschaltet." -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "Der Wartungsmodus wurde erfolgreich ausgeschaltet." -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "Die Ankündigung wurde gespeichert." -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "Ankündigung wurde gelöscht." -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "Das angeforderte Einstellungsregister existiert nicht" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "Die Einstellungen wurde gespeichert." -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "Die Gruppe wurde gelöscht." -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "Fortschritt: Datenprüfungen ausführen" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "Datenprüfungen laufen …" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "Die Datenprüfungen wurden erfolgreich ausgeführt." -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "Es gab ein Problem beim Ausführen der Datenprüfungen." -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, 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:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "Die angeforderte Lösungsoption existiert nicht" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "Das Dashboard-Widget wurde gespeichert." -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "Das Dashboard-Widget wurde erstellt." -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "Das Dashboard-Widget wurde gelöscht." -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "Ihre Dashboardkonfiguration wurde erfolgreich gespeichert." -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "Die Konfiguration des Standard-Dashboardes wurde erfolgreich gespeichert." -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "Die Einladung wurde erfolgreich erstellt. Der Einladungscode ist {code}" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "Wir haben die Berechtigungen erfolgreich zugewiesen." -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "Die globale Benutzerberechtigung wurde gelöscht." -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "Die globale Gruppenberechtigung wurde gelöscht." -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "Die Objekt-Benutzerberechtigung wurde gelöscht." -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "Die Objekt-Gruppenberechtigung wurde gelöscht." -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "Wir haben Ihnen eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passworts gesendet." -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 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:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "Das Drittanbieter-Konto wurde erfolgreich getrennt." -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 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:1216 +#: aleksis/core/views.py:1168 msgid "Person was already invited." msgstr "Person wurde bereits eingeladen." +#~ msgid "Create group" +#~ msgstr "Gruppe erstellen" + +#~ msgid "Filter groups" +#~ msgstr "Gruppen filtern" + +#~ msgid "Clear" +#~ msgstr "Zurücksetzen" + +#~ msgid "Selected groups" +#~ msgstr "Ausgewählte Gruppen" + #~ msgid "Assign child groups to groups" #~ msgstr "Kindgruppen zu Gruppen zuordnen" diff --git a/aleksis/core/locale/fr/LC_MESSAGES/django.po b/aleksis/core/locale/fr/LC_MESSAGES/django.po index a7c63ae547d8a34164af552cdab6b41a49048aaa..a60dbead8094306a5bdfa18d3c37267aa7404a96 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: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\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,10 +44,8 @@ msgstr "Détails de contact" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 #, fuzzy #| msgid "Group" msgid "Groups" @@ -105,213 +103,205 @@ msgstr "" msgid "There was a non-unique email address." msgstr "" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 #, fuzzy #| msgid "Contact details" msgid "Search by contact details" msgstr "Détails de contact" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "groupe" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 #, fuzzy #| msgid "Contact details" msgid "Contact data" msgstr "Détails de contact" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 #, fuzzy #| msgid "Contact details" msgid "Advanced personal data" msgstr "Détails de contact" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Cet nom est deja en utilisation." -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 #, fuzzy #| msgid "Contact details" msgid "Common data" msgstr "Détails de contact" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 #, fuzzy #| msgid "Person" msgid "Persons" msgstr "Personne" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "Date" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "Prénom" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "Nom de famille" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 #, fuzzy #| msgid "Contact details" msgid "Additional data" msgstr "Détails de contact" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 #, fuzzy #| msgid "Contact details" msgid "Account data" msgstr "Détails de contact" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "" @@ -335,793 +325,837 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 #, fuzzy #| msgid "Contact details" msgid "Start date" msgstr "Détails de contact" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "Personne" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 #, fuzzy #| msgid "Contact details" msgid "Can view address" msgstr "Détails de contact" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 #, fuzzy #| msgid "Contact details" msgid "Can view contact details" msgstr "Détails de contact" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 #, fuzzy #| msgid "Contact details" msgid "Can view photo" msgstr "Détails de contact" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 #, fuzzy #| msgid "Contact details" msgid "Can view avatar image" msgstr "Détails de contact" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 #, fuzzy #| msgid "Contact details" msgid "Can view persons groups" msgstr "Détails de contact" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 #, fuzzy #| msgid "Contact details" msgid "Can view personal details" msgstr "Détails de contact" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 #, fuzzy #| msgid "First name" msgid "Short name" msgstr "Prénom" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "Date d'anniversaire" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 #, fuzzy #| msgid "Date of birth" msgid "Place of birth" msgstr "Date d'anniversaire" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "Sexe" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "Description" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 #, fuzzy #| msgid "Contact details" msgid "Can view statistics about group." msgstr "Détails de contact" -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 #, fuzzy #| msgid "Last name" msgid "Long name" msgstr "Nom de famille" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "Propriétaires" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 #, fuzzy #| msgid "Person" msgid "Personal details" msgstr "Personne" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "Détails de contact" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 #, fuzzy #| msgid "Group" msgid "Group type" msgstr "Groupe" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 #, fuzzy #| msgid "Group" msgid "Group types" msgstr "Groupe" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 #, fuzzy #| msgid "Contact details" msgid "Can view system status" msgstr "Détails de contact" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 #, fuzzy #| msgid "Contact details" msgid "Can impersonate" msgstr "Détails de contact" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 #, fuzzy #| msgid "Contact details" msgid "Can invite persons" msgstr "Détails de contact" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 #, fuzzy #| msgid "Contact details" msgid "E-Mail address" msgstr "Détails de contact" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 #, fuzzy #| msgid "Owners" msgid "Owner" msgstr "Propriétaires" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 #, fuzzy #| msgid "Contact details" msgid "Additional button title" msgstr "Détails de contact" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 #, fuzzy #| msgid "Contact details" msgid "Additional button URL" msgstr "Détails de contact" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 #, fuzzy #| msgid "Contact details" msgid "Additional button icon" msgstr "Détails de contact" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 #, fuzzy #| msgid "Contact details" msgid "Additional attributes" msgstr "Détails de contact" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 #, fuzzy #| msgid "Contact details" msgid "Can view room timetable" msgstr "Détails de contact" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 #, fuzzy #| msgid "Contact details" msgid "Start date and time" msgstr "Détails de contact" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 #, fuzzy #| msgid "Person" msgid "Personal events" msgstr "Personne" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 #, fuzzy #| msgid "Group" msgid "Related group" msgstr "Groupe" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +msgid "Action" +msgstr "" + +#: aleksis/core/models.py:2017 +msgid "Send notifications" +msgstr "" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "" + +#: aleksis/core/models.py:2140 +#, fuzzy +#| msgid "Person" +msgid "Personal event alarm" +msgstr "Personne" + +#: aleksis/core/models.py:2141 +#, fuzzy +#| msgid "Person" +msgid "Personal event alarms" +msgstr "Personne" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "" @@ -1340,46 +1374,82 @@ msgstr "" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "" @@ -1832,22 +1902,6 @@ msgstr "" msgid "Edit group" msgstr "" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "" @@ -2314,6 +2368,11 @@ msgid "" " " msgstr "" +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "" @@ -2873,11 +2932,11 @@ msgstr "" msgid "This username is not allowed." msgstr "Cet nom est deja en utilisation." -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "" @@ -2901,129 +2960,129 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 #, 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 6d5f93f8b104eb1ffbdea76e9d3c6510a1f3f5c4..cc4d428e9622401c5441e977be5e327e29fd6078 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: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\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,10 +48,8 @@ msgstr "Inscriptio electronica" msgid "Home and mobile phone" msgstr "Numerus telephoni mobilis" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "Greges" @@ -111,217 +109,209 @@ msgstr "" msgid "There was a non-unique email address." msgstr "Inscriptio electronica" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "Quaerere" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "Quaerere cum breve nomine" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 #, fuzzy #| msgid "E-mail address" msgid "Search by contact details" msgstr "Inscriptio electronica" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "Grex" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 #, fuzzy #| msgid "E-mail address" msgid "Address" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 #, fuzzy #| msgid "Persons and accounts" msgid "Create a new account" msgstr "Personae et computi" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "Anus scolae" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 #, fuzzy #| msgid "Data management" msgid "Common data" msgstr "Adminstratio datarum" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "personae" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "Photographia" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "dies" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "tempus" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "Quis nuntium videatne?" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "Scribe nuntium:" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "Primus nomen" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "Secondus nomen" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 #, fuzzy #| msgid "E-mail address" msgid "A person is using this e-mail address" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 #, fuzzy #| msgid "Who should see the announcement?" msgid "Who should get the permission?" msgstr "Quis nuntium videatne?" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 #, fuzzy #| msgid "E-mail address" msgid "Address data" msgstr "Inscriptio electronica" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 #, fuzzy #| msgid "Additional name(s)" msgid "Additional data" msgstr "addita nomines" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 #, fuzzy #| msgid "Data management" msgid "Account data" msgstr "Adminstratio datarum" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "" @@ -347,837 +337,885 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 #, fuzzy #| msgid "Edit school term" msgid "Linked school term" msgstr "Muta anum scolae" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "Dies et hora" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 #, fuzzy #| msgid "E-mail address" msgid "IP address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "Nomen" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "ani scolae" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "Persona" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 #, fuzzy #| msgid "E-mail address" msgid "Can view address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 #, fuzzy #| msgid "E-mail address" msgid "Can view contact details" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 #, fuzzy #| msgid "E-mail address" msgid "Can view photo" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 #, fuzzy #| msgid "E-mail address" msgid "Can view avatar image" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 #, fuzzy #| msgid "Persons and accounts" msgid "Can view persons groups" msgstr "Personae et computi" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 #, fuzzy #| msgid "Stop impersonation" msgid "Can view personal details" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "femininum" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "maskulinum" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "addita nomines" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "Breve nomen" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "Via" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "Numerus domini" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "Numerus directorius" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "Urbs" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "Numerus telephoni domi" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "Numerus telephoni mobilis" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "Dies natalis" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 #, fuzzy #| msgid "Date of birth" msgid "Place of birth" msgstr "Dies natalis" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "Genus" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "Parentes" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "Descriptio" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 #, fuzzy #| msgid "Persons and accounts" msgid "Can view statistics about group." msgstr "Personae et computi" -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 #, fuzzy #| msgid "Last name" msgid "Long name" msgstr "Secondus nomen" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Titulus" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "Mittens" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Nota" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 #, fuzzy #| msgid "Notification" msgid "Send notification at" msgstr "Nuntius" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "" + +#: aleksis/core/models.py:752 #, fuzzy #| msgid "Notifications" msgid "Notification" msgstr "Nuntii" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "Nuntii" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 #, fuzzy #| msgid "Announcements" msgid "Announcement" msgstr "Nuntii" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "Nuntii" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 #, fuzzy #| msgid "Announcements" msgid "Announcement recipient" msgstr "Nuntii" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 #, fuzzy #| msgid "Announcements" msgid "Announcement recipients" msgstr "Nuntii" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 #, fuzzy #| msgid "Site title" msgid "Widget Title" msgstr "Titulus paginae" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 #, fuzzy #| msgid "Site title" msgid "Widget is broken" msgstr "Titulus paginae" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 #, fuzzy #| msgid "Dashboard" msgid "Can edit default dashboard" msgstr "Forum" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 #, fuzzy #| msgid "Dashboard" msgid "Dashboard Widget" msgstr "Forum" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 #, fuzzy #| msgid "Dashboard" msgid "Dashboard Widgets" msgstr "Forum" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 #, fuzzy #| msgid "Icon" msgid "Icon URL" msgstr "Nota" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget" msgstr "Forum" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget order" msgstr "Forum" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 #, fuzzy #| msgid "Dashboard" msgid "Dashboard widget orders" msgstr "Forum" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 #, fuzzy #| msgid "Persons" msgid "Personal details" msgstr "personae" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 #, fuzzy #| msgid "E-mail address" msgid "Contact details" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 #, fuzzy #| msgid "Group" msgid "Group type" msgstr "Grex" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 #, fuzzy #| msgid "Groups" msgid "Group types" msgstr "Greges" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 #, fuzzy #| msgid "System status" msgid "Can view system status" msgstr "Status systemae" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 #, fuzzy #| msgid "Data management" msgid "Can manage data" msgstr "Adminstratio datarum" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 #, fuzzy #| msgid "Stop impersonation" msgid "Can impersonate" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 #, fuzzy #| msgid "Stop impersonation" msgid "Can invite persons" msgstr "Simulandum aliquem finire" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 #, fuzzy #| msgid "Notifications" msgid "Notification sent" msgstr "Nuntii" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 #, fuzzy #| msgid "E-mail address" msgid "E-Mail address" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 #, fuzzy #| msgid "Icon" msgid "Back URL" msgstr "Nota" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button title" msgstr "addita nomines" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button URL" msgstr "addita nomines" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 #, fuzzy #| msgid "Additional name(s)" msgid "Additional button icon" msgstr "addita nomines" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 #, fuzzy #| msgid "Additional name(s)" msgid "Additional attributes" msgstr "addita nomines" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 #, fuzzy #| msgid "E-mail address" msgid "Can view room timetable" msgstr "Inscriptio electronica" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 #, fuzzy #| msgid "Date and time" msgid "Start date and time" msgstr "Dies et hora" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 #, fuzzy #| msgid "Date and time" msgid "End date and time" msgstr "Dies et hora" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 #, fuzzy #| msgid "Time" msgid "Timezone" msgstr "tempus" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 #, fuzzy #| msgid "Persons" msgid "Personal events" msgstr "personae" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 #, fuzzy #| msgid "Notifications" msgid "Location" msgstr "Nuntii" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 #, fuzzy #| msgid "Group" msgid "Related group" msgstr "Grex" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 #, fuzzy #| msgid "Impersonation" msgid "Organisation" msgstr "Simulare aliquem" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 #, fuzzy #| msgid "Impersonation" msgid "Organisations" msgstr "Simulare aliquem" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +#, fuzzy +#| msgid "Notifications" +msgid "Action" +msgstr "Nuntii" + +#: aleksis/core/models.py:2017 +#, fuzzy +#| msgid "Notification" +msgid "Send notifications" +msgstr "Nuntius" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "" + +#: aleksis/core/models.py:2140 +#, fuzzy +#| msgid "Persons" +msgid "Personal event alarm" +msgstr "personae" + +#: aleksis/core/models.py:2141 +#, fuzzy +#| msgid "Persons" +msgid "Personal event alarms" +msgstr "personae" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "" @@ -1404,46 +1442,82 @@ msgstr "" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "Britannicus" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "Germanus" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 #, fuzzy #| msgid "Notifications" @@ -1924,22 +1998,6 @@ msgstr "Forum" msgid "Edit group" msgstr "" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "" @@ -2424,6 +2482,11 @@ msgid "" " " msgstr "" +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "Quaerere" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "" @@ -2990,11 +3053,11 @@ msgstr "" msgid "This username is not allowed." msgstr "" -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "" @@ -3018,131 +3081,131 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 #, fuzzy #| msgid "System status" msgid "Run data checks …" msgstr "Status systemae" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 msgid "Person was already invited." msgstr "" diff --git a/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/core/locale/nb_NO/LC_MESSAGES/django.po index add3eaa2d5f6eb6f504d4065087d46cc29b7f7e0..6da342f356a37e9f98b071eb971832bbc8eae54f 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: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\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,10 +41,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "" @@ -98,199 +96,191 @@ msgstr "" msgid "There was a non-unique email address." msgstr "" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "" @@ -314,739 +304,779 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 msgid "Personal details" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 msgid "Personal events" msgstr "" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 msgid "Related group" msgstr "" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +msgid "Action" +msgstr "" + +#: aleksis/core/models.py:2017 +msgid "Send notifications" +msgstr "" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "" + +#: aleksis/core/models.py:2140 +msgid "Personal event alarm" +msgstr "" + +#: aleksis/core/models.py:2141 +msgid "Personal event alarms" +msgstr "" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "" @@ -1255,46 +1285,82 @@ msgstr "" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "" @@ -1741,22 +1807,6 @@ msgstr "" msgid "Edit group" msgstr "" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "" @@ -2208,6 +2258,11 @@ msgid "" " " msgstr "" +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "" @@ -2758,11 +2813,11 @@ msgstr "" msgid "This username is not allowed." msgstr "" -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "" @@ -2786,129 +2841,129 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 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 484afef140a8ab77f8a002e09250147ce5c39f20..dd47ad4c961409f04421a0d7d49211c701e3a149 100644 --- a/aleksis/core/locale/ru/LC_MESSAGES/django.po +++ b/aleksis/core/locale/ru/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\n" "PO-Revision-Date: 2023-08-12 09:43+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" "Language-Team: Russian <https://translate.edugit.org/projects/aleksis/aleksis-core/ru/>\n" @@ -42,10 +42,8 @@ msgstr "ÐÐ´Ñ€ÐµÑ Ñл.почты" msgid "Home and mobile phone" msgstr "Домашний и мобильный телефоны" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "Группы" @@ -110,199 +108,191 @@ msgstr "" msgid "There was a non-unique email address." msgstr "Подтвердите Ñвой Ð°Ð´Ñ€ÐµÑ Ñл.почты" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "ПоиÑк" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "ПоиÑк по имени" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "ПоиÑк по контактным данным" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "Разрешение" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "Тип Ñодержимого" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "Пользователь" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "Группа" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "ОÑновные данные" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "ÐдреÑ" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "Контактные данные" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "Дополнительные личные данные" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "Ðовый пользователь" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "Создать новую учётную запиÑÑŒ" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "ПоÑле выбора ÑущеÑтвующего Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñоздать новый логин нельзÑ." -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Ðтот логин уже занÑÑ‚." -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "Учебный год" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "Общие данные" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "Люди" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "Фото" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "Дата" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "ВремÑ" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "С какого и по какое Ð²Ñ€ÐµÐ¼Ñ Ñто объÑвление должно отображатьÑÑ?" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "Кто должен видеть Ñто объÑвление?" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "Ðапишите Ñвое объÑвление:" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "ОбъÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð¾Ð³Ð¾ Вам Ñоздавать не разрешено." -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "Дата и Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° должны быть до даты и времени окончаниÑ." -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "Ðужен Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один получатель." -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "Код приглашениÑ" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "Укажите, пожалуйÑта, код приглашениÑ." -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "ИмÑ" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "ФамилиÑ" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "Ðтот Ñл.Ð°Ð´Ñ€ÐµÑ ÐºÐµÐ¼-то иÑпользуетÑÑ" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "Кто должен получить такое разрешение?" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "Ð’ Ñлучае чего?" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "Отметьте объекты, к которым будет предоÑтавлен доÑтуп:" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "ПредоÑтавить доÑтуп ко вÑем объектам" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "Вам нужно выбрать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одну группу или физлицо, кто получит доÑтуп." -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "Ð’Ñ‹ должны предоÑтавить доÑтуп ко вÑем или к конкретным объектам." -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "ПодробноÑти адреÑа" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "Дополнительные данные" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "Данные учётной запиÑи" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "Пароль" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "Пароль (ещё раз)" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "Выбранное дейÑтвие не ÑущеÑтвует." -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "У Ð’Ð°Ñ Ð½ÐµÑ‚ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° запуÑк {} на вÑех выбранных объектах." -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "Ðеправильный выбор." @@ -326,755 +316,807 @@ msgstr "Ð ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð½Ðµ найдена!" msgid "No backup result found!" msgstr "Результат резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ найден!" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "СвÑзанный учебный год" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "Булево (Да/Ðет)" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "ТекÑÑ‚ (одна Ñтрока)" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "Дата и времÑ" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "ДеÑÑтичное чиÑло" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "ÐÐ´Ñ€ÐµÑ Ñл.почты" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "Целое" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "IP адреÑ" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Булево или пуÑтое (Да/Ðет/Ðичего)" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "ТекÑÑ‚ (многоÑтрочный)" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "URL / СÑылка" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "Полное имÑ" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "Дата начала" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "Дата окончаниÑ" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "Дата начала должна быть ранее даты окончаниÑ." -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "Ðа Ñто Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð»Ð¸ на его чаÑть уже запланирован учебный год." -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "Учебный год" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "Физлицо" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "Может видеть адреÑ" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "Может видеть контактные данные" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "Может видеть фото" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "Может видеть аватар" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "Может видеть группы лиц" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "Может видеть личные данные" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "жен" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "муж" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "другой" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "СвÑзанный пользователь" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "Дополнительные имена" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "Короткое имÑ" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "Улица" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "Ðомер дома" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "Почтовый индекÑ" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "Город/меÑто" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "Домашний телефон" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "Мобильный телефон" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "Дата рождениÑ" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "МеÑто рождениÑ" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "Пол" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "Ðто официальное фото, которое иÑпользуетÑÑ Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð² и внутренних нужд." -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "Отобразить фото/аватар" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "Ðто фото или аватар Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ отображениÑ." -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "Опекуны / Родители" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "ОпиÑание" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "Может определÑть дочерние группы в группы" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "Может видеть ÑтатиÑтику группы." -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "Длинное имÑ" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "УчаÑтники" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "Владельцы" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "РодительÑкие группы" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "Тип группы" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Ðазвание" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "Приложение" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "ÐктивноÑть" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "ÐктивноÑти" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "Отправитель" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "Получатель" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "СÑылка" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Иконка" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "Отправить уведомление в" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "Читать" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "Отправлено" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +#, fuzzy +#| msgid "Calendar" +msgid "Calendar alarm" +msgstr "Календарь" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "Уведомление" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "УведомлениÑ" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "СÑылка на подробный обзор" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "Дата и времÑ, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ показывать" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "Дата и времÑ, по какое показывать" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "ОбъÑвление" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "ОбъÑвление" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "Получатель объÑвлениÑ" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "Получатели объÑвлениÑ" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "Ðазвание виджета" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "Ðктивировать виджет" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "Виджет поломалÑÑ" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "Размер на мобильных" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "<= 600 пикÑ, 12 Ñтолбцов" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "Размер на планшетах" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "> 600 пикÑ, 12 Ñтолбцов" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "Размер на ПК" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "> 992 пикÑ, 12 Ñтолбцов" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "Размер Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… Ñкранов" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "> 1200 пикÑ, 12 Ñтолбцов" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "Может редактировать типовую/Ñтандартную информпанель" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "Виджет информпанели" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "Виджеты информпанели" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "URL" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "Иконка URL" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "ВнешнÑÑ ÑÑылка на виджет" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "Внешние ÑÑылки на виджеты" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "Содержимое" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "Виджет Ñ Ð¿Ð¾ÑтоÑнным Ñодержимым" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "Виджеты Ñ Ð¿Ð¾ÑтоÑнным Ñодержимым" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "Виджет информпанели" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "ПорÑдок" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "ЧаÑть типовой информпанели" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "ПорÑдок виджета на информпанели" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "ПорÑдок виджетов на информпанели" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "Меню ID" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "ПользовательÑкое меню" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "ПользовательÑкие меню" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "Меню" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "Пункт пользовательÑкого меню" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "Пункты пользовательÑкого меню" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "Ðазвание типа" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 #, fuzzy #| msgid "Personal Calendar URLs" msgid "Personal details" msgstr "URL-ÑÑылка ÑобÑтвенных календарей" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "Контактные данные" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "Ðватар" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "Тип группы" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "Типы групп" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "Может проÑматривать ÑоÑтоÑние ÑиÑтемы" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "Может управлÑть данными" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "Может маÑкироватьÑÑ" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "Может иÑпользовать поиÑк" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "Может менÑть ÑвойÑтва Ñайта" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "Может менÑть перÑональные ÑвойÑтва" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "Может менÑть ÑвойÑтва группы" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "Может генерировать теÑтовые PDF" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "Может приглашать других" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 #, fuzzy #| msgid "Birthday Calendar" msgid "Can view birthday calendar" msgstr "Календарь Дней РождениÑ" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "Задание проверки ÑвÑзанных данных" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "Проблема решена" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "Уведомление отправлено" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "Результат проверки данных" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "Результаты проверки данных" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "Может запуÑкать проверки данных" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "Может решать проблемы проверки данных" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "ÐÐ´Ñ€ÐµÑ Ñл.почты" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "Владелец" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "Файл дейÑтвителен до" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "Сгенерированный файл HTML" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "Сгенерированный файл PDF" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "Файл PDF" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "Файлы PDF" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "Результат заданиÑ" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "Пользователь заданиÑ" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "URL Ð´Ð»Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‚Ð°" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "Ðазвание процеÑÑа" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "Сообщение об ошибке" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "Сообщение об уÑпехе" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "URL Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² Ñлучае уÑпеха" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "Ðазвание дополнительной кнопки" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "URL дополнительной кнопки" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "Иконка дополнительной кнопки" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "Полученный результат" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "Фоновое задание уÑпешно завершено" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "Фоновое задание \"{}\" уÑпешно завершено." -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "Ошибка фонового заданиÑ" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "Ошибка фонового Ð·Ð°Ð´Ð°Ð½Ð¸Ñ \"{}\"." -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "Фоновое задание" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "Ðазначение Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ заданиÑ" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "Дополнительные атрибуты" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "Разрешённые пределы дейÑтвиÑ, которые могут запрашивать клиенты" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "Ðто изображение будет иÑпользоватьÑÑ Ð² качеÑтве значка во Ð²Ñ€ÐµÐ¼Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸. Должно быть квадратным." -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "Может проÑмативать раÑпиÑание комнаты" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "Комната" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "Комнаты" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "Дата и Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "Дата и Ð²Ñ€ÐµÐ¼Ñ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "ЧаÑовой поÑÑ" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "Повторы" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "ИÑправлено оÑновное Ñобытие" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "Календарное Ñобытие" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "Календарные ÑобытиÑ" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "Дни РождениÑ" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "{} отмечает День РождениÑ" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "Выходные" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "Выходной" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 #, fuzzy #| msgid "Birthday Calendar" msgid "Can view holiday calendar" msgstr "Календарь Дней РождениÑ" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 #, fuzzy #| msgid "Personal Calendar URLs" msgid "Personal events" msgstr "URL-ÑÑылка ÑобÑтвенных календарей" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 #, fuzzy #| msgid "Notification" msgid "Location" msgstr "Уведомление" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 #, fuzzy #| msgid "Create group" msgid "Related group" msgstr "Создать группу" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 #, fuzzy #| msgid "Internationalisation" msgid "Organisation" msgstr "ИнтернационализациÑ" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 #, fuzzy #| msgid "Invitations" msgid "Organisations" msgstr "ПриглашениÑ" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +#, fuzzy +#| msgid "Actions" +msgid "Action" +msgstr "ДейÑтвиÑ" + +#: aleksis/core/models.py:2017 +#, fuzzy +#| msgid "Send notification at" +msgid "Send notifications" +msgstr "Отправить уведомление в" + +#: aleksis/core/models.py:2131 +#, fuzzy +#| msgid "Calendar" +msgid "Calendar alarms" +msgstr "Календарь" + +#: aleksis/core/models.py:2140 +#, fuzzy +#| msgid "Personal Calendar URLs" +msgid "Personal event alarm" +msgstr "URL-ÑÑылка ÑобÑтвенных календарей" + +#: aleksis/core/models.py:2141 +#, fuzzy +#| msgid "Personal Calendar URLs" +msgid "Personal event alarms" +msgstr "URL-ÑÑылка ÑобÑтвенных календарей" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "Общее" @@ -1283,50 +1325,88 @@ msgstr "ÐвтоматичеÑки обновлÑть информпанель msgid "Automatically update the dashboard and its widgets sitewide" msgstr "ÐвтоматичеÑки обновлÑть информпанель и её виджеты (Ð´Ð»Ñ Ð²Ñего Ñайта)" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +#, fuzzy +#| msgid "Holiday" +msgid "Friday" +msgstr "Выходной" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "Цвет ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð”Ð½ÐµÐ¹ РождениÑ" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "Цвет ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð’Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ñ…" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 #, fuzzy #| msgid "Holiday calendar feed color" msgid "Personal events feed color" msgstr "Цвет ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð’Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ñ…" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "Ðктивные календари" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 #, fuzzy #| msgid "Regular expression for allowed usernames" msgid "Comma-separated list of disallowed usernames" msgstr "РегулÑрное выражение Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÑ‘Ð½Ð½Ñ‹Ñ… логинов" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "ÐнглийÑкий" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "Ðемецкий" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "УкраинÑкий" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "Удалить" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "ДейÑтвиÑ" @@ -1846,22 +1926,6 @@ msgstr "Ð¢Ð¸Ð¿Ð¾Ð²Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð¿Ð°Ð½ÐµÐ»ÑŒ" msgid "Edit group" msgstr "Редактировать группу" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "Создать группу" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "Фильтровать группы" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "ОчиÑтить" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "Выбранные группы" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "Домой" @@ -2357,6 +2421,11 @@ msgstr "" " ЕÑли интернет работает и ошибка вÑÑ‘ равно приÑутÑтвует, обратитеÑÑŒ, пожалуйÑта, к ÑиÑтемным админиÑтраторам:\n" " " +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "ПоиÑк" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "Глобальный поиÑк" @@ -3027,11 +3096,11 @@ msgstr "Отключить" msgid "This username is not allowed." msgstr "Ðтот логин уже занÑÑ‚." -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "Ðл.почта" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "СМС" @@ -3055,132 +3124,144 @@ msgstr "Во Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° PDF возникла про msgid "Download PDF" msgstr "Скачать PDF" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "Физлицо Ñохранено." -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "Группа Ñохранена." -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "Режим обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑƒÑпешно активирован." -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "Режим обÑÐ»ÑƒÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑƒÑпешно выключен." -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "ОбъÑвление Ñохранено." -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "ОбъÑвление удалено." -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "Журнал Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ‹Ð¼Ð¸ ÑвойÑтвами не ÑущеÑтвует" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "СвойÑтва Ñохранены." -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "Группа удалена." -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "Ð’ процеÑÑе: ЗапуÑк проверки данных" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "ЗапуÑкаетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ° данных …" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "Проверка данных уÑпешно запущена." -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "Во Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿ÑƒÑка проверки данных возникла проблема." -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "Вариант Ñ€ÐµÑˆÐµÐ½Ð¸Ñ \"{solve_option_obj.verbose_name}\" " -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "Запрошенный вариант Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ðµ ÑущеÑтвует" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "Виджет информпанели Ñохранён." -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "Виджет информпанели Ñоздан." -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "Виджет информпанели удалён." -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "Ваша ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð¿Ð°Ð½ÐµÐ»Ð¸ Ñохранена." -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð¹/Ñтандартной информпанели." -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "Приглашение уÑпешно Ñоздано. Код приглашениÑ: {code}" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "Мы уÑпешно назначили доÑтупы." -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "Глобальный пользовательÑкий доÑтуп удалён." -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "Глобальный групповой доÑтуп удалён." -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "Объектный пользовательÑкий доÑтуп удалён." -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "Объектный групповой доÑтуп удалён." -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "Учётную запиÑÑŒ третьей Ñтороны Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ, Ñ‚.к. Ñто единÑтвенный ÑпоÑоб входа." -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ третьей Ñтороны уÑпешно отключена." -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "Владелец указанного Ñл.адреÑа уÑпешно приглашён. ИнÑтрукции о дальнейших дейÑтвиÑÑ… отправлены на Ñл.почту." -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 msgid "Person was already invited." msgstr "Кто-то уже приглаÑил его/её." +#~ msgid "Create group" +#~ msgstr "Создать группу" + +#~ msgid "Filter groups" +#~ msgstr "Фильтровать группы" + +#~ msgid "Clear" +#~ msgstr "ОчиÑтить" + +#~ msgid "Selected groups" +#~ msgstr "Выбранные группы" + #~ msgid "Assign child groups to groups" #~ msgstr "Определить дочерние группы к группе" diff --git a/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/core/locale/tr_TR/LC_MESSAGES/django.po index d0b7ea7cafb46c09c643f3d2093b261cd7b695f2..42ede65bb7463c988d4d183a1a1f830d4c9d1eaa 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: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\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,10 +41,8 @@ msgstr "" msgid "Home and mobile phone" msgstr "" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "" @@ -98,199 +96,191 @@ msgstr "" msgid "There was a non-unique email address." msgstr "" -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "" -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "" -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "" -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "" -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "" -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "" -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "" -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "" -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "" -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "" -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "" @@ -314,739 +304,779 @@ msgstr "" msgid "No backup result found!" msgstr "" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "" -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "" -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "" -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "" -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "" -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +msgid "Calendar alarm" +msgstr "" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 msgid "Personal details" msgstr "" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "" -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "" -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "" -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 msgid "Personal events" msgstr "" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 msgid "Related group" msgstr "" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +msgid "Action" +msgstr "" + +#: aleksis/core/models.py:2017 +msgid "Send notifications" +msgstr "" + +#: aleksis/core/models.py:2131 +msgid "Calendar alarms" +msgstr "" + +#: aleksis/core/models.py:2140 +msgid "Personal event alarm" +msgstr "" + +#: aleksis/core/models.py:2141 +msgid "Personal event alarms" +msgstr "" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "" @@ -1255,46 +1285,82 @@ msgstr "" msgid "Automatically update the dashboard and its widgets sitewide" msgstr "" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +msgid "Friday" +msgstr "" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "" @@ -1741,22 +1807,6 @@ msgstr "" msgid "Edit group" msgstr "" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "" @@ -2208,6 +2258,11 @@ msgid "" " " msgstr "" +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "" @@ -2758,11 +2813,11 @@ msgstr "" msgid "This username is not allowed." msgstr "" -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "" @@ -2786,128 +2841,128 @@ msgstr "" msgid "Download PDF" msgstr "" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "" -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "" -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "" -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "" -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "" -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "" -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "" -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "" -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "" -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "" -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "" -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "" -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "" -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "" -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "" -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "" -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "" -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "" -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "" -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "" -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "" -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "" -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "" -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "" -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 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 1bdaa62464e777fca04ad1537580c7e0cc508125..e50d207a27f0890617bacf28e1da7832268d857b 100644 --- a/aleksis/core/locale/uk/LC_MESSAGES/django.po +++ b/aleksis/core/locale/uk/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-15 15:50+0200\n" +"POT-Creation-Date: 2025-01-14 18:15+0100\n" "PO-Revision-Date: 2024-08-29 08:21+0000\n" "Last-Translator: Serhii Horichenko <m@sgg.im>\n" "Language-Team: Ukrainian <https://translate.edugit.org/projects/aleksis/aleksis-core/uk/>\n" @@ -42,10 +42,8 @@ msgstr "Ел.адреÑа" msgid "Home and mobile phone" msgstr "Домашній та мобільний телефони" -#: aleksis/core/apps.py:182 aleksis/core/forms.py:222 -#: aleksis/core/models.py:479 aleksis/core/models.py:1089 -#: aleksis/core/templates/core/group/list.html:8 -#: aleksis/core/templates/core/group/list.html:9 +#: aleksis/core/apps.py:182 aleksis/core/forms.py:223 +#: aleksis/core/models.py:495 aleksis/core/models.py:1121 msgid "Groups" msgstr "Групи" @@ -99,199 +97,191 @@ msgstr "ПереконайтеÑÑ, що е-адреÑи Ð´Ð»Ñ Ð²ÑÑ–Ñ… Ñ” ун msgid "There was a non-unique email address." msgstr "Знайдені неунікальні е-адреÑи." -#: aleksis/core/filters.py:39 aleksis/core/templates/core/group/list.html:20 -#: aleksis/core/templates/search/search.html:7 -#: aleksis/core/templates/search/search.html:22 -msgid "Search" -msgstr "Пошук" - -#: aleksis/core/filters.py:56 +#: aleksis/core/filters.py:43 msgid "Search by name" msgstr "Пошук за ім'Ñм" -#: aleksis/core/filters.py:68 +#: aleksis/core/filters.py:55 msgid "Search by contact details" msgstr "Пошук за контактними даними" -#: aleksis/core/filters.py:89 +#: aleksis/core/filters.py:76 msgid "Permission" msgstr "Дозвіл" -#: aleksis/core/filters.py:97 +#: aleksis/core/filters.py:84 msgid "Content type" msgstr "Тип зміÑту" -#: aleksis/core/filters.py:110 aleksis/core/models.py:672 +#: aleksis/core/filters.py:97 aleksis/core/models.py:688 msgid "User" msgstr "КориÑтувач" -#: aleksis/core/filters.py:132 aleksis/core/models.py:478 +#: aleksis/core/filters.py:119 aleksis/core/models.py:494 msgid "Group" msgstr "Група" -#: aleksis/core/forms.py:46 aleksis/core/forms.py:556 +#: aleksis/core/forms.py:47 aleksis/core/forms.py:557 msgid "Base data" msgstr "ОÑновні дані" -#: aleksis/core/forms.py:51 aleksis/core/models.py:1085 -#: aleksis/core/tables.py:29 +#: aleksis/core/forms.py:52 aleksis/core/models.py:1117 msgid "Address" msgstr "ÐдреÑа" -#: aleksis/core/forms.py:52 aleksis/core/forms.py:565 +#: aleksis/core/forms.py:53 aleksis/core/forms.py:566 msgid "Contact data" msgstr "Контактні дані" -#: aleksis/core/forms.py:54 +#: aleksis/core/forms.py:55 msgid "Advanced personal data" msgstr "Додаткові оÑобиÑті дані" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "New user" msgstr "Ðовий кориÑтувач" -#: aleksis/core/forms.py:104 +#: aleksis/core/forms.py:105 msgid "Create a new account" msgstr "Створити новий обліковий запиÑ" -#: aleksis/core/forms.py:131 +#: aleksis/core/forms.py:132 msgid "You cannot set a new username when also selecting an existing user." msgstr "Обравши вже Ñ–Ñнуючого кориÑтувача неможливо Ñтворити новий логін." -#: aleksis/core/forms.py:135 +#: aleksis/core/forms.py:136 msgid "This username is already in use." msgstr "Такий логін вже зайнÑтий." -#: aleksis/core/forms.py:152 aleksis/core/models.py:150 +#: aleksis/core/forms.py:153 aleksis/core/models.py:163 msgid "School term" msgstr "Ðавчальний рік" -#: aleksis/core/forms.py:153 +#: aleksis/core/forms.py:154 msgid "Common data" msgstr "Загальні дані" -#: aleksis/core/forms.py:154 aleksis/core/forms.py:209 -#: aleksis/core/models.py:171 +#: aleksis/core/forms.py:155 aleksis/core/forms.py:210 +#: aleksis/core/models.py:187 msgid "Persons" msgstr "ОÑоби" -#: aleksis/core/forms.py:155 aleksis/core/models.py:227 -#: aleksis/core/models.py:532 aleksis/core/models.py:1087 -#: aleksis/core/tables.py:28 +#: aleksis/core/forms.py:156 aleksis/core/models.py:243 +#: aleksis/core/models.py:548 aleksis/core/models.py:1119 msgid "Photo" msgstr "Фото" -#: aleksis/core/forms.py:201 aleksis/core/forms.py:204 -#: aleksis/core/models.py:93 +#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 +#: aleksis/core/models.py:95 msgid "Date" msgstr "Дата" -#: aleksis/core/forms.py:202 aleksis/core/forms.py:205 -#: aleksis/core/models.py:101 +#: aleksis/core/forms.py:203 aleksis/core/forms.py:206 +#: aleksis/core/models.py:103 msgid "Time" msgstr "ЧаÑ" -#: aleksis/core/forms.py:235 +#: aleksis/core/forms.py:236 msgid "From when until when should the announcement be displayed?" msgstr "З Ñкого по Ñкий Ñ‡Ð°Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð¾ відображатиÑÑ Ñ†Ðµ оголошеннÑ?" -#: aleksis/core/forms.py:238 +#: aleksis/core/forms.py:239 msgid "Who should see the announcement?" msgstr "Хто повинен бачити це оголошеннÑ?" -#: aleksis/core/forms.py:239 +#: aleksis/core/forms.py:240 msgid "Write your announcement:" msgstr "Складіть Ñвоє оголошенÑ:" -#: aleksis/core/forms.py:240 +#: aleksis/core/forms.py:241 msgid "Set a priority" msgstr "" -#: aleksis/core/forms.py:279 +#: aleksis/core/forms.py:280 msgid "You are not allowed to create announcements which are only valid in the past." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¼Ð¸Ð½ÑƒÐ»Ð¾Ð³Ð¾ Вам Ñтворювати не дозволено." -#: aleksis/core/forms.py:283 +#: aleksis/core/forms.py:284 msgid "The from date and time must be earlier then the until date and time." msgstr "Дата Ñ– Ñ‡Ð°Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ повинні бути раніше за дату Ñ– Ñ‡Ð°Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ." -#: aleksis/core/forms.py:292 +#: aleksis/core/forms.py:293 msgid "You need at least one recipient." msgstr "Вам потрібен принаймні один отримувач." -#: aleksis/core/forms.py:386 +#: aleksis/core/forms.py:387 msgid "Invitation code" msgstr "Код запрошеннÑ" -#: aleksis/core/forms.py:387 +#: aleksis/core/forms.py:388 msgid "Please enter your invitation code." msgstr "Ðапишіть, будь лаÑка, Ñвій код запрошеннÑ." -#: aleksis/core/forms.py:394 aleksis/core/models.py:200 +#: aleksis/core/forms.py:395 aleksis/core/models.py:216 msgid "First name" msgstr "Ім'Ñ" -#: aleksis/core/forms.py:395 aleksis/core/models.py:201 +#: aleksis/core/forms.py:396 aleksis/core/models.py:217 msgid "Last name" msgstr "Прізвище" -#: aleksis/core/forms.py:404 +#: aleksis/core/forms.py:405 msgid "A person is using this e-mail address" msgstr "Цією е-адреÑою хтоÑÑŒ кориÑтуєтьÑÑ" -#: aleksis/core/forms.py:432 +#: aleksis/core/forms.py:433 msgid "Who should get the permission?" msgstr "Хто повинен отримати такий дозвіл?" -#: aleksis/core/forms.py:433 +#: aleksis/core/forms.py:434 msgid "On what?" msgstr "Ð’ разі чого?" -#: aleksis/core/forms.py:459 +#: aleksis/core/forms.py:460 msgid "Select objects which the permission should be granted for:" msgstr "Оберіть об'єкти, до Ñких буде наданий дозвіл:" -#: aleksis/core/forms.py:462 +#: aleksis/core/forms.py:463 msgid "Grant the permission for all objects" msgstr "Ðадати дозвіл до вÑÑ–Ñ… об'єктів" -#: aleksis/core/forms.py:470 +#: aleksis/core/forms.py:471 msgid "You must select at least one group or person which should get the permission." msgstr "Ви повинні обрати принаймні одну групу або оÑобу, хто буде мати дозвіл." -#: aleksis/core/forms.py:475 +#: aleksis/core/forms.py:476 msgid "You must grant the permission to all objects or to specific objects." msgstr "Ви повинні надати дозвіл до вÑÑ–Ñ… або до конкретних об'єктів." -#: aleksis/core/forms.py:561 +#: aleksis/core/forms.py:562 msgid "Address data" msgstr "Дані адреÑи" -#: aleksis/core/forms.py:567 +#: aleksis/core/forms.py:568 msgid "Additional data" msgstr "Додаткові дані" -#: aleksis/core/forms.py:573 +#: aleksis/core/forms.py:574 msgid "Account data" msgstr "Дані облікового запиÑу" -#: aleksis/core/forms.py:580 +#: aleksis/core/forms.py:581 msgid "Password" msgstr "Пароль" -#: aleksis/core/forms.py:583 +#: aleksis/core/forms.py:584 msgid "Password (again)" msgstr "Пароль (ще раз)" -#: aleksis/core/forms.py:735 +#: aleksis/core/forms.py:736 msgid "The selected action does not exist." msgstr "Обрана Ð´Ñ–Ñ Ð½Ðµ Ñ–Ñнує." -#: aleksis/core/forms.py:746 +#: aleksis/core/forms.py:747 msgid "You do not have permission to run {} on all selected objects." msgstr "У Ð’Ð°Ñ Ð²Ñ–Ð´Ñутній дозвіл на запуÑк {} на уÑÑ–Ñ… обраних об'єктах." -#: aleksis/core/forms.py:802 +#: aleksis/core/forms.py:803 msgid "No valid selection." msgstr "Ðеправильний вибір." @@ -315,741 +305,793 @@ msgstr "Резервна ÐºÐ¾Ð¿Ñ–Ñ Ð½Ðµ знайдена!" msgid "No backup result found!" msgstr "Результат резервного ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð½Ðµ знайдений!" -#: aleksis/core/mixins.py:447 +#: aleksis/core/mixins.py:449 msgid "Linked school term" msgstr "Пов'Ñзаний навчальний рік" -#: aleksis/core/models.py:91 +#: aleksis/core/models.py:93 msgid "Boolean (Yes/No)" msgstr "Логічне (Так/ÐÑ–)" -#: aleksis/core/models.py:92 +#: aleksis/core/models.py:94 msgid "Text (one line)" msgstr "ТекÑÑ‚ (один Ñ€Ñдок)" -#: aleksis/core/models.py:94 +#: aleksis/core/models.py:96 msgid "Date and time" msgstr "Дата Ñ– чаÑ" -#: aleksis/core/models.py:95 +#: aleksis/core/models.py:97 msgid "Decimal number" msgstr "ДеÑÑтичне чиÑло" -#: aleksis/core/models.py:96 aleksis/core/models.py:220 +#: aleksis/core/models.py:98 aleksis/core/models.py:236 msgid "E-mail address" msgstr "ÐдреÑа е-пошти" -#: aleksis/core/models.py:97 +#: aleksis/core/models.py:99 msgid "Integer" msgstr "Ціле" -#: aleksis/core/models.py:98 +#: aleksis/core/models.py:100 msgid "IP address" msgstr "IP адреÑа" -#: aleksis/core/models.py:99 +#: aleksis/core/models.py:101 msgid "Boolean or empty (Yes/No/Neither)" msgstr "Логічне або порожнє (Так/ÐÑ–/Ðічого)" -#: aleksis/core/models.py:100 +#: aleksis/core/models.py:102 msgid "Text (multi-line)" msgstr "ТекÑÑ‚ (багаторÑдковий)" -#: aleksis/core/models.py:102 +#: aleksis/core/models.py:104 msgid "URL / Link" msgstr "URL / ПоÑиланнÑ" -#: aleksis/core/models.py:114 aleksis/core/models.py:1036 -#: aleksis/core/models.py:1761 aleksis/core/models.py:1907 +#: aleksis/core/models.py:127 aleksis/core/models.py:1068 +#: aleksis/core/models.py:1819 aleksis/core/models.py:1970 msgid "Name" msgstr "Повне ім'Ñ" -#: aleksis/core/models.py:116 aleksis/core/models.py:1491 +#: aleksis/core/models.py:129 aleksis/core/models.py:1522 msgid "Start date" msgstr "Дата початку" -#: aleksis/core/models.py:117 aleksis/core/models.py:1492 +#: aleksis/core/models.py:130 aleksis/core/models.py:1523 msgid "End date" msgstr "Дата закінченнÑ" -#: aleksis/core/models.py:136 +#: aleksis/core/models.py:149 msgid "The start date must be earlier than the end date." msgstr "Початкова дата повинна бути раніше кінцевої дати." -#: aleksis/core/models.py:143 +#: aleksis/core/models.py:156 msgid "There is already a school term for this time or a part of this time." msgstr "Ðа цей Ñ‡Ð°Ñ Ð°Ð±Ð¾ на чаÑтину цього чаÑу вже припадає навчальний рік." -#: aleksis/core/models.py:151 +#: aleksis/core/models.py:164 msgid "School terms" msgstr "Ðавчальні роки" -#: aleksis/core/models.py:170 aleksis/core/models.py:985 +#: aleksis/core/models.py:186 aleksis/core/models.py:1017 msgid "Person" msgstr "ОÑоба" -#: aleksis/core/models.py:173 +#: aleksis/core/models.py:189 msgid "Can view address" msgstr "Може бачити адреÑу" -#: aleksis/core/models.py:174 +#: aleksis/core/models.py:190 msgid "Can view contact details" msgstr "Може бачити контактні дані" -#: aleksis/core/models.py:175 +#: aleksis/core/models.py:191 msgid "Can view photo" msgstr "Може бачити фото" -#: aleksis/core/models.py:176 +#: aleksis/core/models.py:192 msgid "Can view avatar image" msgstr "Може бачити аватар" -#: aleksis/core/models.py:177 +#: aleksis/core/models.py:193 msgid "Can view persons groups" msgstr "Може бачити групи оÑоби" -#: aleksis/core/models.py:178 +#: aleksis/core/models.py:194 msgid "Can view personal details" msgstr "Може бачити оÑобиÑті дані" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "female" msgstr "жін" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "male" msgstr "чол" -#: aleksis/core/models.py:189 +#: aleksis/core/models.py:205 msgid "other" msgstr "інший" -#: aleksis/core/models.py:197 aleksis/core/models.py:1355 +#: aleksis/core/models.py:213 aleksis/core/models.py:1386 msgid "Linked user" msgstr "Пов'Ñзаний кориÑтувач" -#: aleksis/core/models.py:203 +#: aleksis/core/models.py:219 msgid "Additional name(s)" msgstr "Додаткові імена" -#: aleksis/core/models.py:207 aleksis/core/models.py:497 -#: aleksis/core/models.py:1447 +#: aleksis/core/models.py:223 aleksis/core/models.py:513 +#: aleksis/core/models.py:1478 msgid "Short name" msgstr "Коротке ім'Ñ" -#: aleksis/core/models.py:212 +#: aleksis/core/models.py:228 msgid "Street" msgstr "ВулицÑ" -#: aleksis/core/models.py:213 +#: aleksis/core/models.py:229 msgid "Street number" msgstr "Ðомер будинку" -#: aleksis/core/models.py:214 +#: aleksis/core/models.py:230 msgid "Postal code" msgstr "Поштовий індекÑ" -#: aleksis/core/models.py:215 +#: aleksis/core/models.py:231 msgid "Place" msgstr "МіÑто" -#: aleksis/core/models.py:217 +#: aleksis/core/models.py:233 msgid "Home phone" msgstr "Домашній телефон" -#: aleksis/core/models.py:218 +#: aleksis/core/models.py:234 msgid "Mobile phone" msgstr "Мобільний телефон" -#: aleksis/core/models.py:222 +#: aleksis/core/models.py:238 msgid "Date of birth" msgstr "Дата народженнÑ" -#: aleksis/core/models.py:223 +#: aleksis/core/models.py:239 msgid "Place of birth" msgstr "МіÑце народженнÑ" -#: aleksis/core/models.py:224 +#: aleksis/core/models.py:240 msgid "Sex" msgstr "Стать" -#: aleksis/core/models.py:231 aleksis/core/models.py:536 +#: aleksis/core/models.py:247 aleksis/core/models.py:552 msgid "This is an official photo, used for official documents and for internal use cases." msgstr "Це офіційне фото, Ñке викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð² та внутрішніх потреб." -#: aleksis/core/models.py:236 aleksis/core/models.py:540 +#: aleksis/core/models.py:252 aleksis/core/models.py:556 msgid "Display picture / Avatar" msgstr "Відобразити фото/аватар" -#: aleksis/core/models.py:239 aleksis/core/models.py:543 +#: aleksis/core/models.py:255 aleksis/core/models.py:559 msgid "This is a picture or an avatar for public display." msgstr "Це фото або аватар Ð´Ð»Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ відображеннÑ." -#: aleksis/core/models.py:244 +#: aleksis/core/models.py:260 msgid "Guardians / Parents" msgstr "Опікуни / батьки" -#: aleksis/core/models.py:251 +#: aleksis/core/models.py:267 msgid "Primary group" msgstr "Первинна група" -#: aleksis/core/models.py:254 aleksis/core/models.py:676 -#: aleksis/core/models.py:700 aleksis/core/models.py:795 -#: aleksis/core/models.py:1070 aleksis/core/models.py:1820 +#: aleksis/core/models.py:270 aleksis/core/models.py:692 +#: aleksis/core/models.py:716 aleksis/core/models.py:827 +#: aleksis/core/models.py:1102 aleksis/core/models.py:1878 msgid "Description" msgstr "ОпиÑ" -#: aleksis/core/models.py:481 +#: aleksis/core/models.py:497 msgid "Can assign child groups to groups" msgstr "Може призначати підлеглі групи до груп" -#: aleksis/core/models.py:482 +#: aleksis/core/models.py:498 msgid "Can view statistics about group." msgstr "Може бачити ÑтатиÑтику групи." -#: aleksis/core/models.py:495 aleksis/core/models.py:1448 +#: aleksis/core/models.py:511 aleksis/core/models.py:1479 msgid "Long name" msgstr "Повна назва" -#: aleksis/core/models.py:508 +#: aleksis/core/models.py:524 msgid "Members" msgstr "УчаÑники" -#: aleksis/core/models.py:511 +#: aleksis/core/models.py:527 msgid "Owners" msgstr "ВлаÑники" -#: aleksis/core/models.py:518 +#: aleksis/core/models.py:534 msgid "Parent groups" msgstr "БатьківÑькі групи" -#: aleksis/core/models.py:526 +#: aleksis/core/models.py:542 msgid "Type of group" msgstr "Тип групи" -#: aleksis/core/models.py:675 aleksis/core/models.py:699 -#: aleksis/core/models.py:794 aleksis/core/models.py:1272 -#: aleksis/core/models.py:1819 +#: aleksis/core/models.py:691 aleksis/core/models.py:715 +#: aleksis/core/models.py:826 aleksis/core/models.py:1304 +#: aleksis/core/models.py:1877 #: aleksis/core/templates/core/announcement/list.html:18 msgid "Title" msgstr "Ðазва" -#: aleksis/core/models.py:678 +#: aleksis/core/models.py:694 msgid "Application" msgstr "Додаток" -#: aleksis/core/models.py:684 +#: aleksis/core/models.py:700 msgid "Activity" msgstr "ÐктивніÑть" -#: aleksis/core/models.py:685 +#: aleksis/core/models.py:701 msgid "Activities" msgstr "ÐктивноÑті" -#: aleksis/core/models.py:691 +#: aleksis/core/models.py:707 msgid "Sender" msgstr "Відправник" -#: aleksis/core/models.py:696 +#: aleksis/core/models.py:712 msgid "Recipient" msgstr "Отримувач" -#: aleksis/core/models.py:701 aleksis/core/models.py:1037 +#: aleksis/core/models.py:717 aleksis/core/models.py:1069 msgid "Link" msgstr "ПоÑиланнÑ" -#: aleksis/core/models.py:704 aleksis/core/models.py:1038 -#: aleksis/core/models.py:1405 +#: aleksis/core/models.py:720 aleksis/core/models.py:1070 +#: aleksis/core/models.py:1436 #: aleksis/core/templates/oauth2_provider/application/detail.html:26 msgid "Icon" msgstr "Піктограма" -#: aleksis/core/models.py:707 +#: aleksis/core/models.py:723 msgid "Send notification at" msgstr "ÐадіÑлати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾" -#: aleksis/core/models.py:709 +#: aleksis/core/models.py:725 msgid "Read" msgstr "Читати" -#: aleksis/core/models.py:710 +#: aleksis/core/models.py:726 msgid "Sent" msgstr "ÐадіÑлано" -#: aleksis/core/models.py:727 +#: aleksis/core/models.py:731 aleksis/core/models.py:2130 +#, fuzzy +#| msgid "Calendar" +msgid "Calendar alarm" +msgstr "Календар" + +#: aleksis/core/models.py:752 msgid "Notification" msgstr "СповіщеннÑ" -#: aleksis/core/models.py:728 aleksis/core/preferences.py:29 +#: aleksis/core/models.py:753 aleksis/core/preferences.py:29 msgid "Notifications" msgstr "СповіщеннÑ" -#: aleksis/core/models.py:796 +#: aleksis/core/models.py:828 msgid "Link to detailed view" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° детальний переглÑд" -#: aleksis/core/models.py:797 +#: aleksis/core/models.py:829 msgid "Priority" msgstr "" -#: aleksis/core/models.py:800 +#: aleksis/core/models.py:832 msgid "Date and time from when to show" msgstr "Дата Ñ– чаÑ, з Ñкого показувати" -#: aleksis/core/models.py:803 +#: aleksis/core/models.py:835 msgid "Date and time until when to show" msgstr "Дата Ñ– чаÑ, до Ñкого показувати" -#: aleksis/core/models.py:828 +#: aleksis/core/models.py:860 msgid "Announcement" msgstr "ОголошеннÑ" -#: aleksis/core/models.py:829 +#: aleksis/core/models.py:861 #: aleksis/core/templates/core/announcement/list.html:7 #: aleksis/core/templates/core/announcement/list.html:8 msgid "Announcements" msgstr "ОголошеннÑ" -#: aleksis/core/models.py:872 +#: aleksis/core/models.py:904 msgid "Announcement recipient" msgstr "Отримувач оголошеннÑ" -#: aleksis/core/models.py:873 +#: aleksis/core/models.py:905 msgid "Announcement recipients" msgstr "Отримувачі оголошеннÑ" -#: aleksis/core/models.py:893 +#: aleksis/core/models.py:925 msgid "Widget Title" msgstr "Ðазва віджета" -#: aleksis/core/models.py:894 +#: aleksis/core/models.py:926 msgid "Activate Widget" msgstr "Ðктивувати віджет" -#: aleksis/core/models.py:895 +#: aleksis/core/models.py:927 msgid "Widget is broken" msgstr "Віджет зламавÑÑ" -#: aleksis/core/models.py:898 +#: aleksis/core/models.py:930 msgid "Size on mobile devices" msgstr "Розмір на мобільних" -#: aleksis/core/models.py:899 +#: aleksis/core/models.py:931 msgid "<= 600 px, 12 columns" msgstr "<= 600 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:904 +#: aleksis/core/models.py:936 msgid "Size on tablet devices" msgstr "Розмір на планшетах" -#: aleksis/core/models.py:905 +#: aleksis/core/models.py:937 msgid "> 600 px, 12 columns" msgstr "> 600 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:910 +#: aleksis/core/models.py:942 msgid "Size on desktop devices" msgstr "Розмір на ПК" -#: aleksis/core/models.py:911 +#: aleksis/core/models.py:943 msgid "> 992 px, 12 columns" msgstr "> 992 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:916 +#: aleksis/core/models.py:948 msgid "Size on large desktop devices" msgstr "Розмір на великих екранах" -#: aleksis/core/models.py:917 +#: aleksis/core/models.py:949 msgid "> 1200 px>, 12 columns" msgstr "> 1200 пікÑ, 12 Ñтовпчиків" -#: aleksis/core/models.py:948 +#: aleksis/core/models.py:980 msgid "Can edit default dashboard" msgstr "Може редагувати типову/Ñтандартну інформпанель" -#: aleksis/core/models.py:949 +#: aleksis/core/models.py:981 msgid "Dashboard Widget" msgstr "Віджет інформпанелі" -#: aleksis/core/models.py:950 +#: aleksis/core/models.py:982 msgid "Dashboard Widgets" msgstr "Віджети інформпанелі" -#: aleksis/core/models.py:956 +#: aleksis/core/models.py:988 msgid "URL" msgstr "URL" -#: aleksis/core/models.py:957 +#: aleksis/core/models.py:989 msgid "Icon URL" msgstr "Піктограма URL" -#: aleksis/core/models.py:963 +#: aleksis/core/models.py:995 msgid "External link widget" msgstr "Зовнішнє поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° віджет" -#: aleksis/core/models.py:964 +#: aleksis/core/models.py:996 msgid "External link widgets" msgstr "Зовнішні поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° віджети" -#: aleksis/core/models.py:970 +#: aleksis/core/models.py:1002 msgid "Content" msgstr "ЗміÑÑ‚" -#: aleksis/core/models.py:976 +#: aleksis/core/models.py:1008 msgid "Static content widget" msgstr "Віджет з поÑтійним зміÑтом" -#: aleksis/core/models.py:977 +#: aleksis/core/models.py:1009 msgid "Static content widgets" msgstr "Віджети з поÑтійним зміÑтом" -#: aleksis/core/models.py:982 +#: aleksis/core/models.py:1014 msgid "Dashboard widget" msgstr "Віджет інформпанелі" -#: aleksis/core/models.py:987 +#: aleksis/core/models.py:1019 msgid "Order" msgstr "ПорÑдок" -#: aleksis/core/models.py:988 +#: aleksis/core/models.py:1020 msgid "Part of the default dashboard" msgstr "ЧаÑтина типової інформпанелі" -#: aleksis/core/models.py:1003 +#: aleksis/core/models.py:1035 msgid "Dashboard widget order" msgstr "ПорÑдок віджету на інформпанелі" -#: aleksis/core/models.py:1004 +#: aleksis/core/models.py:1036 msgid "Dashboard widget orders" msgstr "ПорÑдок віджетів на інформпанелі" -#: aleksis/core/models.py:1010 +#: aleksis/core/models.py:1042 msgid "Menu ID" msgstr "Меню ID" -#: aleksis/core/models.py:1023 +#: aleksis/core/models.py:1055 msgid "Custom menu" msgstr "КориÑтувацьке меню" -#: aleksis/core/models.py:1024 +#: aleksis/core/models.py:1056 msgid "Custom menus" msgstr "КориÑтувацькі меню" -#: aleksis/core/models.py:1034 +#: aleksis/core/models.py:1066 msgid "Menu" msgstr "Меню" -#: aleksis/core/models.py:1044 +#: aleksis/core/models.py:1076 msgid "Custom menu item" msgstr "Пункт кориÑтувацького меню" -#: aleksis/core/models.py:1045 +#: aleksis/core/models.py:1077 msgid "Custom menu items" msgstr "Пункти кориÑтувацького меню" -#: aleksis/core/models.py:1069 +#: aleksis/core/models.py:1101 msgid "Title of type" msgstr "Ðазва типу" -#: aleksis/core/models.py:1073 +#: aleksis/core/models.py:1105 msgid "Owners of groups with this group type can see the groups" msgstr "" -#: aleksis/core/models.py:1076 +#: aleksis/core/models.py:1108 msgid "Owners of groups with this group type can see group members" msgstr "" -#: aleksis/core/models.py:1084 +#: aleksis/core/models.py:1116 #, fuzzy #| msgid "Personal events" msgid "Personal details" msgstr "ОÑобиÑті події" -#: aleksis/core/models.py:1086 +#: aleksis/core/models.py:1118 msgid "Contact details" msgstr "Контактні дані" -#: aleksis/core/models.py:1088 +#: aleksis/core/models.py:1120 #: aleksis/core/templates/core/partials/avatar_content.html:14 #: aleksis/core/templates/core/partials/avatar_content.html:15 msgid "Avatar" msgstr "Ðватар" -#: aleksis/core/models.py:1093 +#: aleksis/core/models.py:1125 msgid "Information owners of groups with this group type can see of the group's members" msgstr "" -#: aleksis/core/models.py:1103 +#: aleksis/core/models.py:1135 msgid "Group type" msgstr "Тип групи" -#: aleksis/core/models.py:1104 +#: aleksis/core/models.py:1136 msgid "Group types" msgstr "Типи груп" -#: aleksis/core/models.py:1115 +#: aleksis/core/models.py:1147 msgid "Can view system status" msgstr "Може бачити Ñтан ÑиÑтеми" -#: aleksis/core/models.py:1116 +#: aleksis/core/models.py:1148 msgid "Can manage data" msgstr "Може керувати даними" -#: aleksis/core/models.py:1117 +#: aleksis/core/models.py:1149 msgid "Can impersonate" msgstr "Може маÑкуватиÑÑ" -#: aleksis/core/models.py:1118 +#: aleksis/core/models.py:1150 msgid "Can use search" msgstr "Може шукати" -#: aleksis/core/models.py:1119 +#: aleksis/core/models.py:1151 msgid "Can change site preferences" msgstr "Може змінювати влаÑтивоÑті Ñайту" -#: aleksis/core/models.py:1120 +#: aleksis/core/models.py:1152 msgid "Can change person preferences" msgstr "Може змінювати влаÑтивоÑті оÑоби" -#: aleksis/core/models.py:1121 +#: aleksis/core/models.py:1153 msgid "Can change group preferences" msgstr "Може змінювати влаÑтивоÑті групи" -#: aleksis/core/models.py:1122 +#: aleksis/core/models.py:1154 msgid "Can test PDF generation" msgstr "Може генерувати теÑтові PDF" -#: aleksis/core/models.py:1123 +#: aleksis/core/models.py:1155 msgid "Can invite persons" msgstr "Може запрошувати оÑіб" -#: aleksis/core/models.py:1124 +#: aleksis/core/models.py:1156 msgid "Can view birthday calendar" msgstr "Може бачити календар днів народженнÑ" -#: aleksis/core/models.py:1151 +#: aleksis/core/models.py:1183 msgid "Related data check task" msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ пов'Ñзаних даних" -#: aleksis/core/models.py:1159 +#: aleksis/core/models.py:1191 msgid "Issue solved" msgstr "Проблема вирішена" -#: aleksis/core/models.py:1160 +#: aleksis/core/models.py:1192 msgid "Notification sent" msgstr "Ð¡Ð¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð°Ð´Ñ–Ñлане" -#: aleksis/core/models.py:1173 +#: aleksis/core/models.py:1205 msgid "Data check result" msgstr "Результат перевірки даних" -#: aleksis/core/models.py:1174 +#: aleksis/core/models.py:1206 msgid "Data check results" msgstr "Результати перевірки даних" -#: aleksis/core/models.py:1176 +#: aleksis/core/models.py:1208 msgid "Can run data checks" msgstr "Може запуÑкати перевірки даних" -#: aleksis/core/models.py:1177 +#: aleksis/core/models.py:1209 msgid "Can solve data check problems" msgstr "Може розв'Ñзувати проблеми перевірки даних" -#: aleksis/core/models.py:1184 +#: aleksis/core/models.py:1216 msgid "E-Mail address" msgstr "ÐдреÑа е-пошти" -#: aleksis/core/models.py:1243 aleksis/core/models.py:1827 +#: aleksis/core/models.py:1275 aleksis/core/models.py:1885 msgid "Owner" msgstr "ВлаÑник" -#: aleksis/core/models.py:1247 +#: aleksis/core/models.py:1279 msgid "File expires at" msgstr "Файл дійÑний до" -#: aleksis/core/models.py:1250 +#: aleksis/core/models.py:1282 msgid "Generated HTML file" msgstr "Згенерований файл HTML" -#: aleksis/core/models.py:1253 +#: aleksis/core/models.py:1285 msgid "Generated PDF file" msgstr "Згенерований файл PDF" -#: aleksis/core/models.py:1260 +#: aleksis/core/models.py:1292 msgid "PDF file" msgstr "Файл PDF" -#: aleksis/core/models.py:1261 +#: aleksis/core/models.py:1293 msgid "PDF files" msgstr "Файли PDF" -#: aleksis/core/models.py:1266 +#: aleksis/core/models.py:1298 msgid "Task result" msgstr "Результат завданнÑ" -#: aleksis/core/models.py:1269 +#: aleksis/core/models.py:1301 msgid "Task user" msgstr "КориÑтувач завданнÑ" -#: aleksis/core/models.py:1273 +#: aleksis/core/models.py:1305 msgid "Back URL" msgstr "URL Ð´Ð»Ñ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ" -#: aleksis/core/models.py:1274 +#: aleksis/core/models.py:1306 msgid "Progress title" msgstr "Ðазва процеÑу" -#: aleksis/core/models.py:1275 +#: aleksis/core/models.py:1307 msgid "Error message" msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку" -#: aleksis/core/models.py:1276 +#: aleksis/core/models.py:1308 msgid "Success message" msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ уÑпіх" -#: aleksis/core/models.py:1277 +#: aleksis/core/models.py:1309 msgid "Redirect on success URL" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð² разі уÑпіху" -#: aleksis/core/models.py:1279 +#: aleksis/core/models.py:1311 msgid "Additional button title" msgstr "Ðазва додаткової кнопки" -#: aleksis/core/models.py:1281 +#: aleksis/core/models.py:1313 msgid "Additional button URL" msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— кнопки" -#: aleksis/core/models.py:1283 +#: aleksis/core/models.py:1315 msgid "Additional button icon" msgstr "Піктограма додаткової кнопки" -#: aleksis/core/models.py:1285 +#: aleksis/core/models.py:1317 msgid "Result fetched" msgstr "Отриманий результат" -#: aleksis/core/models.py:1310 +#: aleksis/core/models.py:1341 msgid "Background task completed successfully" msgstr "Фонове Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ ÑƒÑпішно завершене" -#: aleksis/core/models.py:1311 +#: aleksis/core/models.py:1342 msgid "The background task '{}' has been completed successfully." msgstr "Фонове Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ '{}' було уÑпішно завершене." -#: aleksis/core/models.py:1317 +#: aleksis/core/models.py:1348 msgid "Background task failed" msgstr "Збій фонового завданнÑ" -#: aleksis/core/models.py:1318 +#: aleksis/core/models.py:1349 msgid "The background task '{}' has failed." msgstr "У фонового Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ '{}' ÑтавÑÑ Ð·Ð±Ñ–Ð¹." -#: aleksis/core/models.py:1327 +#: aleksis/core/models.py:1358 msgid "Background task" msgstr "Фонове завданнÑ" -#: aleksis/core/models.py:1341 +#: aleksis/core/models.py:1372 msgid "Task user assignment" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача завданнÑ" -#: aleksis/core/models.py:1342 +#: aleksis/core/models.py:1373 msgid "Task user assignments" msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів завданнÑ" -#: aleksis/core/models.py:1358 +#: aleksis/core/models.py:1389 msgid "Additional attributes" msgstr "Додаткові атрибути" -#: aleksis/core/models.py:1399 +#: aleksis/core/models.py:1430 msgid "Allowed scopes that clients can request" msgstr "Дозволені межі дії, Ñкі можуть запитувати клієнти" -#: aleksis/core/models.py:1409 +#: aleksis/core/models.py:1440 msgid "This image will be shown as icon in the authorization flow. It should be squared." msgstr "Це Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ іконкою під Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ—. Воно повинне бути квадратним." -#: aleksis/core/models.py:1459 +#: aleksis/core/models.py:1490 msgid "Can view room timetable" msgstr "Може бачити розклад кімнати" -#: aleksis/core/models.py:1461 +#: aleksis/core/models.py:1492 msgid "Room" msgstr "Кімната" -#: aleksis/core/models.py:1462 +#: aleksis/core/models.py:1493 msgid "Rooms" msgstr "Кімнати" -#: aleksis/core/models.py:1487 +#: aleksis/core/models.py:1518 msgid "Start date and time" msgstr "Дата Ñ– Ñ‡Ð°Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ" -#: aleksis/core/models.py:1489 +#: aleksis/core/models.py:1520 msgid "End date and time" msgstr "Дата Ñ– Ñ‡Ð°Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ" -#: aleksis/core/models.py:1490 +#: aleksis/core/models.py:1521 msgid "Timezone" msgstr "ЧаÑовий поÑÑ" -#: aleksis/core/models.py:1493 +#: aleksis/core/models.py:1525 msgid "Recurrences" msgstr "Повтори" -#: aleksis/core/models.py:1499 +#: aleksis/core/models.py:1533 msgid "Amended base event" msgstr "Виправлена оÑновна подіÑ" -#: aleksis/core/models.py:1651 +#: aleksis/core/models.py:1701 msgid "Calendar Event" msgstr "Календарна подіÑ" -#: aleksis/core/models.py:1652 +#: aleksis/core/models.py:1702 msgid "Calendar Events" msgstr "Календарні події" -#: aleksis/core/models.py:1682 +#: aleksis/core/models.py:1742 msgid "Birthdays" msgstr "Дні ÐародженнÑ" -#: aleksis/core/models.py:1687 +#: aleksis/core/models.py:1747 msgid "{}'s birthday" msgstr "{} ÑвÑткує День ÐародженнÑ" -#: aleksis/core/models.py:1742 aleksis/core/models.py:1811 +#: aleksis/core/models.py:1800 aleksis/core/models.py:1869 msgid "Holidays" msgstr "Вихідні" -#: aleksis/core/models.py:1810 +#: aleksis/core/models.py:1868 msgid "Holiday" msgstr "Вихідний" -#: aleksis/core/models.py:1812 +#: aleksis/core/models.py:1870 msgid "Can view holiday calendar" msgstr "Може бачити календар зі ÑвÑтами" -#: aleksis/core/models.py:1817 +#: aleksis/core/models.py:1875 msgid "Personal events" msgstr "ОÑобиÑті події" -#: aleksis/core/models.py:1821 +#: aleksis/core/models.py:1879 msgid "Location" msgstr "ÐаÑ.пункт" -#: aleksis/core/models.py:1908 +#: aleksis/core/models.py:1971 aleksis/core/models.py:2005 msgid "Email" msgstr "Е-пошта" -#: aleksis/core/models.py:1911 +#: aleksis/core/models.py:1974 msgid "Related group" msgstr "Пов'Ñзана група" -#: aleksis/core/models.py:1918 +#: aleksis/core/models.py:1981 msgid "Organisation" msgstr "ОрганізаціÑ" -#: aleksis/core/models.py:1919 +#: aleksis/core/models.py:1982 msgid "Organisations" msgstr "Організації" +#: aleksis/core/models.py:2003 +msgid "Audio" +msgstr "" + +#: aleksis/core/models.py:2004 +msgid "Display" +msgstr "" + +#: aleksis/core/models.py:2006 +msgid "Procedure" +msgstr "" + +#: aleksis/core/models.py:2010 +msgid "Event" +msgstr "" + +#: aleksis/core/models.py:2014 +#, fuzzy +#| msgid "Actions" +msgid "Action" +msgstr "Дії" + +#: aleksis/core/models.py:2017 +#, fuzzy +#| msgid "Send notification at" +msgid "Send notifications" +msgstr "ÐадіÑлати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾" + +#: aleksis/core/models.py:2131 +#, fuzzy +#| msgid "Calendar" +msgid "Calendar alarms" +msgstr "Календар" + +#: aleksis/core/models.py:2140 +#, fuzzy +#| msgid "Personal events" +msgid "Personal event alarm" +msgstr "ОÑобиÑті події" + +#: aleksis/core/models.py:2141 +#, fuzzy +#| msgid "Personal events" +msgid "Personal event alarms" +msgstr "ОÑобиÑті події" + #: aleksis/core/preferences.py:25 msgid "General" msgstr "Загальне" @@ -1258,46 +1300,84 @@ msgstr "Ðвтоматично оновлювати інформпанель Ñ‚ msgid "Automatically update the dashboard and its widgets sitewide" msgstr "Ðвтоматично оновлювати інформпанель та Ñ—Ñ— віджети (Ð´Ð»Ñ Ð²Ñього Ñайту)" -#: aleksis/core/preferences.py:491 +#: aleksis/core/preferences.py:491 aleksis/core/preferences.py:513 +msgid "First day that appears in the calendar" +msgstr "" + +#: aleksis/core/preferences.py:493 aleksis/core/preferences.py:516 +msgid "Monday" +msgstr "" + +#: aleksis/core/preferences.py:494 aleksis/core/preferences.py:517 +msgid "Tuesday" +msgstr "" + +#: aleksis/core/preferences.py:495 aleksis/core/preferences.py:518 +msgid "Wednesday" +msgstr "" + +#: aleksis/core/preferences.py:496 aleksis/core/preferences.py:519 +msgid "Thursday" +msgstr "" + +#: aleksis/core/preferences.py:497 aleksis/core/preferences.py:520 +#, fuzzy +#| msgid "Holiday" +msgid "Friday" +msgstr "Вихідний" + +#: aleksis/core/preferences.py:498 aleksis/core/preferences.py:521 +msgid "Saturday" +msgstr "" + +#: aleksis/core/preferences.py:499 aleksis/core/preferences.py:522 +msgid "Sunday" +msgstr "" + +#: aleksis/core/preferences.py:515 +msgid "Use page default" +msgstr "" + +#: aleksis/core/preferences.py:534 msgid "Birthday calendar feed color" msgstr "Колір ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð”Ð½Ñ–Ð² ÐародженнÑ" -#: aleksis/core/preferences.py:503 +#: aleksis/core/preferences.py:546 msgid "Holiday calendar feed color" msgstr "Колір ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð’Ð¸Ñ…Ñ–Ð´Ð½Ð¸Ñ…" -#: aleksis/core/preferences.py:515 +#: aleksis/core/preferences.py:558 msgid "Personal events feed color" msgstr "Колір Ñтрічки з оÑобиÑтими подіÑми" -#: aleksis/core/preferences.py:528 +#: aleksis/core/preferences.py:571 msgid "Activated calendars" msgstr "Ðктивні календарі" -#: aleksis/core/preferences.py:546 +#: aleksis/core/preferences.py:589 msgid "Comma-separated list of disallowed usernames" msgstr "Заборонені імена кориÑтувачів через кому" -#: aleksis/core/settings.py:550 +#: aleksis/core/settings.py:552 msgid "English" msgstr "ÐнглійÑька" -#: aleksis/core/settings.py:551 +#: aleksis/core/settings.py:553 msgid "German" msgstr "Ðімецька" -#: aleksis/core/settings.py:552 +#: aleksis/core/settings.py:554 msgid "Ukrainian" msgstr "УкраїнÑька" -#: aleksis/core/tables.py:96 aleksis/core/tables.py:133 +#: aleksis/core/tables.py:23 aleksis/core/tables.py:60 #: aleksis/core/templates/core/announcement/list.html:42 #: aleksis/core/templates/core/pages/delete.html:22 #: aleksis/core/templates/oauth2_provider/application/detail.html:21 msgid "Delete" msgstr "Видалити" -#: aleksis/core/tables.py:98 aleksis/core/tables.py:135 +#: aleksis/core/tables.py:25 aleksis/core/tables.py:62 #: aleksis/core/templates/core/announcement/list.html:22 msgid "Actions" msgstr "Дії" @@ -1815,22 +1895,6 @@ msgstr "Типова інформпанель" msgid "Edit group" msgstr "Редагувати групу" -#: aleksis/core/templates/core/group/list.html:14 -msgid "Create group" -msgstr "Створити групу" - -#: aleksis/core/templates/core/group/list.html:17 -msgid "Filter groups" -msgstr "Фільтрувати групи" - -#: aleksis/core/templates/core/group/list.html:24 -msgid "Clear" -msgstr "ОчиÑтити" - -#: aleksis/core/templates/core/group/list.html:28 -msgid "Selected groups" -msgstr "Вибрані групи" - #: aleksis/core/templates/core/index.html:4 msgid "Home" msgstr "Додому" @@ -2326,6 +2390,11 @@ msgstr "" " Якщо інтернет працює Ñ– помилка вÑе одно приÑутнÑ, звернітьÑÑ Ð´Ð¾ ÑиÑтемних адмініÑтраторів:\n" " " +#: aleksis/core/templates/search/search.html:7 +#: aleksis/core/templates/search/search.html:22 +msgid "Search" +msgstr "Пошук" + #: aleksis/core/templates/search/search.html:8 msgid "Global Search" msgstr "Глобальний пошук" @@ -2994,11 +3063,11 @@ msgstr "Вимкнути" msgid "This username is not allowed." msgstr "Цей логін заборонений." -#: aleksis/core/util/notifications.py:67 +#: aleksis/core/util/notifications.py:68 msgid "E-Mail" msgstr "Е-пошта" -#: aleksis/core/util/notifications.py:68 +#: aleksis/core/util/notifications.py:69 msgid "SMS" msgstr "SMS" @@ -3022,132 +3091,144 @@ msgstr "Під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ PDF виникла проб msgid "Download PDF" msgstr "Звантажити PDF" -#: aleksis/core/views.py:303 aleksis/core/views.py:313 +#: aleksis/core/views.py:255 aleksis/core/views.py:265 msgid "The person has been saved." msgstr "ОÑоба збережена." -#: aleksis/core/views.py:362 +#: aleksis/core/views.py:314 msgid "The group has been saved." msgstr "Група збережена." -#: aleksis/core/views.py:410 +#: aleksis/core/views.py:362 msgid "Maintenance mode was turned on successfully." msgstr "Режим обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¹ уÑпішно." -#: aleksis/core/views.py:412 +#: aleksis/core/views.py:364 msgid "Maintenance mode was turned off successfully." msgstr "Режим обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÑпішно вимкнений." -#: aleksis/core/views.py:469 +#: aleksis/core/views.py:421 msgid "The announcement has been saved." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ðµ." -#: aleksis/core/views.py:485 +#: aleksis/core/views.py:437 msgid "The announcement has been deleted." msgstr "ÐžÐ³Ð¾Ð»Ð¾ÑˆÐµÐ½Ð½Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ðµ." -#: aleksis/core/views.py:554 +#: aleksis/core/views.py:506 msgid "The requested preference registry does not exist" msgstr "Журналу із запитаними влаÑтивоÑÑ‚Ñми не Ñ–Ñнує" -#: aleksis/core/views.py:573 +#: aleksis/core/views.py:525 msgid "The preferences have been saved successfully." msgstr "ВлаÑтивоÑті збережені." -#: aleksis/core/views.py:596 +#: aleksis/core/views.py:548 msgid "The group has been deleted." msgstr "Група видалена." -#: aleksis/core/views.py:631 +#: aleksis/core/views.py:583 msgid "Progress: Run data checks" msgstr "Перебіг: ЗапуÑк перевірки даних" -#: aleksis/core/views.py:632 +#: aleksis/core/views.py:584 msgid "Run data checks …" msgstr "ЗапуÑкаєтьÑÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ° даних …" -#: aleksis/core/views.py:633 +#: aleksis/core/views.py:585 msgid "The data checks were run successfully." msgstr "Перевірка даних уÑпішно запущена." -#: aleksis/core/views.py:634 +#: aleksis/core/views.py:586 msgid "There was a problem while running data checks." msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку перевірки даних виникла проблема." -#: aleksis/core/views.py:651 +#: aleksis/core/views.py:603 #, python-brace-format msgid "The solve option '{solve_option_obj.verbose_name}' " msgstr "Варіант розв'ÑÐ·Ð°Ð½Ð½Ñ \"{solve_option_obj.verbose_name}\" " -#: aleksis/core/views.py:661 +#: aleksis/core/views.py:613 msgid "The requested solve option does not exist" msgstr "Запитаний варіант розв'ÑÐ·Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує" -#: aleksis/core/views.py:694 +#: aleksis/core/views.py:646 msgid "The dashboard widget has been saved." msgstr "Віджет інформпанелі збережений." -#: aleksis/core/views.py:724 +#: aleksis/core/views.py:676 msgid "The dashboard widget has been created." msgstr "Віджет інформпанелі Ñтворений." -#: aleksis/core/views.py:734 +#: aleksis/core/views.py:686 msgid "The dashboard widget has been deleted." msgstr "Віджет інформпанелі видалений." -#: aleksis/core/views.py:806 +#: aleksis/core/views.py:758 msgid "Your dashboard configuration has been saved successfully." msgstr "Ваша ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð¿Ð°Ð½ÐµÐ»Ñ– збережена." -#: aleksis/core/views.py:808 +#: aleksis/core/views.py:760 msgid "The configuration of the default dashboard has been saved successfully." msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ñ—/Ñтандартної інформпанелі збережена." -#: aleksis/core/views.py:879 +#: aleksis/core/views.py:831 #, python-brace-format msgid "The invitation was successfully created. The invitation code is {code}" msgstr "Ð—Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ ÑƒÑпішно Ñтворене. Код запрошеннÑ: {code}" -#: aleksis/core/views.py:976 +#: aleksis/core/views.py:928 msgid "We have successfully assigned the permissions." msgstr "Ми уÑпішно призначили дозволи." -#: aleksis/core/views.py:986 +#: aleksis/core/views.py:938 msgid "The global user permission has been deleted." msgstr "Глобальний кориÑтувацький дозвіл видалений." -#: aleksis/core/views.py:996 +#: aleksis/core/views.py:948 msgid "The global group permission has been deleted." msgstr "Глобальний груповий дозвіл видалений." -#: aleksis/core/views.py:1006 +#: aleksis/core/views.py:958 msgid "The object user permission has been deleted." msgstr "Об'єктний кориÑтувацький дозвіл видалений." -#: aleksis/core/views.py:1016 +#: aleksis/core/views.py:968 msgid "The object group permission has been deleted." msgstr "Об'єктний груповий дозвіл видалений." -#: aleksis/core/views.py:1098 +#: aleksis/core/views.py:1050 msgid "We sent you an email with instructions for resetting your password." msgstr "Ми надіÑлали Вам е-лиÑта з наÑтановами щодо Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ." -#: aleksis/core/views.py:1122 +#: aleksis/core/views.py:1074 msgid "The third-party account could not be disconnected because it is the only login method available." msgstr "Обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони не можна від'єднати оÑкільки він єдиний ÑпоÑіб Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ." -#: aleksis/core/views.py:1129 +#: aleksis/core/views.py:1081 msgid "The third-party account has been successfully disconnected." msgstr "Обліковий Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони уÑпішно від'єднаний." -#: aleksis/core/views.py:1205 +#: aleksis/core/views.py:1157 msgid "Person was invited successfully and an email with further instructions has been send to them." msgstr "ОÑоба уÑпішно запрошена. ЛиÑÑ‚ з інÑтрукціÑми щодо наÑтупних дій надіÑланий на Ñ—Ñ— ел.пошту." -#: aleksis/core/views.py:1216 +#: aleksis/core/views.py:1168 msgid "Person was already invited." msgstr "ОÑоба вже була запрошена." +#~ msgid "Create group" +#~ msgstr "Створити групу" + +#~ msgid "Filter groups" +#~ msgstr "Фільтрувати групи" + +#~ msgid "Clear" +#~ msgstr "ОчиÑтити" + +#~ msgid "Selected groups" +#~ msgstr "Вибрані групи" + #~ msgid "Assign child groups to groups" #~ msgstr "Призначити підлеглі групи до груп" diff --git a/aleksis/core/migrations/0069_add_calendar_alarm.py b/aleksis/core/migrations/0069_add_calendar_alarm.py new file mode 100644 index 0000000000000000000000000000000000000000..1ecbdbe511af95fa2244e06986131b876d0e00f1 --- /dev/null +++ b/aleksis/core/migrations/0069_add_calendar_alarm.py @@ -0,0 +1,53 @@ +# Generated by Django 5.0.6 on 2024-07-12 11:34 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('core', '0068_calendar_event_amends_unique_constraints'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='CalendarAlarm', + 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)), + ('action', models.CharField(choices=[('audio', 'Audio'), ('display', 'Display'), ('email', 'Email'), ('procedure', 'Procedure')], default='display', max_length=10, verbose_name='Action')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='alarms', to='core.calendarevent', verbose_name='Event')), + ('send_notifications', models.BooleanField(default=False, verbose_name='Send notifications')), + ('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')), + ], + options={ + 'verbose_name': 'Calendar alarm', + 'verbose_name_plural': 'Calendar alarms', + }, + ), + migrations.CreateModel( + name='PersonalEventAlarm', + fields=[ + ('calendaralarm_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.calendaralarm')), + ], + options={ + 'verbose_name': 'Personal event alarm', + 'verbose_name_plural': 'Personal event alarms', + }, + bases=('core.calendaralarm',), + ), + migrations.AddField( + model_name='notification', + name='calendar_alarm', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to='core.calendaralarm', verbose_name='Calendar alarm'), + ), + migrations.AddConstraint( + model_name='notification', + constraint=models.UniqueConstraint(condition=models.Q(('calendar_alarm__isnull', False)), fields=('calendar_alarm', 'recipient'), name='unique_recipient_per_calendar_alarm'), + ), + ] diff --git a/aleksis/core/migrations/0070_oauth_token_checksum.py b/aleksis/core/migrations/0070_oauth_token_checksum.py new file mode 100644 index 0000000000000000000000000000000000000000..b091d273be8f03b3b72d39defe0f950412871364 --- /dev/null +++ b/aleksis/core/migrations/0070_oauth_token_checksum.py @@ -0,0 +1,48 @@ +# Generated by Django 5.1.5 on 2025-01-17 15:18 + +import django.db.models.deletion +import oauth2_provider.models +from django.conf import settings +from django.db import migrations, models +from oauth2_provider.settings import oauth2_settings + +def forwards_func(apps, schema_editor): + """ + Forward migration touches every "old" accesstoken.token which will cause the checksum to be computed. + """ + AccessToken = apps.get_model(oauth2_settings.ACCESS_TOKEN_MODEL) + accesstokens = AccessToken._default_manager.iterator() + for accesstoken in accesstokens: + accesstoken.save(update_fields=['token_checksum']) + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0069_add_calendar_alarm'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='oauthaccesstoken', + name='token_checksum', + field=oauth2_provider.models.TokenChecksumField(db_index=True, default='', max_length=64, unique=True, blank=True), + preserve_default=False, + ), + migrations.RunPython(forwards_func, migrations.RunPython.noop), + migrations.AlterField( + model_name='oauthaccesstoken', + name='token_checksum', + field=oauth2_provider.models.TokenChecksumField(blank=False, max_length=64, db_index=True, unique=True), + ), + migrations.AddField( + model_name='oauthrefreshtoken', + name='token_family', + field=models.UUIDField(blank=True, editable=False, null=True), + ), + migrations.AlterField( + model_name='oauthaccesstoken', + name='token', + field=models.TextField(), + ), + ] diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index eb2f31556e4e36fa05eacde98c2a9fdb81a891f1..fcba78889865e00191e81df9cbe771ec54be8e29 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -1,8 +1,9 @@ # flake8: noqa: DJ12 import os +from collections.abc import Iterable from datetime import datetime -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterable, List, Optional, Union +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Union from django.conf import settings from django.contrib import messages @@ -20,7 +21,6 @@ from django.views.generic import CreateView, UpdateView from django.views.generic.edit import DeleteView, ModelFormMixin 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 @@ -38,7 +38,7 @@ from aleksis.core.managers import ( SchoolTermRelatedQuerySet, ) -from .util.core_helpers import ExtendedICal20Feed +from .util.core_helpers import EXTENDED_ITEM_ELEMENT_FIELD_MAP, ExtendedICal20Feed if TYPE_CHECKING: from .models import Person @@ -216,7 +216,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): cls._safe_add(classmethod(func), name or func.__name__) @classmethod - def get_filter_fields(cls) -> List[str]: + def get_filter_fields(cls) -> list[str]: """Get names of all text-searchable fields of this model.""" fields = [] for field in cls.syncable_fields(): @@ -659,6 +659,7 @@ class CalendarEventMixin(RegistryObject): start: Optional[datetime] = None, end: Optional[datetime] = None, queryset: Optional[QuerySet] = None, + **kwargs, ) -> ExtendedICal20Feed: """Create the calendar feed with all events.""" feed = cls.start_feed(request=request, params=params) @@ -667,7 +668,7 @@ class CalendarEventMixin(RegistryObject): reference_queryset = queryset else: reference_queryset = cls.get_objects( - request=request, params=params, start=start, end=end + request=request, params=params, start=start, end=end, **kwargs ) for reference_object in reference_queryset: @@ -695,11 +696,12 @@ class CalendarEventMixin(RegistryObject): params: dict[str, any] | None = None, with_reference_object: bool = False, queryset: Optional[QuerySet] = None, + **kwargs, ) -> Calendar: """Get events for this calendar feed.""" feed = cls.create_feed( - request=request, params=params, start=start, end=end, queryset=queryset + request=request, params=params, start=start, end=end, queryset=queryset, **kwargs ) return feed.get_calendar_object(with_reference_object=with_reference_object) @@ -712,11 +714,12 @@ class CalendarEventMixin(RegistryObject): params: dict[str, any] | None = None, with_reference_object: bool = False, queryset: Optional[QuerySet] = None, + **kwargs, ): """Get single events for this calendar feed.""" feed = cls.create_feed( - request=request, params=params, start=start, end=end, queryset=queryset + request=request, params=params, start=start, end=end, queryset=queryset, **kwargs ) events = feed.get_single_events(start, end, with_reference_object=with_reference_object) return events @@ -724,7 +727,7 @@ class CalendarEventMixin(RegistryObject): @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] + return [field_map[0] for field_map in EXTENDED_ITEM_ELEMENT_FIELD_MAP] @classmethod def get_event_field_value( diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 02a60685a11ee349fd9341a2ba3b48adc05e7e9b..6a813fa84be2a47dcfe8ce4bfe73f0d6376c1f7f 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1,8 +1,9 @@ # flake8: noqa: DJ01 import base64 +from collections.abc import Iterable, Iterator, Sequence from datetime import date, datetime, timedelta from itertools import chain -from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Optional, Sequence, Union +from typing import TYPE_CHECKING, Any, Optional, Union from urllib.parse import urljoin from django.conf import settings @@ -35,7 +36,7 @@ from django_ical.utils import build_rrule_from_recurrences_rrule, build_rrule_fr from django_pg_rrule.models import RecurrenceModel from dynamic_preferences.models import PerInstancePreferenceModel from guardian.shortcuts import get_objects_for_user -from icalendar import vCalAddress, vText +from icalendar import Alarm, vCalAddress, vText from icalendar.prop import vRecur from invitations import signals from invitations.base_invitation import AbstractBaseInvitation @@ -103,6 +104,17 @@ FIELD_CHOICES = ( ("URLField", _("URL / Link")), ) +CALENDAR_ALARM_FIELD_MAP = ( + ("action", "action"), + ("trigger", "trigger"), + ("duration", "duration"), + ("repeat", "repeat"), + ("attach", "attach"), + ("description", "description"), + ("summary", "summary"), + ("attendee", "attendee"), +) + class SchoolTerm(ExtensibleModel): """School term model. @@ -432,7 +444,7 @@ class Person(ExtensibleModel): self.primary_group = self.member_of.filter(**{f"{field}__regex": pattern}).first() def notify_about_changed_data( - self, changed_fields: Iterable[str], recipients: Optional[List[str]] = None + self, changed_fields: Iterable[str], recipients: Optional[list[str]] = None ): """Notify (configured) recipients about changed data of this person.""" context = {"person": self, "changed_fields": changed_fields} @@ -713,6 +725,15 @@ class Notification(ExtensibleModel, TimeStampedModel): read = models.BooleanField(default=False, verbose_name=_("Read")) sent = models.BooleanField(default=False, verbose_name=_("Sent")) + calendar_alarm = models.ForeignKey( + "CalendarAlarm", + related_name="notifications", + verbose_name=_("Calendar alarm"), + on_delete=models.CASCADE, + null=True, + blank=True, + ) + def __str__(self): return str(self.title) @@ -730,6 +751,13 @@ class Notification(ExtensibleModel, TimeStampedModel): class Meta: verbose_name = _("Notification") verbose_name_plural = _("Notifications") + constraints = [ + models.UniqueConstraint( + fields=["calendar_alarm", "recipient"], + condition=Q(calendar_alarm__isnull=False), + name="unique_recipient_per_calendar_alarm", + ), + ] class AnnouncementQuerySet(models.QuerySet): @@ -775,7 +803,7 @@ class AnnouncementQuerySet(models.QuerySet): return announcements - def for_person(self, person: Person) -> List: + def for_person(self, person: Person) -> list: """Get all announcements for one person.""" # Filter by person announcements_for_person = [] @@ -1608,6 +1636,15 @@ class CalendarEvent(CalendarEventMixin, ExtensiblePolymorphicModel, RecurrenceMo """Return the reference object itself.""" return reference_object + @classmethod + def value_valarm( + cls, reference_object: "CalendarEvent", request: HttpRequest | None = None + ) -> list[Alarm]: + """Return all CalendarAlarms associated with the event, converted into Alarm objects.""" + return [ + calendar_alarm.get_alarm(request) for calendar_alarm in reference_object.alarms.all() + ] + @classmethod def get_objects( cls, @@ -1943,3 +1980,162 @@ class Organisation(ExtensibleModel): class Meta: verbose_name = _("Organisation") verbose_name_plural = _("Organisations") + + +class CalendarAlarm(ExtensiblePolymorphicModel): + """An alarm bound to a CalendarEvent. + + To make use of this model, you need to inherit from this model. + Every subclass of this model represents a certain group of alarms. + + Every `value_*` method from can be implemented to provide additional data + (either static or dynamic). Some like `value_action` are pre-implemented + in this model. Some like `value_action` are optional and need to be implemented + in a model inheriting from this model. The following iCal attributes are supported: + + action, trigger, duration, repeat, attach, description, summary, attendee + + Whether the implementation of some methods is required depends on the action + type of the alarm. See the iCalendar RFC 5545 documentation for more information. + """ + + ACTION_CHOICES = [ + ("audio", _("Audio")), + ("display", _("Display")), + ("email", _("Email")), + ("procedure", _("Procedure")), + ] + + event = models.ForeignKey( + CalendarEvent, on_delete=models.CASCADE, related_name="alarms", verbose_name=_("Event") + ) + + action = models.CharField( + verbose_name=_("Action"), max_length=10, default="display", choices=ACTION_CHOICES + ) + + send_notifications = models.BooleanField(verbose_name=_("Send notifications"), default=False) + + def value_action(self, request: HttpRequest | None = None) -> str: + """Return the action type of the calendar alarm. + + The action type determines in which way the alarm shall be communicated to the user. + """ + return self.action + + def value_trigger(self, request: HttpRequest | None = None) -> Union[datetime, timedelta]: + """Return the trigger of the calendar alarm. + + The trigger can be either a time delta value indicating at which time relative to the + reference event the alarm shall be triggered or a datetime value indicating an absolute + time at which this shall happen. + """ + raise NotImplementedError() + + def value_attach(self, request: HttpRequest | None = None) -> Optional[str]: + """Return the attachment of the calendar alarm.""" + if self.value_action(request) == "procedure": + raise NotImplementedError() + return None + + def value_description(self, request: HttpRequest | None = None) -> Optional[str]: + """Return the description of the calendar alarm.""" + if self.value_action(request) == "display" or self.value_action(request) == "email": + raise NotImplementedError() + return None + + def value_summary(self, request: HttpRequest | None = None) -> Optional[str]: + """Return the summary of the calendar alarm.""" + if self.value_action(request) == "email": + raise NotImplementedError() + return None + + def value_attendee(self, request: HttpRequest | None = None) -> Optional[str]: + """Return the attendees of the calendar alarm.""" + if self.value_action(request) == "email": + raise NotImplementedError() + return None + + def value_notification_recipients(self, request: HttpRequest | None = None) -> list[Person]: + """Return the recipients of the notification linked to the calendar alarm.""" + raise NotImplementedError() + + def value_notification_sender(self, request: HttpRequest | None = None) -> str: + """Return the sender of the notification linked to the calendar alarm.""" + raise NotImplementedError() + + def value_notification_title(self, request: HttpRequest | None = None) -> str: + """Return the title of the notification linked to the calendar alarm.""" + raise NotImplementedError() + + def value_notification_description(self, request: HttpRequest | None = None) -> str: + """Return the description of the notification linked to the calendar alarm.""" + return self.value_description(request) + + def value_notification_send_at(self, request: HttpRequest | None = None) -> datetime: + """Return the absolute time to send the notification linked to the calendar alarm.""" + if isinstance(self.value_trigger(request), datetime): + return self.value_trigger(request) + elif isinstance(self.value_trigger(request), timedelta): + return self.event.datetime_start - self.value_trigger(request) + + def get_alarm(self, request: Optional[HttpRequest] = None) -> Alarm: + alarm = Alarm() + for field in CALENDAR_ALARM_FIELD_MAP: + method_name = f"value_{field[0]}" + if hasattr(self, method_name) and callable(getattr(self, method_name)): + value = getattr(self, method_name)(request=request) + if value: + alarm.add(field[1], value) + return alarm + + def update_or_create_notifications( + self, request: Optional[HttpRequest] = None + ) -> Optional[list[Notification]]: + """Update or create notifications for this calendar alarm (and send them).""" + notifications = [] + + default_dict = {} + for field_name in [field.name for field in Notification._meta.get_fields()]: + method_name = f"value_notification_{field_name}" + if hasattr(self, method_name) and callable(getattr(self, method_name)): + value = getattr(self, method_name)(request=request) + if value: + default_dict[field_name] = value + + for recipient in self.value_notification_recipients(request): + try: + notification = Notification.objects.get(calendar_alarm=self, recipient=recipient) + for key, value in default_dict.items(): + setattr(notification, key, value) + notification.save() + except Notification.DoesNotExist: + new_values = {"calendar_alarm": self, "recipient": recipient} + new_values.update(default_dict) + notification = Notification(**new_values) + notification.save() + + # Using django's update_or_create creates id collisions, for some reason. + notifications.append(notification) + + return notifications + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + + if self.send_notifications: + self.update_or_create_notifications() + + class Meta: + verbose_name = _("Calendar alarm") + verbose_name_plural = _("Calendar alarms") + + +class PersonalEventAlarm(CalendarAlarm): + def value_description(self, request: HttpRequest | None = None) -> Optional[str]: + """Return the description of the personal event alarm.""" + return self.event.description + + class Meta: + verbose_name = _("Personal event alarm") + verbose_name_plural = _("Personal event alarms") diff --git a/aleksis/core/schema/__init__.py b/aleksis/core/schema/__init__.py index a551a5ec8568cad8238a43d3ef68bdb3ca79aaa4..696e2867e85219523041d21c9172422c1f577b05 100644 --- a/aleksis/core/schema/__init__.py +++ b/aleksis/core/schema/__init__.py @@ -148,21 +148,15 @@ class Query(graphene.ObjectType): if has_person(info.context.user): qs = qs | Person.objects.filter(id=info.context.user.person.id) - active_school_term = get_active_school_term(info.context) - group_q = Q(school_term=active_school_term) | Q(school_term=None) - qs = ( - ( - qs - | Person.objects.filter( - member_of__in=Group.objects.filter(group_q).filter( - owners=info.context.user.person, - group_type__owners_can_see_members=True, - ), - ) + active_school_term = get_active_school_term(info.context) + group_q = Q(school_term=active_school_term) | Q(school_term=None) + qs = qs | Person.objects.filter( + member_of__in=Group.objects.filter(group_q).filter( + owners=info.context.user.person, + group_type__owners_can_see_members=True, + ), ) - .distinct() - .annotate_permissions(info.context.user) - ) + qs = qs.distinct().annotate_permissions(info.context.user) return graphene_django_optimizer.query(qs, info) def resolve_person_by_id(root, info, id): # noqa @@ -252,9 +246,9 @@ class Query(graphene.ObjectType): def resolve_pdf_by_id(root, info, id, **kwargs): # noqa pdf_file = PDFFile.objects.get(pk=id) - if has_person(info.context) and info.context.user.person != pdf_file.person: - return None - return pdf_file + if has_person(info.context) and info.context.user.person == pdf_file.person: + return pdf_file + return None def resolve_search_snippets(root, info, query, limit=-1, **kwargs): indexed_models = UnifiedIndex().get_indexed_models() diff --git a/aleksis/core/schema/personal_event.py b/aleksis/core/schema/personal_event.py index f97a1d0dfceb7dfde10077f988813c045a742ec9..3bf36b2e4c352cee626529002897cfc6095b6e3e 100644 --- a/aleksis/core/schema/personal_event.py +++ b/aleksis/core/schema/personal_event.py @@ -1,4 +1,4 @@ -from typing import Iterable +from collections.abc import Iterable from django.utils import timezone diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index 1bde194250b368081bb8ce1a15a3af147ad3aa28..11b27b5a16825109cbe8fce44b5b3a4ee2110bdd 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -583,13 +583,10 @@ YARN_INSTALLED_APPS = [ "jquery-sortablejs@^1.0.1", "sortablejs@^1.15.0", "@sentry/tracing@^7.28.0", - "luxon@^2.3.2", "@iconify/iconify@^2.2.1", "@iconify/json@^2.1.30", "@mdi/font@^7.2.96", "apollo-boost@^0.4.9", - "apollo-link-batch-http@^1.2.14", - "apollo-link-retry@^2.2.16", "apollo3-cache-persist@^0.14.1", "deepmerge@^4.2.2", "graphql@^15.8.0", @@ -615,6 +612,9 @@ YARN_INSTALLED_APPS = [ "vue-draggable-grid@^0.4.0", "rrule", "luxon@^3.4.3", + "apollo-upload-client@^18.0.1", + "@vitejs/plugin-legacy@^6.0.0", + "terser@^5.37.0", ] merge_app_settings("YARN_INSTALLED_APPS", YARN_INSTALLED_APPS, True) diff --git a/aleksis/core/static/print.css b/aleksis/core/static/print.css index 1c3e9d486a27e913671a453219c60b70b8778462..e65660d48517619b2346a2435320adcf4f4398d6 100644 --- a/aleksis/core/static/print.css +++ b/aleksis/core/static/print.css @@ -117,12 +117,23 @@ header .col { /* Some stuff for tables */ +table.thead { + display: table-row-group; + break-inside: avoid; +} + table.small-print, td.small-print, th.small-print { font-size: 10pt; } +table.tbody tr td, +table.tbody tr th { + break-inside: avoid !important; + break-after: auto; +} + tr { border-bottom: 1px solid rgba(0, 0, 0, 0.3); } diff --git a/aleksis/core/templates/core/vue_index.html b/aleksis/core/templates/core/vue_index.html index 8a000ad1d5e8147183207b00fe4ea5d4cecb4844..19e192432ac050d51ca23ed3a13bead25099a346 100644 --- a/aleksis/core/templates/core/vue_index.html +++ b/aleksis/core/templates/core/vue_index.html @@ -34,6 +34,8 @@ {% block no_frontend %} {% if not need_maintenance_response %} {% vite_asset 'aleksis/core/frontend/index.js' %} + {% vite_legacy_asset 'aleksis/core/frontend/index-legacy.js' %} + {% vite_legacy_polyfills nomodule=False %} {% endif %} {% endblock no_frontend %} </body> diff --git a/aleksis/core/tests/managers/test_aleksisbasemanager.py b/aleksis/core/tests/managers/test_aleksisbasemanager.py index 205bf023bfec007ee2e8c4114f35f59f14136c5e..3690831008fb9830fd4e847baae34685a3a6df51 100644 --- a/aleksis/core/tests/managers/test_aleksisbasemanager.py +++ b/aleksis/core/tests/managers/test_aleksisbasemanager.py @@ -1,18 +1,24 @@ - +import pytest from aleksis.core.models import Person -import pytest pytestmark = pytest.mark.django_db + def test_managed_by(): - managed_person = Person.objects.create(first_name="Jane", last_name="Doe", managed_by_app_label="core") + managed_person = Person.objects.create( + first_name="Jane", last_name="Doe", managed_by_app_label="core" + ) unmanaged_person_1 = Person.objects.create(first_name="Jane 2", last_name="Doe 2") unmanaged_person_2 = Person.objects.create(first_name="Jane 2", last_name="Doe 2") - assert list(Person.objects.managed_by_app("core")) == [managed_person] + assert list(Person.objects.managed_by_app("core")) == [managed_person] assert list(Person.objects.all()) == [unmanaged_person_1, unmanaged_person_2] assert list(Person.objects.unmanaged()) == [unmanaged_person_1, unmanaged_person_2] - assert list(Person.objects.managed_and_unmanaged()) == [managed_person, unmanaged_person_1, unmanaged_person_2] \ No newline at end of file + assert list(Person.objects.managed_and_unmanaged()) == [ + managed_person, + unmanaged_person_1, + unmanaged_person_2, + ] diff --git a/aleksis/core/tests/mixins/test_registry_object.py b/aleksis/core/tests/mixins/test_registry_object.py index d872e4a7078d27fd176a4b3f557bef3b55467fbb..9ee68d0a615844759e127e57ba44cc3c7999881f 100644 --- a/aleksis/core/tests/mixins/test_registry_object.py +++ b/aleksis/core/tests/mixins/test_registry_object.py @@ -1,5 +1,3 @@ -import pytest - from aleksis.core.mixins import RegistryObject diff --git a/aleksis/core/tests/models/test_calendar_event.py b/aleksis/core/tests/models/test_calendar_event.py index 6c65afa612871dad427dc6b2368f987a3d8c932c..f26e7dcdeccdaaea29698bd1acfe1a120b800f83 100644 --- a/aleksis/core/tests/models/test_calendar_event.py +++ b/aleksis/core/tests/models/test_calendar_event.py @@ -1,26 +1,36 @@ from datetime import datetime, timezone +from zoneinfo import ZoneInfo import pytest -from aleksis.core.models import CalendarEvent -from recurrence import Recurrence, WEEKLY, Rule +from recurrence import WEEKLY, Recurrence, Rule -from zoneinfo import ZoneInfo +from aleksis.core.models import CalendarEvent pytestmark = pytest.mark.django_db def test_calendar_event_timezone(): - datetime_start = datetime(2024, 1, 1, 0, 0, tzinfo=timezone.utc).astimezone(ZoneInfo("Europe/Berlin")) - datetime_end = datetime(2024, 12, 31, 0, 0, tzinfo=timezone.utc).astimezone(ZoneInfo("Europe/Berlin")) + datetime_start = datetime(2024, 1, 1, 0, 0, tzinfo=timezone.utc).astimezone( + ZoneInfo("Europe/Berlin") + ) + datetime_end = datetime(2024, 12, 31, 0, 0, tzinfo=timezone.utc).astimezone( + ZoneInfo("Europe/Berlin") + ) # No timezone set - calendar_event = CalendarEvent.objects.create(datetime_start=datetime_start, datetime_end=datetime_end) + calendar_event = CalendarEvent.objects.create( + datetime_start=datetime_start, datetime_end=datetime_end + ) calendar_event.refresh_from_db() assert calendar_event.datetime_start == datetime(2024, 1, 1, 0, 0, tzinfo=timezone.utc) assert calendar_event.datetime_end == datetime(2024, 12, 31, 0, 0, tzinfo=timezone.utc) - assert CalendarEvent.value_start_datetime(calendar_event) == datetime(2024, 1, 1, 0, 0, tzinfo=timezone.utc) - assert CalendarEvent.value_end_datetime(calendar_event) == datetime(2024, 12, 31, 0, 0, tzinfo=timezone.utc) + assert CalendarEvent.value_start_datetime(calendar_event) == datetime( + 2024, 1, 1, 0, 0, tzinfo=timezone.utc + ) + assert CalendarEvent.value_end_datetime(calendar_event) == datetime( + 2024, 12, 31, 0, 0, tzinfo=timezone.utc + ) assert calendar_event.timezone is None # Set timezone if not allowed diff --git a/aleksis/core/tests/models/test_holiday.py b/aleksis/core/tests/models/test_holiday.py index cacc860921c742351ed00d02da39607ad73e1695..02cb9de042d8bfc47d99ac3513bb3edb04d242a0 100644 --- a/aleksis/core/tests/models/test_holiday.py +++ b/aleksis/core/tests/models/test_holiday.py @@ -1,32 +1,37 @@ +from datetime import date, datetime + import pytest +from recurrence import WEEKLY, Recurrence, Rule -pytestmark = pytest.mark.django_db from aleksis.core.models import Holiday -from datetime import date, datetime -from recurrence import Recurrence, Rule, WEEKLY +pytestmark = pytest.mark.django_db def test_holiday_get_days(): - holiday = Holiday.objects.create(date_start=date(2024, 2, 1), date_end=date(2024, 2, 4), holiday_name="Test Holiday") + holiday = Holiday.objects.create( + date_start=date(2024, 2, 1), date_end=date(2024, 2, 4), holiday_name="Test Holiday" + ) assert set(holiday.get_days()) == { date(2024, 2, 1), date(2024, 2, 2), date(2024, 2, 3), - date(2024, 2, 4) + date(2024, 2, 4), } -def test_holiday_exdates(): - holiday = Holiday.objects.create(date_start=date(2024, 2, 1), date_end=date(2024, 2, 28), holiday_name="Test Holiday") +def test_holiday_exdates(): + holiday = Holiday.objects.create( + date_start=date(2024, 2, 1), date_end=date(2024, 2, 28), holiday_name="Test Holiday" + ) pattern = Recurrence(datetime(2024, 2, 3)) pattern.rrules.append(Rule(WEEKLY, until=datetime(2024, 6, 1))) - exdates = holiday.get_ex_dates(datetime(2024, 2,3), datetime(2024, 4, 1), pattern) + exdates = holiday.get_ex_dates(datetime(2024, 2, 3), datetime(2024, 4, 1), pattern) assert set(exdates) == { datetime(2024, 2, 3), datetime(2024, 2, 10), datetime(2024, 2, 17), - datetime(2024, 2, 24) + datetime(2024, 2, 24), } diff --git a/aleksis/core/tests/regression/test_regression.py b/aleksis/core/tests/regression/test_regression.py index c540111d38b29bb35b33fa562f78c06c74f2cd30..a578145dba3bf3c98ccffb8df00a4f78e3c0b7ee 100644 --- a/aleksis/core/tests/regression/test_regression.py +++ b/aleksis/core/tests/regression/test_regression.py @@ -1,16 +1,14 @@ import base64 from django.contrib.auth import get_user_model +from django.test import override_settings +from django.urls import reverse import pytest from aleksis.core.models import Group, OAuthApplication, Person pytestmark = pytest.mark.django_db -from django.http import HttpResponse -from django.test import override_settings -from django.urls import path, reverse -from django.views.generic import View def test_all_settigns_registered(): diff --git a/aleksis/core/tests/regression/view_oauth.py b/aleksis/core/tests/regression/view_oauth.py index d5671208e127e79c30d7bb179bbf2e82a35616fb..5116a66b48d86b34a063a85ec380face37495ec2 100644 --- a/aleksis/core/tests/regression/view_oauth.py +++ b/aleksis/core/tests/regression/view_oauth.py @@ -1,6 +1,5 @@ from django.http import HttpResponse -from django.test import override_settings -from django.urls import path, reverse +from django.urls import path from django.views.generic import View from oauth2_provider.views.mixins import ScopedResourceMixin diff --git a/aleksis/core/tests/schema/test_groups.py b/aleksis/core/tests/schema/test_groups.py index 7b7b2297efa9125faf042d2de3441ce7e8e2dff1..222e1aca5bc9ca68aea892bc3e5fd3930c37c02b 100644 --- a/aleksis/core/tests/schema/test_groups.py +++ b/aleksis/core/tests/schema/test_groups.py @@ -1,12 +1,8 @@ -import json -import pytest -from graphql.error.graphql_error import GraphQLError - -from aleksis.core.models import Group, GroupType, Person from django.contrib.auth.models import Permission -from aleksis.core.util.core_helpers import get_site_preferences +import pytest +from aleksis.core.models import Group, GroupType, Person pytestmark = pytest.mark.django_db @@ -17,19 +13,27 @@ def test_groups_query(client_query): wrong_group_type = GroupType.objects.create(name="wrong") group_not_owner = Group.objects.create(name="not_owner") - group_correct_group_type_owner = Group.objects.create(name="correct_group_type_owner", group_type=correct_group_type) + group_correct_group_type_owner = Group.objects.create( + name="correct_group_type_owner", group_type=correct_group_type + ) - group2_correct_group_type_owner = Group.objects.create(name="correct_group_type_owner", group_type=correct_group_type) - group_wrong_group_type_owner = Group.objects.create(name="wrong_group_type_owner", group_type=wrong_group_type) + group2_correct_group_type_owner = Group.objects.create( + name="correct_group_type_owner", group_type=correct_group_type + ) + group_wrong_group_type_owner = Group.objects.create( + name="wrong_group_type_owner", group_type=wrong_group_type + ) group_no_group_type_owner = Group.objects.create(name="no_group_type_owner") - for g in (group_correct_group_type_owner, group2_correct_group_type_owner, group_wrong_group_type_owner, group_no_group_type_owner): + for g in ( + group_correct_group_type_owner, + group2_correct_group_type_owner, + group_wrong_group_type_owner, + group_no_group_type_owner, + ): g.owners.add(p) - - response, content = client_query( - "{groups{id}}" - ) + response, content = client_query("{groups{id}}") assert len(content["data"]["groups"]) == 0 for g in Group.objects.all(): @@ -39,23 +43,26 @@ def test_groups_query(client_query): ) assert content["data"]["object"] is None - global_permission = Permission.objects.get(codename="view_group", content_type__app_label="core") + global_permission = Permission.objects.get( + codename="view_group", content_type__app_label="core" + ) p.user.user_permissions.add(global_permission) - response, content = client_query( - "{groups{id}}" + response, content = client_query("{groups{id}}") + assert set(int(g["id"]) for g in content["data"]["groups"]) == set( + Group.objects.values_list("id", flat=True) ) - assert set(int(g["id"]) for g in content["data"]["groups"]) == set(Group.objects.values_list("id", flat=True)) p.user.user_permissions.remove(global_permission) correct_group_type.owners_can_see_groups = True correct_group_type.save() - response, content = client_query( - "{groups{id}}" - ) - assert set(int(g["id"]) for g in content["data"]["groups"]) == {group_correct_group_type_owner.id, group2_correct_group_type_owner.id} + response, content = client_query("{groups{id}}") + assert set(int(g["id"]) for g in content["data"]["groups"]) == { + group_correct_group_type_owner.id, + group2_correct_group_type_owner.id, + } for g in (group_correct_group_type_owner, group2_correct_group_type_owner): response, content = client_query( @@ -64,7 +71,7 @@ def test_groups_query(client_query): ) assert content["data"]["object"]["id"] == str(g.id) - for g in (group_not_owner, group_wrong_group_type_owner, group_no_group_type_owner): + for g in (group_not_owner, group_wrong_group_type_owner, group_no_group_type_owner): response, content = client_query( "query groupById($id: ID) {object: groupById(id: $id) { id } }", variables={"id": g.id}, diff --git a/aleksis/core/tests/schema/test_persons.py b/aleksis/core/tests/schema/test_persons.py index 70b876129ce4d2051e21b17c12b67e464bd6b402..06f7de81c7127dd9d0817d1e6e02dcc7107a0472 100644 --- a/aleksis/core/tests/schema/test_persons.py +++ b/aleksis/core/tests/schema/test_persons.py @@ -1,8 +1,8 @@ +from django.contrib.auth.models import Permission + import pytest from aleksis.core.models import Group, GroupType, Person -from django.contrib.auth.models import Permission - pytestmark = pytest.mark.django_db @@ -13,17 +13,30 @@ def test_persons_query(client_query): wrong_group_type = GroupType.objects.create(name="wrong") group_not_owner = Group.objects.create(name="not_owner") - group_correct_group_type_owner = Group.objects.create(name="correct_group_type_owner", group_type=correct_group_type) + group_correct_group_type_owner = Group.objects.create( + name="correct_group_type_owner", group_type=correct_group_type + ) - group2_correct_group_type_owner = Group.objects.create(name="correct_group_type_owner", group_type=correct_group_type) - group_wrong_group_type_owner = Group.objects.create(name="wrong_group_type_owner", group_type=wrong_group_type) + group2_correct_group_type_owner = Group.objects.create( + name="correct_group_type_owner", group_type=correct_group_type + ) + group_wrong_group_type_owner = Group.objects.create( + name="wrong_group_type_owner", group_type=wrong_group_type + ) group_no_group_type_owner = Group.objects.create(name="no_group_type_owner") - for g in (group_correct_group_type_owner, group2_correct_group_type_owner, group_wrong_group_type_owner, group_no_group_type_owner): + for g in ( + group_correct_group_type_owner, + group2_correct_group_type_owner, + group_wrong_group_type_owner, + group_no_group_type_owner, + ): g.owners.add(p) correct_member = Person.objects.create(first_name="correct_member", last_name="correct_member") - correct_member_2 = Person.objects.create(first_name="correct_member_2", last_name="correct_member_2") + correct_member_2 = Person.objects.create( + first_name="correct_member_2", last_name="correct_member_2" + ) wrong_member = Person.objects.create(first_name="wrong_member", last_name="wrong_member") for g in (group_correct_group_type_owner, group2_correct_group_type_owner): @@ -32,11 +45,7 @@ def test_persons_query(client_query): for g in (group_not_owner, group_wrong_group_type_owner, group_no_group_type_owner): g.members.add(wrong_member) - - - response, content = client_query( - "{persons{id}}" - ) + response, content = client_query("{persons{id}}") assert len(content["data"]["persons"]) == 1 assert content["data"]["persons"][0]["id"] == str(p.id) @@ -45,25 +54,29 @@ def test_persons_query(client_query): "query personById($id: ID) {object: personById(id: $id) { id } }", variables={"id": g.id}, ) - assert content["data"]["object"] == None + assert content["data"]["object"] is None - global_permission = Permission.objects.get(codename="view_person", content_type__app_label="core") + global_permission = Permission.objects.get( + codename="view_person", content_type__app_label="core" + ) p.user.user_permissions.add(global_permission) - response, content = client_query( - "{persons{id}}" + response, content = client_query("{persons{id}}") + assert set(int(g["id"]) for g in content["data"]["persons"]) == set( + Person.objects.values_list("id", flat=True) ) - assert set(int(g["id"]) for g in content["data"]["persons"]) == set(Person.objects.values_list("id", flat=True)) p.user.user_permissions.remove(global_permission) correct_group_type.owners_can_see_members = True correct_group_type.save() - response, content = client_query( - "{persons{id}}" - ) - assert set(int(g["id"]) for g in content["data"]["persons"]) == {p.id, correct_member.id, correct_member_2.id} + response, content = client_query("{persons{id}}") + assert set(int(g["id"]) for g in content["data"]["persons"]) == { + p.id, + correct_member.id, + correct_member_2.id, + } for g in (correct_member, correct_member_2): response, content = client_query( @@ -76,4 +89,4 @@ def test_persons_query(client_query): "query personById($id: ID) {object: personById(id: $id) { id } }", variables={"id": wrong_member.id}, ) - assert content["data"]["object"] == None + assert content["data"]["object"] is None diff --git a/aleksis/core/tests/templatetags/test_data_helpers.py b/aleksis/core/tests/templatetags/test_data_helpers.py index 176e08b22ecb252d5b0113583ab534f46e978072..677c115ef94f0e9585520caf5e39053c444a4d21 100644 --- a/aleksis/core/tests/templatetags/test_data_helpers.py +++ b/aleksis/core/tests/templatetags/test_data_helpers.py @@ -8,7 +8,7 @@ pytestmark = pytest.mark.django_db def test_get_dict_object(): - class _Foo(object): + class _Foo: bar = 12 assert _Foo.bar == get_dict(_Foo, "bar") diff --git a/aleksis/core/tests/views/test_account.py b/aleksis/core/tests/views/test_account.py index fa55e8465bfa50b2a12479f6c72ee747cd1f2ef6..b6a6d48e548df6a7d748ffa745251df35fbe8352 100644 --- a/aleksis/core/tests/views/test_account.py +++ b/aleksis/core/tests/views/test_account.py @@ -49,7 +49,7 @@ def test_logout(client, django_user_model): ], AUTH_LDAP_SERVER_URI="ldap://[100::0]", AUTH_LDAP_SET_USABLE_PASSWORD=True, - **LDAP_SETTINGS + **LDAP_SETTINGS, ) def test_login_ldap_fail_if_previously_ldap_authenticated(client, django_user_model): username = "foo" diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py index d5870ee34e9d751ed693faede71749532e70c362..ad25573c525634a9d08f6a2822336502ea4f4185 100644 --- a/aleksis/core/urls.py +++ b/aleksis/core/urls.py @@ -30,12 +30,12 @@ urlpatterns = [ path("__icons__/", include("dj_iconify.urls")), path( "graphql/", - csrf_exempt(views.LoggingGraphQLView.as_view(batch=True)), + csrf_exempt(views.LoggingGraphQLView.as_view()), name="graphql", ), path("logo", force_maintenance_mode_off(views.LogoView.as_view()), name="logo"), path( - ".well-known/openid-configuration/", + ".well-known/openid-configuration", ConnectDiscoveryInfoView.as_view(), name="oidc_configuration", ), @@ -98,7 +98,7 @@ urlpatterns = [ ), path("accounts/", include("allauth.urls")), path( - "accounts/social/connections/<int:pk>/delete/", + "accounts/3rdparty/<int:pk>/delete/", views.SocialAccountDeleteView.as_view(), name="delete_social_account_by_pk", ), diff --git a/aleksis/core/util/apps.py b/aleksis/core/util/apps.py index fce211f57ea53d280841d7e74ce99d30f091827e..56816725acb3de1c43f150e8e33a6e80ba611f97 100644 --- a/aleksis/core/util/apps.py +++ b/aleksis/core/util/apps.py @@ -1,6 +1,7 @@ import logging +from collections.abc import Sequence from importlib import metadata -from typing import TYPE_CHECKING, Any, Optional, Sequence +from typing import TYPE_CHECKING, Any, Optional import django.apps from django.contrib.auth.signals import user_logged_in, user_logged_out diff --git a/aleksis/core/util/celery_progress.py b/aleksis/core/util/celery_progress.py index 008b979ec37207d05b2b22538a7761591ed8b22c..469c19a47ac2b70d518a934d0383edd369bf68f1 100644 --- a/aleksis/core/util/celery_progress.py +++ b/aleksis/core/util/celery_progress.py @@ -1,6 +1,7 @@ +from collections.abc import Generator, Iterable, Sequence from functools import wraps from numbers import Number -from typing import Callable, Generator, Iterable, Optional, Sequence, Union +from typing import Callable, Optional, Union from django.apps import apps from django.contrib import messages diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py index 71c3163af23d68d8305318be3486c72f402ed0b3..3a6aa841a4d26823e24c18a34b6e9ca50a4bfff7 100644 --- a/aleksis/core/util/core_helpers.py +++ b/aleksis/core/util/core_helpers.py @@ -1,11 +1,12 @@ import json import os +from collections.abc import Sequence from datetime import datetime, timedelta from importlib import import_module, metadata from itertools import groupby from operator import itemgetter from types import ModuleType -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Sequence, Union +from typing import TYPE_CHECKING, Any, Callable, Optional, Union from warnings import warn from django.conf import settings @@ -217,10 +218,7 @@ def has_person(obj: Union[HttpRequest, Model]) -> bool: return False person = getattr(obj, "person", None) - if person is None or getattr(person, "is_dummy", False): - return False - - return True + return not (person is None or getattr(person, "is_dummy", False)) def custom_information_processor(request: Union[HttpRequest, None]) -> dict: @@ -354,7 +352,7 @@ def get_allowed_object_ids(request: HttpRequest, models: list) -> list: return allowed_object_ids -def process_custom_context_processors(context_processors: list) -> Dict[str, Any]: +def process_custom_context_processors(context_processors: list) -> dict[str, Any]: """Process custom context processors.""" context = {} processors = tuple(import_string(path) for path in context_processors) @@ -478,8 +476,8 @@ def get_ip(*args, **kwargs): 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 + ( +EXTENDED_FEED_FIELD_MAP = feedgenerator.FEED_FIELD_MAP + (("color", "color"),) +EXTENDED_ITEM_ELEMENT_FIELD_MAP = feedgenerator.ITEM_ELEMENT_FIELD_MAP + ( ("color", "color"), ("meta", "x-meta"), ("reference_object", "reference_object"), @@ -498,7 +496,7 @@ class ExtendedICal20Feed(feedgenerator.ICal20Feed): cal.add("calscale", "GREGORIAN") cal.add("prodid", "-//AlekSIS//AlekSIS//EN") - for ifield, efield in feedgenerator.FEED_FIELD_MAP: + for ifield, efield in EXTENDED_FEED_FIELD_MAP: val = self.feed.get(ifield) if val is not None: cal.add(efield, val) @@ -520,7 +518,7 @@ class ExtendedICal20Feed(feedgenerator.ICal20Feed): component_type = item.get("component_type") element = Todo() if component_type == "todo" else Event() - for ifield, efield in feedgenerator.ITEM_ELEMENT_FIELD_MAP: + for ifield, efield in EXTENDED_ITEM_ELEMENT_FIELD_MAP: val = item.get(ifield) if val is not None: if ifield == "attendee": @@ -597,3 +595,4 @@ def filter_active_school_term_by_date( } ) ) + return qs diff --git a/aleksis/core/util/email.py b/aleksis/core/util/email.py index eae0e584604aa4e7141edcb6b244a2e1a079a762..99f0e1e71c25b5aa968c9323753ac50721bde795 100644 --- a/aleksis/core/util/email.py +++ b/aleksis/core/util/email.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional +from typing import Any, Optional from django.conf import settings @@ -9,8 +9,8 @@ from aleksis.core.util.core_helpers import get_site_preferences, process_custom_ def send_email( template_name: str, - recipient_list: List[str], - context: Dict[str, Any], + recipient_list: list[str], + context: dict[str, Any], from_email: Optional[str] = None, **kwargs, ): diff --git a/aleksis/core/util/frontend_helpers.py b/aleksis/core/util/frontend_helpers.py index 885ac39fd51833c55ce072cc8a425991cfea7db2..0565cfb2272c99723c189788a294040d50231300 100644 --- a/aleksis/core/util/frontend_helpers.py +++ b/aleksis/core/util/frontend_helpers.py @@ -1,7 +1,8 @@ import json import os import shutil -from typing import Any, Optional, Sequence +from collections.abc import Sequence +from typing import Any, Optional from django.conf import settings diff --git a/aleksis/core/util/notifications.py b/aleksis/core/util/notifications.py index 183858f9407ce5afb04c1dd8b60693ec4973cd02..d6126a9f3e5d274f0087c473dd7a63f38bbf80e5 100644 --- a/aleksis/core/util/notifications.py +++ b/aleksis/core/util/notifications.py @@ -1,6 +1,7 @@ """Utility code for notification system.""" -from typing import TYPE_CHECKING, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Union from django.apps import apps from django.conf import settings diff --git a/aleksis/core/util/pdf.py b/aleksis/core/util/pdf.py index 01bf7601c92cc81425f04268a6276509ea4ab4f5..1a606220150870444d8da8cee0dd0ad574173068 100644 --- a/aleksis/core/util/pdf.py +++ b/aleksis/core/util/pdf.py @@ -3,7 +3,7 @@ import os import subprocess # noqa from datetime import timedelta from tempfile import TemporaryDirectory -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Optional, Union from urllib.parse import urljoin from django.conf import settings @@ -89,7 +89,7 @@ def process_context_for_pdf(context: Optional[dict] = None, request: Optional[Ht def generate_pdf_from_html( html: str, request: Optional[HttpRequest] = None, file_object: Optional[PDFFile] = None -) -> Tuple[PDFFile, AsyncResult]: +) -> tuple[PDFFile, AsyncResult]: """Start a PDF generation task and return the matching file object and Celery result.""" html_file = ContentFile(html.encode(), name="source.html") @@ -119,7 +119,7 @@ def generate_pdf_from_template( request: Optional[HttpRequest] = None, render_method: Optional[Callable] = None, file_object: Optional[PDFFile] = None, -) -> Tuple[PDFFile, AsyncResult]: +) -> tuple[PDFFile, AsyncResult]: """Start a PDF generation task and return the matching file object and Celery result.""" processed_context = process_context_for_pdf(context, request) diff --git a/aleksis/core/views.py b/aleksis/core/views.py index be56108b6d3c6811b19d262e119993b4b238cda4..a356ad0df0ded55ee7bdb967ef5953bd054d8897 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -1,5 +1,5 @@ from textwrap import wrap -from typing import Any, Dict, Optional, Type +from typing import Any, Optional from urllib.parse import urlencode, urlparse, urlunparse from django.apps import apps @@ -46,7 +46,9 @@ from django_filters.views import FilterView from django_tables2 import SingleTableMixin, SingleTableView from dynamic_preferences.forms import preference_form_builder from graphene_django.views import GraphQLView -from graphql import GraphQLError +from graphql import ( + GraphQLError, +) from guardian.shortcuts import GroupObjectPermission, UserObjectPermission from haystack.generic_views import SearchView from haystack.inputs import AutoQuery @@ -134,6 +136,9 @@ from .util.core_helpers import ( from .util.forms import PreferenceLayout from .util.pdf import render_pdf +if settings.SENTRY_ENABLED: + import sentry_sdk + class LogoView(View): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: @@ -630,7 +635,7 @@ class DashboardWidgetListView(PermissionRequiredMixin, SingleTableView): class DashboardWidgetEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for dashboard widgets.""" - def get_form_class(self) -> Type[BaseModelForm]: + def get_form_class(self) -> type[BaseModelForm]: return modelform_factory(self.object.__class__, fields=self.fields) model = DashboardWidget @@ -905,12 +910,12 @@ class AssignPermissionView(SuccessNextMixin, PermissionRequiredMixin, DetailView form_class = AssignPermissionForm success_url = "manage_user_global_permissions" - def get_form_kwargs(self) -> Dict[str, Any]: + def get_form_kwargs(self) -> dict[str, Any]: kwargs = super().get_form_kwargs() kwargs["permission"] = self.get_object() return kwargs - def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: + def get_context_data(self, **kwargs: Any) -> dict[str, Any]: # Overwrite get_context_data to ensure correct function call order self.object = self.get_object() context = super().get_context_data(**kwargs) @@ -1265,8 +1270,17 @@ class TwoFactorLoginView(two_factor_views.LoginView): class LoggingGraphQLView(GraphQLView): """GraphQL view that raises unknown exceptions instead of blindly catching them.""" - def execute_graphql_request(self, *args, **kwargs): - result = super().execute_graphql_request(*args, **kwargs) + def execute_graphql_request( + self, request, data, query, variables, operation_name, show_graphiql=False + ): + if settings.SENTRY_ENABLED and operation_name: + scope = sentry_sdk.get_current_scope() + scope.set_transaction_name(operation_name) + + result = super().execute_graphql_request( + request, data, query, variables, operation_name, show_graphiql + ) + errors = result.errors or [] for error in errors: if not isinstance( diff --git a/aleksis/core/vite.config.js b/aleksis/core/vite.config.js index fb43a46a0a9533a5282f1b3424078791529d3186..c08d285ed2565c56c23c20e07c0ba838c8391f77 100644 --- a/aleksis/core/vite.config.js +++ b/aleksis/core/vite.config.js @@ -33,6 +33,7 @@ import topLevelAwait from "vite-plugin-top-level-await"; import browserslistToEsbuild from "browserslist-to-esbuild"; const license = require("rollup-plugin-license"); import SupportedBrowsers from "vite-plugin-browserslist-useragent"; +import legacy from "@vitejs/plugin-legacy"; // Read the hints writen by `aleksis-admin vite` const django_values = JSON.parse(fs.readFileSync("./django-vite-values.json")); @@ -301,6 +302,10 @@ export default defineConfig({ ignoreMinor: true, allowHigherVersions: true, }), + legacy({ + targets: browsersList, + modernPolyfills: true, + }), VitePWA({ injectRegister: "null", devOptions: { diff --git a/conftest.py b/conftest.py index 1a448a6f93b2cc6ae536c916c8a9ab56d5b9fe5a..6591233d81c8ec06a3bf2934c64e0023c52cdde4 100644 --- a/conftest.py +++ b/conftest.py @@ -30,15 +30,15 @@ def graphql_query( header_params = {"headers": headers} resp = client.post( graphql_url, - json.dumps([body]), + json.dumps(body), content_type="application/json", **header_params, ) else: resp = client.post( - graphql_url, json.dumps([body]), content_type="application/json" + graphql_url, json.dumps(body), content_type="application/json" ) - content = json.loads(resp.content)[0] + content = json.loads(resp.content) return resp, content diff --git a/docs/admin/10_install.rst b/docs/admin/10_install.rst index 0d35c8f65b5ce21d16d8f306368ea75ac957c92f..f7346c108c0537dc14b7eb76aef5208f7ca9c2db 100644 --- a/docs/admin/10_install.rst +++ b/docs/admin/10_install.rst @@ -32,7 +32,7 @@ For an installation on a dedicated server, the following prerequisites are neede * Valkey (or legacy Redis) * uWSGI * nginx - * Python 3.9 or newer + * Python 3.10 or newer * Node.js 18 or newer * Some system dependencies to build Python modules and manage frontend files * System locales for all supported languages diff --git a/pyproject.toml b/pyproject.toml index 214edf7e6487edcb6f3e4fb2f0b1537015b17212..cbae5d45357ead68b5ed875031f5e3eafb14a813 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ authors = [ "Lukas Weichelt <lukas.weichelt@teckids.org>", "Michael Bauer <michael-bauer@posteo.de>" ] -maintainers = ["Jonathan Weth <dev@jonathanweth.de>", "Dominik George <dominik.george@teckids.org>"] +maintainers = ["Jonathan Weth <jonathan.weth@teckids.org>", "Dominik George <dominik.george@teckids.org>"] license = "EUPL-1.2-or-later" homepage = "https://aleksis.org" repository = "https://edugit.org/AlekSIS/official/AlekSIS-Core" @@ -61,10 +61,10 @@ python = "^3.10" Django = "^5.1" django-any-js = "^1.1" # Legacy django-tables2 = "^2.1" # Legacy -django-phonenumber-field = {version = "^7.0", extras = ["phonenumbers"]} +django-phonenumber-field = {version = "^8.0", extras = ["phonenumbers"]} colour = "^0.1.5" dynaconf = {version = "^3.1", extras = ["yaml", "toml", "ini"]} -django-auth-ldap = { version = "^4.0", optional = true } +django-auth-ldap = { version = "^5.1", optional = true } django-maintenance-mode = "^0.21.0" django-ipware = "^7.0" django-impersonate = "^1.4" @@ -103,11 +103,11 @@ django-prometheus = "^2.1.0" django-model-utils = "^5.0.0" bs4 = "^0.0.2" django-invitations = "^2.0.0" -django-allauth = "^0.63.6" +django-allauth = "^65.0.0" django-uwsgi-ng = "^2.0" django-extensions = "^3.1.1" ipython = "^8.0.0" -django-oauth-toolkit = "^2.0.0" +django-oauth-toolkit = "^3.0.0" django-storages = {version = "^1.14.2", optional = true} boto3 = {version = "^1.34.52", optional = true} django-cleanup = "^9.0.0" @@ -122,7 +122,7 @@ django-iconify = "^0.4" customidenticon = "^0.1.5" graphene-django = ">=3.0.0, <=3.2.2" selenium = "^4.4.3" -django-vite = "^3.0.0" +django-vite = "^3.0.6" graphene-django-cud = "^0.13.0" django-ical = "^1.9.2" django-recurrence = "^1.11.1" @@ -146,16 +146,16 @@ aleksis-admin = 'aleksis.core.__main__:aleksis_cmd' django-stubs = "^4.2" safety = "^2.3.5" -ruff = "^0.1.5" +ruff = "^0.8.2" [tool.poetry.group.test.dependencies] -pytest = "^7.2" -pytest-django = "^4.1" +pytest = "^8.3" +pytest-django = "^4.9" pytest-django-testing-postgresql = "^0.2" -pytest-cov = "^4.0.0" -pytest-sugar = "^0.9.2" -selenium = "<4.10.0" -freezegun = "^1.1.0" +pytest-cov = "^6.0.0" +pytest-sugar = "^1.0.0" +selenium = "^4.27.0" +freezegun = "^1.5.0" [tool.poetry.group.docs] optional = true @@ -166,20 +166,20 @@ sphinxcontrib-django = "^2.3.0" sphinxcontrib-svg2pdfconverter = "^1.1.1" sphinx-autodoc-typehints = "^1.7" sphinx_material = "^0.0.35" - [tool.ruff] -exclude = ["migrations", "tests"] +exclude = ["migrations"] line-length = 100 [tool.ruff.lint] select = ["E", "F", "UP", "B", "SIM", "I", "DJ", "A", "S"] ignore = ["UP034", "UP015", "B028"] - -[tool.ruff.isort] +[tool.ruff.lint.extend-per-file-ignores] +"**/*/tests/**/*.py" = ["S101", "ARG", "FBT", "PLR2004", "S311", "S105", "S107"] +[tool.ruff.lint.isort] known-first-party = ["aleksis"] section-order = ["future", "standard-library", "django", "third-party", "first-party", "local-folder"] -[tool.ruff.isort.sections] +[tool.ruff.lint.isort.sections] django = ["django"] [build-system] requires = ["poetry-core>=1.0.0"]