From 43d52a360cdc9d9b554b81d1ec476832bade70f4 Mon Sep 17 00:00:00 2001 From: Salim Elliye Date: Sat, 5 Apr 2025 20:21:34 +0300 Subject: [PATCH] ll --- osinaweb/db.sqlite3 | Bin 2142208 -> 2142208 bytes .../__pycache__/admin.cpython-313.pyc | Bin 3534 -> 3421 bytes .../__pycache__/models.cpython-313.pyc | Bin 31858 -> 32065 bytes .../__pycache__/urls.cpython-313.pyc | Bin 6146 -> 6276 bytes .../__pycache__/views.cpython-313.pyc | Bin 36351 -> 36857 bytes .../add/__pycache__/urls.cpython-313.pyc | Bin 3825 -> 4077 bytes .../add/__pycache__/views.cpython-313.pyc | Bin 34756 -> 36398 bytes osinaweb/osinacore/add/urls.py | 2 + osinaweb/osinacore/add/views.py | 79 +++++--- osinaweb/osinacore/admin.py | 12 +- .../edit/__pycache__/urls.cpython-313.pyc | Bin 3134 -> 3254 bytes .../edit/__pycache__/views.cpython-313.pyc | Bin 28555 -> 29722 bytes osinaweb/osinacore/edit/urls.py | 1 + osinaweb/osinacore/edit/views.py | 20 +- .../0110_projectrequirement_milestone.py | 19 ++ ...e_projectrequirement_userstory_and_more.py | 24 +++ .../0112_rename_title_milestone_name.py | 18 ++ ...userstory_completed_userstory_confirmed.py | 23 +++ .../migrations/0114_alter_project_end_date.py | 18 ++ .../0115_projectstatus_default_created.py | 18 ++ ...16_remove_projectstatus_default_created.py | 17 ++ ...ojectrequirement_milestone.cpython-313.pyc | Bin 0 -> 1055 bytes ...irement_userstory_and_more.cpython-313.pyc | Bin 0 -> 1059 bytes ...ename_title_milestone_name.cpython-313.pyc | Bin 0 -> 780 bytes ...pleted_userstory_confirmed.cpython-313.pyc | Bin 0 -> 959 bytes ...114_alter_project_end_date.cpython-313.pyc | Bin 0 -> 849 bytes ...jectstatus_default_created.cpython-313.pyc | Bin 0 -> 844 bytes ...jectstatus_default_created.cpython-313.pyc | Bin 0 -> 762 bytes osinaweb/osinacore/models.py | 34 ++-- .../templates/add_templates/add-epic.html | 9 +- .../add_templates/add-milestone.html | 45 +++++ .../templates/add_templates/add-project.html | 33 +--- .../add_templates/add-userstory-modal.html | 27 ++- .../details_templates/milestone-details.html | 180 ++++++++++++++++++ .../details_templates/project-details.html | 57 +++++- .../edit_templates/edit-userstory-modal.html | 57 ++++++ osinaweb/osinacore/urls.py | 3 +- osinaweb/osinacore/views.py | 14 +- osinaweb/static/js/pop-modals.js | 2 +- osinaweb/static/js/projects/add-project.js | 18 -- 40 files changed, 612 insertions(+), 118 deletions(-) create mode 100644 osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py create mode 100644 osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py create mode 100644 osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py create mode 100644 osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py create mode 100644 osinaweb/osinacore/migrations/0114_alter_project_end_date.py create mode 100644 osinaweb/osinacore/migrations/0115_projectstatus_default_created.py create mode 100644 osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py create mode 100644 osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0111_rename_projectrequirement_userstory_and_more.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0113_userstory_completed_userstory_confirmed.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0114_alter_project_end_date.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0115_projectstatus_default_created.cpython-313.pyc create mode 100644 osinaweb/osinacore/migrations/__pycache__/0116_remove_projectstatus_default_created.cpython-313.pyc create mode 100644 osinaweb/osinacore/templates/add_templates/add-milestone.html create mode 100644 osinaweb/osinacore/templates/details_templates/milestone-details.html create mode 100644 osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html delete mode 100644 osinaweb/static/js/projects/add-project.js diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 9e949f452016b0eeecccb27c7c593a890766a396..63641231665df7293994df102d3cfbcd9aed2b6b 100644 GIT binary patch delta 8626 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 delta 12857 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 JWYW26{{Rp|b=Cj? diff --git a/osinaweb/osinacore/__pycache__/models.cpython-313.pyc b/osinaweb/osinacore/__pycache__/models.cpython-313.pyc index 593d04e99c604a3fcae88a00ba10f6e97c26557a..c4e68049272ecc15abe88ea7aa39bfd1fcce2b2f 100644 GIT binary patch delta 1945 zcmYLJdrXs86z};$TWHHl1%VcM6qr~+q$E@75P6g;Aa4`}p&+eLDJ|X>6xarCPG!rY zayFfDD4LDwA7;33@evnvn}3*Pae_e@*%D{m!#y$|kT{pP-SeRil3&l`ch0%@ob%lW zkKl{P5d1JWSS90s;f42`KR*+koC=?yCG{xBsnjQM7AKeXzy+*KGjn+;Aq=&FN^vM{ z7y>H;_`lpDU`hHe7{wdu6Y#azYPbyOdg(*>MtoseAHamTZ~1WnCPnj#-2(h7p3iiH zVw9Kj&En#$lggp0k+3oCGI1hH2XG&MS#^!$+3Z>2i40HYIOr!dcb)i`H3$p=Ad}ra z$YWU;2a|A0m<}jycY0VH&a*kdghP2T@tXX0S5vCp?(;LdUCSeU8cyz$O=&~-b@z8) z57gtwwiHbw_pn~d)yFGXO#`bFRMBK32*4$)_u_=rfGxSdDZ|Jd1Ng(zMjXwX7i1tk zmWSd`c_|t_<)AujA>gf=2+XuDN?b%b0mb?@a>{Pmlv+2bjv7}-4f)2@$$eJbYqbUH zSscYL!m?t$U!=E)b3Cj!OAOdv_2IEfY7L@BEB?)SC zxt%`0*W+Xh$&&{7enDIkPwsFy9rn##?3hGr@_M$oSew%^9n|D)Yj->SP6vy|dpVIQ zDU^(W4(mI>>AZy@;gcc8@et#XX{7U9@0s4KRbwF)eFZpMP>~`z6UIXlPFlx8%zXv_ z>-l3L>3s#W0>~H4wL68{jqbudie##?1ph8{sg{#Skc{r46|h|5TrN5RW^7tp#`VwE z+Ef-I5tuQcxCks_SuubjgRD!ix}-*!TLPt?ELni}b0SpPBok!dgOaU6HsEnpB;Tw; zyj*$&vT;+{F|Cz21jO?>v9Do1#+GlSmEdG?pgc=}H8@roodB*>*^$BU|}n*tQ$kLzECGK{Y7g&J|N`c(n8VpPpxbpQa1JU@X zCZSOBNRyE}clcT3v%Tj0B+7h~V3J^j-~oX&r@5hb@CD;TXI-oqn`_OAHN1vTjYn(0 zHRvKHb@Ai6_#w-A#U-0XUNaRE;h* delta 1825 zcmZWpeN0nV6z_RJf!bP;&vuoyf=HdAz_fxviqgXPE}#KLsFgmtLTTZ(6@@vO+Z2~6 zn-WSW^wbT0d2#DQjlOylMs%h!MG*-PH z@1Cpk@aPGsW>qSMj6Fs96K?s4>ZL3g!ThY_45zZ5!6lqD^}%JV&(2};$+QGi$3%-K zv(Et*WyIjw`X$(r>xNOhmHQ2hi5=QeK+ozka6?>Z?gy9@2iKh9;EtHHb{_{niI)nz zARlGB1s>vx!r_QpYJ+&EFb-fAf41CU_-WB&P6jx#-bJ6}4V$pcUM_9*iET(84Kmrx z5xi?EjXe+3Q9)18%j3zC%tRG4%qm&je%X{dez5mI?|6&`CrVaw20*XXi2BmZ^d*cW z5Kx%FX2#wpn^G>GRO)Ujb;A)8%9Z^#^p=)jvCSZQH^hQAjyzHc5*XXao#&<_Yr1%! zkcorEE>6(nh)0v8v~_t}vmA~3;eu#WEzc?7eU_yjP-+%w^G7>WQqKQ7M^JQ6$0Ta7dSncR9B2!sAwLLKf{y zKv_KRH4c~8sUC9>r4#hzmK848Qn6odB)SR5Dm)4^i3CQpRIcUBVG>rJ1{0dA>|nT>S8hx6tXwKV~sNrAJuN=ikYV(Mda%WxwR$CG&4`>|EH@F!g8iQ&&?|u{6dGv z=hoNwgmR`5q{223eT8^$<86+sWU*E!<5)u))ZiZtd!SM5YTV7itN7cNqw-qvslmUQaYD$Az{JkmBOoa%`DavhvNrDRmj|ik*OJ}e^`1kx-n7pkya>_TLLjTsUb@7_X z`1G6c>Ep}RjGDi+T(yjEZXV}76Y=f+71-GPYw1qL-6&WY8Y7L|ysFwC)EE0ZyS#jm zcM01mi83;B({j5r6kxhm(j^guYb5C+cIq|a*%lSRCKMf=(13<*sjwG|wp{_+VdrwL zA$$@}ViWAda%U6g44>f@=L0w-p5A^K7PJwenM&+Hi^~QmzU^{AvZQvCt%=!;QNjyE zapPb7F8B~bZ5_~t-?ydbOY!^2)<|UOC+H-}$6#7z4GGSm$L}lg@Lrc71#Ka6H(*QZ z5=93w2@WCeZifzW++6^0234M=(L0!$H44q1Ua+wlkjZ__#*9{j_ZG#9Pd!N-xG}+7 z4Hv{#ubcxrw)^b1KEf;VaT7KXZV zVT}2EmHS9xV5Vwg3a+;%;Hqv7%b~hEdzlnTsCcufbRI3Gt1DensbA9hO2;JCLpe*y3CHkh?^5^(^?jegR=nT0DQ96c xXy226pnP9B$ELq_E{8sp>yaP1I|pc6X*tm8L80NbmD|-sc_7 z?0!7*$!PoUPN&0SJl`gsZ7z2z?Otn7>(}9`&2P&UP5s3upUt-=&cRb#$#(9dCBFje zHV%p{Uoac+rxxE}(Q1gLqAj=aVw+jz%Vukq*^L+D#ny|EY32Hh_T2XWIOT*j>aYWUap7P2tImGLku~cG z*lVh+4`tC%R$JaiUJl!+RRM^3V4;$Ta-prQ6HQ}gT}=a5m>`- zQd*=mP-pet80w8R0tj5iYZSg^K%X&|BqvcQ`MuGa!|Rm34Ig;ew%fFL2Y%}D?3ZY9 zmxdZ&($mUGrEwjB48BKE%|r(th12+Gvva6v+{GRx?-9Z&Ajt delta 1163 zcmZY8O-vg{6aZkaGd3}iO=5e!w%3jWwXx&G2JG;cPzMTR4Jmv-I z_I%y#`rGMjwV2QFAgsSXtGfKwf9yXdwr#dk9hSM7AM6tT*;bNmvn85z@|l~TJ3V*` zr|oZqHTQv-9|O=RK>?cRYOdC*j!c4hgN(<^+QIZfEdiPdK9pZPq`~Y26{$ z3P!je!u^d+K(~mE!e6Zxo8y&FmGnTWc`n^VUF3{{zx2ofrY@@fN^f;Y9jb4Dsci~= z>yi4Hx=qy`(R$hF9D~j={bm`^ed1x}WfrUN9_}6NH6{TmL{#uQk6dQ#XM9O37^x9R zjp+G1fQp0{Jx_~XhaHlp*ab9;I>jtHSri?~1ki zfMO)3;Fn%`ooRwqx~!Fr^bDkD^v@mvdQ2`dOaHG@7mIh(c(78aE~<-K08p0nuy}^X z!!?`XPk=w6y#zEwvI>6hm1O39)a6Rq@WsIw*B(>vS8%r|@jtstoi1li&1tQ4-fIe8 z76bikbdKuznrH-)5J(<{0bM88nG6e*BDI(iOhGVpbPLcZ84(nGB+6#{n;0_NKSh~; zMV@6#l~^^YChL8Gl4Qd4h%aomAG3DB7usht&(mDp@vn_20$Lz<1g1r7&}}X|Oe8g~2fLc??k4IXyIh_z38;!5$~L`Mny8mN=khr( z6nw4d(a~l|8Ec|(@&&hHD_e?>>V?ClgQdnbdSpkeY#lz~lszgKy|GiK~g|aU8Y!tIiJ3XY@g=Fb1v!Z& zsm1zm)w)nQy^NCF98LBjR-oovoW5|wA{i&!<;&Icz%|5YrXY+iDgr7m2I)}%fg&A{ zZUMMjsM$riKvzs)0;&uI$~Q1P5l~#Bxq;`RfNg{49X=F)Zjc1~)A~A}%SAqy1EH7s zyc^sfh|0>{5Rv}K%EHgq;Qob&fk$Y9`UPp%1Lc>w{V%ZiPc{gW-YlEFl99U*`)ueHUTJ5G;#9MT2;0wKqd$C<_oo9?2OYUtGC9oP6vvp zZSHK%Vq%Qk{H1*klQAf$ionhWxwQ!7sv?j}ia>5C0$E(t4I)7H6oCvZnm&17mlW3; qAQOlfinTXC>YBnN`5}jqfl2Hm6DMN;<7Z|d^8=XqNosOsZyNwZ*4=sl delta 474 zcmex4pXvW>Cce+Syj%=G;9z+%-70G$p9EvvM)l`R!og-z3`Kr1X2IrC45lCj3=ESM znVr>w8G>!RrM*ImLKGN+ZGmb+gYAH1Sg>QTgA_v+V^Mgzy{6OVS`B|yS zB|)i$rI|&kxv6<2oByS$GASrr=hL{zr*WN6|019M4)zOt`WN^duJd_bsaJIXC~wS;?r8!^pr;lnWyAfJ8AX&@BoeP^1H76@g_z#H7t<^JExV%Yn?< zli%fkVXU0|xFC_O5~Q(evR9!pYYmXOdUH|XQ%1(R$q~f{to1;Fott}$&oHt!1DU5L z$Cd76ESoG*roq|@?~>n5g;pyKxP$zw6A0+(gS%F!`uyP=abu>>?TI>QgxxVIB+3dVg)Nwz>EWjmNrv)e2WKi!w8F-Emecb~CNv&C+O@sr0qgzq7U7 zZ126;ZLo+ljmBl?bLFy(%Sh{Ga;Cl4n!aq-w;H+Rx$o+d{dTjZM|WN{HnxAv znv+z%iszQ~kv^F;_{bTuWASe%eZpFyn*0bl$y;hj@+P?Ld zWt+&m-8LBv!bAvpX9&DAI7Cm3o!LCT*iGX_kHKttSEs1D$j6E>R@AENKsUr7l24~mb%Mw85X+w(>;hd8 zex!g-$rBeJufVu`;3q&g#Sqf%>#MZlQ=n^N7%432m8TPWlQ>KqzXUoi?qNHkuLvGb ze4qO+r%jfDJ`$q{Q5`a;=AZ39*|q9H9q77;KaA2N9w;?t`zy{c`< nuk{@T_m%D=+@H|}xU delta 1043 zcmZwF%}*0S6aerJogyuvSm^ePLWQN}qtY+ig%;Wh6pIoNMKmEqM5qXgn2HAzm3ZTz zNpVcX8=mYD^8?#b<#LVW=Wf2$~kL1>tRobOuVc@^2GbNDo>8E(JGm= zvFqaQVI`3Xu+JjyWIw88Hf*%pLI*~K#fYOUXOu~ZT^08TduWu|M^U95sOl9}arViW zCvoPbdD6!gsoa{vJ^s6OFTb72qa*Wd_ued2hiI4d#m)x%T#l^Xs#kG~f!us55 zVfAvMIJdgCIDefzvN+ir%dZBX82813W$Vie*9z;!cJ`t6*~W-S6LH;284U(*B!ui4 zynBX5Ufoq+^_A9ax=SOPy&LS^YIG3j5I2eZezn15-fSurG)E^mI?MNfruiX+n*V?q z!Gho_C7x!tvSl~WW4spAiNl!pl%_Q)08*el3pB-TC=CKsbFe(E^^8H!n0j^@=n8K{ zva>UFQon?uL$B&8C$wM|g4uUBfKGEKic6R9uB1iBAS(K=0A1p4BoBLDCoMN&*oKdH zmi$jcTcMphK%-p7bi3Z%x|4X3d7e@GMuDE>euRJyO2zcn`r4|F&jG!}I}kc`@a;%i zs{*Y`MaVesLg{8ctF#fs@aVy@6*GR$9?XYC9(SQN1fU^Mz6f-HhY=zOE!&dj4ud(@Hy}*Zc%pu}|(HdoFl*>V&3Lnww#Gk&t wieF33Kx#&v7w7Lj&+9nKcIzD-C-rzjpP|215In)%5YRz>8tFl8aabJs->vmKM*si- diff --git a/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc b/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc index dde20c366c37471180ab179f60f4864490e79303..b534df1132f40c4dad4d71d5b838e074a71182cd 100644 GIT binary patch delta 4337 zcmZ`+3viUx75?wO|J^)xlij@E$tG;blRz*K5|apl5DDdHMTsFPDy}e)Fg*>1tx4QNnL;$IQS_eaDhASjU;N99CPVq-IIm*%Gqh$Mf$_ zSFBl5yj`H!vLs%J+A<}LJYkqsrf1Icu%m5(k|k`eAwZbwY5n3u4q zTp~G{Q{_}EmMXP3xqD&E!zn2#&Sdyy>EWVL(;9EVdhQ$G9>3qA<}`RjKg@mGJ$(Ug z!WP_B*2&V~$+9g=648Mb)dM4r9psC1`HW0FC35>bhmmH=b#ns%s0?wO#0#s_P2Xbsb%L zyzyA$RBCZ3wfIEG+o{!)&b!79pXsF3EYOvAlz(WjO&M}ShTJJbNytzVwiSiba<8Oj zQ!i+m)=RQ|M$*W}&x~-qyv1n1X(`&P&q85sllmmCbnB{xu(id6e}9py>!!tvkG9aM zacZ49Mc<(H>YaL+(OcofTGLo^%ttXeRU6E)*4*D}rpOH{uc13NrgIwRjz=*%RW-~j zciZAtNijL)B@`HbC6Xgy-ANWP&K^k5pqtYqd=)~(*M zZt~&d1aZ@Kv)dDJ4GwwSm9rzBWW11EsK;o5%kAz7cyD{!Ips*wp`^DB8IaUbnD@THa&+mmT9vHZ-;P<9kaDza zGJD0j?_M^wPioqOua^?4ElHIV8gyRSDR0Om<{CrR$`-3fP!eNh;Wavq$Xx18SaM1dGMA}4H|B-R zmFzUlD-ZKJeh`hk1_5(fY&nG~@-m|D^LYavZy+M~`7ou59yh-q zeI2@JzlW(GDflAGyCY;N#!pL=w^BF_1(F;YbiA6G@2AMkFv-KqB5p$s5Bjogcau z>lVj+kZgi_6HpR`14>P?>jbtIBJ27W3+nwyZ@H3EJkfs67)ogy*N3echvau<+ZC&Q zV(@fl$l5Y4hf}hrQi?+<#pC)bmaHjDQOHs>WpRWoj?-n67RRJz*_5R%WNEvw^0K94 ze+L|^DHsdq6hGeiNas{eMJT7@sqU$qhEPt!vD?m#;BYrLy_=kI#g;c^D-GF7r)=dR zTlrH1r-n`rO;t68s+!L2xm>k&(pElc>m1L#V$P&`#$RSpIHQn$ww&X4AG>=dQExHU zj%%r|la3e<8ShWHlA0e*XuPUs)~0d8`^o9!$?vCTg>8A^w1OGER@8Y?@LJ7_EJfs0 zoM{~@J_?r>)v!^xwx|j#y`;`n6hDGUN{pTRkpO#KL%kzA`2_ARgj& zT(7UxK7;mwV8zm5txm*z93~n|%wmu@>tp|LV{wNV?=+2fir@yHGpLKmBbbUJZAKI0 zH$}kZ-@$)GT@E48?E>poWMYZ3_FuKByp`KV_Wskwx6}JwF zfQh)HDQ%m(1tLlF`cYkl;B2@sJSLSqU}&PxukNXLzuW`kw|@la-x;?=*F2 zUqbIa@JiEqL*~QY88yqU3g$MqGgVq)u>aO)7&`~n))ICe8d`G@?`W-N&%?pidfhpi z@kygY8dCyv!o)>1*u9NfbV%lKV)! z0NiVq!|$3G1V3K$Uxuak@!DIWPtw`)D(|GKzN@p%9It9F4*6~Pb!Ve4jDsbpf}eK2 zr(^HHn@Ya<9~AV51b-v=1in&MvJaqbW4HEmR4fesYU5*Sybu41dW)dH zMhUiVw!+aZnbF?x#+Cx?`|m9+S~d3F7p(jCF~E&9`O|+L7w;J)rxqzmdZuz>39<-s5H|8W67!*8cSajg*eVB$X#B2zk0UY45KR=L1k3hq)q2o(b@1_hMe4QUa5T}q7R3}l0ZtDChbod780_2O!N>Qo8~;bZ zD^MHLMXv`xuR86dGF3+=&>(iA3bt;gF`q0S}OC8v%{XZ-cW3 zs_rw24YK|t3krwfq3L_k!{iAy;ZKc}MQ zRE(U;kW)EvstZoFz^Mv2B|N8m=5(-}wvp5R@E!22`?8F?QN*9*-vT4|9d}l-RqU!- zQl(9+NSt;vlxI}wY;{ac;`CynO<_t*OX73|YOksa*}9mP#Oc)xIu7<*vRGS8P2%*j J;KhR~_CJE3GC}|V delta 3235 zcmZuzdr*|u760zXe!I)^+6T)buZ4vL7DX1L5D-*EKvWjXh9(j1y0VKb^769y3P?q! z0TZimOr5csN5^R}iCX7trY3DO>D1;`JIdHryR`|O@Q0mA4QQKbO~>|}Z+RG}-|YP6 z+;h%7_uTWkd*QTr<(L?IKPE;e;J2n^V&|7_qp^vs=u%D!%QqznD~OLDx4Pq#1fIUt z;?8!PlY}-lFUde&LXrSMmT$>%FZzbej2l6WJ}$dXtBVZh3G^*`y;0n z?u>Ng%6r5sR&h`Tde1h9i(3i5w>`(s%9}IqFzBFvcr*V ztHIcmGrvJ_8yk)AZuSdHLebp6yEnl79sbT>&$)<@rn###h;&HP&AZzC&B2h?>+|`2 zo*nyPXU--T4?oS><}_{&3mXiLCrdGLBNH-fBPr%0&&7H1i3W?Cc_W=sW!$TSt^ z$uOojS4mldTiqx+S*N;*BC33if?Lz5UO{oiFH3M}UFR4-jx^U3^btHqkU-E6b*&co z)e1Az)oPLkiDe;BbQ6ghA~4aFGBn{lDaMq$kg<@|6YS#q`6$w`+G~N~q6FO!a1qBa z0fTU$XTD=lu&A z=Yro7X!m=(?K^rq_$fG8>X2Tc&GK8N&x*D47DKv#56d~w67X}r6cs{IK7UU$4|E3u zU7ZezzeZ=1fd7c#hXhI-W<&YqHVbSkPenJLE8nONy8&0r^QE(>xki3i-YseAGzUYk zgOyo&#mo*e)2!Hn@yg5r#p3I<{xQL0I^)C}K{ycO^9Q|nFJFGp+p`OkoPpd2`g!i` z-O+Ed7&7_01I<02t`<+ne$T8-sl$+VcGaWUh1zxYghAS&s=^&S1xemYFa$&E*0d|v zqH!7SUGqXsgkm3Q%lUdIU-_E^ZxJX>PO0Nr1pnuXAq{y-`(FoVRXiJqs;Ujr+o=5% zoT%EYwY_=}`!cy${-UaeiHVu=ikkC`U4+lqXE7PHwJB;DbsyN^(smP+*IL*GXsj(# zU!>z?7_BXm-beC`e6{urGyjaZN;w&bx=ip69Nf6Pl#KA7BRC?tMDzuM$C~38#Iq9M zm<>mSzXxAz%+_7OwM-q*4->WZuxryMu}qwA?Yr38yP>tN6@F8ZC}~Q>P7x;R7Q>r* z9bB(l0!OoSpmrrP9avojEDGvfi&!)ST*(9BhSxQj(Z2Fw!^br09%=Yk7hfo8DHsU0 z`@^wTDoLp>C+_6)b>~p?4~U^8M3FyMb8nFJ9KwNQc<9O;pz3%$66cAhL?V(XrAkyp zDHA?wp-RFXvvA;JXHntPOXI_bra9>8xMG*bv*lTOfGkSre?o`)Gb#1Uy#FZ6a0Z- z3N~%2Vt<0MEltv0WN77kTh2u2?ju<&qR&sm-&^hSd*Atl8Sjxk<>Q>lmA1GCr?#(U zGcfH;RVxGd(3sc3zJfe&rSvbb2x)1CZ}tXTapv1V-qVH$rR`mg zd2;Wqz)QchcXvh(ZBYu&5-vD5*;8_;9N!N)`<{Lxm$V!Nc?cn6Pj7d37Y}-T{%$W1 z(!U#?O42j}#Q~fp`wCeWe7>(%Do3s?7w%sq+3AJjdIAH1iNHt@kMI;vAkqR|2NNr4 z^i?}pNY&$Q@jGI|17#ICx0sX`X6zDL<`XO>C?FUlz3;;(2W{pRv@RkjCJ5gI*uYw8 z9j=Y?`hf}+I|WA$53m~04Rz^H;oflQT;2{puZNML?b0^Xwaa&hY!Mrk2KzBM)=ZH2efBgk!^{tCkZ(>HdX`%>EyW zoHd8zT}iNqR96y^WnP8=^@WLG9WhDGxL6IvBcHNmkZ|Nf=7LX;JTpLl?)Vr1{mbC= zlJm0!^hEIY39b;(gy7VwoLZ1m^Koh*P7T4S2{@HMr;_JX(VSAtDUh5Z#Oe5R0fX*3spQ>uvY1;@v32pU_hSAHQ&NRRODJ_ag)`VOk_|+Q*Qd5sl0}$0l+*PvIso d*BqC~>1FWti!H`9RyoHda(XS3mmC$@{{Zl_L)riU diff --git a/osinaweb/osinacore/add/urls.py b/osinaweb/osinacore/add/urls.py index 079d3850..26388d3d 100644 --- a/osinaweb/osinacore/add/urls.py +++ b/osinaweb/osinacore/add/urls.py @@ -11,6 +11,8 @@ urlpatterns = [ path('project/', views.add_project, name='addproject'), + path('milestone//', views.add_milestone, name='addmilestone'), + path('milestone-story//', views.add_user_story_modal, name='addmilestoneuserstorymodal'), path('project-member//', views.add_project_member_modal, name='addprojectmembermodal'), path('project-story//', views.add_user_story_modal, name='adduserstorymodal'), path('project-file//', views.add_file_modal, name='addfilemodal'), diff --git a/osinaweb/osinacore/add/views.py b/osinaweb/osinacore/add/views.py index 39017f9a..d8617627 100644 --- a/osinaweb/osinacore/add/views.py +++ b/osinaweb/osinacore/add/views.py @@ -213,7 +213,8 @@ def add_project(request): details = request.POST.get('details') membersids = request.POST.getlist('members') start_date = request.POST.get('start_date') - end_date = request.POST.get('end_date') + end_date = request.POST.get('end_date') if request.POST.get('end_date') else None + project = Project( name=name, @@ -228,13 +229,11 @@ def add_project(request): project.project_type.set(project_type) project.members.set(membersids) - requirements = request.POST.getlist('requirements') - for requirement_content in requirements: - if requirement_content: - requirement = ProjectRequirement( - content=requirement_content, project=project, added_by=request.user) - requirement.save() - + ProjectStatus.objects.create( + status = "In Progress", + project = project, + date = datetime.now() + ) return redirect('my-projects') context = { @@ -246,6 +245,34 @@ def add_project(request): return render(request, 'add_templates/add-project.html', context) + +@staff_login_required +def add_milestone(request, project_id): + project = get_object_or_404(Project, project_id=project_id) + if request.method == 'POST': + name = request.POST.get('name') + description = request.POST.get('description') + start_date = request.POST.get('start_date') + end_date = request.POST.get('end_date') + + milestone = Milestone( + project=project, + name=name, + description=description, + start_date=start_date, + end_date=end_date + ) + + milestone.save() + + redirect_url = reverse('detailed-project', args=[project.project_id]) + return redirect(redirect_url) + context = { + 'project': project, + } + return render(request, 'add_templates/add-milestone.html', context) + + @staff_login_required def add_project_member_modal(request, project_id): project = get_object_or_404(Project, id=project_id) @@ -268,26 +295,38 @@ def add_project_member_modal(request, project_id): return render(request, 'add_templates/add-project-member-modal.html', context) + @staff_login_required -def add_user_story_modal(request, project_id): - project = get_object_or_404(Project, project_id=project_id) +def add_user_story_modal(request, milestone_id=None, project_id=None): + if project_id: + project = get_object_or_404(Project, project_id=project_id) + milestone = None + elif milestone_id: + milestone = get_object_or_404(Milestone, id=milestone_id) + project = milestone.project + milestones = Milestone.objects.filter(project=project).order_by('-id') if request.method == 'POST': content = request.POST.get('content') - - story = ProjectRequirement( - content=content, + completed = True if request.POST.get('completed') else False + confirmed = True if request.POST.get('confirmed') else False + if not milestone: + milestone = Milestone.objects.get(id=request.POST.get('milestone')) + story = UserStory( project=project, + content=content, + milestone = milestone, + completed = completed, + confirmed = confirmed, added_by=request.user, ) story.save() - # Reload the parent page using JavaScript response = HttpResponse( '') return response - context = { - 'project': project, + 'milestone': milestone, + 'milestones': milestones } @@ -350,7 +389,7 @@ def add_task(request, project_id=None, requirement_id=None): epics_of_my_project = Epic.objects.filter(project=project) if requirement_id: requirement = get_object_or_404( - ProjectRequirement, id=requirement_id) + UserStory, id=requirement_id) # Case where user wants to add task from tasks page(No project specified) else: @@ -386,7 +425,7 @@ def add_task(request, project_id=None, requirement_id=None): start_date=start_date, end_date=end_date, assigned_to=assigned_to, - requirement=requirement, + userstory=requirement, ) @@ -459,10 +498,6 @@ def add_epic(request, project_id): title = request.POST.get('title') status = request.POST.get('status') description = request.POST.get('description') - - project_id = request.POST.get('project') - project = get_object_or_404(Project, id=project_id) - start_date = request.POST.get('start_date') end_date = request.POST.get('end_date') diff --git a/osinaweb/osinacore/admin.py b/osinaweb/osinacore/admin.py index ffcbd2ab..8bff995b 100644 --- a/osinaweb/osinacore/admin.py +++ b/osinaweb/osinacore/admin.py @@ -3,20 +3,12 @@ from .models import * # Register your models here. - -class RequirementInline(admin.TabularInline): - model = ProjectRequirement - extra = 1 - - - - class CredentialInline(admin.TabularInline): model = ProjectCredential extra = 1 class ProjectAdmin(admin.ModelAdmin): - inlines=[RequirementInline, CredentialInline] + inlines=[CredentialInline] @@ -34,6 +26,8 @@ admin.site.register(Department) admin.site.register(StaffProfile) admin.site.register(ProjectType) admin.site.register(Project, ProjectAdmin) +admin.site.register(Milestone) +admin.site.register(UserStory) admin.site.register(ProjectStatus) admin.site.register(PinnedProject) admin.site.register(Epic) diff --git a/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc b/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc index b2ada5edc9db5e4df42a845c3fc71cd006d3e497..024800ed5924243ba0e91392206f45984929a10b 100644 GIT binary patch delta 245 zcmdldu}xC_GcPX}0}vc{`Ix?glY!wehyw$%P{!wgjq2LWS}}}D48g`R%t2-_1qeFW zB$&;TSzn?^Cf!uiY;zQI38SiLaY=qrrM^vZNs$$p8K0SAr+-T*H6^p8v^cd0EVlUs z%Nk}z*~z6GeFCB&nRt*?JXmh>AC4_j5!*mG9W^B@+rj?r5r~Wb qO!niN%dfCN^}3SnMJ3w{E)f@5A~!$d@@3?Dgyu+;yn-m delta 140 zcmdlcxlcmtj762{Ha ztjm}gWhNiu=$o9*xmHRXsJ2J~L`Z@NDG(tIB4j4(aaC~{1DT9KT>N74Ca$@gles+@ Pxh-Y+nHsr^41vM`lj0kY diff --git a/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc b/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc index deb7c0b15813437a90b615f2b2dbbaca1fa9a280..3f21abca802eba08e838ea6974ad8eadae6add85 100644 GIT binary patch delta 2668 zcmb`Je{54#6vy9t?d#Upc3Zcu+d4)|-LE&hN;(!shy2nB6fGOI8B! ze^3Srn=C=ONB|K+Ob{X(<}<;?7$*?|3UPH{XPNv6LqQj04u657_q@uUnG0y*%lg^5 z=l*!-d(O#iH(#K4U8NI-H5!g0k7eFaV}AL|3F-7eXWm&_SFLen8K`2IA`i-G9M2oy zVFq(l3NnW|Gx6?{&np}iW z%T!DgCz^M7B|fT4mb;lImFVa%5FH7`p@!GN<7RNJe0*q8R%}R7F0Po4**>{jo=v%B zZpNjuGCp>Z@$MQo%`2KbK~KYzkHNtAj2AU~8c-$=yO}6AvL_H_$zHUkB_Eq+>1tO7JV+cDHv1du znygEM%}sm~f-FUqZZheD#Zl!Gci)LJA&{p5Vo0D*j0=qiYbD@0z$(CMJjA7>DUg{A zqVeL3YP=1o1?JY^cH0A?R8NC9SOa0y#HPhKP>8G;B%i=}f_2n@I%~K0z?`tUcwJe) z))3K}!&-Ah%ZIi6;hZCdorOJGzDGM_oue-adK~O>2w4n3&dj71D> zhajpJp0t@BPqJmw9k|?PO_AairL84v@OGP(-9`+XaMG4cvpa}6Tew)%Nz`^lH zrm&%`RzBf4F|Wa;a7*V3)*(_bQcDb`Q?s2c;8SB_J8+Gofi z9Y&Q{^i(p5*5h+zEM@jMX6G&CE|95isNQNkv)(9dpEn>6eGJQw0Zsr;0zLtB06qnL z25197O?lm4F9yfw0I_Tn!0H8@0h|SV0g!Ho2n*nZP zM{E%!2%Q7;E>XfQ9N~}~Q<=8smpl<=+0b+u& zUz>(2s1N^*!^EzvwN_a>Z|~+d z!PXBXi!PvhViXdhSwe&u(B>v63(9=K7ew6{1gz)~-zI`iQArk~p8qX+ms-IOHtnzH zIrlv0KL2x0?%grX9-m^x7mJDtHS}3FbS(16?N1h)*zvUU1k**Vt}1z<_Pj&xsB6}n zAEFSk59kLT*YDyY{jt|)+7A)$rWDNf@MfyIjAjlnFy* z-YDOBQ<|}DT<@t7hRM+&FZGzU z2v3u_R$fxS4jYpVjpjKUGsfolhSqo@Dn;Y5ISDM~_s2JMU-qLOJF@w1_Bn)|WUiMx zeJix=IsVLQhcH5pxctWIX05P`%*}GiZC|kJ-DD=_5$txm=%D|MAsmWI0Vx;}U!diX zT)w76%l2|-QmUdj;y`Bh1P1dM|pqCeT9>BX&<8#_VEjCOXLNuQ@Z3U z2tNQE1YQMR15&^t;7wo?fOfmeF5eiAw*jT~)v(?H-UZ$RjsOV!U-}b<>|IbcYz)ro7Uxl!(TEg8Q^~9E z^(0d;6}4*TO#hGC%pxf+1vdtQol>+nD)k4XXjeFAR(;}?`@G<4b>QZR|DPT2i@1fK zN!c>_rN{vx`6Wc=DTVkIE@Z0#>ucZ}U>f)qI0t+OoChud-vcQiXHN3Zd@^_FvGdA< zf_Ftusd6i&4olHhiey%%Wde(2+Mbyya flfIe+rgvr@W9+o1YD(jq;FlguGqZe1Y-fK0VD{+z diff --git a/osinaweb/osinacore/edit/urls.py b/osinaweb/osinacore/edit/urls.py index 0ddd9542..90b5fba9 100644 --- a/osinaweb/osinacore/edit/urls.py +++ b/osinaweb/osinacore/edit/urls.py @@ -11,6 +11,7 @@ urlpatterns = [ path('project//', views.edit_project, name='editproject'), path('project//toggle_pin/', views.toggle_pin_project, name='toggle_pin_project'), path('projectstatus//', views.edit_project_status_modal, name='editprojectstatusmodal'), + path('story//', views.edit_user_story_modal, name='edituserstorymodal'), path('task//', views.edit_task, name='edittask'), path('task-status//', views.edit_task_status_modal, name='edittaskstatusmodal'), path('epic/', views.edit_epic, name='editepic'), diff --git a/osinaweb/osinacore/edit/views.py b/osinaweb/osinacore/edit/views.py index c1bdbf73..4b0cd6a7 100644 --- a/osinaweb/osinacore/edit/views.py +++ b/osinaweb/osinacore/edit/views.py @@ -233,7 +233,25 @@ def toggle_pin_project(request, project_id): return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) +@staff_login_required +def edit_user_story_modal(request, story_id): + story = get_object_or_404(UserStory, id=story_id) + milestones = Milestone.objects.filter(project=story.project) + if request.method == 'POST': + story.milestone = get_object_or_404(Milestone, id=request.POST.get('milestone')) + story.content = request.POST.get('content') + story.completed = True if request.POST.get('completed') else False + story.confirmed = True if request.POST.get('confirmed') else False + story.save() + response = HttpResponse( + '') + return response + context = { + 'milestones': milestones, + 'story': story, + } + return render(request, 'edit_templates/edit-userstory-modal.html', context) @staff_login_required @@ -260,7 +278,7 @@ def edit_task(request, task_id): epic = get_object_or_404(Epic, id=epic_id) task.epic = epic - task.requirement = request.POST.get('requirement') + task.userstory = request.POST.get('requirement') task.status = request.POST.get('status') # Convert assigned_to ID to a StaffProfile instance diff --git a/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py b/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py new file mode 100644 index 00000000..88c21e4c --- /dev/null +++ b/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-05 13:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0109_remove_status_task'), + ] + + operations = [ + migrations.AddField( + model_name='projectrequirement', + name='milestone', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.milestone'), + ), + ] diff --git a/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py b/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py new file mode 100644 index 00000000..ee7bb020 --- /dev/null +++ b/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.7 on 2025-04-05 13:40 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0110_projectrequirement_milestone'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RenameModel( + old_name='ProjectRequirement', + new_name='UserStory', + ), + migrations.RenameField( + model_name='task', + old_name='requirement', + new_name='userstory', + ), + ] diff --git a/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py b/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py new file mode 100644 index 00000000..eb9e245e --- /dev/null +++ b/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 14:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0111_rename_projectrequirement_userstory_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='milestone', + old_name='title', + new_name='name', + ), + ] diff --git a/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py b/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py new file mode 100644 index 00000000..f32283e4 --- /dev/null +++ b/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.7 on 2025-04-05 14:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0112_rename_title_milestone_name'), + ] + + operations = [ + migrations.AddField( + model_name='userstory', + name='completed', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='userstory', + name='confirmed', + field=models.BooleanField(default=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0114_alter_project_end_date.py b/osinaweb/osinacore/migrations/0114_alter_project_end_date.py new file mode 100644 index 00000000..02a23dce --- /dev/null +++ b/osinaweb/osinacore/migrations/0114_alter_project_end_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0113_userstory_completed_userstory_confirmed'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='end_date', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py b/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py new file mode 100644 index 00000000..661fea38 --- /dev/null +++ b/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0114_alter_project_end_date'), + ] + + operations = [ + migrations.AddField( + model_name='projectstatus', + name='default_created', + field=models.BooleanField(default=False), + ), + ] diff --git a/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py b/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py new file mode 100644 index 00000000..34e8d9b1 --- /dev/null +++ b/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0115_projectstatus_default_created'), + ] + + operations = [ + migrations.RemoveField( + model_name='projectstatus', + name='default_created', + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef0ff7eb4752a9603e1de14017c0685a60eee7ac GIT binary patch literal 1055 zcmZuwyKmD#7(YMa*rqSs(kBuv?LdSSCrAvI5E2qp>Vpn;Duzb7I`K7f>)7d?-6~8- zNX#t#A7EpIiGP7~Np%YYQ@2zBv2thQfYe&@ci-!N-*><7Za6-!1NPM(UA2A-0Q}%a z{uTZz!*!;d0S7q37Qg~q#Vv7D!qTRU=Z2r$kxYFw&FrdC>1Wb zu~QPM-u7GAjr}MjRB1;Z3P>|c%w&!<{KV`tP){pk(GjrZh^Bz$dchw1e?zA8URWnZ zd+Nqmp|068*CY1C4ZhhMeDl|Rj^Y$8$x$tdbv5p2c%r43Zc*)Je!j~h+r&<+MZ^!? zW`q%)t5ho%#HbyeAV^|2P6&)$azu>|jt)^X#^^ZlSsaBi)!Kf5NF0Tz_Ii4RQ670q z5|zUw2v~s-G9FQks2E4gt*5-g&}}1@!e!yWM}hZ|O<g();ekp(xTqTcp2~j75dOu*putwwv8_W<%*s z5Cm^t>ffOMjje}-0Z*QKONqVvW;bany0Ej~dvCrs-@b3RpU+zeuJ2E-8t+mF{Zhg3 z$_zk%6TlfFh-lkrOXFHe;na3&OXqqCJwP*v=noM|SM>@Wl1I;FJ;6NP$drvs6_hoJ z1&bmtXb8Yo(`#@i^1?vWM?8ea20{M|fHPD@TqB65h{ko2s-`Qk^xFgkQmRJf&fhr| zEo({6PH_y(!oNGzOOQ0ltf*PIFD@-D(iRU7Sv}(Hxb1P)WI;rmp3g)S222)SCDqEPD$RYtIEg}j3hi*{yEJf` zOyYo@Bq$v@;z(w1b(CfsIM5O}I*c@QnIG@vIZ(y(uzW*%<-Ei+PE#r^N?}{uXMl5* z9=9D|9Rtxgr3W4~^SyutA*DPGbU7(boL0-J0l{T07Pu^^pK@id9ADdi{ete3jSAg; zxxTR@b2mFYCS~w%EXXS)^1%@Ez2t6GhyswIe3rY-Ls-ZX`e1 zYA(VSj_);@?|Y}rUJvVSHBn)|3Hgy7kKTqk#lSsuf<~AmPgpGh${2g}$=P7h66LYL z|2cItR_X*U42-jd)+skYPrNA4#amcDqMm`wr(Im=;JFJt_Z4^MSI_5Hf8e!VMxQj^ z@APuWyw|}~7kH{$EO(2gtBh`1Jv_?Zf7C6`sKQtp3R$aQeAwbs!=v`f8JSI9X`vnl z2g&HoLB_4cE+xv;%o5^bKoUPojDF5%AXNW?Q2Cy&Y1*}cwCSIy^xL?r8K14r#O(RR K>@|WQZtw@cuN>$A literal 0 HcmV?d00001 diff --git a/osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad8632b16a3f4b6990d93609abb8cd93fd8766a7 GIT binary patch literal 780 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 literal 0 HcmV?d00001 diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 25be9240..eb5e8e29 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -172,8 +172,6 @@ class StaffProfile(models.Model): - - class StaffPosition(models.Model): staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE) position = models.ForeignKey(JobPosition, null=True, on_delete=models.SET_NULL) @@ -198,7 +196,7 @@ class Project(models.Model): details = models.TextField() members = models.ManyToManyField('StaffProfile', default='', related_name='members_project') start_date = models.DateField() - end_date = models.DateField() + end_date = models.DateField(null=True, blank=True) active = models.BooleanField(default=True, null=True) project_id = models.CharField(max_length=20, null=True, blank=True) def __str__(self): @@ -259,17 +257,6 @@ class PinnedProject(models.Model): - -class Milestone(models.Model): - title = models.CharField(max_length=150) - description = models.TextField() - project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) - start_date = models.DateField() - end_date = models.DateField() - def __str__(self): - return self.title - - class Epic(models.Model): title = models.CharField(max_length=150) STATUS_CHOICES = ( @@ -285,11 +272,26 @@ class Epic(models.Model): return self.title -class ProjectRequirement(models.Model): + +class Milestone(models.Model): + name = models.CharField(max_length=150) + description = models.TextField() + project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) + start_date = models.DateField() + end_date = models.DateField() + def __str__(self): + return self.name + + + +class UserStory(models.Model): + milestone = models.ForeignKey(Milestone, on_delete=models.SET_NULL, null=True) content = models.CharField(max_length=350) project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) date = models.DateField(null=True, auto_now=True) added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) + confirmed = models.BooleanField(default=True) + completed = models.BooleanField(default=False) def __str__(self): return self.content @@ -339,7 +341,7 @@ class Task(models.Model): start_date = models.DateField(null=True) end_date = models.DateField(null=True) assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True) - requirement = models.ForeignKey(ProjectRequirement, on_delete=models.SET_NULL, null=True, blank=True) + userstory = models.ForeignKey(UserStory, on_delete=models.SET_NULL, null=True, blank=True) task_id = models.CharField(max_length=20, null=True, blank=True) def save(self, *args, **kwargs): if not self.task_id: diff --git a/osinaweb/osinacore/templates/add_templates/add-epic.html b/osinaweb/osinacore/templates/add_templates/add-epic.html index 176939e4..04a21be5 100644 --- a/osinaweb/osinacore/templates/add_templates/add-epic.html +++ b/osinaweb/osinacore/templates/add_templates/add-epic.html @@ -11,18 +11,13 @@ action="{% url 'addepic' project.project_id %}"> {% csrf_token %}
- +
- -
- +
diff --git a/osinaweb/osinacore/templates/add_templates/add-milestone.html b/osinaweb/osinacore/templates/add_templates/add-milestone.html new file mode 100644 index 00000000..9eeb8210 --- /dev/null +++ b/osinaweb/osinacore/templates/add_templates/add-milestone.html @@ -0,0 +1,45 @@ +{% extends "add-edit-main.html" %} +{%load static%} +{% block content %} + +
+
+

+ Create Milestone For {{project.name}} +

+
+ {% csrf_token %} +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
+
+ +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/add_templates/add-project.html b/osinaweb/osinacore/templates/add_templates/add-project.html index 311e7c76..9c1a7622 100644 --- a/osinaweb/osinacore/templates/add_templates/add-project.html +++ b/osinaweb/osinacore/templates/add_templates/add-project.html @@ -70,35 +70,6 @@ class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none mt-1"> -
- -
-
- -
- - - - - -
-
-
-
@@ -118,7 +89,5 @@
- - {% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html b/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html index 64f067f8..ccc7cdee 100644 --- a/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html +++ b/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html @@ -13,15 +13,40 @@ -
+ {% csrf_token %}

Add User Story

+ + {% if not milestone %} +
+ + +
+ {% endif %}
+ + +
+ +

Completed

+
+ +
+ +

Confirmed

+
+ +
+
+ + + + + + + + + + + + + + + + {% if stories %} + {% for story in stories %} + + + + + + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
+ Story + + Confirmed + + Completed + + Related Task + + Actions +
+

{{story.content}}

+
+

{{story.confirmed}}

+
+

{{story.completed}}

+
+ {% if story.task_set.all %} + {% for task in story.task_set.all %} + + + {% endfor %} + {% else %} +
+

Add Task

+ +
+ + + +
+
+
+ {% endif %} +
+
+ + + + + +
+ + + +
+
+
+ No Stories at the moment +
+ + + + + + + +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/details_templates/project-details.html b/osinaweb/osinacore/templates/details_templates/project-details.html index 54d87740..7f82a236 100644 --- a/osinaweb/osinacore/templates/details_templates/project-details.html +++ b/osinaweb/osinacore/templates/details_templates/project-details.html @@ -72,23 +72,27 @@ @@ -396,10 +400,22 @@ + + Milestone + Story + + Confirmed + + + Completed + Related Task @@ -417,10 +433,33 @@ {% if stories %} {% for story in stories %} + + {% if story.milestone %} + {{story.milestone.name}} + + + + + {% else %} +

{{story.milestone.name}}

+ {% endif %} + +

{{story.content}}

+ +

{{story.confirmed}}

+ + + +

{{story.completed}}

+ + {% if story.task_set.all %} {% for task in story.task_set.all %} @@ -466,7 +505,7 @@
- + diff --git a/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html b/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html new file mode 100644 index 00000000..c1f41e78 --- /dev/null +++ b/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html @@ -0,0 +1,57 @@ +{% load static %} + + + + + + + Osina + + + + + + + + + {% csrf_token %} +

Edit User Story

+ + {% if not milestone %} +
+ + +
+ {% endif %} + +
+ +
+ + +
+ +

Completed

+
+ +
+ +

Confirmed

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/osinaweb/osinacore/urls.py b/osinaweb/osinacore/urls.py index 8d5530a2..1277e629 100644 --- a/osinaweb/osinacore/urls.py +++ b/osinaweb/osinacore/urls.py @@ -63,7 +63,8 @@ urlpatterns = [ path('customers//', views.customerdetails, name='customerdetails'), path('businesses//', views.businessdetails, name='businessdetails'), path('staffs//', views.staffdetails, name='userdetails'), - path('projectdetails//', views.projectdetails, name='detailed-project'), + path('projects//', views.projectdetails, name='detailed-project'), + path('milestones//', views.milestonedetails, name='detailed-milestone'), path('tasks//', views.taskdetails, name='detailed-task'), path('show-points//', views.show_points_modal, name='showpoints'), path('timeline//', views.timeline_modal, name='timeline'), diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 052b63c0..637c2557 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -606,7 +606,7 @@ def projectdetails(request, project_id): project_notes = Note.objects.filter(project=project).order_by('-id') statuses = ProjectStatus.objects.filter(project=project).order_by('-id') - stories = ProjectRequirement.objects.filter(project=project).order_by('-id') + stories = UserStory.objects.filter(project=project).order_by('-id') credentials = ProjectCredential.objects.filter(project=project).order_by('-id') albums = ProjectFileAlbum.objects.filter(project=project).order_by('-id') @@ -653,6 +653,18 @@ def projectdetails(request, project_id): return render(request, 'details_templates/project-details.html', context) +@staff_login_required +def milestonedetails(request, milestone_id): + milestone = get_object_or_404(Milestone, id=milestone_id) + stories = UserStory.objects.filter(milestone=milestone).order_by('-id') + context = { + 'milestone': milestone, + 'stories' : stories, + + } + + return render(request, 'details_templates/milestone-details.html', context) + def chat_room(request, chat_id): diff --git a/osinaweb/static/js/pop-modals.js b/osinaweb/static/js/pop-modals.js index caeae880..bcc7d110 100644 --- a/osinaweb/static/js/pop-modals.js +++ b/osinaweb/static/js/pop-modals.js @@ -70,7 +70,7 @@ function initializeModalButtons() { addButtonClickListener("addStaffPositionButton", "fit-content", "260px"); addButtonClickListener("addStatusButtonMobile", "500px", "80px"); addButtonClickListener("userRecentActivitiesButton", "400px", "600px"); - addButtonClickListener("addUserStoryButton", "400px", "160px"); + addButtonClickListener("addUserStoryButton", "400px", "330px"); addButtonClickListener("reactionDetailsButton", "400px", "300px"); addButtonClickListener("addPaymentCommentButton", "500px", "250px"); diff --git a/osinaweb/static/js/projects/add-project.js b/osinaweb/static/js/projects/add-project.js deleted file mode 100644 index 5a42ce41..00000000 --- a/osinaweb/static/js/projects/add-project.js +++ /dev/null @@ -1,18 +0,0 @@ -const addReqButton = document.getElementById("addReqButton"); -const addReqContainerTemplate = document.getElementById("addReqContainerTemplate"); -const addReqContainer = document.getElementById("addReqContainer"); - -addReqButton.addEventListener("click", function () { - // Clone the template and remove the "hidden" class - const newContainer = addReqContainerTemplate.cloneNode(true); - newContainer.classList.remove("hidden"); - - // Add an event listener to the new container's remove button - const removeReqButton = newContainer.querySelector("#removeReqButton"); - removeReqButton.addEventListener("click", function () { - // Remove the clicked container when the remove button is clicked - newContainer.remove(); - }); - - addReqContainer.appendChild(newContainer); -}); \ No newline at end of file