Skip to content
Snippets Groups Projects
Verified Commit 1cf488b1 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Merge branch 'master' into...

Merge branch 'master' into 300-allow-using-time-slot-numbers-in-long-term-absences-dialog-instead-of-datetimes
parents f447db9f 9e24f1ee
No related branches found
No related tags found
1 merge request!464Resolve "Allow using time slot numbers in long term absences dialog (instead of datetimes)"
Pipeline #195654 failed
Showing
with 377 additions and 302 deletions
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"],
},
},
],
},
},
],
};
......@@ -2,10 +2,12 @@
"name": "aleksis-builddeps",
"version": "1.0.0",
"dependencies": {
"@intlify/eslint-plugin-vue-i18n": "^2.0.0",
"@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",
"graphql": "^16.10.0",
"prettier": "^3.4.0",
"stylelint": "^15.0.0",
"stylelint-config-prettier": "^9.0.3",
......
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",
},
};
......@@ -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
......@@ -92,3 +94,5 @@ htmlcov/
# Data
maintenance_mode_state.txt
media/
aleksis/core/static/style.css
......@@ -20,9 +20,10 @@ import CancelButton from "aleksis.core/components/generic/buttons/CancelButton.v
{{ $t("alsijil.coursebook.print.title") }}
</template>
<template #content>
{{ $t("alsijil.coursebook.print.groups") }}
<v-autocomplete
v-if="!group"
:items="availableGroups"
:label="$t('alsijil.coursebook.print.groups')"
item-text="name"
item-value="id"
:value="value"
......@@ -87,7 +88,16 @@ export default {
*/
availableGroups: {
type: Array,
required: true,
required: false,
default: () => [],
},
/**
* Set a group to use this dialog exclusively for
*/
group: {
type: Object,
required: false,
default: null,
},
/**
* Initially selected groups
......@@ -121,6 +131,9 @@ export default {
},
computed: {
selectedGroups() {
if (this.group) {
return [this.group.id];
}
if (this.currentGroupSelection.length == 0) {
return this.value.map((group) => group.id);
} else {
......
query personalNotes($orderBy: [String], $filters: JSONString) {
items: personalNotes(orderBy: $orderBy, filters: $filters) {
id
note
extraMark {
id
}
canEdit
canDelete
}
}
mutation createPersonalNotes($input: [BatchCreatePersonalNoteInput]!) {
createPersonalNotes(input: $input) {
items: personalNotes {
......
......@@ -10,6 +10,9 @@
:show-select="false"
@items="items = $event"
>
<template #additionalActions>
<coursebook-print-dialog :group="group" />
</template>
<template
v-for="(extraMark, index) in extraMarks"
#[`extraMarks.${index}.count`]="{ item }"
......@@ -65,11 +68,11 @@
i18n-key="alsijil.coursebook.statistics.person_view_details"
icon-text="mdi-open-in-new"
:to="{
name: 'alsijil.coursebook_statistics',
name: 'core.personById',
params: {
personId: item.person.id,
mode: MODE.PARTICIPATIONS,
id: item.person.id,
},
hash: '#' + MODE.PARTICIPATIONS,
}"
/>
</template>
......@@ -81,13 +84,14 @@ import groupOverviewTabMixin from "aleksis.core/mixins/groupOverviewTabMixin.js"
import CRUDList from "aleksis.core/components/generic/CRUDList.vue";
import PersonChip from "aleksis.core/components/person/PersonChip.vue";
import SecondaryActionButton from "aleksis.core/components/generic/buttons/SecondaryActionButton.vue";
import CoursebookPrintDialog from "../CoursebookPrintDialog.vue";
import AbsenceReasonChip from "aleksis.apps.kolego/components/AbsenceReasonChip.vue";
import ExtraMarkChip from "aleksis.apps.alsijil/components/extra_marks/ExtraMarkChip.vue";
import { statisticsByGroup } from "./statistics.graphql";
import { absenceReasons } from "../queries/absenceReasons.graphql";
import { extraMarks } from "../../extra_marks/extra_marks.graphql";
import { extraMarks } from "../queries/extraMarks.graphql";
import { MODE } from "./modes";
export default {
......@@ -99,6 +103,7 @@ export default {
ExtraMarkChip,
PersonChip,
SecondaryActionButton,
CoursebookPrintDialog,
},
data() {
return {
......
......@@ -7,18 +7,7 @@
<v-card-title v-else-if="compact">
{{ $t("alsijil.coursebook.statistics.person_compact.title") }}
<v-spacer />
<base-button
:icon="true"
icon-text="mdi-open-in-new"
i18n-key=""
:to="{
name: 'alsijil.coursebook_statistics',
params: {
personId: person.id,
mode: MODE.PARTICIPATIONS,
},
}"
/>
<slot name="header" />
</v-card-title>
<v-card-title v-else>
{{ $t("alsijil.coursebook.statistics.title_plural") }}
......@@ -59,7 +48,6 @@
<script>
import personOverviewCardMixin from "aleksis.core/mixins/personOverviewCardMixin.js";
import BaseButton from "aleksis.core/components/generic/buttons/BaseButton.vue";
import MessageBox from "aleksis.core/components/generic/MessageBox.vue";
import StatisticsAbsencesCard from "./StatisticsAbsencesCard.vue";
import StatisticsTardinessCard from "./StatisticsTardinessCard.vue";
......@@ -73,7 +61,6 @@ export default {
name: "StatisticsForPersonCard",
mixins: [personOverviewCardMixin],
components: {
BaseButton,
MessageBox,
StatisticsAbsencesCard,
StatisticsTardinessCard,
......@@ -111,6 +98,9 @@ export default {
MODE() {
return MODE;
},
mode() {
return this.$hash;
},
gridTemplateAreas() {
return this.compact
? `"absences extra_marks" "tardinesses tardinesses"`
......
......@@ -2,6 +2,13 @@
<fullscreen-dialog-page
:fallback-url="{ name: 'core.personById', props: { id: personId } }"
>
<template #title>
{{
$t("alsijil.coursebook.statistics.person_page.title", {
fullName: personName?.fullName || "???",
})
}}
</template>
<div class="d-flex" style="gap: 4em">
<div class="flex-grow-1" style="max-width: 100%">
<!-- documentations for person list -->
......@@ -172,6 +179,14 @@
<v-list-item-action
class="flex-row full-width justify-md-end ma-0 align-center fill-height"
>
<v-chip
color="warning"
class="mx-1"
v-if="!item.relatedDocumentation.amended"
>{{
$t("alsijil.coursebook.statistics.not_counted")
}}</v-chip
>
<!-- chips: absences & extraMarks -->
<absence-reason-chip
v-if="item.absenceReason"
......@@ -301,11 +316,6 @@ export default {
type: [Number, String],
required: true,
},
mode: {
type: String,
required: false,
default: MODE.PARTICIPATIONS,
},
},
apollo: {
personName: {
......@@ -315,13 +325,6 @@ export default {
person: this.personId,
};
},
result({ data }) {
this.$setToolBarTitle(
this.$t("alsijil.coursebook.statistics.person_page.title", {
fullName: data.personName.fullName || "???",
}),
);
},
},
absenceReasons: {
query: absenceReasons,
......@@ -346,6 +349,9 @@ export default {
MODE() {
return MODE;
},
mode() {
return this.$hash;
},
},
methods: {
gqlQuery() {
......@@ -360,12 +366,9 @@ export default {
this.selected = [];
this.$router.push({
name: "alsijil.coursebook_statistics",
params: {
personId: this.personId,
mode: mode,
},
this.$router.replace({
...this.$route,
hash: "#" + mode,
});
},
showEdit(item) {
......
<template>
<statistics-for-person-card v-bind="{ ...$attrs, ...$props }">
<template #header>
<base-button
:icon="true"
icon-text="mdi-open-in-new"
i18n-key=""
:to="{
name: $route.name,
params: $route.params,
hash: '#' + MODE.PARTICIPATIONS,
}"
/>
<statistics-for-person-page
v-if="Object.values(MODE).includes(mode)"
:person-id="person.id"
/>
</template>
</statistics-for-person-card>
</template>
<script>
import personOverviewCardMixin from "aleksis.core/mixins/personOverviewCardMixin.js";
import BaseButton from "aleksis.core/components/generic/buttons/BaseButton.vue";
import StatisticsForPersonPage from "./StatisticsForPersonPage.vue";
import StatisticsForPersonCard from "./StatisticsForPersonCard.vue";
import { MODE } from "./modes";
export default {
name: "StatisticsForPersonWidget",
mixins: [personOverviewCardMixin],
components: {
BaseButton,
StatisticsForPersonPage,
StatisticsForPersonCard,
},
computed: {
MODE() {
return MODE;
},
mode() {
return this.$hash;
},
},
};
</script>
export const MODE = {
PARTICIPATIONS: "participations",
PERSONAL_NOTES: "personal_notes",
PARTICIPATIONS: "alsijil.participations",
PERSONAL_NOTES: "alsijil.personal_notes",
};
......@@ -64,6 +64,7 @@ query participationsOfPerson($person: ID!) {
colourFg
colourBg
}
amended
}
canEdit
canDelete
......
<script>
import { extraMarks } from "./extra_marks.graphql";
import { extraMarksList } from "./extra_marks.graphql";
export default {
name: "ExtraMarkButtons",
......@@ -10,7 +10,7 @@ export default {
},
apollo: {
extraMarks: {
query: extraMarks,
query: extraMarksList,
update: (data) => data.items,
skip() {
return this.customExtraMarks.length > 0;
......
......@@ -87,7 +87,7 @@ import InlineCRUDList from "aleksis.core/components/generic/InlineCRUDList.vue";
<script>
import formRulesMixin from "aleksis.core/mixins/formRulesMixin.js";
import {
extraMarks,
extraMarksList,
createExtraMarks,
deleteExtraMarks,
updateExtraMarks,
......@@ -121,7 +121,7 @@ export default {
},
],
i18nKey: "alsijil.extra_marks",
gqlQuery: extraMarks,
gqlQuery: extraMarksList,
gqlCreateMutation: createExtraMarks,
gqlPatchMutation: updateExtraMarks,
gqlDeleteMutation: deleteExtraMarks,
......
query extraMarks($orderBy: [String], $filters: JSONString) {
query extraMarksList($orderBy: [String], $filters: JSONString) {
items: extraMarks(orderBy: $orderBy, filters: $filters) {
id
shortName
......
import { DateTime } from "luxon";
import { MODE } from "./components/coursebook/statistics/modes";
export const collectionItems = {
coreGroupActions: [
......@@ -32,7 +31,7 @@ export const collectionItems = {
key: "core-person-widgets",
component: () =>
import(
"./components/coursebook/statistics/StatisticsForPersonCard.vue"
"./components/coursebook/statistics/StatisticsForPersonWidget.vue"
),
shouldDisplay: () => true,
colProps: {
......@@ -113,21 +112,5 @@ export default {
permission: "alsijil.view_extramarks_rule",
},
},
{
path: `statistics/:personId/:mode(${Object.values(MODE).join("|")})`,
component: () =>
import(
"./components/coursebook/statistics/StatisticsForPersonPage.vue"
),
name: "alsijil.coursebook_statistics",
props: true,
meta: {
inMenu: false,
titleKey: "alsijil.coursebook.statistics.person_compact.title",
toolbarTitle: "alsijil.coursebook.statistics.person_compact.title",
// TODO: Add permission & change it here.
permission: "alsijil.view_documentations_menu_rule",
},
},
],
};
......@@ -82,7 +82,8 @@
"title": "Kursbuch · Statistiken · {fullName}"
},
"person_view_details": "Details",
"title_plural": "Statistiken"
"title_plural": "Statistiken",
"not_counted": "nicht gezählt"
},
"status": {
"available": "Kursbucheintrag vorhanden",
......
......@@ -85,7 +85,8 @@
"summary": "Summary"
},
"person_view_details": "Details",
"title_plural": "Statistics"
"title_plural": "Statistics",
"not_counted": "not counted"
},
"notes": {
"show_list": "List of participants",
......
......@@ -2,6 +2,7 @@ from django.db.models import FilteredRelation, Q, QuerySet, Value
from django.db.models.aggregates import Count, Sum
from django.utils.translation import gettext as _
from aleksis.apps.chronos.models import LessonEvent
from aleksis.apps.kolego.models import AbsenceReason
from aleksis.core.models import Group, Person, SchoolTerm
......@@ -137,13 +138,6 @@ def annotate_person_statistics_for_school_term(
datetime_end__date__lte=school_term.date_end,
)
if group:
documentations = documentations.filter(
pk__in=Documentation.objects.filter(course__groups=group)
.values_list("pk", flat=True)
.union(
Documentation.objects.filter(course__groups__parent_groups=group).values_list(
"pk", flat=True
)
)
)
lesson_events = LessonEvent.objects.filter(LessonEvent.objects.for_group_q(group))
documentations = documentations.filter(amends__in=lesson_events)
return annotate_person_statistics_from_documentations(persons, documentations)
......@@ -48,6 +48,7 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
course = graphene.Field(CourseType, required=False)
amends = graphene.Field(lambda: LessonEventType, required=False)
amended = graphene.Boolean(required=False)
subject = graphene.Field(SubjectType, required=False)
participations = graphene.List(ParticipationStatusType, required=False)
......@@ -66,6 +67,11 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
return root._amends_prefetched
return root.amends
@staticmethod
@bypass_get_queryset
def resolve_amended(root: Documentation, info, **kwargs):
return root.amends_id is not None
@staticmethod
@bypass_get_queryset
def resolve_teachers(root: Documentation, info, **kwargs):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment