diff --git a/README.html b/README.html index 587828167..f53a68f60 100644 --- a/README.html +++ b/README.html @@ -12,7 +12,7 @@ const baseUrl = '/2024' -

CS3281&2 student data website

+

CS3281&2 student data website

diff --git a/README.page-vue-render.js b/README.page-vue-render.js index 3ceceef87..7e2bb5131 100644 --- a/README.page-vue-render.js +++ b/README.page-vue-render.js @@ -8,6 +8,6 @@ with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"fixed":""} with(this){return _c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_c('h1',{attrs:{"id":"cs3281-and-amp-2-student-data-website"}},[_v("CS3281&2 student data website"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3281-and-amp-2-student-data-website","onclick":"event.stopPropagation()"}})])])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")])]),_v(" on Sun, 12 May 2024, 15:45:25 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")])]),_v(" on Sun, 12 May 2024, 15:54:53 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} }]; \ No newline at end of file diff --git a/activities-dashboard.html b/activities-dashboard.html index 758d0b0d7..90b5106e9 100644 --- a/activities-dashboard.html +++ b/activities-dashboard.html @@ -14,7 +14,7 @@

GitHub Activities Dashboard

  • This page contains a list of your NUS-OSS GitHub posts during the period eligible for course credit.
    For CS3282 students, the activity period varies based on when you finished CS3282.
  • The content of each panel body may not be exactly as it shows up on GitHub, as some crude sanitizations have been done to prevent post contents interfering with MarkBind parsing.
  • It goes without saying that GitHub activities are not the sole representation of your work. It's just one source of evidence only. So, don't put too much importance on what you see in this page.
    -Furthermore, the stats (i.e., posts counts) are not directly comparable between devs, as they are influenced by the type of work/project.
  • This page will be updated once in a while, in 1-2 week intervals.

[This page was last updated on 2024-05-07 @22:54]

CS3281

ARIF..ALID @Arif-Khalid 23 27+84 10 9


MISR..ITYA @MadLamprey 13 0+10 3 1


NERE.. BIN @NereusWB922 36 16+35 8 7


NGUY..UYEN @nknguyenhc 20 39+67 12 22


EYO ..EVIN @KevinEyo1 13 42+10 6 26


LAM ..FONG @LamJiuFong 8 36+13 2 14


WANG..TING @jingting1412 9 45+6 2 4


WANG..IWEN @yiwen101 14 92+6 7 21


XU S..UYAO @Tim-Siu 8 55+16 3 15


ALVI..S NG @supermii2 3 9+5 3 4


GEOR.. YAO @asdfghjkxd 15 50+38 9 5


JONA.. WEI @jonasongg 15 49+22 7 5


POON..RYAN @sopa301 20 47+43 11 8


CHIN..YUAN @mingyuanc 15 46+22 0 0


DOMI.. GIN @domoberzin 31 14+20 1 1


TYE ..QUES @marquestye 11 26+9 1 0


XENO..NONG @xenosf 17 13+11 3 1


YEO ..HENG @dishenggg 20 18+7 1 1


ZHU ..ANXI @yuanxi1 10 7+3 0 0



CS3282

GOH ..RIEL @gycgabriel 3 0+42 5 5


LEE ..SAAC @luminousleek 11 11+112 7 11


VIGN..IYER @vigneshsankariyer1234567890 5 0+43 1 4


WONG..HONG @cheehongw 8 10+45 7 11


CHAN..HENG @yucheng11122017 12 23+485 9 69


ELTO.. HAO @EltonGohJH 2 5+83 3 16


HANN.. XIN @kaixin-hc 12 3+201 7 67


LEE ..AVID @itsyme 4 5+62 5 5


CHAR..USAR @ckcherry23 2 0+226 11 23


DAVI.. ONG @vvidday 0 0+107 1 1


GOKU..AJIV @gok99 1 0+63 3 13


MARC.. KYE @MarcusTXK 0 0+63 3 4


CHAN..OLAS @Nicolascwy 30 27+172 7 11


DOMI.. JUN @domlimm 7 11+107 3 35


JAY ..TING @jayasting98 14 13+168 5 10


KEVI..TONG @kevin9foong 6 3+26 3 2


MOK ..RGUS @FergusMok 22 27+156 4 4


NEO ..QING @weiquu 34 4+332 24 58


ONG ..DRIC @cedricongjh 55 15+406 12 79


SIM ..NICE @EuniceSim142 18 16+62 0 0


ZHAN..QING @ziqing26 24 7+206 4 6


+Furthermore, the stats (i.e., posts counts) are not directly comparable between devs, as they are influenced by the type of work/project.
  • This page will be updated once in a while, in 1-2 week intervals.
  • [This page was last updated on 2024-05-07 @22:54]

    CS3281

    ARIF..ALID @Arif-Khalid 23 27+84 10 9


    MISR..ITYA @MadLamprey 13 0+10 3 1


    NERE.. BIN @NereusWB922 36 16+35 8 7


    NGUY..UYEN @nknguyenhc 20 39+67 12 22


    EYO ..EVIN @KevinEyo1 13 42+10 6 26


    LAM ..FONG @LamJiuFong 8 36+13 2 14


    WANG..TING @jingting1412 9 45+6 2 4


    WANG..IWEN @yiwen101 14 92+6 7 21


    XU S..UYAO @Tim-Siu 8 55+16 3 15


    ALVI..S NG @supermii2 3 9+5 3 4


    GEOR.. YAO @asdfghjkxd 15 50+38 9 5


    JONA.. WEI @jonasongg 15 49+22 7 5


    POON..RYAN @sopa301 20 47+43 11 8


    CHIN..YUAN @mingyuanc 15 46+22 0 0


    DOMI.. GIN @domoberzin 31 14+20 1 1


    TYE ..QUES @marquestye 11 26+9 1 0


    XENO..NONG @xenosf 17 13+11 3 1


    YEO ..HENG @dishenggg 20 18+7 1 1


    ZHU ..ANXI @yuanxi1 10 7+3 0 0



    CS3282

    GOH ..RIEL @gycgabriel 3 0+42 5 5


    LEE ..SAAC @luminousleek 11 11+112 7 11


    VIGN..IYER @vigneshsankariyer1234567890 5 0+43 1 4


    WONG..HONG @cheehongw 8 10+45 7 11


    CHAN..HENG @yucheng11122017 12 23+485 9 69


    ELTO.. HAO @EltonGohJH 2 5+83 3 16


    HANN.. XIN @kaixin-hc 12 3+201 7 67


    LEE ..AVID @itsyme 4 5+62 5 5


    CHAR..USAR @ckcherry23 2 0+226 11 23


    DAVI.. ONG @vvidday 0 0+107 1 1


    GOKU..AJIV @gok99 1 0+63 3 13


    MARC.. KYE @MarcusTXK 0 0+63 3 4


    CHAN..OLAS @Nicolascwy 30 27+172 7 11


    DOMI.. JUN @domlimm 7 11+107 3 35


    JAY ..TING @jayasting98 14 13+168 5 10


    KEVI..TONG @kevin9foong 6 3+26 3 2


    MOK ..RGUS @FergusMok 22 27+156 4 4


    NEO ..QING @weiquu 34 4+332 24 58


    ONG ..DRIC @cedricongjh 55 15+406 12 79


    SIM ..NICE @EuniceSim142 18 16+62 0 0


    ZHAN..QING @ziqing26 24 7+206 4 6


    diff --git a/activities-dashboard.page-vue-render.js b/activities-dashboard.page-vue-render.js index f86ec4ec3..f64f741a2 100644 --- a/activities-dashboard.page-vue-render.js +++ b/activities-dashboard.page-vue-render.js @@ -20,6 +20,6 @@ with(this){return _c('h1',{attrs:{"id":"cs3281"}},[_v("CS3281"),_c('a',{staticCl with(this){return _c('h1',{attrs:{"id":"cs3282"}},[_v("CS3282"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282","onclick":"event.stopPropagation()"}})])} },function anonymous( ) { -with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")])]),_v(" on Sun, 12 May 2024, 15:45:25 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} +with(this){return _c('footer',[_c('div',{staticClass:"text-center"},[_c('p',[_v("["),_c('strong',[_v("This site was generated using "),_c('img',{attrs:{"src":"https://markbind.org/favicon.ico","width":"25"}}),_v(" "),_c('a',{attrs:{"href":"https://markbind.org/"}},[_v("MarkBind 5.5.2")])]),_v(" on Sun, 12 May 2024, 15:54:53 UTC]"),_c('br'),_v(" "),_c('span',{staticClass:"dimmed"},[_c('small',[_c('small',[_v("favicon.ico of this site was made by "),_c('a',{attrs:{"href":"https://www.flaticon.com/authors/smashicons","title":"Smashicons"}},[_v("Smashicons")]),_v(" from "),_c('a',{attrs:{"href":"https://www.flaticon.com/","title":"Flaticon"}},[_v("www.flaticon.com")]),_v(" is licensed by "),_c('a',{attrs:{"href":"http://creativecommons.org/licenses/by/3.0/","title":"Creative Commons BY 3.0","target":"_blank"}},[_v("CC 3.0 BY")])])])])])])])} }]; \ No newline at end of file diff --git a/cs3282-index.html b/cs3282-index.html index 237a5dd87..be2b98233 100644 --- a/cs3282-index.html +++ b/cs3282-index.html @@ -16,7 +16,7 @@ Zitadel, Templ, FerretDB

    WONG CHEE HONG

    MarkBind

    CHAN YU CHENG

    ELTON GOH JUN HAO

    HANNAH CHIA KAI XIN

    LEE WEI, DAVID

    RepoSense

    CHARISMA KAUSAR

    DAVID GARETH ONG

    GOKUL RAJIV

    MARCUS TANG XIN KYE

    TEAMMATES

    CHANG WENG YEW, NICOLAS

    DOMINIC LIM KAI JUN

    JAY ALJELO SAEZ TING

    KEVIN FOONG WEI TONG

    MOK KHENG SHENG FERGUS

    NEO WEI QING

    ONG JUN HENG, CEDRIC

    SIM SING YEE, EUNICE

    ZHANG ZIQING


    1. In the Python project, NEWS entries document contributions so that it can be added into the changelog.

    +date-fns

    DAVID GARETH ONG

    GOKUL RAJIV

    MARCUS TANG XIN KYE

    TEAMMATES

    CHANG WENG YEW, NICOLAS

    DOMINIC LIM KAI JUN

    JAY ALJELO SAEZ TING

    KEVIN FOONG WEI TONG

    MOK KHENG SHENG FERGUS

    NEO WEI QING

    ONG JUN HENG, CEDRIC

    SIM SING YEE, EUNICE

    ZHANG ZIQING


    1. In the Python project, NEWS entries document contributions so that it can be added into the changelog.

    diff --git a/cs3282-index.page-vue-render.js b/cs3282-index.page-vue-render.js index ae4358f3c..d140000ef 100644 --- a/cs3282-index.page-vue-render.js +++ b/cs3282-index.page-vue-render.js @@ -1,7 +1,7 @@ var pageVueRenderFn = function anonymous( ) { -with(this){return _c('div',{attrs:{"id":"app"}},[_c('header',{attrs:{"fixed":""}},[_c('navbar',{attrs:{"placement":"top","type":"primary"},scopedSlots:_u([{key:"brand",fn:function(){return [_c('a',{staticClass:"navbar-brand",attrs:{"href":"/2024/index.html","title":"Home"}},[_v("CS3281&2-2024/Students")])]},proxy:true},{key:"right",fn:function(){return [_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://github.com/nus-cs3281/2024"}},[_c('span',[_c('span',{staticClass:"fab fa-github",attrs:{"aria-hidden":"true"}})])])])]},proxy:true}])},[_v(" "),_c('dropdown',{staticClass:"nav-link",scopedSlots:_u([{key:"header",fn:function(){return [_v("CS3281")]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/index.html"}},[_v("Students")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/students/knowledge.html"}},[_v("Knowledge")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"https://nus-cs3281.github.io/2024-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByAuthors&breakdown=false"}},[_v("Code Dashboard")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/activities-dashboard.html"}},[_v("Activities Dashboard")])])]),_v(" "),_c('dropdown',{staticClass:"nav-link",scopedSlots:_u([{key:"header",fn:function(){return [_v("CS3282")]},proxy:true}])},[_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/cs3282-index.html"}},[_v("Students")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/students/talksSchedule.html"}},[_v("Lightning Talks")])]),_v(" "),_c('li',[_c('a',{staticClass:"dropdown-item",attrs:{"href":"/2024/activities-dashboard.html"}},[_v("Activities Dashboard")])])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"/2024/instructions.html"}},[_v("Instructions")])]),_v(" "),_c('li',[_c('a',{staticClass:"nav-link",attrs:{"href":"https://nus-cs3281.github.io/website/"}},[_v("CS3281&2 Website "),_c('span',[_c('span',{staticClass:"glyphicon glyphicon-share-alt",attrs:{"aria-hidden":"true"}})])])])],1)],1),_v(" "),_c('div',{attrs:{"id":"flex-body"}},[_c('div',{staticClass:"fixed-header-padding",attrs:{"id":"content-wrapper"}},[_m(0),_v(" "),_m(1),_v(" "),_m(2),_v(" "),_m(3),_v(" "),_m(4),_v(" "),_m(5),_v(" "),_m(6),_v(" "),_m(7),_v(" "),_m(8),_v(" "),_m(9),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"goh-yee-chong-gabriel"}},[_v("GOH YEE CHONG, GABRIEL"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#goh-yee-chong-gabriel","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/gycgabriel/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/gycgabriel"}},[_v("https://www.github.com/gycgabriel")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h2',{attrs:{"id":"cs3282-progress"}},[_v("CS3282 Progress"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282-progress","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"issues-watcher"}},[_v("Issues - WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#issues-watcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/221"}},[_v("Tasks To Self-Test Knowledge Unhide Activity Dashboard #221")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/224"}},[_v("Bug when not entering anything into Select repo dialog #224")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/225"}},[_v("Show a list of hidden users at the end #225")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/227"}},[_v("Error toast shown on selecting p.Low or priority.Low label on WATcher repository #227")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Submitted Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/232"}},[_v("Move Activity Dashboard from prototype to release #232")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Commented on Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/236"}},[_v("Bypass logging in if viewing public repos only #236")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Commented on Issue: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/240"}},[_v("Hiding labels do not work as expected #240")])])])])])]),_c('h3',{attrs:{"id":"pr-reviews-watcher"}},[_v("PR Reviews - WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-reviews-watcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/223"}},[_v("Hide 0 issue columns #223")])])]),_v(" "),_c('tr',[_c('td',[_v("1-4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/226"}},[_v("Keep filters option when switching repos #226")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/228"}},[_v("Prevent redirection when repo not set #228")])])]),_v(" "),_c('tr',[_c('td',[_v("2-4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/230"}},[_v("Fix label filter not working #230")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/233"}},[_v("Improve activity dashboard design #233")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Commented on PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/234"}},[_v("Refactor test cases (In progress) #234")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/235"}},[_v("Show list of hidden users #235")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/238"}},[_v("Remove unused services #238")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Commented on PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/254"}},[_v("Refactor Label model #254")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/255"}},[_v("Add shareable repo-specific URL #255")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/259"}},[_v("Refactor certain filters into its own service #259")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/260"}},[_v("Remove test cases for permissions service #260")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/272"}},[_v("Automatic deployment #272")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/288"}},[_v("Enable pre push hook for npm run test #288")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/289"}},[_v("Refactor milestones to save by name #289")])])])])])]),_c('h3',{attrs:{"id":"pr-contributed-watcher"}},[_v("PR Contributed - WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-contributed-watcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Contributed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/239"}},[_v("Build in Github Actions #239")])])])])])]),_c('h3',{attrs:{"id":"pr-reviews-catcher"}},[_v("PR Reviews - CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-reviews-catcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Commented on PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1238"}},[_v("Redirect invalid routes to 404 not found page #1238")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"error-messages-and-hint-labels-in-angular-forms"}},[_v("Error messages and Hint labels in Angular forms"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#error-messages-and-hint-labels-in-angular-forms","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Forms have a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("FormGroup")]),_v(", where each part of the form is controled by a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("FormControl")]),_v(" component.")]),_v(" "),_c('p',[_v("In the ts file, Validators check and ensure the form is valid for submission. If it is not, the submit button is greyed out.")]),_v(" "),_c('p',[_v("In the html file, the individual form input boxes are built, and shown with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("*ngIf")]),_v(" statements. "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("")]),_v(" also has additional parameters to specify whether the input is required and the max length of the input. The form error messages are programmed here in the html file, for example:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs"}},[_c('span',[_v("\n")]),_c('span',[_v(" Title required.\n")]),_c('span',[_v("\n")])])]),_c('p',[_v("Hint labels can be used to show the remaining characters in a input box with limited characters when approaching that limit.")]),_v(" "),_c('p',[_v("While a string with validators could be used to instantiate a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("FormGroup")]),_v(", a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("FormControl")]),_v(" element ensured that validators are processed such that the form error messages are shown in components that are children to other Angular components. (PR "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/861"}},[_v("#861")]),_v(")")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://www.kiltandcode.com/2020/08/13/show-validation-error-messages-for-reactive-forms-in-angular-9/"}},[_v("Show Validation Error Messages for Reactive Forms in Angular 9")])])]),_v(" "),_c('h3',{attrs:{"id":"lifecycle-hooks-in-angular"}},[_v("Lifecycle Hooks in Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#lifecycle-hooks-in-angular","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("After a component is instantiated, the ts file has lifecycle hooks in the form of methods that initialize or modify the component content or state. These methods are prefixed with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ng")]),_v(".")]),_v(" "),_c('p',[_v("The sequence in which these lifecycle hooks are called:")]),_v(" "),_c('ul',[_c('li',[_v("OnChanges")]),_v(" "),_c('li',[_v("OnInit")]),_v(" "),_c('li',[_v("DoCheck - repeated")]),_v(" "),_c('li',[_v("AfterContentInit")]),_v(" "),_c('li',[_v("AfterContentChecked - repeated")]),_v(" "),_c('li',[_v("AfterViewInit")]),_v(" "),_c('li',[_v("AfterViewChecked - repeated")]),_v(" "),_c('li',[_v("OnDestroy")])]),_v(" "),_c('p',[_v("Most notably used is "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngOnInit")]),_v(", which used to instantiate the component variables. In CATcher, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngAfterViewInit")]),_v(" is also used to load issues after the component has been initialized.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/lifecycle-hooks"}},[_v("Lifecycle Hooks")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://blog.logrocket.com/angular-lifecycle-hooks/"}},[_v("Angular lifecycle hooks explained")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/questions/40817336/whats-the-difference-between-ngoninit-and-ngafterviewinit-of-angular2#:~:text=ngOnInit()%20is%20called%20right,its%20children's%20views%2C%20are%20created"}},[_v("What's the difference between ngOnInit and ngAfterViewInit of Angular2?")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://www.youtube.com/watch?v=kKtrHrciIVs&ab_channel=WebTechTalk"}},[_v("Video: Angular - Zero to Hero - Life Cycle Hooks")])])]),_v(" "),_c('h3',{attrs:{"id":"viewchild-in-angular"}},[_v("ViewChild in Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#viewchild-in-angular","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("While html files can add custom child components using custom defined decorators such as "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("")]),_v(", the parent component may need references to these children components to add change content or add interactability. ViewChild, ContentChild are queries to access child components from the parent component.")]),_v(" "),_c('p',[_v("For example:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs"}},[_c('span',[_v("@ViewChild(ViewIssueComponent, { static: false }) viewIssue: ViewIssueComponent;\n")])])]),_c('h4',{attrs:{"id":"static-vs-dynamic-queries"}},[_v("Static vs Dynamic queries"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#static-vs-dynamic-queries","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Static queries are queries on child components that do not change during runtime, as such result of the reference to the child component can be made available in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngOnInit")]),_v(".")]),_v(" "),_c('p',[_v("Dynamic queries are queries on child components that change during runtime, so reference to child component can only be made available in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("ngAfterViewInit")]),_v(".")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://blog.angular-university.io/angular-viewchild/"}},[_v("Angular @ViewChild")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/static-query-migration#what-does-this-flag-mean-and-why-is-it-necessary"}},[_v("Static query migration guide")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://www.youtube.com/watch?v=4YmnbGoh49U&ab_channel=AngularConnect"}},[_v("Video: Better concepts, less code in Angular 2 - Victor Savkin and Tobias Bosch")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/questions/34326745/whats-the-difference-between-viewchild-and-contentchild"}},[_v("What's the difference between @ViewChild and @ContentChild?")])])]),_v(" "),_c('h3',{attrs:{"id":"property-binding"}},[_v("Property Binding"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#property-binding","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Square brackets in html tags in angular indicate that the right hand side is a dynamic expression. For example:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs"}},[_c('span',[_v("\n")]),_c('span',[_v("\n")])])]),_c('p',[_v("The dynamic expression can be evaluated in the context of the corresponding .ts file of the html file.")]),_v(" "),_c('h3',{attrs:{"id":"event-binding"}},[_v("Event binding"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#event-binding","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Parenthesis within html tags, for example "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("(click)")]),_v(" are used to call the component's corresponding method on click. In the example above, "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("$event.stopPropagation()")]),_v(" is a Javascript call that prevents the label "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Disagree")]),_v(" within the issue bar from being clickable because its parent is clickable. The click event from parent is stopped from propagating to this particular child.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/property-binding"}},[_v("Angular Doc Property Binding")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/event-binding"}},[_v("Angular Doc Event Binding")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/a/35944965"}},[_v("StackOverflow simple summary")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/questions/32315647/javascript-how-does-event-stoppropagation-work"}},[_v("StackOverflow Stop Propagation")])])]),_v(" "),_c('h3',{attrs:{"id":"git-rebase"}},[_v("Git Rebase"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#git-rebase","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Below is a link to a good explanation with visuals to explain rebasing. Rebasing helped to clean the commit history of my main branch after accidental merging with other branches.")]),_v(" "),_c('p',[_v("Resource:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/a/29049698"}},[_v("github fork : your branch is 5 commits ahead how to clean this without pushing")]),_v(" |")])]),_v(" "),_c('h3',{attrs:{"id":"github-file-upload-api-createfile-vs-createtree"}},[_v("Github File Upload API: CreateFile vs CreateTree"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#github-file-upload-api-createfile-vs-createtree","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("The API for committing a single file and committing multiple files at once are different.\nAttempting to do multiple single file commits in a short duration of time will likely cause HttpError to occur. The current recommeded fix is to put in sleep before the next single file commit, or merge multiple single file commits into a single multiple file commit.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/a/58837709"}},[_v("Use Octokit or the GitHub Rest API to upload multiple files")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/a/19732043"}},[_v("GITHub API Issue with file upload")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://gist.github.com/StephanHoyer/91d8175507fcae8fb31a"}},[_v("Committing multiple files code gist Octokat")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/octokit/octokit.js/issues/1308"}},[_v("Octokit Pushing a tree")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://stackoverflow.com/questions/61583403/edit-multiple-files-in-single-commit-with-github-api"}},[_v("Github API Edit multiple files upload")])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-freecodecamp-org"}},[_v("Project: FreeCodeCamp.org"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-freecodecamp-org","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("An open source platform providing free resources to learn coding.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give a description of your contributions, including links to relevant PRs")]),_v(" "),_c('p',[_v("Merged "),_c('a',{attrs:{"href":"https://github.com/freeCodeCamp/freeCodeCamp/pull/53564"}},[_v("fix(curriculum): update instructions for step 110 for rpg project #53564")])]),_v(" "),_c('p',[_v("Awaiting Review "),_c('a',{attrs:{"href":"https://github.com/freeCodeCamp/freeCodeCamp/pull/53617"}},[_v("fix(client): Add live image URL validation for portfolio images #53617")])]),_v(" "),_c('h4',{attrs:{"id":"adding-image-url-validation-for-frontend"}},[_v("Adding image URL validation for frontend"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#adding-image-url-validation-for-frontend","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Learnt how we can use image() html object to verify if the image URL is live.")]),_v(" "),_c('h4',{attrs:{"id":"debugging-ci-cd-tests"}},[_v("Debugging CI/CD tests"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#debugging-ci-cd-tests","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Learnt that the previous test cases can affect the next test cases, so I should run all test cases in order to check if there's problems with loading and saving state.")]),_v(" "),_c('p',[_v("Learnt to check if I forgot to check logic with loading saved states (adding a portfolio section in user settings, and loading that section portfolio)")]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give tools/technologies you learned here. Include resources you used, and a brief summary of the resource.")]),_v(" "),_c('h4',{attrs:{"id":"setting-up-a-github-repository-with-windows-subsystem-for-linux-wsl"}},[_v("Setting up a GitHub repository with Windows Subsystem for Linux (WSL)"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#setting-up-a-github-repository-with-windows-subsystem-for-linux-wsl","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Learnt to use VSCode to access code on the WSL. Git clone repository on the WSL, not on windows.")]),_v(" "),_c('h4',{attrs:{"id":"discord-server-and-forums"}},[_v("Discord server and forums"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#discord-server-and-forums","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("FreeCodeCamp has live Discord server and forums with active and dedicated contributors.")]),_v(" "),_c('p',[_v("Setting up was difficult, and while instructions could be clearer separated into Windows and Mac users (for Windows users, for Mac users), it was good they had detailed instructions.")]),_v(" "),_c('h4',{attrs:{"id":"wait-time-for-help"}},[_v("Wait time for help"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#wait-time-for-help","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("As with all open source projects, getting help or code reviews can take time. I was fortunate my first PR was an easy fix and quickly reviewed within 15 mins, but my second PR is still awaiting review. Nonetheless, the contributors are helpful and helped point out the cause of my CI/CD issues.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"lee-xiong-jie-isaac"}},[_v("LEE XIONG JIE, ISAAC"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#lee-xiong-jie-isaac","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/luminousleek/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/luminousleek"}},[_v("https://www.github.com/luminousleek")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher"}},[_v("WATcher")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("MarkBind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h2',{attrs:{"id":"cs3282-progress-2"}},[_v("CS3282 Progress"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282-progress-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"summary"}},[_v("Summary"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#summary","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Reviewed PRs of CS3281 mentees as well as a first-time contributor for CATcher and WATcher")]),_v(" "),_c('li',[_v("Provided in-person guidance to CS3281 mentees regularly")]),_v(" "),_c('li',[_v("Explored and implemented methods to test logger output in MarkBind")])]),_v(" "),_c('h3',{attrs:{"id":"pr-reviews-catcher-2"}},[_v("PR Reviews - CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-reviews-catcher-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1237"}},[_v("Add whitespace validation #1237")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1233"}},[_v("Fix broken duplicate link #1233")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1238"}},[_v("Redirect invalid routes to 404 not found page #1238")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1241"}},[_v("Preserve line breaks in markdown #1241")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1264"}},[_v("Raising warnings when submitting team response with assignees who aren't in organization #1264")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1256"}},[_v("Add login redirect #1256")])])])])])]),_c('h3',{attrs:{"id":"pr-contributions-catcher"}},[_v("PR Contributions - CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-contributions-catcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1240"}},[_v("Add documentation for CATcher's parser #1240")])])])])])]),_c('h3',{attrs:{"id":"pr-reviews-watcher-2"}},[_v("PR Reviews - WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-reviews-watcher-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/241"}},[_v("Refactor test cases for Login Component, Session Model and Conflict Model #241")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/243"}},[_v("Remove markdown.css from test env stylesheets #243")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/244"}},[_v("Refactor test cases for issue paginator #244")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/245"}},[_v("Refactor test cases for issue sorter #245")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/246"}},[_v("Refactor github label constants #246")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/247"}},[_v("Refactor test cases for search filter #247")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/254"}},[_v("Refactor Label model #254")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/255"}},[_v("Add shareable repo-specific URL #255")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/258"}},[_v("Refactor test cases for Label Service #258")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/262"}},[_v("Remove constants for DataFile and Team model #262")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/257"}},[_v("Refactor test cases for Issue Model #257")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/263"}},[_v("Refactor test cases for Phase Service #263")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/274"}},[_v("Refactor test cases for label filter bar component #274")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/275"}},[_v("Update test cases for phase service #275")])])]),_v(" "),_c('tr',[_c('td',[_v("8-9")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/291"}},[_v("Refactor Phase Service and remove Phase #291")])])]),_v(" "),_c('tr',[_c('td',[_v("8-9")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/303"}},[_v("Create tests for Milestone service #303")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/304"}},[_v("Create tests for Error Handling service #304")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/339"}},[_v("Show prs without milestone #339")])])])])])]),_c('h3',{attrs:{"id":"pr-contributions-markbind"}},[_v("PR Contributions - MarkBind"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-contributions-markbind","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2421"}},[_v("Simplify fix for abrupt panel transition #2421")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2462"}},[_v("Use intended test input for NodeProcessor test #2462")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2463"}},[_v("Test logger calls in tests for NodeProcessor #2463")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2483"}},[_v("Standardise NodeProcessor.data.ts constant names #2483")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2511"}},[_v("Implement method to process attributes that can be overridden by slots #2511")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Authored PR (merged): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2513"}},[_v("Remove Overridden Question Attributes in Documentation #2513")])])]),_v(" "),_c('tr',[_c('td',[_v("Reading")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2525"}},[_v("Add tests for logger output when component attributes are overridden by slots #2525")])])]),_v(" "),_c('tr',[_c('td',[_v("Reading")]),_v(" "),_c('td',[_v("Authored PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2526"}},[_v("Add missing documentation for attributes overridden by slots #2526")])])])])])]),_c('h3',{attrs:{"id":"issues-raised-markbind"}},[_v("Issues Raised - MarkBind"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#issues-raised-markbind","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Raised Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2476"}},[_v("Add logger warnings when slots override attributes in NodeProcessor.ts #2476")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Raised Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2512"}},[_v("Overridden Attribute for Question in Documentation causes Logger Warnings and Build Failure #2512")])])]),_v(" "),_c('tr',[_c('td',[_v("Reading")]),_v(" "),_c('td',[_v("Raised Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2524"}},[_v("Tab-Group Header not displayed #2524")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"css-flexbox"}},[_v("CSS Flexbox"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#css-flexbox","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Flexbox is used to order, align and space out items in a one dimensional container (i.e. a row or a column), even when the size of the items are unknown or dynamic.")]),_v(" "),_c('p',[_v("Items can be given a default size ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-basis")]),_v("), and can also grow ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-grow")]),_v(") and shrink ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-shrink")]),_v(") according to the extra space in the container (or lack thereof). These three properties can be controlled with the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex")]),_v(" property, e.g.")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs css"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-selector-class"}},[_v(".item")]),_v(" {\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-attribute"}},[_v("flex")]),_v(": "),_c('span',{pre:true,attrs:{"class":"hljs-number"}},[_v("0")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-number"}},[_v("1")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-number"}},[_v("10%")]),_v("\n")]),_c('span',[_v("}\n")])])]),_c('p',[_v("where the three parameters correspond to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-grow")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-shrink")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-basis")]),_v(" respectively. In this case, the default width of the item is 10% of the width of the container, and it does not grow nor shrink relative to the other items (assuming the other items also have their "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex")]),_v(" property set to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("0 1 auto")]),_v(").")]),_v(" "),_c('p',[_v("The "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("flex-basis")]),_v(" property can also be set to the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("content")]),_v(" keyword, where the width of the item is based on the content within the item (e.g. if it contains text, then the width of the item is the length of the text string). This allows for dynamically sized items within the container, which may enable the layout to look cleaner.")]),_v(" "),_c('p',[_v("For a helpful summary of flexbox properties, visit "),_c('a',{attrs:{"href":"https://css-tricks.com/snippets/css/a-guide-to-flexbox/"}},[_v("https://css-tricks.com/snippets/css/a-guide-to-flexbox/")])]),_v(" "),_c('h3',{attrs:{"id":"prettier-husky-and-pretty-quick"}},[_v("Prettier, husky and pretty-quick"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#prettier-husky-and-pretty-quick","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Prettier is a tool to format code according to a given code style automatically. Unlike a linter such as TSLint, prettier only cares about formatting, rather than detecting programming errors. Prettier supports both Typescript and Angular, which CATcher is written in.")]),_v(" "),_c('p',[_v("Since it is quite wasteful to run prettier to format the entire codebase every time a change is made, so a more efficient method is to format the codebase once, and then format only the changes made during each commit.")]),_v(" "),_c('p',[_v("This is where the husky tool comes in, which enables hooks to be run before each commit. The relevant hook here is pretty-quick, and this formats the changed/staged files during each commit. This frees developers from having to fuss with maintaining code formatting or fixing formatting mistakes, leading to less frustration.")]),_v(" "),_c('p',[_v("For more information, visit "),_c('a',{attrs:{"href":"https://prettier.io"}},[_v("Prettier")]),_v(" and "),_c('a',{attrs:{"href":"https://typicode.github.io/husky/"}},[_v("husky")])]),_v(" "),_c('h3',{attrs:{"id":"arcsecond"}},[_v("Arcsecond"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#arcsecond","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://github.com/francisrstokes/arcsecond"}},[_v("Arcsecond")]),_v(" is a zero-dependency parser combinator library for Javascript that is now being used in CATcher to parse GitGub issues and comments.")]),_v(" "),_c('p',[_v("Previously in order to parse the comments, we used the regex string "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("(${headerString})\\\\s+([\\\\s\\\\S]*?)(?=${headerString}|$)\\gi")]),_v(" which is neither human readable nor maintainable. In addition, this string only finds matches - more regex is used to extract relevant information from the comments.")]),_v(" "),_c('p',[_v("In comparison, arcsecond offers human friendly parsers such as "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("str")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("char")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("letters")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("digits")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("between")]),_v(" and so on, and these parsers can be composed and run in sequence. This makes building and maintaining parsers much easier. In addition, arcsecond also allows you to extract certain information from a string (as opposed to the entire string) by way of the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("coroutine")]),_v(" parser.")]),_v(" "),_c('p',[_v("For example, take the string \"Today is Wednesday and the weather is 30 degrees Celsius\", and you want to extract the day (Wednesday) and the temperature (30). One parser that can achieve that is:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs typescript"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("const")]),_v(" dayWeatherParser = coroutine("),_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("function")]),_v("*("),_c('span',{pre:true,attrs:{"class":"hljs-params"}}),_v(") ")]),_v("{\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("yield")]),_v(" str("),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"Today is \"")]),_v("); "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// parse and ignore")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("const")]),_v(" day = "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("yield")]),_v(" letters; "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// parse 'Wednesday' and store")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("yield")]),_v(" str("),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\" and the weather is \"")]),_v("); "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// parse and ignore")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("const")]),_v(" temperature = "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("yield")]),_v(" digits; "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// parse '30' and store")]),_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("yield")]),_v(" str("),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\" degrees Celsius\"")]),_v("); "),_c('span',{pre:true,attrs:{"class":"hljs-comment"}},[_v("// parse and ignore")]),_v("\n")]),_c('span',[_v("\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("return")]),_v(" {\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-attr"}},[_v("day")]),_v(": day,\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-attr"}},[_v("temperature")]),_v(": temperature\n")]),_c('span',[_v(" }\n")]),_c('span',[_v("})\n")])])]),_c('p',[_v("This allows us to build complex and versatile parsers easily, yet in a way that is clear and understandable. For more information, check out the "),_c('a',{attrs:{"href":"https://github.com/francisrstokes/arcsecond/blob/master/tutorial/tutorial-part-1.md"}},[_v("tutorial here")])]),_v(" "),_c('h3',{attrs:{"id":"jasmine"}},[_v("Jasmine"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#jasmine","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://jasmine.github.io/"}},[_v("Jasmine")]),_v(" is a testing framework for Javascript code. In Jasmine, test suites are functions in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("describe")]),_v(" blocks, and each spec is also a function in an "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("it")]),_v(" block.")]),_v(" "),_c('p',[_v("For example, here is a suite that tests a certain function:")]),_v(" "),_c('pre',[_c('code',{pre:true,attrs:{"class":"hljs typescript"}},[_c('span',[_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("function")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-title"}},[_v("testMethod")]),_v("("),_c('span',{pre:true,attrs:{"class":"hljs-params"}}),_v(") ")]),_v("{\n")]),_c('span',[_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-keyword"}},[_v("return")]),_v(" "),_c('span',{pre:true,attrs:{"class":"hljs-literal"}},[_v("true")]),_v(";\n")]),_c('span',[_v("}\n")]),_c('span',[_v("\n")]),_c('span',[_v("describe("),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"testMethod suite\"")]),_v(", "),_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_v("() =>")]),_v(" {\n")]),_c('span',[_v(" it("),_c('span',{pre:true,attrs:{"class":"hljs-string"}},[_v("\"testMethod should return true\"")]),_v(", "),_c('span',{pre:true,attrs:{"class":"hljs-function"}},[_v("() =>")]),_v(" {\n")]),_c('span',[_v(" expect(testMethod()).toBe("),_c('span',{pre:true,attrs:{"class":"hljs-literal"}},[_v("true")]),_v(");\n")]),_c('span',[_v(" });\n")]),_c('span',[_v("});\n")])])]),_c('p',[_v("Expectations are built with the function "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("expect")]),_v(" which takes a value ("),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("testMethod()")]),_v(" in the example above), and is chained with a "),_c('a',{attrs:{"href":"https://jasmine.github.io/api/edge/matchers.html"}},[_v("Matcher")]),_v(" such as "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("toBe")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("toEqual")]),_v(" or "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("toBeGreaterThan")]),_v(". This provides greater flexibility than say JUnit's assert methods, since one assert method corresponds to one condition.")]),_v(" "),_c('p',[_v("Since test suites and specs are functions, normal Javascript scoping rules apply, so variables can be shared between specs. In addition, there are separate setup and teardown methods such as "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("beforeEach")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("afterAll")]),_v(".")]),_v(" "),_c('p',[_v("For more information, check out the "),_c('a',{attrs:{"href":"https://jasmine.github.io/tutorials/your_first_suite"}},[_v("Your First Suite tutorial here")])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-foo"}},[_v("Project: Foo"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-foo","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give an intro to the project here ...")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-2"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give a description of your contributions, including links to relevant PRs")]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-2"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give tools/technologies you learned here. Include resources you used, and a brief summary of the resource.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"vignesh-sankar-iyer"}},[_v("VIGNESH SANKAR IYER"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vignesh-sankar-iyer","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/vigneshsankariyer1234567890/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/vigneshsankariyer1234567890"}},[_v("https://github.com/vigneshsankariyer1234567890")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")]),_v(",\n"),_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel"}},[_v("Zitadel")]),_v(",\n"),_c('a',{attrs:{"href":"https://github.com/a-h/templ"}},[_v("Templ")]),_v(",\n"),_c('a',{attrs:{"href":"https://github.com/FerretDB/FerretDB"}},[_v("FerretDB")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h1',{attrs:{"id":"cs3282-progress-3"}},[_v("CS3282 Progress"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282-progress-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h2',{attrs:{"id":"summary-2"}},[_v("Summary"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#summary-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Reviewed some PRs of CS3281 students and external contributors")]),_v(" "),_c('li',[_v("In-person guidance with CS3281 mentees over telegram")]),_v(" "),_c('li',[_v("Created PRs and Issues in external projects:\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel"}},[_v("Zitadel")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/a-h/templ"}},[_v("Templ")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/FerretDB/FerretDB"}},[_v("FerretDB")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/xserrat/docker-facebook-demucs"}},[_v("Facebook Demucs")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/u2takey/ffmpeg-go"}},[_v("ffmpeg-go")])])])])]),_v(" "),_c('h3',{attrs:{"id":"catcher-2"}},[_v("CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#catcher-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("4 July 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1202"}},[_v("Specify node version in package.json")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("12 Oct 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1215"}},[_v("Fetch settings json directly without api")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("14 Oct 2023")]),_v(" "),_c('td',[_v("Version Release")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1219"}},[_v("v3.5.1")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("4 Mar 2024")]),_v(" "),_c('td',[_v("Version Release")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1252"}},[_v("v3.5.3")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("4 Mar 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1249"}},[_v("Upgrade to Angular 13")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"watcher"}},[_v("WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#watcher","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("19 Sep 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/193"}},[_v("Improve efficiency of saving and deleting issue models")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("28 Oct 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/207"}},[_v("Add Issues Dashboard access by URL")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("20 Feb 2024")]),_v(" "),_c('td',[_v("Issue Contributor")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/issues/249"}},[_v("Refactor filters into own service")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("20 Feb 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/259"}},[_v("Refactor certain filters into its own service #259")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("22 Feb 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/261"}},[_v("Refactor sorting")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("28 Feb 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/264"}},[_v("Refactor milestone filters")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("4 March 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/265"}},[_v("Refactor title filter")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("14 March 2024")]),_v(" "),_c('td',[_v("Version Release")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/279"}},[_v("Create version for v1.1.1")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("18 March 2024")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/285"}},[_v("Release changelog automation")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"zitadel"}},[_v("Zitadel"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#zitadel","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("15 Mar 2024")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel/pull/7579"}},[_v("fix: Incorrect button positioning on email verification")])]),_v(" "),_c('td',[_v("Fixed template HTML template issue")])]),_v(" "),_c('tr',[_c('td',[_v("3 Apr 2024")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel/pull/7683"}},[_v("fix: Update url to redirect to name change url")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"templ"}},[_v("Templ"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#templ","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("4 Apr 2024")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/a-h/templ/pull/666"}},[_v("docs: Create documentation and examples for Internationalization")])]),_v(" "),_c('td',[_v("Created SSR page with simple Go server using Templ, Echo, HTMX")])])])])]),_c('h3',{attrs:{"id":"ferretdb"}},[_v("FerretDB"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ferretdb","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("3 Apr 2024")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/FerretDB/FerretDB/pull/4219"}},[_v("Add local Changelog generation based on PR titles and labels")])]),_v(" "),_c('td',[_v("Created customised Changelog that queries GitHub API, loads a Changelog template based on GitHub's own Changelog template, groups PRs by labels and renders to stdout")])])])])]),_c('h3',{attrs:{"id":"facebook-demucs"}},[_v("Facebook Demucs"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#facebook-demucs","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("13 Mar 2024")]),_v(" "),_c('td',[_v("Issue Contributor")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/xserrat/docker-facebook-demucs/issues/38"}},[_v("Enhancement: Ensure image runs without dropping into a shell to run the demucs command")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"ffmpeg-go"}},[_v("ffmpeg-go"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ffmpeg-go","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("13 Mar 2024")]),_v(" "),_c('td',[_v("Issue Contributor")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/u2takey/ffmpeg-go/issues/112"}},[_v("[Enhancement] Migrate to aws-sdk-go-v2")])]),_v(" "),_c('td')])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"angular"}},[_v("Angular"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Having had experience in mainly React and NodeJS projects earlier, I was overall more used to creating projects with Functional Components, rather than Class Components as with Angular. However, I realised that one of the key aspects of frontend frameworks, namely reactivity, was in fact the main drivers of development of such frameworks in the first place!")]),_v(" "),_c('p',[_v("In fact, even React were originally championing the idea of Class Components in order to isolate various web components into areas or responsibility, following rule number 1 of Software Engineering: Single Responsibility. However, while React is largely unopinionated in how you structure your code with regards to the coupling of business logic and HTML, Angular differs by dictating where and how you structure your components.")]),_v(" "),_c('p',[_v("Angular separates components into modules which comprise of 3 to 4 files:")]),_v(" "),_c('ul',[_c('li',[_v("Components, which are necessarily TypeScript classes which have the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("@Component")]),_v(" decorator;")]),_v(" "),_c('li',[_v("Templates, which dictate the HTML that is produced and rendered by the component;")]),_v(" "),_c('li',[_v("Styles, which dictate the type of styling to apply to the component.")]),_v(" "),_c('li',[_v("Module, which indicate the modules or services that are to be imported by the component. Interestingly,")])]),_v(" "),_c('p',[_v("On the other hand, React only dictates that class components should produce some sort of HTML using the render function. Even this is removed with the introduction of Functional Components that are simply functions which render and produce some HTML. React introduces hooks which are often used by developers to manage some state at the component level, using functions with side effects.")]),_v(" "),_c('p',[_v("Each method has its positives and negatives. Because of its opinionated nature, Angular makes it easy to standardize frontend coding standards and pattern across an entire enterprise, making it an apt choice to use as a tool for OSS development. On the other hand, React allows you to develop code more quickly, with more attention needed to be paid at the rendering lifecycles in order to let the Virtual DOM know when a particular component needs to be rendered again. On top of this, Angular wholely separates business logic from rendered HTML, whereas React takes the does not make this distinction.")]),_v(" "),_c('p',[_v("Another key point is how React and Angular differentiate in providing context (sharing or passing down state between different branches of the DOM tree). React has its own Context API that is used to share some sort of state between different components, whereas Angular does this by the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("providers")]),_v(" declaration in the module folder, which results in a set of singletons that are shared by components that exist below it in the tree.")]),_v(" "),_c('h3',{attrs:{"id":"rxjs"}},[_v("RxJS"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#rxjs","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I also picked up RxJS along the way, which was Angular's answer to creating reactive components. RxJS essentially deals with asynchronous pipe/filter, publisher/subscriber behavior which allows values to change and other components or functions to subscribe to these changes. This works considering Angular's Change Detection strategy which I will explain later.")]),_v(" "),_c('p',[_v("In comparison, React introduced and adopted hooks to encapsulate the behavior of having to rerender. React does this by operating on a Virtual DOM, and appropriately rerendering components and their children in patches when a change was detected. On the other hand, Angular does not have any abstraction to operate and rerender components whose state have changed. Instead, Angular uses a Change Detection Strategy which can be configured by the user (either onPush or Default). Angular Change Detection works by using Zone.js and activating after every async action performed. CD traversal starts at the root component (usually App) and works its way down the component tree updating the DOM as needed. What's happening under the hood is that browser events are registered into Zone.js - Angular's mechanism for orchestrating async events - which emits changes after initial template bindings are created.\n...")])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-zitadel"}},[_v("Project: Zitadel"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-zitadel","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Zitadel is an open source user management tool that aims to provide easy identity infrastructure, with out-of-the-box features such as")]),_v(" "),_c('ul',[_c('li',[_v("Multi-tenancy with team management")]),_v(" "),_c('li',[_v("Secure Login")]),_v(" "),_c('li',[_v("Self-service")]),_v(" "),_c('li',[_v("OpenID Connect")]),_v(" "),_c('li',[_v("SAML2")]),_v(" "),_c('li',[_v("LDAP")])]),_v(" "),_c('p',[_v("and more solutions. It provides easy integration with oAuth providers such as GitHub, Facebook, O365 and serves as an easy way for enterprises to set up multi-tenancy identity providers with clear separation of identities. Zitadel is written in Go and consists of an interesting mix of server-side rendered authentication (using Go and HTML templates), along with a client side application written in Angular, as well as modularised Core library that uses Event-driven architecture to ensure that all events are not only captured but also traceable.")]),_v(" "),_c('p',[_v("The team favours transaction safety, with high availability, and have employed and implemented it's own message queue system. It works by placing events into an in-memory queue for subscribers, under the pub-sub model.")]),_v(" "),_c('p',[_v("Zitadel has 7.1k stars and is used by many organisations as an alternative to other identity infrastructure platforms, due to it's heavy customisability in terms of branding and deployment options.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-3"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Fixed button positioning issues on email verification screen within the Login page "),_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel/pull/7579"}},[_v("PR #7579")])]),_v(" "),_c('li',[_v("Fixed navigation issues where users would be directed incorrectly to another page when clicking on \"Back\" "),_c('a',{attrs:{"href":"https://github.com/zitadel/zitadel/pull/7683"}},[_v("PR #7683")])])]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-3"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Deploying both an Angular console application, which is a management interface, as well as Server side pages for authentication (Login, Register and Password Reset pages) were important. Particularly, Zitadel uses HTML templates heavily along with a flexible component system that enables easy internationalisation, which is important for a tool like Zitadel that everyone can use.")]),_v(" "),_c('p',[_v("Also, learning about gRPC through interactions with the backend was also enlightening as I was more familiar with GraphQL and traditional HTTP endpoints through my experience with CATcher/WATcher and personal projects and internships.")]),_v(" "),_c('p',[_v("gRPC uses Protocol Buffers (protobufs) by default, which is a lightweight, highly efficient serialization tool; which serves it's purpose when building a distributed application like Zitadel. It also allows for server-side and client-side streaming, both of which are used (particularly for event logging) in Zitadel.")]),_v(" "),_c('h3',{attrs:{"id":"project-templ"}},[_v("Project: Templ"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-templ","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Templ is a HTML templating language for Go that has great developer tooling, including an LSP (Language Server Protocol) for Vim users and extension for VSCode users. With Templ, we can create components that render fragments of HTML and then compose them to create screens, pages, documents or apps.")]),_v(" "),_c('p',[_v("This allows for")]),_v(" "),_c('ul',[_c('li',[_v("Server-side rendering (deployed as a serverless function or standard Go program)")]),_v(" "),_c('li',[_v("Static rendering (create static HTML files to deploy how you choose)")]),_v(" "),_c('li',[_v("Compiled code (components compiled to performant Go code)")]),_v(" "),_c('li',[_v("Ability to move away from JavaScript in client-side and server-side contexts")])]),_v(" "),_c('p',[_v("Templ borrows heavily from the Component model in React and Angular, and as such models it's own components as mark up and code that is compiled into functions that return a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("templ.Component")]),_v(" interface.")]),_v(" "),_c('p',[_v("This allows for Templ to be used in tandem with htmx, to selectively replace content within a webpage instead of replacing the whole web page within the browser.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-4"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Add documentation for using Templ with i18n by using "),_c('a',{attrs:{"href":"https://github.com/invopop/ctxi18n"}},[_v("ctxi18n")]),_v(": "),_c('a',{attrs:{"href":"https://github.com/a-h/templ/pull/666"}},[_v("PR #666")])])]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-4"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt how to build an SSR application using Go, HTMX and Templ by building an example application to provide documentation for i18n support. I also used Server-side Events which enabled minified HTMX runtime to add elements based on the component that was received on the stream endpoint. I also understood how i18n was generally implemented on products with a need to support a variety of languages, as well as building generalised components that decoupled the actual components from the textual UI.")]),_v(" "),_c('h3',{attrs:{"id":"project-ferretdb"}},[_v("Project: FerretDB"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-ferretdb","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("FerretDB was founded to become the de-facto open-source substitute to MongoDB. FerretDB is an open-source proxy, converting the MongoDB 5.0+ wire protocol queries to SQL - using PostgreSQL or SQLite as a database engine.")]),_v(" "),_c('p',[_v("MongoDB was originally the eye-opening technology for developers that allowed developers to build applications faster than using relational databases. However, with MongoDB abandoning its open-source roots, there was a need for an easy-to-use open-source document database solution, which is what FerretDB aims to fill.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-5"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-5","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Add local changelog generation that uses a milestone title to generate the batch of changes for the milestone "),_c('a',{attrs:{"href":"https://github.com/FerretDB/FerretDB/pull/4219"}},[_v("PR #4219")])])]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-5"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-5","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("While I did not learn much about the database design in itself, I learnt about Conventional Commits: a standardised format that dictates how developers should write their commit messages. Conventional commits allowed for projects with a large developer base to have visibility and transparency over who did what, when. Furthermore, the standardisation allows for easy automatic changelog generation, important for when products are shipped out to actual users; as well as making it easier for people to contribute to projects.")]),_v(" "),_c('p',[_v("FerretDB suffered from the lack of implementation of Conventional Commits: without it, it was dependent on the platform (GitHub) the repository was hosted on to actually generate meaningful Changelogs. This added additional dependencies that tied the project with GitHub unnecessarily, instead of allowing the project to be independent of the Git versioning platform it was hosted on (GitLab, BitBucket are suitable alternatives).")]),_v(" "),_c('p',[_v("As such, Changelog generation was originally done by using the GitHub workflow directly, which overly complicated the release process, necessitating for another way to locally generate the Changelog.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"wong-chee-hong"}},[_v("WONG CHEE HONG"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#wong-chee-hong","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/cheehongw/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/cheehongw"}},[_v("https://www.github.com/cheehongw")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher"}},[_v("CATcher")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h1',{attrs:{"id":"cs3282-progress-4"}},[_v("CS3282 Progress"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282-progress-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h2',{attrs:{"id":"summary-3"}},[_v("Summary"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#summary-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Reviewed PRs of CS3281 students and external contributors in CATcher and WATcher")]),_v(" "),_c('li',[_v("In-person guidance with CS3281 mentees over telegram")]),_v(" "),_c('li',[_v("Maintained and upgraded libraries in CATcher")]),_v(" "),_c('li',[_v("Created two PRs in external project - SourceAcademy")])]),_v(" "),_c('h2',{attrs:{"id":"before-semester-contributions"}},[_v("Before-semester contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#before-semester-contributions","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"catcher-3"}},[_v("CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#catcher-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("13 Jun 2023")]),_v(" "),_c('td',[_v("Mentor")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1191"}},[_v("Question: @angular/common version to use #1191")])]),_v(" "),_c('td',[_v("Provided guidance on how to resolve the issue")])]),_v(" "),_c('tr',[_c('td',[_v("12 Jun 2023")]),_v(" "),_c('td',[_v("PR author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1193"}},[_v("Fix peer dependencies #1193")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("19 Jul 2023")]),_v(" "),_c('td',[_v("Issue Reporter")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1204"}},[_v("Documentation for CATcher's parser #1204")])]),_v(" "),_c('td',[_v("Created issue to discuss documentation for CATcher's parser")])]),_v(" "),_c('tr',[_c('td',[_v("19 Sep 2023")]),_v(" "),_c('td',[_v("PR author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1203"}},[_v("Upgrade to Angular 11 #1203")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"watcher-2"}},[_v("WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#watcher-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("29 Jun 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/131"}},[_v("Detail page detail list #131")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("29 Jun 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/147"}},[_v("Add wrap for username in issues-viewer's card-view #147")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("29 Jun 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/149"}},[_v("Disable milestone filter if there are no milestones #149")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("29 Jun - 18 Jul")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/150"}},[_v("Add reset labels feature #150")])]),_v(" "),_c('td',[_v("Mentored PR author to improve code quality and readability")])]),_v(" "),_c('tr',[_c('td',[_v("30 Jun 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/151"}},[_v("Show loading spinner on switch repository #151")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("28 Oct 2023")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/215"}},[_v("Option to Limit Repository Access #215")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"catcher-4"}},[_v("CATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#catcher-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("Week 2")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1239"}},[_v("Uncaught error when invalid link is clicked #1239")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 4")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1234"}},[_v("Default branch to main #1234")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 4")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1242"}},[_v("Angular 12 #1242")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 5")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1243"}},[_v("Faulty list view when back navigating #1243")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 6")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1245"}},[_v("Fix markdown blockquote preview difference #1245")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 6")]),_v(" "),_c('td',[_v("Issue Reporter")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1247"}},[_v("Migrate to ESLint #1247")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 7")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1252"}},[_v("Create release 3.5.3 #1252")])]),_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1254"}},[_v("New release for 3.5.3 #1254")])])])]),_v(" "),_c('td',[_v("Assisted in the creation of new CATcher release")])]),_v(" "),_c('tr',[_c('td',[_v("Week 7 - 8")]),_v(" "),_c('td',[_v("Issue Reporter & PR Author")]),_v(" "),_c('td',[_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1248"}},[_v("Clean up dependencies #1248")])]),_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1244"}},[_v("Remove wait-on from devDep #1244")])]),_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1246"}},[_v("tslib unused #1246")])]),_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/issues/1253"}},[_v("Remove node-fetch as direct dependency #1253")])])])]),_v(" "),_c('td',[_v("Address neglected depenedencies in CATcher")])]),_v(" "),_c('tr',[_c('td',[_v("Week 11")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1240"}},[_v("Add documentation for CATcher's parser #1240")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 13")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1256"}},[_v("Add login redirect #1256")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_v("PR Reviewer & Co-author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1250"}},[_v("Migrate from TSLint to ESLint #1250")])]),_v(" "),_c('td',[_v("Had to step in to complete the PR")])]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1249"}},[_v("Upgrade to Angular 13 #1249")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/1275"}},[_v("Fix e2e regression caused by changes in AuthService #1275")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"watcher-3"}},[_v("WATcher"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#watcher-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("Week 4")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/235"}},[_v("Show list of hidden users #235")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 4")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/239"}},[_v("Build in Github Actions #239")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 5")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/250"}},[_v("Remove unused session-fix-confirmation component #250")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 5")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/253"}},[_v("Remove unused models #253")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Week 6")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/252"}},[_v("Upgrade to Angular 11 #252")])]),_v(" "),_c('td')]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("PR Reviewer")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/269"}},[_v("Fix zone testing import error #269")])]),_v(" "),_c('td')])])])]),_c('h3',{attrs:{"id":"external-project-sourceacademy"}},[_v("External Project - SourceAcademy"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#external-project-sourceacademy","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Date")]),_v(" "),_c('th',[_v("Role")]),_v(" "),_c('th',[_v("Description")]),_v(" "),_c('th',[_v("Key Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("Week 13")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/source-academy/frontend/pull/2943"}},[_v("Fix double window prompt when uploading users #2943")])]),_v(" "),_c('td',[_v("Fixed a bug")])]),_v(" "),_c('tr',[_c('td',[_v("Week 13")]),_v(" "),_c('td',[_v("PR Author")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/source-academy/frontend/pull/2946"}},[_v("i18n framework #2946")])]),_v(" "),_c('td',[_v("Laid the groundwork for internationalization in source academy")])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h1',{attrs:{"id":"cs3282"}},[_v("CS3282"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#cs3282","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This semester, I focused my efforts on trying to upgrade the outdated dependencies in CATcher. This was a challenging task as I had to understand the dependencies of the project. Even though the current state of the repository is not what I have hoped to achieve, I hope future devs reading this might find some insights on how to approach this task.")]),_v(" "),_c('h3',{attrs:{"id":"node-package-manager-npm-and-yarn"}},[_v("Node Package Manager (npm) and Yarn"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#node-package-manager-npm-and-yarn","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("From working with CATcher and SourceAcademy, I have gotten a more solid understanding of how package managers work. Before this, I only saw Node and npm as something we had to install before we can start developing our project. However, the fact is that package managers are a crucial aspect of any project, since they manage the dependencies of the project.")]),_v(" "),_c('h3',{attrs:{"id":"dependency-management"}},[_v("Dependency Management"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#dependency-management","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In CATcher, I focused on identifying the dependencies that needed to be updated. I learned that dependencies are managed in the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("package.json")]),_v(" file, and that the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("package-lock.json")]),_v(" file is used to lock the dependencies to a specific version. This is important as it ensures that the project is reproducible across different machines. Unfortunately, this is not used in CATcher, but i believe CATcher will benefit from using a lockfile in the future.")]),_v(" "),_c('h3',{attrs:{"id":"upgrading-dependencies"}},[_v("Upgrading Dependencies"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#upgrading-dependencies","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Beyond that, I have learnt how to use "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("npm outdated")]),_v(", "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("npm-check")]),_v(" etc to identify outdated dependencies. I also learnt how to use "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("npm ls")]),_v(" to print out the dependency tree of a given package. This was useful in identifying the dependencies that needed to be updated.")]),_v(" "),_c('p',[_v("Resources")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://docs.npmjs.com/cli/v6/commands/npm-outdated"}},[_v("https://docs.npmjs.com/cli/v6/commands/npm-outdated")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://www.npmjs.com/package/npm-check"}},[_v("https://www.npmjs.com/package/npm-check")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docs.npmjs.com/cli/v6/commands/npm-ls"}},[_v("https://docs.npmjs.com/cli/v6/commands/npm-ls")])]),_v(" "),_c('li')]),_v(" "),_c('h3',{attrs:{"id":"eslint-migration"}},[_v("ESLint migration"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#eslint-migration","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I also assisted with the tslint to eslint migration in CATcher. While initially a PR done by a mentee, I had to stay involved and understand the changes made as well. I had to understand how to configure eslint to work with the project. This was a challenging task, but I am glad that I managed to complete it.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://eslint.org/docs/user-guide/configuring"}},[_v("https://eslint.org/docs/user-guide/configuring")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/angular-eslint/angular-eslint/blob/main/docs/MIGRATING_FROM_TSLINT.md"}},[_v("https://github.com/angular-eslint/angular-eslint/blob/main/docs/MIGRATING_FROM_TSLINT.md")])])]),_v(" "),_c('h3',{attrs:{"id":"i18next"}},[_v("i18next"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#i18next","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Beyond work done in CATcher, I also worked on SourceAcademy, where I implemented an i18n framework. i18next is a powerful library that allows for easy translation of text in a project. During my implementation of the i18n framework in SourceAcademy, I referenced several implementations of i18n across various established open source repos such as HospitalRun and FreeCodeCamp for any best practices. From these references, I learned how to structure the i18n files and the various translation resources to make it easy for future translators to add on new translations.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://www.i18next.com/"}},[_v("https://www.i18next.com/")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://react.i18next.com/"}},[_v("https://react.i18next.com/")])])]),_v(" "),_c('h2',{attrs:{"id":"angular-essentials"}},[_v("Angular Essentials"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#angular-essentials","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I had contributed to CATcher as part of IWM, but I have never really approached the Angular aspects of the project.")]),_v(" "),_c('p',[_v("Essentially, the core ideas behind Angular involves:")]),_v(" "),_c('ul',[_c('li',[_v("Components, a TypeScript class with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("@Component")]),_v(" decorator, an HTML template and styles.\n"),_c('ul',[_c('li',[_v("The decorator accepts parameters that help Angular know which HTML file is the component's template and which css file is the component's styles.")]),_v(" "),_c('li',[_v("The decorator also accepts a parameter that is the component's selector, which is how we can reuse this component as an HTML element in other HTML files.")])])]),_v(" "),_c('li',[_v("An HTML template that instructs Angular how to render the component")]),_v(" "),_c('li',[_v("An optional set of CSS styles that define the appearance of the template's HTML elements")])]),_v(" "),_c('p',[_v("The other key concepts include event bindings and property binding that link the template to the TypeScript class. Knowing these essentials allowed me to fix "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/57"}},[_v("WATcher PR#57")]),_v(".")]),_v(" "),_c('p',[_v("Another key part of Angular is its Dependency Injection system and services. Angular allows us to provide dependencies at different levels of the application, and how the dependencies are instantiated.")]),_v(" "),_c('ul',[_c('li',[_v("For example, when you providing a service at the root level, Angular creates a single, shared instance of the service and injects it into any class that asks for it.")]),_v(" "),_c('li',[_v("Also, it seems like most of WATcher and CATcher's services are provided at the root level.")])]),_v(" "),_c('p',[_v("Finally, as part of fixing \""),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/92"}},[_v("Remove label-filter-bar as module export #92")]),_v("\", I also learned about how related components are organized and grouped into modules. Each Module are self-contained and provide a certain set of functionality and components related to that module, thereby achieving separation of concerns.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/what-is-angular"}},[_v("https://angular.io/guide/what-is-angular")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/dependency-injection"}},[_v("https://angular.io/guide/dependency-injection")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://angular.io/guide/ngmodules"}},[_v("https://angular.io/guide/ngmodules")])])]),_v(" "),_c('h2',{attrs:{"id":"e2e-testing-with-playwright"}},[_v("E2E Testing with Playwright"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#e2e-testing-with-playwright","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("After having 2 separate hotfixes pushed in a single semester, I started to look more deeply into ensuring the robustness of our application. During these 2 hotfixes, bugs were only uncovered during manual testing. However, it is time consuming to conduct manual tests, and we need to find a way to automate it. E2E tests simulate user interactions such as clicks and typing and is a useful way to ensure our end-product is performing as expected.")]),_v(" "),_c('p',[_v("During this semester, one of the high priority issues was to migrate our E2E solution away from Protractor. As such, I have investigated Cypress and Playwright as two potential E2E solutions.")]),_v(" "),_c('h4',{attrs:{"id":"mocking-services"}},[_v("Mocking services"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#mocking-services","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("When performing migration from Protractor to Playwright, I learned about the different strategies E2E tests can be conducted. Typically, we would want to conduct E2E tests against our production server, since that is what our end users will be using. However, since CATcher depends alot on GitHub's API for its functionality, we are unable to perform automated tests against GitHub. A second strategy would be to mock the functions that hit GitHub's API, and we would test solely the functionalities and behaviours of the app. This let me realized that there is a test vs production version of CATcher.")]),_v(" "),_c('p',[_v("I have also looked into whether it is possible to perform E2E testing against the production server, since one of the bugs fixed in the hotfixes can only be caught if we did not adopt a mocking strategy. One of the key feasibility concerns I had with testing against the GitHub API was simulating user authentication. This was because authenticating with GitHub requires multi-factor authentication, something that is difficult to achieve with automated E2E testing. Some potential solutions to bypassing MFA would be to use TOTP, which can be generated programmatically. More research will be needed in this area.")]),_v(" "),_c('h4',{attrs:{"id":"aspects-learnt"}},[_v("Aspects Learnt"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#aspects-learnt","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Configuring and setting up Playwright for a project.")]),_v(" "),_c('li',[_v("Learned about how Playwright/Cypress/Protractor identifies and interacts with HTML elements using selectors.")]),_v(" "),_c('li',[_v("Learned about how CATcher API calls are mocked during E2E testing")])]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://playwright.dev"}},[_v("https://playwright.dev")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://www.cypress.io/"}},[_v("https://www.cypress.io/")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/CATcher-org/CATcher/pull/539"}},[_v("This pull request by ptvrajsk documenting how he implemented E2E with Protractor")])])]),_v(" "),_c('h2',{attrs:{"id":"github-actions"}},[_v("Github Actions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#github-actions","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I also picked up Github Actions when contributing to the CI/CD pipeline in "),_c('a',{attrs:{"href":"https://github.com/CATcher-org/WATcher/pull/81"}},[_v("Enable linting in Github workflow #81")]),_v(". I learned how Github Actions are set up and how they can be triggered upon pushing to main/master and also on pull requests.")]),_v(" "),_c('p',[_v("Furthermore, I learnt how we can use matrix strategies to run the same job with different parameters, such as different OS and different node versions.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://docs.github.com/en/actions/quickstart"}},[_v("https://docs.github.com/en/actions/quickstart")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs"}},[_v("https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs")])])]),_v(" "),_c('h2',{attrs:{"id":"rxjs-and-the-observer-pattern"}},[_v("RxJS and the Observer Pattern"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#rxjs-and-the-observer-pattern","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Part of working with CATcher source code was frequently encountering Observables and Observers. RxJS supports "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Observers")]),_v(" and "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Observables")]),_v(", allowing updates to some "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Observable")]),_v(" to be received by some "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Observer")]),_v(" that is subscribed to it. With this pattern, we can trigger updates in many dependent objects automatically and asynchronously when some object state changes.")]),_v(" "),_c('p',[_v("Resources:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://rxjs.dev/"}},[_v("https://rxjs.dev/")])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-sourceacademy-frontend"}},[_v("Project: SourceAcademy Frontend"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-sourceacademy-frontend","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Sourceacademy is the an online experiential environment used for teaching students computational thinking and is used by the School of Computing in NUS and Uppsala University in Sweden to teach introductory programming modules. The frontend is built using React and Redux.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-6"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-6","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In this project, I have authored and merged two PRs. They are listed as follows:")]),_v(" "),_c('ul',[_c('li',[_c('p',[_c('a',{attrs:{"href":"https://github.com/source-academy/frontend/pull/2943"}},[_v("Fix double window prompt when uploading users #2943")])]),_v(" "),_c('p',[_v("In this PR, I fixed a long standing bug regarding the UI where two file prompts show up upon clicking a \"upload csv\" button. To solve this, I first reproduced the issue on my local development environment, and then identified the issue, which happened to be the incorrect use of a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("")]),_v(" react component within a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("")]),_v(" component. The components were imported from a "),_c('a',{attrs:{"href":"https://blueprintjs.com/"}},[_v("theming library")]),_v(" and a "),_c('a',{attrs:{"href":"https://www.papaparse.com/"}},[_v("CSV parser library")]),_v(" respectively.")])]),_v(" "),_c('li',[_c('p',[_c('a',{attrs:{"href":"https://github.com/source-academy/frontend/pull/2946"}},[_v("i18n framework #2946")])]),_v(" "),_c('p',[_v("In this PR, I laid the groundwork for future internationalization work to be done on SourceAcademy. SourceAcademy started out as a project in NUS but has plans to go international, as seen by its use in Uppsala university in Sweden. As such, adding i18n to the project will be crucial for its future.")]),_v(" "),_c('p',[_v("In this PR, I introduced the use of "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("react-i18next")]),_v(" library, as well as define data structures to allow future translators to easily add on new translations and languages.")])])]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-6"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-6","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('strong',[_v("React & Redux")])]),_v(" "),_c('p',[_v("Sourceacademy is built in React and Redux, and as such, I have had to learn how to work with these two libraries. While I have used React and Redux before, I have not seen how it can be used in a large scale project like Sourceacademy. In Sourceacademy, I have seen how Redux and Redux Toolkit was used to create a typesafe global state that is shared across the entire application and I appreciate how well structured the code was in the repository.")]),_v(" "),_c('p',[_c('strong',[_v("i18next")])]),_v(" "),_c('p',[_v("i18next is a library that allows for internationalization in a React project. It is a powerful library that allows for easy translation of text in a project. During my implementation of the i18n framework in Sourceacademy, I referenced several implementations of i18n across various established open source repos such as HospitalRun and FreeCodeCamp for any best practices. From these references, I learned how to structure the i18n files and the various translation resources to make it easy for future translators to add on new translations.")]),_v(" "),_c('p',[_v("Furthermore, the i18n framework that I contributed to has strong type safety and only allows keys that are defined in the translation files to be used, making it easier for future developers to see what keys are allowed on what file. I am grateful for the Sourceacademy maintainers for their guidance in this implementation.")]),_v(" "),_c('p',[_c('strong',[_v("Practices and tools from SourceAcademy that could be adopted by CATcher")])]),_v(" "),_c('p',[_v("SourceAcademy utilises Yarn as their package manager. From almost all points of view, yarn has the exact same functionality as npm, but it is faster and more reliable. As such, we could consider moving over to using Yarn in CATcher as well.")]),_v(" "),_c('p',[_v("Furthermore, I was particularly impressed with the testing framework that they had to ensure any new changes were not breaking. They made use of jest and had an interactive UI test runner that allowed the developer to see which tests were failing and why. This is something that CATcher could consider adopting as well.")])])])],1)],1),_v(" "),_m(10),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"chan-yu-cheng"}},[_v("CHAN YU CHENG"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#chan-yu-cheng","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/yucheng11122017/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/yucheng11122017"}},[_v("https://github.com/yucheng11122017")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/yucheng11122017/markbind"}},[_v("Markbind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h2',{attrs:{"id":"prs-i-wrote"}},[_v("PRs I wrote:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#prs-i-wrote","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Improvements to Annotation\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2388"}},[_v("Annotate support different labels #2388")]),_v(" "),_c('ul',[_c('li',[_v("Support slots for annotation which enables more flexible image for annotation point")])])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2427"}},[_v("Enable markdown for content, header and label in annotation point")]),_v(" "),_c('ul',[_c('li',[_v("Previously, annotation point did not support Markdown in content, header and label. Now, Markdown can be used providing more flexibility to the user.")])])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2436"}},[_v("Disable pop over in a-point if there is no header and content passed by user #2436")]),_v(" "),_c('ul',[_c('li',[_v("Fix bug where there is no header and content but there is still a popover, resulting in a small arrow pointing to nothing")])])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2375"}},[_v("Add horizontal spacing between the icon and text in the custom icon list #2352 #2375")]),_v(" "),_c('ul',[_c('li',[_v("Add i-spacing feature for customised list")])])])])]),_v(" "),_c('li',[_v("Release\n"),_c('ul',[_c('li',[_v("Did release for Markbind v5.3.0")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2455"}},[_v("Modify release documentation to add detailed instructions on permissions #2455")]),_v(" "),_c('ul',[_c('li',[_v("Due to some permission issues when doing the release, I created a PR to update the documentation with regards to permissions")])])])])]),_v(" "),_c('li',[_v("Customised lists\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2444"}},[_v("Add text for icon #2444")]),_v(" "),_c('ul',[_c('li',[_v("Added text attributes for customised icons")])])])])]),_v(" "),_c('li',[_v("Others\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2445"}},[_v("Optimize code printing #2445")]),_v(" "),_c('ul',[_c('li',[_v("Improve printing for code by making code light theme automatically when printing, removing code wrap and code copy buttons when printing, include code highlighting when printing")])])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2502"}},[_v("Ignore plantuml images for test sites #2502")]),_v(" "),_c('ul',[_c('li',[_v("Test sites previously only ignored plantuml images for test_site. This PR enables ignoring plantuml images for other test sites as well")])])])])])]),_v(" "),_c('p',[_v("PRs I guided/reviewed")]),_v(" "),_c('ul',[_c('li',[_v("Templates\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2398"}},[_v("MarkBind Template for Student Portfolio #2398")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v("MarkBind Template for Software Project Documentation #2400")])])])]),_v(" "),_c('li',[_v("DevOps\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2429"}},[_v("Utilize GitHub Actions to aid checking of commit message #2429")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2470"}},[_v("Utilize GitHub Actions to check for SEMVER impact label #2470")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2484"}},[_v("Add a reminder when contributor is new to ping all contributor bot #2484")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2510"}},[_v("Improve security of GitHub Actions workflows #2510")])])])]),_v(" "),_c('li',[_v("Plugins\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446"}},[_v("Add dataTable plugin #2446")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2475"}},[_v("Add Mermaid Plugin #2475")])])])]),_v(" "),_c('li',[_v("Customised Lists\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2520"}},[_v("Support text-icons of lists #2520")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2454"}},[_v("Customizing list icons: give a way to apply to current item only #2454")])])])]),_v(" "),_c('li',[_v("Logging and testing\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2465"}},[_v("Efficient validation for intra-link with hash #2465")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2493"}},[_v("Rule based html validation against hydration #2493")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2483"}},[_v("Standardise NodeProcessor.data.ts constant names #2483")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2463"}},[_v("Test logger calls in tests for NodeProcessor #2463")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2506"}},[_v("Add warning for including empty segments or files in optional mode #2506")])])])])]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2388"}},[_v("Annotate support different labels #2388")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Discussed Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2370"}},[_v("Create specific instructions to enable PR preview for CS2103T tP users #2370")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2388"}},[_v("Annotate support different labels #2388")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Discussed Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2370"}},[_v("Create specific instructions to enable PR preview for CS2103T tP users #2370")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Discussed Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/659"}},[_v("Provide good examples of MarkBind usage #659")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2392"}},[_v("Correct broken UG external link #2392")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2389"}},[_v("Replacing default icon for conversion #2389")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2394"}},[_v("Use a more noticeable color for highlight words in fenced code #2393")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2395"}},[_v("Allow markbind serve to specify custom host #2395")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2427"}},[_v("Annotation content slot #2427")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2429"}},[_v("Utilize GitHub Actions to aid checking of commit message #2429")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2429"}},[_v("Utilize GitHub Actions to aid checking of commit message #2429")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Released Markbind v5.3.0")])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Opened Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2434"}},[_v("Add warning about npm permissions for release notes #2434")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2436"}},[_v("Disable pop over in a-point if there is no header and content passed by user #2436")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Researched on Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2367"}},[_v("Re-introduce lazy loading for pictures #2367")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2431"}},[_v("Add line-numbers when wrapping is needed for printing #2431")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2436"}},[_v("Disable pop over in a-point if there is no header and content passed by user #2436")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2425"}},[_v("Migrate stylelint to latest version #2292 #2425")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2431"}},[_v("Add line-numbers when wrapping is needed for printing #2431")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2443"}},[_v("Add pageNav to Reader-Facing Features #2443")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2441"}},[_v("Debug cannot import footnote from hash #2441")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Researched issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2343"}},[_v("Support multiple levels in top navbar #2343")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2445"}},[_v("Fix print code highlight #2445")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2444"}},[_v("Add text for icon #2444")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Contributed to PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2375"}},[_v("Add horizontal spacing between the icon and text in the custom icon list #2352 #2375")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446"}},[_v("Add SortableTable plugin #2446")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v("MarkBind Template for Software Project Documentation #2400")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2453"}},[_v("Add keeping fork up to date section in DG #2453")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Discussed Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1616"}},[_v("[cs2103 website] Some top-nav menu items are not highlighted when visited #1616")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2375"}},[_v("Add horizontal spacing between the icon and text in the custom icon list #2352 #2375")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2454"}},[_v("Customizing list icons: give a way to apply to current item only #2454")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Discussed issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2140"}},[_v("Utilize GitHub Action to aid PR review #2140")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Opened issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2455"}},[_v("Automate all-contributors bot #2457")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2463"}},[_v("Test logger calls in tests for NodeProcessor #2463")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Opened issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2467"}},[_v("Add documentation about npm unlink in DG #2467")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2463"}},[_v("Test logger calls in tests for NodeProcessor #2463")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2470"}},[_v("Utilize GitHub Actions to check for SEMVER impact label #2470")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2455"}},[_v("Modify release documentation to add detailed instructions on permissions #2455")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2445"}},[_v("Optimize code printing #2445")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2444"}},[_v("Add text for icon #2444")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2472"}},[_v("Add the announcement component #2472")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2474"}},[_v("Set global variables using nunjucks syntax #2474")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2477"}},[_v("Add pagefind #2477")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2484"}},[_v("Add a reminder when contributor is new to ping all contributor bot #2484")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2487"}},[_v("Fix imported modal button position off #2487")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2492"}},[_v("Defer scripts in page template #2492")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2493"}},[_v("Rule based html validation against hydration #2493")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2494"}},[_v("Support Bootstrap icons #2494")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Opened PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2502"}},[_v("Ignore plantuml images for test sites #2502")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Discussed Issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2490"}},[_v("text-icons of lists: give a way to auto-increment #2490")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2502"}},[_v("Ignore plantuml images for test sites #2502")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2520"}},[_v("Support text-icons of lists #2520")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2514"}},[_v("UG: images appear in two places #2514")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2510"}},[_v("Improve security of GitHub Actions workflows #2510")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2507"}},[_v("Add note on absolute links #2507")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2506"}},[_v("Add warning for including empty segments or files in optional mode #2506")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2501"}},[_v("Change seamless panels to inherit any parent's colours #2501")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2484"}},[_v("Add a reminder when contributor is new to ping all contributor bot #2484")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"vue"}},[_v("Vue"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"vue-components"}},[_v("Vue components"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-components","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Since Markbind uses Vue components, I had to pick this up, having only experience with React before. I had to learn what is a Vue instance, how to compile Vue and so on.\nResources I used included the Markbind dev page regarding "),_c('a',{attrs:{"href":"https://markbind.org/devdocs/devGuide/design/serverSideRendering.html"}},[_v("SSR")]),_v(" of course, the "),_c('a',{attrs:{"href":"https://vuejs.org/guide/introduction.html"}},[_v("Vue Official Documentation")]),_v(" and "),_c('a',{attrs:{"href":"https://markbind.org/devdocs/devGuide/design/serverSideRendering.html"}},[_v("another Vue tutorial")]),_v(".\nThis was especially useful when dealing with Vue templates in one of my PRs about jQuery, which logged an warning since there was a script tag in the template. I had to learn about side effects in Vue from resources such as this "),_c('a',{attrs:{"href":"https://github.com/vuejs/vue/issues/11697"}},[_v("stackflow post")]),_v(" about Vue disallowing side effects for not just script tags but also style tags.")]),_v(" "),_c('p',[_v("####"),_c('mark',[_v("Vue slots and named slots")])]),_v(" "),_c('p',[_v("I also learnt about Vue slots and named slots and what is the difference. I was confused about how to enable more dynamic content for content in annotation point, which had to enable more than one slot hence needed to learn about named slots to enable multiple slots to be used. I referred to tutorials "),_c('a',{attrs:{"href":"https://blog.logrocket.com/understanding-slots-vue-js/#working-multiple-named-slots"}},[_v("here")]),_v(" and "),_c('a',{attrs:{"href":"https://vuejs.org/guide/components/slots.html"}},[_v("here")])]),_v(" "),_c('h4',{attrs:{"id":"vue-test-utils"}},[_v("Vue test utils"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-test-utils","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Since every new feature in Markbind required unit testing, I had to create unit tests for the scroll top button component. Therefore, I had to learn how to use Vue Test Utils and its snapshots.\nI had to learn how to")]),_v(" "),_c('ul',[_c('li',[_v("deal with setTimeout. This was probably the hardest part as trying to mock the setTimeout (following this "),_c('a',{attrs:{"href":"https://stackoverflow.com/questions/67981140/how-to-test-settimeout-function-calld-in-vue-created-hook-using-vue-utils-jes"}},[_v("tutorial")]),_v(") and using nextTick (using this "),_c('a',{attrs:{"href":"https://dmitripavlutin.com/vue-next-tick/"}},[_v("tutorial")]),_v(") on Vue test did not work. I had to resort to using setTimeout in the test to wait out the setTimeout in the component.")]),_v(" "),_c('li',[_v("mount components with props and attached to a document")]),_v(" "),_c('li',[_v("dispatch events to trigger the scroll event needed for the scroll top button component")]),_v(" "),_c('li',[_v("test if a function has been called")])]),_v(" "),_c('h4',{attrs:{"id":"vue-test-utils-mount-vs-shallow-mount"}},[_c('mark',[_v("Vue test utils: Mount vs shallow mount")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-test-utils-mount-vs-shallow-mount","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("When writing test cases for my PR, I had to investigate the differences between mount and shallow mount. The idea is that the mount function renders all child and parent components in a DOM. In contrast, the shallowMount does not render the child components and only adds the parent component. Hence, mount offers a more mocked environment. This information was learnt from "),_c('a',{attrs:{"href":"https://reflect.run/articles/introduction-to-vue-test-utils/#:~:text=The%20mount%20function%20renders%20all,only%20adds%20the%20parent%20component"}},[_v("here")])]),_v(" "),_c('h4',{attrs:{"id":"custom-directives"}},[_c('mark',[_v("Custom directives")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#custom-directives","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Directives was used in the new plugins "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446"}},[_v("Datatable")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2475"}},[_v("Mermaid")]),_v(" to solve the issue about these diagrams not rendering in panels and modals. Hence, I learnt about Vue custom directives, which are basically objects that contain lifecycle hooks. This was used in both PRs to force the Datatable and Mermaid diagram to render even when within the panel or modal. I learnt about custom directives from "),_c('a',{attrs:{"href":"https://vuejs.org/guide/reusability/custom-directives"}},[_v("here")])]),_v(" "),_c('h3',{attrs:{"id":"jquery-cheerio-and-javascript-for-dom-manipulation"}},[_v("Jquery, Cheerio and Javascript for DOM manipulation"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#jquery-cheerio-and-javascript-for-dom-manipulation","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("As I had to write a plugin and remove jQuery, I became a lot more familiar with DOM manipulation using Cheerio, jQuery and vanilla Javascript. Since I had to remove jQuery from Markbind, this "),_c('a',{attrs:{"href":"https://youmightnotneedjquery.com/"}},[_v("page")]),_v(" was very useful for me to understand how to convert from jQuery to vanilla Javascript. I also learnt from the "),_c('a',{attrs:{"href":"https://api.jquery.com/"}},[_v("jQuery API documentation")]),_v(" about each functions' behavior, especially more advanced functions like wrap and on. Through this PR, I became more familiar with using vanilla Javascript for DOM manipulation as well. For example, how to create elements, add styling and scroll etc.\nBecause the contact form plugin required DOM manipulation, I used cheerio for this PR and learnt about its API calls. The "),_c('a',{attrs:{"href":"https://cheerio.js.org/"}},[_v("cheerio API documentation")]),_v(" was very helpful in my understanding of the calls.")]),_v(" "),_c('h3',{attrs:{"id":"css"}},[_v("CSS"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#css","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("As I worked on some front end bugs, I had to learn more about CSS. Specifically:")]),_v(" "),_c('ul',[_c('li',[_v("How styles override each other. The iconColor in bozes are not working in certain circumstances due to Bootstrap styling. Hence, I had to learn more about overriding in CSS styles. This "),_c('a',{attrs:{"href":"https://www.tutorialspoint.com/Rules-to-override-Style-Sheet-Rule-in-CSS"}},[_v("guide")]),_v(" was useful in teaching me about it and I also about the "),_c('a',{attrs:{"href":"https://www.w3schools.com/css/css_important.asp"}},[_v("important property in CSS")]),_v(" which was what was causing the bug")]),_v(" "),_c('li',[_v("Transitions. The panel transition had some errors with an abrupt transition, which was a bug regarding the CSS transitions. I learnt about how CSS transitions from 0 to the max-height, and if the max-height was not set correctly (in this case it did not include margins) there would be problems.")]),_v(" "),_c('li',[_v("CSS selectors. As I had to style the form plugin and also had to finish up a PR regarding standardising tab buttons, I learnt about CSS selectors used for styling, from selecting by tag to by descendents. This "),_c('a',{attrs:{"href":"http://web.simmons.edu/~grabiner/comm244/weekfour/selectors.html"}},[_v("guide")]),_v(" was useful for my learning")])]),_v(" "),_c('h4',{attrs:{"id":"vendor-prefixing"}},[_c('mark',[_v("Vendor prefixing")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vendor-prefixing","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I also learnt about vendor prefixing. This is basically where browser specific CSS were offered and hence the CSS was prefixed by certain identifiers that were unique to the browser.\nHowever, this also causes some issues since there is inconsistency between browsers. This was causing problems in my PR which aimed to optimize code printing but the behaviour was not consistent across machines and browsers. Hence I learnt about this "),_c('a',{attrs:{"href":"https://css-tricks.com/is-vendor-prefixing-dead/"}},[_v("here")]),_v(".")]),_v(" "),_c('h3',{attrs:{"id":"typescript-and-migration"}},[_v("Typescript and migration"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#typescript-and-migration","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("As I did a typescript migration, I learnt to code in it. Specifically")]),_v(" "),_c('ul',[_c('li',[_v("Different ways to import and export files and functions in Typescript, which differed significantly from Javascript. The "),_c('a',{attrs:{"href":"https://markbind.org/devdocs/devGuide/development/migratingToTypeScript.html#import-export-syntax-reference"}},[_v("Markbind documentation")]),_v(" on that was very useful in my understanding.")]),_v(" "),_c('li',[_v("Defining and importing types. I learnt that npm packages often defined interfaces for their packages, making it easier to convert.")])]),_v(" "),_c('p',[_v("I learnt about the simliarity index about github files. According to the typescript migration documentation, there was a need to have two seperate commits, one to rename and one to adapt. If both were done within one commit, the simliarity index would be below the threshold and the commit history would be lost. This is something that I would definitely take note of in the future when renaming files.")]),_v(" "),_c('p',[_v("I had to do a squash commit for the typescript migration. I learnt about the differences between rebasing vs merging through this "),_c('a',{attrs:{"href":"https://www.atlassian.com/git/tutorials/merging-vs-rebasing"}},[_v("article")]),_v(" and about the pros and cons and dos and don'ts for rebasing. I was encountering the problem where squashing the merge resulted in the PR containing the recent commits from the master branch. This taught me not to miz up merging and rebasing and just do one or the other.")]),_v(" "),_c('h3',{attrs:{"id":"github-actions-2"}},[_v("Github actions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#github-actions-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt how to configure Github actions as I had to upgrade node version from 14 to 16 in Markbind/markbind-action and to also remove some depreated syntaxes. I learnt about the workflow of github actions and it's purpose.\nI also had to learn how to test GitHub actions. I followed the tutorial in "),_c('a',{attrs:{"href":"https://markbind.org/devdocs/devGuide/githubActions/markbindAction.html"}},[_v("Markbind Dev Guide")]),_v(" on testing and also attempted to use VSCode Extension for Github Actions to test more effectively following this "),_c('a',{attrs:{"href":"https://github.blog/2023-03-28-announcing-the-github-actions-extension-for-vs-code/"}},[_v("tutorial")]),_v(".")]),_v(" "),_c('h4',{attrs:{"id":"attemping-to-write-a-github-action"}},[_c('mark',[_v("Attemping to write a Github action")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#attemping-to-write-a-github-action","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I attempted to do a PR which notifies the person who merged the PR if the author of the PR is a first-time contributor, and adds a comment to remind them to add them to the contributor list.")]),_v(" "),_c('p',[_v("While there was an existing package which checks if the user is a first-time contributor, I thought that there was some issues with their Github-action and hence attempted to fork and write "),_c('a',{attrs:{"href":"https://github.com/yucheng11122017/first-contribution-check-action"}},[_v("my own")]),_v(". Hence, I had to learn about the learning working of a github action and I also had to learn about the "),_c('a',{attrs:{"href":"https://docs.github.com/en/rest/actions?apiVersion=2022-11-28"}},[_v("Github API")]),_v(".")]),_v(" "),_c('p',[_v("Additionally, this Github action was rather difficult to test manually because one would need to create a new repo and contribute to it etc to check the workflow works. Hence I tried to write unit test cases for it. Therefore I learnt about "),_c('a',{attrs:{"href":"https://github.com/nock/nock"}},[_v("nock")]),_v(" library which was recommended to use for Github actions, which mocks the Github API. I also used this "),_c('a',{attrs:{"href":"https://akashrajpurohit.com/blog/integration-testing-in-javascript-with-jest-and-nock-a-beginners-guide/"}},[_v("tutorial")]),_v(".")]),_v(" "),_c('h4',{attrs:{"id":"github-action-security"}},[_c('mark',[_v("Github action security")]),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#github-action-security","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("A PR was also created to improve the "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2510"}},[_v("Github action security")]),_v(". Hence I learnt about the good practises in Github Action to enhance security. For example, using the SHA of the commit rather than the version number could prevent attacks. Specifying the permissions that a workflow has also improves security practises. I refered to some blogs that the author of the PR specified "),_c('a',{attrs:{"href":"https://blog.gitguardian.com/github-actions-security-cheat-sheet/"}},[_v("here")]),_v(" and "),_c('a',{attrs:{"href":"https://dev.to/suzukishunsuke/secure-github-actions-by-pullrequesttarget-641"}},[_v("here")]),_v(".")]),_v(" "),_c('h3',{attrs:{"id":"nunjucks"}},[_v("Nunjucks"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#nunjucks","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt about Nunjucks when making documentation updates. Specifically, regarding Nunjucks Macros: how to declare them, write if statements and how to use them. The "),_c('a',{attrs:{"href":"https://mozilla.github.io/nunjucks/getting-started.html"}},[_v("documentation on Nunjucks")]),_v(" are particularly useful.")]),_v(" "),_c('h3',{attrs:{"id":"node-js-versioning"}},[_v("Node.js versioning"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#node-js-versioning","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt about Node.js versioning when upgrading the Node version and when writing the documentaiton on migrating Node js. For example, odd numbered Node.js versions are unstable and will reach end of life sooner, while even numbered Node.js version will be maintained for a longer period. I also learnt the difference between a major release and minor release, with the "),_c('tooltip',{scopedSlots:_u([{key:"content",fn:function(){return [_v("Eg. 1.0.0 to 2.0.0")]},proxy:true}])},[_v("former increasing the first number")]),_v(" and containing major and breaking changes, while the later has smaller changes which are not breaking.")],1),_v(" "),_c('h3',{attrs:{"id":"deployment"}},[_v("Deployment"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#deployment","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("For the node.js version upgrade, I had to check that the deployment was ok with the higher version. I therefore had to learn how to deploy the sites with github pages,CircleCi and Appveyor and Surge. I didn't do it with Travis due to a persistent account error. I followed the tutorial in the "),_c('a',{attrs:{"href":"https://markbind.org/userGuide/deployingTheSite.html"}},[_v("Markbind tutorial")]),_v(" to learn the deploying for each CI platform.")]),_v(" "),_c('h3',{attrs:{"id":"reuse-principle"}},[_v("Reuse principle"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#reuse-principle","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("There was an issue with Markdown using include within another include, because the outer variable was overriding the inner variable. This causes a cyclical reference error. I was told that this was inline with the golden principle of reuse, where inner variables should be allowed to override the inner variables so that components can be reused without having to change the inner contents.")]),_v(" "),_c('h3',{attrs:{"id":"documentation"}},[_v("Documentation"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#documentation","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt about the importance of good documentation and how to manage documentation. I think it is quite easy to keep adding things into documentation but it is more important to be able to present information in a way that is presentation and pallatable to users. For example, Markbind had an issue with cyclical references in includes and it would be good to document this. However, since it was an edge case, it was recommended to instead use a panel which was not as noticable so users could easily skip over it if not applicable to them.")]),_v(" "),_c('h3',{attrs:{"id":"project-management"}},[_v("Project management"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-management","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"people-management"}},[_v("People management"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#people-management","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I would actually argue that my biggest takeaway from CS3282 this semester is how to manage people.\nIn the beginning, the juniors from CS3281 were struggling a lot with the project and managing their own workload.\nThey were struggling with the steep learning curve that such an open module that CS3281 has.")]),_v(" "),_c('p',[_v("Initially, I was rather frustrated with them and I didn't really understand their concerns and problems.\nHowever, after taking some time to think about it, I tried to remain objective and patient with them, the same way my seniors were with me.\nThe rest of the seniors and I also tried different ways to motivate them and encourage them.")]),_v(" "),_c('p',[_v("For example, we started having weekly stand ups every Saturday, where the juniors had to talk about what they did and what they planned to do. Having these stand ups created an arbitary deadline for the juniors to do some work and this motivated them more. It also gave them the opportunity to ask us any questions immediately. I also tried to drop by their lectures (whenever I can remember) so they can ask me questions immediately and ping me for any reviews they needed. I think this slot was really important for me to understand their problems better. For example, I was wondering why a certain junior was writing test suites in a rather odd way, and how come he didn't catch problems with the test suites. When I spoke to him during the lecture slot, he told me that he actually did not know how to check through the test suite properly and that is why he did not notice any issues. Hence I spent that time teaching him how to test the test suites.")]),_v(" "),_c('p',[_v("Overall, I feel that people management was my biggest takeaway from the project. Just from learning from the juniors and how they behaved, I hope that this can translate to other projects when managing other developers.")]),_v(" "),_c('h4',{attrs:{"id":"pr-reviews"}},[_v("PR reviews"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#pr-reviews","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I learnt was how to phrase my comments precisely and with sufficient detail. If my comments are too vague, they sometimes intepreted it differently from what I meant it to be. I tried to give more context to my comments and, if I could, provide exact suggestions on what I wanted to change.")]),_v(" "),_c('p',[_v("An example of this was a discussion I had with a junior. I commented on his PR and told him to delete a certain part. But because I only referred to one line in his PR, he thought that I meant for him to only delete that specific line, when I wanted an entire hunk to be deleted, and this let to a lot of back and forth between us. The discussion can be seen "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446#discussion_r1567581147"}},[_v("here")]),_v(". Hence, I learnt that I should give clearer and more direct instructions.")]),_v(" "),_c('p',[_v("Also another thing that I learnt was to strike the right balance between being encourgaing and also being direct enough. As a reviewer, I don't want to come off too harsh which is discouraging, after all mistakes are a normal part of the process. However, it was also important to call out certain mistakes for the code writer to improve. For example, a junior had a certain way of writing code which was generally considered bad practise. Initially, I simply offered a suggestion on the PR, hoping that he would get the message that this was bad practise. However, after he did it multiple times, I specifically called him out for it and told him to correct it. While it may be a bit more harsh, he stopped doing so and his code quality improved.")]),_v(" "),_c('h4',{attrs:{"id":"release"}},[_v("Release"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#release","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I also learnt how to do a release for Markbind. It was actually rather straightforward due to the detailed documentation on Markbind's "),_c('a',{attrs:{"href":"https://markbind.org/devdocs/devGuide/projectManagement.html#doing-a-release"}},[_v("developer guide")]),_v(".")]),_v(" "),_c('p',[_v("I learnt about the versioning number in NPM and also about SERVER impact, which was important in helping me decide what should the version upgrade be. I refered to this "),_c('a',{attrs:{"href":"https://semver.org/"}},[_v("link")]),_v(".")]),_v(" "),_c('p',[_v("However, due to some issues with regards to the permissions on NPM, I also learnt about the way NPM packages are organised and the NPM organisations. The issue was that markbind-cli package was not under the same organisation markbind because of naming conventions. Because packages under an organisation would have @{organisation_name}/{package_name} under it, hence markbind-cli was not under the organisation initially. Hence, I learnt about the naming convention in NPM packages and the work arounds.")]),_v(" "),_c('h3',{attrs:{"id":"web-accessibility"}},[_v("Web accessibility"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#web-accessibility","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I attempted to do a PR about web accessibility. The idea was that users can make use of an inbuilt web accessibility tool to check if their website is considered accessible. For example, it could flag out issues with color constrast that make it harder for people with poor eyesight to use their website. While I did not manage to finish this PR in the end, I learnt about web accessibilty.")]),_v(" "),_c('p',[_v("For example I learnt about the color constrast ratio and how to calculate it. This is used to ensure that those with poor eyesight could still use the website with enough color constrast. This was learnt from "),_c('a',{attrs:{"href":"https://medium.muz.li/the-science-of-color-contrast-an-expert-designers-guide-33e84c41d156"}},[_v("here")]),_v(" and "),_c('a',{attrs:{"href":"https://www.w3.org/TR/WCAG20-TECHS/G17.html"}},[_v("here")])]),_v(" "),_c('p',[_v("Another thing I learnt was about tab index. The idea is that some users rely on tabbing to navigate through the website. Hence, it is important for websites to use a tab index in their elements to enable users to tab between different elements. Therefore, I learnt about tab index from "),_c('a',{attrs:{"href":"https://www.a11yproject.com/posts/how-to-use-the-tabindex-attribute/#:~:text=tabindex%20is%20a%20global%20attribute,via%20the%20keyboard's%20Tab%20key."}},[_v("here")])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-foo-2"}},[_v("Project: Foo"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-foo-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give an intro to the project here ...")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-7"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-7","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give a description of your contributions, including links to relevant PRs")]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-7"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-7","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give tools/technologies you learned here. Include resources you used, and a brief summary of the resource.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"elton-goh-jun-hao"}},[_v("ELTON GOH JUN HAO"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#elton-goh-jun-hao","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/EltonGohJH/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/EltonGohJH"}},[_v("https://github.com/EltonGohJH")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("MarkBind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Helped prepare idea & facilitated Saturday code sprint - MarkBind website making")])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Repo cleaning - Added tags to issues, added items to project road map, added summaries to issues, and cleaned up some issues. Examples: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2382"}},[_v("Allow markbind serve to specify custom host #2382")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2397"}},[_v("Optimize MarkBind for saving as PDF #2397")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2401"}},[_v("UG: images appear in two places #2401")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Investigated: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2401"}},[_v("UG: images appear in two places #2401")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Investigated and closed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2157"}},[_v("The collapsed page nav appears in the print view #2157")])])]),_v(" "),_c('tr',[_c('td',[_v("4, 5")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v("MarkBind Template for Software Project Documentation #2400")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2425"}},[_v("Migrate stylelint to latest version #2292")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Discussed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2420"}},[_v("Use justified text formatting for tooltips #2420")])])]),_v(" "),_c('tr',[_c('td',[_v("5, 6")]),_v(" "),_c('td',[_v("Investigated and reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2414"}},[_v("Fix external styles and script not hoisted #2414")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2431"}},[_v("Add line-numbers when wrapping is needed for printing #2431")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Investigated: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2432"}},[_v("Tooltip artefact left over for annotation point #2432")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2436"}},[_v("Disable pop over in a-point if there is no header and content passed by user #2436")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Investigated and helped fix bug: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2429"}},[_v("Utilize GitHub Actions to aid checking of commit message #2429")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Helped fix bug and merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2427"}},[_v("Annotation content slot #2427")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2375"}},[_v("Add horizontal spacing between the icon and text in the custom icon list #2375")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2453"}},[_v("Add keeping your fork up to date section in DG #2453")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2444"}},[_v("Add text support for icon #2444")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2465"}},[_v("Efficient validation for intra-link with hash #2465")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2486"}},[_v("Fix stray space before popover and tooltip #2486")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed and approved: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2487"}},[_v("Fix off-positioned close button in imported modal #2487")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2507"}},[_v("Add note on URLs in includes #2507")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2474"}},[_v("Set global variables using nunjucks syntax #2474")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2475"}},[_v("Add Mermaid Plugin #2475")])])]),_v(" "),_c('tr',[_c('td',[_v("7-13")]),_v(" "),_c('td',[_v("Part of weekly sync with CS3281 students")])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"special-mention-to-chatgpt-and-github-copilot"}},[_v("Special mention to ChatGPT and GitHub Copilot"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#special-mention-to-chatgpt-and-github-copilot","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("A fun fact is that I use ChatGPT and GitHub Copilot for everything in the list below.\nChatGPT just makes it so much easy to write and debug code. ChatGPT has really helped me to picked up the technology and tools mentioned below.\nI find that GitHub Copilot is super helpful when writing boiler plates code and code in general.")]),_v(" "),_c('h3',{attrs:{"id":"vue-js"}},[_v("Vue.js"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-js","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("During the semester, I learned the fundamentals of Vue.js, including the Vue lifecycle, creating Vue components, and working with both Vue 2 and Vue 3.\nIt was exciting to discover that my previous experience with React was easily transferable to Vue, which helped me to quickly grasp the fundamentals of the framework.")]),_v(" "),_c('p',[_v("While using Vue, I also realised the importance of having a huge community behind a framework.\nWhen working with Vue, I find it harder to find solutions online as there are less resources available compared to React.\nHowever, I still had a great time learning Vue and learning a new framework for Frontend.")]),_v(" "),_c('h4',{attrs:{"id":"resource-used"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://vuejs.org/"}},[_v("Vue docs")]),_v(": This is the most valuable resource I used to learn Vue. The docs are pretty well written and easy to understand.\nHowever, there are some parts that are not very well documented such as SSR.")])]),_v(" "),_c('h3',{attrs:{"id":"monorepo-and-monorepo-management-tools"}},[_v("Monorepo and Monorepo management tools"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#monorepo-and-monorepo-management-tools","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("During the semester, I learned about Monorepo and Monorepo management tools like Lerna, NPM Workspaces, and Turborepo.\nI gained an understanding of the benefits that Monorepo provides, such as simplified version control, dependency management and sharing of configs.\nI learned how Monorepo management tools can help with versioning and also help to speed up running test and building through concurrency and caching.")]),_v(" "),_c('p',[_v("Overall, I gained a greater appreciation for Monorepo and its management tools, and I can see how they can greatly simplify software development and improve efficiency.")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-2"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://lerna.js.org/"}},[_v("Lerna docs")]),_v(": This is the main resource I used to learn about Lerna. The docs are pretty well written and easy to understand.")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://www.youtube.com/watch?v=9iU_IE6vnJ8"}},[_v("Fireship on monorepo")]),_v(": This is a good summary video by Fireship which shares about what exactly is Monorepo and why it is useful.")])]),_v(" "),_c('h3',{attrs:{"id":"serverside-rendering-ssr"}},[_v("Serverside Rendering (SSR)"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#serverside-rendering-ssr","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is my first time actually working with SSR directly.\nPrior to this, I only have a basic understanding of SSR, and I was not sure how it works.\nThrough learning how to migrate from Vue 2 and Vue 3, I have really learnt a lot about how SSR works and why is it needed.\nBelow are a list of things that I have learned about SSR:")]),_v(" "),_c('ul',[_c('li',[_v("How does SSR work and what are the benefits of using SSR?")]),_v(" "),_c('li',[_v("How does SSR differ from Client-Side Rendering (CSR)?")]),_v(" "),_c('li',[_v("What is client-side hydration and how does it work in conjunction with SSR?")]),_v(" "),_c('li')]),_v(" "),_c('p',[_v("I am really glad that I have learnt about SSR as SSR will is getting more and more prevalent in the industry.")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-3"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-3","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://vuejs.org/"}},[_v("Vue docs")]),_v(": This is super helpful in understand about SSR in vue.")]),_v(" "),_c('li',[_v("Other than that, I think a lot of SSR and even CSR knowledge is learned from ChatGPT.")])]),_v(" "),_c('h3',{attrs:{"id":"webpack"}},[_v("Webpack"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#webpack","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Previously, in all honesty I did not really know what Webpack is and how it works.\nWebpack seems to just be a magical tool that just works.\nThrough updating of Webpack and attempting to migrate Vue 2 to Vue 3. I learned a lot about Webpack and what it does.\nBelow are a list of things that I have learned about Webpack:")]),_v(" "),_c('ul',[_c('li',[_v("What is Webpack and how does it work? (bundling etc.)")]),_v(" "),_c('li',[_v("Learned about different types of Webpack plugins")])]),_v(" "),_c('h4',{attrs:{"id":"resource-used-4"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-4","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://webpack.js.org/"}},[_v("Webpack docs")]),_v(": This is the main resource I used to learn about Webpack.")])]),_v(" "),_c('h3',{attrs:{"id":"i-learn-how-to-use-open-source-software"}},[_v("I learn how to use Open Source Software"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#i-learn-how-to-use-open-source-software","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is quite a random learning point, but I think it is important to mention.\nSomehow, I handled a lot of upgrading of dependencies.\nI learned how to safely update dependencies and ensure that it does not break a codebase.\nI also learned the importance of reading the changelog and release notes of dependencies.")]),_v(" "),_c('p',[_v("I had a painful experience when I had to debug why html format has changed after running npm install.\nThe reason for this is that the developer of js-beautify has changed the way it formats custom tag but did not mention it in the release notes.\nThis caused a lot of tests to fail and I had to spend a lot of time debugging it.")]),_v(" "),_c('p',[_v("Through this experience, I learned the importance of ensuring that changes are documented properly and correctly.")]),_v(" "),_c('h3',{attrs:{"id":"gomock"}},[_v("gomock"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#gomock","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I have learned to use GoMock, a mocking framework for Golang, which streamlines the creation of mock objects for unit testing. It helps with decoupling components, enabling the simulation of complex behaviors and interactions. I am surprised how easy it to use to mock complex behaviours.\nWill definitely use it for Golang testing next time!")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-5"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-5","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/uber-go/mock"}},[_v("gomock docs")])])]),_v(" "),_c('h3',{attrs:{"id":"yarn-workspaces"}},[_v("Yarn workspaces"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#yarn-workspaces","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Yarn Workspaces is a feature of Yarn that simplifies handling multiple packages within a single repository by enabling shared dependencies and centralized script management. I learnt Yarn Workspaces while setting up the repository for the Twenty project.\nOverall, it is a good experience as I learnt more alternatives to Lerna and NPM workspaces.")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-6"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-6","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://yarnpkg.com/features/workspaces"}},[_v("Yarn workspaces docs")])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"projects-i-have-worked-on"}},[_v("Projects I have worked on"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#projects-i-have-worked-on","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h4',{attrs:{"id":"mattermost"}},[_v("Mattermost"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#mattermost","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Mattermost is an open-source collaboration platform designed for secure communication throughout the entire software development lifecycle. It serves as a self-hostable alternative to Slack, offering similar functionalities with the added benefit of full control over hosting and management.")]),_v(" "),_c('h3',{attrs:{"id":"twenty"}},[_v("Twenty"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#twenty","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Twenty CRM is a modern, open-source Customer Relationship Management (CRM) platform. It serves as an self-hostable alternative to Salesforce.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-8"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-8","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In the "),_c('a',{attrs:{"href":"https://github.com/mattermost/mattermost/pull/26278"}},[_v("mattermost PR (merged)")]),_v(". I addressed this "),_c('a',{attrs:{"href":"https://github.com/mattermost/mattermost/issues/25991"}},[_v("issue")]),_v(" where the CLI command to list the teams uses a magic number of 9999. Utilizing such large magic numbers presents two problems: it restricts the ability to list more than 9999 teams and could result in a request that is too large. To solve this, I implemented pagination for the request, with each page containing 200 teams. Subsequently, I updated the test cases to reflect the new expected behavior.")]),_v(" "),_c('p',[_v("In the "),_c('a',{attrs:{"href":"https://github.com/twentyhq/twenty/pull/4198"}},[_v("Twenty PR (merged)")]),_v(". I addressed an "),_c('a',{attrs:{"href":"https://github.com/twentyhq/twenty/issues/4181"}},[_v("issue")]),_v(" reported by a user concerning LinkedIn school URLs not parsing correctly. Upon investigating the issue on the frontend, I discovered that the existing regex was only configured to support company URLs. To resolve this, I updated the regex to also accommodate school URLs and conducted tests to ensure the fix was effective.")]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-8"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-8","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"gomock-2"}},[_v("gomock"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#gomock-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I have learned to use GoMock, a mocking framework for Golang, which streamlines the creation of mock objects for unit testing. It helps with decoupling components, enabling the simulation of complex behaviors and interactions. I am surprised how easy it to use to mock complex behaviours.\nWill definitely use it for Golang testing next time!")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-7"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-7","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/uber-go/mock"}},[_v("gomock docs")])])]),_v(" "),_c('h3',{attrs:{"id":"yarn-workspaces-2"}},[_v("Yarn workspaces"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#yarn-workspaces-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Yarn Workspaces is a feature of Yarn that simplifies handling multiple packages within a single repository by enabling shared dependencies and centralized script management. I learnt Yarn Workspaces while setting up the repository for the Twenty project.\nOverall, it is a good experience as I learnt more alternatives to Lerna and NPM workspaces.")]),_v(" "),_c('h4',{attrs:{"id":"resource-used-8"}},[_v("Resource used:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#resource-used-8","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://yarnpkg.com/features/workspaces"}},[_v("Yarn workspaces docs")])])]),_v(" "),_c('h3',{attrs:{"id":"practices-tools-from-mattermost-that-could-be-adopted-by-markbind"}},[_v("Practices/tools from Mattermost that could be adopted by Markbind"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#practices-tools-from-mattermost-that-could-be-adopted-by-markbind","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I was particularly impressed with the "),_c('a',{attrs:{"href":"https://docs.twenty.com/start/local-setup/"}},[_v("Twenty's onboarding guide")]),_v(" because it includes multi-OS setup guides and instructions on setting up through Docker containers. Furthermore, it provides an IDE setup guide, and its repository contains a "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v(".vscode/extensions.json")]),_v(" file that assists users in configuring VS Code. For Markbind, while the Docker container setup may not be necessary, adopting a multi-OS guide could be beneficial. It could promote useful tools like "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("nvm")]),_v(" for testing across multiple Node.js versions, and a VS Code extensions list could help new developers adhere to our coding practices.")]),_v(" "),_c('p',[_v("I was really impressed with the PR review workflow at Mattermost. It's incredibly systematic, featuring stages such as UI review, Dev review, and QA review, which make the process feel seamless. Additionally, they utilize bots to remind reviewers to complete their reviews. While Markbind is smaller and might not require such an elaborate setup, investigating the potential of GitHub PR bots could be beneficial. These tools could streamline our review process and ensure that contributions are efficiently and effectively vetted.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"hannah-chia-kai-xin"}},[_v("HANNAH CHIA KAI XIN"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#hannah-chia-kai-xin","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/kaixin-hc/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/kaixin-hc"}},[_v("https://www.github.com/kaixin-hc")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("Markbind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h2',{attrs:{"id":"spotlighted-achievements-work"}},[_v("Spotlighted achievements/work:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#spotlighted-achievements-work","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Release: 5.5.0 and patches 5.5.1 and 5.5.2:")]),_v(" "),_c('li',[_v("Project management\n"),_c('ul',[_c('li',[_v("Prepared idea and facillitated Saturday code sprint to onboard juniors")]),_v(" "),_c('li',[_v("Regular repository maintenance and labelling, as well as investigating and closing old issues and creating new ones usually related to project maintenance (examples - not comprehensive: adding clarifications "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2091#issuecomment-1909719113"}},[_v("#2091")]),_v(", investigation and closing ("),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/633"}},[_v("#633")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1916"}},[_v("#1916")]),_v("), adding/changing labels "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2547"}},[_v("#2547")]),_v(", new issues ("),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2459"}},[_v("goal")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2496"}},[_v("#2496")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2552"}},[_v("template deploy buttons")]),_v("), "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2541"}},[_v("linking related issues")]),_v(")")]),_v(" "),_c('li',[_v("(Re)introduction of GitHub projects, clean up of github projects to create a targeted project roadmap and provide group goals and direction + documentation for the above")]),_v(" "),_c('li',[_v("Discussion/investigation of "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2073"}},[_v("github teams related permissions issues")])])])]),_v(" "),_c('li',[_v("PR Review Examples:\n"),_c('ul',[_c('li',[_v("Templates: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v("Software Project")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2398"}},[_v("Personal Resume")])]),_v(" "),_c('li',[_v("Review of Teammates docs upgrade: "),_c('a',{attrs:{"href":"https://github.com/TEAMMATES/teammates/pull/12893#event-12140069832"}},[_v("Upgrade to latest MarkBind version ")])]),_v(" "),_c('li',[_v("Testing: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2476"}},[_v("Standardise NodeProcessor.data.ts constant names #2476")]),_v(" and reviews on related PRs")]),_v(" "),_c('li',[_v("Dev experience: completing typescript migration ("),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2482"}},[_v("#2482")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2481"}},[_v("#2481")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2480"}},[_v("#2480")]),_v(") (I also suggested this task to the juniors!), "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2470"}},[_v(" Utilize GitHub Actions to check for SEMVER impact label #2470 ")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2484#pullrequestreview-1983735630"}},[_v(" Add a reminder when contributor is new to ping all contributor bot #2484 ")])]),_v(" "),_c('li',[_v("User facing features: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2501"}},[_v("Change seamless panels to inherit any parent's colours")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2494"}},[_v(" Support Bootstrap icons #2494 ")])])])]),_v(" "),_c('li',[_v("PR examples - this year prioritised docs/maintenance related issues to also give the juniors a chance to work on big issues\n"),_c('ul',[_c('li',[_v("Docs maintenance: eg "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2505"}},[_v("Update recommended IDE")])]),_v(" "),_c('li',[_v("Code maintenance: eg "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2497"}},[_v("Remove generated PUML image and exclude it from .gitignore #2497")]),_v(" and associated issue "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2498"}},[_v("2498")])])])])]),_v(" "),_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Prepared idea & helped facillitate Saturday code sprint - MarkBind website making")])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Reviewed and merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2388"}},[_v("Annotate support different labels #2388")]),_v(" - and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2390"}},[_v("added contributor")])])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Repo cleaning - investigated, reviewed available information, sometimes closed issues: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/633"}},[_v("PageNav cannot handle duplicate headings #633")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1903"}},[_v(" PUML not working on CI deployment (Teammates) due to lack of graphviz #1903 ")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2091"}},[_v(" Combine the syntax cheat sheet and full syntax reference pages #2091 ")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Product Roadmap. Investigated methods to plot out product roadmap, settling on GitHub Projects. Set up the project and categories with the team and sorted issues into the roadmap. ("),_c('a',{attrs:{"href":"https://github.com/orgs/MarkBind/projects/1"}},[_v("Roadmap here")]),_v(") - "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/813"}},[_v("Related issue")])])]),_v(" "),_c('tr',[_c('td',[_v("3-6")]),_v(" "),_c('td',[_v("Repo cleaning - Add tags to issues, add items to project road map, add summaries to issues. Examples : "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2091#issuecomment-1909719113"}},[_v("Combine the syntax cheat sheet and full syntax reference pages #2091")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1831"}},[_v("Pop-Ups like tooltip/trigger do not work within the tree component")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2352"}},[_v(" Add horizontal spacing between the icon and text in the custom icon list #2352 ")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("My PR was merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2407"}},[_v("Chore: Remove unused CSS for seamless panel styling #2407")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed and Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2406"}},[_v(" Enhance search performance of algolia plugin #2406 ")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Reviewed and discussed PR (eventually closed): "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2413"}},[_v("Automatically add line-numbers when soft-wrapping (#2404) #2413 ")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Investigate "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2416"}},[_v(".gitignore not generated when init #2416")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Investigate "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2419"}},[_v("Tooltips seem to add an extra space in front #2419 ")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v("MarkBind Template for Software Project Documentation #2400")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Add contributors in PRs with all-contributor: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2437"}},[_v("yiwen101 1")]),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2435"}},[_v("2")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2428"}},[_v("luminousleek")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2422"}},[_v("KevinEyo1")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Pair programming / in person discussion with 3281 students")])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2425"}},[_v("Migrate stylelint to latest version #2292 #2425")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed and Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2429"}},[_v(" Utilize GitHub Actions to aid checking of commit message #2429 ")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed and Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2414"}},[_v(" Fix external styles and script not hoisted #2414 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Reviewed and Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2426"}},[_v(" Combining syntax cheat sheet and full syntax reference pages #2426 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Reviewed and Merged PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1843"}},[_v(" Upgrade simple-git version #1843 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Recess")]),_v(" "),_c('td',[_v("Investigate issues / maintanence: investigate "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1916"}},[_v("Screenshots of the sample configurations for WebStorm are blurry #1916 ")]),_v(", mantain "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2424"}},[_v("Create table from csv file. #2424")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2441/files"}},[_v("Debug cannot import footnote from hash #2441")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR x2 times: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v(" MarkBind Template for Software Project Documentation #2400 ")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR : "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2398"}},[_v("MarkBind Template for Student Portfolio #2398")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Project management: met juniors with a curated list of issues based on project interest with 3282 team, updated the project management guide, reviewed issues in the repo")])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Discussed "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2367"}},[_v("Re-introduce lazy loading for pictures #2367")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed / left comments: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2444"}},[_v(" Add text for icon #2444 ")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Issue mantainence: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1916"}},[_v("#1916")]),_v(", "),_c('a',{attrs:{"href":""}},[_v("all-contributors automation discussion")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Merged + commented on: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2453"}},[_v("Add keeping fork up to date section in DG #2453")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Commented on and reviewed "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446#issuecomment-1990329474"}},[_v(" Add dataTable plugin #2446 ")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Merged + Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2452"}},[_v("Layout.ts to typescript #2452")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Review & Merge: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2465"}},[_v(" Efficient validation for intra-link with hash #2465 ")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Review & Merge: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2470"}},[_v(" Utilize GitHub Actions to check for SEMVER impact label #2470 ")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Review & Merge: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2400"}},[_v(" MarkBind Template for Software Project Documentation #2400 ")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("File issue & investigate on "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2498"}},[_v("Testing sites with generated files #2498")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review & Merge "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1913"}},[_v("typescript issues")]),_v("(site, test, markdownit items)")])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review & merge "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2483"}},[_v("Standardise NodeProcessor.data.ts constant names #2483")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/commit/6778b84c51213378acf2b53f62fd78b69c3e55e3"}},[_v("Allocate space for scrollbar in nav components")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/commit/6cc2461c46b2b1d9ceab34d77e003b2244171086"}},[_v("Fix stray space before popover and tooltip")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Flagged issues with "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2496"}},[_v("dependencies and NPM install")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Mantain repository")])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Write issue + Review PRs + PR related to testing of PUML: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/commit/2d6ca0113a9d90f713a70aea9c81087ecedc09b4"}},[_v("Remove generated PUML file wrongly included")]),_v(", reviewed "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/commit/003822f9acef4f36ecc942e2aef668e36085a8d5"}},[_v("necessary refactoring PR")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2498"}},[_v("made issue & investigated")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Reviewed and commented on "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2517"}},[_v(" Include link to the migrated AB3 website on our showcase #2517 ")]),_v(", flagging the issue with the migrated website")])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Chore: docs PR - "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/commit/74e580b837730a44f9fb5dc7b92cd2ad2de1ae5c"}},[_v("Update documentation for recommended IDE ")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Merged + Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2486"}},[_v("Fix stray space before popover and tooltip #2486")]),_v(",")])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2501"}},[_v("Change seamless panels to inherit any parent's colours")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Review: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2493"}},[_v("Rule based html validation against hydration #2493")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2523"}},[_v(" Using DangerJS to check changes coupling of implementation files to test or documentation files #2523 ")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed + Merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2513"}},[_v(" Remove Overridden Question Attributes in Documentation #2513")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("On similar issue, consolidated comments "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2476"}},[_v("on untested slot overriding in MarkBind #2476")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2511"}},[_v("approved PR #2511")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2510#pullrequestreview-1996333509"}},[_v(" Improve security of GitHub Actions workflows #2510 ")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2507"}},[_v(" Add note on absolute links #2507 ")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Maintain Issue Tracker: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1749"}},[_v("Add related comments about navbar highlighting to issue (and recategorise + rename it)")]),_v(", remove the discussion tag from essentially resolved issues and recategorise "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1161"}},[_v("Link to DevGuide in markbind.org")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2359"}},[_v("migrating bootswatch")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2181"}},[_v("Log warning if the include fragment is empty")])])]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_v("Reviewed")])]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_v("4 PRs of docs changes in preparation for the release: Add getting started warning for python 3.12 with Node LTS by @kaixin-hc in "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2536"}},[_v("#2536")]),_v(", Chore (docs): Fix grammar + clarify sentence by @kaixin-hc in "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2535"}},[_v("#2535")]),_v(", Chore: Document bootstrap classes with t-class in lists by @kaixin-hc in "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2534"}},[_v("#2534")]),_v(", Remove milestones from our project workflow docs by @kaixin-hc in "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2537"}},[_v("#2537")])])]),_v(" "),_c('tr',[_c('td',[_v("Reading Week")]),_v(" "),_c('td',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2537"}},[_v("Resolve workflow changes")]),_v(" (docs PR - above) + close all milestones in repository + relevant investigation of issue")])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Repository mantainence(eg: closing finished issues, commenting on others: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/813"}},[_v("Project Roadmap Review")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2496"}},[_v("python 3.12 dependency issue")]),_v(")")])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Released "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/releases/tag/v5.5.0"}},[_v("v5.5.0")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Investigated and closed issues: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/814"}},[_v("Migrate all MarkBind components from vue-strap to bootstrap-vue")]),_v(" (open since 2018!) and "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2025"}},[_v(" Vue hydration issues caused by invalid HTML make page unscrollable after clicking on modal #2025 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Wrote & PR merged for issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2539"}},[_v("Move buggy bootstrap-icons dependency to core/package.json")]),_v(" and investigated "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2538"}},[_v("on related issue")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Wrote & PR merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2540"}},[_v(" Bump fontawesome to remove console error #2540 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Wrote and PR merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2545"}},[_v("Writeup of using github projects for roadmap")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Added comments to issues: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2451"}},[_v("Missing output for plugins")]),_v(" - also bumped priority of this issue,")])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Created issue, investigated, and PR merged: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2544"}},[_v(" Update links to point to working site #2544 ")]),_v(" spotted links to MarkBind site that were not working.")])]),_v(" "),_c('tr',[_c('td',[_v("Exam week")]),_v(" "),_c('td',[_v("Created issue & made PR to markbind-init "),_c('a',{attrs:{"href":"https://github.com/MarkBind/init-typical/issues/3"}},[_v("to update links to point to working site")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Released "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/releases/tag/v5.5.1"}},[_v("v5.5.1")]),_v(" and released "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/releases/tag/v5.5.1"}},[_v("v5.5.2")]),_v(" patches as we troubleshooted issues")])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Reviewed "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2551"}},[_v(" Revert dg json changes #2551 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Discussion: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/815"}},[_v("Consider starting a public discussion channel (e.g. Discord, Gitter) to connect with external contributors ")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("Investigated and wrote out proposal for "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2073"}},[_v(" Standardize and document steps wrt to GitHub teams and PR review procedure #2073 ")])])]),_v(" "),_c('tr',[_c('td',[_v("Exam Week")]),_v(" "),_c('td',[_v("New issue: "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2552"}},[_v("Add Netlify deploy buttons for templates")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h2',{attrs:{"id":"frontend"}},[_v("Frontend"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#frontend","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"rounded-vs-square-edges-for-signalling-functionality"}},[_v("Rounded vs Square edges for signalling functionality"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#rounded-vs-square-edges-for-signalling-functionality","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Researching whether to use rounded corners, sqared off corners, or fully rounded boxes was interesting from a usability perpective. Some resources I used to learn about them:")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://ux.stackexchange.com/questions/40744/mixing-rounded-corners-and-square-corners"}},[_v("https://ux.stackexchange.com/questions/40744/mixing-rounded-corners-and-square-corners")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://medium.com/@carolinalina/how-to-design-ui-buttons-that-convert-d5ebb1080969"}},[_v("https://medium.com/@carolinalina/how-to-design-ui-buttons-that-convert-d5ebb1080969")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://prototypr.io/post/the-rounded-user-experience/"}},[_v("https://prototypr.io/post/the-rounded-user-experience/")])])]),_v(" "),_c('p',[_v("The information from "),_c('a',{attrs:{"href":"https://uxdesign.cc/make-sense-of-rounded-corners-on-buttons-dfc8e13ea7f7"}},[_v("https://uxdesign.cc/make-sense-of-rounded-corners-on-buttons-dfc8e13ea7f7")]),_v(" in particular made a case for fully rounded buttons for primary content when you have space to spare, to direct users attention to those buttons. They suggested to avoid fully rounded buttons when many are used next to each other as it may not be obvious which to click. I used this information to infer what the average user might takeaway if minimized panels were pills rather than rounded buttons.")]),_v(" "),_c('h3',{attrs:{"id":"vue-2"}},[_v("Vue"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://v1.vuejs.org/guide/instance.html"}},[_v("https://v1.vuejs.org/guide/instance.html")])]),_v(" "),_c('li',[_v("Scoped styles: "),_c('a',{attrs:{"href":"https://vue-loader.vuejs.org/guide/scoped-css.html"}},[_v("https://vue-loader.vuejs.org/guide/scoped-css.html")]),_v(", also informing the issue I created "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/1768"}},[_v("#1768")]),_v(" in MarkBind")]),_v(" "),_c('li',[_v("Learning about slots: "),_c('a',{attrs:{"href":"https://learnvue.co/2021/03/when-why-to-use-vue-scoped-slots/#conclusion"}},[_v("https://learnvue.co/2021/03/when-why-to-use-vue-scoped-slots/#conclusion")]),_v(", "),_c('a',{attrs:{"href":"https://www.smashingmagazine.com/2019/07/using-slots-vue-js/"}},[_v("https://www.smashingmagazine.com/2019/07/using-slots-vue-js/")])])]),_v(" "),_c('h3',{attrs:{"id":"scrollbars"}},[_v("Scrollbars"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#scrollbars","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Using overflow-x: scroll on the default navbar, seemed to cause the dropdown to break.")]),_v(" "),_c('p',[_v("After a few stack overflow posts and reading, I found this article: "),_c('a',{attrs:{"href":"https://css-tricks.com/popping-hidden-overflow/"}},[_v("https://css-tricks.com/popping-hidden-overflow/")]),_v(" that explains that setting "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("overflow-x")]),_v(" sets "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("overflow-y")]),_v(" as well, and it's just not possible to have a dropdown peep out of a scrollable overflow without setting positions relatively. "),_c('a',{attrs:{"href":"https://www.sitepoint.com/community/t/css-drop-down-menu-hidden-behind-horizontal-scrollbar/367783"}},[_v("This discussion")]),_v(" with the offered "),_c('a',{attrs:{"href":"https://codepen.io/paulobrien/embed/vYxWppv?"}},[_v("solution")]),_v(" was also interesting.")]),_v(" "),_c('p',[_v("I briefly explored existing libraries like "),_c('a',{attrs:{"href":"https://floating-ui.com/"}},[_v("https://floating-ui.com/")]),_v(". Libraries like this exist to make it easier to accomplish this surprisingly complex task.")]),_v(" "),_c('p',[_v("I also learned about the accessibility of scrollbars ("),_c('a',{attrs:{"href":"https://adrianroselli.com/2019/01/baseline-rules-for-scrollbar-usability.html"}},[_v("https://adrianroselli.com/2019/01/baseline-rules-for-scrollbar-usability.html")]),_v(") and ("),_c('a',{attrs:{"href":"https://www.w3.org/WAI/standards-guidelines/act/rules/0ssw9k/proposed/"}},[_v("https://www.w3.org/WAI/standards-guidelines/act/rules/0ssw9k/proposed/")]),_v("), which discussed what goes into making scrollbars accessible. Visually, visible scrollbars provide an obvious indication that there is more content. These design tips on scrollbars ("),_c('a',{attrs:{"href":"https://www.nngroup.com/articles/scrolling-and-scrollbars/"}},[_v("https://www.nngroup.com/articles/scrolling-and-scrollbars/")]),_v(") were also interesting, particularly the note to avoid horizontal scrolling wherever possible.")]),_v(" "),_c('p',[_v("This informed my decision that it would be better not to make a scrollable navbar the default, but have a dropdown menu with more options for smaller screens")]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar"}},[_v("::webkit-scrollbar")]),_v(" pseudo-element does not work for all browsers and should be used with caution.")]),_v(" "),_c('h2',{attrs:{"id":"open-source-dependencies"}},[_v("Open source dependencies"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#open-source-dependencies","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"ghpages"}},[_v("ghpages"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ghpages","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Used when researching the deploy and build commands for MarkBind.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/tschaub/gh-pages"}},[_v("https://github.com/tschaub/gh-pages")])])]),_v(" "),_c('h3',{attrs:{"id":"commander"}},[_v("Commander"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#commander","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Used to write CLI programs.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://www.npmjs.com/package/commander"}},[_v("https://www.npmjs.com/package/commander")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://en.wikipedia.org/wiki/Usage_message"}},[_v("https://en.wikipedia.org/wiki/Usage_message")]),_v(" (conventions in defining parameters)")])]),_v(" "),_c('h3',{attrs:{"id":"jest"}},[_v("jest"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#jest","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Mainly studied the changelog to see if this would break when dependencies were updated.")]),_v(" "),_c('ul',[_c('li',[_v("Introduction: "),_c('a',{attrs:{"href":"https://jestjs.io/"}},[_v("https://jestjs.io/")]),_v(" and repository("),_c('a',{attrs:{"href":"https://github.com/facebook/jest"}},[_v("https://github.com/facebook/jest")]),_v(")")]),_v(" "),_c('li',[_v("relevant blog post: "),_c('a',{attrs:{"href":"https://jestjs.io/blog/2021/05/25/jest-27"}},[_v("https://jestjs.io/blog/2021/05/25/jest-27")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/facebook/jest/blob/main/CHANGELOG.md#2700"}},[_v("changelog")])]),_v(" "),_c('li',[_v("Jest testrunners: they plan on changing the default test-runner from "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("jasmine2")]),_v(" to "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("jest-circus")]),_v(" in version 27, with "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("jasmine2")]),_v(" "),_c('a',{attrs:{"href":"https://jestjs.io/blog/2020/05/05/jest-26"}},[_v("to be discontinued afterwards")]),_v(". Though I think we're using "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("jasmine2")]),_v(" and not "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("jest-circus")]),_v(", but MarkBind we never explicitly specify a change from the default")])]),_v(" "),_c('h3',{attrs:{"id":"fs-extra"}},[_v("fs-extra"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#fs-extra","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Handy utility that I ended up using extensively")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/jprichardson/node-fs-extra"}},[_v("https://github.com/jprichardson/node-fs-extra")])])]),_v(" "),_c('h2',{attrs:{"id":"git"}},[_v("Git"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#git","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("CI pipeline (particularly with git):")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration"}},[_v("https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration")]),_v(", particularly the section on "),_c('a',{attrs:{"href":"https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration#about-continuous-integration-using-github-actions"}},[_v("github actions")])]),_v(" "),_c('li',[_v("Follow-up research about github actions\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://docs.github.com/en/actions/quickstart"}},[_v("https://docs.github.com/en/actions/quickstart")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions"}},[_v("https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions")])])])]),_v(" "),_c('li',[_v("Basic research about "),_c('a',{attrs:{"href":"https://travis-ci.org/"}},[_v("Travis CI")]),_v(" and "),_c('a',{attrs:{"href":"https://www.netlify.com/"}},[_v("Netlify")])])]),_v(" "),_c('h2',{attrs:{"id":"logging-framework"}},[_v("Logging Framework"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#logging-framework","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://www.sentinelone.com/blog/logging-framework/"}},[_v("https://www.sentinelone.com/blog/logging-framework/")]),_v(" as an introduction")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://se-education.org/se-book/errorHandling/#-12"}},[_v("https://se-education.org/se-book/errorHandling/#-12")]),_v(" also as an introduction")]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://github.com/winstonjs/winston"}},[_v("https://github.com/winstonjs/winston")]),_v(" (library used with markbind)")])]),_v(" "),_c('h2',{attrs:{"id":"ways-versioning-is-implemented"}},[_v("Ways Versioning is Implemented"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ways-versioning-is-implemented","onclick":"event.stopPropagation()"}})]),_v(" "),_c('ul',[_c('li',[_v("Learn about semantic versioning: "),_c('a',{attrs:{"href":"https://semver.org/"}},[_v("https://semver.org/")])]),_v(" "),_c('li',[_v("Alternate versioning solutions:\n"),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/jimporter/mike"}},[_v("https://github.com/jimporter/mike")])]),_v(" "),_c('li',[_c('a',{attrs:{"href":"https://docusaurus.io/docs/versioning"}},[_v("https://docusaurus.io/docs/versioning")])])])])]),_v(" "),_c('h2',{attrs:{"id":"javascript"}},[_v("Javascript"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#javascript","onclick":"event.stopPropagation()"}})]),_v(" "),_c('h3',{attrs:{"id":"javascript-with-regard-to-object-oriented-programming"}},[_v("Javascript with regard to object oriented programming"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#javascript-with-regard-to-object-oriented-programming","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Looking into this was inspired by the issues on refactoring the large "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("core/site/index.js")]),_v(" file which is over 1.5k lines into more manageable class. At present, most of the file is made up of the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("Site")]),_v(" class, which makes sense from an object oriented perspective. All the functions which are supported by Site are things which affect what the site itself holds or does: generating itself, deploying itself, initialising itself.")]),_v(" "),_c('p',[_v("One suggestion for refactoring would be separating out each command into separate files. We could abstract away the command logic might be separating each command into classes, having each command inherit from a Command class, and having the site class just generate and execute each command when it is called to do so. But is this necessary or desirable?")]),_v(" "),_c('p',[_v("Java and Javascript are different in that Java is class based and Javascript is prototype-based. Class based languages are founded on the concept of classes and instances being distinct, where classes are an abstract description of a set of potential instances which have the properties defined in the class - no more and no less. Prototype based languages have a 'prototypical object' which is the template used to create a new object, but once you create it or at run time the object can specify its own additional properties and be assigned as the prototype for additional objects (source: "),_c('a',{attrs:{"href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model"}},[_v("mozilla, class-based vs prototype based languages")]),_v(")")]),_v(" "),_c('p',[_v("Nevertheless, Site.js does use \"classes\" of managers to manage externals, etc, so perhaps in production avoiding classes is not a big deal. Would still be a useful abstraction to manage the complexity of the file.")]),_v(" "),_c('h3',{attrs:{"id":"certain-functions-in-javascript"}},[_v("Certain functions in javascript"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#certain-functions-in-javascript","onclick":"event.stopPropagation()"}})]),_v(" "),_c('panel',{scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_v("JavaScript forEach (and async loops)")])]},proxy:true}])},[_v(" "),_c('p',[_v("\"JavaScript Array.prototype.forEach loop is not asynchronous. The Array.prototype.forEach method accepts a callback as an argument which can be an asynchronous function, but the forEach method will not wait for any promises to be resolved before moving onto the next iteration.\" ("),_c('a',{attrs:{"href":"https://atomizedobjects.com/blog/javascript/is-javascript-foreach-async/"}},[_v("Source")]),_v(").")]),_v(" "),_c('p',[_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("forEach")]),_v(" does not look at what is returned, and won't handle the promise that an async function would return. Naturally, this means you cannot use async or await with it. The algorithm for forEach creates a loop that calls the callback function for each("),_c('a',{attrs:{"href":"https://stackoverflow.com/questions/5050265/javascript-node-js-is-array-foreach-asynchronous"}},[_v("StackOverflow Source")]),_v(", "),_c('a',{attrs:{"href":"https://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript"}},[_v("more information about loops")]),_v(")")]),_v(" "),_c('p',[_v("Instead, we could use map and the promise 'class' functions.")])]),_v(" "),_c('panel',{scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_v("Javascript map can be destructive sometimes")])]},proxy:true}])},[_v(" "),_c('p',[_v("Just needed to note this, and consider other options. Refactoring my code allowed me to avoid destructively modifying the list.\n[source]("),_c('a',{attrs:{"href":"https://dev.to/lofiandcode/"}},[_v("https://dev.to/lofiandcode/")]),_v("\ncan-map-mutate-the-original-array-yes-dmb)")])]),_v(" "),_c('h3',{attrs:{"id":"softwrapping-vs-hard-wrapping-code"}},[_v("Softwrapping vs hard wrapping code"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#softwrapping-vs-hard-wrapping-code","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("After extensive reading, I am more familiar with the arguments for softwrapping code vs longwrapping code, as well as keyboard shortcuts for skilling to the next line in editors like vim which also affect developer preference. I liked "),_c('a',{attrs:{"href":"https://jesseduffield.com/Hard-Wrap-vs-Soft-Wrap/"}},[_v("this article")]),_v(".")]),_v(" "),_c('p',[_v("In particular, I found the idea of semantic line breaks (single linebreaks being for your eyes only) in languages like HTML interesting. The argument for it(trivially rearranging items in a comma separated list, for example) was one I had not seen explicated before. While I am unlikely to adopt it, it also sheds light on why line-break problems are so common in MarkBind.")]),_v(" "),_c('h3',{attrs:{"id":"css-vendor-locking"}},[_v("CSS Vendor Locking:"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#css-vendor-locking","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("In the past, different browsers used different prefixes for CSS properties, so developers would often extensively cover the available cases with prefixes.")]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://stackoverflow.com/questions/76144712/visual-studio-code-warning-also-define-the-standard-property-background-clip"}},[_v("Stylelint removes vendor prefixes")])]),_v(" "),_c('p',[_v("There is a danger for specific properties... eg "),_c('a',{attrs:{"href":"https://stackoverflow.com/questions/75688924/background-clip-text-isnt-working-at-all-in-css"}},[_v("background-clip: text")]),_v(" ... but for other cases in the markbind code, like "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("background-clip: padding-box")]),_v(", it is no longer to prefix in order to obtain the desired behaviour.")]),_v(" "),_c('p',[_v("Background reading on vendor prefixing: "),_c('a',{attrs:{"href":"https://css-tricks.com/is-vendor-prefixing-dead/"}},[_v("Is vendor prefixing dead?")])]),_v(" "),_c('h3',{attrs:{"id":"precommit-hooks"}},[_v("Precommit hooks"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#precommit-hooks","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Husky orchestrates Git hooks within Node.js environments, facilitating essential pre-commit and pre-push tasks such as code linting, testing, and formatting. This tool streamlines development workflows by automating quality assurance measures, thereby upholding codebase integrity and promoting team-wide adherence to established coding standards. David's lightning talk about this topic was helpful in teaching me about this topic.")]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://github.com/godotengine/godot-docs/pull/9094"}},[_v("This PR also helped me learn about it as I read about the hook and what it did")]),_v(". MarkBind also uses hooks.")]),_v(" "),_c('h3',{attrs:{"id":"ant-design"}},[_v("Ant design"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#ant-design","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Similar to material UI. No very notable observations, except that familiarity with at least one component design system seems to make picking up others much easier.")])],1)]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Observations")]),_v(" from external projects")])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"project-godot"}},[_v("Project: Godot"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#project-godot","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("While I was not able to make a contribution to the main repository, as I was using this software and following development discussions I'd like to share my understanding. Additionally, I made a PR to the documentation repository which I will elaborate on later.")]),_v(" "),_c('p',[_v("Godot is an open-source game engine, which can also be used to create other GUI centric applications such as RPG map makers. I have used Godot for a few games so that I could familiarise myself with the tool from the user perspective.")]),_v(" "),_c('h4',{attrs:{"id":"user-experience"}},[_v("User experience"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#user-experience","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("One area where Godot is strong is the new-user experience. It offers multiple ways to get started: a free playable desktop tutorial, step-by-step tutorial based documentation for 2d or 3d games, youtube video tutorials, primers to the overall concept, as well as active community support in the forum, discord, or over other social media platforms like Reddit.")]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://docs.google.com/presentation/d/1xuesBz7XkaeQNFNVyGkFE70QM5ILFrqiTuSbo_cvsME/edit#slide=id.g26929859d4f_0_37252"}},[_v("Here is a link to my slides where I discuss game design principles in Godot, introducing some of the concepts behind the engine as well as the ways users can get started")])]),_v(" "),_c('p',[_c('mark',[_v("With MarkBind, this lends validation to the idea that we might want to also have multiple ways to get started.")]),_v(" This informed my thoughts on this issue "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2257"}},[_v("Add a set of tutorials for MarkBind")]),_v(" which I added to the overall pinned goal to Make it easier for users to get started with markbind")]),_v(" "),_c('h4',{attrs:{"id":"arrangement-of-repository-and-maintenance"}},[_v("Arrangement of repository and maintenance"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#arrangement-of-repository-and-maintenance","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("It's clear that Godot is a huge project - they even have a development fund from donors, and I believe there are people paid to work on the project full time. Nevertheless, it seems that while there is an active developer community there is also an abundance of work and limits on attention. Furthermore, with such a big project and so many issues, this is a project that uses an organisation to group many active repositories - the main godot repository, as well as godot-docs and "),_c('a',{attrs:{"href":"https://github.com/godotengine/godot-proposals/issues?page=2&q=is%3Aissue+is%3Aopen"}},[_v("godot-proposals")]),_v(" are some examples. godot-proposals are used for new feature requests and has 4.2k issues as well as discussions! "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("godot")]),_v(" has over 5k issues - and over 2.4k PULL REQUESTS. This is an huge volume especially considering that it is an active repository - pull requests are closed or merged daily.")]),_v(" "),_c('p',[_c('strong',[_v("Decision Making")]),_v(": Godot mantainers discuss new features over PR meetings that happen on a regular basis before asking community members to work on them. Given the volume of requests and the number of users using the program, adding new features depends on certain principles. There has been some discussion over this issue that was very interesting: "),_c('a',{attrs:{"href":"https://github.com/godotengine/godot-proposals/issues/575"}},[_v(" Godot Engine's vision and development philosophy should be better formalized or easily accessible #575 ")])]),_v(" "),_c('p',[_v("(This user was later was banned from the organisation and "),_c('a',{attrs:{"href":"https://waiting-for-blue-robot.gitlab.io/no_longer_a_blue_robot.html"}},[_v("wrote a book about the experience")]),_v(")")]),_v(" "),_c('p',[_v("Leaving aside the drama, the point around \"What direction does an open source repository go\" was very intersting to investigate, though I haven't yet come to any conclusion. "),_c('mark',[_v("This is the source of one of my suggestions to the CS3282 team to document some of the design principles in MarkBind such as extensibility, so as to aid in new batches making decisions about the project")]),_v(". Right now, a lot of this knowledge only lives in a few people (like prof Damith). This could lead to a loss of knowledge in the future and inconsistency in the project.")]),_v(" "),_c('h3',{attrs:{"id":"sphinx"}},[_v("Sphinx"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#sphinx","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("I tested out this open source documentation when working on the Godot documentation.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://towardsdatascience.com/documenting-python-code-with-sphinx-554e1d6c4f6d"}},[_v("This Medium article")]),_v(" is a good upfront summary of setting up Sphinx. As you can see from the article, the set up process is not trivial.")]),_v(" "),_c('li',[_v("Sphinx does offer some good features such as strong search, layouts and versioning. There seem to be "),_c('a',{attrs:{"href":"https://www.sphinx-doc.org/en/master/"}},[_v("other features")]),_v(" which might be worth evaluating for MarkBind")]),_v(" "),_c('li',[_v("In my exploration with using Sphinx to run the Godot documentation, one part was very frustrating - I hated not being able to hot reload the docs as I wrote them; you have to run an additional command. This feature is very useful for MarkBind.")])]),_v(" "),_c('h3',{attrs:{"id":"hsr-optimizer"}},[_v("HSR Optimizer"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#hsr-optimizer","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_c('a',{attrs:{"href":"https://github.com/fribbels/hsr-optimizer/issues"}},[_v("HSR Optimizer")]),_v(" is a tool built to help Honkai:Star Rail players figure out how to build their characters by helping to abstract some of the math away in a user friendly interface.")]),_v(" "),_c('p',[_v("They are very light on documentation - essentially just "),_c('a',{attrs:{"href":"https://github.com/fribbels/hsr-optimizer/blob/main/GETTING_STARTED.md"}},[_v("the getting started")]),_v(" and "),_c('a',{attrs:{"href":"https://github.com/fribbels/hsr-optimizer/blob/main/CONTRIBUTING.md"}},[_v("CONTRIBUTING.MD")]),_v(" pages. To compensate for this, the discord server where development takes place is very active, and new developers are encouraged to hop over and ask questions. One advantage I noticed form having a very light set of documentation is you feel empowered to start pretty fast, as you aren't worried that you've missed something that isn't written down. However, this also does restrict some communication to a more closed platform, and knowledge about the architecture and why certain decisions are made is totally opaque unless someone calls it out explicitly. Furthermore, code comments/discussion may also occur primarily in Discord.")]),_v(" "),_c('p',[_v("An active, up to date issue tracker is mantained by the main developer, which uses a simple format of \"Motivation\" and \"Goal\" and also uses the GitHub project tracker to manage all issues. One thing I really liked about the issue tracker is that it mainly uses only two criteria - priority and size - but this is very effective as a contributor to understand what is worth working on. XS PRs only involve a small amount of code, and the are good PRs to try in multiple categories. The quick response from developers was very motivating when exploring this project.")]),_v(" "),_c('p',[_v("One nice aspect of the project is it is dogfooded by the creator and there's fairly close communication with a passionate community, so there is a clear motivation for features which are asked for and developments made. This is aided by a very clear value proposition to Honkai: Star Rail players.")]),_v(" "),_c('h3',{attrs:{"id":"react-admin"}},[_v("React-Admin"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#react-admin","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("React-Admin is a tool to build CRUD apps for business usecases very quickly. It's robust, flexible, and very easy to use. As a result, it is well adopted by the industry. I explored this project and used it for another project I was doing this semester, and also presented on this for tech talks.")]),_v(" "),_c('p',[_v("Some interesting aspects:")]),_v(" "),_c('ul',[_c('li',[_v("Funded by Enterprise - since they can pay staff and have active paying customers, they have a well-organised and updated repository as well as regular updates of both the free content and the paid/locked content")]),_v(" "),_c('li',[_v("That funding seems to have a chilling effect on outside contributors (I think), as most PRs seem to be by the team; but deprioritised issues are up for grabs by the outside community. But that isn't such a downside considering the team is unlikely to have to spend time on mentoring or helping out new contributors")]),_v(" "),_c('li',[_v("Demo pages that show features and are navigable by users. The features that are used are clearly signposted. "),_c('mark',[_v("Looking at these demo pages informed some of the issues I created fro MarkBind in terms of making things easier for new users to get started")]),_v(" - an example is my suggestion to link netlify demo pages for new users to click around in.")]),_v(" "),_c('li',[_v("Codepen for the example makes it even easier to understand how everything fits together and use exactly what is used in the examples. "),_c('strong',[_v("Markbind seems to do a similar thing with netlify deploy buttons, but with a higher barrier to entry because you must make a repo in your own account")])]),_v(" "),_c('li',[_v("Ability to guess what the shape of user data looks like to get started even more quickly. "),_c('mark',[_v("It would not be trivial but the "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("markbind init --convert")]),_v(" command could be improved to better guess the shape of the user website")])])]),_v(" "),_c('h3',{attrs:{"id":"supabase"}},[_v("Supabase"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#supabase","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Supabase. I learned: what it is and how to use it and it's capabilities. Example: learned that it can "),_c('a',{attrs:{"href":"https://supabase.com/docs/guides/database/joins-and-nesting"}},[_v("implicitly do joins")])]),_v(" "),_c('h3',{attrs:{"id":"godot-supabase"}},[_v("godot-supabase"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#godot-supabase","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("This is an addon for godot, that helps to streamline the use of supabase in godot, where it can be used as a backend. godot-supabase is not actively updated or mantained, which was also pretty discouraging for me to PR on it... I considered it since I was using it, but it seems it may not be commonly used either. This was a good experience for me to try a less-wellknown opensource repository. It was extremely useful to me, which is a good example of how open source can help people you don't know anything about.")]),_v(" "),_c('p',[_v("While documentation was relatively sparse, one advantage of the way the user developed it was by creating demos using the system and making those code repos public - though the web based demos went down, the code was still up on Godot and very helpful to figure out syntax.")]),_v(" "),_c('h3',{attrs:{"id":"my-contributions-9"}},[_v("My Contributions"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-contributions-9","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("Give a description of your contributions, including links to relevant PRs")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/godotengine/godot-docs/pull/9094"}},[_v("Add new documentation about the pre-commit hook #9094")]),_v(" - PR Merged")])]),_v(" "),_c('p',[_v("After the precommit hook was added in the godot repository, there had to be documentation added for it. I took this up because it seemed to me to be something that would affect a lotof new developers, but even though I had 3-4 reviews, it took around a month to merge, which discouraged me from trying to merge something to the Godot repository. This PR also demonstrates the rate of change and development in Godot - after the commit hook improvement was made, only a few weeks later the decision was made to change one of the linting tools - which would also modify the documentation I had written as the precommit hook helped to lint using that tool.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/fribbels/hsr-optimizer/pull/282"}},[_v("feat(#278): add button to ScoringModal to reset all characters")]),_v(" - PR merged")])]),_v(" "),_c('p',[_v("This PR modified the UI to meet user demand. I think the most interesting part of this PR was the user demand aspect - the issue originated in the discord server, where the user shared their case and that helped to surface the need for the PR. The PR was very very well-scoped - great way to familiarise with code style and the related aspect of the repo while limiting problems. Doing this PR also was useful in using Ant design.")]),_v(" "),_c('ul',[_c('li',[_c('a',{attrs:{"href":"https://github.com/fribbels/hsr-optimizer/issues/170"}},[_v("[Bug] Recalculate score for saved builds #170 ")]),_v(" - investigated & PR merged")])]),_v(" "),_c('p',[_v("Here is my transferred comment with explanation summarising discord discussion")]),_v(" "),_c('blockquote',[_c('p',[_v("There are use cases where you might not want to update your saved build with the most recent algorithm, such as with characters who can have multiple build profiles: (see #35 for more discussion. When #35 is implemented, scores will eventually be attached to scoring profiles instead of characters. The build itself should be saved with a profile attached to it instead of the behaviour we have now in the fix)")]),_v(" "),_c('p',[_v("One obvious issue with mantaining build's score based on the scoring algorithm when it was saved is the user will probably forget what their custom settings were, and it'd be a whole bunch more (out of scope) work to make a UI that makes sense for this.")]),_v(" "),_c('p',[_v("so the fix for this bug is just to get the two numbers to match by updating the saved builds since \"we want to score both the character and its saved builds by the current user defined scoring algorithm\".")])]),_v(" "),_c('p',[_v("This feature was interesting to me because of how it interfaced with the game itself. Because there are multiple ways to develop a character, players might want to score / optimise their character to different stats. This was an interesting mid-point solution working towards a bigger solution in the future (multiple saved builds)")]),_v(" "),_c('p',[_v("It was also interesting how data was separated. Originally I wrote this PR to call a function from the data class (separation of concerns) but as the data class is in .js and not .ts (slow migration) and the feature is relatively isolated, they suggested I put it all into one file where it was called instead.")]),_v(" "),_c('h3',{attrs:{"id":"my-learning-record-9"}},[_v("My Learning Record"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#my-learning-record-9","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("See knowledge.md for things learned.")])])])],1)],1),_v(" "),_c('div',[_c('box',[_c('h2',{attrs:{"id":"lee-wei-david"}},[_v("LEE WEI, DAVID"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#lee-wei-david","onclick":"event.stopPropagation()"}})]),_v(" "),_c('div',{staticClass:"container"},[_c('div',{staticClass:"row"},[_c('div',{staticClass:"col"},[_c('img',{attrs:{"src":"/2024/students/itsyme/photo.png","width":"100"}}),_c('br')]),_v(" "),_c('div',{staticClass:"col"},[_c('p',[_c('strong',[_v("GitHub:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://www.github.com/itsyme"}},[_v("https://www.github.com/itsyme")])]),_c('br')]),_v(" "),_c('p',[_c('strong',[_v("Projects:")]),_v(" "),_c('span',[_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind"}},[_v("MarkBind")])])])])])]),_v(" "),_c('p'),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Progress")])])]},proxy:true}])},[_v(" "),_c('div',[_c('div',{staticClass:"table-responsive"},[_c('table',{staticClass:"markbind-table table table-bordered table-striped"},[_c('thead',[_c('tr',[_c('th',[_v("Week")]),_v(" "),_c('th',[_v("Achievements")])])]),_v(" "),_c('tbody',[_c('tr',[_c('td',[_v("Pre-Sem")]),_v(" "),_c('td',[_v("Authored PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2303"}},[_v("Revert expand collapse all buttons #2303")])])]),_v(" "),_c('tr',[_c('td',[_v("1")]),_v(" "),_c('td',[_v("Worked on slides for Saturday code sprint (as I couldn't make it for the sprint)")])]),_v(" "),_c('tr',[_c('td',[_v("2")]),_v(" "),_c('td',[_v("Opened issues for templates "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2384"}},[_v("MarkBind Template for CS2103/Software Documentation #2384")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2385"}},[_v("MarkBind Template for Student Portfolio #2385")]),_v(", "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2386"}},[_v("MarkBind Template for Course Pages #2386")])])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Repo Cleanup: Added relevant issues to GitHub Project")])]),_v(" "),_c('tr',[_c('td',[_v("3")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2395"}},[_v("Allow markbind serve to specify custom host #2382 #2395")])])]),_v(" "),_c('tr',[_c('td',[_v("4")]),_v(" "),_c('td',[_v("Authored PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2411"}},[_v("bump nunjucks to 3.2.4 #2411")])])]),_v(" "),_c('tr',[_c('td',[_v("5")]),_v(" "),_c('td',[_v("Created Issue "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2417"}},[_v("Validation when specifying custom host #2417")])])]),_v(" "),_c('tr',[_c('td',[_v("6")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2440"}},[_v("UG > PagNav: Misleading sentence #2440")])])]),_v(" "),_c('tr',[_c('td',[_v("7")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2445"}},[_v("Optimize code printing #2445")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2450"}},[_v("Re-introduce lazy loading #2367 #2450")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2452"}},[_v("Migrate layout to Typescript #2452")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Fixed commits in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("master")]),_v(" branch due to use of \"Squash and merge\" instead of \"Rebase and merge\"")])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Authored PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2453"}},[_v("Add keeping fork up to date section in DG #2453")])])]),_v(" "),_c('tr',[_c('td',[_v("8")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2455"}},[_v("Modify release documentation to add detailed instructions on permissions #2455")])])]),_v(" "),_c('tr',[_c('td',[_v("9")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2463"}},[_v("Test logger calls in tests for NodeProcessor #2463")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Created Issue "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2478"}},[_v("Re-Implement CollapseExpandAllButtons into site-nav #2478")])])]),_v(" "),_c('tr',[_c('td',[_v("10")]),_v(" "),_c('td',[_v("Did "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/releases/tag/v5.4.0"}},[_v("Release v5.4.0")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2398"}},[_v("MarkBind Template for Student Portfolio #2398")])])]),_v(" "),_c('tr',[_c('td',[_v("11")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2482"}},[_v("Migrate core/index.js to Typescript #2482")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2484"}},[_v("Add a reminder when contributor is new to ping all contributor bot #2484")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2487"}},[_v("Fix imported modal button position off #2487")])])]),_v(" "),_c('tr',[_c('td',[_v("12")]),_v(" "),_c('td',[_v("Reveiwed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2506"}},[_v("Add warning for including empty segments or files in optional mode #2506")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2446"}},[_v("Add dataTable plugin #2446")])])]),_v(" "),_c('tr',[_c('td',[_v("13")]),_v(" "),_c('td',[_v("Fixed commits in "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("master")]),_v(" branch due to use of \"Create a merge commit\" instead of \"Squash and merge\"")])]),_v(" "),_c('tr',[_c('td',[_v("7-13")]),_v(" "),_c('td',[_v("Part of weekly sync with CS3281 students")])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2522"}},[_v("Move scripts to bottom in page.njk #2522")])])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2528"}},[_v("Add documentation regarding security practices for github actions #2528")])])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Investigated issue for CI "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/issues/2496"}},[_v("Document: Node LTS (v20) and python 3.12 does not work on MarkBind install #2496")])])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Authored PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2530"}},[_v("Add install setuptools to ci #2530")])])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2526"}},[_v("Add missing documentation for attributes overridden by slots #2526")])])]),_v(" "),_c('tr',[_c('td',[_v("R")]),_v(" "),_c('td',[_v("Reviewed PR "),_c('a',{attrs:{"href":"https://github.com/MarkBind/markbind/pull/2525"}},[_v("Add tests for logger output when component attributes are overridden by slots #2525")])])])])])])])]),_v(" "),_c('panel',{attrs:{"minimized":""},scopedSlots:_u([{key:"header",fn:function(){return [_c('p',[_c('strong',[_v("Knowledge gained")])])]},proxy:true}])},[_v(" "),_c('div',[_c('h3',{attrs:{"id":"vue-js-2"}},[_v("Vue.js"),_c('a',{staticClass:"fa fa-anchor",attrs:{"href":"#vue-js-2","onclick":"event.stopPropagation()"}})]),_v(" "),_c('p',[_v("One of the largest takeaways from working with MarkBind in the last semester has been Vue.js, an open-source front-end framework that MarkBind uses to build it's UI components. Previously, only knowing the React.js framework, Vue.js is a handy addition to my arsenal. The basics of Vue.js was rather simple to pick up. Reading the "),_c('a',{attrs:{"href":"https://vuejs.org/guide/introduction.html"}},[_v("Vue.js documentation")]),_v(", and referencing examples of already implemented Vue components in MarkBind, I quickly understood the use of "),_c('code',{pre:true,attrs:{"class":"hljs inline no-lang"}},[_v("