From 328c297436e0aba88fbb9e8753b7b8c6385fa0ef Mon Sep 17 00:00:00 2001 From: Meis Date: Mon, 14 Feb 2022 18:19:34 -0700 Subject: [PATCH 01/69] [Cypress] 2022 - Resolve V716 and V619-2 in Annual file --- .../fixtures/2022-FRONTENDTESTBANK9999.txt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cypress/fixtures/2022-FRONTENDTESTBANK9999.txt b/cypress/fixtures/2022-FRONTENDTESTBANK9999.txt index 9e9639907..f302bfc95 100644 --- a/cypress/fixtures/2022-FRONTENDTESTBANK9999.txt +++ b/cypress/fixtures/2022-FRONTENDTESTBANK9999.txt @@ -1,11 +1,11 @@ 1|FRONTENDTESTBANK9999|2022|4|Mr. Smug Pockets|555-555-5555|pockets@ficus.com|1234 Hocus Potato Way|Tatertown|UT|84096|9|10|53-1111111|FRONTENDTESTBANK9999 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999JAJZMZSDXF8A57HP1HJZQOZ66|20210613|3|2|2|2|3|218910|5|20210913|1234 Hocus Potato Way|Tatertown|NM|14755|12075|12075970400|1|13||11||KE0NW|1|||||NA2IJJ7VBBQ15DTFRNK1PVWOPOXL3NH1PHUMN7S2J4|2|2|7|||||E120FYAU7BTSC3P51IL87C97W3N9VT791BMJI57RLJQSHOFDTUD7PQSPGHQ69D7I2P8JBDCBUIGRLX2BUS7SJR|DOOOI8UXY9PZDSRVFKP91CUQG95E88Y22KDR1AI3|1K1JINAYSIHCWBGJW3KOHU5D5TSK1Z61SUT5M9WQVWOHX|27|24|41|43|2|MS1LKLX7XZRKL23TV01I49RADZGUN0QY5AG9H4BJCVFTA4ZQ1EJUS1376QJXD87ZZDN5EFZIUWB8SK5EU34RVGOVTE|Y083OZN1VFT6B2XGL397ABL0Z4EV4CD45I7ZJ7FRSXXL4BRMKVPR5UCVV0K6IDLP7WLCBZAQ5KXT69PNE9PWQKCPKJB|UV0FTHG00G8WM65I7591IJYP9TEMXMDCVGZYRJTBUBBKEZI65HGL9ML|3|2|2|2|1|1|75|4|NA|0|NA|3|2|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|32|NA|NA|256|29|1111|1111|1111|1111|NA|3|2|16|Exempt|2|2|NA|3|1|5|1||DOREBESQSW1QT58SD2OZTHQUGXLSKCAJYZ63NJE2MUIAFQL4KW6PU26YSU786GT0IMCWWKCN25Y7KU0VLU0PPKWR8G6DKWI9BANPIE9I2ZZ5XDUX0TBAY4XFRFQZF087WS9ESTAKIV5V9HSZ2VXW7J5JMGPP4CGYA51BK68T57NN4KTKJVXIQMFXBTN5E3LGKKX3LITQ4C7OPFJ|7|6|5|5|||1111|2|1111 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999D7FLMYAQU3A27O2YMZM0M7O40|NA|2|2|2|2|3|333835|6|20211221|Exempt|Exempt|MD|Exempt|24005|24005411307|2|||||ZW7WDQK1904WRV8V703SW14U8RVTN3NTGJU74JT8IKZD6Q1SG0UFNQTCW8VZFT8BNCCXRPVFFDIHYCPTJABPPLVRJW|2|1||||3OFU|1|1|4||41|27|44|KKHW809PRP|0WYJKE6HXKA4XQGK3X4TP2|5V6APWVXJPN52LLJ3EFKV8A2DKRR50PDWA08BO3UVRSS584VHFUGCJ37YIVBCLE1WG|44|43|27|1|4|RO3KGE6NGR|XKB0K7HHU|Q54JC5Z9FMCY3LXW6ZTLL1OL75RI16W0KX59K1VFPE75KHYWCDJS7PZUDF|2|2|4|4|3|3|74|30|NA|6|NA|3|1|8888|8888|9||9||10|||||NA|NA|7273|4218|9266|21.21|NA|NA|NA|89|12|1111|1111|1111|1111|752565|3|5|29|15|3|3|NA|6||||||17||||||2|2|1111 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK99992D86K2HB6JZVFPIHG72A9ML89|20210615|1|32|2|2|1|32153|2|20211221|Exempt|Exempt|TX|Exempt|48113|48113016302|2|13|14|12|11|58NEWEVSRFYEPX1G1TLP00DHRUI9TN3RIU35KN4V4K4Z7QLWSGYCUFBK5JVFOD09NHXVNULHRFSRDWAJ9ZJJUJ|14|1|12||13|6WPH8YHK0WLJOZLH9QX7EJ9N9OW6G86GF7L7Y|2|2|2|3|1|5|4|DL4VGN1RVXOV2K3Y2FYDSPLYTH0UXU2OLJN|G3XFURJGQYOAS8VJP1ZJ6MUJP2VWZ092JRS9H6SGOE0MTI8OQJ83E2A5VCWYTB69J60QDLV2AKLA1UVUN0OMF5I|2|8|||||KJERDZB84RC3X4IPJUPL54O7V4G9GOHVT0W0LVUFCGCA8X00DQWO4MWJ97XRIQW9HWIKM0FW2X5YQ8|W89CG5WDC20SE84FUN|V10VL5B39K1I1HJLVMAUW8XJE37Y5UOVLLPFNPSO1T4IDWURCTP4Q3ECBC1FV9G8A4GR16FQXRV9QHNX2QSDX3MMY0Z|1|4|3|2|2|2|75|16|NA|0|17.17|3|2|778|659|5||8|2O91IBQI8BQ015E1PJU1O41R5F6YJQC2UZD3C9MT0ZZV1ONHCQS60TU0AJEVAN6|10|||||NA|NA|NA|NA|NA|17.17|32|NA|60|164|9|1111|1111|1111|1111|711850|3|5|20|3|1111|1111|NA|1|1|4||||2|3|1||||2|1111|2 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK99990FKQC8WR3V4AJP7GQ6EAPE631|20210416|3|2|2|2|3|53323|5|20211221|1234 Hocus Potato Way|Tatertown|MI|12144|26045|26045020601|2|||||ZAVSGED3A7O2EEKULYGPM7JKA79K6T6EDOB6BGV5OQQEUPT2|2|14|11||1|TX5I|1|2|3|2|4|5|1|B6LNQPESDFFYIFUG7LVMNK6INE6SD1MIWKOSFD2LY4V42ZCGCH5EC1VUBY5L226BG|90UCYIPFNV857RH8XZPG538LOQ|3CFG9EA8R0C0TAWB29Y8ZCC9QAYLRLKH07C5L5SIEESJII48KH1F40XI6FLXFX8J9IG0BX1W|6|||||BMIPP01AZG76BAM5QRX6ZHGA8UP2GAH2MWKZD0W2Z8V|0AZ8MF7FP0BB0K4ERSABUC25WJ4J7NW1JCO8ZTYT4WHH3MIXG369DCAMDJHRMNH0DW7NRW5DPTDG3VMDS|SDCR9OG56GK1EXBORBYZJFZEH6NIJ|1|3|2|1|2|2|60|5|245|0|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|3|NA|NA|34|13|1111|1111|1111|1111|NA|1|1111|8|NA|2|3|NA|5|1|4|1||QP5WFS4TKMX6OM9DC6X1KXLY2T98Z9KXJ8CAF7TZYOG3FWDIGC696ZBTO6Z0VZ8I2L3AI8HZ3IUVM5CNJIR8US37U5EEG45OXC55ADR8O1LR3ODFTH2HC3IEVZ64HLJG4L|10|3|6|3|||1111|1|2 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MB4EBCIXBLY98W5WLPB97X956|20210312|1|1|2|2|2|251981|5|20210913|1234 Hocus Potato Way|Tatertown|NY|22025|36047|36047116600|4|||||6N2L65BOG5B93X6FEW7K54NGW4GTQ9GUZ8V6CQYZWLJ70H89KHG9F5G2ZKFMQ6OAX6SET9KV9J5UFDXF7WHSRWNXK|5|||||P2Z5DKOLC0EXL62S51A37T4NQR0AOWKNAF2RCS5RJLJB7XVL9NSDVAQKXTR8Q332YF3F613G1UVG1J4KAGJQFSQNF|3|4|2|||||TI9DDZP830IBD02DH95AJCAG57S9CV32ZK7A97UQPMFKZTXI21QQX2K59Y51NNT2UZZMK4AH4|VCDC254RNE|JZKOBJHMK5Q1ZHWA5MZUP21HMUVQONRW9QS1UR8JRDS9OPLBWUDB2JH03EN63H1WOBEAA6H9OVUPKMKHMJSYZT0PLUW35RQAOU|7|||||2JGS46UO6XRWDM93TI01F4UF9DN4PRJZW|JDVCG1N7ONSUCFWG8WRVM3561716R969AKLHD7VJR|I44W34IUTYH5L8GQVD3TYY1WYJ3J1YCUKTL1OWNWNK8NI8MV539E1CRBB4FOJDUAWT1XGP0YQG41MF3FX|2|3|2|2|1|1|100|69|NA|0|NA|3|2|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|34|NA|NA|180|3|1111|1111|1111|1111|NA|3|5|22|10|1111|1111|NA|1||||||1||||||1111|1111|1111 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MG9LY2DFTDM01XUP7VZ5KPX29|20210228|1|4|2|2|2|131385|2|20210913|1234 Hocus Potato Way|Tatertown|MN|66963|27113|27113090400|1|||||ZFBYIFPDQR78DPE0D8Z902DHM8U9MW0GU|4|||||B87H13ZS768INKWKQ482V15YEMR9JWPWTDVVWBHDKYJ9U5X9B9F51OWYNWEQJ9XUACCC9RSX29LZ923MBQWJ8P|1|3|6|||||JRHC9X7I7Y|W6BD2ZJWAIQE|5KW7FKS51|8|||||SS6ZU4UTFA50OGO37HQ3YRKFY2FJF8TE7CGQ|Q2PP7MJZ54DO1F427WDL6JVUUZY0CM6OUCHFJ5OZTA51BC5ZJPTL3QI6Z|Q9DZIEL|3|4|2|2|1|1|21|65|NA|0|18.18|3|1|8888|703|9||8|V1B49UO22BPBZSZB3KDOOM5LS8QS99Q2M6QA5H6PYOH8RWA|10|||||NA|NA|NA|NA|NA|10.1|33|NA|27|246|34|1111|1111|1111|1111|887751|3|5|15|12|1111|1111|NA|1||3||4||1||3||3||1111|1111|2 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999EOOE8G89OT03UW42AXMZZC874|20211105|1|4|2|1|1|6273|5|20211221|1234 Hocus Potato Way|Tatertown|TN|30068|47157|47157021126|3|||||3UCQA795LJFIVVG8356RB4GCJPBHHUMZY2LCFDEZDESK3TLMHOHKQ475UCBL1N8VKYDJG88LEEB607HU7HFVI387B3|1|2||||WGRZE26CSKF06BNZRB7IMBGEI1764CA188H|3|1|1|5|3|4|2|024K0SKX9|IO523XCTCLNRI0L7FY9JARYNU4C90G1VQHKZOH3CBY67AY2PFVZ3IYUKVHTFCG5TGNSFVP7B2RHXNFKQCANFI9FWYOQFB8AWG|BTYOI3VLX4X4I00EUN7IAMZ98WGR2KGKMBF0YS21ELZIKE8T9Y6C5Z4TI3RZFQOEK87HAPG|8|||||FP9AZVY7Y64US2E1P49DMNQY03JP6Y|8AVOYZIWGGCF|KL50O3LNI1Q0FSEW8DNA8TB55PLU2I0PYF7O9ZHHB1RPCQHS5W7VNMHC3Q3AD7FUUH8ZZ83HBJU8UDFJN|1|4|2|1|1|1|33|98|73|0|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|7|NA|NA|294|6|1111|1111|1111|1111|NA|3|5|11|NA|1|3|NA|2||||2||8||||8||2|1|1111 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999PSKL6Y7NHQWC1MI6XZS2YOU13|20211202|2|2|2|2|3|36312|1|20211221|1234 Hocus Potato Way|Tatertown|FL|20172|12095|12095013607|1|||||5FYG0L2TWMF8SLH0F77JH1RP9WMHPIYAZ2UQ34EOTAPRT3S0IUR0GM1JW2ADCTWSQBKB039XPN06933LI|1|2||||BMPTP33A7WXKWXK7O9MGJJP89UGF7N9Q9UG8KWTML1UC17|1|1|4|2|1|5|3|TB6EA116FYD9375EZJPY2NKQTFNV8SEZ20KM9F1E3EX5UUL8I5D3NV3S3VLP|PPPTMDDD6|V8T253DUD2A6YSV5WYERFTX1DMXAHB|27|25||22|5|Y05PB05POTUTGAPPE5SE4YFB7EB7VZ3G3JRFA46WFXC8DLFXXHHRSZYDHEC7O|U7AK68XREC65R6HBHK92CL8L3PBLD8TAEM9DLL2C2BHT3AQF3MCZ1LOFJH8T12EGO7|6LJQAQX629HQ5SDQW5UGQZY674D4Q4O7UPUUS6JXU5K6CX0J53GQHGZ2JPJLCR0OWTVBBM4CDBF7M3|1|2|2|2|2|1|65|42|NA|6|NA|2|1|669|656|8|RNXKZEN6M28V7U7KLRFIPN8AZXK7RBL3DJK927LQBK03|8|ULO8PN7Z58O4U5AU2GUQ4Y1H0JTN23WKH4UPJ8U6VYQRO9YH8WDT4GYCMHJ5MZ36A0X2WST3K7|10|||||NA|NA|NA|NA|NA|2.02|NA|NA|89|NA|30|1|2|2|1|118769|3|5|16|15|2|2|NA|3||||2||4||||8||1|2|1 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999Z84EL0SA9X4QD3Q5QMM0EEC78|20210322|4|4|2|2|2|176492|3|20211221|1234 Hocus Potato Way|Tatertown|MA|68714|25009|25009221700|1|||||D3HGC2SLFGNWBIRSN7U2DZID0NMGL0A0DPW09XKDW5YAZSW7A8RZVCQF3MF9X72MMK6JOLVNHC9EUD|1|2||||K0CC4OWK2FCUD564W44FV5K6H545IQMZHCCFPS6XM8UISLLZS1LH060I72JD3HSTXEERQ7SUH1K9SC8IT5EG1L2FN|1|1|7|||||H8D7D|GKXP92HNJZ|AKLRMH|6|||||V4|FD0C2LLMN8AGU2UKVQSWB6LLZ11L4U90M1R457UY9SHCRFSNOOZ97ZH91|CZ2Z5JSVGR815SE5HOGMMQ2RCBRE04NTJ68S7AP3HTXEVM1OUH2K579NKU98113DTAYBOZRTGC5TRCWGHWKZM46P6|3|3|2|1|1|2|102|37|NA|0|NA|3|2|8888|774|9||3||3|5|4|2||NA|NA|NA|NA|NA|NA|NA|NA|44|196|27|1111|1111|1111|1111|925106|3|5|22|20|1|3|NA|4|1||2|||8|1||11|||1111|2|1 -2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MGJIPL5D07WUU8HO33EPNI908|NA|1|4|2|2|1|410946|6|20210913|1234 Hocus Potato Way|Tatertown|PA|24250|42029|42029300301|1|||||OAORAGNCTSIBXEAUGJMKVU0GGB2IKGORJWFXAOOLNWYEC4AT63E71SMYN0K8IK3FQQO3IXQL3V9T|1|||13|2|CY88KIDBS9KP7LAJ42H972Y|1|2|4||||25|S5XZPEM10E1F226PW37SG36RBX24AISMUE7OBLJ2KKOK8HDT|GXAXY0BWUX75UG5X03L0VSGE5SAURB5C3KXVSHQY3HY4B4L6MYHYCHU60C8NPPSM3TTOLHK7DY7SJ|KH29APHQO32HUBEVZOIYLSZVI440WS9M5VHLJOCPH3Y8VINQG9QU8RMP5GN2DX0GXSA9|5|||||B2MD8GCA|2HFLMNMG44YX5KFBGKOVC1V04E3TCAXAKWJ47MXNP9D1IP5WS1XTPAB7H82JNAVDX48EHRWE0YBW8GVUQFWJQ|EV31S0E59HYHJGUM25DQCSSHLY4FFFYR0BZ87A9MIE4ECCG9CBJ|2|1|1|2|2|1|23|30|NA|2|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|12.120000000000001|NA|NA|NA|238|14|1|1|2|2|172918|3|5|27|15|3|3|NA|6||||||17||||||1111|1|2 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999JAJZMZSDXF8A57HP1HJZQOZ66|20220613|3|2|2|2|3|218910|5|20220913|1234 Hocus Potato Way|Little Valley|NY|14755|36009|NA|1|13||11||KE0NW|1|||||NA2IJJ7VBBQ15DTFRNK1PVWOPOXL3NH1PHUMN7S2J4|2|2|7|||||E120FYAU7BTSC3P51IL87C97W3N9VT791BMJI57RLJQSHOFDTUD7PQSPGHQ69D7I2P8JBDCBUIGRLX2BUS7SJR|DOOOI8UXY9PZDSRVFKP91CUQG95E88Y22KDR1AI3|1K1JINAYSIHCWBGJW3KOHU5D5TSK1Z61SUT5M9WQVWOHX|27|24|41|43|2|MS1LKLX7XZRKL23TV01I49RADZGUN0QY5AG9H4BJCVFTA4ZQ1EJUS1376QJXD87ZZDN5EFZIUWB8SK5EU34RVGOVTE|Y083OZN1VFT6B2XGL397ABL0Z4EV4CD45I7ZJ7FRSXXL4BRMKVPR5UCVV0K6IDLP7WLCBZAQ5KXT69PNE9PWQKCPKJB|UV0FTHG00G8WM65I7591IJYP9TEMXMDCVGZYRJTBUBBKEZI65HGL9ML|3|2|2|2|1|1|75|4|NA|0|NA|3|2|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|32|NA|NA|256|29|1111|1111|1111|1111|NA|3|2|16|Exempt|2|2|NA|3|1|5|1||DOREBESQSW1QT58SD2OZTHQUGXLSKCAJYZ63NJE2MUIAFQL4KW6PU26YSU786GT0IMCWWKCN25Y7KU0VLU0PPKWR8G6DKWI9BANPIE9I2ZZ5XDUX0TBAY4XFRFQZF087WS9ESTAKIV5V9HSZ2VXW7J5JMGPP4CGYA51BK68T57NN4KTKJVXIQMFXBTN5E3LGKKX3LITQ4C7OPFJ|7|6|5|5|||1111|2|1111 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999D7FLMYAQU3A27O2YMZM0M7O40|NA|2|2|2|2|3|333835|6|20221221|Exempt|Exempt|MD|Exempt|24005|24005411307|2|||||ZW7WDQK1904WRV8V703SW14U8RVTN3NTGJU74JT8IKZD6Q1SG0UFNQTCW8VZFT8BNCCXRPVFFDIHYCPTJABPPLVRJW|2|1||||3OFU|1|1|4||41|27|44|KKHW809PRP|0WYJKE6HXKA4XQGK3X4TP2|5V6APWVXJPN52LLJ3EFKV8A2DKRR50PDWA08BO3UVRSS584VHFUGCJ37YIVBCLE1WG|44|43|27|1|4|RO3KGE6NGR|XKB0K7HHU|Q54JC5Z9FMCY3LXW6ZTLL1OL75RI16W0KX59K1VFPE75KHYWCDJS7PZUDF|2|2|4|4|3|3|74|30|NA|6|NA|3|1|8888|8888|9||9||10|||||NA|NA|7273|4218|9266|21.21|NA|NA|NA|89|12|1111|1111|1111|1111|752565|3|5|29|15|3|3|NA|6||||||17||||||2|2|1111 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK99992D86K2HB6JZVFPIHG72A9ML89|20220615|1|32|2|2|1|32153|2|20221221|Exempt|Exempt|TX|Exempt|48113|48113016302|2|13|14|12|11|58NEWEVSRFYEPX1G1TLP00DHRUI9TN3RIU35KN4V4K4Z7QLWSGYCUFBK5JVFOD09NHXVNULHRFSRDWAJ9ZJJUJ|14|1|12||13|6WPH8YHK0WLJOZLH9QX7EJ9N9OW6G86GF7L7Y|2|2|2|3|1|5|4|DL4VGN1RVXOV2K3Y2FYDSPLYTH0UXU2OLJN|G3XFURJGQYOAS8VJP1ZJ6MUJP2VWZ092JRS9H6SGOE0MTI8OQJ83E2A5VCWYTB69J60QDLV2AKLA1UVUN0OMF5I|2|8|||||KJERDZB84RC3X4IPJUPL54O7V4G9GOHVT0W0LVUFCGCA8X00DQWO4MWJ97XRIQW9HWIKM0FW2X5YQ8|W89CG5WDC20SE84FUN|V10VL5B39K1I1HJLVMAUW8XJE37Y5UOVLLPFNPSO1T4IDWURCTP4Q3ECBC1FV9G8A4GR16FQXRV9QHNX2QSDX3MMY0Z|1|4|3|2|2|2|75|16|NA|0|17.17|3|2|778|659|5||8|2O91IBQI8BQ015E1PJU1O41R5F6YJQC2UZD3C9MT0ZZV1ONHCQS60TU0AJEVAN6|10|||||NA|NA|NA|NA|NA|17.17|32|NA|60|164|9|1111|1111|1111|1111|711850|3|5|20|3|1111|1111|NA|1|1|4||||2|3|1||||2|1111|2 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK99990FKQC8WR3V4AJP7GQ6EAPE631|20220416|3|2|2|2|3|53323|5|20221221|1234 Hocus Potato Way|Tatertown|MI|12144|26045|26045020601|2|||||ZAVSGED3A7O2EEKULYGPM7JKA79K6T6EDOB6BGV5OQQEUPT2|2|14|11||1|TX5I|1|2|3|2|4|5|1|B6LNQPESDFFYIFUG7LVMNK6INE6SD1MIWKOSFD2LY4V42ZCGCH5EC1VUBY5L226BG|90UCYIPFNV857RH8XZPG538LOQ|3CFG9EA8R0C0TAWB29Y8ZCC9QAYLRLKH07C5L5SIEESJII48KH1F40XI6FLXFX8J9IG0BX1W|6|||||BMIPP01AZG76BAM5QRX6ZHGA8UP2GAH2MWKZD0W2Z8V|0AZ8MF7FP0BB0K4ERSABUC25WJ4J7NW1JCO8ZTYT4WHH3MIXG369DCAMDJHRMNH0DW7NRW5DPTDG3VMDS|SDCR9OG56GK1EXBORBYZJFZEH6NIJ|1|3|2|1|2|2|60|5|245|0|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|3|NA|NA|34|13|1111|1111|1111|1111|NA|1|1111|8|NA|2|3|NA|5|1|4|1||QP5WFS4TKMX6OM9DC6X1KXLY2T98Z9KXJ8CAF7TZYOG3FWDIGC696ZBTO6Z0VZ8I2L3AI8HZ3IUVM5CNJIR8US37U5EEG45OXC55ADR8O1LR3ODFTH2HC3IEVZ64HLJG4L|10|3|6|3|||1111|1|2 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MB4EBCIXBLY98W5WLPB97X956|20220312|1|1|2|2|2|251981|5|20220913|1234 Hocus Potato Way|Tatertown|NY|22025|36047|36047116600|4|||||6N2L65BOG5B93X6FEW7K54NGW4GTQ9GUZ8V6CQYZWLJ70H89KHG9F5G2ZKFMQ6OAX6SET9KV9J5UFDXF7WHSRWNXK|5|||||P2Z5DKOLC0EXL62S51A37T4NQR0AOWKNAF2RCS5RJLJB7XVL9NSDVAQKXTR8Q332YF3F613G1UVG1J4KAGJQFSQNF|3|4|2|||||TI9DDZP830IBD02DH95AJCAG57S9CV32ZK7A97UQPMFKZTXI21QQX2K59Y51NNT2UZZMK4AH4|VCDC254RNE|JZKOBJHMK5Q1ZHWA5MZUP21HMUVQONRW9QS1UR8JRDS9OPLBWUDB2JH03EN63H1WOBEAA6H9OVUPKMKHMJSYZT0PLUW35RQAOU|7|||||2JGS46UO6XRWDM93TI01F4UF9DN4PRJZW|JDVCG1N7ONSUCFWG8WRVM3561716R969AKLHD7VJR|I44W34IUTYH5L8GQVD3TYY1WYJ3J1YCUKTL1OWNWNK8NI8MV539E1CRBB4FOJDUAWT1XGP0YQG41MF3FX|2|3|2|2|1|1|100|69|NA|0|NA|3|2|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|34|NA|NA|180|3|1111|1111|1111|1111|NA|3|5|22|10|1111|1111|NA|1||||||1||||||1111|1111|1111 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MG9LY2DFTDM01XUP7VZ5KPX29|20220228|1|4|2|2|2|131385|2|20220913|1234 Hocus Potato Way|Tatertown|MN|66963|27113|27113090400|1|||||ZFBYIFPDQR78DPE0D8Z902DHM8U9MW0GU|4|||||B87H13ZS768INKWKQ482V15YEMR9JWPWTDVVWBHDKYJ9U5X9B9F51OWYNWEQJ9XUACCC9RSX29LZ923MBQWJ8P|1|3|6|||||JRHC9X7I7Y|W6BD2ZJWAIQE|5KW7FKS51|8|||||SS6ZU4UTFA50OGO37HQ3YRKFY2FJF8TE7CGQ|Q2PP7MJZ54DO1F427WDL6JVUUZY0CM6OUCHFJ5OZTA51BC5ZJPTL3QI6Z|Q9DZIEL|3|4|2|2|1|1|21|65|NA|0|18.18|3|1|8888|703|9||8|V1B49UO22BPBZSZB3KDOOM5LS8QS99Q2M6QA5H6PYOH8RWA|10|||||NA|NA|NA|NA|NA|10.1|33|NA|27|246|34|1111|1111|1111|1111|887751|3|5|15|12|1111|1111|NA|1||3||4||1||3||3||1111|1111|2 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999EOOE8G89OT03UW42AXMZZC874|20221105|1|4|2|1|1|6273|5|20221221|1234 Hocus Potato Way|Tatertown|TN|30068|47157|47157021126|3|||||3UCQA795LJFIVVG8356RB4GCJPBHHUMZY2LCFDEZDESK3TLMHOHKQ475UCBL1N8VKYDJG88LEEB607HU7HFVI387B3|1|2||||WGRZE26CSKF06BNZRB7IMBGEI1764CA188H|3|1|1|5|3|4|2|024K0SKX9|IO523XCTCLNRI0L7FY9JARYNU4C90G1VQHKZOH3CBY67AY2PFVZ3IYUKVHTFCG5TGNSFVP7B2RHXNFKQCANFI9FWYOQFB8AWG|BTYOI3VLX4X4I00EUN7IAMZ98WGR2KGKMBF0YS21ELZIKE8T9Y6C5Z4TI3RZFQOEK87HAPG|8|||||FP9AZVY7Y64US2E1P49DMNQY03JP6Y|8AVOYZIWGGCF|KL50O3LNI1Q0FSEW8DNA8TB55PLU2I0PYF7O9ZHHB1RPCQHS5W7VNMHC3Q3AD7FUUH8ZZ83HBJU8UDFJN|1|4|2|1|1|1|33|98|73|0|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|NA|7|NA|NA|294|6|1111|1111|1111|1111|NA|3|5|11|NA|1|3|NA|2||||2||8||||8||2|1|1111 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999PSKL6Y7NHQWC1MI6XZS2YOU13|20221202|2|2|2|2|3|36312|1|20221221|1234 Hocus Potato Way|Tatertown|FL|20172|12095|12095013607|1|||||5FYG0L2TWMF8SLH0F77JH1RP9WMHPIYAZ2UQ34EOTAPRT3S0IUR0GM1JW2ADCTWSQBKB039XPN06933LI|1|2||||BMPTP33A7WXKWXK7O9MGJJP89UGF7N9Q9UG8KWTML1UC17|1|1|4|2|1|5|3|TB6EA116FYD9375EZJPY2NKQTFNV8SEZ20KM9F1E3EX5UUL8I5D3NV3S3VLP|PPPTMDDD6|V8T253DUD2A6YSV5WYERFTX1DMXAHB|27|25||22|5|Y05PB05POTUTGAPPE5SE4YFB7EB7VZ3G3JRFA46WFXC8DLFXXHHRSZYDHEC7O|U7AK68XREC65R6HBHK92CL8L3PBLD8TAEM9DLL2C2BHT3AQF3MCZ1LOFJH8T12EGO7|6LJQAQX629HQ5SDQW5UGQZY674D4Q4O7UPUUS6JXU5K6CX0J53GQHGZ2JPJLCR0OWTVBBM4CDBF7M3|1|2|2|2|2|1|65|42|NA|6|NA|2|1|669|656|8|RNXKZEN6M28V7U7KLRFIPN8AZXK7RBL3DJK927LQBK03|8|ULO8PN7Z58O4U5AU2GUQ4Y1H0JTN23WKH4UPJ8U6VYQRO9YH8WDT4GYCMHJ5MZ36A0X2WST3K7|10|||||NA|NA|NA|NA|NA|2.02|NA|NA|89|NA|30|1|2|2|1|118769|3|5|16|15|2|2|NA|3||||2||4||||8||1|2|1 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999Z84EL0SA9X4QD3Q5QMM0EEC78|20220322|4|4|2|2|2|176492|3|20221221|1234 Hocus Potato Way|Tatertown|MA|68714|25009|25009221700|1|||||D3HGC2SLFGNWBIRSN7U2DZID0NMGL0A0DPW09XKDW5YAZSW7A8RZVCQF3MF9X72MMK6JOLVNHC9EUD|1|2||||K0CC4OWK2FCUD564W44FV5K6H545IQMZHCCFPS6XM8UISLLZS1LH060I72JD3HSTXEERQ7SUH1K9SC8IT5EG1L2FN|1|1|7|||||H8D7D|GKXP92HNJZ|AKLRMH|6|||||V4|FD0C2LLMN8AGU2UKVQSWB6LLZ11L4U90M1R457UY9SHCRFSNOOZ97ZH91|CZ2Z5JSVGR815SE5HOGMMQ2RCBRE04NTJ68S7AP3HTXEVM1OUH2K579NKU98113DTAYBOZRTGC5TRCWGHWKZM46P6|3|3|2|1|1|2|102|37|NA|0|NA|3|2|8888|774|9||3||3|5|4|2||NA|NA|NA|NA|NA|NA|NA|NA|44|196|27|1111|1111|1111|1111|925106|3|5|22|20|1|3|NA|4|1||2|||8|1||11|||1111|2|1 +2|FRONTENDTESTBANK9999|FRONTENDTESTBANK9999MGJIPL5D07WUU8HO33EPNI908|NA|1|4|2|2|1|410946|6|20220913|1234 Hocus Potato Way|Tatertown|PA|24250|42029|42029300301|1|||||OAORAGNCTSIBXEAUGJMKVU0GGB2IKGORJWFXAOOLNWYEC4AT63E71SMYN0K8IK3FQQO3IXQL3V9T|1|||13|2|CY88KIDBS9KP7LAJ42H972Y|1|2|4||||25|S5XZPEM10E1F226PW37SG36RBX24AISMUE7OBLJ2KKOK8HDT|GXAXY0BWUX75UG5X03L0VSGE5SAURB5C3KXVSHQY3HY4B4L6MYHYCHU60C8NPPSM3TTOLHK7DY7SJ|KH29APHQO32HUBEVZOIYLSZVI440WS9M5VHLJOCPH3Y8VINQG9QU8RMP5GN2DX0GXSA9|5|||||B2MD8GCA|2HFLMNMG44YX5KFBGKOVC1V04E3TCAXAKWJ47MXNP9D1IP5WS1XTPAB7H82JNAVDX48EHRWE0YBW8GVUQFWJQ|EV31S0E59HYHJGUM25DQCSSHLY4FFFYR0BZ87A9MIE4ECCG9CBJ|2|1|1|2|2|1|23|30|NA|2|NA|3|1|8888|8888|9||9||10|||||NA|NA|NA|NA|NA|12.120000000000001|NA|NA|NA|238|14|1|1|2|2|172918|3|5|27|15|3|3|NA|6||||||17||||||1111|1|2 \ No newline at end of file From 3370e7026a6d8b87c9839d8a6853350a8b2c5506 Mon Sep 17 00:00:00 2001 From: Wyatt Pearsall Date: Wed, 16 Feb 2022 15:26:01 -0500 Subject: [PATCH 02/69] Update README.md typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ae492b1da..abe9aba4a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # HMDA Frontend Projects -The HDMA Frontend monorepo hosts the public facing applications for the collection, publication, and navigation of millions of HMDA records per year. This repository combines six, previously separate, React application repos in order to simplify component sharing, synchronize versioning of common dependencies, and improve rendering efficiency when navigating between apps. +The HMDA Frontend monorepo hosts the public facing applications for the collection, publication, and navigation of millions of HMDA records per year. This repository combines six, previously separate, React application repos in order to simplify component sharing, synchronize versioning of common dependencies, and improve rendering efficiency when navigating between apps. ## Contents - [HMDA Frontend Projects](#hmda-frontend-projects) @@ -203,4 +203,4 @@ In the event that you need to review video to help debug CI failures, update the CONFIG="--config video=true" RECORD="--record" CYPRESS_RECORD_KEY= -``` \ No newline at end of file +``` From 34ac859505f84fdea360403434b3d22cc7b61ffa Mon Sep 17 00:00:00 2001 From: Meis Date: Thu, 10 Feb 2022 12:45:43 -0700 Subject: [PATCH 03/69] Online LARFT - v0.1.0 --- .../react-fluid-table-0.4.2.tgz | Bin 0 -> 18298 bytes package.json | 1 + src/tools/index.js | 2 + src/tools/online-lar-formatting/FileUpload.js | 43 + src/tools/online-lar-formatting/Header.jsx | 38 + src/tools/online-lar-formatting/ParsedRow.jsx | 174 + src/tools/online-lar-formatting/RawRow.jsx | 119 + src/tools/online-lar-formatting/SavedRows.jsx | 90 + .../online-lar-formatting/SchemaLar.json | 3475 +++++++++++++++++ .../online-lar-formatting/SchemaLarRaw.js | 116 + src/tools/online-lar-formatting/SchemaTs.json | 217 + .../online-lar-formatting/SchemaTsRaw.js | 21 + src/tools/online-lar-formatting/index.css | 124 + src/tools/online-lar-formatting/index.jsx | 254 ++ .../online-lar-formatting/schemaGenerator.js | 96 + .../temp_enumerations.txt | 63 + src/tools/online-lar-formatting/utils.js | 56 + yarn.lock | 9 +- 18 files changed, 4897 insertions(+), 1 deletion(-) create mode 100644 npm-packages-offline-cache/react-fluid-table-0.4.2.tgz create mode 100644 src/tools/online-lar-formatting/FileUpload.js create mode 100644 src/tools/online-lar-formatting/Header.jsx create mode 100644 src/tools/online-lar-formatting/ParsedRow.jsx create mode 100644 src/tools/online-lar-formatting/RawRow.jsx create mode 100644 src/tools/online-lar-formatting/SavedRows.jsx create mode 100644 src/tools/online-lar-formatting/SchemaLar.json create mode 100644 src/tools/online-lar-formatting/SchemaLarRaw.js create mode 100644 src/tools/online-lar-formatting/SchemaTs.json create mode 100644 src/tools/online-lar-formatting/SchemaTsRaw.js create mode 100644 src/tools/online-lar-formatting/index.css create mode 100644 src/tools/online-lar-formatting/index.jsx create mode 100644 src/tools/online-lar-formatting/schemaGenerator.js create mode 100644 src/tools/online-lar-formatting/temp_enumerations.txt create mode 100644 src/tools/online-lar-formatting/utils.js diff --git a/npm-packages-offline-cache/react-fluid-table-0.4.2.tgz b/npm-packages-offline-cache/react-fluid-table-0.4.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f67accc3774cfa374cfd436250c4e211d8b14e56 GIT binary patch literal 18298 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 Juy+7P0RY!|F3kV{ literal 0 HcmV?d00001 diff --git a/package.json b/package.json index 241dc8cc6..705cf8e8e 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "react-dev-utils": "11.0.4", "react-dom": "16.13.1", "react-dropzone": "10.2.2", + "react-fluid-table": "^0.4.2", "react-helmet": "5.2.1", "react-highlight-words": "0.17.0", "react-redux": "7.2.4", diff --git a/src/tools/index.js b/src/tools/index.js index a8e56e17f..43e32a32c 100644 --- a/src/tools/index.js +++ b/src/tools/index.js @@ -8,6 +8,7 @@ import RateSpreadRequirements from './rate-spread/Requirements' import RateSpreadMethodology from './rate-spread/Methodology' import FFVT from './file-format-verification/index' import LARFormatting from './lar-formatting/index' +import { OnlineLARFT } from './online-lar-formatting' import './index.css' @@ -28,6 +29,7 @@ const Tools = () => { + ) diff --git a/src/tools/online-lar-formatting/FileUpload.js b/src/tools/online-lar-formatting/FileUpload.js new file mode 100644 index 000000000..6781278a1 --- /dev/null +++ b/src/tools/online-lar-formatting/FileUpload.js @@ -0,0 +1,43 @@ +import React from 'react'; + +/** + * Read user-selected file contents. + * https://gist.github.com/ilonacodes/5159f439c801004ff6505179756fac9f#file-index-jsx + * @param {function} onContentReady Callback the gets the file content when ready + * @param {boolean} isHidden Hide the default UI + * @param {String} inputId ID of the input field + * @returns + */ +export const FileUpload = ({ + onContentReady, + isHidden = true, + inputId='file-upload' +}) => { + let fileReader + + const handleFileRead = e => { + const content = fileReader.result + onContentReady(content) + } + + const handleFileChosen = file => { + if (!file) return + fileReader = new FileReader() + fileReader.onloadend = handleFileRead + fileReader.readAsText(file) + } + + return ( +
+ handleFileChosen(e.target.files[0])} + onClick={e => e.target.value = ''} + /> +
+ ) +} \ No newline at end of file diff --git a/src/tools/online-lar-formatting/Header.jsx b/src/tools/online-lar-formatting/Header.jsx new file mode 100644 index 000000000..facf2994b --- /dev/null +++ b/src/tools/online-lar-formatting/Header.jsx @@ -0,0 +1,38 @@ +import React from 'react' +import Heading from '../../common/Heading' +import { Link } from 'react-router-dom' +import { withAppContext } from '../../common/appContextHOC' + + +const _Header = ({ config: { defaultDocsPeriod = '2018' } }) => ( + + +

+ The online HMDA LAR formatting tool is a web application created by the + Bureau for HMDA filers, who do not have another means of doing so, to + enter and format data into a pipe delimited text file. A pipe delimited + text file is the required format, beginning with data collected in 2017, + for financial institutions to file their loan/application register (LAR) + using the HMDA Platform. +

+

+ Follow the{' '} + + Online LAR Formatting Tool instructions + {' '} + to format your data into a pipe delimited text file. +

+
+
+) + +export const Header = withAppContext(_Header) \ No newline at end of file diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx new file mode 100644 index 000000000..2176be32a --- /dev/null +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -0,0 +1,174 @@ +import React, { useState } from 'react' +import { getSchema, parseRow } from './utils' +import { useEffect } from 'react' + +const getType = ({ fieldType }) => { + if (fieldType == 'Alphanumeric') return 'text' + if (fieldType == 'Numeric') return 'number' + return 'text' +} + +const buildOptions = column => { + const vals = column.values.map(({ value, description }) => ( + + )) + + vals.unshift() + return vals +} + +export const ParsedRow = ({ row, setRow, currCol }) => { + const [filter, setFilter] = useState('') + + // Smoothly bring the focused field into view + useEffect(() => { + const el = document.getElementById(`${currCol?.fieldName}`) + el?.parentElement?.parentElement?.scrollIntoView({ + block: 'nearest', + behavior: 'smooth', + }) + if (el) el.parentElement.parentElement.style = {}//.transform = `translateY(0px)` + }, [currCol]) + + const _onChange = e => { + const newRow = { ...row } + newRow[e.target.id] = e.target.value + setRow(newRow) + } + + const rowValues = parseRow(row) + + const checkHighlighted = (a, b) => + a && b && a.fieldIndex === b.fieldIndex ? 'highlight' : '' + + const inputs = getSchema(row) + .filter( + column => + !filter.length || column.fieldName.toLowerCase().includes(filter) + ) + .map(column => { + const highlightClass = checkHighlighted(column, currCol) + const { examples, values } = column + let userInput + + // Field allows freeform text but also has enumerated values + if (examples.length && values.length) { + userInput = ( + `${value} - ${description}`) + .join(' (or) ')}`} + style={{ + border: '1px dotted grey', + width: '100%', + }} + /> + ) + } else if (values.length) { + userInput = ( + + ) + } else { + userInput = ( + + ) + } + + return ( + + + + + + + + + {userInput} + + + ) + }) + + return ( +
+
+

Parsed Field Values

+ setFilter(e.target.value.toLowerCase())} + /> + {!!filter.length && ( + + )} +
+
+ e.preventDefault()} + style={{ height: window.innerHeight * 0.1, borderCollapse: 'separate' }} + > + + + + + + + + + {inputs} + +
Column #LabelValue
+
+
+ ) +} diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx new file mode 100644 index 000000000..9b28d0d7a --- /dev/null +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -0,0 +1,119 @@ +import React from 'react' +import { getSchema, parseRow, stringifyRow } from './utils' + +const grabRawArea = () => document.getElementById('rawArea') + +const findPipes = row => stringifyRow(row).matchAll(new RegExp(/\|/, 'gi')) + +const highlight = text => {text} + +// Compare the current cursor position to the positions of +// the column delimiters to determine which LAR field is +// currently being edited/focused +const updateCurrentColumn = (setFn, row) => { + const cursorPos = getCursorPos(grabRawArea()).start + const pipes = findPipes(row) + + let colNum = 0 + let pipeIter = pipes.next() + + while (!pipeIter.done && pipeIter.value.index < cursorPos) { + pipeIter = pipes.next() + colNum++ + } + + setFn(getSchema(row)[colNum]) +} + +export const RawRow = ({ + row, + setRow, + currCol, + setCurrCol, + saveRow, + newRow, + deleteRow +}) => { + return ( +
+ + {!!currCol?.toString() && ( +
+ Field name: {highlight(currCol.fieldName)} +
+ Column: {highlight(currCol.fieldIndex + 1)}{' '} +
+ )} +
) } diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index 707e4f886..c469f8a66 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -42,8 +42,14 @@ margin-top: 0px; margin-bottom: 10px; } -.raw-row label > button:not(:first-of-type) { - margin-left: 1em; +.raw-row .action-wrapper button:not(:first-of-type) { + margin-left: .5em; +} + +.raw-row .action-wrapper { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; } /* ParsedRow */ diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index 9cf6f4d61..bb87572bd 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -1,4 +1,4 @@ -import React, { useLayoutEffect, useState } from 'react' +import React, { useState } from 'react' import { ParsedRow } from './ParsedRow' import { RawRow } from './RawRow' import { @@ -8,29 +8,18 @@ import { cloneObjectArray, unity, getSchema, + createID, + isTS, + isLAR, + log } from './utils' import { SavedRows } from './SavedRows' import { FileUpload } from './FileUpload' import { Header } from './Header' -import './index.css' -let NEXT_ID = 0 -const createID = () => (NEXT_ID++).toString() - -const Error = ({ text, onClick }) => { - const err_id = 'file-error' - useLayoutEffect(() => { - document.getElementById(err_id).scrollIntoView({ behavior: 'smooth' }) - }, []) +import { Error } from './Error' - return ( -
- {text} x -
- ) -} +import './index.css' -const isTS = r => r && r['Record Identifier'] === '1' -const isLAR = r => r && r['Record Identifier'] === '2' // TODO: // √ - Each imported row needs an `id @@ -75,12 +64,12 @@ export const OnlineLARFT = () => { let updateFn if (isTS(_row)) { - console.log('Processing a TS row', _row) + log('Processing a TS row', _row) vals = ts updateFn = setTS } else if (isLAR(_row)) { - console.log('Processing a LAR row', _row) + log('Processing a LAR row', _row) vals = lars updateFn = setLARs @@ -88,22 +77,22 @@ export const OnlineLARFT = () => { // Only allow single TS row if (vals === ts) { - console.log('Saving TS row') + log('Saving TS row') const nextTS = cloneObject(_row) nextTS.id = createID() updateFn([nextTS]) } else { const cloned = cloneObjectArray(vals) - console.log('Saving LAR row') + log('Saving LAR row') // Update existing item if (!!_row?.id) { const updateIndex = cloned.findIndex(el => el?.id === _row.id) if (updateIndex > -1) { - console.log('Updating index: ', updateIndex) - console.log('previous Row at index: ', cloned[updateIndex]) - console.log('Updated Row: ', _row) + log('Updating index: ', updateIndex) + log('previous Row at index: ', cloned[updateIndex]) + log('Updated Row: ', _row) cloned[updateIndex] = cloneObject(_row) updateFn(cloned) // Save rows newRow() // Clear Pipe-delimited area @@ -113,7 +102,7 @@ export const OnlineLARFT = () => { } // Append new item - console.log('Adding new item') + log('Adding new item') const obj = cloneObject(_row) obj.id = createID() cloned.push(obj) @@ -124,7 +113,7 @@ export const OnlineLARFT = () => { } const deleteRow = _row => { - console.log('Deleting ', _row) + log('Deleting ', _row) if (isTS(_row)) setTS([]) else { let cloned = cloneObjectArray(lars).filter(r => r.id !== _row.id) @@ -135,12 +124,12 @@ export const OnlineLARFT = () => { } const saveUpload = content => { - console.log('Parsing upload: ', content) + log('Parsing upload: ', content) if (!content) return const up_rows = content.split('\n') if (!up_rows.length) return - console.log('Rows: ', up_rows) + log('Rows: ', up_rows) let _ts = [], _lar = [], @@ -157,7 +146,7 @@ export const OnlineLARFT = () => { setTS(_ts) setLARs(_lar) newRow() - console.log( + log( 'The following rows were excluded due to unrecognized formatting: ', Object.keys(_unknown) .map(k => ` Row #${k}: ${_unknown[k]}`) @@ -198,7 +187,7 @@ export const OnlineLARFT = () => { .filter(unity) .map(s => s.trim()) .join('\n') - console.log('Saving: ', content) + log('Saving: ', content) download('LarFile.txt', content) }} diff --git a/src/tools/online-lar-formatting/utils.js b/src/tools/online-lar-formatting/utils.js index fb1453115..9c3a94dc1 100644 --- a/src/tools/online-lar-formatting/utils.js +++ b/src/tools/online-lar-formatting/utils.js @@ -5,6 +5,18 @@ export const LAR_SCHEMA = larSchema.schema export const TS_SCHEMA = tsSchema.schema export const DELIMITER = '|' +let NEXT_ID = 0 +export const createID = () => (NEXT_ID++).toString() + +export const isTS = r => r && r['Record Identifier'] === '1' +export const isLAR = r => r && r['Record Identifier'] === '2' + +export const cloneObject = item => JSON.parse(JSON.stringify(item)) +export const cloneObjectArray = array => array.map(cloneObject) +export const unity = x => x +export const log = data => + process.env.NODE_ENV !== 'production' ? console.log(data) : null + export const getSchema = row => { if (!row) return LAR_SCHEMA // Row string @@ -12,8 +24,7 @@ export const getSchema = row => { if (row.match(/^1/)) return TS_SCHEMA } else { // Row object - if (row['Record Identifier'] === '1') - return TS_SCHEMA + if (isTS(row)) return TS_SCHEMA } return LAR_SCHEMA } @@ -42,7 +53,7 @@ export const parseRow = (row = {}) => { return row.split(DELIMITER).reduce((prev, currVal, currIdx) => { const columnSchema = schema[currIdx] if (!columnSchema) { - console.error('No schema at ', currIdx, currVal) + console.error('Unknown column at ', currIdx, currVal) return prev } @@ -50,7 +61,3 @@ export const parseRow = (row = {}) => { return prev }, {}) } - -export const cloneObject = item => JSON.parse(JSON.stringify(item)) -export const cloneObjectArray = array => array.map(cloneObject) -export const unity = x => x \ No newline at end of file From addfa3930cf1941fd654b39e28e604c01101730c Mon Sep 17 00:00:00 2001 From: Meis Date: Thu, 10 Feb 2022 20:29:25 -0700 Subject: [PATCH 05/69] [olarft] Performance optimization --- src/tools/online-lar-formatting/SavedRows.jsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tools/online-lar-formatting/SavedRows.jsx b/src/tools/online-lar-formatting/SavedRows.jsx index 93f2341d7..828aa58e3 100644 --- a/src/tools/online-lar-formatting/SavedRows.jsx +++ b/src/tools/online-lar-formatting/SavedRows.jsx @@ -1,5 +1,5 @@ -import React from 'react' -import { getSchema } from './utils' +import React, { useMemo } from 'react' +import { getSchema, log } from './utils' import { Table } from 'react-fluid-table' const tableHeight = rows => { @@ -23,10 +23,14 @@ const Section = ({ title, rows, highlightSelected, setSelected }) => { else { columns.unshift({ key: 'rowId', header: 'Row #', width: 100 }) - const injectedRows = rows.map((x, idx) => ({ - ...x, - rowId: (idx + 1).toString(), - })) + // This memoization seems to fix the major performance bottle n + const injectedRows = useMemo(() => { + log(`Calculating row IDs: ${title}`) + return rows.map((x, idx) => ({ + ...x, + rowId: (idx + 1).toString(), + }))}, [rows] + ) body = ( Date: Thu, 10 Feb 2022 20:46:28 -0700 Subject: [PATCH 06/69] [olarft] Confirmation dialog for destructive actions (delete, delete all, overwrite all) --- src/tools/online-lar-formatting/index.jsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index bb87572bd..5b24a251c 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -25,9 +25,9 @@ import './index.css' // √ - Each imported row needs an `id // √ - Do everything by ID // √ - Bug: Update the `Update` button for the currently selected object on Clear Saved +// √ - On Upload, Clear Saved +// √ - If TS/LAR, confirm overwrite // - Provide search for LAR/TS -// - On Upload, Clear Saved -// - If TS/LAR, confirm overwrite // - On Download // - Provide file dialog? // - Provide date selector for Date fields @@ -113,6 +113,8 @@ export const OnlineLARFT = () => { } const deleteRow = _row => { + const confirm = window.confirm('Are you sure you want to delete this row?') + if (!confirm) return log('Deleting ', _row) if (isTS(_row)) setTS([]) else { @@ -164,7 +166,15 @@ export const OnlineLARFT = () => { @@ -197,6 +207,12 @@ export const OnlineLARFT = () => {
e.preventDefault()} - style={{ height: window.innerHeight * 0.1, borderCollapse: 'separate' }} + style={{ + height: window.innerHeight * 0.1, + borderCollapse: 'separate', + }} > diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx index 8938bd456..d33e8eacb 100644 --- a/src/tools/online-lar-formatting/RawRow.jsx +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -32,12 +32,20 @@ export const RawRow = ({ setCurrCol, saveRow, newRow, - deleteRow + deleteRow, + id='raw-row' }) => { return ( -
+
+

+ document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) + } + > + Submission File Row +

setSelected(injectedRows[index])} - rowStyle={i => highlightSelected(injectedRows[i])} + onRowClick={(e, { index }) => setSelected(filteredRows[index])} + rowStyle={i => highlightSelected(filteredRows[i])} /> ) } + const rowCount = + filteredRows.length !== rows.length + ? `(${filteredRows.length}/${rows.length})` + : `(${rows.length})` + return (
{title && ( -

- document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) + document.getElementById('file-actions')?.scrollIntoView({ behavior: 'smooth' }) } > - {title} + {title} {rowCount} + + + setSearchFilter(e.target.value.trim()) + } + placeholder='Search LAR' + value={searchFilter} + hidden={id.match(/ts/) || !rows.length} + /> + {!!searchFilter.length && ( + + )} +

)} {body || null} @@ -67,19 +103,18 @@ const TSheet = ({ rows, ...props }) => ( const LARs = ({ rows, ...props }) => (
) - export const SavedRows = ({ ts, lars, selected, setSelected, deleteRow }) => { - const highlightSelected = r => { if (!selected || !r) return {} - const highlighted = selected.id === r.id && - selected['Record Identifier'] === r['Record Identifier'] + const highlighted = + selected.id === r.id && + selected['Record Identifier'] === r['Record Identifier'] return highlighted ? { background: 'lightblue' } : {} } diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index 5265b5b65..becebfa2b 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -17,6 +17,10 @@ margin-left: auto; } +.file-actions { + padding-top: 5px; +} + .file-actions > button:not(:first-of-type) { margin-left: 1em; } @@ -25,6 +29,9 @@ } /* RawRow */ +.action-wrapper.raw { + margin-top: 1em; +} .raw-row button { margin-top: .5em; } @@ -61,7 +68,7 @@ flex-flow: row nowrap; justify-content: flex-start; align-items: center; - margin: 1.3em 0; + margin: 1.3em 0 5px 0; } .parsed-row .section-heading > * { margin: 0; @@ -131,3 +138,17 @@ padding: 5px; padding-left: 0px; } +.saved-rows .search-box input { + margin-left: 1em; + border-radius: 8px; + text-align: center; + padding: .1em; +} +.saved-rows .search-box button { + margin: 0 0 0 .5em; + padding: .4em .75em; + border-radius: 8px; +} +.saved-rows .highlight-match { + background: lightcoral; +} diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index 5b24a251c..cb73ea691 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -17,6 +17,7 @@ import { SavedRows } from './SavedRows' import { FileUpload } from './FileUpload' import { Header } from './Header' import { Error } from './Error' +import { useRestyledButtonLinks } from './useRestyledButtonLinks' import './index.css' @@ -24,23 +25,22 @@ import './index.css' // TODO: // √ - Each imported row needs an `id // √ - Do everything by ID -// √ - Bug: Update the `Update` button for the currently selected object on Clear Saved +// √ - Bug: `Update` button incorrect on `Clear Saved` // √ - On Upload, Clear Saved // √ - If TS/LAR, confirm overwrite -// - Provide search for LAR/TS +// √ - Provide search for LAR +// √- Provide date selector for Date fields +// - Provide search for TS? // - On Download // - Provide file dialog? -// - Provide date selector for Date fields -// - fieldName.toLowerCase().includes('date') -// - format: yyyymmdd // - Example/Enumerations in `info` button/column -const focusAtZero = () => - setTimeout(() => { - const el = document.getElementById('rawArea') - el.focus() - el.selectionEnd = 0 - }, 0) +const focusAtZero = () => null + // setTimeout(() => { + // const el = document.getElementById('rawArea') + // el.focus() + // el.selectionEnd = 0 + // }, 0) export const OnlineLARFT = () => { const [ts, setTS] = useState([]) @@ -48,6 +48,7 @@ export const OnlineLARFT = () => { const [selected, setSelected] = useState(parseRow(ts.length ? '2|' : '1|')) const [currCol, setCurrCol] = useState() const [fileError, setFileError] = useState() + useRestyledButtonLinks() const newRow = () => { const nextRow = parseRow(ts.length ? '2|' : '1|') @@ -162,7 +163,7 @@ export const OnlineLARFT = () => { {fileError && ( setFileError(null)} /> )} -
+
) } diff --git a/src/tools/online-lar-formatting/useRestyledButtonLinks.jsx b/src/tools/online-lar-formatting/useRestyledButtonLinks.jsx new file mode 100644 index 000000000..a8fa884d6 --- /dev/null +++ b/src/tools/online-lar-formatting/useRestyledButtonLinks.jsx @@ -0,0 +1,13 @@ +import { useLayoutEffect } from 'react' + +// Remove .button-link to show `Return to top` as a button +export const useRestyledButtonLinks = () => { + useLayoutEffect( + () => document + .querySelectorAll('.button-link') + .forEach( + e => (e.className = (e.className || '').replace('button-link', '')) + ), + [] + ) +} From 701dc2df7c888f5b1865519a8b1c2eb9293fc3e8 Mon Sep 17 00:00:00 2001 From: Meis Date: Tue, 15 Feb 2022 15:03:02 -0700 Subject: [PATCH 11/69] [olarft] UI Cleanup --- src/tools/online-lar-formatting/RawRow.jsx | 8 ++++---- src/tools/online-lar-formatting/index.css | 5 +++++ src/tools/online-lar-formatting/index.jsx | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx index 130a62285..b43bedf91 100644 --- a/src/tools/online-lar-formatting/RawRow.jsx +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -49,7 +49,7 @@ export const RawRow = ({ }) => { return (
-

document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) @@ -59,9 +59,9 @@ export const RawRow = ({ {row['Record Identifier'] === '1' ? 'Transmittal Sheet' : row.rowId - ? `LAR row ${row.rowId}` - : 'a new LAR row'} -

+ ? `LAR Row ${row.rowId}` + : 'a new LAR Row'} +
+

Saved Records

Date: Wed, 16 Feb 2022 10:27:36 -0700 Subject: [PATCH 12/69] [olarft] Create Accordion component --- src/tools/online-lar-formatting/Accordion.css | 55 +++++++++++++++++++ src/tools/online-lar-formatting/Accordion.jsx | 50 +++++++++++++++++ src/tools/online-lar-formatting/index.css | 42 +++++++++++++- src/tools/online-lar-formatting/index.jsx | 4 +- 4 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 src/tools/online-lar-formatting/Accordion.css create mode 100644 src/tools/online-lar-formatting/Accordion.jsx diff --git a/src/tools/online-lar-formatting/Accordion.css b/src/tools/online-lar-formatting/Accordion.css new file mode 100644 index 000000000..37d159611 --- /dev/null +++ b/src/tools/online-lar-formatting/Accordion.css @@ -0,0 +1,55 @@ +.accordion-bordered { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; + padding-left: 0; + color: #212121; + margin: 0; + padding: 0; + width: 100%; +} + +.accordion-bordered > li { + background-color: #f1f1f1; + font-family: SourceSansPro; + list-style: none; + margin-bottom: 0.5rem; + width: 100%; +} + +.accordion-button { + background-color: #d6d7d9 !important; + background-image: url('../../filing/images/minus.png'); + background-image: url('../../filing/images/minus.svg'); + background-position: right 2rem center; + background-repeat: no-repeat; + background-size: 1.5rem; + border-radius: 0; + color: #212121; + cursor: pointer; + display: inline-block; + margin-top: 0; + padding: .5rem 4rem .5rem .5em; + text-align: left; + width: 100%; +} + +.accordion-button[aria-expanded='false'] { + background-image: url('../../filing/images/plus.png'); + background-image: url('../../filing/images/plus.svg'); +} + +.accordion-content { + background-color: #ffffff; + border-top: none; + overflow: auto; + padding: 0em 1em 1em; +} + +.accordion-content[aria-hidden='true'] { + display: none; +} + +.accordion-content > *:first-child { + margin-top: 0; +} \ No newline at end of file diff --git a/src/tools/online-lar-formatting/Accordion.jsx b/src/tools/online-lar-formatting/Accordion.jsx new file mode 100644 index 000000000..2f44ea200 --- /dev/null +++ b/src/tools/online-lar-formatting/Accordion.jsx @@ -0,0 +1,50 @@ +import React from 'react' +import './Accordion.css' + +function handleToggleClick(id) { + let accordionButton = document.getElementById(`accordion-button-${id}`) + let expanded = + accordionButton.getAttribute('aria-expanded') === 'false' ? false : true + + document + .getElementById(`accordion-button-${id}`) + .setAttribute('aria-expanded', !expanded) + document + .getElementById(`accordion-${id}`) + .setAttribute('aria-hidden', expanded) +} + +export const collapseAll = () => { + document + .querySelectorAll(`[id^="accordion-button-"]`) + .forEach(e => e.setAttribute('aria-expanded', false)) + document + .querySelectorAll(`[id^="accordion-"]`) + .forEach(e => e.setAttribute('aria-hidden', true)) +} + +export const Accordion = ({ heading, content, id }) => { + return ( +
    +
  • + + +
  • +
+ ) +} + diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index c924935cb..8e3606869 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -115,10 +115,48 @@ width: 6em; } .parsed-row .fieldName { - width: 40%; + width: 50%; +} +.parsed-row .accordion-bordered > li{ + background-color: inherit; +} +.parsed-row .accordion-bordered .accordion-button { + background-color: white !important; + border-left: 5px solid white; +} +.parsed-row .accordion-bordered .accordion-button:hover { + color: black; + border-left: 5px dotted darkolivegreen; + background-color: lightgoldenrodyellow !important; } .parsed-row .highlight { - background: lightblue; + background: rgb(145, 206, 226); +} + +.parsed-row .table-wrapper > table > thead { + z-index: 1; +} +.more-info h3 { + border-top: 1px dotted lightblue; + padding-top: 8px; + +} +.more-info h3::before { + content: "» "; +} +.more-info h3 , .more-info th { + font-size: 1.7rem; +} +.more-info h3, .more-info table { + margin-top: 1em; +} +.more-info .values { + margin-top: 1.5em; + width: 100%; +} +.more-info .values, .more-info .values td { + border-color: grey; + } /* SavedRows */ diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index 3c716ebb5..b91d9c420 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -18,6 +18,7 @@ import { FileUpload } from './FileUpload' import { Header } from './Header' import { Error } from './Error' import { useRestyledButtonLinks } from './useRestyledButtonLinks' +import { collapseAll } from './Accordion' import './index.css' @@ -30,10 +31,10 @@ import './index.css' // √ - If TS/LAR, confirm overwrite // √ - Provide search for LAR // √- Provide date selector for Date fields +// √ - Example/Enumerations in `info` button/column // - Provide search for TS? // - On Download // - Provide file dialog? -// - Example/Enumerations in `info` button/column const focusAtZero = () => null // setTimeout(() => { @@ -56,6 +57,7 @@ export const OnlineLARFT = () => { setSelected(nextRow) setCurrCol(getSchema(nextRow)[0]) + collapseAll() } const saveRow = _row => { From ade357e2fc0bcaaf21344d198a9df062303a678f Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 10:33:20 -0700 Subject: [PATCH 13/69] [olarft] [Parsed] Display enumerations, examples, and descriptions --- src/tools/online-lar-formatting/ParsedRow.jsx | 83 +++++++++++++++++-- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx index 6783d3067..7f1f693e8 100644 --- a/src/tools/online-lar-formatting/ParsedRow.jsx +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -1,6 +1,7 @@ import React, { useState } from 'react' -import { getSchema, parseRow } from './utils' +import { cloneObjectArray, getSchema, parseRow } from './utils' import { useEffect } from 'react' +import { Accordion } from './Accordion' const getType = ({ fieldType }) => { if (fieldType == 'Alphanumeric') return 'text' @@ -27,6 +28,73 @@ const toJsDateString = str => { } +const MoreInfo = ({ field }) => { + if (!field) return null + const { examples = [], values = [] } = field + const _examples = [] + let _values = cloneObjectArray(values) + let _descriptions = [] + + examples.forEach(curr => { + if (typeof curr === 'string') { + const [ex, ...enums] = curr.split(' (or) ') + if (ex.match(/^Specify/)) _descriptions.push(
  • {ex}
  • ) + else if (ex) _examples.push(
  • {ex}
  • ) + + // Fields that have both enums and free text + if (enums?.length) { + if (_values?.append) + _values.append(enums.map(e => ({ value: e, description: e }))) + else + _values = enums.map(e => ({ value: e, description: e })) + } + } + }) + + + + const Examples = _examples.length ? ( +
    +

    Examples

    +
      {_examples}
    +
    + ) : null + + const Description = _descriptions.length ? ( +
    +

    Field Description

    +
      {_descriptions}
    +
    + ) : null + + const valueRows = _values.map(v => { + return
    + }) + + const Values = _values.length ? ( +
    +

    Enumerations

    +
    {v.value}{v.description}
    + + + + + + + {valueRows} +
    ValueDescription
    + + ) : null + + return ( +
    + {Examples} + {Description} + {Values} +
    + ) +} + export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { const [filter, setFilter] = useState('') @@ -144,11 +212,16 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { - - - - {userInput} + + {userInput} ) }) From 7bde9d5d090e3cc214ef7c840accce92d273cec7 Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 10:42:43 -0700 Subject: [PATCH 14/69] [olarft][Parsed] Add button to collapse open accordions --- src/tools/online-lar-formatting/ParsedRow.jsx | 17 +++++++++++++---- src/tools/online-lar-formatting/index.css | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx index 7f1f693e8..887d9d761 100644 --- a/src/tools/online-lar-formatting/ParsedRow.jsx +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { cloneObjectArray, getSchema, parseRow } from './utils' import { useEffect } from 'react' -import { Accordion } from './Accordion' +import { Accordion, collapseAll } from './Accordion' const getType = ({ fieldType }) => { if (fieldType == 'Alphanumeric') return 'text' @@ -232,7 +232,9 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => {

    - document.getElementById('raw-row')?.scrollIntoView({ behavior: 'smooth' }) + document + .getElementById('raw-row') + ?.scrollIntoView({ behavior: 'smooth' }) } > Parsed Values @@ -270,8 +272,15 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { > - Column # - Label + Column + + Label + + + + Value diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index 8e3606869..81e822101 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -136,6 +136,11 @@ .parsed-row .table-wrapper > table > thead { z-index: 1; } +.parsed-row .collapse-all { +margin: 0; +padding: .3em; +} + .more-info h3 { border-top: 1px dotted lightblue; padding-top: 8px; @@ -195,3 +200,12 @@ .saved-rows .highlight-match { background: lightcoral; } + + +/* Utility classes */ +.space-between { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; +} \ No newline at end of file From 659c0bfefec6ff7b1f723a0d57c13a326336b866 Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 11:26:31 -0700 Subject: [PATCH 15/69] [larft] Replace old LARFT with new LARFT --- src/tools/index.js | 4 ++-- src/tools/online-lar-formatting/Header.jsx | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/index.js b/src/tools/index.js index 43e32a32c..67a2c44d7 100644 --- a/src/tools/index.js +++ b/src/tools/index.js @@ -28,8 +28,8 @@ const Tools = () => { /> - - + {/* */} + ) diff --git a/src/tools/online-lar-formatting/Header.jsx b/src/tools/online-lar-formatting/Header.jsx index facf2994b..10ff4d00c 100644 --- a/src/tools/online-lar-formatting/Header.jsx +++ b/src/tools/online-lar-formatting/Header.jsx @@ -8,14 +8,14 @@ const _Header = ({ config: { defaultDocsPeriod = '2018' } }) => (

    - The online HMDA LAR formatting tool is a web application created by the + The HMDA LAR formatting tool is a web application created by the Bureau for HMDA filers, who do not have another means of doing so, to enter and format data into a pipe delimited text file. A pipe delimited text file is the required format, beginning with data collected in 2017, @@ -25,9 +25,9 @@ const _Header = ({ config: { defaultDocsPeriod = '2018' } }) => (

    Follow the{' '} - Online LAR Formatting Tool instructions + LAR Formatting Tool instructions {' '} to format your data into a pipe delimited text file.

    From d7b8ff123ed90024dba95340de79076601310407 Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 11:50:44 -0700 Subject: [PATCH 16/69] [larft] Scroll to sections on header click --- src/tools/online-lar-formatting/RawRow.jsx | 19 ++++--------------- src/tools/online-lar-formatting/SavedRows.jsx | 6 ++---- src/tools/online-lar-formatting/index.jsx | 5 +++-- src/tools/online-lar-formatting/utils.js | 3 +++ 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx index b43bedf91..4c7f2db72 100644 --- a/src/tools/online-lar-formatting/RawRow.jsx +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { getSchema, parseRow, stringifyRow } from './utils' +import { getSchema, goTo, goToFileActions, parseRow, stringifyRow } from './utils' import { ParsedRow } from './ParsedRow' const CurrentColumn = ({ column }) => { @@ -37,6 +37,7 @@ const updateCurrentColumn = (setFn, row) => { setFn(getSchema(row)[colNum]) } +// TODO: Rename => EditingRow export const RawRow = ({ row, setRow, @@ -49,12 +50,7 @@ export const RawRow = ({ }) => { return (
    -

    - document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) - } - > +

    goTo('raw-row')}> {row.rowId ? 'Editing' : 'Creating'}{' '} {row['Record Identifier'] === '1' ? 'Transmittal Sheet' @@ -85,14 +81,7 @@ export const RawRow = ({

    -

    - document - .getElementById('raw-row') - ?.scrollIntoView({ behavior: 'smooth' }) - } - > +

    goTo('raw-row')}> Pipe-Delimited Values

    diff --git a/src/tools/online-lar-formatting/SavedRows.jsx b/src/tools/online-lar-formatting/SavedRows.jsx index fba7235f4..d72ec1257 100644 --- a/src/tools/online-lar-formatting/SavedRows.jsx +++ b/src/tools/online-lar-formatting/SavedRows.jsx @@ -1,5 +1,5 @@ import React, { useMemo, useState } from 'react' -import { getSchema, log, LAR_SCHEMA } from './utils' +import { getSchema, log, LAR_SCHEMA, goToFileActions } from './utils' import { Table } from 'react-fluid-table' const tableHeight = rows => { @@ -70,9 +70,7 @@ const Section = ({ id, title, rows, highlightSelected, setSelected }) => { {title && (

    - document.getElementById('file-actions')?.scrollIntoView({ behavior: 'smooth' }) - } + onClick={goToFileActions} > {title} {rowCount} diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index b91d9c420..8affec724 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -11,7 +11,8 @@ import { createID, isTS, isLAR, - log + log, + goToFileActions } from './utils' import { SavedRows } from './SavedRows' import { FileUpload } from './FileUpload' @@ -224,7 +225,7 @@ export const OnlineLARFT = () => { Clear Saved

    -

    Saved Records

    +

    Saved Records

    { return prev }, {}) } + +export const goTo = id => document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' }) +export const goToFileActions = () => goTo('file-actions') \ No newline at end of file From 678899f38acc4a132dda32f95b7d623a07ba754c Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 13:26:01 -0700 Subject: [PATCH 17/69] [larft] Parsed Values tables full width --- src/tools/online-lar-formatting/index.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index 81e822101..fb1057a5a 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -133,6 +133,9 @@ background: rgb(145, 206, 226); } +.parsed-row .table-wrapper > table { + width: 100%; +} .parsed-row .table-wrapper > table > thead { z-index: 1; } From 15b5c9f8e5bef4ec9fdd5bdc7119ab210e889aa0 Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 15:19:44 -0700 Subject: [PATCH 18/69] [larft] Highlight column selected in Parsed --- src/tools/online-lar-formatting/ParsedRow.jsx | 10 +++++++--- src/tools/online-lar-formatting/RawRow.jsx | 7 ++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx index 887d9d761..7ab90992e 100644 --- a/src/tools/online-lar-formatting/ParsedRow.jsx +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -95,7 +95,7 @@ const MoreInfo = ({ field }) => { ) } -export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { +export const ParsedRow = ({ id='parsed-row', row, setRow, currCol, setCurrCol }) => { const [filter, setFilter] = useState('') // Smoothly bring the focused field into view @@ -105,7 +105,7 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { block: 'nearest', behavior: 'auto', }) - if (el) el.parentElement.parentElement.style = {}//.transform = `translateY(0px)` + if (el) el.parentElement.parentElement.style = {} }, [currCol]) const _onChange = e => { @@ -114,6 +114,10 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { setRow(newRow) } + const focusOnColumn = (col) => { + if (currCol?.fieldIndex !== col?.fieldIndex) setCurrCol(col) + } + const rowValues = parseRow(row) const checkHighlighted = (a, b) => @@ -207,6 +211,7 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { key={column.fieldName} className={highlightClass} key={column.fieldName} + onClick={() => focusOnColumn(column)} > @@ -217,7 +222,6 @@ export const ParsedRow = ({ id='parsed-row', row, setRow, currCol }) => { heading={column.fieldName} content={} id={`${column.fieldIndex}`} - width='100%' /> diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx index 4c7f2db72..06fcf054d 100644 --- a/src/tools/online-lar-formatting/RawRow.jsx +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -80,7 +80,12 @@ export const RawRow = ({ - +

    goTo('raw-row')}> Pipe-Delimited Values

    From cdb249e1c0be4c2e5e1d954fd57a4175b854facc Mon Sep 17 00:00:00 2001 From: Meis Date: Wed, 16 Feb 2022 17:45:23 -0700 Subject: [PATCH 19/69] [larft][Parsed] Refactored --- src/tools/online-lar-formatting/Accordion.jsx | 4 +- src/tools/online-lar-formatting/MoreInfo.jsx | 86 ++++ src/tools/online-lar-formatting/Parsed.jsx | 62 +++ .../online-lar-formatting/ParsedHeader.jsx | 28 ++ src/tools/online-lar-formatting/ParsedRow.jsx | 399 +++++------------- .../online-lar-formatting/ParsedTable.jsx | 32 ++ src/tools/online-lar-formatting/RawRow.jsx | 4 +- src/tools/online-lar-formatting/index.css | 44 +- src/tools/online-lar-formatting/index.jsx | 2 +- .../online-lar-formatting/parsedHelpers.jsx | 33 ++ 10 files changed, 376 insertions(+), 318 deletions(-) create mode 100644 src/tools/online-lar-formatting/MoreInfo.jsx create mode 100644 src/tools/online-lar-formatting/Parsed.jsx create mode 100644 src/tools/online-lar-formatting/ParsedHeader.jsx create mode 100644 src/tools/online-lar-formatting/ParsedTable.jsx create mode 100644 src/tools/online-lar-formatting/parsedHelpers.jsx diff --git a/src/tools/online-lar-formatting/Accordion.jsx b/src/tools/online-lar-formatting/Accordion.jsx index 2f44ea200..ff149b8f6 100644 --- a/src/tools/online-lar-formatting/Accordion.jsx +++ b/src/tools/online-lar-formatting/Accordion.jsx @@ -23,7 +23,7 @@ export const collapseAll = () => { .forEach(e => e.setAttribute('aria-hidden', true)) } -export const Accordion = ({ heading, content, id }) => { +export const Accordion = ({ heading, content, children, id }) => { return (
    • @@ -41,7 +41,7 @@ export const Accordion = ({ heading, content, id }) => { className='accordion-content' aria-hidden='true' > - {content || null} + {content || children || null}
    diff --git a/src/tools/online-lar-formatting/MoreInfo.jsx b/src/tools/online-lar-formatting/MoreInfo.jsx new file mode 100644 index 000000000..c651898b6 --- /dev/null +++ b/src/tools/online-lar-formatting/MoreInfo.jsx @@ -0,0 +1,86 @@ +import React, { memo } from 'react' +import { cloneObjectArray } from './utils' + +const DELIMITER = ' (or) ' + +const isDescription = str => str.match(/^Specify/) + +const isString = str => typeof str === 'string' + +const List = (title, list, className) => { + if (!list?.length) return null + + return ( +
    +

    {title}

    +
      {list}
    +
    + ) +} + +const buildRows = list => + list.map(v => { + return ( + + {v.value} + {v.description} + + ) + }) + +const Table = (title, list, className) => { + if (!list.length) return null + const rows = buildRows(list) + + return ( +
    +

    {title}

    + + + + + + + + {rows} +
    ValueDescription
    +
    + ) +} + + +export const MoreInfo = memo(({ field }) => { + if (!field) return null + const { examples = [], values = [] } = field + const _examples = [] + const _descriptions = [] + let _values = cloneObjectArray(values) + + examples.forEach(curr => { + if (isString(curr)) { + const [ex, ...enums] = curr.split(DELIMITER) + + if (isDescription(ex)) _descriptions.push(
  • {ex}
  • ) + else if (ex) _examples.push(
  • {ex}
  • ) + + // Fields that have both enums and free text + if (enums?.length) { + if (_values?.append) + _values.append(enums.map(e => ({ value: e, description: e }))) + else _values = enums.map(e => ({ value: e, description: e })) + } + } + }) + + const Examples = List('Examples', _examples, 'examples') + const Description = List('Field Description', _descriptions, 'descriptions') + const Values = Table('Enumerations', _values, 'values') + + return ( +
    + {Examples} + {Description} + {Values} +
    + ) +}) diff --git a/src/tools/online-lar-formatting/Parsed.jsx b/src/tools/online-lar-formatting/Parsed.jsx new file mode 100644 index 000000000..fe02819b9 --- /dev/null +++ b/src/tools/online-lar-formatting/Parsed.jsx @@ -0,0 +1,62 @@ +import React, { useState } from 'react' +import { useEffect } from 'react' +import { ParsedRow } from './ParsedRow' +import { getSchema, parseRow } from './utils' +import { ParsedHeader } from './ParsedHeader' +import { ParsedTable } from './ParsedTable' +import { applyFilter, checkHighlighted } from './parsedHelpers' + +function useFocusOnSelectedColumn(col, setCurrCol) { + // Bring the focused column into view + useEffect(() => { + const el = document.getElementById(`${col?.fieldName}`) + el?.parentElement?.parentElement?.scrollIntoView({ + block: 'nearest', + behavior: 'auto', + }) + if (el) el.parentElement.parentElement.style = {} + }, [col]) + + // Provide a function that will set focus to this column + const focus = target => { + if (col?.fieldIndex !== target?.fieldIndex) setCurrCol(target) + } + + return focus +} + +export const Parsed = ({ + id = 'parsed-row', + row, + setRow, + currCol, + setCurrCol +}) => { + const [filter, setFilter] = useState('') + const setFocus = useFocusOnSelectedColumn(currCol, setCurrCol) + + const _onChange = e => { + const newRow = { ...row } + newRow[e.target.id] = e.target.value + setRow(newRow) + } + + const tableRows = getSchema(row) + .filter(x => applyFilter(x, filter)) + .map(column => ( + + )) + + return ( +
    + + +
    + ) +} diff --git a/src/tools/online-lar-formatting/ParsedHeader.jsx b/src/tools/online-lar-formatting/ParsedHeader.jsx new file mode 100644 index 000000000..70fd2b3da --- /dev/null +++ b/src/tools/online-lar-formatting/ParsedHeader.jsx @@ -0,0 +1,28 @@ +import React from 'react' +import { goTo } from './utils' + +export const ParsedHeader = ({ filter, setFilter, id }) => ( +
    +

    goTo(id)}> + Parsed Values +

    + setFilter(e.target.value.toLowerCase())} /> + {!!filter.length && ( + + )} +
    +) diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx index 7ab90992e..dea64569e 100644 --- a/src/tools/online-lar-formatting/ParsedRow.jsx +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -1,301 +1,118 @@ -import React, { useState } from 'react' -import { cloneObjectArray, getSchema, parseRow } from './utils' -import { useEffect } from 'react' -import { Accordion, collapseAll } from './Accordion' - -const getType = ({ fieldType }) => { - if (fieldType == 'Alphanumeric') return 'text' - if (fieldType == 'Numeric') return 'number' - return 'text' -} - -const buildOptions = column => { - const vals = column.values.map(({ value, description }) => ( - - )) - - vals.unshift() - return vals -} - -const toJsDateString = str => { - if (!str) return '' - console.log('Date string: ', `${str.slice(0,4)}-${str.slice(4,6)}-${str.slice(6)}`) - - return `${str.slice(0,4)}-${str.slice(4,6)}-${str.slice(6)}` - -} - -const MoreInfo = ({ field }) => { - if (!field) return null - const { examples = [], values = [] } = field - const _examples = [] - let _values = cloneObjectArray(values) - let _descriptions = [] - - examples.forEach(curr => { - if (typeof curr === 'string') { - const [ex, ...enums] = curr.split(' (or) ') - if (ex.match(/^Specify/)) _descriptions.push(
  • {ex}
  • ) - else if (ex) _examples.push(
  • {ex}
  • ) - - // Fields that have both enums and free text - if (enums?.length) { - if (_values?.append) - _values.append(enums.map(e => ({ value: e, description: e }))) - else - _values = enums.map(e => ({ value: e, description: e })) - } - } - }) - - - - const Examples = _examples.length ? ( -
    -

    Examples

    -
      {_examples}
    -
    - ) : null - - const Description = _descriptions.length ? ( -
    -

    Field Description

    -
      {_descriptions}
    -
    - ) : null - - const valueRows = _values.map(v => { - return {v.value}{v.description} - }) - - const Values = _values.length ? ( -
    -

    Enumerations

    - - - - - - - - {valueRows} -
    ValueDescription
    -
    - ) : null +import React from 'react' +import { Accordion } from './Accordion' +import { MoreInfo } from './MoreInfo' +import { buildOptions, getType, toJsDateString } from './parsedHelpers' + +export const ParsedRow = ({ + column, + highlightClass, + row, + onChange, + onFocus, +}) => { + const userInput = buildInput(column, row, onChange) + const moreInfo = + const { fieldName, fieldIndex } = column return ( -
    - {Examples} - {Description} - {Values} -
    + onFocus(column)} + > + + + + + + + {userInput} + ) } -export const ParsedRow = ({ id='parsed-row', row, setRow, currCol, setCurrCol }) => { - const [filter, setFilter] = useState('') - - // Smoothly bring the focused field into view - useEffect(() => { - const el = document.getElementById(`${currCol?.fieldName}`) - el?.parentElement?.parentElement?.scrollIntoView({ - block: 'nearest', - behavior: 'auto', - }) - if (el) el.parentElement.parentElement.style = {} - }, [currCol]) - - const _onChange = e => { - const newRow = { ...row } - newRow[e.target.id] = e.target.value - setRow(newRow) - } - - const focusOnColumn = (col) => { - if (currCol?.fieldIndex !== col?.fieldIndex) setCurrCol(col) +function buildInput(_col, _row, _changeFn) { + console.log('Building input...') + + if (!_col) return null + const { examples = [], values = [] } = _col + + // Date field + if (_col.fieldName?.includes('Date')) { + return ( + { + _changeFn({ + target: { + id: e.target.id, + value: e.target.value?.replaceAll('-', ''), + }, + }) + }} + value={toJsDateString(_row[_col.fieldName]?.toString() || '')} + /> + ) } - const rowValues = parseRow(row) - - const checkHighlighted = (a, b) => - a && b && a.fieldIndex === b.fieldIndex ? 'highlight' : '' - - const inputs = getSchema(row) - .filter( - column => - !filter.length || column.fieldName.toLowerCase().includes(filter) + // Field allows freeform text but also has enumerated values + else if (examples.length && values.length) { + return ( + `${value} - ${description}`) + .join(' (or) ')}`} + style={{ + border: '1px dotted grey', + width: '100%', + }} + /> ) - .map(column => { - const highlightClass = checkHighlighted(column, currCol) - const { examples, values } = column - let userInput - - // Date field - if (column.fieldName?.includes('Date')){ - userInput = ( - { - _onChange({ - target: { - id: e.target.id, - value: e.target.value?.replaceAll('-', ''), - }, - }) - }} - value={toJsDateString( - rowValues[column.fieldName]?.toString() || '' - )} - /> - ) - } - // Field allows freeform text but also has enumerated values - else if (examples.length && values.length) { - userInput = ( - `${value} - ${description}`) - .join(' (or) ')}`} - style={{ - border: '1px dotted grey', - width: '100%', - }} - /> - ) - } else if (values.length) { - // Enumerations only - userInput = ( - - ) - } else { - // Examples only - userInput = ( - - ) - } - - return ( - focusOnColumn(column)} - > - - - - - - - {userInput} - - ) - }) - - return ( -
    -
    -

    - document - .getElementById('raw-row') - ?.scrollIntoView({ behavior: 'smooth' }) - } - > - Parsed Values -

    - setFilter(e.target.value.toLowerCase())} - /> - {!!filter.length && ( - - )} -
    -
    - e.preventDefault()} - style={{ - height: window.innerHeight * 0.1, - borderCollapse: 'separate', - }} - > - - - - - - - - - {inputs} - -
    Column - Label - - - - Value
    -
    -
    - ) + {buildOptions(_col)} + + ) + } else { + // Examples only + return ( + + ) + } } diff --git a/src/tools/online-lar-formatting/ParsedTable.jsx b/src/tools/online-lar-formatting/ParsedTable.jsx new file mode 100644 index 000000000..641382835 --- /dev/null +++ b/src/tools/online-lar-formatting/ParsedTable.jsx @@ -0,0 +1,32 @@ +import React from 'react' +import { collapseAll } from './Accordion' + +export const ParsedTable = ({ rows }) => ( +
    + e.preventDefault()} + style={{ + height: window.innerHeight * 0.1, + borderCollapse: 'separate', + }} + > + + + + + + + + + {rows} + +
    Column + Label + + + + Value
    +
    +) diff --git a/src/tools/online-lar-formatting/RawRow.jsx b/src/tools/online-lar-formatting/RawRow.jsx index 06fcf054d..34d808f86 100644 --- a/src/tools/online-lar-formatting/RawRow.jsx +++ b/src/tools/online-lar-formatting/RawRow.jsx @@ -1,6 +1,6 @@ import React from 'react' import { getSchema, goTo, goToFileActions, parseRow, stringifyRow } from './utils' -import { ParsedRow } from './ParsedRow' +import { Parsed } from './Parsed' const CurrentColumn = ({ column }) => { if (!column?.toString()) return null @@ -80,7 +80,7 @@ export const RawRow = ({ - * { +.parsed .section-heading > * { margin: 0; padding: 0; height: 2em; line-height: 2em; } -.parsed-row .section-heading button.clear, -.parsed-row .section-heading input { +.parsed .section-heading button.clear, +.parsed .section-heading input { margin-left: 2em; } -.parsed-row .section-heading button.clear { +.parsed .section-heading button.clear { line-height: normal; padding: 5px 1em; vertical-align: middle; } -.parsed-row .section-heading input { +.parsed .section-heading input { padding: 0 0.3em; } -.parsed-row .table-wrapper, -.parsed-row table, -.parsed-row tbody { +.parsed .table-wrapper, +.parsed table, +.parsed tbody { overflow: scroll; } -.parsed-row table { +.parsed table { position: relative; } -.parsed-row thead { +.parsed thead { position: sticky; top: 0; } -.parsed-row tbody { +.parsed tbody { margin-top: 0; } -.parsed-row tr { +.parsed tr { scroll-margin-top: 4em; } -.parsed-row .fieldIndex { +.parsed .fieldIndex { width: 6em; } -.parsed-row .fieldName { +.parsed .fieldName { width: 50%; } -.parsed-row .accordion-bordered > li{ +.parsed .accordion-bordered > li{ background-color: inherit; } -.parsed-row .accordion-bordered .accordion-button { +.parsed .accordion-bordered .accordion-button { background-color: white !important; border-left: 5px solid white; } -.parsed-row .accordion-bordered .accordion-button:hover { +.parsed .accordion-bordered .accordion-button:hover { color: black; border-left: 5px dotted darkolivegreen; background-color: lightgoldenrodyellow !important; } -.parsed-row .highlight { +.parsed .highlight { background: rgb(145, 206, 226); } -.parsed-row .table-wrapper > table { +.parsed .table-wrapper > table { width: 100%; } -.parsed-row .table-wrapper > table > thead { +.parsed .table-wrapper > table > thead { z-index: 1; } -.parsed-row .collapse-all { +.parsed .collapse-all { margin: 0; padding: .3em; } diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index 8affec724..98cbab527 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { ParsedRow } from './ParsedRow' +import { Parsed } from './Parsed' import { RawRow } from './RawRow' import { parseRow, diff --git a/src/tools/online-lar-formatting/parsedHelpers.jsx b/src/tools/online-lar-formatting/parsedHelpers.jsx new file mode 100644 index 000000000..1abb720e5 --- /dev/null +++ b/src/tools/online-lar-formatting/parsedHelpers.jsx @@ -0,0 +1,33 @@ +import React from 'react' + +export const applyFilter = (column, filter) => + !filter.length || column.fieldName.toLowerCase().includes(filter) + +export const checkHighlighted = (a, b) => + a && b && a.fieldIndex === b.fieldIndex ? 'highlight' : '' + +export const getType = ({ fieldType }) => { + if (fieldType == 'Alphanumeric') return 'text' + if (fieldType == 'Numeric') return 'number' + return 'text' +} + +export const buildOptions = column => { + const vals = column.values.map(({ value, description }) => ( + + )) + + vals.unshift( + + ) + return vals +} + +export const toJsDateString = str => { + if (!str) return '' + return `${str.slice(0, 4)}-${str.slice(4, 6)}-${str.slice(6)}` +} From dadcf69ce69e2218ece353e6d7f51390b5a256c2 Mon Sep 17 00:00:00 2001 From: Meis Date: Thu, 17 Feb 2022 14:38:15 -0700 Subject: [PATCH 20/69] [larft] Editing, Piped refactors --- src/tools/online-lar-formatting/Editing.jsx | 61 ++++++ .../online-lar-formatting/EditingActions.jsx | 49 +++++ .../online-lar-formatting/FileActions.jsx | 82 +++++++ src/tools/online-lar-formatting/Piped.jsx | 122 +++++++++++ src/tools/online-lar-formatting/RawRow.jsx | 206 ------------------ src/tools/online-lar-formatting/SavedRows.jsx | 19 +- src/tools/online-lar-formatting/clipboard.js | 34 +++ src/tools/online-lar-formatting/download.jsx | 15 ++ src/tools/online-lar-formatting/index.css | 6 +- src/tools/online-lar-formatting/index.jsx | 187 +++++----------- 10 files changed, 434 insertions(+), 347 deletions(-) create mode 100644 src/tools/online-lar-formatting/Editing.jsx create mode 100644 src/tools/online-lar-formatting/EditingActions.jsx create mode 100644 src/tools/online-lar-formatting/FileActions.jsx create mode 100644 src/tools/online-lar-formatting/Piped.jsx delete mode 100644 src/tools/online-lar-formatting/RawRow.jsx create mode 100644 src/tools/online-lar-formatting/clipboard.js create mode 100644 src/tools/online-lar-formatting/download.jsx diff --git a/src/tools/online-lar-formatting/Editing.jsx b/src/tools/online-lar-formatting/Editing.jsx new file mode 100644 index 000000000..5b12e88ae --- /dev/null +++ b/src/tools/online-lar-formatting/Editing.jsx @@ -0,0 +1,61 @@ +import React from 'react' +import { goTo } from './utils' +import { Parsed } from './Parsed' +import { Piped } from './Piped' +import { EditingActions } from './EditingActions' + +export const Editing = ({ + row, + setRow, + currCol, + setCurrCol, + saveRow, + newRow, + deleteRow, + id = 'raw-row', +}) => { + const PipedActions = ( + + ) + return ( +
    +

    goTo(id)}> + {row.rowId ? 'Editing' : 'Creating'}{' '} + {row['Record Identifier'] === '1' + ? 'Transmittal Sheet' + : row.rowId + ? `LAR Row ${row.rowId}` + : 'a new LAR Row'} +

    + + + +
    + ) +} diff --git a/src/tools/online-lar-formatting/EditingActions.jsx b/src/tools/online-lar-formatting/EditingActions.jsx new file mode 100644 index 000000000..cdd5f8c58 --- /dev/null +++ b/src/tools/online-lar-formatting/EditingActions.jsx @@ -0,0 +1,49 @@ +import React from 'react' +import { copyPiped, pastePiped } from './clipboard' + +const isEditing = row => row && row.rowId > -1 + +export const EditingActions = ({ + row, + deleteRow, + newRow, + setRow, + saveRow, + showTextActions = true, +}) => { + const paste = pastePiped(setRow) + const saveButtonText = isEditing(row) ? `Update Row ${row.rowId}` : 'Save Row' + + let deleteButton + if (isEditing(row)) { + deleteButton = ( + + ) + } + + return ( +
    +
    + + {deleteButton} + +
    + {!showTextActions ? null : ( +
    + + +
    + )} +
    + ) +} diff --git a/src/tools/online-lar-formatting/FileActions.jsx b/src/tools/online-lar-formatting/FileActions.jsx new file mode 100644 index 000000000..69b4c0397 --- /dev/null +++ b/src/tools/online-lar-formatting/FileActions.jsx @@ -0,0 +1,82 @@ +import React, { useState } from 'react' +import { stringifyRow, unity } from './utils' +import { FileUpload } from './FileUpload' +import { Error } from './Error' +import { download } from './download' + +const MESSAGES = { + upload: + 'Uploading a file will overwrite your current filing data. Are you sure?', + clear: 'This will delete all current filing data. Are you sure?', + needTS: 'Please create a Transmittal Sheet before saving!', + needLAR: 'Please create at least one Loan/Application Row before saving!', +} + +const createFileContent = (ts, lars) => + ts + .concat(lars) + .map(stringifyRow) + .filter(unity) + .map(s => s.trim()) + .join('\n') + +const DownloadButton = ({ ts, lars, setFileError }) => { + const handleDownload = () => { + if (!ts.length) return setFileError(MESSAGES.needTS) + if (!lars.length) return setFileError(MESSAGES.needLAR) + setFileError('') + download('LarFile.txt', createFileContent(ts, lars)) + } + + return ( + + ) +} + +const UploadButton = ({ hasSavedRecords }) => ( + +) + +const ClearButton = ({ hasSavedRecords, clearSaved }) => ( + +) + +export const FileActions = ({ + saveUpload, + hasSavedRecords, + clearSaved, + ts, + lars, +}) => { + const [fileError, setFileError] = useState() + + return ( +
    + {fileError && ( + setFileError(null)} /> + )} + + + + +
    + ) +} diff --git a/src/tools/online-lar-formatting/Piped.jsx b/src/tools/online-lar-formatting/Piped.jsx new file mode 100644 index 000000000..893cc75fe --- /dev/null +++ b/src/tools/online-lar-formatting/Piped.jsx @@ -0,0 +1,122 @@ +import React from 'react' +import { getSchema, goTo, parseRow, stringifyRow } from './utils' + +export const grabRawArea = () => document.getElementById('rawArea') + +const findPipes = row => stringifyRow(row).matchAll(new RegExp(/\|/, 'gi')) + +const highlight = text => {text} + +// Compare the current cursor position to the positions of +// the column delimiters to determine which LAR field is +// currently being edited/focused +const updateCurrentColumn = (setFn, row) => { + console.log('Updating column') + + const cursorPos = getCursorPos(grabRawArea()).start + const pipes = findPipes(row) + + let colNum = 0 + let pipeIter = pipes.next() + + while (!pipeIter.done && pipeIter.value.index < cursorPos) { + pipeIter = pipes.next() + colNum++ + } + + setFn(getSchema(row)[colNum]) +} + +const CurrentColumn = ({ column }) => { + if (!column?.toString()) return null + return ( +
    + Field name: {highlight(column.fieldName)} +
    + Column: {highlight(column.fieldIndex + 1)}{' '} +
    + ) +} + +const PasteableTextArea = ({ setRow, setCurrCol, row}) => { + const updateSelectedRow = e => + setRow({ + ...parseRow(e.target.value.trim()), + id: row?.id, + rowId: row.rowId, + }) + + const handleChange = () => updateCurrentColumn(setCurrCol, row) + const handlePaste = e => setRow(parseRow(e.target.value)) + + return ( + <> + - - - - ) -} - -// Thanks https://stackoverflow.com/a/7745998/15861235 -function getCursorPos(input) { - if ('selectionStart' in input && document.activeElement == input) { - return { - start: input.selectionStart, - end: input.selectionEnd, - } - } else if (input.createTextRange) { - var sel = document.selection.createRange() - if (sel.parentElement() === input) { - var rng = input.createTextRange() - rng.moveToBookmark(sel.getBookmark()) - for ( - var len = 0; - rng.compareEndPoints('EndToStart', rng) > 0; - rng.moveEnd('character', -1) - ) { - len++ - } - rng.setEndPoint('StartToStart', input.createTextRange()) - for ( - var pos = { start: 0, end: len }; - rng.compareEndPoints('EndToStart', rng) > 0; - rng.moveEnd('character', -1) - ) { - pos.start++ - pos.end++ - } - return pos - } - } - return -1 -} diff --git a/src/tools/online-lar-formatting/SavedRows.jsx b/src/tools/online-lar-formatting/SavedRows.jsx index d72ec1257..b3603b3ae 100644 --- a/src/tools/online-lar-formatting/SavedRows.jsx +++ b/src/tools/online-lar-formatting/SavedRows.jsx @@ -20,7 +20,6 @@ const Section = ({ id, title, rows, highlightSelected, setSelected }) => { })) }, [rows]) - const filteredRows = searchFilter.length && id === 'saved-lars' ? injectedRows.filter(ir => @@ -64,21 +63,16 @@ const Section = ({ id, title, rows, highlightSelected, setSelected }) => { filteredRows.length !== rows.length ? `(${filteredRows.length}/${rows.length})` : `(${rows.length})` - + return (
    {title && ( -

    +

    {title} {rowCount} - setSearchFilter(e.target.value.trim()) - } + onChange={e => setSearchFilter(e.target.value.trim())} placeholder='Search LAR' value={searchFilter} hidden={id.match(/ts/) || !rows.length} @@ -107,7 +101,7 @@ const LARs = ({ rows, ...props }) => ( /> ) -export const SavedRows = ({ ts, lars, selected, setSelected, deleteRow }) => { +export const SavedRows = ({ selected, ts, lars, setSelected, deleteRow }) => { const highlightSelected = r => { if (!selected || !r) return {} const highlighted = @@ -118,17 +112,22 @@ export const SavedRows = ({ ts, lars, selected, setSelected, deleteRow }) => { return (
    +

    + Saved Records +

    ) diff --git a/src/tools/online-lar-formatting/clipboard.js b/src/tools/online-lar-formatting/clipboard.js new file mode 100644 index 000000000..c58fafe9f --- /dev/null +++ b/src/tools/online-lar-formatting/clipboard.js @@ -0,0 +1,34 @@ +import { grabRawArea } from './Piped' +import { parseRow } from './utils' + +export const pastePiped = (setRow) => { + return () => { + if (navigator?.clipboard?.readText) { + navigator.clipboard + .readText() + .then(clipText => setRow(parseRow(clipText))) + } else { + document.getElementById('paste-button-input') + el.select() + document.execCommand('paste') + var event = new Event('change') + el.dispatchEvent(event) + } + } +} + +/** + * Copy pipe-delimited row to user's clipboard + */ + export const copyPiped = () => { + const el = grabRawArea() + if (navigator?.clipboard?.writeText) { + navigator.clipboard.writeText(el?.value).then( + _success => console.log('Success'), + _failed => console.error('Failed') + ) + } else { + el.select() + document.execCommand('copy') + } +} \ No newline at end of file diff --git a/src/tools/online-lar-formatting/download.jsx b/src/tools/online-lar-formatting/download.jsx new file mode 100644 index 000000000..6dcceb8c0 --- /dev/null +++ b/src/tools/online-lar-formatting/download.jsx @@ -0,0 +1,15 @@ +export function download(filename, text) { + var element = document.createElement('a') + element.setAttribute( + 'href', + 'data:text/plain;charset=utf-8,' + encodeURIComponent(text) + ) + element.setAttribute('download', filename) + + element.style.display = 'none' + document.body.appendChild(element) + + element.click() + + document.body.removeChild(element) +} diff --git a/src/tools/online-lar-formatting/index.css b/src/tools/online-lar-formatting/index.css index e8965d0b3..e6d0a4ed2 100644 --- a/src/tools/online-lar-formatting/index.css +++ b/src/tools/online-lar-formatting/index.css @@ -3,15 +3,17 @@ cursor: pointer; } .error { + scroll-margin-top: 1em; margin-bottom: 1em; padding: 1em; - border: 1px solid rgb(106, 8, 128); + border: 1px solid darkred; border-left-width: 10px; - color: rgb(106, 8, 128); + color: darkred; display: flex; flex-flow: row nowrap; justify-content: space-between; cursor: pointer; + font-size: 2rem; } .error .close { margin-left: auto; diff --git a/src/tools/online-lar-formatting/index.jsx b/src/tools/online-lar-formatting/index.jsx index 98cbab527..ef4883fe5 100644 --- a/src/tools/online-lar-formatting/index.jsx +++ b/src/tools/online-lar-formatting/index.jsx @@ -1,79 +1,71 @@ import React, { useState } from 'react' -import { Parsed } from './Parsed' -import { RawRow } from './RawRow' +import { Header } from './Header' +import { FileActions } from './FileActions' +import { Editing } from './Editing' +import { SavedRows } from './SavedRows' +import { useRestyledButtonLinks } from './useRestyledButtonLinks' +import { collapseAll } from './Accordion' import { parseRow, - stringifyRow, cloneObject, cloneObjectArray, - unity, getSchema, createID, isTS, isLAR, log, - goToFileActions } from './utils' -import { SavedRows } from './SavedRows' -import { FileUpload } from './FileUpload' -import { Header } from './Header' -import { Error } from './Error' -import { useRestyledButtonLinks } from './useRestyledButtonLinks' -import { collapseAll } from './Accordion' - import './index.css' - // TODO: -// √ - Each imported row needs an `id -// √ - Do everything by ID -// √ - Bug: `Update` button incorrect on `Clear Saved` -// √ - On Upload, Clear Saved -// √ - If TS/LAR, confirm overwrite -// √ - Provide search for LAR -// √- Provide date selector for Date fields -// √ - Example/Enumerations in `info` button/column -// - Provide search for TS? -// - On Download -// - Provide file dialog? +// - LAR/TS Column filter +// - TS text search +// - File download dialog? + +/* Thoughts + * I think we might want to invert control by managing creation of the Saved section's table's content + * higher-up the component tree, where it'll be easier to memoize since it's widely-used + * yet expensive to create. // MOVE-UP + */ const focusAtZero = () => null - // setTimeout(() => { - // const el = document.getElementById('rawArea') - // el.focus() - // el.selectionEnd = 0 - // }, 0) +// setTimeout(() => { +// const el = document.getElementById('rawArea') +// el.focus() +// el.selectionEnd = 0 +// }, 0) export const OnlineLARFT = () => { const [ts, setTS] = useState([]) const [lars, setLARs] = useState([]) const [selected, setSelected] = useState(parseRow(ts.length ? '2|' : '1|')) const [currCol, setCurrCol] = useState() - const [fileError, setFileError] = useState() + const hasSavedRecords = !!ts.length || !!lars.length + useRestyledButtonLinks() const newRow = () => { const nextRow = parseRow(ts.length ? '2|' : '1|') nextRow.id = createID() - setSelected(nextRow) setCurrCol(getSchema(nextRow)[0]) collapseAll() + setSelected(nextRow) } - const saveRow = _row => { - if (!_row) return + const saveRow = () => { + if (!selected) return let vals let updateFn - if (isTS(_row)) { - log('Processing a TS row', _row) + if (isTS(selected)) { + log('Processing a TS row', selected) vals = ts updateFn = setTS - } else if (isLAR(_row)) { - log('Processing a LAR row', _row) + } else if (isLAR(selected)) { + log('Processing a LAR row', selected) vals = lars updateFn = setLARs @@ -83,21 +75,22 @@ export const OnlineLARFT = () => { if (vals === ts) { log('Saving TS row') - const nextTS = cloneObject(_row) + const nextTS = cloneObject(selected) nextTS.id = createID() updateFn([nextTS]) + newRow() // Clear Pipe-delimited area } else { const cloned = cloneObjectArray(vals) log('Saving LAR row') // Update existing item - if (!!_row?.id) { - const updateIndex = cloned.findIndex(el => el?.id === _row.id) + if (!!selected?.id) { + const updateIndex = cloned.findIndex(el => el?.id === selected.id) if (updateIndex > -1) { log('Updating index: ', updateIndex) log('previous Row at index: ', cloned[updateIndex]) - log('Updated Row: ', _row) - cloned[updateIndex] = cloneObject(_row) + log('Updated Row: ', selected) + cloned[updateIndex] = cloneObject(selected) updateFn(cloned) // Save rows newRow() // Clear Pipe-delimited area focusAtZero() @@ -107,7 +100,7 @@ export const OnlineLARFT = () => { // Append new item log('Adding new item') - const obj = cloneObject(_row) + const obj = cloneObject(selected) obj.id = createID() cloned.push(obj) updateFn(cloned) // Save rows @@ -116,13 +109,13 @@ export const OnlineLARFT = () => { } } - const deleteRow = _row => { + const deleteRow = () => { const confirm = window.confirm('Are you sure you want to delete this row?') if (!confirm) return - log('Deleting ', _row) - if (isTS(_row)) setTS([]) + log('Deleting ', selected) + if (isTS(selected)) setTS([]) else { - let cloned = cloneObjectArray(lars).filter(r => r.id !== _row.id) + let cloned = cloneObjectArray(lars).filter(r => r.id !== selected.id) setLARs(cloned) } newRow() @@ -141,7 +134,7 @@ export const OnlineLARFT = () => { _lar = [], _unknown = {} - up_rows.forEach((r, idx) => { + up_rows.forEach(r => { const parsed = parseRow(r) parsed.id = createID() if (isTS(parsed)) return _ts.push(parsed) @@ -160,80 +153,32 @@ export const OnlineLARFT = () => { ) } + const clearSaved = () => { + setTS([]) + setLARs([]) + newRow() + } + return (
    - {fileError && ( - setFileError(null)} /> - )} -
    - - - - -
    -

    Saved Records

    + - + {
    ) } - -function download(filename, text) { - var element = document.createElement('a') - element.setAttribute( - 'href', - 'data:text/plain;charset=utf-8,' + encodeURIComponent(text) - ) - element.setAttribute('download', filename) - - element.style.display = 'none' - document.body.appendChild(element) - - element.click() - - document.body.removeChild(element) -} From 184088f46175470724da70595c45ee7b11f7799d Mon Sep 17 00:00:00 2001 From: Meis Date: Thu, 17 Feb 2022 14:44:05 -0700 Subject: [PATCH 21/69] [larft] Fix unique keys --- src/tools/online-lar-formatting/MoreInfo.jsx | 10 +++++----- src/tools/online-lar-formatting/Parsed.jsx | 1 + src/tools/online-lar-formatting/ParsedRow.jsx | 4 ++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tools/online-lar-formatting/MoreInfo.jsx b/src/tools/online-lar-formatting/MoreInfo.jsx index c651898b6..f7947577b 100644 --- a/src/tools/online-lar-formatting/MoreInfo.jsx +++ b/src/tools/online-lar-formatting/MoreInfo.jsx @@ -18,10 +18,10 @@ const List = (title, list, className) => { ) } -const buildRows = list => +const buildRows = (list, idx) => list.map(v => { return ( - + {v.value} {v.description} @@ -56,12 +56,12 @@ export const MoreInfo = memo(({ field }) => { const _descriptions = [] let _values = cloneObjectArray(values) - examples.forEach(curr => { + examples.forEach((curr, idx) => { if (isString(curr)) { const [ex, ...enums] = curr.split(DELIMITER) - if (isDescription(ex)) _descriptions.push(
  • {ex}
  • ) - else if (ex) _examples.push(
  • {ex}
  • ) + if (isDescription(ex)) _descriptions.push(
  • {ex}
  • ) + else if (ex) _examples.push(
  • {ex}
  • ) // Fields that have both enums and free text if (enums?.length) { diff --git a/src/tools/online-lar-formatting/Parsed.jsx b/src/tools/online-lar-formatting/Parsed.jsx index fe02819b9..7a6468d5f 100644 --- a/src/tools/online-lar-formatting/Parsed.jsx +++ b/src/tools/online-lar-formatting/Parsed.jsx @@ -45,6 +45,7 @@ export const Parsed = ({ .filter(x => applyFilter(x, filter)) .map(column => ( Date: Thu, 17 Feb 2022 17:01:15 -0700 Subject: [PATCH 22/69] [larft] Use `log` utility; Cleanup --- src/tools/online-lar-formatting/ParsedRow.jsx | 3 +- src/tools/online-lar-formatting/Piped.jsx | 16 ++++------ src/tools/online-lar-formatting/clipboard.js | 6 ++-- src/tools/online-lar-formatting/index.jsx | 31 +++++++------------ src/tools/online-lar-formatting/utils.js | 5 +-- 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/tools/online-lar-formatting/ParsedRow.jsx b/src/tools/online-lar-formatting/ParsedRow.jsx index f4ec13395..3c4545286 100644 --- a/src/tools/online-lar-formatting/ParsedRow.jsx +++ b/src/tools/online-lar-formatting/ParsedRow.jsx @@ -2,6 +2,7 @@ import React from 'react' import { Accordion } from './Accordion' import { MoreInfo } from './MoreInfo' import { buildOptions, getType, toJsDateString } from './parsedHelpers' +import { log } from './utils' export const ParsedRow = ({ column, @@ -39,7 +40,7 @@ export const ParsedRow = ({ } function buildInput(_col, _row, _changeFn) { - console.log('Building input...') + log('Building input...') if (!_col) return null const { examples = [], values = [] } = _col diff --git a/src/tools/online-lar-formatting/Piped.jsx b/src/tools/online-lar-formatting/Piped.jsx index 893cc75fe..198014c3e 100644 --- a/src/tools/online-lar-formatting/Piped.jsx +++ b/src/tools/online-lar-formatting/Piped.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { getSchema, goTo, parseRow, stringifyRow } from './utils' +import { getSchema, goTo, parseRow, stringifyRow, log } from './utils' export const grabRawArea = () => document.getElementById('rawArea') @@ -11,7 +11,7 @@ const highlight = text => {text} // the column delimiters to determine which LAR field is // currently being edited/focused const updateCurrentColumn = (setFn, row) => { - console.log('Updating column') + log('Updating column') const cursorPos = getCursorPos(grabRawArea()).start const pipes = findPipes(row) @@ -38,14 +38,14 @@ const CurrentColumn = ({ column }) => { ) } -const PasteableTextArea = ({ setRow, setCurrCol, row}) => { +const PasteableTextArea = ({ setRow, setCurrCol, row }) => { const updateSelectedRow = e => setRow({ ...parseRow(e.target.value.trim()), id: row?.id, rowId: row.rowId, }) - + const handleChange = () => updateCurrentColumn(setCurrCol, row) const handlePaste = e => setRow(parseRow(e.target.value)) @@ -58,11 +58,7 @@ const PasteableTextArea = ({ setRow, setCurrCol, row}) => { onClick={handleChange} onKeyUp={handleChange} /> -