Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • AlekSIS/official/AlekSIS-App-Alsijil
  • sunweaver/AlekSIS-App-Alsijil
  • 8tincsoVluke/AlekSIS-App-Alsijil
  • perfreicpo/AlekSIS-App-Alsijil
  • noifobarep/AlekSIS-App-Alsijil
  • 7ingannisdo/AlekSIS-App-Alsijil
  • unmruntartpa/AlekSIS-App-Alsijil
  • balrorebta/AlekSIS-App-Alsijil
  • comliFdifwa/AlekSIS-App-Alsijil
  • 3ranaadza/AlekSIS-App-Alsijil
10 results
Show changes
Commits on Source (19)
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):
......