From 884fc8d5b02bd84ab96efe5f8591653d6d211507 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Tue, 19 Sep 2023 13:45:41 +0200 Subject: [PATCH 01/10] VBV-488: create edoniq sftp client --- env_secrets/local_daniel.env | Bin 539 -> 971 bytes env_secrets/prod-azure.json | Bin 4698 -> 5192 bytes server/requirements/requirements-dev.txt | 8 +++ server/requirements/requirements.in | 1 + server/requirements/requirements.txt | 8 +++ .../edoniq_test/result_import/__init__.py | 0 .../result_import/edoniq_sftp_connection.py | 63 ++++++++++++++++++ .../tests/edoniq_pruefung_resultate.csv | 6 ++ 8 files changed, 86 insertions(+) create mode 100644 server/vbv_lernwelt/edoniq_test/result_import/__init__.py create mode 100644 server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py create mode 100644 server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv diff --git a/env_secrets/local_daniel.env b/env_secrets/local_daniel.env index 2a0d57f30ff79c98c92fdc9e2bb20822e31df6f4..9a1c2df5cf987af71f5c5ecdc61ca75f7e7eadf9 100644 GIT binary patch literal 971 zcmV;+12p^qM@dveQdv+`08Z*`Y>&>Vgm1R%VO{i^*z)Z0dLk(`U1m&U{Cr5w8DyYo z_HeQ{eB%sS-kKDa{a_f$xf(~M7dzN}d*O;cgTsG3E+1#`qkCRv{%Q@)P17l5{Y0qU zWh@`Bbd8lXIQgAze&TCjgw%vhaP(x^l7(pDG5p8lb}6y7-WO_CF7XXhuL^dmOq)~_ z1hznpR?3Hg(^zL{Dq$qTDqE36s?yaC=JaQ1&ipPr%+Y^T9GZi1^zi7$YNgL1)m_*? zO6QvRDxdKzDx@zoUU`|v(g)2Vy?OfTkSX+h;f>Vm`*TrVfmj_3GI zM+keLa1x}m`|?V2FNW)glhs$-%a_hD)W&95>5W0KuGg>$ekiOTkr69C8vm#@@kd%? z1lhgrsv`bh(ELAb$xe-hok|T5(0;(^ntDZQh?F#)f zi0n%o6yd97>MWiqJqY!rE~3g!;t(O7a*nWi0h1{=9vb2W8^Gs~_IpRp$*sirn$NFN zL8#ME>xzalEYgA1nFQ_gx@Ob5kC3=eITw1w3JNOS$H8{QYsGWS+Gtb{><3?kAsx$t z^*`3MN=_{S;z{`sg8^7$J&o>J{zsOk}5RB!fZ;mb!1K_45G_f3u+;+ zP&K~Lc)+IS_NuuqkyFOFcA{BrB=6e9s(DwTJptvLCns79DnA;+kT%98S(8_F%0{s0 zkv#>2o>dt$7kp{!LViE(q)C(6roUR7Frh} zXLvk{KduZOhLb93rRHqg9PI-0 z1dBXDjv^e?2RT#kw6QN#5-bx@$mU&w?=Tt_%#0GC+I(s!mu>(NDL}MweEI=)x9n+2h^4pFUp2 z#(ta46n!d|-pIJG+~O^*4>Y8|4)v1_0v2Z)U>+Un=xyuRkb!Qp@ zc&wh=Ebl>ZvbSmDPx96krot0hq&|X77o=paVI^?TN4e=BO9B&dpb{njS)XX%S!@^A zn)L)Xj?b@A<$sv-c_?a1$Y8g(hfQLR;+?;K<(xn#_>7G`N4Uh@FL2x^Af5}_a9;;n d!XV|ESBRJ9<^l0|8hLlJT1gG+eV=PM7{B*y2?GEC diff --git a/env_secrets/prod-azure.json b/env_secrets/prod-azure.json index 453296ed5ffb3b4d60dc2971cb4f872fcac0b7ae..edb6cff1c1b1691c018f1f29008214e2a71ee035 100644 GIT binary patch literal 5192 zcmV-O6u0XDM@dveQdv+`0Q`CD5kQOPP!_opF_PBinAHwyP0w+(Wd>pCQ#f4ig7W;B zEsIrrgCo3=l+^c=ieN1dLa{#n(XJDbS(QJ=IE*;-=Vv4b`l}^XdOkFxAj5CDF$wwb z*i6R2SiJ9r2u)ZhmF_SRb~nPx3aU%u%%!V6!!Bxbw-5-rD_r(%c4`oU8d}$4l8f%% z=Ep5_tz;*oGz?11-sSO-hxpwEcv&S*7xKmo{SR;V;VdnCJg(>Ud5y-GG^=y(vjx}k zn%RZ)ubHCH1Sv{05Dbe6%kIIE03fU9rve&Mv+e34c{SWB_7xa-P$8`$X;uA+JHvSz z8j3+xQEXbgE)$WCl|&%ORpu&1%!4Y4;%!LaYySPx$V%U)Qfx2KlX@*5m;2?-%9dig zyGnD|Sk748u$g)1=$ozD_tM7=$CWq_I>XX^;t(3RrxBlLkXnpb~be*EhC!hrITwuwlcU&Op;( zP&Ow^DRjIvWy9}8u&Z)SsK((6%qZ(_s^Qz5z6I*SV zxGr=K!Dv}<3k8)ptr{0ksE1iyU!?XL0<2$r>!d2PFQ@U%?x>DNPV=k46QInUVidQQ zEhZCuc@FB7q)wq(hvc9+A{uKw`p4s|@=h&aCi;mj>EA}7r3&m`!B;KS6(Xum)arFU zYuaZ&C>JenG$d79`xhf`(&y_~h+7PHi)ccyc<(psv0edJ9v-ybLR$5`ijt5L_tlw& zycOC+1jDkRqtCz9FIoM9-2MimL&t~DYoG_qmZRgr2wcee)#_44wDt`?V=rCvDnMpF zksU0`6hpta?VEZE!Atg-*El?Qy+tF`@(J^N6% zN(Ce$!0GwCGBe04C^9y?qsU)luj`r6mOUd4{|5MjO*9MeGhv`m4<}Y9gkHThpB7|o zVre4Y=+EI(ecw zYkJ*Tq@jtRG95;r0K+uXL@uPxL}{t9(!Rl>6CJC~0eJaJ5j@|0g+o>HG@gQDQ1q2U zAQQJDa}6c$uKQ~$?1{U_5+fx1FlCwa!7>w>`=W62yn_s_u#eK`K&5L4egTfdW@&2jw@K8KH~kMH@wVQ!HKgxuXU;Qtcsjh?&pgHlog59o0MaoMmT#a^f~cwSAJY$WHop`CGsZRkwvBjwOjPk|Q(AbHcg zI)@!5>T`zaa$O#E;HzPq3^oCZc2B~FIY?BiZL z&Ba2KK=N|GtGsZ6DwcMScxz&z%l)6k)h+~?r1_<-HtMjS0khuV$z!<7Lls9CCAp7` zOuMY3s4-YbOrmVeSd0`6w5NkA=JB&Owp#fvn=qEO}6)GIqXUv;$z!Opq(vG7?g@(Th6 z=Ci5jPx$E`s#GCa7AsxIN0dtF{sY0+bd-@?Kq$oB{NfoH@Tr+CvT{zZHBaU-$Xjs{ zcOmL)ic{0i1ru)NXpOu4S)IdepYsDrNFOjsa*rX6rVPr(E5Sm0Jq)kJgD`#8e{dC+ zKn2pfHiYq z+y&_O54;fNRC;$<3h*@ii^Xab^%9c}c_PKz3vFYAMl7I+`r77IDcoo5hxZf>QsVz3 z4hx+1z?IgL!TY+!DnfOhtn{Y_+E8Nfdo`XMy4ah|(@@6E7$bvqh?G5%1wmtLpHmRQ zzT=iM8nO%~1U4Pwb|rSUp{6MB&De#}FXfPVLq^Y)vXRLs6)LUX^Q|uJb+zn8l!MrQ zPEXYw_XYv+Q$mdV z-txFx!ou9PJ!rJnn{?_Nl?eQeHyyf~vQvt0gsC6Rrdp6)3oTt?DcU<=$}F3Hc$g;D zxU^gINep2Yi|?N|Wh5$hH5J9UUM~#&uI1j70G1+^W+EbGTD$bwgNb@$@IdWGt{wbE zB9A{YVJbK@Nk-i=4V3SVHL@Gz^`GAeg{U5>BL+ucdRJrVkImJdk#hIJjaUsEk!YmPuJLT6vO((MQ( zgfYZDlz&wo^F`x^cx%UO>Y3|Z(~J1h+>t-bG%+HJ$2!Ab30F{z_O325o3*li>Q6l1AHmJh`R;Ys zGXLEIz{k2%Cj^NHLO!WENA%@k~d>oOK(v^6$&0Fg;2`)s5@l7Jr-K@e=F#*m<4xAQVw zsWa4nXiK|Z!B_KGa#2kc+v&P|uo+jZ=K|$e3X*kT$2Rev`{L zgE-nfn+-#|%A1beBcu9BCG|+HwyI}xNsQXa3(w7qjFO!yp8oWiMMM#$Ntd+$i4On9 zbDuNI=pi~s)r)CoEfGSl{tZ$zFb3=iGI^@h2K;hIBVqlp%>5AZ5sR1?Ojy2CP+%?l zQaG$|emrg?#sVtC^El};OdT#hkHhFY(DK;}n8s-jv#+KD1lJ00>T%jnp1}x}*HL|D z3E2LCQWJ_`Iba`@IS>CV{*?HW5d%Ujm3yds7t#YQ;6`p$F#V0P<|YLJ-;mG)grn zZKyZ)ct}=|?c}~*xukQ8##!f`6^@r!`%)+ie!M7Y@~-;*vMfq_A)T<^as~3ga-~^?T1wPkUj+SO0^gwTnep{mkntdWc{x6q&Dm&Zet1=gQX!1QNFwJAFZn3d{U8qP0kLCCAdAJ} z1?GszHpuQHw`<>Qf9UP*cz9qqwbTq%N`EyV1uJVidkDcX8-l*>s|>^tU-PDJsPOP? zxcz`m@a!08p>tm!;CHY1_-ti_Ee+$PXsm-DQb4YS;A;e|=0mebxl~bxzeGrVb>#p8 zx&dLNT3r`m#-__Gp9h?iCcsp=v;zWJBRh~LyfD|NQ1mk#$6X)`8D@`3>o)~ld~}JR z!x{HKA{21l+E+8-h^4?ecV7N~TJdUGmmZOh0MB<1lVQ)iYNB~%lLiVw}yqa^~YEvYwGo>JAQ?5xsW(J4hxgql7VXo#Zv@ zW}U60^h=Auo{yKe??_j0L-Oz4KcVnPKJ^>w0*GoPS#J&n*o;PAn#`2koESLJ$3!E<-}U>aI{NNHwN+_cGtce1$X3vZm6*Q`Aepd7KqCs&a?`4 zn0Xa3Vihde2f!V2f(}BMN-8{nPL`amTMs2)`Eew>$opEEd%e8|s9@&~&g$NL##UWk z-yz*Fey76ZuAxyxtp^bj0`P;qYW3w1&+b}CQ$Ch7Bx9PNrT zRqeG{m)3>Xk}`L7b?l7i4sDQh(W0UtugXVfzINNs)*fD%7n*=Lx!=5@bp=Wv+u)kw zmJPJ~UgbWUD}+V<7Hdf_^l%hv<~c}DR26hLn|T(wKef*mWyjq3bqgyl(x~nkSXB1m zRv%r*mP@y^K7VcCYXsc19>hoAD`mHVyL~MP?xbe-8at#O%IXnN^5sq*4H5(NxiqN_ zq1BpUyts|OkptD8jYPk?1Q6cnPGZYmtLW6GqIgH!S6IurdUMT@a~k}osEz6;ah(jBI!Py>suATI{K zF2(NoM4?hVA9?5FW8dab{3wXuNP;=;Qgvd^&Wmwbc&Jo{^VEUgfgcKc*a?LwQRy*UBQ-l5D+b(UPIt?`8SP`R#Kw#HkS zGF0DFrjvm?&H|O&21ubirJ7^t3X|2$p~a5BX+cM)p=&&GDTjxkD^CER#;}Gqg4_?K z11OUjXv3bPjA+u?LTNlO-El?mb}q0gNl;id=Ay4-D*6AViBZPMlvVde;jASZgwM-A z5-g2=8NO)FBkBBphlBN~ z^0ztso2RBVOZQ-~l5B6o{ORiO8@);qOBTELFh~=7Iv?wVv>?Go*#XTKaIBFhLKNCY Cq8Gvd literal 4698 zcmV-g5~b|`M@dveQdv+`03ra`WaR zlOoT&yrRW=b>H+VNR_5l4%L7K$?Q)>tyT1?dhbs2?5TW$dxCu)()Ii-rT#e$4@!>g zwirCCpn0(nWW6;!P#F|hHg%oa-*DO__N-V9WYB!XZ^r%M6-mGeRbmQa-RL6k$QYhv zRl;X?QZ?g;gvi9H?I#bIBsb@tH*qEDXs)%0{gbbeey~wS%Nn%j{$Be6LO-Wh((oAJtBh1Y^A*o!qTZT+~-rHk+|728MU6E`j^SZqrBlRC8D`) z&D~AUBJjVQv~h3uR$M1YC385{V5S=Iz3y}j4@hU?yuqyR3{`^-+DN>MeLi}`*M8pT zQ)8&adDtV94AE{_sz+|p)^zfsq=Pjwl<#~}oL}x8P%4WxG@5M=Y&UO?D#Vk``?yg8 z@R$Pz@GmowKwd%Pr)HchFJHn(9|4kXS5mefk+r6lPsEUn&}LRmiw|Zt`W$PkT(kli zw__PqLuoydAleKvPezx>v#8wNyYv5@x0A;6p>=6xe@lTu$6Ro0IQ=9_o*< zc?M^zUmSy5oMFOsONry&(V7FK&LS(QGBeMULZD&h%ip=8tSh2uR>^MQ;MV9CE#sFnhWPWXJ%)V{Hd2W0fm?W*kslEidD&BN_-jy@+0Si&G+pys-E zs4i+LG@sI?d$X$Lc#A`#4%|$qMO3dJ%bsI6n|!YL5OPIpluffOwO}Nchlm3Xfgm~G z+;JYGQ{HCgXif~vttkv?N7V9A?2H#^09N5^__mxoPpJUFPOnpNlyurV+kz&jws%;Q z^B9n*h($7@!fR^ya@2WBivk0!<8A7amQ&j;q>)W=M~(tSthm^KoqAt|F1IrKmYO*TSI>BZnaGUJ_5w(qYY5`y43#D;KYfYdC$?I& z`hto$${Wg}p<&+lUY(b4aTi>gaKVKK0Q^qY?QAbYpag#r&2K4zF-Nr_?s~OPj?^jc z7D0c+f7!spqeX5kkfDK(RVApVF0%QY>+!rSN8VkUSyAnt1w=voalG0;11unQbk0n( zJzK?%p>@NEE7puXVpW1k#M&D3CNqPdHtTE};tb^9PmT;h1F1DZDmN%qu+E&uT%0b+ zb5Kq~Ba4=B_rsnm+)Hft_-6=dN9Kf-4QYH+i&Nn$C1!UmBtqSiz&1GssLH~Z<-$*L zkvli|1d9I+^Que{6fO0M)~Rh1_l;~<9|z4632>0_?-Ef~6uB(*@D?aWqpIVX9KkKk z(5|q*k~?)9j)wbfUO(idUAj;k<8$M3LN?1@2I*(K$k#Ywl4V$`QcSVIYqP?0`bIe6 z+knoc3-6FiD`7Gh?Z8_YuX>uo`uwQ-fmpT$pS(zn;#IXd2f5Bt~ku-o#|LDQ&2PDr{x{9Lp34=O2Rc-x z_mrBM1*H)0C`)Q8ycoEiuPcmRGu80M(E9x;_-1K(fxN&z)om+Bv+7IpL|fUtMxD5f zr1 z6P&5dQLxFbtYJLZkZ_(8mQ?oZhRy-Y2aDB_w1#N$T-pP^zf#*ghKhlihdE#i!Iije z8Fr9p%Uqdq*T=0M?7zqS)xTM+%z~)g+m~$O+AKk>dhytww0fTMX zZX8(@rnJaP8YRU~3t*A4#Lm7XeQG%=9b~?V6v;-LI)Awx6uwW<8vJKOq5&51~ba1V@Ly;9%AT0QFlE;#)_zrBpAiUdUOI#-_d(s9- zryd&V66?3_uKMN4H!!>EJ?rWXRr%=HAegPdPsEMir-m5lR(r#EKKY1iM?zTH@#fjh zF!ZFA>o}=1MGiJRJ{Z)9;hFI^(;lAK_CKhOZBaEG!uKX9T)QM^c4pkqctYQIG@Pjc zp-J)F(IAc)ji)!MB1+DE8J)*h+r}mLTeo(__CgCVHMFgCHlZo^;&e_9C^@A_M0h8& zrT$g&DS;dT3af773+(*YnoHDl+E-^z?Y%CxFF_%l8V?DTITmny3r_O}N;S~}!ic7> z3ooYaD34WA3N=J4!g79}VTr=e`rq`V|K5)#_=KSWGHl0UbuBl*Hd8bRt`9@sw2+o7 z;D#kB@3yo|K?>1+o6YX3sPaiNhW;M&2;+5K50+tAN))Ji9OKSrX1l5qN8(wB2?^t9JL_SAaB!esH?KA8tR!Rhq}P zzjGjJ7roX%5|69NzEu8r9#_>+z4+q4cUUo}VpX97SmjYqx?49n(C)US1M zBU8K?oGQpt0)?h2N<3^9=*9 zrrsUc`=tkrT~g2CrUAYYvFFaZn?sc-1%>1ZH8I|M-;u`AxLLniGO7iDv?K=zF;S%> z#d+i_9>O~&>v)b74UoI{Vc+k+Io|5QO>(lZddGAHbk3RAz=<-{-|RT8&O+P*MEzQP z=cS5BSVzJo(3qf2IhGckFYK<(3#4}D&IEygF>q+)G(g&*p)^r;W-ut4GGks>BJ6j& zWDcQJt#YnKF~$NP3db^+Dy%dAcl;ngG}O^A!>uF&4zn{An(q(V$7>TK&yPz=V#zcY zhv!-nvF+!cPC9&ZHvS@tL2ZW1mdYm=v2&PkWLD;pn9|Nol5~+m zrfLN3ql>RsH}Z^KazbE}jzK?$kNjGQ>QLLVK#lHncmKV*R_I?II!x0N4D^#3_1QP< zfXxxHqG`!ADxQgLU@JL9)J@fGxI z5hka^g&_#~!Wb4&mk(`PF~Z3fQ7|YYF@otS6obpzUooT)I}bwViWRYb+r5zRtz|a* z?W))T`fle}bNl-0EB+AL2MOL<_y-O$JED#=cOBPP`tEy6b;u(-)BmN}nA0QoCDc%1 z>I;Bwt(iAvgww5aD}DPJJ)O}$ZeeGd4%dC~#@M88r=f)e z&{2(JHr67p;FB_g7KWngIF4QpEFQur9VL45+WC@=-_hD+yisEE?NPaO3K5D2&ImwJ zlrtWsiU7(RxSD&S>ye8CxjV;bc=-wRj`Wgv;blp%Xodq{tkW+zv9xRfu=h@oU8s&m zbM73ARbo|{LCtrqOn@_xe|3mRFt4#4V|4A=F_aJi&(jK`}!{3u~lQYUy;%Z-Cl%W~d0~@RDCM8rW$f_J2 zO^V8eFC)l`;i%nFe(57o*Z~r3dDrrFZc*sbN`E#Qw*sDNqhVQ7L~|I~#b;{VD@N`Ache4F{R+Xhd~Y({AL zM7Cl9eqOw!W@-MSfky))qm()HO$GUj&twfzY*z(64f&;7UwGZ)fdAjsKC=~PH?2%T z*FKaI$2qF`;B4q}&yq-|DiIa4~@WD>H^5GG8HIRkap{@zYklhN>u5KYtMb2u1I zziKGxt2kc15tS(_n0YStoIr$&XH-<_{;jhnAYA+rLbjL;<>1kMHa$fWKF47 zzPUIhVA>Qx^t`_xZIxPdqu+m^!8*C^z!HU0+z*792QJ$Kkxb1vAaPx%+iY~p3hTUy zGsv%3<3fYHqlxmCJ=@v+>JsLe&gR~@`Q(`;C5UPH_740Sx@E=EkU#2rYrMpZH#2lnKiznQBu|Xg4l~*a$Ozpnovo;VNA`k;HVBDQAPx# diff --git a/server/requirements/requirements-dev.txt b/server/requirements/requirements-dev.txt index a66e01e8..cfec2bd4 100644 --- a/server/requirements/requirements-dev.txt +++ b/server/requirements/requirements-dev.txt @@ -43,6 +43,8 @@ azure-storage-blob==12.17.0 # django-storages backcall==0.2.0 # via ipython +bcrypt==4.0.1 + # via paramiko beautifulsoup4==4.11.2 # via wagtail black==23.7.0 @@ -69,6 +71,7 @@ cffi==1.15.1 # via # argon2-cffi-bindings # cryptography + # pynacl cfgv==3.3.1 # via pre-commit charset-normalizer==3.2.0 @@ -95,6 +98,7 @@ cryptography==41.0.3 # azure-identity # azure-storage-blob # msal + # paramiko # pyjwt decorator==5.1.1 # via @@ -336,6 +340,8 @@ packaging==23.1 # marshmallow # pytest # pytest-sugar +paramiko==3.3.1 + # via -r requirements.in parso==0.8.3 # via jedi pathspec==0.11.2 @@ -400,6 +406,8 @@ pylint-django==2.5.3 # via -r requirements-dev.in pylint-plugin-utils==0.8.2 # via pylint-django +pynacl==1.5.0 + # via paramiko pyproject-hooks==1.0.0 # via build pytest==7.4.0 diff --git a/server/requirements/requirements.in b/server/requirements/requirements.in index ae9264d7..76388ad2 100644 --- a/server/requirements/requirements.in +++ b/server/requirements/requirements.in @@ -40,6 +40,7 @@ python-json-logger concurrent-log-handler python-dateutil pycryptodome +paramiko wagtail>=4 wagtail-factories>=4 diff --git a/server/requirements/requirements.txt b/server/requirements/requirements.txt index 1261d7d5..a0818296 100644 --- a/server/requirements/requirements.txt +++ b/server/requirements/requirements.txt @@ -34,6 +34,8 @@ azure-storage-blob==12.17.0 # via # -r requirements.in # django-storages +bcrypt==4.0.1 + # via paramiko beautifulsoup4==4.11.2 # via wagtail boto3==1.28.23 @@ -52,6 +54,7 @@ cffi==1.15.1 # via # argon2-cffi-bindings # cryptography + # pynacl charset-normalizer==3.2.0 # via requests click==8.1.6 @@ -67,6 +70,7 @@ cryptography==41.0.3 # azure-identity # azure-storage-blob # msal + # paramiko # pyjwt defusedxml==0.7.1 # via willow @@ -211,6 +215,8 @@ packaging==23.1 # via # gunicorn # marshmallow +paramiko==3.3.1 + # via -r requirements.in pillow==10.0.0 # via # -r requirements.in @@ -234,6 +240,8 @@ pycryptodome==3.18.0 # via -r requirements.in pyjwt[crypto]==2.8.0 # via msal +pynacl==1.5.0 + # via paramiko python-dateutil==2.8.2 # via # -r requirements.in diff --git a/server/vbv_lernwelt/edoniq_test/result_import/__init__.py b/server/vbv_lernwelt/edoniq_test/result_import/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py b/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py new file mode 100644 index 00000000..8bc6ae72 --- /dev/null +++ b/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py @@ -0,0 +1,63 @@ +import csv +import os +from io import StringIO + +import paramiko +import structlog + +logger = structlog.get_logger(__name__) + + +def _create_edoniq_sftp_client(): + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + # Get the private key from the environment variable and convert it to a key object + private_key_env_var_name = "IT_EDONIQ_SFTP_PRIVATE_KEY" + private_key_str = os.environ.get(private_key_env_var_name).replace("\\n", "\n") + if not private_key_str: + logger.warn( + "Environment variable not set or empty", + env_var=private_key_env_var_name, + label="edoniq_import", + ) + raise ValueError( + f"Environment variable {private_key_env_var_name} not set or empty." + ) + + private_key_file = StringIO(private_key_str) + private_key = paramiko.Ed25519Key.from_private_key(private_key_file) + + client.connect( + hostname="217.20.192.94", + port=20041, + username="sftpuser", + pkey=private_key, + ) + + return client.open_sftp(), client + + +class EdoniqSftpClient: + def __enter__(self): + (self.sftp_client, self.ssh_client) = _create_edoniq_sftp_client() + return self.sftp_client + + def __exit__(self, exc_type, exc_value, exc_traceback): + # self.sftp_client.close() + self.ssh_client.close() + + +def load_edoniq_test_results_csv_data(): + with EdoniqSftpClient() as sftp_client: + with sftp_client.file("/upload/PruefungResultate.csv", "r") as file: + data = file.read().decode("utf-8") + return data + + +if __name__ == "__main__": + csv_data = load_edoniq_test_results_csv_data() + csv_reader = csv.reader(StringIO(csv_data), delimiter=";") + for i, row in enumerate(csv_reader): + if len(row) > 4 and row[4] == "AG 2023 A" and row[5] == "de_üK1_BA_KN": + print(row) diff --git a/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv b/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv new file mode 100644 index 00000000..ab14dc4d --- /dev/null +++ b/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv @@ -0,0 +1,6 @@ +Benutzer Login;Benutzer Name;Benutzer Vorname;Korrespondenzsprache;OE;Sequenztitel;Sequenz ID;letztes Datum der Durchführung des Kandidaten;Zeitstempel Beginn;Bearbeitungsdauer;erreichte Punkte absolut ; erreichbares Punktetotal absolut;erreichte Punkte;Bestehensgrenze prozentual;Bestanden-/Nicht-Bestanden Status;Note;prozentualer Durchschnitt der Versuche dieses Kandidaten;prozentualer Durchschnitt aller Kandidaten + ; +cc36ad95-d09c-4187-b1d4-689ada3ef497;Sommer;Diego;de;AG 2023 A;de_üK1_BA_KN;1688059890497;06.09.2023;06.09.2023 18:48;00:17:10.4650;21.25 ; 29;73.28;60;Bestanden;;73.28;65.91 +58fdb8e2-881d-48fd-8df9-05f31586e909;Demirel;Beyzanur;de;AG 2023 A;de_üK1_BA_KN;1688059890497;07.09.2023;07.09.2023 19:00;00:17:49.8550;12.23 ; 29;42.16;60;Nicht bestanden;;42.16;65.91 +19d4e374-7300-45cc-a420-bebe184c5c4e;Appert;Mascha;de;AG 2023 A;de_üK1_BA_KN;1688059890497;10.09.2023;10.09.2023 10:48;00:18:22.9710;17.62 ; 29;60.76;60;Bestanden;;60.76;65.91 +29610d7c-ed48-43b8-ab71-ce0e726aada4;Gianformaggio;Ylaria;de;AG 2023 A;de_üK1_KO_Testlauf;1686325621487;10.09.2023;10.09.2023 16:32;00:00:00.0000;0.00 ; 15;0.00;60;Begonnen;;38.11;55.30 \ No newline at end of file From 589453a8dc962844dd41efd910c71f27aab6ff01 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 28 Sep 2023 11:20:51 +0200 Subject: [PATCH 02/10] Remove `evaluation_grade` and set `evaluation_points` and `evaluation_passed` fields --- client/src/gql/gql.ts | 8 +- client/src/gql/graphql.ts | 14 +- client/src/gql/schema.graphql | 5 +- client/src/graphql/client.ts | 1 - client/src/graphql/mutations.ts | 3 - client/src/graphql/queries.ts | 3 +- client/src/locales/de/translation.json | 52 +++++-- client/src/locales/fr/translation.json | 50 ++++++- client/src/locales/it/translation.json | 50 ++++++- .../EvaluationSummary.vue | 22 ++- client/src/services/assignmentService.ts | 9 -- client/src/types.ts | 7 +- .../e2e/assignment/assignmentStudent.cy.js | 131 ++++++++++++++++++ .../e2e/assignment/assignmentTrainer.cy.js | 104 ++++++++++++++ cypress/e2e/feedback/feedbackStudent.cy.js | 1 + .../assignment/graphql/mutations.py | 6 +- .../vbv_lernwelt/assignment/graphql/types.py | 3 +- .../migrations/0008_auto_20230928_1254.py | 40 ++++++ server/vbv_lernwelt/assignment/models.py | 6 +- server/vbv_lernwelt/assignment/serializers.py | 3 +- server/vbv_lernwelt/assignment/services.py | 19 +-- .../assignment/tests/test_graphql.py | 7 +- .../assignment/tests/test_services.py | 8 +- server/vbv_lernwelt/assignment/views.py | 2 +- .../course/creators/test_course.py | 2 - 25 files changed, 469 insertions(+), 87 deletions(-) create mode 100644 server/vbv_lernwelt/assignment/migrations/0008_auto_20230928_1254.py diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index ae3edad5..ab9d81fb 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -14,10 +14,10 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document- */ const documents = { "\n mutation AttendanceCheckMutation(\n $attendanceCourseId: ID!\n $attendanceUserList: [AttendanceUserInputType]!\n ) {\n update_course_session_attendance_course_users(\n id: $attendanceCourseId\n attendance_user_list: $attendanceUserList\n ) {\n course_session_attendance_course {\n id\n attendance_user_list {\n user_id\n first_name\n last_name\n email\n status\n }\n }\n }\n }\n": types.AttendanceCheckMutationDocument, - "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, + "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, "\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc, "\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument, - "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, @@ -44,7 +44,7 @@ export function graphql(source: "\n mutation AttendanceCheckMutation(\n $att /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"]; +export function graphql(source: "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -56,7 +56,7 @@ export function graphql(source: "\n query attendanceCheckQuery($courseSessionId /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"]; +export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index a2fa0067..870bb977 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -78,7 +78,8 @@ export type AssignmentCompletionObjectType = { completion_data?: Maybe; completion_status: AssignmentAssignmentCompletionCompletionStatusChoices; created_at: Scalars['DateTime']['output']; - evaluation_grade?: Maybe; + evaluation_max_points?: Maybe; + evaluation_passed?: Maybe; evaluation_points?: Maybe; evaluation_submitted_at?: Maybe; evaluation_user?: Maybe; @@ -561,7 +562,7 @@ export type MutationUpsertAssignmentCompletionArgs = { completion_data_string?: InputMaybe; completion_status?: InputMaybe; course_session_id: Scalars['ID']['input']; - evaluation_grade?: InputMaybe; + evaluation_passed?: InputMaybe; evaluation_points?: InputMaybe; initialize_completion?: InputMaybe; learning_content_page_id?: InputMaybe; @@ -691,13 +692,12 @@ export type UpsertAssignmentCompletionMutationVariables = Exact<{ assignmentUserId?: InputMaybe; completionStatus: AssignmentCompletionStatus; completionDataString: Scalars['String']['input']; - evaluationGrade?: InputMaybe; evaluationPoints?: InputMaybe; initializeCompletion?: InputMaybe; }>; -export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; +export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; type CoursePageFieldsAssignmentObjectTypeFragment = { __typename?: 'AssignmentObjectType', title?: string | null, id?: string | null, slug?: string | null, content_type?: string | null, frontend_url?: string | null } & { ' $fragmentName'?: 'CoursePageFieldsAssignmentObjectTypeFragment' }; @@ -735,7 +735,7 @@ export type AssignmentCompletionQueryQueryVariables = Exact<{ export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, max_points?: number | null, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null, competence_certificate?: ( { __typename?: 'CompetenceCertificateObjectType' } & { ' $fragmentRefs'?: { 'CoursePageFieldsCompetenceCertificateObjectTypeFragment': CoursePageFieldsCompetenceCertificateObjectTypeFragment } } - ) | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; + ) | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_points?: number | null, evaluation_max_points?: number | null, evaluation_passed?: boolean | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; export type CourseQueryQueryVariables = Exact<{ courseId: Scalars['Int']['input']; @@ -803,9 +803,9 @@ export type SendFeedbackMutationMutation = { __typename?: 'Mutation', send_feedb export const CoursePageFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const AttendanceCheckMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AttendanceCheckMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AttendanceUserInputType"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update_course_session_attendance_course_users"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"attendance_user_list"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"first_name"}},{"kind":"Field","name":{"kind":"Name","value":"last_name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}},{"kind":"Argument","name":{"kind":"Name","value":"initialize_completion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}},{"kind":"Argument","name":{"kind":"Name","value":"initialize_completion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; export const AttendanceCheckQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"attendanceCheckQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; -export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const CompetenceCertificateQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"competenceCertificateQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_list"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}}]}},{"kind":"Field","name":{"kind":"Name","value":"learning_content"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}},{"kind":"Field","name":{"kind":"Name","value":"circle"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenericScalar"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"submitted"},"value":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"submitted"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index 6ba5dec7..708ba6da 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -296,8 +296,9 @@ type AssignmentCompletionObjectType { submitted_at: DateTime evaluation_submitted_at: DateTime evaluation_user: UserType - evaluation_grade: Float evaluation_points: Float + evaluation_max_points: Float + evaluation_passed: Boolean assignment_user: UserType! assignment: AssignmentObjectType! completion_status: AssignmentAssignmentCompletionCompletionStatusChoices! @@ -548,7 +549,7 @@ type CompetenceCertificateListObjectType implements CoursePageInterface { type Mutation { send_feedback(course_session_id: ID!, data: GenericScalar, learning_content_page_id: ID!, submitted: Boolean = false): SendFeedbackMutation update_course_session_attendance_course_users(attendance_user_list: [AttendanceUserInputType]!, id: ID!): AttendanceCourseUserMutation - upsert_assignment_completion(assignment_id: ID!, assignment_user_id: UUID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_grade: Float, evaluation_points: Float, initialize_completion: Boolean, learning_content_page_id: ID): AssignmentCompletionMutation + upsert_assignment_completion(assignment_id: ID!, assignment_user_id: UUID, completion_data_string: String, completion_status: AssignmentCompletionStatus, course_session_id: ID!, evaluation_passed: Boolean, evaluation_points: Float, initialize_completion: Boolean, learning_content_page_id: ID): AssignmentCompletionMutation } type SendFeedbackMutation { diff --git a/client/src/graphql/client.ts b/client/src/graphql/client.ts index 27e6aa18..926e0052 100644 --- a/client/src/graphql/client.ts +++ b/client/src/graphql/client.ts @@ -47,7 +47,6 @@ export const graphqlClient = new Client({ JSON.parse(args.completion_data_string || "{}") ), completion_status: args.completion_status, - evaluation_grade: args.evaluation_grade, evaluation_points: args.evaluation_points, }, }; diff --git a/client/src/graphql/mutations.ts b/client/src/graphql/mutations.ts index 42106cb0..19ee3349 100644 --- a/client/src/graphql/mutations.ts +++ b/client/src/graphql/mutations.ts @@ -31,7 +31,6 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` $assignmentUserId: UUID $completionStatus: AssignmentCompletionStatus! $completionDataString: String! - $evaluationGrade: Float $evaluationPoints: Float $initializeCompletion: Boolean ) { @@ -42,7 +41,6 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` assignment_user_id: $assignmentUserId completion_status: $completionStatus completion_data_string: $completionDataString - evaluation_grade: $evaluationGrade evaluation_points: $evaluationPoints initialize_completion: $initializeCompletion ) { @@ -51,7 +49,6 @@ export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` completion_status submitted_at evaluation_submitted_at - evaluation_grade evaluation_points completion_data } diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index 954037f9..f909d44e 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -65,8 +65,9 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(` assignment_user { id } - evaluation_grade evaluation_points + evaluation_max_points + evaluation_passed completion_data } } diff --git a/client/src/locales/de/translation.json b/client/src/locales/de/translation.json index d6ef60e5..3dbcc42d 100644 --- a/client/src/locales/de/translation.json +++ b/client/src/locales/de/translation.json @@ -17,6 +17,7 @@ "Feedback anschauen": "Feedback anschauen", "Feedback: Feedback zum Lehrgang": "Feedback: Feedback zum Lehrgang", "Freigabetermin Bewertungen:": "Freigabetermin Bewertungen:", + "Hier überprüfst und bestätigst du die Anwesenheit deiner Teilnehmenden": [], "MS Teams öffnen": "MS Teams öffnen", "Nächste Termine": "Nächste Termine", "Passwort": "Passwort", @@ -29,26 +30,44 @@ "Wissens - und Verständnisfragen": "Wissens - und Verständnisfragen", "Zur Zeit sind keine Termine vorhanden": "Zur Zeit sind keine Termine vorhanden", "a": { + "Alle aufklappen": "Alle aufklappen", + "AlleTermine": "a.AlleTermine", + "Begründung": "Begründung", + "Beurteilungsinstrument anzeigen": "Beurteilungsinstrument anzeigen", + "Beurteilungskriterium": "Beurteilungskriterium", + "Bewertung": "Bewertung", + "Bewertung fortsetzen": "a.Bewertung fortsetzen", "Bewertung freigegeben": "Bewertung freigegeben", - "Datum": "a.Datum", + "Bewertung starten": "Bewertung starten", + "Circle": "Circle", + "Datum": "Datum", "Details anzeigen": "Details anzeigen", + "Ergebnisse": "Ergebnisse", "Ergebnisse abgegeben": "Ergebnisse abgegeben", + "Ergebnisse anschauen": "Ergebnisse anschauen", + "Geleitete Fallarbeit": "Geleitete Fallarbeit", "Gesamtpunktzahl": "Gesamtpunktzahl", - "Handlungskompetenzen": "a.Handlungskompetenzen", + "Handlungskompetenzen": "Handlungskompetenzen", "Höchstpunktzahl": "Höchstpunktzahl", + "Kein Circle verfügbar oder ausgewählt": [], "KompetenzNavi": "KompetenzNavi", + "Kompetenznachweis": "Kompetenznachweis", "Kompetenznachweise": "Kompetenznachweise", - "Mediathek": "a.Mediathek", + "Leistungsziele": "Leistungsziele", + "Mediathek": "Mediathek", "Punkte": "Punkte", - "Selbsteinschätzung": "a.Selbsteinschätzung", + "Selbsteinschätzung": "Selbsteinschätzung", + "Selbsteinschätzung anschauen": "a.Selbsteinschätzung anschauen", "Selbsteinschätzungen": "Selbsteinschätzungen", - "Standort": "a.Standort", - "Trainer": "a.Trainer", + "Standort": "Standort", + "Trainer": "Trainer", + "VorschauTeilnehmer": "Vorschau Teilnehmer", "Zwischenstand": "Zwischenstand", - "competenceCertificateNoUserPoints": "a.competenceCertificateNoUserPoints", + "competenceCertificateNoUserPoints": "Der Punktestand wird zu einem späteren Zeitpunkt berechnet.", "Übersicht": "Übersicht" }, "assignment": { + "Du musst die Bewertung bis am x um y Uhr abschliessen und freigeben": "Du musst die Bewertung bis am {{x}} um {{y}} Uhr abschliessen und freigeben.", "acceptConditionsDisclaimer": "Bedingungen akzeptieren und Ergebnisse abgeben", "assessmentDocumentDisclaimer": "Diese geleitete Fallarbeit wird auf Grund des folgenden Beurteilungsinstrument bewertet:", "assessmentTitle": "Bewertung", @@ -61,7 +80,9 @@ "dueDateSubmission": "Abgabetermin", "edit": "Bearbeiten", "effortTitle": "Zeitaufwand", + "evaluationInstrumentDescriptionText": "Die Gesamtpunktzahl und die daraus resultierende Note wird auf Grund des hinterlegeten Beurteilungsinstrument berechnet.", "initialSituationTitle": "Ausgangslage", + "justificationRequiredText": "Hier muss zwingend eine Begründung erfasst werden.", "lastChangesNotSaved": "Die letzte Änderung konnte nicht gespeichert werden.", "performanceObjectivesTitle": "Leistungsziele", "showAssessmentDocument": "Bewertungsinstrument anzeigen", @@ -70,12 +91,13 @@ "taskDefinition": "Bearbeite die Teilaufgaben und dokumentiere deine Ergebnisse.", "taskDefinitionTitle": "Aufgabenstellung", "von x Punkten": "von {{x}} Punkten", + "x hat die Ergebnisse am y um z Uhr abgegeben": "{{x}} hat die Ergebnisse am {{y}} um {{z}} Uhr abgegeben", "x von y Arbeiten abgeschlossen": "{{x}} von {{y}} Arbeiten abgeschlossen", - "x von y Kompetenznachweis-Elementen abgeschlossen": "assignment.x von y Kompetenznachweis-Elementen abgeschlossen" + "x von y Kompetenznachweis-Elementen abgeschlossen": "{{x}} von {{y}} Kompetenznachweis-Elementen abgeschlossen" }, "circlePage": { - "Dieser Inhalt gehört zu x": "circlePage.Dieser Inhalt gehört zu x", - "Im KompetenzNavi anschauen": "circlePage.Im KompetenzNavi anschauen", + "Dieser Inhalt gehört zu x": "Dieser Inhalt gehört zu «{{x}}»", + "Im KompetenzNavi anschauen": "Im KompetenzNavi anzeigen", "circleContentBoxTitle": "Das lernst du in diesem Circle", "contactExpertButton": "Trainer/-in kontaktieren", "contactExpertDescription": "Tausche dich mit der Trainer/-in für den Circle {{circleName}} aus.", @@ -117,11 +139,14 @@ "title": "Cockpit", "trainerFilesText": "Hier findest du die Trainerunterlagen (Lösungsblätter, Präsentationen etc.) für deinen Circle." }, + "competence": { + "listPageDescription": "competence.listPageDescription" + }, "competenceCertificate": { - "mainTitle": "competenceCertificate.mainTitle" + "mainTitle": "Kompetenznachweis" }, "competenceCertificates": { - "mainTitle": "competenceCertificates.mainTitle" + "mainTitle": "Kompetenznachweise" }, "competences": { "assessAgain": "Selbsteinschätzung im Circle «{{x}}» anschauen", @@ -152,7 +177,8 @@ }, "edoniqTest": { "qualifiesForExtendedTime": "Ich bestätige, dass ich Anrecht auf einen Test mit Nachteilsausgleich habe.", - "qualifiesForExtendedTimeTitle": "Lernende mit Nachteilsausgleich (bewilligungspflichtig)" + "qualifiesForExtendedTimeTitle": "Lernende mit Nachteilsausgleich (bewilligungspflichtig)", + "startTest": "Test starten" }, "feedback": { "answers": "Antworten", diff --git a/client/src/locales/fr/translation.json b/client/src/locales/fr/translation.json index dd19cd85..1c60634f 100644 --- a/client/src/locales/fr/translation.json +++ b/client/src/locales/fr/translation.json @@ -1,4 +1,5 @@ { + "Alle": "Tout", "Anwesenheit Präsenzkurse": "Présence aux cours", "Anwesenheit bestätigen": "Confirmer la présence", "Anwesenheit prüfen": "Vérifier la présence", @@ -7,29 +8,55 @@ "Ergebnisse anschauen": "Consulter les résultats", "Feedback": "Feedback", "Feedback anschauen": "Consulter le feedback", + "Hier überprüfst und bestätigst du die Anwesenheit deiner Teilnehmenden": [], "MS Teams öffnen": "Ouvrir MS Teams ", "Nächste Termine": "Prochaines dates", "Passwort": "Mot de passe", + "Sehr unzufrieden": "très insatisfait", + "Sehr zufrieden": "très satisfait", "Status anschauen": "Consulter le statut", "TODO: Nächste Termine": "TODO: prochaines dates", "Trainerunterlagen": "Documents du formateur / de la formatrice", "Wissens - und Verständnisfragen": "Questions de connaissance et de compréhension ", "Zur Zeit sind keine Termine vorhanden": "Aucune réunion n’est prévue pour le moment", "a": { + "Alle aufklappen": "Tout déplier", + "Begründung": "Justification", + "Beurteilungsinstrument anzeigen": "Afficher l'outil d'évaluation", + "Beurteilungskriterium": "Critère d'évaluation", + "Bewertung": "Évaluation", + "Bewertung fortsetzen": "Continuer l'évaluation", "Bewertung freigegeben": "Évaluations validée/s", + "Bewertung starten": "Continuer l'évaluation", + "Circle": "Cercle", + "Datum": "Date", "Details anzeigen": "Afficher les détails", + "Ergebnisse": "Résultats", "Ergebnisse abgegeben": "Résultats remis", + "Ergebnisse anschauen": "Voir les résultats", + "Geleitete Fallarbeit": "Étude de cas dirigée", "Gesamtpunktzahl": "Score total", + "Handlungskompetenzen": "Compétences opérationnelles", "Höchstpunktzahl": "Score maximum", + "Kein Circle verfügbar oder ausgewählt": [], "KompetenzNavi": "NaviCompétence", + "Kompetenznachweis": "Contrôle de compétences", "Kompetenznachweise": "Contrôles de compétences", - "Kompetenznachweise": "Contrôles de compétences", + "Leistungsziele": "Objectif évaluateur", + "Mediathek": "Médiathèque", "Punkte": "points", + "Selbsteinschätzung": "Auto-évaluation", + "Selbsteinschätzung anschauen": "Voir l'auto-évaluation", "Selbsteinschätzungen": "Auto-évaluations", + "Standort": "Emplacement", + "Trainer": "Formateur / Formatrice", + "VorschauTeilnehmer": "Aperçu participant", "Zwischenstand": "Point intermédiaire", + "competenceCertificateNoUserPoints": "Le score sera calculé à un moment ultérieur.", "Übersicht": "Aperçu" }, "assignment": { + "Du musst die Bewertung bis am x um y Uhr abschliessen und freigeben": "Vous devez terminer et valider l'évaluation avant le {{x}} à {{y}} heures.", "acceptConditionsDisclaimer": "Accepter les conditions et remettre les résultats", "assessmentDocumentDisclaimer": "Cette étude de cas dirigée est évaluée par l’outil suivant :", "assessmentTitle": "Évaluation", @@ -42,7 +69,9 @@ "dueDateSubmission": "Date de remise", "edit": "Traiter", "effortTitle": "Temps nécessaire", + "evaluationInstrumentDescriptionText": "Le score total et la note en résultant sont calculés sur la base de l'outil d'évaluation enregistré.", "initialSituationTitle": "Situation initiale", + "justificationRequiredText": "Ici, une justification doit impérativement être saisie.", "lastChangesNotSaved": "La dernière modification n’a pas pu être enregistrée.", "performanceObjectivesTitle": "Objectifs", "showAssessmentDocument": "Afficher l’outil d’évaluation", @@ -51,9 +80,13 @@ "taskDefinition": "Résous les exercices et documente tes résultats.", "taskDefinitionTitle": "Énoncé du problème", "von x Punkten": "sur {{x}} points", - "x von y Arbeiten abgeschlossen": "{{x}} sur {{y}} épreuves terminées" + "x hat die Ergebnisse am y um z Uhr abgegeben": "{{x}} a soumis les résultats le {{y}} à {{z}} heures", + "x von y Arbeiten abgeschlossen": "{{x}} sur {{y}} épreuves terminées", + "x von y Kompetenznachweis-Elementen abgeschlossen": "{{x}} sur {{y}} éléments de contrôle de compétences terminés" }, "circlePage": { + "Dieser Inhalt gehört zu x": "Ce contenu appartient à «{{x}}»", + "Im KompetenzNavi anschauen": "Afficher dans le \"KompetenzNavi\"", "circleContentBoxTitle": "Ce que tu vas apprendre dans ce cercle", "contactExpertButton": "Contacter le formateur / la formatrice", "contactExpertDescription": "Échanger avec le formateur / la formatrice si tu as des questions sur le cercle {{circleName}}.", @@ -95,6 +128,12 @@ "title": "Cockpit", "trainerFilesText": "Tu trouves ici les documents de formation (feuilles de solution, présentations, etc.) pour ton cercle." }, + "competenceCertificate": { + "mainTitle": "Contrôle de compétences" + }, + "competenceCertificates": { + "mainTitle": "Contrôles de compétences" + }, "competences": { "assessAgain": "Voir l'auto-évaluation dans le cercle «{{x}}»", "assessment": "Évaluations", @@ -124,7 +163,8 @@ }, "edoniqTest": { "qualifiesForExtendedTime": "Je confirme que j'ai droit à un test avec compensation des inégalités.", - "qualifiesForExtendedTimeTitle": "Apprenti-e-s avec compensation des inégalités (soumis à autorisation)" + "qualifiesForExtendedTimeTitle": "Apprenti-e-s avec compensation des inégalités (soumis à autorisation)", + "startTest": "Démarrer l'essai" }, "feedback": { "answers": "Réponses", @@ -315,8 +355,10 @@ "welcome": "Tout s'est bien passé, tu es maintenant inscrit/e à l'environnement d'apprentissage numérique de l'Association pour la formation professionnelle en assurance (AFA) !" } }, + "unzufrieden": "insatisfait", "x von y Bewertungen freigegeben": "{{x}} de {{y}} évaluations validée/s", "x von y Ergebnisse abgegeben": "{{x}} de {{y}} résultats remis", "x von y Feedbacks abgegeben": "{{x}} de {{y}} feedbacks remis", - "x von y abgeschlossen": "{{x}} de {{y}} achevée/s" + "x von y abgeschlossen": "{{x}} de {{y}} achevée/s", + "zufrieden": "satisfait" } diff --git a/client/src/locales/it/translation.json b/client/src/locales/it/translation.json index 4f3ee534..9d545607 100644 --- a/client/src/locales/it/translation.json +++ b/client/src/locales/it/translation.json @@ -1,4 +1,5 @@ { + "Alle": "Tutto", "Anwesenheit Präsenzkurse": "Presenza ai corsi", "Anwesenheit bestätigen": "Confermare la presenza", "Anwesenheit prüfen": "Verificare la presenza", @@ -7,29 +8,55 @@ "Ergebnisse anschauen": "Vedere i risultati", "Feedback": "Feedback", "Feedback anschauen": "Vedere il feedback", + "Hier überprüfst und bestätigst du die Anwesenheit deiner Teilnehmenden": [], "MS Teams öffnen": "Aprire MS Teams", "Nächste Termine": "Prossime date", "Passwort": "Password", + "Sehr unzufrieden": "molto insoddisfatto", + "Sehr zufrieden": "molto soddisfatto", "Status anschauen": "Vedere lo stato", "TODO: Nächste Termine": "TODO: prossime date", "Trainerunterlagen": "Documenti del/della trainer", "Wissens - und Verständnisfragen": "Domande di conoscenza e di comprensione", "Zur Zeit sind keine Termine vorhanden": "Al momento non ci sono scadenze", "a": { + "Alle aufklappen": "Apri tutto", + "Begründung": "Motivazione", + "Beurteilungsinstrument anzeigen": "Mostra lo strumento di valutazione", + "Beurteilungskriterium": "Criterio di valutazione", + "Bewertung": "Valutazione", + "Bewertung fortsetzen": "Continua la valutazione", "Bewertung freigegeben": "Valutazioni approvate/a", + "Bewertung starten": "Continua la valutazione", + "Circle": "Cerchio", + "Datum": "Data", "Details anzeigen": "Mostrare i dettagli", + "Ergebnisse": "Risultati", "Ergebnisse abgegeben": "Risultati consegnati", + "Ergebnisse anschauen": "Guarda i risultati", + "Geleitete Fallarbeit": "Caso di studio guidato", "Gesamtpunktzahl": "Punteggio totale", + "Handlungskompetenzen": "Competenze operative", "Höchstpunktzahl": "Punteggio massimo", + "Kein Circle verfügbar oder ausgewählt": [], "KompetenzNavi": "NaviCompetenze", + "Kompetenznachweis": "Controllo delle competenze", "Kompetenznachweise": "Controlli delle competenze", - "Kompetenznachweise": "Controlli delle competenze", + "Leistungsziele": "Obiettivo di valutazione", + "Mediathek": "Mediateca", "Punkte": "punti", + "Selbsteinschätzung": "Auto-valutazione", + "Selbsteinschätzung anschauen": "Guarda l'auto-valutazione", "Selbsteinschätzungen": "Auto-valutaziones", + "Standort": "Posizione", + "Trainer": "Trainer", + "VorschauTeilnehmer": "Anteprima partecipante", "Zwischenstand": "Punto intermedio", + "competenceCertificateNoUserPoints": "Il punteggio verrà calcolato in un momento successivo.", "Übersicht": "Panoramica" }, "assignment": { + "Du musst die Bewertung bis am x um y Uhr abschliessen und freigeben": " Devi completare e rilasciare la valutazione entro il {{x}} alle ore {{y}}.", "acceptConditionsDisclaimer": "Accettare le condizioni e consegnare i risultati", "assessmentDocumentDisclaimer": "Questa analisi guidata del caso viene valutata sulla base del seguente strumento di valutazione:", "assessmentTitle": "Valutazione", @@ -42,7 +69,9 @@ "dueDateSubmission": "Termine di consegna", "edit": "Modificare", "effortTitle": "Tempo richiesto", + "evaluationInstrumentDescriptionText": "Il punteggio totale e il voto risultante vengono calcolati sulla base dello strumento di valutazione archiviato.", "initialSituationTitle": "Situazione di partenza", + "justificationRequiredText": "Qui è assolutamente necessario inserire una motivazione.", "lastChangesNotSaved": "Non è stato possibile salvare l’ultima modifica.", "performanceObjectivesTitle": "Obiettivi di valutazione", "showAssessmentDocument": "Mostrare lo strumento di valutazione", @@ -51,9 +80,13 @@ "taskDefinition": "Svolgi le attività parziali e documenta i tuoi risultati.", "taskDefinitionTitle": "Compito", "von x Punkten": "di {{x}} punti", - "x von y Arbeiten abgeschlossen": "{{x}} di {{y}} compiti completati" + "x hat die Ergebnisse am y um z Uhr abgegeben": "{{x}} ha consegnato i risultati il {{y}} alle ore {{z}}", + "x von y Arbeiten abgeschlossen": "{{x}} di {{y}} compiti completati", + "x von y Kompetenznachweis-Elementen abgeschlossen": "{{x}} su {{y}} elementi del controllo delle competenze completati" }, "circlePage": { + "Dieser Inhalt gehört zu x": "Questo contenuto appartiene a «{{x}}»", + "Im KompetenzNavi anschauen": "Mostra nel \"KompetenzNavi\"", "circleContentBoxTitle": "Cosa apprenderai in questo Circle", "contactExpertButton": "Contattare il/la trainer", "contactExpertDescription": "Confrontati con il/la trainer per il Circle {{circleName}}.", @@ -95,6 +128,12 @@ "title": "Cockpit", "trainerFilesText": "Qui trovi i documenti del/della trainer (soluzioni, presentazioni ecc.) per il tuo Circle." }, + "competenceCertificate": { + "mainTitle": "Controllo delle competenze" + }, + "competenceCertificates": { + "mainTitle": "Controlli delle competenze" + }, "competences": { "assessAgain": "Guarda l'autovalutazione nel cerchio «{{x}}»", "assessment": "Valutazioni", @@ -124,7 +163,8 @@ }, "edoniqTest": { "qualifiesForExtendedTime": "Confermo di avere diritto a un test con compensazione delli ineguaglianze", - "qualifiesForExtendedTimeTitle": "Impiegati con compensazione delli ineguaglianze (soggetto ad approvazione)" + "qualifiesForExtendedTimeTitle": "Impiegati con compensazione delli ineguaglianze (soggetto ad approvazione)", + "startTest": "Inizia la prova" }, "feedback": { "answers": "Risposte", @@ -315,8 +355,10 @@ "welcome": "Tutto ha funzionato, ora sei registrata/o nell'ambiente di apprendimento digitale dell'Associazione per la formazione professionale nell'assicurazione (AFA)!" } }, + "unzufrieden": "insoddisfatto", "x von y Bewertungen freigegeben": "{{x}} di {{y}} valutazioni approvate/a", "x von y Ergebnisse abgegeben": "{{x}} di {{y}} risultati consegnati/o", "x von y Feedbacks abgegeben": "{{x}} di {{y}} feedback consegnati/o", - "x von y abgeschlossen": "{{x}} di {{y}} completate/a" + "x von y abgeschlossen": "{{x}} di {{y}} completate/a", + "zufrieden": "soddisfatto" } diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue index ea535174..d5726d75 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue @@ -4,7 +4,6 @@ import { useCurrentCourseSession } from "@/composables"; import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations"; import { maxAssignmentPoints, - pointsToGrade, userAssignmentPoints, } from "@/services/assignmentService"; import type { @@ -47,7 +46,6 @@ async function submitEvaluation() { assignmentUserId: props.assignmentUser.user_id.toString(), completionStatus: "EVALUATION_SUBMITTED", completionDataString: JSON.stringify({}), - evaluationGrade: grade.value ?? 1, evaluationPoints: userPoints.value, // next line used for urql // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -78,12 +76,6 @@ const maxPoints = computed(() => maxAssignmentPoints(props.assignment)); const userPoints = computed(() => userAssignmentPoints(props.assignment, props.assignmentCompletion) ); -const grade = computed(() => { - if (props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED") { - return props.assignmentCompletion.evaluation_grade; - } - return pointsToGrade(userPoints.value, maxPoints.value); -}); const evaluationUser = computed(() => { if (props.assignmentCompletion.evaluation_user) { @@ -102,14 +94,14 @@ const evaluationUser = computed(() => {

Bewertung von {{ evaluationUser.first_name }} {{ evaluationUser.last_name }}

-

{{ $t("a.Bewertung Freigabe") }}

+

{{ $t("a.Bewertung Freigabe") }}

-
+
-
+
{{ userPoints }}
-
+
{{ $t("assignment.von x Punkten", { x: maxPoints }) }}
@@ -140,7 +132,11 @@ const evaluationUser = computed(() => { Uhr
-
diff --git a/client/src/services/assignmentService.ts b/client/src/services/assignmentService.ts index 1a770d85..439dfb5d 100644 --- a/client/src/services/assignmentService.ts +++ b/client/src/services/assignmentService.ts @@ -16,7 +16,6 @@ import pick from "lodash/pick"; export interface GradedUser { user: CourseSessionUser; - grade: number; points: number; } @@ -64,7 +63,6 @@ export async function loadAssignmentCompletionStatusData( if (userAssignmentStatus?.completion_status === "EVALUATION_SUBMITTED") { gradedUsers.push({ user: csu, - grade: userAssignmentStatus.evaluation_grade ?? 0, points: userAssignmentStatus.evaluation_points ?? 0, }); } @@ -123,10 +121,3 @@ export function userAssignmentPoints( ) ); } - -export function pointsToGrade(points: number, maxPoints: number) { - // round to half-grades - const grade = Math.round((points / maxPoints) * 10); - const halfGrade = grade / 2; - return Math.min(halfGrade, 5) + 1; -} diff --git a/client/src/types.ts b/client/src/types.ts index a300e47f..18b8e04d 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -595,8 +595,9 @@ export interface AssignmentCompletion { completion_status: AssignmentCompletionStatus; evaluation_user: string | null; completion_data: AssignmentCompletionData; - evaluation_grade: number | null; evaluation_points: number | null; + evaluation_max_points: number | null; + evaluation_passed: boolean | null; } export type UpsertUserAssignmentCompletion = { @@ -608,15 +609,15 @@ export type UpsertUserAssignmentCompletion = { export type EvaluationCompletionData = UpsertUserAssignmentCompletion & { assignment_user_id: string; - evaluation_grade?: number; evaluation_points?: number; + evaluation_max_points?: number; + evaluation_passed?: boolean; }; export interface UserAssignmentCompletionStatus { id: string; assignment_user_id: string; completion_status: AssignmentCompletionStatus; - evaluation_grade: number | null; evaluation_points: number | null; learning_content_page_id: number; } diff --git a/cypress/e2e/assignment/assignmentStudent.cy.js b/cypress/e2e/assignment/assignmentStudent.cy.js index b1b7320a..da74d8d9 100644 --- a/cypress/e2e/assignment/assignmentStudent.cy.js +++ b/cypress/e2e/assignment/assignmentStudent.cy.js @@ -1,3 +1,4 @@ +import { TEST_STUDENT1_USER_ID } from "../../consts"; import { login } from "../helpers"; describe("assignmentStudent.cy.js", () => { @@ -109,4 +110,134 @@ describe("assignmentStudent.cy.js", () => { ); }); }); + + it.only("can make complete assignment", () => { + cy.learningContentMultiLayoutNextStep(); + cy.testLearningContentTitle( + "Teilaufgabe 1: Beispiel einer Versicherungspolice finden" + ); + // Click confirmation + cy.get('[data-cy="it-checkbox-confirmation-1"]').click(); + cy.learningContentMultiLayoutNextStep(); + + // step 2 + cy.testLearningContentTitle( + "Teilaufgabe 2: Kundensituation und Ausgangslage" + ); + cy.get('[data-cy="it-textarea-user-text-input-1"]') + .clear() + .type("Hallo Teilaufgabe 2"); + // wait because of input debounce + cy.wait(550); + cy.learningContentMultiLayoutNextStep(); + + // check that results are stored on server + // load AssignmentCompletion from DB and check + cy.loadAssignmentCompletion( + "assignment_user_id", + TEST_STUDENT1_USER_ID + ).then((ac) => { + expect(ac.completion_status).to.equal("IN_PROGRESS"); + expect(JSON.stringify(ac.completion_data)).to.include( + "Hallo Teilaufgabe 2" + ); + }); + + // step 3 + cy.testLearningContentTitle("Teilaufgabe 3: Aktuelle Versicherung"); + cy.get('[data-cy="it-textarea-user-text-input-1"]') + .clear() + .type("Hallo Teilaufgabe 3"); + // wait because of input debounce + cy.wait(550); + cy.learningContentMultiLayoutNextStep(); + + // step 4 + cy.testLearningContentTitle("Teilaufgabe 4: Deine Empfehlungen"); + cy.get('[data-cy="it-textarea-user-text-input-1"]') + .clear() + .type("Hallo Teilaufgabe 4.1"); + cy.wait(550); + cy.get('[data-cy="it-textarea-user-text-input-2"]') + .clear() + .type("Hallo Teilaufgabe 4.2"); + cy.wait(550); + cy.get('[data-cy="it-textarea-user-text-input-3"]') + .clear() + .type("Hallo Teilaufgabe 4.3"); + // wait because of input debounce + cy.wait(550); + cy.learningContentMultiLayoutNextStep(); + + // step 5 + cy.testLearningContentTitle("Teilaufgabe 5: Reflexion"); + cy.get('[data-cy="it-textarea-user-text-input-1"]') + .clear() + .type("Hallo Teilaufgabe 5.1"); + cy.wait(550); + cy.get('[data-cy="it-textarea-user-text-input-2"]') + .clear() + .type("Hallo Teilaufgabe 5.2"); + cy.wait(550); + cy.get('[data-cy="it-textarea-user-text-input-3"]') + .clear() + .type("Hallo Teilaufgabe 5.3"); + // wait because of input debounce + cy.wait(550); + cy.learningContentMultiLayoutNextStep(); + + // step 6 + cy.testLearningContentTitle("Teilaufgabe 6: Learnings"); + cy.get('[data-cy="it-textarea-user-text-input-1"]') + .clear() + .type("Hallo Teilaufgabe 6.1"); + cy.wait(550); + cy.get('[data-cy="it-textarea-user-text-input-2"]') + .clear() + .type("Hallo Teilaufgabe 6.2"); + // wait because of input debounce + cy.wait(550); + cy.learningContentMultiLayoutNextStep(); + + cy.get('[data-cy="confirm-submit-results"]').click(); + cy.get('[data-cy="confirm-submit-person"]').click(); + cy.get('[data-cy="submit-assignment"]').click(); + cy.get('[data-cy="success-text"]').should("exist"); + + // app goes back to circle view -> check if assignment is marked as completed + cy.url().should((url) => { + expect(url).to.match(/\/fahrzeug#lu-transfer?$/); + }); + cy.reload(); + cy.get( + '[data-cy="test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice-checkbox"]' + ).should("have.class", "cy-checked"); + + // reopening page should get directly to last step + cy.visit( + "/course/test-lehrgang/learn/fahrzeug/überprüfen-einer-motorfahrzeug-versicherungspolice" + ); + cy.url().should("include", "step=7"); + + // load AssignmentCompletion from DB and check + cy.loadAssignmentCompletion( + "assignment_user_id", + TEST_STUDENT1_USER_ID + ).then((ac) => { + expect(ac.completion_status).to.equal("SUBMITTED"); + expect(ac.evaluation_max_points).to.equal(24); + const completionString = JSON.stringify(ac.completion_data); + console.log(completionString); + expect(completionString).to.include("Hallo Teilaufgabe 2"); + expect(completionString).to.include("Hallo Teilaufgabe 3"); + expect(completionString).to.include("Hallo Teilaufgabe 4.1"); + expect(completionString).to.include("Hallo Teilaufgabe 4.2"); + expect(completionString).to.include("Hallo Teilaufgabe 4.3"); + expect(completionString).to.include("Hallo Teilaufgabe 5.1"); + expect(completionString).to.include("Hallo Teilaufgabe 5.2"); + expect(completionString).to.include("Hallo Teilaufgabe 5.3"); + expect(completionString).to.include("Hallo Teilaufgabe 6.1"); + expect(completionString).to.include("Hallo Teilaufgabe 6.2"); + }); + }); }); diff --git a/cypress/e2e/assignment/assignmentTrainer.cy.js b/cypress/e2e/assignment/assignmentTrainer.cy.js index 339f12f9..998e0686 100644 --- a/cypress/e2e/assignment/assignmentTrainer.cy.js +++ b/cypress/e2e/assignment/assignmentTrainer.cy.js @@ -90,4 +90,108 @@ describe("assignmentTrainer.cy.js", () => { }); }); }); + + it.only("can make complete evaluation", () => { + cy.visit("/course/test-lehrgang/cockpit"); + cy.get( + '[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]' + ).click(); + + cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click(); + + cy.get('[data-cy="start-evaluation"]').click(); + + // step 1 + cy.get('[data-cy="evaluation-task"]').should( + "contain", + "Beurteilungskriterium 1 / 5" + ); + cy.get('[data-cy="subtask-6"]').click(); + cy.get('[data-cy="reason-text"]').type("Begründung Schritt 1"); + // wait for debounce + cy.wait(500); + cy.get('[data-cy="next-step"]').click(); + + // step 2 + cy.get('[data-cy="evaluation-task"]').should( + "contain", + "Beurteilungskriterium 2 / 5" + ); + cy.get('[data-cy="subtask-4"]').click(); + cy.get('[data-cy="reason-text"]').type("Begründung Schritt 2"); + cy.wait(500); + cy.get('[data-cy="next-step"]').click(); + + // step 3 + cy.get('[data-cy="evaluation-task"]').should( + "contain", + "Beurteilungskriterium 3 / 5" + ); + cy.get('[data-cy="subtask-2"]').click(); + cy.get('[data-cy="reason-text"]').type("Begründung Schritt 3"); + cy.wait(500); + cy.get('[data-cy="next-step"]').click(); + + // step 4 + cy.get('[data-cy="evaluation-task"]').should( + "contain", + "Beurteilungskriterium 4 / 5" + ); + cy.get('[data-cy="subtask-3"]').click(); + cy.get('[data-cy="reason-text"]').type("Begründung Schritt 4"); + cy.wait(500); + cy.get('[data-cy="next-step"]').click(); + + // step 5 + cy.get('[data-cy="evaluation-task"]').should( + "contain", + "Beurteilungskriterium 5 / 5" + ); + cy.get('[data-cy="subtask-2"]').click(); + cy.get('[data-cy="reason-text"]').type("Begründung Schritt 5"); + cy.wait(500); + cy.get('[data-cy="next-step"]').click(); + + // freigabe + cy.get('[data-cy="sub-title"]').should("contain", "Bewertung Freigabe"); + cy.get('[data-cy="user-points"]').should("contain", "17"); + cy.get('[data-cy="total-points"]').should("contain", "24"); + cy.get('[data-cy="submit-evaluation"]').click(); + + cy.get('[data-cy="result-section"]').should( + "contain", + "Deine Bewertung für Test Student1 wurde freigegeben" + ); + + // going back to cockpit should show points for student + cy.visit("/course/test-lehrgang/cockpit"); + cy.reload(); + cy.get( + '[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]' + ).click(); + + cy.get('[data-cy="Student1"]').should("contain", "Bewertung freigegeben"); + cy.get('[data-cy="Student1"]').should("contain", "17 Punkte"); + + // clicking on results page will go to last step + cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click(); + cy.url().should("include", "step=6"); + + // load AssignmentCompletion from DB and check + cy.loadAssignmentCompletion( + "assignment_user_id", + TEST_STUDENT1_USER_ID + ).then((ac) => { + expect(ac.completion_status).to.equal("EVALUATION_SUBMITTED"); + expect(ac.evaluation_points).to.equal(17); + expect(ac.evaluation_max_points).to.equal(24); + expect(ac.evaluation_passed).to.equal(true); + const completionString = JSON.stringify(ac.completion_data); + expect(completionString).to.include("Begründung Schritt 1"); + expect(completionString).to.include("Begründung Schritt 2"); + expect(completionString).to.include("Begründung Schritt 3"); + expect(completionString).to.include("Begründung Schritt 4"); + expect(completionString).to.include("Begründung Schritt 5"); + }); + }); }); diff --git a/cypress/e2e/feedback/feedbackStudent.cy.js b/cypress/e2e/feedback/feedbackStudent.cy.js index 47ae97a2..8c77ae26 100644 --- a/cypress/e2e/feedback/feedbackStudent.cy.js +++ b/cypress/e2e/feedback/feedbackStudent.cy.js @@ -133,6 +133,7 @@ describe("feedbackStudent.cy.js", () => { // reopening page should get directly to last step cy.visit("/course/test-lehrgang/learn/fahrzeug/feedback"); + cy.url().should("include", "step=11"); // check stored data cy.loadFeedbackResponse("feedback_user_id", TEST_STUDENT1_USER_ID).then( diff --git a/server/vbv_lernwelt/assignment/graphql/mutations.py b/server/vbv_lernwelt/assignment/graphql/mutations.py index 4c3df31c..683baf74 100644 --- a/server/vbv_lernwelt/assignment/graphql/mutations.py +++ b/server/vbv_lernwelt/assignment/graphql/mutations.py @@ -29,8 +29,8 @@ class AssignmentCompletionMutation(graphene.Mutation): ) completion_data_string = graphene.String() - evaluation_grade = graphene.Float() evaluation_points = graphene.Float() + evaluation_passed = graphene.Boolean() initialize_completion = graphene.Boolean(required=False) @classmethod @@ -44,8 +44,8 @@ class AssignmentCompletionMutation(graphene.Mutation): assignment_user_id=None, completion_status: AssignmentCompletionStatus = AssignmentCompletionStatus.IN_PROGRESS, completion_data_string="{}", - evaluation_grade=None, evaluation_points=None, + evaluation_passed=None, initialize_completion=False, ): if assignment_user_id is None: @@ -97,8 +97,8 @@ class AssignmentCompletionMutation(graphene.Mutation): evaluation_data = { "evaluation_user": info.context.user, - "evaluation_grade": evaluation_grade, "evaluation_points": evaluation_points, + "evaluation_passed": evaluation_passed, } ac = update_assignment_completion( diff --git a/server/vbv_lernwelt/assignment/graphql/types.py b/server/vbv_lernwelt/assignment/graphql/types.py index 198ff0ff..0649eb26 100644 --- a/server/vbv_lernwelt/assignment/graphql/types.py +++ b/server/vbv_lernwelt/assignment/graphql/types.py @@ -31,8 +31,9 @@ class AssignmentCompletionObjectType(DjangoObjectType): "completion_data", "evaluation_user", "additional_json_data", - "evaluation_grade", "evaluation_points", + "evaluation_passed", + "evaluation_max_points", ) diff --git a/server/vbv_lernwelt/assignment/migrations/0008_auto_20230928_1254.py b/server/vbv_lernwelt/assignment/migrations/0008_auto_20230928_1254.py new file mode 100644 index 00000000..84f8b2f3 --- /dev/null +++ b/server/vbv_lernwelt/assignment/migrations/0008_auto_20230928_1254.py @@ -0,0 +1,40 @@ +# Generated by Django 3.2.20 on 2023-09-28 10:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("assignment", "0007_auto_20230901_1112"), + ] + + operations = [ + migrations.RemoveField( + model_name="assignmentcompletion", + name="evaluation_grade", + ), + migrations.RemoveField( + model_name="assignmentcompletionauditlog", + name="evaluation_grade", + ), + migrations.AddField( + model_name="assignmentcompletion", + name="evaluation_max_points", + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name="assignmentcompletion", + name="evaluation_passed", + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name="assignmentcompletionauditlog", + name="evaluation_max_points", + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name="assignmentcompletionauditlog", + name="evaluation_passed", + field=models.BooleanField(blank=True, null=True), + ), + ] diff --git a/server/vbv_lernwelt/assignment/models.py b/server/vbv_lernwelt/assignment/models.py index c485aab7..5e6e28a2 100644 --- a/server/vbv_lernwelt/assignment/models.py +++ b/server/vbv_lernwelt/assignment/models.py @@ -316,8 +316,9 @@ class AssignmentCompletion(models.Model): blank=True, related_name="+", ) - evaluation_grade = models.FloatField(null=True, blank=True) evaluation_points = models.FloatField(null=True, blank=True) + evaluation_max_points = models.FloatField(null=True, blank=True) + evaluation_passed = models.BooleanField(null=True, blank=True) assignment_user = models.ForeignKey(User, on_delete=models.CASCADE) assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE) @@ -395,5 +396,6 @@ class AssignmentCompletionAuditLog(models.Model): assignment_user_email = models.CharField(max_length=255) assignment_slug = models.CharField(max_length=255) evaluation_user_email = models.CharField(max_length=255, blank=True, default="") - evaluation_grade = models.FloatField(null=True, blank=True) evaluation_points = models.FloatField(null=True, blank=True) + evaluation_max_points = models.FloatField(null=True, blank=True) + evaluation_passed = models.BooleanField(null=True, blank=True) diff --git a/server/vbv_lernwelt/assignment/serializers.py b/server/vbv_lernwelt/assignment/serializers.py index 3b9b7aa3..78791487 100644 --- a/server/vbv_lernwelt/assignment/serializers.py +++ b/server/vbv_lernwelt/assignment/serializers.py @@ -19,6 +19,7 @@ class AssignmentCompletionSerializer(serializers.ModelSerializer): "completion_data", "evaluation_user", "additional_json_data", - "evaluation_grade", "evaluation_points", + "evaluation_max_points", + "evaluation_passed", ] diff --git a/server/vbv_lernwelt/assignment/services.py b/server/vbv_lernwelt/assignment/services.py index d98c6958..ad39afc2 100644 --- a/server/vbv_lernwelt/assignment/services.py +++ b/server/vbv_lernwelt/assignment/services.py @@ -26,8 +26,8 @@ def update_assignment_completion( completion_data=None, completion_status: AssignmentCompletionStatus = AssignmentCompletionStatus.IN_PROGRESS, evaluation_user: User | None = None, - evaluation_grade: float | None = None, evaluation_points: float | None = None, + evaluation_passed: bool | None = None, validate_completion_status_change: bool = True, copy_task_data: bool = False, initialize_completion: bool = False, @@ -119,12 +119,6 @@ def update_assignment_completion( ac.evaluation_user = evaluation_user if completion_status == AssignmentCompletionStatus.EVALUATION_SUBMITTED: - if evaluation_grade is None: - raise serializers.ValidationError( - { - "evaluation_grade": "evaluation_grade is required for EVALUATION_SUBMITTED status" - } - ) if evaluation_points is None: raise serializers.ValidationError( { @@ -132,9 +126,15 @@ def update_assignment_completion( } ) - ac.evaluation_grade = evaluation_grade + ac.evaluation_max_points = assignment.get_max_points() ac.evaluation_points = evaluation_points + # if no evaluation_passed is provided, we calculate it from the points + if evaluation_passed is None and evaluation_points is not None: + # if more or equal than 60% of the points are reached, the assignment is passed + # TODO: check with VBV if this is correct + ac.evaluation_passed = (evaluation_points / ac.evaluation_max_points) >= 0.6 + if completion_status == AssignmentCompletionStatus.SUBMITTED: ac.submitted_at = timezone.now() if evaluation_user: @@ -192,6 +192,9 @@ def update_assignment_completion( assignment_user_email=assignment_user.email, assignment_slug=assignment.slug, completion_data=deepcopy(ac.completion_data), + evaluation_points=evaluation_points, + evaluation_max_points=ac.evaluation_max_points, + evaluation_passed=ac.evaluation_passed, ) if evaluation_user: acl.evaluation_user_email = evaluation_user.email diff --git a/server/vbv_lernwelt/assignment/tests/test_graphql.py b/server/vbv_lernwelt/assignment/tests/test_graphql.py index 9f5d0174..debebc04 100644 --- a/server/vbv_lernwelt/assignment/tests/test_graphql.py +++ b/server/vbv_lernwelt/assignment/tests/test_graphql.py @@ -330,7 +330,6 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): course_session_id: {self.course_session.id} completion_status: EVALUATION_SUBMITTED completion_data_string: "{completion_data_string}" - evaluation_grade: 4.5, evaluation_points: 16, ) {{ assignment_completion {{ @@ -370,8 +369,9 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "EVALUATION_SUBMITTED") - self.assertEqual(db_entry.evaluation_grade, 4.5) self.assertEqual(db_entry.evaluation_points, 16) + self.assertEqual(db_entry.evaluation_max_points, 24) + self.assertTrue(db_entry.evaluation_passed) self.assertDictEqual( db_entry.completion_data, { @@ -440,6 +440,9 @@ class AttendanceCourseUserMutationTestCase(GraphQLTestCase): }, }, ) + self.assertEqual(acl.evaluation_points, 16) + self.assertEqual(acl.evaluation_max_points, 24) + self.assertTrue(acl.evaluation_passed) def test_student_can_upsert_reflection(self): """ diff --git a/server/vbv_lernwelt/assignment/tests/test_services.py b/server/vbv_lernwelt/assignment/tests/test_services.py index c523424a..3708a8d0 100644 --- a/server/vbv_lernwelt/assignment/tests/test_services.py +++ b/server/vbv_lernwelt/assignment/tests/test_services.py @@ -478,7 +478,6 @@ class UpdateAssignmentCompletionTestCase(TestCase): completion_data={}, completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED, evaluation_user=self.trainer, - evaluation_grade=None, evaluation_points=None, ) @@ -489,7 +488,6 @@ class UpdateAssignmentCompletionTestCase(TestCase): completion_data={}, completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED, evaluation_user=self.trainer, - evaluation_grade=4.5, evaluation_points=16, ) @@ -500,8 +498,9 @@ class UpdateAssignmentCompletionTestCase(TestCase): ) self.assertEqual(ac.completion_status, "EVALUATION_SUBMITTED") - self.assertEqual(ac.evaluation_grade, 4.5) self.assertEqual(ac.evaluation_points, 16) + self.assertEqual(ac.evaluation_max_points, 24) + self.assertTrue(ac.evaluation_passed) trainer_input = ac.completion_data[evaluation_task["id"]] self.assertDictEqual( trainer_input["expert_data"], {"points": 2, "text": "Gut gemacht!"} @@ -532,6 +531,9 @@ class UpdateAssignmentCompletionTestCase(TestCase): self.assertDictEqual( user_input["user_data"], {"text": "Ich würde nichts weiteres empfehlen."} ) + self.assertEqual(acl.evaluation_points, 16) + self.assertEqual(acl.evaluation_max_points, 24) + self.assertTrue(acl.evaluation_passed) # AssignmentCompletionAuditLog entry will remain event after deletion of foreign keys ac.delete() diff --git a/server/vbv_lernwelt/assignment/views.py b/server/vbv_lernwelt/assignment/views.py index 58cef7ab..974af663 100644 --- a/server/vbv_lernwelt/assignment/views.py +++ b/server/vbv_lernwelt/assignment/views.py @@ -20,8 +20,8 @@ def request_assignment_completion_status(request, assignment_id, course_session_ "id", "assignment_user_id", "completion_status", - "evaluation_grade", "evaluation_points", + "evaluation_passed", "learning_content_page_id", ) return Response(status=200, data=qs) diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index e4a23b7e..ac32e2fa 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -271,7 +271,6 @@ def create_test_assignment_evaluation_data( completion_data={}, completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED, evaluation_user=evaluation_user, - evaluation_grade=6, evaluation_points=evaluation_points, ) @@ -288,7 +287,6 @@ def create_edoniq_test_result_data( completion_data={}, completion_status=AssignmentCompletionStatus.EVALUATION_SUBMITTED, evaluation_user=User.objects.get(username="admin"), - evaluation_grade=6, evaluation_points=points, ) From f8c6daf9eb8f527d9c03a6fda3f69e74a1e910a4 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 28 Sep 2023 16:38:23 +0200 Subject: [PATCH 03/10] =?UTF-8?q?VBV-519:=20Anpassungen=20Darstellung=20Wi?= =?UTF-8?q?ssens-=20und=20Verst=C3=A4ndnisfragen=20f=C3=BCr=20Lernende?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/dueDates/dueDatesUtils.ts | 20 +-- .../blocks/EdoniqTestBlock.vue | 130 ++++++++++++++---- client/src/services/assignmentService.ts | 7 + client/src/stores/courseSessions.ts | 12 ++ client/src/types.ts | 9 ++ .../course/creators/test_course.py | 15 ++ server/vbv_lernwelt/course/serializers.py | 9 ++ .../course_session/serializers.py | 19 +++ 8 files changed, 182 insertions(+), 39 deletions(-) diff --git a/client/src/components/dueDates/dueDatesUtils.ts b/client/src/components/dueDates/dueDatesUtils.ts index 0c305f05..850377f8 100644 --- a/client/src/components/dueDates/dueDatesUtils.ts +++ b/client/src/components/dueDates/dueDatesUtils.ts @@ -3,23 +3,25 @@ import dayjs from "dayjs"; import LocalizedFormat from "dayjs/plugin/localizedFormat"; import i18next from "i18next"; -export const formatDueDate = (start: string, end: string) => { +export const formatDueDate = (start: string, end?: string) => { dayjs.extend(LocalizedFormat); const startDayjs = dayjs(start); - const endDayjs = dayjs(end); const startDateString = getDateString(startDayjs); - const endDateString = getDateString(endDayjs); - // if startDayjs isundefined, dont show the day twice + let endDayjs; + let endDateString; + if (end) { + endDayjs = dayjs(end); + endDateString = getDateString(endDayjs); + } - if (!startDayjs.isValid() && !endDayjs.isValid()) { + // at least `start` must be provided and valid + if (!startDayjs.isValid()) { return i18next.t("Termin nicht festgelegt"); } - if (!startDayjs || (!startDayjs.isValid() && endDayjs.isValid())) { - return `${endDateString} ${getTimeString(endDayjs)} ${endDayjs.format("[Uhr]")}`; - } - if (!endDayjs || (!endDayjs.isValid() && startDayjs.isValid())) { + // when only `start` is provided, show only the start date with time + if (!endDayjs || !endDayjs.isValid()) { return `${startDateString} ${getTimeString(startDayjs)} ${startDayjs.format( "[Uhr]" )}`; diff --git a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue index 22b47398..47abd727 100644 --- a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue +++ b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue @@ -2,17 +2,20 @@ import { useTranslation } from "i18next-vue"; import ItCheckbox from "@/components/ui/ItCheckbox.vue"; import LearningContentSimpleLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentSimpleLayout.vue"; -import type { - Assignment, - AssignmentCompletion, - LearningContentEdoniqTest, -} from "@/types"; +import type { AssignmentCompletion, LearningContentEdoniqTest } from "@/types"; import { computed, ref } from "vue"; import * as log from "loglevel"; import { itPost } from "@/fetchHelpers"; import { useQuery } from "@urql/vue"; import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries"; import { useCurrentCourseSession } from "@/composables"; +import { useCourseSessionsStore } from "@/stores/courseSessions"; +import dayjs from "dayjs"; +import { + formatDueDate, + getDateString, +} from "../../../../components/dueDates/dueDatesUtils"; +import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue"; const { t } = useTranslation(); @@ -21,6 +24,11 @@ const props = defineProps<{ }>(); const courseSession = useCurrentCourseSession(); +const courseSessionsStore = useCourseSessionsStore(); + +const courseSessionEdoniqTest = computed(() => { + return courseSessionsStore.findCourseSessionEdoniqTest(props.content.id); +}); const queryResult = useQuery({ query: ASSIGNMENT_COMPLETION_QUERY, @@ -31,21 +39,25 @@ const queryResult = useQuery({ }, }); -const assignment = computed( - () => queryResult.data.value?.assignment as Assignment | undefined -); const assignmentCompletion = computed( () => queryResult.data.value?.assignment_completion as AssignmentCompletion | undefined ); const completionStatus = computed(() => { - return assignmentCompletion.value?.completion_status ?? "IN_PROGRESS"; + return assignmentCompletion.value?.completion_status ?? ""; }); const termsAccepted = ref(false); const extendedTimeTest = ref(false); +const deadlineInPast = computed(() => { + // with 16 minutes buffer + return dayjs(courseSessionEdoniqTest.value?.deadline_start) + .add(16, "minute") + .isBefore(dayjs()); +}); + async function startTest() { log.info("start test", props.content); const response = await itPost("/api/core/edoniq-test/redirect/", { @@ -62,24 +74,46 @@ async function startTest() { :title="props.content.title" :learning-content="props.content" > - -
-
-
- {{ $t("a.Bewertung") }}: - {{ assignmentCompletion?.evaluation_points }} - {{ $t("assignment.von x Punkten", { x: assignment?.max_points }) }} -
-
Ergebnisse abgeben, Bewertung ausstehend
-
-
-

+
+
+

{{ $t("a.Aufgabe") }}

+

{{ $t("edoniqTest.testDescription") }}

+
-
+
+

{{ $t("a.Abgabetermin") }}

+

+ {{ + $t("edoniqTest.submitDateDescription", { + x: formatDueDate(courseSessionEdoniqTest.deadline_start), + }) + }} +

+
+ +
+

{{ $t("a.Kompetenznachweis") }}

+
+ {{ + $t("circlePage.Dieser Inhalt gehört zu x", { + x: content.competence_certificate?.title, + }) + }}. +
+
+ + {{ $t("circlePage.Im KompetenzNavi anschauen") }} + +
+
+ +
+
+

{{ $t("edoniqTest.checkboxTitle") }}

-
+

{{ $t("edoniqTest.qualifiesForExtendedTimeTitle") }}

-
+
+ +
+
+ {{ $t("edoniqTest.deadlineInPast") }} +
+
+ {{ $t("a.Abgabetermin") }}: + {{ getDateString(dayjs(courseSessionEdoniqTest?.deadline_start)) }} +
+
-
+
+ +
+
+ +
+ {{ $t("a.Resultat") }}: + + {{ assignmentCompletion.evaluation_points }} + + {{ + $t("assignment.von x Punkten", { + x: assignmentCompletion.evaluation_max_points, + }) + }} +
+ +
+ +
+
+
diff --git a/client/src/services/assignmentService.ts b/client/src/services/assignmentService.ts index 439dfb5d..dc6bb4da 100644 --- a/client/src/services/assignmentService.ts +++ b/client/src/services/assignmentService.ts @@ -121,3 +121,10 @@ export function userAssignmentPoints( ) ); } + +export function pointsToGrade(points: number, maxPoints: number) { + // round to half-grades + const grade = Math.round((points / maxPoints) * 10); + const halfGrade = grade / 2; + return Math.min(halfGrade, 5) + 1; +} diff --git a/client/src/stores/courseSessions.ts b/client/src/stores/courseSessions.ts index 7c6bb476..d5fd89d2 100644 --- a/client/src/stores/courseSessions.ts +++ b/client/src/stores/courseSessions.ts @@ -5,6 +5,7 @@ import type { CourseSession, CourseSessionAssignment, CourseSessionAttendanceCourse, + CourseSessionEdoniqTest, CourseSessionUser, DueDate, ExpertSessionUser, @@ -264,6 +265,16 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => { } } + function findCourseSessionEdoniqTest( + contentId?: number + ): CourseSessionEdoniqTest | undefined { + if (contentId && currentCourseSession.value) { + return currentCourseSession.value.edoniq_tests.find( + (a) => a.learning_content_id === contentId + ); + } + } + return { uniqueCourseSessionsByCourse, allCurrentCourseSessions, @@ -280,6 +291,7 @@ export const useCourseSessionsStore = defineStore("courseSessions", () => { removeDocument, findAttendanceCourse, findCourseSessionAssignment, + findCourseSessionEdoniqTest, allDueDates, // use `useCurrentCourseSession` whenever possible diff --git a/client/src/types.ts b/client/src/types.ts index 18b8e04d..4ea6bda2 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -485,6 +485,14 @@ export interface CourseSessionAssignment { evaluation_deadline_start: string; } +export interface CourseSessionEdoniqTest { + id: number; + course_session_id: number; + learning_content_id: number; + deadline_id: number; + deadline_start: string; +} + export interface CourseSession { id: number; created_at: string; @@ -500,6 +508,7 @@ export interface CourseSession { media_library_url: string; attendance_courses: CourseSessionAttendanceCourse[]; assignments: CourseSessionAssignment[]; + edoniq_tests: CourseSessionEdoniqTest[]; documents: CircleDocument[]; users: CourseSessionUser[]; due_dates: DueDate[]; diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index ac32e2fa..4582f963 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -49,12 +49,14 @@ from vbv_lernwelt.course.utils import get_wagtail_default_site from vbv_lernwelt.course_session.models import ( CourseSessionAssignment, CourseSessionAttendanceCourse, + CourseSessionEdoniqTest, ) from vbv_lernwelt.feedback.services import update_feedback_response from vbv_lernwelt.learnpath.models import ( Circle, LearningContentAssignment, LearningContentAttendanceCourse, + LearningContentEdoniqTest, ) from vbv_lernwelt.learnpath.tests.learning_path_factories import ( CircleFactory, @@ -168,6 +170,19 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False): ) csa.submission_deadline.save() + cset = CourseSessionEdoniqTest.objects.create( + course_session=cs_bern, + learning_content=LearningContentEdoniqTest.objects.get( + slug="test-lehrgang-lp-circle-fahrzeug-lc-wissens-und-verständnisfragen" + ), + ) + cset.deadline.start = timezone.make_aware( + (next_monday + relativedelta(days=3)).replace( + hour=21, minute=0, second=0, microsecond=0 + ) + ) + cset.deadline.save() + cs_zurich = CourseSession.objects.create( course_id=COURSE_TEST_ID, title="Test Zürich 2022 a", diff --git a/server/vbv_lernwelt/course/serializers.py b/server/vbv_lernwelt/course/serializers.py index 69d326b2..a1b1ba56 100644 --- a/server/vbv_lernwelt/course/serializers.py +++ b/server/vbv_lernwelt/course/serializers.py @@ -10,10 +10,12 @@ from vbv_lernwelt.course.models import ( from vbv_lernwelt.course_session.models import ( CourseSessionAssignment, CourseSessionAttendanceCourse, + CourseSessionEdoniqTest, ) from vbv_lernwelt.course_session.serializers import ( CourseSessionAssignmentSerializer, CourseSessionAttendanceCourseSerializer, + CourseSessionEdoniqTestSerializer, ) from vbv_lernwelt.duedate.models import DueDate from vbv_lernwelt.duedate.serializers import DueDateSerializer @@ -61,6 +63,7 @@ class CourseSessionSerializer(serializers.ModelSerializer): documents = serializers.SerializerMethodField() attendance_courses = serializers.SerializerMethodField() assignments = serializers.SerializerMethodField() + edoniq_tests = serializers.SerializerMethodField() due_dates = serializers.SerializerMethodField() def get_course(self, obj): @@ -97,6 +100,11 @@ class CourseSessionSerializer(serializers.ModelSerializer): CourseSessionAssignment.objects.filter(course_session=obj), many=True ).data + def get_edoniq_tests(self, obj): + return CourseSessionEdoniqTestSerializer( + CourseSessionEdoniqTest.objects.filter(course_session=obj), many=True + ).data + def get_due_dates(self, obj): due_dates = DueDate.objects.filter(course_session=obj) return DueDateSerializer(due_dates, many=True).data @@ -114,6 +122,7 @@ class CourseSessionSerializer(serializers.ModelSerializer): "additional_json_data", "attendance_courses", "assignments", + "edoniq_tests", "learning_path_url", "cockpit_url", "competence_url", diff --git a/server/vbv_lernwelt/course_session/serializers.py b/server/vbv_lernwelt/course_session/serializers.py index 76c9d9f8..7bec74a2 100644 --- a/server/vbv_lernwelt/course_session/serializers.py +++ b/server/vbv_lernwelt/course_session/serializers.py @@ -3,6 +3,7 @@ from rest_framework import serializers from vbv_lernwelt.course_session.models import ( CourseSessionAssignment, CourseSessionAttendanceCourse, + CourseSessionEdoniqTest, ) @@ -61,3 +62,21 @@ class CourseSessionAssignmentSerializer(serializers.ModelSerializer): def get_submission_deadline_start(self, obj): if obj.submission_deadline: return obj.submission_deadline.start + + +class CourseSessionEdoniqTestSerializer(serializers.ModelSerializer): + deadline_start = serializers.SerializerMethodField() + + class Meta: + model = CourseSessionEdoniqTest + fields = [ + "id", + "course_session_id", + "learning_content_id", + "deadline_id", + "deadline_start", + ] + + def get_deadline_start(self, obj): + if obj.deadline: + return obj.deadline.start From 4123e15f22eb234af368ba064c884aee88147720 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Fri, 29 Sep 2023 12:43:53 +0200 Subject: [PATCH 04/10] VBV-514: Bewertung von Assignments ist "opt-in" --- client/src/gql/gql.ts | 4 ++-- client/src/gql/graphql.ts | 6 +++-- client/src/gql/schema.graphql | 5 +++++ client/src/graphql/queries.ts | 1 + .../AssignmentEvaluationPage.vue | 12 ++++++++-- .../blocks/EdoniqTestBlock.vue | 2 ++ client/src/types.ts | 1 + client/src/utils/typeMaps.ts | 14 ++---------- client/src/utils/utils.ts | 22 ++++++++++++++++++- .../assignment/creators/create_assignments.py | 1 + .../vbv_lernwelt/assignment/graphql/types.py | 1 + .../0009_assignment_needs_evaluation.py | 20 +++++++++++++++++ server/vbv_lernwelt/assignment/models.py | 6 +++++ 13 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 server/vbv_lernwelt/assignment/migrations/0009_assignment_needs_evaluation.py diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index ab9d81fb..c5616dce 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -17,7 +17,7 @@ const documents = { "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, "\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc, "\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument, - "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, @@ -56,7 +56,7 @@ export function graphql(source: "\n query attendanceCheckQuery($courseSessionId /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"]; +export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 870bb977..8ccd1166 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -118,6 +118,8 @@ export type AssignmentObjectType = CoursePageInterface & { learning_content?: Maybe; live?: Maybe; max_points?: Maybe; + /** Muss der Auftrag durch eine Expertin oder einen Experten beurteilt werden? */ + needs_expert_evaluation: Scalars['Boolean']['output']; performance_objectives?: Maybe; slug?: Maybe; tasks?: Maybe; @@ -732,7 +734,7 @@ export type AssignmentCompletionQueryQueryVariables = Exact<{ }>; -export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, max_points?: number | null, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null, competence_certificate?: ( +export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, needs_expert_evaluation: boolean, max_points?: number | null, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null, competence_certificate?: ( { __typename?: 'CompetenceCertificateObjectType' } & { ' $fragmentRefs'?: { 'CoursePageFieldsCompetenceCertificateObjectTypeFragment': CoursePageFieldsCompetenceCertificateObjectTypeFragment } } ) | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_points?: number | null, evaluation_max_points?: number | null, evaluation_passed?: boolean | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; @@ -805,7 +807,7 @@ export const CoursePageFieldsFragmentDoc = {"kind":"Document","definitions":[{"k export const AttendanceCheckMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AttendanceCheckMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AttendanceUserInputType"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update_course_session_attendance_course_users"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"attendance_user_list"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"first_name"}},{"kind":"Field","name":{"kind":"Name","value":"last_name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}},{"kind":"Argument","name":{"kind":"Name","value":"initialize_completion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; export const AttendanceCheckQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"attendanceCheckQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; -export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"needs_expert_evaluation"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const CompetenceCertificateQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"competenceCertificateQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_list"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}}]}},{"kind":"Field","name":{"kind":"Name","value":"learning_content"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}},{"kind":"Field","name":{"kind":"Name","value":"circle"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenericScalar"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"submitted"},"value":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"submitted"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index 708ba6da..ce075601 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -226,6 +226,11 @@ type LearningContentAssignmentObjectType implements LearningContentInterface { type AssignmentObjectType implements CoursePageInterface { assignment_type: AssignmentAssignmentAssignmentTypeChoices! + + """ + Muss der Auftrag durch eine Expertin oder einen Experten beurteilt werden? + """ + needs_expert_evaluation: Boolean! competence_certificate: CompetenceCertificateObjectType """Erläuterung der Ausgangslage""" diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index f909d44e..7acabe82 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -32,6 +32,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(` ) { assignment(id: $assignmentId) { assignment_type + needs_expert_evaluation max_points content_type effort_required diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue index 02c0820c..24422f6f 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue @@ -14,6 +14,7 @@ import log from "loglevel"; import { computed, onMounted, reactive } from "vue"; import { useRouter } from "vue-router"; import { getPreviousRoute } from "@/router/history"; +import { getAssignmentTypeTitle } from "@/utils/utils"; const props = defineProps<{ courseSlug: string; @@ -87,7 +88,10 @@ const assignment = computed(
- {{ $t("a.Geleitete Fallarbeit") }}: {{ assignment?.title }} + + {{ getAssignmentTypeTitle(assignment.assignment_type) }}: + + {{ assignment?.title }}
From 86cf8f44d3f2289407814c28aba26706029a1498 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 5 Oct 2023 12:04:39 +0200 Subject: [PATCH 08/10] Add percent for results and "Bestanden"/"Nicht Bestanden" --- client/src/colors.json | 4 ++ client/src/gql/gql.ts | 4 +- client/src/gql/graphql.ts | 4 +- client/src/graphql/queries.ts | 2 + .../EvaluationSummary.vue | 13 ++++++ .../documentPage/DocumentUploadForm.vue | 8 ++-- .../competence/CompetenceAssignmentRow.vue | 14 +++++++ .../blocks/EdoniqTestBlock.vue | 19 +++++++-- client/src/types.ts | 2 + cypress/e2e/appointments.cy.js | 4 +- .../e2e/assignment/assignmentStudent.cy.js | 2 +- .../e2e/assignment/assignmentTrainer.cy.js | 2 +- .../competenceCertificate.cy.js | 41 ++++++++++++++++++- .../core/management/commands/cypress_reset.py | 18 +++++++- server/vbv_lernwelt/core/views.py | 22 ++++++---- .../course/creators/test_course.py | 12 ++++-- .../vbv_lernwelt/templates/admin/index.html | 4 ++ 17 files changed, 146 insertions(+), 29 deletions(-) diff --git a/client/src/colors.json b/client/src/colors.json index f49a11b6..77490890 100644 --- a/client/src/colors.json +++ b/client/src/colors.json @@ -3,6 +3,10 @@ "current": "currentColor", "white": "#ffffff", "black": "#0A0A0A", + "error-red": { + "200": "#FEDADA", + "500": "#DD2424" + }, "blue": { "200": "#D2E0FA", "300": "#B4CCFA", diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index c5616dce..68842432 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -19,7 +19,7 @@ const documents = { "\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument, "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, - "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, + "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, }; @@ -64,7 +64,7 @@ export function graphql(source: "\n query courseQuery($courseId: Int!) {\n c /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n"]; +export function graphql(source: "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 8ccd1166..1506ba90 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -755,7 +755,7 @@ export type CompetenceCertificateQueryQueryVariables = Exact<{ export type CompetenceCertificateQueryQuery = { __typename?: 'Query', competence_certificate_list?: ( { __typename?: 'CompetenceCertificateListObjectType', competence_certificates?: Array<( { __typename?: 'CompetenceCertificateObjectType', assignments?: Array<( - { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, max_points?: number | null, completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_points?: number | null } | null, learning_content?: { __typename?: 'LearningContentAssignmentObjectType', title?: string | null, id?: string | null, slug?: string | null, content_type?: string | null, frontend_url?: string | null, circle?: ( + { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, max_points?: number | null, completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_points?: number | null, evaluation_max_points?: number | null, evaluation_passed?: boolean | null } | null, learning_content?: { __typename?: 'LearningContentAssignmentObjectType', title?: string | null, id?: string | null, slug?: string | null, content_type?: string | null, frontend_url?: string | null, circle?: ( { __typename?: 'CircleObjectType' } & { ' $fragmentRefs'?: { 'CoursePageFieldsCircleObjectTypeFragment': CoursePageFieldsCircleObjectTypeFragment } } ) | null } | { __typename?: 'LearningContentAttendanceCourseObjectType', title?: string | null, id?: string | null, slug?: string | null, content_type?: string | null, frontend_url?: string | null, circle?: ( @@ -809,5 +809,5 @@ export const UpsertAssignmentCompletionDocument = {"kind":"Document","definition export const AttendanceCheckQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"attendanceCheckQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"needs_expert_evaluation"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CompetenceCertificateQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"competenceCertificateQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_list"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}}]}},{"kind":"Field","name":{"kind":"Name","value":"learning_content"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}},{"kind":"Field","name":{"kind":"Name","value":"circle"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; +export const CompetenceCertificateQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"competenceCertificateQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_list"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"learning_content"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}},{"kind":"Field","name":{"kind":"Name","value":"circle"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenericScalar"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"submitted"},"value":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"submitted"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index 7acabe82..4ecc5998 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -103,6 +103,8 @@ export const COMPETENCE_NAVI_CERTIFICATE_QUERY = graphql(` completion_status submitted_at evaluation_points + evaluation_max_points + evaluation_passed } learning_content { title diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue index d5726d75..ce53b692 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue @@ -103,9 +103,22 @@ const evaluationUser = computed(() => {
{{ $t("assignment.von x Punkten", { x: maxPoints }) }} + ({{ + ( + ((props.assignmentCompletion?.evaluation_points ?? 0) / + (props.assignmentCompletion?.evaluation_max_points ?? 1)) * + 100 + ).toFixed(0) + }}%)
+
+ + {{ $t("a.Nicht Bestanden") }} + +
+

{{ $t("assignment.evaluationInstrumentDescriptionText") }}

diff --git a/client/src/pages/cockpit/documentPage/DocumentUploadForm.vue b/client/src/pages/cockpit/documentPage/DocumentUploadForm.vue index 420eea55..1fbe6452 100644 --- a/client/src/pages/cockpit/documentPage/DocumentUploadForm.vue +++ b/client/src/pages/cockpit/documentPage/DocumentUploadForm.vue @@ -92,7 +92,7 @@ function showFileInformation() {

{{ formData.file.name }}

-

{{ $t("circlePage.documents.selectFile") }}

+

{{ $t("circlePage.documents.selectFile") }}

{{ $t("circlePage.documents.maxFileSize") }}

@@ -103,7 +103,7 @@ function showFileInformation() {

{{ $t("circlePage.documents.modalNameInformation") }}

-

{{ $t("circlePage.documents.chooseName") }}

+

{{ $t("circlePage.documents.chooseName") }}

@@ -116,13 +116,13 @@ function showFileInformation() { :items="props.learningSequences" >
-

+

{{ $t("circlePage.documents.chooseLearningSequence") }}

-

+

{{ $t("circlePage.documents.uploadErrorMessage") }}

diff --git a/client/src/pages/competence/CompetenceAssignmentRow.vue b/client/src/pages/competence/CompetenceAssignmentRow.vue index c1acb8ae..bfafef2d 100644 --- a/client/src/pages/competence/CompetenceAssignmentRow.vue +++ b/client/src/pages/competence/CompetenceAssignmentRow.vue @@ -35,6 +35,7 @@ const getIconName = () => { v-if="assignment.learning_content" :href="assignment.frontend_url" class="link" + data-cy="open-learning-content" > {{ $t("general.im circle x anschauen", { @@ -84,6 +85,19 @@ const getIconName = () => {
{{ $t("assignment.von x Punkten", { x: assignment.max_points }) }} + ({{ + ( + ((assignment.completion?.evaluation_points ?? 0) / + (assignment.completion?.evaluation_max_points ?? 1)) * + 100 + ).toFixed(0) + }}%) +
+
+ {{ $t("a.Nicht Bestanden") }}
diff --git a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue index 103af4ef..6904adad 100644 --- a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue +++ b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue @@ -150,7 +150,7 @@ async function startTest() {
-
+
{{ $t("edoniqTest.deadlineInPast") }}
@@ -162,7 +162,7 @@ async function startTest() {
-
+
{{ $t("a.Resultat") }}: @@ -173,7 +173,20 @@ async function startTest() { $t("assignment.von x Punkten", { x: assignmentCompletion.evaluation_max_points, }) - }} + }}, + {{ + ( + ((assignmentCompletion.evaluation_points ?? 0) / + (assignmentCompletion.evaluation_max_points ?? 1)) * + 100 + ).toFixed(0) + }}%, + + ({{ $t("a.Bestanden") }}) + + + ({{ $t("a.Nicht Bestanden") }}) +
diff --git a/client/src/types.ts b/client/src/types.ts index dc7afd26..5219e900 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -424,6 +424,8 @@ export interface CompetenceCertificateAssignment extends BaseCourseWagtailPage { completion_status: AssignmentCompletionStatus; evaluation_submitted_at: string | null; evaluation_points: number | null; + evaluation_max_points: number | null; + evaluation_passed: boolean | null; } | null; } diff --git a/cypress/e2e/appointments.cy.js b/cypress/e2e/appointments.cy.js index e3f618f5..cc660032 100644 --- a/cypress/e2e/appointments.cy.js +++ b/cypress/e2e/appointments.cy.js @@ -1,4 +1,4 @@ -import {login} from "./helpers"; +import { login } from "./helpers"; // constants const COURSE_SELECT = "[data-cy=appointments-course-select]"; @@ -19,7 +19,7 @@ describe("appointments.cy.js", () => { cy.get(SESSION_SELECT).should("contain", "Bern"); cy.get(CIRCLE_SELECT).should("contain", "Alle"); - cy.get(".cy-single-due-date").should("have.length", 4); + cy.get(".cy-single-due-date").should("have.length", 5); }); it("can filter by circle", () => { diff --git a/cypress/e2e/assignment/assignmentStudent.cy.js b/cypress/e2e/assignment/assignmentStudent.cy.js index da74d8d9..1a686c55 100644 --- a/cypress/e2e/assignment/assignmentStudent.cy.js +++ b/cypress/e2e/assignment/assignmentStudent.cy.js @@ -111,7 +111,7 @@ describe("assignmentStudent.cy.js", () => { }); }); - it.only("can make complete assignment", () => { + it("can make complete assignment", () => { cy.learningContentMultiLayoutNextStep(); cy.testLearningContentTitle( "Teilaufgabe 1: Beispiel einer Versicherungspolice finden" diff --git a/cypress/e2e/assignment/assignmentTrainer.cy.js b/cypress/e2e/assignment/assignmentTrainer.cy.js index 998e0686..7685dcef 100644 --- a/cypress/e2e/assignment/assignmentTrainer.cy.js +++ b/cypress/e2e/assignment/assignmentTrainer.cy.js @@ -91,7 +91,7 @@ describe("assignmentTrainer.cy.js", () => { }); }); - it.only("can make complete evaluation", () => { + it("can make complete evaluation", () => { cy.visit("/course/test-lehrgang/cockpit"); cy.get( '[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]' diff --git a/cypress/e2e/competenceNavi/competenceCertificate.cy.js b/cypress/e2e/competenceNavi/competenceCertificate.cy.js index 0bbff9f0..9b679590 100644 --- a/cypress/e2e/competenceNavi/competenceCertificate.cy.js +++ b/cypress/e2e/competenceNavi/competenceCertificate.cy.js @@ -90,7 +90,46 @@ describe("competenceCertificate.cy.js", () => { '[data-cy="assignment-test-lehrgang-assignment-edoniq-wissens-und-verständisfragen-circle-fahrzeug-demo"]' ) .should("contain", "19") - .and("contain", "Bewertung freigegeben"); + .and("contain", "Bewertung freigegeben") + .and("not.contain", "Nicht Bestanden"); + + // it can open learning content page directly + cy.get( + '[data-cy="assignment-test-lehrgang-assignment-edoniq-wissens-und-verständisfragen-circle-fahrzeug-demo"] [data-cy="open-learning-content"]' + ).click(); + cy.get('[data-cy="test-result"]') + .should("contain", "19 von 24 Punkten") + .and("contain", "79%") + .and("contain", "Bestanden"); + }); + + it("check with finished failed edoniq test", () => { + cy.manageCommand( + "cypress_reset --create-assignment-completion --create-edoniq-test-results 10 24" + ); + login("test-student1@example.com", "test"); + + // go to certificate detail page + cy.visit( + "/course/test-lehrgang/competence/certificates/kompetenznachweis-1" + ); + + cy.get( + '[data-cy="assignment-test-lehrgang-assignment-edoniq-wissens-und-verständisfragen-circle-fahrzeug-demo"]' + ) + .should("contain", "10") + .and("contain", "Bewertung freigegeben") + .and("contain", "42%") + .and("contain", "Nicht Bestanden"); + + // it can open learning content page directly + cy.get( + '[data-cy="assignment-test-lehrgang-assignment-edoniq-wissens-und-verständisfragen-circle-fahrzeug-demo"] [data-cy="open-learning-content"]' + ).click(); + cy.get('[data-cy="test-result"]') + .should("contain", "10 von 24 Punkten") + .and("contain", "42%") + .and("contain", "Nicht Bestanden"); }); it("check with finished edoniq test and finished casework", () => { diff --git a/server/vbv_lernwelt/core/management/commands/cypress_reset.py b/server/vbv_lernwelt/core/management/commands/cypress_reset.py index 4d021aab..12fc46b6 100644 --- a/server/vbv_lernwelt/core/management/commands/cypress_reset.py +++ b/server/vbv_lernwelt/core/management/commands/cypress_reset.py @@ -32,6 +32,11 @@ from vbv_lernwelt.notify.models import Notification default=False, help="will create assignment evaluation data for test-student1@example.com", ) +@click.option( + "--assignment-evaluation-scores", + default=None, + help="Provide assignment evaluation scores in the format: 6,6,6,3,3", +) @click.option( "--create-edoniq-test-results", type=(int, int), @@ -47,6 +52,7 @@ from vbv_lernwelt.notify.models import Notification def command( create_assignment_completion, create_assignment_evaluation, + assignment_evaluation_scores, create_edoniq_test_results, create_feedback_responses, ): @@ -68,7 +74,16 @@ def command( user=User.objects.get(id=TEST_STUDENT1_USER_ID), ) if create_assignment_evaluation: - print("create assignment evaulation data for test course") + if not assignment_evaluation_scores: + assignment_evaluation_scores = [6, 6, 6, 3, 3] + else: + assignment_evaluation_scores = tuple( + map(int, assignment_evaluation_scores.split(",")) + ) + print( + "create assignment evaluation data for test course", + assignment_evaluation_scores, + ) create_test_assignment_evaluation_data( assignment=Assignment.objects.get( slug="test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs-versicherungspolice" @@ -76,6 +91,7 @@ def command( course_session=CourseSession.objects.get(id=TEST_COURSE_SESSION_BERN_ID), assignment_user=User.objects.get(id=TEST_STUDENT1_USER_ID), evaluation_user=User.objects.get(id=TEST_TRAINER1_USER_ID), + input_scores=assignment_evaluation_scores, ) user_points, max_points = create_edoniq_test_results diff --git a/server/vbv_lernwelt/core/views.py b/server/vbv_lernwelt/core/views.py index cc04c8e1..08584092 100644 --- a/server/vbv_lernwelt/core/views.py +++ b/server/vbv_lernwelt/core/views.py @@ -135,27 +135,33 @@ def check_rate_limit(request): def cypress_reset_view(request): if not settings.APP_ENVIRONMENT.startswith("prod"): # Checking for the flags in the POST request + options = {} + create_assignment_completion = ( request.data.get("create_assignment_completion") == "true" ) + if create_assignment_completion: + options["create_assignment_completion"] = create_assignment_completion + create_assignment_evaluation = ( request.data.get("create_assignment_evaluation") == "true" ) + if create_assignment_evaluation: + options["create_assignment_evaluation"] = create_assignment_evaluation + # assignment evaluation scores + assignment_evaluation_scores = request.data.get("assignment_evaluation_scores") + if assignment_evaluation_scores: + options["assignment_evaluation_scores"] = assignment_evaluation_scores + create_feedback_responses = ( request.data.get("create_feedback_responses") == "true" ) + if create_feedback_responses: + options["create_feedback_responses"] = create_feedback_responses # edoniq test results edoniq_test_user_points = request.data.get("edoniq_test_user_points") edoniq_test_max_points = request.data.get("edoniq_test_max_points") - - options = {} - if create_assignment_completion: - options["create_assignment_completion"] = create_assignment_completion - if create_assignment_evaluation: - options["create_assignment_evaluation"] = create_assignment_evaluation - if create_feedback_responses: - options["create_feedback_responses"] = create_feedback_responses if bool(edoniq_test_user_points and edoniq_test_max_points): options["create_edoniq_test_results"] = ( int(edoniq_test_user_points), diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index 85986b61..04b510bc 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -252,14 +252,18 @@ def create_test_assignment_submitted_data(assignment, course_session, user): def create_test_assignment_evaluation_data( - assignment, course_session, assignment_user, evaluation_user + assignment, course_session, assignment_user, evaluation_user, input_scores=None ): if assignment and course_session and assignment_user and evaluation_user: subtasks = assignment.get_evaluation_tasks() evaluation_points = 0 for index, evaluation_task in enumerate(subtasks): - evaluation_points += evaluation_task["value"]["max_points"] + task_score = evaluation_task["value"]["max_points"] + if input_scores[index] < len(input_scores): + task_score = input_scores[index] + + evaluation_points += task_score update_assignment_completion( assignment_user=assignment_user, @@ -269,8 +273,8 @@ def create_test_assignment_evaluation_data( completion_data={ evaluation_task["id"]: { "expert_data": { - "points": evaluation_task["value"]["max_points"], - "text": "Gut gemacht!", + "points": task_score, + "text": f"Kriterium {index + 1}: Gut gemacht!", } }, }, diff --git a/server/vbv_lernwelt/templates/admin/index.html b/server/vbv_lernwelt/templates/admin/index.html index a0953118..da2faf49 100644 --- a/server/vbv_lernwelt/templates/admin/index.html +++ b/server/vbv_lernwelt/templates/admin/index.html @@ -55,6 +55,10 @@
+
From 919d3267c7d345811e0189a10aafff5e1f73f537 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 5 Oct 2023 18:04:13 +0200 Subject: [PATCH 09/10] VBV-544: Import edoniq data via "Kursfreigaben ID"/edoniq_course_release_id --- .../course/creators/test_course.py | 4 +- .../result_import/edoniq_sftp_connection.py | 6 ++- .../edoniq_test/result_import/services.py | 39 +++++++++++-------- .../tests/edoniq_pruefung_resultate.csv | 10 ++--- .../edoniq_test/tests/test_result_import.py | 16 ++++---- .../migrations/0008_add_edoniq_sequence_id.py | 3 -- 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index 04b510bc..040e6c58 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -476,10 +476,10 @@ damit du erfolgreich mit deinem Lernpfad (durch-)starten kannst. ), checkbox_text="Hiermit bestätige ich, dass ich die Anweisungen verstanden und die Redlichkeitserklärung akzeptiert habe.", test_url="https://exam.vbv-afa.ch/e-tutor/v4/user/course/pre_course_object?aid=1689096897473,2147466097", - edoniq_course_release_id="1689096897473", + edoniq_course_release_id="1689096523730", edoniq_sequence_id="1688059890497", extended_time_test_url="https://exam2.vbv-afa.ch/e-tutor/v4/user/course/pre_course_object?aid=1689096897473,2147466097", - edoniq_extended_course_release_id="1689096897473", + edoniq_extended_course_release_id="1691157696911", edoniq_extended_sequence_id="1691151920116", ) diff --git a/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py b/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py index d14b69fb..164b75dc 100644 --- a/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py +++ b/server/vbv_lernwelt/edoniq_test/result_import/edoniq_sftp_connection.py @@ -59,7 +59,9 @@ if __name__ == "__main__": csv_data = load_edoniq_test_results_csv_data() csv_reader = csv.reader(StringIO(csv_data), delimiter=";") for i, row in enumerate(csv_reader): - # if len(row) > 4 and row[4] == "AG 2023 A" and row[5] == "de_üK1_BA_KN": + # if len(row) > 4 and row[4] == "AG 2023 A" and row[5] == "de_üK1_KO_Testlauf": # print(row) - if i < 10: + if len(row) > 4 and row[6] == "1691151920116": print(row) + # if i < 10: + # print(row) diff --git a/server/vbv_lernwelt/edoniq_test/result_import/services.py b/server/vbv_lernwelt/edoniq_test/result_import/services.py index 1b6fb45c..1f26d75a 100644 --- a/server/vbv_lernwelt/edoniq_test/result_import/services.py +++ b/server/vbv_lernwelt/edoniq_test/result_import/services.py @@ -14,25 +14,28 @@ from vbv_lernwelt.learnpath.models import LearningContentEdoniqTest logger = structlog.get_logger(__name__) -def get_distinct_sequence_ids(): - distinct_sequence_ids = LearningContentEdoniqTest.objects.values_list( - "edoniq_sequence_id", flat=True +def get_distinct_course_release_ids(): + distinct_course_release_ids = LearningContentEdoniqTest.objects.values_list( + "edoniq_course_release_id", flat=True ).distinct() - distinct_sequence_extended_ids = LearningContentEdoniqTest.objects.values_list( - "edoniq_extended_sequence_id", flat=True - ).distinct() + distinct_course_release_extended_ids = ( + LearningContentEdoniqTest.objects.values_list( + "edoniq_extended_course_release_id", flat=True + ).distinct() + ) # filter out empty values return { seq_id - for seq_id in list(distinct_sequence_ids) + list(distinct_sequence_extended_ids) + for seq_id in list(distinct_course_release_ids) + + list(distinct_course_release_extended_ids) if seq_id } def filter_relevant_rows(csv_data): - sequence_ids = get_distinct_sequence_ids() + release_ids = get_distinct_course_release_ids() csv_reader = csv.reader(StringIO(csv_data), delimiter=";") # read headers @@ -46,7 +49,9 @@ def filter_relevant_rows(csv_data): row = [item.strip() for item in row] records.append(dict(zip(headers, row))) - relevant_rows = [row for row in records if row.get("Sequenz ID") in sequence_ids] + relevant_rows = [ + row for row in records if row.get("Kursfreigaben ID") in release_ids + ] return relevant_rows @@ -57,7 +62,7 @@ class EdoniqCsvTestResult: user_points: float max_points: float passed: bool - edoniq_sequence_id: str + edoniq_course_release_id: str unfinished: bool = False @@ -67,14 +72,14 @@ def create_edoniq_csv_test_result(edoniq_csv_row_dict) -> EdoniqCsvTestResult: max_points = float(edoniq_csv_row_dict["erreichbares Punktetotal absolut"]) passed = edoniq_csv_row_dict["Bestanden-/Nicht-Bestanden Status"] == "Bestanden" unfinished = edoniq_csv_row_dict["Bestanden-/Nicht-Bestanden Status"] == "Begonnen" - edoniq_sequence_id = edoniq_csv_row_dict["Sequenz ID"] + edoniq_course_release_id = edoniq_csv_row_dict["Kursfreigaben ID"] return EdoniqCsvTestResult( user_id=user_id, user_points=user_points, max_points=max_points, passed=passed, - edoniq_sequence_id=edoniq_sequence_id, + edoniq_course_release_id=edoniq_course_release_id, unfinished=unfinished, ) @@ -88,8 +93,10 @@ def upsert_edoniq_test_result( # because the same edoniq test is used in multiple languages, # we have to consider multiple learning contents learning_content_qs = LearningContentEdoniqTest.objects.filter( - Q(edoniq_sequence_id=edoniq_csv_test_result.edoniq_sequence_id) - | Q(edoniq_extended_sequence_id=edoniq_csv_test_result.edoniq_sequence_id) + Q(edoniq_course_release_id=edoniq_csv_test_result.edoniq_course_release_id) + | Q( + edoniq_extended_course_release_id=edoniq_csv_test_result.edoniq_course_release_id + ) ) user_course_session_ids = set( @@ -127,7 +134,7 @@ def upsert_edoniq_test_result( evaluation_passed=edoniq_csv_test_result.passed, evaluation_max_points=edoniq_csv_test_result.max_points, additional_json_data={ - "edoniq_sequence_id": edoniq_csv_test_result.edoniq_sequence_id, + "edoniq_course_release_id": edoniq_csv_test_result.edoniq_course_release_id, }, validate_submission_update=False, ) @@ -138,7 +145,7 @@ def upsert_edoniq_test_result( label="edoniq_import_results", error="user or learning_content not found", user_id=edoniq_csv_test_result.user_id, - sequence_id=edoniq_csv_test_result.edoniq_sequence_id, + edoniq_course_release_id=edoniq_csv_test_result.edoniq_course_release_id, exc_info=True, ) if not fail_silently: diff --git a/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv b/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv index eedc5f9a..8f984e3a 100644 --- a/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv +++ b/server/vbv_lernwelt/edoniq_test/tests/edoniq_pruefung_resultate.csv @@ -1,6 +1,6 @@ -Benutzer Login;Benutzer Name;Benutzer Vorname;Korrespondenzsprache;OE;Sequenztitel;Sequenz ID;letztes Datum der Durchführung des Kandidaten;Zeitstempel Beginn;Bearbeitungsdauer;erreichte Punkte absolut ; erreichbares Punktetotal absolut;erreichte Punkte;Bestehensgrenze prozentual;Bestanden-/Nicht-Bestanden Status;Note;prozentualer Durchschnitt der Versuche dieses Kandidaten;prozentualer Durchschnitt aller Kandidaten +Benutzer Login;Benutzer Name;Benutzer Vorname;Korrespondenzsprache;OE;Sequenztitel;Sequenz ID;letztes Datum der Durchführung des Kandidaten;Zeitstempel Beginn;Bearbeitungsdauer;erreichte Punkte absolut ; erreichbares Punktetotal absolut;erreichte Punkte;Bestehensgrenze prozentual;Bestanden-/Nicht-Bestanden Status;Note;prozentualer Durchschnitt der Versuche dieses Kandidaten;prozentualer Durchschnitt aller Kandidaten;Kursfreigaben ID ; -65c73ad0-6d53-43a9-a4a4-64143f27b03a;Student1;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1688059890497;06.09.2023;06.09.2023 18:48;00:17:10.4650;21.25 ; 29;73.28;60;Bestanden;;73.28;65.91 -19c40d94-15cc-4198-aaad-ef707c4b0900;Student2;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1688059890497;07.09.2023;07.09.2023 19:00;00:17:49.8550;12.23 ; 29;42.16;60;Nicht bestanden;;42.16;65.91 -bcf94dba-53bc-474b-a22d-e4af39aa042b;Student3;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1691151920116;10.09.2023;10.09.2023 10:48;00:18:22.9710;0.00 ; 29;60.76;60;Begonnen;;60.76;65.91 -bcf94dba-53bc-474b-a22d-e4af39aa042b;Student3;Test;de;Test Bern 2022 a;AG 2023 A;de_üK1_KO_Testlauf;1686325621487;10.09.2023;10.09.2023 16:32;00:00:00.0000;0.00 ; 15;0.00;60;Begonnen;;38.11;55.30 \ No newline at end of file +65c73ad0-6d53-43a9-a4a4-64143f27b03a;Student1;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1688059890497;06.09.2023;06.09.2023 18:48;00:17:10.4650;21.25 ; 29;73.28;60;Bestanden;;73.28;65.91;1689096523730 +19c40d94-15cc-4198-aaad-ef707c4b0900;Student2;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1688059890497;07.09.2023;07.09.2023 19:00;00:17:49.8550;12.23 ; 29;42.16;60;Nicht bestanden;;42.16;65.91;1689096523730 +bcf94dba-53bc-474b-a22d-e4af39aa042b;Student3;Test;de;Test Bern 2022 a;de_üK1_BA_KN;1691151920116;10.09.2023;10.09.2023 10:48;00:18:22.9710;0.00 ; 29;60.76;60;Begonnen;;60.76;65.91;1689096523730 +bcf94dba-53bc-474b-a22d-e4af39aa042b;Student3;Test;de;Test Bern 2022 a;AG 2023 A;de_üK1_KO_Testlauf;1686325621487;10.09.2023;10.09.2023 16:32;00:00:00.0000;0.00 ; 15;0.00;60;Begonnen;;38.11;55.30;1689096897473 \ No newline at end of file diff --git a/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py b/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py index 7601eed6..4e3e2324 100644 --- a/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py +++ b/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py @@ -14,8 +14,8 @@ from vbv_lernwelt.edoniq_test.result_import.services import ( create_edoniq_csv_test_result, EdoniqCsvTestResult, filter_relevant_rows, - get_distinct_sequence_ids, upsert_edoniq_test_result, + get_distinct_course_release_ids, ) @@ -24,10 +24,10 @@ class EdoniqResultImportTestCase(TestCase): create_default_users() create_test_course(with_sessions=True) - def test_get_distinct_sequence_ids(self): - sequence_ids = get_distinct_sequence_ids() - self.assertEqual(len(sequence_ids), 2) - self.assertSetEqual(sequence_ids, {"1691151920116", "1688059890497"}) + def test_get_distinct_release_ids(self): + release_ids = get_distinct_course_release_ids() + self.assertEqual(len(release_ids), 2) + self.assertSetEqual(release_ids, {"1689096523730", "1691157696911"}) def test_filter_relevant_rows(self): csv_file_path = os.path.dirname(__file__) + "/edoniq_pruefung_resultate.csv" @@ -64,12 +64,14 @@ class EdoniqResultImportTestCase(TestCase): self.assertEqual(edoniq_test_result_row.user_points, 21.25) self.assertEqual(edoniq_test_result_row.max_points, 29) self.assertEqual(edoniq_test_result_row.passed, True) - self.assertEqual(edoniq_test_result_row.edoniq_sequence_id, "1688059890497") + self.assertEqual( + edoniq_test_result_row.edoniq_course_release_id, "1689096523730" + ) def test_upsert_edoniq_test_results(self): row = EdoniqCsvTestResult( user_id=TEST_STUDENT1_USER_ID, - edoniq_sequence_id="1688059890497", + edoniq_course_release_id="1689096523730", user_points=21.25, max_points=29, passed=True, diff --git a/server/vbv_lernwelt/learnpath/migrations/0008_add_edoniq_sequence_id.py b/server/vbv_lernwelt/learnpath/migrations/0008_add_edoniq_sequence_id.py index f84afd8f..bc99297e 100644 --- a/server/vbv_lernwelt/learnpath/migrations/0008_add_edoniq_sequence_id.py +++ b/server/vbv_lernwelt/learnpath/migrations/0008_add_edoniq_sequence_id.py @@ -5,9 +5,6 @@ from django.db import migrations def update_edoniq_ids(apps, schema_editor): LearningContentEdoniqTest = apps.get_model("learnpath", "LearningContentEdoniqTest") - LearningContentEdoniqTest.objects.filter( - test_url__icontains="1689096523730" - ).update(edoniq_sequence_id="1688059890497") LearningContentEdoniqTest.objects.filter( test_url__icontains="1689096523730" ).update( From a8b4454482a5bd5ca9e79fbcd22c365fc27fc7b5 Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Thu, 5 Oct 2023 18:31:58 +0200 Subject: [PATCH 10/10] Open extended time test url when user has done this --- client/src/gql/gql.ts | 4 ++-- client/src/gql/graphql.ts | 5 +++-- client/src/gql/schema.graphql | 1 + client/src/graphql/queries.ts | 1 + .../blocks/EdoniqTestBlock.vue | 9 ++++++--- client/src/types.ts | 1 + server/vbv_lernwelt/assignment/graphql/types.py | 1 + ...nmentcompletion_edoniq_extended_time_flag.py | 17 +++++++++++++++++ server/vbv_lernwelt/assignment/models.py | 1 + server/vbv_lernwelt/assignment/services.py | 3 ++- .../migrations/0005_auto_20230925_1648.py | 1 + .../edoniq_test/result_import/services.py | 10 ++++++++++ .../edoniq_test/tests/test_result_import.py | 2 +- 13 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 server/vbv_lernwelt/assignment/migrations/0010_assignmentcompletion_edoniq_extended_time_flag.py diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index 68842432..3876841a 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -17,7 +17,7 @@ const documents = { "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n $completionStatus: AssignmentCompletionStatus!\n $completionDataString: String!\n $evaluationPoints: Float\n $initializeCompletion: Boolean\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_points: $evaluationPoints\n initialize_completion: $initializeCompletion\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, "\n fragment CoursePageFields on CoursePageInterface {\n title\n id\n slug\n content_type\n frontend_url\n }\n": types.CoursePageFieldsFragmentDoc, "\n query attendanceCheckQuery($courseSessionId: ID!) {\n course_session_attendance_course(id: $courseSessionId) {\n id\n attendance_user_list {\n user_id\n status\n }\n }\n }\n": types.AttendanceCheckQueryDocument, - "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, "\n query competenceCertificateQuery($courseSlug: String!, $courseSessionId: ID!) {\n competence_certificate_list(course_slug: $courseSlug) {\n ...CoursePageFields\n competence_certificates {\n ...CoursePageFields\n assignments {\n ...CoursePageFields\n assignment_type\n max_points\n completion(course_session_id: $courseSessionId) {\n id\n completion_status\n submitted_at\n evaluation_points\n evaluation_max_points\n evaluation_passed\n }\n learning_content {\n title\n id\n slug\n content_type\n frontend_url\n circle {\n ...CoursePageFields\n }\n }\n }\n }\n }\n }\n": types.CompetenceCertificateQueryDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, @@ -56,7 +56,7 @@ export function graphql(source: "\n query attendanceCheckQuery($courseSessionId /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n completion_data\n }\n }\n"]; +export function graphql(source: "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $learningContentId: ID\n $assignmentUserId: UUID\n ) {\n assignment(id: $assignmentId) {\n assignment_type\n needs_expert_evaluation\n max_points\n content_type\n effort_required\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n id\n intro_text\n performance_objectives\n slug\n tasks\n title\n translation_key\n competence_certificate {\n ...CoursePageFields\n }\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n learning_content_page_id: $learningContentId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_points\n evaluation_max_points\n evaluation_passed\n edoniq_extended_time_flag\n completion_data\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 1506ba90..9725ff3a 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -78,6 +78,7 @@ export type AssignmentCompletionObjectType = { completion_data?: Maybe; completion_status: AssignmentAssignmentCompletionCompletionStatusChoices; created_at: Scalars['DateTime']['output']; + edoniq_extended_time_flag: Scalars['Boolean']['output']; evaluation_max_points?: Maybe; evaluation_passed?: Maybe; evaluation_points?: Maybe; @@ -737,7 +738,7 @@ export type AssignmentCompletionQueryQueryVariables = Exact<{ export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentObjectType', assignment_type: AssignmentAssignmentAssignmentTypeChoices, needs_expert_evaluation: boolean, max_points?: number | null, content_type?: string | null, effort_required: string, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, id?: string | null, intro_text: string, performance_objectives?: any | null, slug?: string | null, tasks?: any | null, title?: string | null, translation_key?: string | null, competence_certificate?: ( { __typename?: 'CompetenceCertificateObjectType' } & { ' $fragmentRefs'?: { 'CoursePageFieldsCompetenceCertificateObjectTypeFragment': CoursePageFieldsCompetenceCertificateObjectTypeFragment } } - ) | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_points?: number | null, evaluation_max_points?: number | null, evaluation_passed?: boolean | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; + ) | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionObjectType', id: any, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_points?: number | null, evaluation_max_points?: number | null, evaluation_passed?: boolean | null, edoniq_extended_time_flag: boolean, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: any } | null, assignment_user: { __typename?: 'UserType', id: any } } | null }; export type CourseQueryQueryVariables = Exact<{ courseId: Scalars['Int']['input']; @@ -807,7 +808,7 @@ export const CoursePageFieldsFragmentDoc = {"kind":"Document","definitions":[{"k export const AttendanceCheckMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AttendanceCheckMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AttendanceUserInputType"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update_course_session_attendance_course_users"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceCourseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"attendance_user_list"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attendanceUserList"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"first_name"}},{"kind":"Field","name":{"kind":"Name","value":"last_name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AssignmentCompletionStatus"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}},{"kind":"Argument","name":{"kind":"Name","value":"initialize_completion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"initializeCompletion"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; export const AttendanceCheckQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"attendanceCheckQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_session_attendance_course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attendance_user_list"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; -export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"needs_expert_evaluation"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"needs_expert_evaluation"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"effort_required"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"intro_text"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}},{"kind":"Field","name":{"kind":"Name","value":"edoniq_extended_time_flag"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const CompetenceCertificateQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"competenceCertificateQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_list"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSlug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificates"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type"}},{"kind":"Field","name":{"kind":"Name","value":"max_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_max_points"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_passed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"learning_content"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}},{"kind":"Field","name":{"kind":"Name","value":"circle"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CoursePageFields"}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CoursePageFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CoursePageInterface"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"frontend_url"}}]}}]} as unknown as DocumentNode; export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenericScalar"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"submitted"},"value":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"submitted"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index ce075601..a36eb1e9 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -304,6 +304,7 @@ type AssignmentCompletionObjectType { evaluation_points: Float evaluation_max_points: Float evaluation_passed: Boolean + edoniq_extended_time_flag: Boolean! assignment_user: UserType! assignment: AssignmentObjectType! completion_status: AssignmentAssignmentCompletionCompletionStatusChoices! diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index 4ecc5998..f9c420ce 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -69,6 +69,7 @@ export const ASSIGNMENT_COMPLETION_QUERY = graphql(` evaluation_points evaluation_max_points evaluation_passed + edoniq_extended_time_flag completion_data } } diff --git a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue index 6904adad..e993c236 100644 --- a/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue +++ b/client/src/pages/learningPath/learningContentPage/blocks/EdoniqTestBlock.vue @@ -11,11 +11,11 @@ import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries"; import { useCurrentCourseSession } from "@/composables"; import { useCourseSessionsStore } from "@/stores/courseSessions"; import dayjs from "dayjs"; +import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue"; import { formatDueDate, getDateString, } from "../../../../components/dueDates/dueDatesUtils"; -import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue"; const { t } = useTranslation(); @@ -59,9 +59,12 @@ const deadlineInPast = computed(() => { }); async function startTest() { - // FIXME: when the user already has a test result, we should check in the result - // if the user finished the extended test or the normal test... log.info("start test", props.content); + + if (assignmentCompletion.value?.edoniq_extended_time_flag) { + extendedTimeTest.value = true; + } + const response = await itPost("/api/core/edoniq-test/redirect/", { learning_content_id: props.content.id, extended_time_test: extendedTimeTest.value, diff --git a/client/src/types.ts b/client/src/types.ts index 5219e900..f115ef1c 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -607,6 +607,7 @@ export interface AssignmentCompletion { completion_status: AssignmentCompletionStatus; evaluation_user: string | null; completion_data: AssignmentCompletionData; + edoniq_extended_time_flag: boolean; evaluation_points: number | null; evaluation_max_points: number | null; evaluation_passed: boolean | null; diff --git a/server/vbv_lernwelt/assignment/graphql/types.py b/server/vbv_lernwelt/assignment/graphql/types.py index 0051cec6..d98e40b0 100644 --- a/server/vbv_lernwelt/assignment/graphql/types.py +++ b/server/vbv_lernwelt/assignment/graphql/types.py @@ -31,6 +31,7 @@ class AssignmentCompletionObjectType(DjangoObjectType): "completion_data", "evaluation_user", "additional_json_data", + "edoniq_extended_time_flag", "evaluation_points", "evaluation_passed", "evaluation_max_points", diff --git a/server/vbv_lernwelt/assignment/migrations/0010_assignmentcompletion_edoniq_extended_time_flag.py b/server/vbv_lernwelt/assignment/migrations/0010_assignmentcompletion_edoniq_extended_time_flag.py new file mode 100644 index 00000000..f20bcdb8 --- /dev/null +++ b/server/vbv_lernwelt/assignment/migrations/0010_assignmentcompletion_edoniq_extended_time_flag.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.20 on 2023-10-05 16:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("assignment", "0009_assignment_needs_evaluation"), + ] + + operations = [ + migrations.AddField( + model_name="assignmentcompletion", + name="edoniq_extended_time_flag", + field=models.BooleanField(default=False), + ), + ] diff --git a/server/vbv_lernwelt/assignment/models.py b/server/vbv_lernwelt/assignment/models.py index 38b7d671..d5ab6d74 100644 --- a/server/vbv_lernwelt/assignment/models.py +++ b/server/vbv_lernwelt/assignment/models.py @@ -325,6 +325,7 @@ class AssignmentCompletion(models.Model): evaluation_points = models.FloatField(null=True, blank=True) evaluation_max_points = models.FloatField(null=True, blank=True) evaluation_passed = models.BooleanField(null=True, blank=True) + edoniq_extended_time_flag = models.BooleanField(default=False) assignment_user = models.ForeignKey(User, on_delete=models.CASCADE) assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE) diff --git a/server/vbv_lernwelt/assignment/services.py b/server/vbv_lernwelt/assignment/services.py index 3eb42260..87d31695 100644 --- a/server/vbv_lernwelt/assignment/services.py +++ b/server/vbv_lernwelt/assignment/services.py @@ -33,6 +33,7 @@ def update_assignment_completion( copy_task_data: bool = False, initialize_completion: bool = False, additional_json_data: dict | None = None, + edoniq_extended_time_flag: bool = False, validate_submission_update: bool = True, ) -> tuple[AssignmentCompletion, bool]: """ @@ -146,7 +147,6 @@ def update_assignment_completion( if evaluation_passed is None: if evaluation_points is not None and ac.evaluation_max_points is not None: # if more or equal than 60% of the points are reached, the assignment is passed - # TODO: check with VBV if this is correct ac.evaluation_passed = (evaluation_points / ac.evaluation_max_points) >= 0.6 else: ac.evaluation_passed = evaluation_passed @@ -176,6 +176,7 @@ def update_assignment_completion( ) ac.completion_status = completion_status.value + ac.edoniq_extended_time_flag = edoniq_extended_time_flag ac.additional_json_data = ac.additional_json_data | additional_json_data # TODO: make more validation of the provided input -> maybe with graphql diff --git a/server/vbv_lernwelt/duedate/migrations/0005_auto_20230925_1648.py b/server/vbv_lernwelt/duedate/migrations/0005_auto_20230925_1648.py index a7df7df6..1f3192a8 100644 --- a/server/vbv_lernwelt/duedate/migrations/0005_auto_20230925_1648.py +++ b/server/vbv_lernwelt/duedate/migrations/0005_auto_20230925_1648.py @@ -44,6 +44,7 @@ def reverse_func(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ ("duedate", "0004_alter_duedate_start"), + ("learnpath", "0008_add_edoniq_sequence_id"), ] operations = [ diff --git a/server/vbv_lernwelt/edoniq_test/result_import/services.py b/server/vbv_lernwelt/edoniq_test/result_import/services.py index 1f26d75a..5d0a120b 100644 --- a/server/vbv_lernwelt/edoniq_test/result_import/services.py +++ b/server/vbv_lernwelt/edoniq_test/result_import/services.py @@ -108,6 +108,8 @@ def upsert_edoniq_test_result( ).values_list("course_session__id", flat=True) ) + learning_content = learning_content_qs.first() + for course_session_id in user_course_session_ids: course_session = CourseSession.objects.get(id=course_session_id) @@ -122,6 +124,13 @@ def upsert_edoniq_test_result( if edoniq_csv_test_result.unfinished: completion_status = AssignmentCompletionStatus.SUBMITTED + edoniq_extended_time_flag = False + if ( + learning_content.edoniq_extended_course_release_id + == edoniq_csv_test_result.edoniq_course_release_id + ): + edoniq_extended_time_flag = True + return update_assignment_completion( assignment_user=u, assignment=assignment, @@ -136,6 +145,7 @@ def upsert_edoniq_test_result( additional_json_data={ "edoniq_course_release_id": edoniq_csv_test_result.edoniq_course_release_id, }, + edoniq_extended_time_flag=edoniq_extended_time_flag, validate_submission_update=False, ) diff --git a/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py b/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py index 4e3e2324..5dcd6e1f 100644 --- a/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py +++ b/server/vbv_lernwelt/edoniq_test/tests/test_result_import.py @@ -14,8 +14,8 @@ from vbv_lernwelt.edoniq_test.result_import.services import ( create_edoniq_csv_test_result, EdoniqCsvTestResult, filter_relevant_rows, - upsert_edoniq_test_result, get_distinct_course_release_ids, + upsert_edoniq_test_result, )