@mistriwork/mistri 1.0.0-rc.12 → 1.0.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/client/assets/LayoutBuilder-MPzkVU2e.js.map +1 -1
- package/dist/client/assets/index-D2dHI6hR.js.map +1 -1
- package/dist/client/assets/shell-TreN_uLs.js.map +1 -1
- package/dist/docs/access-model.md +1 -1
- package/dist/docs/build-and-deploy.md +0 -1
- package/dist/docs/cli.md +1 -1
- package/dist/docs/glossary.md +3 -3
- package/dist/docs/query.md +9 -21
- package/dist/docs/status.md +3 -3
- package/dist/embed/react/chunks/LayoutBuilder-Cbxa_wve.js.map +1 -1
- package/dist/embed/react/chunks/app-0UZ1Re1k.js.map +1 -1
- package/dist/embed/react/chunks/page-Bx4o1kpQ.js.map +1 -1
- package/dist/embed/react/chunks/palette-Bb7Lf6eo.js.map +1 -1
- package/dist/embed/react/chunks/shell-DZRACiB9.js.map +1 -1
- package/dist/embed/react/chunks/write-BQO4CFc9.js.map +1 -1
- package/dist/embed/react/index.js +1 -1
- package/dist/server/build/dockerfile.js +1 -1
- package/dist/server/cli/usage.js +2 -2
- package/dist/ui/index.js +2 -2
- package/dist/ui/page.js +2 -2
- package/dist/ui/{shared-N4Ej8yRD.js → shared-1PD7TOTJ.js} +5 -5
- package/dist/ui/{shared-N4Ej8yRD.js.map → shared-1PD7TOTJ.js.map} +1 -1
- package/dist/ui/{shared-D5m86-4o.js → shared-1gMnOu9J.js} +6 -6
- package/dist/ui/{shared-D5m86-4o.js.map → shared-1gMnOu9J.js.map} +1 -1
- package/dist/ui/{shared-Ctaj8mR2.js → shared-5RQMi4BR.js} +3 -3
- package/dist/ui/{shared-Ctaj8mR2.js.map → shared-5RQMi4BR.js.map} +1 -1
- package/dist/ui/{shared-DpLeIATZ.js → shared-B-BUF9fx.js} +2 -2
- package/dist/ui/{shared-DpLeIATZ.js.map → shared-B-BUF9fx.js.map} +1 -1
- package/dist/ui/{shared-DWYnjItP.js → shared-B-MhiPIN.js} +9 -9
- package/dist/ui/{shared-DWYnjItP.js.map → shared-B-MhiPIN.js.map} +1 -1
- package/dist/ui/{shared-0fNuhSbG.js → shared-B07qIMlE.js} +5 -5
- package/dist/ui/{shared-0fNuhSbG.js.map → shared-B07qIMlE.js.map} +1 -1
- package/dist/ui/{shared-lYtMadRU.js → shared-B1SAS_J-.js} +3 -3
- package/dist/ui/{shared-lYtMadRU.js.map → shared-B1SAS_J-.js.map} +1 -1
- package/dist/ui/{shared-CpI0Y8M5.js → shared-B4jgU8h9.js} +6 -6
- package/dist/ui/{shared-CpI0Y8M5.js.map → shared-B4jgU8h9.js.map} +1 -1
- package/dist/ui/{shared-Cxu1c35l.js → shared-B5aBCUi7.js} +30 -30
- package/dist/ui/{shared-Cxu1c35l.js.map → shared-B5aBCUi7.js.map} +1 -1
- package/dist/ui/{shared-CAe-US1q.js → shared-B9H7_Pji.js} +5 -5
- package/dist/ui/{shared-CAe-US1q.js.map → shared-B9H7_Pji.js.map} +1 -1
- package/dist/ui/{shared-Q2bgBaYo.js → shared-BAXr20S-.js} +4 -4
- package/dist/ui/{shared-Q2bgBaYo.js.map → shared-BAXr20S-.js.map} +1 -1
- package/dist/ui/{shared-CyEefFFb.js → shared-BDDUzH-f.js} +19 -19
- package/dist/ui/{shared-CyEefFFb.js.map → shared-BDDUzH-f.js.map} +1 -1
- package/dist/ui/{shared-BdhPI6dq.js → shared-BGmkeDeW.js} +3 -3
- package/dist/ui/{shared-BdhPI6dq.js.map → shared-BGmkeDeW.js.map} +1 -1
- package/dist/ui/{shared-DONIpq2q.js → shared-BHCQ60yN.js} +2 -2
- package/dist/ui/{shared-DONIpq2q.js.map → shared-BHCQ60yN.js.map} +1 -1
- package/dist/ui/{shared-CNmaAv64.js → shared-BHsjawAG.js} +8 -8
- package/dist/ui/{shared-CNmaAv64.js.map → shared-BHsjawAG.js.map} +1 -1
- package/dist/ui/{shared-DgjU9kOy.js → shared-BIQuK_nq.js} +4 -4
- package/dist/ui/{shared-DgjU9kOy.js.map → shared-BIQuK_nq.js.map} +1 -1
- package/dist/ui/{shared-icSQAj21.js → shared-BOe4W2FI.js} +3 -3
- package/dist/ui/{shared-icSQAj21.js.map → shared-BOe4W2FI.js.map} +1 -1
- package/dist/ui/{shared-BlxoOJSk.js → shared-BPpC08ip.js} +3 -3
- package/dist/ui/{shared-BlxoOJSk.js.map → shared-BPpC08ip.js.map} +1 -1
- package/dist/ui/{shared-BtiFL37J.js → shared-BdA3LPCB.js} +2 -2
- package/dist/ui/{shared-BtiFL37J.js.map → shared-BdA3LPCB.js.map} +1 -1
- package/dist/ui/{shared-CvR94vn4.js → shared-Be3nbWsd.js} +11 -11
- package/dist/ui/{shared-CvR94vn4.js.map → shared-Be3nbWsd.js.map} +1 -1
- package/dist/ui/{shared-Bl_nF_IH.js → shared-Bf30ZLoS.js} +8 -4
- package/dist/ui/shared-Bf30ZLoS.js.map +1 -0
- package/dist/ui/{shared-DijrJ_V-.js → shared-BguP_BaR.js} +7 -7
- package/dist/ui/{shared-DijrJ_V-.js.map → shared-BguP_BaR.js.map} +1 -1
- package/dist/ui/{shared-DPAVoWY0.js → shared-BoLbc2WD.js} +17 -2
- package/dist/ui/{shared-DPAVoWY0.js.map → shared-BoLbc2WD.js.map} +1 -1
- package/dist/ui/{shared-BkdBTYwx.js → shared-BttyOW4W.js} +3 -3
- package/dist/ui/{shared-BkdBTYwx.js.map → shared-BttyOW4W.js.map} +1 -1
- package/dist/ui/{shared-CQWLz8uT.js → shared-BumxsBlA.js} +10 -10
- package/dist/ui/{shared-CQWLz8uT.js.map → shared-BumxsBlA.js.map} +1 -1
- package/dist/ui/{shared-Dzu7tFiC.js → shared-Bw73ktBk.js} +3 -3
- package/dist/ui/{shared-Dzu7tFiC.js.map → shared-Bw73ktBk.js.map} +1 -1
- package/dist/ui/{shared-BhAYErSx.js → shared-C1B0GH0e.js} +4 -4
- package/dist/ui/{shared-BhAYErSx.js.map → shared-C1B0GH0e.js.map} +1 -1
- package/dist/ui/{shared-BQJQcGgj.js → shared-C2FsyYr7.js} +4 -4
- package/dist/ui/{shared-BQJQcGgj.js.map → shared-C2FsyYr7.js.map} +1 -1
- package/dist/ui/{shared-B9lw2Ryh.js → shared-C2RU1qjv.js} +4 -4
- package/dist/ui/{shared-B9lw2Ryh.js.map → shared-C2RU1qjv.js.map} +1 -1
- package/dist/ui/{shared-DQYNI9wO.js → shared-C42f07hJ.js} +5 -5
- package/dist/ui/{shared-DQYNI9wO.js.map → shared-C42f07hJ.js.map} +1 -1
- package/dist/ui/{shared-CqCZ8wMY.js → shared-C4LkPCU4.js} +3 -3
- package/dist/ui/{shared-CqCZ8wMY.js.map → shared-C4LkPCU4.js.map} +1 -1
- package/dist/ui/{shared-BhtpgOpa.js → shared-C4wSfz6k.js} +9 -9
- package/dist/ui/{shared-BhtpgOpa.js.map → shared-C4wSfz6k.js.map} +1 -1
- package/dist/ui/{shared-BHc2Izkj.js → shared-C9DZtSFH.js} +2 -2
- package/dist/ui/{shared-BHc2Izkj.js.map → shared-C9DZtSFH.js.map} +1 -1
- package/dist/ui/{shared-DW1YuiNS.js → shared-CA52ClGo.js} +2 -2
- package/dist/ui/{shared-DW1YuiNS.js.map → shared-CA52ClGo.js.map} +1 -1
- package/dist/ui/{shared-BbSbilkh.js → shared-CBciTwm6.js} +9 -9
- package/dist/ui/{shared-BbSbilkh.js.map → shared-CBciTwm6.js.map} +1 -1
- package/dist/ui/{shared-C-J32eBn.js → shared-CL3RLKDA.js} +16 -16
- package/dist/ui/{shared-C-J32eBn.js.map → shared-CL3RLKDA.js.map} +1 -1
- package/dist/ui/{shared-Ck8S4OxW.js → shared-CLq3-_hW.js} +3 -3
- package/dist/ui/{shared-Ck8S4OxW.js.map → shared-CLq3-_hW.js.map} +1 -1
- package/dist/ui/{shared-Q5WefT7G.js → shared-CMjK-Ucd.js} +3 -3
- package/dist/ui/{shared-Q5WefT7G.js.map → shared-CMjK-Ucd.js.map} +1 -1
- package/dist/ui/{shared-D3MAuEA3.js → shared-CPjpSFGh.js} +2 -2
- package/dist/ui/{shared-D3MAuEA3.js.map → shared-CPjpSFGh.js.map} +1 -1
- package/dist/ui/{shared-VshXGwXP.js → shared-CSPhENq3.js} +2 -2
- package/dist/ui/{shared-VshXGwXP.js.map → shared-CSPhENq3.js.map} +1 -1
- package/dist/ui/{shared-DJrJaE73.js → shared-CZJE4Bmp.js} +3 -3
- package/dist/ui/{shared-DJrJaE73.js.map → shared-CZJE4Bmp.js.map} +1 -1
- package/dist/ui/{shared-D7ONOwI7.js → shared-C_BhUL2I.js} +7 -7
- package/dist/ui/{shared-D7ONOwI7.js.map → shared-C_BhUL2I.js.map} +1 -1
- package/dist/ui/{shared-j-2peBIB.js → shared-CbeujwdU.js} +4 -4
- package/dist/ui/{shared-j-2peBIB.js.map → shared-CbeujwdU.js.map} +1 -1
- package/dist/ui/{shared-D5GrOEa2.js → shared-Cbf-o4Dt.js} +4 -4
- package/dist/ui/{shared-D5GrOEa2.js.map → shared-Cbf-o4Dt.js.map} +1 -1
- package/dist/ui/{shared-HwiPIajr.js → shared-CdNmeNHh.js} +3 -3
- package/dist/ui/{shared-HwiPIajr.js.map → shared-CdNmeNHh.js.map} +1 -1
- package/dist/ui/{shared-ZCFt-CPb.js → shared-CdQOMD8J.js} +3 -3
- package/dist/ui/{shared-ZCFt-CPb.js.map → shared-CdQOMD8J.js.map} +1 -1
- package/dist/ui/{shared-ClhXSGGK.js → shared-CdiPYlTh.js} +2 -2
- package/dist/ui/{shared-ClhXSGGK.js.map → shared-CdiPYlTh.js.map} +1 -1
- package/dist/ui/{shared-DA8_pVRZ.js → shared-CepLAhwm.js} +2 -2
- package/dist/ui/{shared-DA8_pVRZ.js.map → shared-CepLAhwm.js.map} +1 -1
- package/dist/ui/{shared-BrYKjrnM.js → shared-Ch82h_Fu.js} +6 -6
- package/dist/ui/{shared-BrYKjrnM.js.map → shared-Ch82h_Fu.js.map} +1 -1
- package/dist/ui/{shared-C4UrE8Fb.js → shared-Chp88all.js} +3 -3
- package/dist/ui/{shared-C4UrE8Fb.js.map → shared-Chp88all.js.map} +1 -1
- package/dist/ui/{shared-CWa80DTO.js → shared-Ci16s2rN.js} +9 -9
- package/dist/ui/{shared-CWa80DTO.js.map → shared-Ci16s2rN.js.map} +1 -1
- package/dist/ui/{shared-tksTLD6Q.js → shared-CiqNkoE1.js} +5 -5
- package/dist/ui/{shared-tksTLD6Q.js.map → shared-CiqNkoE1.js.map} +1 -1
- package/dist/ui/{shared-yt7DjSrq.js → shared-CpMhOq8F.js} +2 -2
- package/dist/ui/{shared-yt7DjSrq.js.map → shared-CpMhOq8F.js.map} +1 -1
- package/dist/ui/{shared-Dm0z5WUl.js → shared-CrWv5JKH.js} +6 -6
- package/dist/ui/{shared-Dm0z5WUl.js.map → shared-CrWv5JKH.js.map} +1 -1
- package/dist/ui/{shared-CQL3FGHc.js → shared-Csfi3Pti.js} +2 -2
- package/dist/ui/{shared-CQL3FGHc.js.map → shared-Csfi3Pti.js.map} +1 -1
- package/dist/ui/{shared-BKNRbm-V.js → shared-CuZt26rm.js} +2 -2
- package/dist/ui/{shared-BKNRbm-V.js.map → shared-CuZt26rm.js.map} +1 -1
- package/dist/ui/{shared-Guq3upiR.js → shared-Cws_z-TS.js} +2 -2
- package/dist/ui/{shared-Guq3upiR.js.map → shared-Cws_z-TS.js.map} +1 -1
- package/dist/ui/{shared-Bw_qZeIj.js → shared-D1KWuCg6.js} +2 -2
- package/dist/ui/{shared-Bw_qZeIj.js.map → shared-D1KWuCg6.js.map} +1 -1
- package/dist/ui/{shared-CuCZKwXW.js → shared-D66ju_Cb.js} +23 -23
- package/dist/ui/{shared-CuCZKwXW.js.map → shared-D66ju_Cb.js.map} +1 -1
- package/dist/ui/{shared-DYfX7NSM.js → shared-DGaQZXnw.js} +2 -2
- package/dist/ui/{shared-DYfX7NSM.js.map → shared-DGaQZXnw.js.map} +1 -1
- package/dist/ui/{shared-B3Hp8tOv.js → shared-DHy41sET.js} +6 -6
- package/dist/ui/{shared-B3Hp8tOv.js.map → shared-DHy41sET.js.map} +1 -1
- package/dist/ui/{shared-CXyd7IKi.js → shared-DKEOMQ6l.js} +2 -2
- package/dist/ui/{shared-CXyd7IKi.js.map → shared-DKEOMQ6l.js.map} +1 -1
- package/dist/ui/{shared-Ccmc8YO0.js → shared-DSUICuaJ.js} +33 -33
- package/dist/ui/{shared-Ccmc8YO0.js.map → shared-DSUICuaJ.js.map} +1 -1
- package/dist/ui/{shared-CL2iw_js.js → shared-DUPMRoO0.js} +13 -13
- package/dist/ui/{shared-CL2iw_js.js.map → shared-DUPMRoO0.js.map} +1 -1
- package/dist/ui/{shared-Dtp4eRul.js → shared-DVfdm6ah.js} +2 -2
- package/dist/ui/{shared-Dtp4eRul.js.map → shared-DVfdm6ah.js.map} +1 -1
- package/dist/ui/{shared-BJ5Ex32G.js → shared-DXM7d7lJ.js} +3 -3
- package/dist/ui/{shared-BJ5Ex32G.js.map → shared-DXM7d7lJ.js.map} +1 -1
- package/dist/ui/{shared-BFr6ld0e.js → shared-DXbMlcev.js} +2 -2
- package/dist/ui/{shared-BFr6ld0e.js.map → shared-DXbMlcev.js.map} +1 -1
- package/dist/ui/{shared-BUp3jv-N.js → shared-D_SkPtJ9.js} +6 -6
- package/dist/ui/{shared-BUp3jv-N.js.map → shared-D_SkPtJ9.js.map} +1 -1
- package/dist/ui/{shared-CdNomVzH.js → shared-Dd21k2ic.js} +4 -4
- package/dist/ui/{shared-CdNomVzH.js.map → shared-Dd21k2ic.js.map} +1 -1
- package/dist/ui/{shared-gRMbxmpu.js → shared-Dh0nHtLZ.js} +8 -8
- package/dist/ui/{shared-gRMbxmpu.js.map → shared-Dh0nHtLZ.js.map} +1 -1
- package/dist/ui/{shared-BKGJgjog.js → shared-DkOdSpSK.js} +3 -3
- package/dist/ui/{shared-BKGJgjog.js.map → shared-DkOdSpSK.js.map} +1 -1
- package/dist/ui/{shared-BMsh72Uq.js → shared-Dkph5ckT.js} +2 -2
- package/dist/ui/{shared-BMsh72Uq.js.map → shared-Dkph5ckT.js.map} +1 -1
- package/dist/ui/{shared-Be1HpDOB.js → shared-Dl1_Nx--.js} +3 -3
- package/dist/ui/{shared-Be1HpDOB.js.map → shared-Dl1_Nx--.js.map} +1 -1
- package/dist/ui/{shared-BQIZWOoJ.js → shared-Dm0IGbAf.js} +2 -2
- package/dist/ui/{shared-BQIZWOoJ.js.map → shared-Dm0IGbAf.js.map} +1 -1
- package/dist/ui/{shared-DSUtcU5S.js → shared-DnIkTpPr.js} +5 -5
- package/dist/ui/{shared-DSUtcU5S.js.map → shared-DnIkTpPr.js.map} +1 -1
- package/dist/ui/{shared-DsxGbYlV.js → shared-Docl_0tq.js} +3 -3
- package/dist/ui/{shared-DsxGbYlV.js.map → shared-Docl_0tq.js.map} +1 -1
- package/dist/ui/{shared-DZskrV26.js → shared-DprrHC72.js} +2 -2
- package/dist/ui/{shared-DZskrV26.js.map → shared-DprrHC72.js.map} +1 -1
- package/dist/ui/{shared-Bmw43Hwf.js → shared-DyKsJTZs.js} +2 -2
- package/dist/ui/{shared-Bmw43Hwf.js.map → shared-DyKsJTZs.js.map} +1 -1
- package/dist/ui/{shared-BLG88Pya.js → shared-FO7vfI3F.js} +4 -4
- package/dist/ui/{shared-BLG88Pya.js.map → shared-FO7vfI3F.js.map} +1 -1
- package/dist/ui/{shared-DLSd80D1.js → shared-HalAVHjv.js} +3 -3
- package/dist/ui/{shared-DLSd80D1.js.map → shared-HalAVHjv.js.map} +1 -1
- package/dist/ui/{shared-D1mMBLdj.js → shared-JvcI-LWp.js} +15 -15
- package/dist/ui/{shared-D1mMBLdj.js.map → shared-JvcI-LWp.js.map} +1 -1
- package/dist/ui/{shared-C6Hv_4O0.js → shared-K7Ym27yg.js} +2 -2
- package/dist/ui/{shared-C6Hv_4O0.js.map → shared-K7Ym27yg.js.map} +1 -1
- package/dist/ui/{shared-B39ln7oi.js → shared-SzlnwfJO.js} +3 -3
- package/dist/ui/{shared-B39ln7oi.js.map → shared-SzlnwfJO.js.map} +1 -1
- package/dist/ui/{shared-DgPn_Jll.js → shared-TrGbd1FY.js} +3 -3
- package/dist/ui/{shared-DgPn_Jll.js.map → shared-TrGbd1FY.js.map} +1 -1
- package/dist/ui/{shared-DrFb-XtA.js → shared-WhbuObEW.js} +2 -2
- package/dist/ui/{shared-DrFb-XtA.js.map → shared-WhbuObEW.js.map} +1 -1
- package/dist/ui/{shared-DiFQljcq.js → shared-XcSKDp6N.js} +11 -11
- package/dist/ui/{shared-DiFQljcq.js.map → shared-XcSKDp6N.js.map} +1 -1
- package/dist/ui/{shared-CMAg58rY.js → shared-Z4uBJU6I.js} +7 -6
- package/dist/ui/shared-Z4uBJU6I.js.map +1 -0
- package/dist/ui/{shared-BnUptuUp.js → shared-bAgeiRa5.js} +2 -2
- package/dist/ui/{shared-BnUptuUp.js.map → shared-bAgeiRa5.js.map} +1 -1
- package/dist/ui/{shared-BxMvSjey.js → shared-cgXG7OgZ.js} +5 -5
- package/dist/ui/{shared-BxMvSjey.js.map → shared-cgXG7OgZ.js.map} +1 -1
- package/dist/ui/{shared-u4CG2kQJ.js → shared-eZ0SB_zm.js} +2 -2
- package/dist/ui/{shared-u4CG2kQJ.js.map → shared-eZ0SB_zm.js.map} +1 -1
- package/dist/ui/{shared-L90bWW8e.js → shared-frKFb79C.js} +2 -2
- package/dist/ui/{shared-L90bWW8e.js.map → shared-frKFb79C.js.map} +1 -1
- package/dist/ui/{shared-Dd34nhkw.js → shared-hAayNSRA.js} +3 -3
- package/dist/ui/{shared-Dd34nhkw.js.map → shared-hAayNSRA.js.map} +1 -1
- package/dist/ui/{shared-DzC64cpp.js → shared-j_J16p2B.js} +2 -2
- package/dist/ui/{shared-DzC64cpp.js.map → shared-j_J16p2B.js.map} +1 -1
- package/dist/ui/{shared-DX7HRIV-.js → shared-tqpl5N3g.js} +6 -6
- package/dist/ui/{shared-DX7HRIV-.js.map → shared-tqpl5N3g.js.map} +1 -1
- package/dist/ui/{shared-BS5dBMpA.js → shared-y-6_ZDts.js} +2 -2
- package/dist/ui/{shared-BS5dBMpA.js.map → shared-y-6_ZDts.js.map} +1 -1
- package/dist/ui/{shared-Cv5v_MP1.js → shared-zG6e1Rhz.js} +13 -13
- package/dist/ui/{shared-Cv5v_MP1.js.map → shared-zG6e1Rhz.js.map} +1 -1
- package/dist/ui/testing.js +1 -1
- package/package.json +4 -4
- package/dist/docs/cli-browser.md +0 -232
- package/dist/docs/database-browser.md +0 -115
- package/dist/docs/keyboard.md +0 -63
- package/dist/docs/mcp.md +0 -86
- package/dist/ui/shared-Bl_nF_IH.js.map +0 -1
- package/dist/ui/shared-CMAg58rY.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-D5m86-4o.js","names":["recordKey","wireKey"],"sources":["../../../kit/src/client/copy/lists/components/GridCellEditor.ts","../../../kit/src/client/components/GridCellEditor.tsx"],"sourcesContent":["/** What GridCellEditor says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n one: 'one of: {allowed}',\n saved: 'Saved {label}.',\n edit: 'Edit {label}',\n});\n","/**\n * A grid's cell edited in place, for a list view that says `editable`.\n *\n * A spreadsheet's contract, on the record form's rules. Enter or F2 on the\n * cell (or a click on it) opens its editor; Enter saves, Esc puts the value\n * back, Tab saves and moves to the row's next editable cell, and leaving the\n * cell saves. The editor is the one a record form draws for the column: a\n * picker for a reference, a list for a vocabulary or a flag, the calendar for\n * a date, a box for the rest.\n *\n * The save is the record form's own request — `/api/update` with the one\n * value and what it replaces as `expected` — so the server judges it as it\n * judges a Save: the reader's grants on the resource and the field, the\n * row policy and tenancy, the resource's validation, its transitions and\n * stamps, and history. Nothing here is a permission; a cell is offered only\n * where that request could succeed.\n *\n * Optimistic, as the board's and the hand order's moves are: the new value\n * is drawn at once, and a refusal puts the stored one back and says why in\n * the same toast those lists use. An unconfirmed write stays drawn and is\n * said as unconfirmed, because the record may hold it. A write that lands\n * offers Undo beside its confirmation, as the Workbench's save does.\n *\n * Not the record form's staged draft: that holds one record's several fields\n * until Save, and a grid's cell is one field saved when it is left. Keeping\n * them apart means a half-typed record form on another tab of the walk is\n * never saved by a cell.\n */\nimport { useEffect, useId, useLayoutEffect, useRef, useState, type KeyboardEvent } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { api, columnDisplay, columnLabel, findTable, state, toast } from '../core.js';\nimport { ownedBy } from '../requestIdentity.js';\nimport { columnKind, type TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { humanName, vocabularyWord } from '@mistriwork/engine/shared/model.js';\nimport { booleanChoices, canEditRow } from '../rowEditing.js';\nimport { updateAttempts } from '../updateAttempts.js';\nimport { recordKey as wireKey } from '../resourceRequests.js';\nimport { validateRecordEdits } from '../recordEditValidation.js';\nimport { shell } from '../shellMode.js';\nimport { sessionIdentity } from '../sessionIdentity.js';\nimport { defaultCurrency, formatLocale, formatTimezone } from '../locale.js';\nimport { rowCurrency } from '@mistriwork/engine/shared/money.js';\nimport { MinorMoneyInput } from './MinorMoneyInput.js';\nimport { Dropdown } from './Dropdown.js';\nimport { RecordPicker } from './RecordPicker.js';\nimport { DateField } from './DateField.js';\nimport { booleanWords, type DisplayRule } from './valueModel.js';\nimport { singleReference, type CellDraw, type EditColumn } from './gridCellModel.js';\nimport { InputSlot, columnInput } from './inputRenderers.js';\nimport { say } from '../copy/lists/components/GridCellEditor.js';\n\nconst said = (value: unknown): string | null => (value === null || value === undefined ? null : String(value));\n\n/**\n * The control a record form draws for a column, over a text value (`null`\n * for none). Shared by a cell and the selection's \"Set field…\".\n */\nexport function ValueControl(props: {\n table: TableMeta;\n column: EditColumn;\n value: string | null;\n onChange: (value: string | null) => void;\n label: string;\n id?: string;\n row?: Record<string, unknown>;\n /** The name of the reference `value` holds, where the caller already has it drawn. */\n valueLabel?: string;\n /** A reference's search text is not a value until one is chosen. */\n onPickerState?: (state: { unresolvedReference: boolean; open: boolean }) => void;\n describedBy?: string;\n invalid?: boolean;\n}) {\n const inputId = useId();\n /* The App's own input for this column, where it names one (`resources.<name>.inputs`): the\n editor still keeps, checks and saves the value it hands back, as text like every control here. */\n const custom = columnInput(props.table.id, props.column.name);\n if (!custom) return <PlatformControl {...props} />;\n return (\n <InputSlot\n component={custom}\n fallback={<PlatformControl {...props} />}\n value={props.value}\n onChange={(next) => props.onChange(next === null || next === '' ? (props.column.nullable ? null : '') : String(next))}\n id={props.id ?? inputId}\n describedBy={props.describedBy}\n invalid={props.invalid === true}\n disabled={false}\n required={props.column.nullable === false}\n label={props.label}\n field={{ name: props.column.name, resource: props.table.id }}\n context=\"edit\"\n />\n );\n}\n\nfunction PlatformControl({\n table,\n column,\n value,\n onChange,\n label,\n id,\n row,\n onPickerState,\n describedBy,\n invalid,\n valueLabel,\n}: Parameters<typeof ValueControl>[0]) {\n const dateId = useId();\n const change = (next: string) => onChange(next === '' && column.nullable ? null : next);\n const target =\n column.references && singleReference(table, column) ? (findTable(column.references.table) as TableMeta | undefined) : undefined;\n if (target) {\n return (\n <RecordPicker\n table={target}\n valueColumn={column.references!.column}\n value={value ?? ''}\n onChange={change}\n ariaLabel={label}\n app\n {...(valueLabel && value ? { known: { value, label: valueLabel } } : {})}\n editing={{ onStateChange: (next) => onPickerState?.(next) }}\n />\n );\n }\n const choices = booleanChoices(column, row) as { yes: string; no: string } | null;\n if (column.allowed?.length || choices) {\n const words = choices ? booleanWords(columnDisplay(table.id, column.name) as DisplayRule | null, choices) : {};\n const items = column.allowed?.length\n ? column.allowed.map((v) => ({ value: v, label: vocabularyWord(v) || humanName(v) }))\n : [\n { value: choices!.yes, label: words.yes ?? say('common.yes') },\n { value: choices!.no, label: words.no ?? say('common.no') },\n ];\n if (value !== null && !items.some((item) => item.value === value)) items.unshift({ value, label: value });\n return (\n <Dropdown\n ariaLabel={label}\n id={id}\n value={value ?? ''}\n ariaInvalid={invalid}\n ariaDescribedBy={describedBy}\n items={[...(column.nullable ? [{ value: '', label: say('common.noValue') }] : []), ...items]}\n onChange={change}\n />\n );\n }\n if (columnKind(column.type) === 'date' && !/time/i.test(column.type)) {\n return (\n <DateField\n id={id ?? dateId}\n value={value ?? ''}\n onChange={change}\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n locale={formatLocale()}\n timezone={formatTimezone()}\n />\n );\n }\n /* Money kept as minor units is typed as the figure it is (\"19.99\") and held as what is stored (1999). */\n const rule = columnDisplay(table.id, column.name) as { format?: string; minor?: true; currency?: string; currencyColumn?: string } | null;\n if (rule?.format === 'money' && rule.minor)\n return (\n <MinorMoneyInput value={value ?? ''} currency={rowCurrency(rule, row, rule.currency || defaultCurrency())} onChange={change}>\n {(text, typed) => (\n <input\n id={id}\n type=\"text\"\n inputMode=\"decimal\"\n className=\"cell-edit\"\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n value={text}\n data-null={String(value === null)}\n onChange={(event) => typed(event.target.value)}\n />\n )}\n </MinorMoneyInput>\n );\n return (\n <input\n id={id}\n type=\"text\"\n className=\"cell-edit\"\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n value={value ?? ''}\n data-null={String(value === null)}\n onChange={(event) => change(event.target.value)}\n title={column.allowed?.length ? say('one', { allowed: column.allowed.join(', ') }) : undefined}\n />\n );\n}\n\n/** The row's next (or previous) editable cell after this one, opened. */\nfunction openNeighbor(from: HTMLElement | null, backward: boolean): boolean {\n const cell = from?.closest('td');\n const row = cell?.closest('tr');\n if (!cell || !row) return false;\n const cells = [...row.querySelectorAll<HTMLElement>(':scope > td.cell-editable')];\n const next = cells[cells.indexOf(cell) + (backward ? -1 : 1)];\n next?.querySelector<HTMLElement>('[data-cell-edits]')?.click();\n return Boolean(next);\n}\n\ninterface Shown {\n value: unknown;\n label?: unknown;\n}\n\nexport function GridCellEdit({\n table,\n row,\n column,\n recordKey,\n draw,\n byName = false,\n valueLabel,\n}: {\n table: TableMeta;\n row: Record<string, unknown>;\n column: EditColumn;\n recordKey: Record<string, unknown>;\n draw: CellDraw;\n /** The cell draws the reference's record by name (`owner_id.name`), not the key it holds. */\n byName?: boolean;\n /** The stored reference's name as the cell draws it: the picker opens on it, never on the bare key. */\n valueLabel?: string;\n}) {\n const client = useQueryClient();\n const errorId = useId();\n const label = columnLabel(table.id, column.name) ?? humanName(column.name);\n const stored = said(row[column.name]);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<string | null>(stored);\n const [problem, setProblem] = useState('');\n /* What the reader saved, drawn until the list's own answer carries it. */\n const [shown, setShown] = useState<(Shown & { from: unknown }) | null>(null);\n const surface = useRef<HTMLDivElement>(null);\n const launcher = useRef<HTMLButtonElement>(null);\n const unresolved = useRef(false);\n const pickerOpen = useRef(false);\n /* Where focus goes once the editor closes: back to the cell, unless Tab sent it on. */\n const refocus = useRef(false);\n const alive = useRef(true);\n useEffect(() => {\n alive.current = true;\n return () => {\n alive.current = false;\n };\n }, []);\n // A refetch that carries a new stored value is the answer; the optimistic drawing yields to it.\n useEffect(() => {\n if (shown && shown.from !== row[column.name]) setShown(null);\n }, [row, column.name, shown]);\n\n useLayoutEffect(() => {\n if (!editing) {\n if (refocus.current) {\n refocus.current = false;\n (launcher.current?.closest('td') as HTMLElement | null)?.focus();\n }\n return;\n }\n const node = surface.current;\n node?.querySelector<HTMLElement>('input, .dd-button, button')?.focus();\n }, [editing]);\n\n const open = () => {\n if (\n !canEditRow(table, recordKey) ||\n updateAttempts.get({ connection: state.activeConnection ?? null, table: table.id, key: recordKey })\n )\n return;\n setDraft(said(shown ? shown.value : row[column.name]));\n setProblem('');\n unresolved.current = false;\n setEditing(true);\n };\n const close = (focusCell: boolean) => {\n refocus.current = focusCell;\n setProblem('');\n setEditing(false);\n };\n\n /** Close the editor and send the value; false while the value is not one to send (the editor stays, saying why). */\n const commit = (value: string | null, focusCell: boolean, labelText?: string): boolean => {\n const original = shown ? said(shown.value) : stored;\n if (value === original) {\n close(focusCell);\n return true;\n }\n const values = { [column.name]: value };\n const refused = validateRecordEdits(table, values, unresolved.current ? { [column.name]: { unresolvedReference: true } } : {});\n if (refused[column.name]) {\n setProblem(refused[column.name]);\n return false;\n }\n let key: ReturnType<typeof wireKey>;\n try {\n key = wireKey(recordKey);\n } catch (error) {\n setProblem((error as Error).message);\n return false;\n }\n if (!canEditRow(table, recordKey)) {\n close(focusCell);\n return true;\n }\n // Drawn at once; put back below if the server says no.\n setShown({ value, label: labelText, from: row[column.name] });\n close(focusCell);\n void send(values, original, key);\n return true;\n };\n const send = async (values: Record<string, string | null>, original: string | null, key: ReturnType<typeof wireKey>) => {\n const connection = state.activeConnection ?? null;\n const identity = sessionIdentity();\n const outcome = await updateAttempts.run({ connection, table: table.id, key: recordKey }, values, () =>\n api('/api/update', { ...ownedBy(connection), table: table.id, key, values, expected: { [column.name]: original } }),\n );\n if (identity !== sessionIdentity()) return;\n if (outcome.kind === 'applied') {\n void shell().undo.refresh();\n void client.invalidateQueries({ queryKey: ['run', connection] });\n void client.invalidateQueries({ queryKey: ['count', connection] });\n toast(\n say('saved', { label }),\n 'ok',\n !identity.tenantRequired && outcome.undoId\n ? {\n label: say('common.undo'),\n run: () => {\n if (identity === sessionIdentity() && connection === (state.activeConnection ?? null))\n void shell().undo.last(outcome.undoId);\n },\n }\n : undefined,\n );\n return;\n }\n // A refusal is the stored value's to keep; an unconfirmed write may have landed, so it stays drawn.\n if (outcome.kind !== 'uncertain' && alive.current) setShown(null);\n toast(outcome.message, 'error');\n };\n\n const pickedLabel = () => (column.references ? surface.current?.querySelector<HTMLInputElement>('input')?.value : undefined);\n const onKey = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n // A picker or a list closes its own popup first; the next Escape puts the value back.\n if (pickerOpen.current || (event.target as Element).closest('[aria-expanded=\"true\"]')) return;\n event.preventDefault();\n event.stopPropagation();\n close(true);\n return;\n }\n if (event.key === 'Enter' && event.target instanceof HTMLInputElement && !pickerOpen.current) {\n event.preventDefault();\n event.stopPropagation();\n commit(draft, true, pickedLabel());\n return;\n }\n if (event.key === 'Tab') {\n event.preventDefault();\n event.stopPropagation();\n const cell = surface.current?.closest('td') as HTMLElement | null;\n const backward = event.shiftKey;\n // Moving on is the save; a value that cannot be sent keeps the reader here.\n if (commit(draft, false, pickedLabel())) {\n requestAnimationFrame(() => {\n if (!openNeighbor(cell, backward)) cell?.focus();\n });\n }\n }\n };\n /* Leaving the cell saves it, as a spreadsheet's does. A popup the editor\n opened (a picker's list, a calendar) is still the editor. */\n const onBlur = () => {\n requestAnimationFrame(() => {\n const node = surface.current;\n const active = document.activeElement;\n if (!alive.current || !node || !editing) return;\n if (active && (node.contains(active) || active.closest('[role=\"listbox\"], [role=\"dialog\"], .dd-popup, .date-field-popup'))) return;\n void commit(draft, false, pickedLabel());\n });\n };\n\n if (!editing) {\n const body = !shown\n ? draw()\n : byName\n ? draw({ value: shown.value === null ? null : (shown.label ?? shown.value) })\n : draw({ value: shown.value, label: shown.label });\n /* The cell's value is the button: a click edits it rather than opening\n the row, and the grid's Enter and F2 press it (useGridKeyboard). */\n return (\n <button\n ref={launcher}\n type=\"button\"\n className=\"cell-edit-launch\"\n aria-label={say('edit', { label })}\n data-cell-opens=\"\"\n data-cell-edits=\"\"\n onClick={(event) => {\n event.stopPropagation();\n open();\n }}\n >\n {body}\n </button>\n );\n }\n const change = (next: string | null) => {\n setDraft(next);\n setProblem('');\n /* Choosing from a list or a picker is the whole edit: nothing left to\n type. A picker reports a choice as its value; a cleared one waits for\n Enter, since clearing may be the start of a new search. */\n if (column.references && next !== null && next !== '') unresolved.current = false;\n if (column.references ? next !== null && next !== '' : Boolean(column.allowed?.length || booleanChoices(column, row))) {\n requestAnimationFrame(() => {\n void commit(next, true, pickedLabel());\n });\n }\n };\n return (\n <div\n ref={surface}\n className=\"cell-edit-surface\"\n data-edit-field=\"\"\n onKeyDownCapture={onKey}\n onBlur={onBlur}\n onClick={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <ValueControl\n table={table}\n column={column}\n value={draft}\n onChange={change}\n label={label}\n row={row}\n valueLabel={shown ? (typeof shown.label === 'string' ? shown.label : undefined) : valueLabel}\n describedBy={problem ? errorId : undefined}\n invalid={Boolean(problem)}\n onPickerState={(next) => {\n unresolved.current = next.unresolvedReference;\n pickerOpen.current = next.open;\n }}\n />\n {problem && (\n <span id={errorId} className=\"edit-field-error\" role=\"alert\">\n {problem}\n </span>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shared-1gMnOu9J.js","names":["recordKey","wireKey"],"sources":["../../../kit/src/client/copy/lists/components/GridCellEditor.ts","../../../kit/src/client/components/GridCellEditor.tsx"],"sourcesContent":["/** What GridCellEditor says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n one: 'one of: {allowed}',\n saved: 'Saved {label}.',\n edit: 'Edit {label}',\n});\n","/**\n * A grid's cell edited in place, for a list view that says `editable`.\n *\n * A spreadsheet's contract, on the record form's rules. Enter or F2 on the\n * cell (or a click on it) opens its editor; Enter saves, Esc puts the value\n * back, Tab saves and moves to the row's next editable cell, and leaving the\n * cell saves. The editor is the one a record form draws for the column: a\n * picker for a reference, a list for a vocabulary or a flag, the calendar for\n * a date, a box for the rest.\n *\n * The save is the record form's own request — `/api/update` with the one\n * value and what it replaces as `expected` — so the server judges it as it\n * judges a Save: the reader's grants on the resource and the field, the\n * row policy and tenancy, the resource's validation, its transitions and\n * stamps, and history. Nothing here is a permission; a cell is offered only\n * where that request could succeed.\n *\n * Optimistic, as the board's and the hand order's moves are: the new value\n * is drawn at once, and a refusal puts the stored one back and says why in\n * the same toast those lists use. An unconfirmed write stays drawn and is\n * said as unconfirmed, because the record may hold it. A write that lands\n * offers Undo beside its confirmation, as the Workbench's save does.\n *\n * Not the record form's staged draft: that holds one record's several fields\n * until Save, and a grid's cell is one field saved when it is left. Keeping\n * them apart means a half-typed record form on another tab of the walk is\n * never saved by a cell.\n */\nimport { useEffect, useId, useLayoutEffect, useRef, useState, type KeyboardEvent } from 'react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { api, columnDisplay, columnLabel, findTable, state, toast } from '../core.js';\nimport { ownedBy } from '../requestIdentity.js';\nimport { columnKind, type TableMeta } from '@mistriwork/engine/shared/schema.js';\nimport { humanName, vocabularyWord } from '@mistriwork/engine/shared/model.js';\nimport { booleanChoices, canEditRow } from '../rowEditing.js';\nimport { updateAttempts } from '../updateAttempts.js';\nimport { recordKey as wireKey } from '../resourceRequests.js';\nimport { validateRecordEdits } from '../recordEditValidation.js';\nimport { shell } from '../shellMode.js';\nimport { sessionIdentity } from '../sessionIdentity.js';\nimport { defaultCurrency, formatLocale, formatTimezone } from '../locale.js';\nimport { rowCurrency } from '@mistriwork/engine/shared/money.js';\nimport { MinorMoneyInput } from './MinorMoneyInput.js';\nimport { Dropdown } from './Dropdown.js';\nimport { RecordPicker } from './RecordPicker.js';\nimport { DateField } from './DateField.js';\nimport { booleanWords, type DisplayRule } from './valueModel.js';\nimport { singleReference, type CellDraw, type EditColumn } from './gridCellModel.js';\nimport { InputSlot, columnInput } from './inputRenderers.js';\nimport { say } from '../copy/lists/components/GridCellEditor.js';\n\nconst said = (value: unknown): string | null => (value === null || value === undefined ? null : String(value));\n\n/**\n * The control a record form draws for a column, over a text value (`null`\n * for none). Shared by a cell and the selection's \"Set field…\".\n */\nexport function ValueControl(props: {\n table: TableMeta;\n column: EditColumn;\n value: string | null;\n onChange: (value: string | null) => void;\n label: string;\n id?: string;\n row?: Record<string, unknown>;\n /** The name of the reference `value` holds, where the caller already has it drawn. */\n valueLabel?: string;\n /** A reference's search text is not a value until one is chosen. */\n onPickerState?: (state: { unresolvedReference: boolean; open: boolean }) => void;\n describedBy?: string;\n invalid?: boolean;\n}) {\n const inputId = useId();\n /* The App's own input for this column, where it names one (`resources.<name>.inputs`): the\n editor still keeps, checks and saves the value it hands back, as text like every control here. */\n const custom = columnInput(props.table.id, props.column.name);\n if (!custom) return <PlatformControl {...props} />;\n return (\n <InputSlot\n component={custom}\n fallback={<PlatformControl {...props} />}\n value={props.value}\n onChange={(next) => props.onChange(next === null || next === '' ? (props.column.nullable ? null : '') : String(next))}\n id={props.id ?? inputId}\n describedBy={props.describedBy}\n invalid={props.invalid === true}\n disabled={false}\n required={props.column.nullable === false}\n label={props.label}\n field={{ name: props.column.name, resource: props.table.id }}\n context=\"edit\"\n />\n );\n}\n\nfunction PlatformControl({\n table,\n column,\n value,\n onChange,\n label,\n id,\n row,\n onPickerState,\n describedBy,\n invalid,\n valueLabel,\n}: Parameters<typeof ValueControl>[0]) {\n const dateId = useId();\n const change = (next: string) => onChange(next === '' && column.nullable ? null : next);\n const target =\n column.references && singleReference(table, column) ? (findTable(column.references.table) as TableMeta | undefined) : undefined;\n if (target) {\n return (\n <RecordPicker\n table={target}\n valueColumn={column.references!.column}\n value={value ?? ''}\n onChange={change}\n ariaLabel={label}\n app\n {...(valueLabel && value ? { known: { value, label: valueLabel } } : {})}\n editing={{ onStateChange: (next) => onPickerState?.(next) }}\n />\n );\n }\n const choices = booleanChoices(column, row) as { yes: string; no: string } | null;\n if (column.allowed?.length || choices) {\n const words = choices ? booleanWords(columnDisplay(table.id, column.name) as DisplayRule | null, choices) : {};\n const items = column.allowed?.length\n ? column.allowed.map((v) => ({ value: v, label: vocabularyWord(v) || humanName(v) }))\n : [\n { value: choices!.yes, label: words.yes ?? say('common.yes') },\n { value: choices!.no, label: words.no ?? say('common.no') },\n ];\n if (value !== null && !items.some((item) => item.value === value)) items.unshift({ value, label: value });\n return (\n <Dropdown\n ariaLabel={label}\n id={id}\n value={value ?? ''}\n ariaInvalid={invalid}\n ariaDescribedBy={describedBy}\n items={[...(column.nullable ? [{ value: '', label: say('common.noValue') }] : []), ...items]}\n onChange={change}\n />\n );\n }\n if (columnKind(column.type) === 'date' && !/time/i.test(column.type)) {\n return (\n <DateField\n id={id ?? dateId}\n value={value ?? ''}\n onChange={change}\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n locale={formatLocale()}\n timezone={formatTimezone()}\n />\n );\n }\n /* Money kept as minor units is typed as the figure it is (\"19.99\") and held as what is stored (1999). */\n const rule = columnDisplay(table.id, column.name) as { format?: string; minor?: true; currency?: string; currencyColumn?: string } | null;\n if (rule?.format === 'money' && rule.minor)\n return (\n <MinorMoneyInput value={value ?? ''} currency={rowCurrency(rule, row, rule.currency || defaultCurrency())} onChange={change}>\n {(text, typed) => (\n <input\n id={id}\n type=\"text\"\n inputMode=\"decimal\"\n className=\"cell-edit\"\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n value={text}\n data-null={String(value === null)}\n onChange={(event) => typed(event.target.value)}\n />\n )}\n </MinorMoneyInput>\n );\n return (\n <input\n id={id}\n type=\"text\"\n className=\"cell-edit\"\n aria-label={label}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n value={value ?? ''}\n data-null={String(value === null)}\n onChange={(event) => change(event.target.value)}\n title={column.allowed?.length ? say('one', { allowed: column.allowed.join(', ') }) : undefined}\n />\n );\n}\n\n/** The row's next (or previous) editable cell after this one, opened. */\nfunction openNeighbor(from: HTMLElement | null, backward: boolean): boolean {\n const cell = from?.closest('td');\n const row = cell?.closest('tr');\n if (!cell || !row) return false;\n const cells = [...row.querySelectorAll<HTMLElement>(':scope > td.cell-editable')];\n const next = cells[cells.indexOf(cell) + (backward ? -1 : 1)];\n next?.querySelector<HTMLElement>('[data-cell-edits]')?.click();\n return Boolean(next);\n}\n\ninterface Shown {\n value: unknown;\n label?: unknown;\n}\n\nexport function GridCellEdit({\n table,\n row,\n column,\n recordKey,\n draw,\n byName = false,\n valueLabel,\n}: {\n table: TableMeta;\n row: Record<string, unknown>;\n column: EditColumn;\n recordKey: Record<string, unknown>;\n draw: CellDraw;\n /** The cell draws the reference's record by name (`owner_id.name`), not the key it holds. */\n byName?: boolean;\n /** The stored reference's name as the cell draws it: the picker opens on it, never on the bare key. */\n valueLabel?: string;\n}) {\n const client = useQueryClient();\n const errorId = useId();\n const label = columnLabel(table.id, column.name) ?? humanName(column.name);\n const stored = said(row[column.name]);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState<string | null>(stored);\n const [problem, setProblem] = useState('');\n /* What the reader saved, drawn until the list's own answer carries it. */\n const [shown, setShown] = useState<(Shown & { from: unknown }) | null>(null);\n const surface = useRef<HTMLDivElement>(null);\n const launcher = useRef<HTMLButtonElement>(null);\n const unresolved = useRef(false);\n const pickerOpen = useRef(false);\n /* Where focus goes once the editor closes: back to the cell, unless Tab sent it on. */\n const refocus = useRef(false);\n const alive = useRef(true);\n useEffect(() => {\n alive.current = true;\n return () => {\n alive.current = false;\n };\n }, []);\n // A refetch that carries a new stored value is the answer; the optimistic drawing yields to it.\n useEffect(() => {\n if (shown && shown.from !== row[column.name]) setShown(null);\n }, [row, column.name, shown]);\n\n useLayoutEffect(() => {\n if (!editing) {\n if (refocus.current) {\n refocus.current = false;\n (launcher.current?.closest('td') as HTMLElement | null)?.focus();\n }\n return;\n }\n const node = surface.current;\n node?.querySelector<HTMLElement>('input, .dd-button, button')?.focus();\n }, [editing]);\n\n const open = () => {\n if (\n !canEditRow(table, recordKey) ||\n updateAttempts.get({ connection: state.activeConnection ?? null, table: table.id, key: recordKey })\n )\n return;\n setDraft(said(shown ? shown.value : row[column.name]));\n setProblem('');\n unresolved.current = false;\n setEditing(true);\n };\n const close = (focusCell: boolean) => {\n refocus.current = focusCell;\n setProblem('');\n setEditing(false);\n };\n\n /** Close the editor and send the value; false while the value is not one to send (the editor stays, saying why). */\n const commit = (value: string | null, focusCell: boolean, labelText?: string): boolean => {\n const original = shown ? said(shown.value) : stored;\n if (value === original) {\n close(focusCell);\n return true;\n }\n const values = { [column.name]: value };\n const refused = validateRecordEdits(table, values, unresolved.current ? { [column.name]: { unresolvedReference: true } } : {});\n if (refused[column.name]) {\n setProblem(refused[column.name]);\n return false;\n }\n let key: ReturnType<typeof wireKey>;\n try {\n key = wireKey(recordKey);\n } catch (error) {\n setProblem((error as Error).message);\n return false;\n }\n if (!canEditRow(table, recordKey)) {\n close(focusCell);\n return true;\n }\n // Drawn at once; put back below if the server says no.\n setShown({ value, label: labelText, from: row[column.name] });\n close(focusCell);\n void send(values, original, key);\n return true;\n };\n const send = async (values: Record<string, string | null>, original: string | null, key: ReturnType<typeof wireKey>) => {\n const connection = state.activeConnection ?? null;\n const identity = sessionIdentity();\n const outcome = await updateAttempts.run({ connection, table: table.id, key: recordKey }, values, () =>\n api('/api/update', { ...ownedBy(connection), table: table.id, key, values, expected: { [column.name]: original } }),\n );\n if (identity !== sessionIdentity()) return;\n if (outcome.kind === 'applied') {\n void shell().undo.refresh();\n void client.invalidateQueries({ queryKey: ['run', connection] });\n void client.invalidateQueries({ queryKey: ['count', connection] });\n toast(\n say('saved', { label }),\n 'ok',\n !identity.tenantRequired && outcome.undoId\n ? {\n label: say('common.undo'),\n run: () => {\n if (identity === sessionIdentity() && connection === (state.activeConnection ?? null))\n void shell().undo.last(outcome.undoId);\n },\n }\n : undefined,\n );\n return;\n }\n // A refusal is the stored value's to keep; an unconfirmed write may have landed, so it stays drawn.\n if (outcome.kind !== 'uncertain' && alive.current) setShown(null);\n toast(outcome.message, 'error');\n };\n\n const pickedLabel = () => (column.references ? surface.current?.querySelector<HTMLInputElement>('input')?.value : undefined);\n const onKey = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n // A picker or a list closes its own popup first; the next Escape puts the value back.\n if (pickerOpen.current || (event.target as Element).closest('[aria-expanded=\"true\"]')) return;\n event.preventDefault();\n event.stopPropagation();\n close(true);\n return;\n }\n if (event.key === 'Enter' && event.target instanceof HTMLInputElement && !pickerOpen.current) {\n event.preventDefault();\n event.stopPropagation();\n commit(draft, true, pickedLabel());\n return;\n }\n if (event.key === 'Tab') {\n event.preventDefault();\n event.stopPropagation();\n const cell = surface.current?.closest('td') as HTMLElement | null;\n const backward = event.shiftKey;\n // Moving on is the save; a value that cannot be sent keeps the reader here.\n if (commit(draft, false, pickedLabel())) {\n requestAnimationFrame(() => {\n if (!openNeighbor(cell, backward)) cell?.focus();\n });\n }\n }\n };\n /* Leaving the cell saves it, as a spreadsheet's does. A popup the editor\n opened (a picker's list, a calendar) is still the editor. */\n const onBlur = () => {\n requestAnimationFrame(() => {\n const node = surface.current;\n const active = document.activeElement;\n if (!alive.current || !node || !editing) return;\n if (active && (node.contains(active) || active.closest('[role=\"listbox\"], [role=\"dialog\"], .dd-popup, .date-field-popup'))) return;\n void commit(draft, false, pickedLabel());\n });\n };\n\n if (!editing) {\n const body = !shown\n ? draw()\n : byName\n ? draw({ value: shown.value === null ? null : (shown.label ?? shown.value) })\n : draw({ value: shown.value, label: shown.label });\n /* The cell's value is the button: a click edits it rather than opening\n the row, and the grid's Enter and F2 press it (useGridKeyboard). */\n return (\n <button\n ref={launcher}\n type=\"button\"\n className=\"cell-edit-launch\"\n aria-label={say('edit', { label })}\n data-cell-opens=\"\"\n data-cell-edits=\"\"\n onClick={(event) => {\n event.stopPropagation();\n open();\n }}\n >\n {body}\n </button>\n );\n }\n const change = (next: string | null) => {\n setDraft(next);\n setProblem('');\n /* Choosing from a list or a picker is the whole edit: nothing left to\n type. A picker reports a choice as its value; a cleared one waits for\n Enter, since clearing may be the start of a new search. */\n if (column.references && next !== null && next !== '') unresolved.current = false;\n if (column.references ? next !== null && next !== '' : Boolean(column.allowed?.length || booleanChoices(column, row))) {\n requestAnimationFrame(() => {\n void commit(next, true, pickedLabel());\n });\n }\n };\n return (\n <div\n ref={surface}\n className=\"cell-edit-surface\"\n data-edit-field=\"\"\n onKeyDownCapture={onKey}\n onBlur={onBlur}\n onClick={(event) => event.stopPropagation()}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <ValueControl\n table={table}\n column={column}\n value={draft}\n onChange={change}\n label={label}\n row={row}\n valueLabel={shown ? (typeof shown.label === 'string' ? shown.label : undefined) : valueLabel}\n describedBy={problem ? errorId : undefined}\n invalid={Boolean(problem)}\n onPickerState={(next) => {\n unresolved.current = next.unresolvedReference;\n pickerOpen.current = next.open;\n }}\n />\n {problem && (\n <span id={errorId} className=\"edit-field-error\" role=\"alert\">\n {problem}\n </span>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -2,10 +2,10 @@ import { nt as Button, rt as buttonClass } from "./shared-poc11xxo.js";
|
|
|
2
2
|
import { gt as defineMessages } from "./shared-DJZjSi3J.js";
|
|
3
3
|
import { t as Field } from "./shared-CERG8O1B.js";
|
|
4
4
|
import { t as MultiStepForm } from "./shared-CntJ4m1g.js";
|
|
5
|
-
import { a as commandInput, i as blankCommandValues, s as commandProblems, t as CommandFields } from "./shared-
|
|
5
|
+
import { a as commandInput, i as blankCommandValues, s as commandProblems, t as CommandFields } from "./shared-JvcI-LWp.js";
|
|
6
6
|
import { i as sayInput } from "./shared-CxovRZz5.js";
|
|
7
7
|
import { c as intakeAddress, f as saveStep, m as sendEmailProof, n as answerClaim, o as confirmEmailProof, p as savedSteps } from "./shared-CKKduWQD.js";
|
|
8
|
-
import { a as formRefusal, d as armLeaveGuard, l as ReviewValue, n as PublicGuard, o as shownOnReview, r as drawsField, s as submitPublicForm, u as IntakeNote } from "./shared-
|
|
8
|
+
import { a as formRefusal, d as armLeaveGuard, l as ReviewValue, n as PublicGuard, o as shownOnReview, r as drawsField, s as submitPublicForm, u as IntakeNote } from "./shared-B4jgU8h9.js";
|
|
9
9
|
import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
10
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
// packages/mistri/src/client/copy/forms/components/SavedFormSurface.ts
|
|
@@ -519,4 +519,4 @@ function SavedFormSurface({ form, appName, base }) {
|
|
|
519
519
|
}
|
|
520
520
|
export { SavedFormSurface, sayInput };
|
|
521
521
|
|
|
522
|
-
//# sourceMappingURL=shared-
|
|
522
|
+
//# sourceMappingURL=shared-5RQMi4BR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-Ctaj8mR2.js","names":["_Fragment"],"sources":["../../src/client/copy/forms/components/SavedFormSurface.ts","../../src/client/components/SavedFormSurface.tsx"],"sourcesContent":["/** What SavedFormSurface says, in the forms room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n review: 'Review',\n reviewTitle: 'Review your answers',\n reviewLead: 'Check each section. Change anything that is not right.',\n keepThisReference: 'Keep this reference.',\n received: 'Received',\n yourReference: 'Your reference',\n submit: 'Submit',\n change: 'Change {label}',\n changeStep: 'Change',\n savedNotShownForYourPrivacy: 'Saved — not shown for your privacy',\n thisApplicationCanNoLonger: 'This application can no longer be continued, so it has been started again from the first step.',\n confirmYourEmail: 'Confirm your email',\n isConfirmedAnAccount: '{email} is confirmed. An account with this email will find your application.',\n optionalWeEmailACode:\n 'Optional. We email a code to your address; confirming it lets an account with this email find the application straight away.',\n codeFromTheEmail: 'Code from the email',\n confirm: 'Confirm',\n sendAnotherCode: 'Send another code',\n emailMeACode: 'Email me a code',\n saveThisStepBefore: 'Save this step before you submit.',\n followItInAnAccount: 'Follow it in an account',\n thisBrowserCanNoLonger: 'This browser can no longer add the application to an account.',\n claimWindow: 'For the next 30 minutes, this browser can add the application to an account, where its status is shown.',\n createAnAccountToTrack: 'Create an account to track this',\n signInToAdd: 'Sign in to add it',\n thisIsAShared: 'This is a shared device',\n checkItsStatus: 'Check its status',\n anyTimeWithYourReference: 'any time with your reference.',\n notSavedYet: 'Not saved yet',\n yourApplicationIsSaved: 'Your application is saved. Carry on where you left off; what you saved is not shown again.',\n eachStepIsSaved:\n 'Each step is saved as you go. We don’t show your details back to you; keep this tab open to review them before you submit.',\n checkingForAnApplication: 'Checking for an application in progress…',\n});\n","/**\n * A public form saved on every step, drawn. Each Next saves the step into the\n * App's own tables (savedFormApi.ts); the last step is the review, and the\n * submit finishes the application.\n *\n * The server never answers back what was typed — not the earlier steps, not\n * with the cookie — so the review is drawn from this page's memory alone:\n * each step's answers as they were sent, held in React state and nowhere\n * else. No storage API, no address, no cache ever holds them. After a reload\n * the server still has the saved steps and the page no longer has their\n * values: the review says so (\"Saved — not shown for your privacy\"), offers\n * Change to enter them again, and still lets the applicant submit.\n *\n * While anything is held or saved and not yet submitted, leaving is guarded:\n * the platform's own exit guard in the App, the browser's prompt outside it.\n */\nimport { useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { AppCommandField } from '../../shared/command.js';\nimport type { FormStep } from '../../shared/formRules.js';\nimport { CommandFields, blankCommandValues, commandInput, commandProblems, type CommandValues } from './CommandFields.js';\nimport { MultiStepForm } from '@mistriwork/kit/client/components/MultiStepForm.js';\nimport { Button, buttonClass } from '@mistriwork/ui/Button.js';\nimport {\n drawsField,\n formRefusal,\n PublicGuard,\n shownOnReview,\n submitPublicForm,\n type FormPresentation,\n type FormReceipt,\n} from './FormSurface.js';\nimport type { GuardHandle } from './PublicGuard.js';\nimport {\n answerClaim,\n confirmEmailProof,\n intakeAddress,\n saveStep,\n savedSteps,\n sendEmailProof,\n type SavedFormFailure,\n} from './savedFormApi.js';\nimport { armLeaveGuard } from './formLeaveGuard.js';\nimport { Field } from '@mistriwork/ui/Field.js';\nimport { IntakeNote } from './IntakeNote.js';\nimport { say } from '../copy/forms/components/SavedFormSurface.js';\n\nexport { sayInput } from './reviewValues.js';\nimport './FormSurface.css';\nimport { ReviewValue } from './ReviewValue.js';\n\n/** A saved form's presentation: its steps, which inputs the submit itself asks on the review, and what follows it. */\nexport type SavedFormPresentation = FormPresentation & {\n steps: FormStep[];\n save: { submit: string[]; statusCheck?: unknown; link?: { sameDevice?: true; statusCheck?: true; email?: { prove?: string } } };\n};\n\nconst REVIEW = '#review';\nconst PRIVATE = say('savedNotShownForYourPrivacy');\nconst GONE = say('thisApplicationCanNoLonger');\n\n/** Whether the step's answers are all still blank: a saved step left as it is keeps what the server has. */\nfunction untouched(fields: readonly AppCommandField[], values: CommandValues): boolean {\n return fields.every((field) => {\n const value = values[field.name];\n if (field.type === 'group')\n return Array.isArray(value) ? value.length === 0 : !value || untouched(field.fields, value as CommandValues);\n return value === undefined || value === '' || value === false;\n });\n}\n\n/**\n * On the review, optional: prove the address typed is the applicant's with a\n * code sent to it. An account with that email then finds the application and\n * adds it without asking (formLink.ts); unproved, it asks first.\n */\nfunction EmailProof({ form, typed }: { form: string; typed: string }) {\n const id = useId();\n const [email, setEmail] = useState(typed);\n const [sent, setSent] = useState(false);\n const [code, setCode] = useState('');\n const [done, setDone] = useState(false);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState(false);\n const run = async (work: () => Promise<void>) => {\n setPending(true);\n setFailure('');\n try {\n await work();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n return (\n <section className=\"form-proof\" aria-labelledby={`${id}-proof`}>\n <h3 id={`${id}-proof`}>{say('confirmYourEmail')}</h3>\n {done ? (\n <p role=\"status\">{say('isConfirmedAnAccount', { email: email.trim() })}</p>\n ) : (\n <>\n <p>{say('optionalWeEmailACode')}</p>\n <Field label={say('common.email')}>\n <input\n className=\"field-control\"\n type=\"email\"\n autoComplete=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.currentTarget.value);\n setSent(false);\n }}\n />\n </Field>\n {sent && (\n <Field label={say('codeFromTheEmail')}>\n <input\n className=\"field-control\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n maxLength={6}\n value={code}\n onChange={(event) => setCode(event.currentTarget.value)}\n />\n </Field>\n )}\n <div className=\"form-claim-actions\">\n {sent && (\n <Button\n intent=\"secondary\"\n size=\"compact\"\n busy={pending}\n onClick={() =>\n void run(async () => {\n await confirmEmailProof(form, email.trim(), code.trim());\n setDone(true);\n })\n }\n >\n {say('confirm')}\n </Button>\n )}\n <Button\n intent={sent ? 'quiet' : 'secondary'}\n size=\"compact\"\n busy={pending && !sent}\n onClick={() =>\n void run(async () => {\n await sendEmailProof(form, email.trim());\n setSent(true);\n setCode('');\n })\n }\n >\n {sent ? say('sendAnotherCode') : say('emailMeACode')}\n </Button>\n </div>\n </>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </section>\n );\n}\n\nexport function SavedFormSurface({\n form,\n appName,\n base,\n}: {\n form: SavedFormPresentation;\n appName: string;\n /** The form's own address (`/{app}/form/{key}`): its status check and account pages are under it. */\n base?: string;\n}) {\n const id = useId();\n const byName = useMemo(() => new Map(form.input.map((field) => [field.name, field])), [form.input]);\n const fieldsOf = (names: readonly string[]) => names.flatMap((name) => byName.get(name) ?? []);\n const submitFields = fieldsOf(form.save.submit);\n const steps = useMemo(\n () => [\n ...form.steps,\n form.style === 'intake'\n ? { id: REVIEW, label: say('review'), fields: form.save.submit, title: say('reviewTitle'), lead: say('reviewLead') }\n : { id: REVIEW, label: say('review'), fields: form.save.submit },\n ],\n [form.steps, form.save.submit, form.style],\n );\n const intake = form.style === 'intake';\n const [values, setValues] = useState<CommandValues>(() => blankCommandValues(form.input));\n /** Each step's answers as they were saved, by step: memory only. */\n const [held, setHeld] = useState<Record<string, Record<string, unknown>>>({});\n /** The steps the server has, by id; null until the resume has answered. */\n const [saved, setSaved] = useState<string[] | null>(null);\n const [current, setCurrent] = useState(0);\n /** A step opened by Change on the review: its Next goes back to the review. */\n const [changing, setChanging] = useState(false);\n const [problems, setProblems] = useState<Record<string, string>>({});\n const [failure, setFailure] = useState('');\n const [receipt, setReceipt] = useState<FormReceipt | null>(null);\n /** Counts refusals at the submit, which the stepper does not see: each sends the focus to what needs fixing. */\n const [refusedAt, setRefusedAt] = useState(0);\n const page = useRef<HTMLElement>(null);\n useEffect(() => {\n if (!refusedAt) return;\n (\n page.current?.querySelector<HTMLElement>('[aria-invalid=\"true\"]') ??\n page.current?.querySelector<HTMLElement>('.form-page-failure:not([hidden])')\n )?.focus();\n }, [refusedAt]);\n /** The done screen's \"This is a shared device\": the claim is burned, and said so. */\n const [shared, setShared] = useState<'no' | 'burning' | 'burned'>('no');\n /* One key per attempt at a step: a retry after a lost answer carries the\n same one, and the server replays rather than saving twice. */\n const keys = useRef(new Map<string, string>());\n /* The App's human check (PublicGuard.tsx): a fresh token for every step and the submit, each asked after an answer. */\n const guarded = useRef<GuardHandle | undefined>(undefined);\n const token = async () => (await guarded.current?.take())?.challenge;\n const keyFor = (step: string) => {\n let key = keys.current.get(step);\n if (!key) keys.current.set(step, (key = crypto.randomUUID()));\n return key;\n };\n\n useEffect(() => {\n let live = true;\n savedSteps(form.id).then(\n (list) => {\n if (!live) return;\n setSaved(list);\n // Resumed: on at the first step not saved, or the review when all are.\n if (list.length)\n setCurrent(\n Math.max(\n 0,\n steps.findIndex((step) => step.id === REVIEW || !list.includes(step.id)),\n ),\n );\n },\n () => {\n if (live) setSaved([]);\n },\n );\n return () => {\n live = false;\n };\n }, [form.id, steps]);\n\n const forget = () => {\n setHeld({});\n setValues(blankCommandValues(form.input));\n };\n const armed = !receipt && (Object.keys(held).length > 0 || (saved?.length ?? 0) > 0);\n // pagehide drops the answers the page holds: a page kept in the back-forward cache keeps none.\n useEffect(() => (armed ? armLeaveGuard(forget) : undefined), [armed]);\n\n const check = (fields: readonly AppCommandField[]): boolean => {\n const names = new Set(fields.map((field) => field.name));\n const found = commandProblems(fields, Object.fromEntries(Object.entries(values).filter(([name]) => names.has(name))));\n setProblems((before) => ({\n ...Object.fromEntries(Object.entries(before).filter(([path]) => !names.has(path.split(/[.[]/)[0]))),\n ...found,\n }));\n return Object.keys(found).length === 0;\n };\n const change = (next: CommandValues, path: string) => {\n setValues(next);\n setProblems((before) =>\n Object.fromEntries(\n Object.entries(before).filter(\n ([problem]) => problem !== path && !problem.startsWith(`${path}.`) && !problem.startsWith(`${path}[`),\n ),\n ),\n );\n };\n const refused = (error: unknown, fields: readonly AppCommandField[]) => {\n const failed = error as SavedFormFailure;\n if (failed.gone) {\n // Forged, expired or finished: the server has nothing for this browser any more.\n keys.current.clear();\n forget();\n setSaved([]);\n setCurrent(0);\n setFailure(GONE);\n return;\n }\n /* One place for each problem: a refusal about a field on this step is\n said beside it, and only there; anything else is the form's line. */\n const refusal = formRefusal(failed, form.input, values);\n if (refusal.field) setProblems((before) => ({ ...before, [refusal.field!]: refusal.beside }));\n if (!drawsField(fields, refusal.field)) setFailure(refusal.alone);\n setRefusedAt((before) => before + 1);\n };\n\n /** Next on a step: check it here, save it there, and hold what was sent for the review. */\n const leave = async (step: FormStep): Promise<boolean> => {\n if (step.id === REVIEW) return true;\n setFailure('');\n const fields = fieldsOf(step.fields);\n // A saved step whose answers this page no longer has, left blank: the server keeps what it has.\n if (saved?.includes(step.id) && !held[step.id] && untouched(fields, values)) return true;\n if (!check(fields)) return false;\n let input: Record<string, unknown>;\n try {\n input = commandInput(fields, values);\n } catch (error) {\n setFailure((error as Error).message);\n return false;\n }\n try {\n await saveStep(form.id, step.id, keyFor(step.id), input, await token());\n } catch (error) {\n refused(error, fields);\n return false;\n } finally {\n guarded.current?.reset();\n }\n keys.current.delete(step.id);\n setHeld((before) => ({ ...before, [step.id]: input }));\n setSaved((before) => [...new Set([...(before ?? []), step.id])]);\n return true;\n };\n\n const complete = async () => {\n setFailure('');\n const missing = form.steps.findIndex((step) => !saved?.includes(step.id));\n if (missing >= 0) {\n setCurrent(missing);\n setFailure(say('saveThisStepBefore'));\n return;\n }\n if (!check(submitFields)) {\n setRefusedAt((before) => before + 1);\n return;\n }\n try {\n const input = commandInput(submitFields, values);\n const challenge = await token();\n const answer = await submitPublicForm(form.id, keyFor(REVIEW), input, intakeAddress(), challenge ? { challenge } : {});\n // Received: the page lets go of every answer it held.\n keys.current.clear();\n forget();\n setReceipt(answer);\n } catch (error) {\n refused(error, submitFields);\n } finally {\n guarded.current?.reset();\n }\n };\n\n if (receipt) {\n // The receipt and fixed words: nothing typed is shown back, here either.\n const message = form.done?.description ?? (receipt.reference ? say('keepThisReference') : undefined);\n return (\n <section className=\"form-page form-page-done\" aria-labelledby={`${id}-done`}>\n <p className=\"eyebrow\">{appName}</p>\n <h1 id={`${id}-done`} tabIndex={-1} ref={(node) => node?.focus()}>\n {form.done?.title ?? say('received')}\n </h1>\n {receipt.reference && (\n <>\n <p className=\"form-page-reference-label\">{say('yourReference')}</p>\n <p className=\"form-page-reference\">\n <strong>{receipt.reference}</strong>\n </p>\n </>\n )}\n {message && <p className=\"form-page-done-message\">{message}</p>}\n {base && form.save.link?.sameDevice && (\n <section className=\"form-claim\" aria-labelledby={`${id}-claim`}>\n <h2 id={`${id}-claim`}>{say('followItInAnAccount')}</h2>\n {shared === 'burned' ? (\n <p className=\"form-page-done-message\" role=\"status\">\n {say('thisBrowserCanNoLonger')}\n </p>\n ) : (\n <>\n <p className=\"form-page-done-message\">{say('claimWindow')}</p>\n <div className=\"form-claim-actions\">\n <a className={buttonClass({ intent: 'primary' })} href={`${base}/claim?account=new`}>\n {say('createAnAccountToTrack')}\n </a>\n <a className={buttonClass({ intent: 'secondary' })} href={`${base}/claim`}>\n {say('signInToAdd')}\n </a>\n </div>\n <Button\n intent=\"quiet\"\n size=\"compact\"\n busy={shared === 'burning'}\n onClick={() => {\n setShared('burning');\n // Burned whether or not the answer arrives: the next person here must not inherit it.\n answerClaim(form.id, 'no').finally(() => setShared('burned'));\n }}\n >\n {say('thisIsAShared')}\n </Button>\n </>\n )}\n </section>\n )}\n {base && form.save.statusCheck !== undefined && (\n <p className=\"form-page-done-message\">\n <a href={`${base}/status`}>{say('checkItsStatus')}</a> {say('anyTimeWithYourReference')}\n </p>\n )}\n </section>\n );\n }\n\n const controls = (list: readonly AppCommandField[]) => (\n <CommandFields\n fields={list}\n values={values}\n problems={problems}\n idPrefix={id}\n disabled={false}\n identityEpoch={0}\n isCurrent={() => true}\n onChange={change}\n inputs={form.inputs}\n />\n );\n const review = () => (\n <div className=\"form-review\">\n {form.steps.map((step, index) => {\n const answers = held[step.id];\n return (\n <section key={step.id} aria-labelledby={`${id}-review-${index}`}>\n <div className=\"form-review-head\">\n <h3 id={`${id}-review-${index}`}>{step.label}</h3>\n <Button\n intent=\"quiet\"\n size=\"compact\"\n onClick={() => {\n setFailure('');\n setChanging(true);\n setCurrent(index);\n }}\n aria-label={say('change', { label: step.label })}\n >\n {say('changeStep')}\n </Button>\n </div>\n {answers ? (\n <dl>\n {fieldsOf(step.fields)\n .filter((field) => shownOnReview(field, answers[field.name]))\n .map((field) => (\n <div key={field.name}>\n <dt>{field.label}</dt>\n <dd>\n <ReviewValue field={field} value={answers[field.name]} />\n </dd>\n </div>\n ))}\n </dl>\n ) : (\n <p>{saved?.includes(step.id) ? PRIVATE : say('notSavedYet')}</p>\n )}\n </section>\n );\n })}\n {form.save.link?.email?.prove && (\n <EmailProof\n form={form.id}\n typed={String(\n Object.values(held).find((answers) => typeof answers[form.save.link!.email!.prove!] === 'string')?.[\n form.save.link.email.prove\n ] ?? '',\n )}\n />\n )}\n {submitFields.length > 0 && <fieldset className=\"command-fields\">{controls(submitFields)}</fieldset>}\n </div>\n );\n\n const resumed = (saved?.length ?? 0) > 0 && !Object.keys(held).length;\n return (\n <section\n ref={page}\n className=\"form-page\"\n {...(intake ? { 'data-style': 'intake', 'aria-label': form.label } : { 'aria-labelledby': `${id}-title` })}\n >\n {!intake && <p className=\"eyebrow\">{appName}</p>}\n {!intake && <h1 id={`${id}-title`}>{form.label}</h1>}\n {/* The description is the first step's alone (FormSurface's rule): over the bar it was read again on every step. */}\n <p className=\"form-note\">{resumed ? say('yourApplicationIsSaved') : say('eachStepIsSaved')}</p>\n {saved === null ? (\n <p className=\"form-page-description\" role=\"status\">\n {say('checkingForAnApplication')}\n </p>\n ) : (\n <form noValidate onSubmit={(event) => event.preventDefault()}>\n <PublicGuard handle={guarded} {...(form.challenge ? { widget: form.challenge } : {})} />\n <MultiStepForm\n steps={steps}\n step={current}\n className=\"form-page-steps\"\n onStepChange={(index) => {\n const back = changing && index > current;\n setChanging(false);\n setFailure('');\n setCurrent(back ? steps.length - 1 : index);\n }}\n completeLabel={form.submitLabel ?? say('submit')}\n validateStep={(step) => leave(step)}\n onComplete={complete}\n {...(intake ? { style: 'intake' as const, note: <IntakeNote note={form.note} /> } : {})}\n said={\n <p className=\"form-page-failure\" tabIndex={-1} role=\"alert\" aria-live=\"assertive\" hidden={!failure}>\n {failure}\n </p>\n }\n >\n {(step, index) =>\n step.id === REVIEW ? (\n review()\n ) : (\n <>\n {index === 0 && form.description && <p className=\"form-page-description\">{form.description}</p>}\n <fieldset className=\"command-fields\">{controls(fieldsOf(step.fields))}</fieldset>\n </>\n )\n }\n </MultiStepForm>\n </form>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shared-5RQMi4BR.js","names":["_Fragment"],"sources":["../../src/client/copy/forms/components/SavedFormSurface.ts","../../src/client/components/SavedFormSurface.tsx"],"sourcesContent":["/** What SavedFormSurface says, in the forms room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n review: 'Review',\n reviewTitle: 'Review your answers',\n reviewLead: 'Check each section. Change anything that is not right.',\n keepThisReference: 'Keep this reference.',\n received: 'Received',\n yourReference: 'Your reference',\n submit: 'Submit',\n change: 'Change {label}',\n changeStep: 'Change',\n savedNotShownForYourPrivacy: 'Saved — not shown for your privacy',\n thisApplicationCanNoLonger: 'This application can no longer be continued, so it has been started again from the first step.',\n confirmYourEmail: 'Confirm your email',\n isConfirmedAnAccount: '{email} is confirmed. An account with this email will find your application.',\n optionalWeEmailACode:\n 'Optional. We email a code to your address; confirming it lets an account with this email find the application straight away.',\n codeFromTheEmail: 'Code from the email',\n confirm: 'Confirm',\n sendAnotherCode: 'Send another code',\n emailMeACode: 'Email me a code',\n saveThisStepBefore: 'Save this step before you submit.',\n followItInAnAccount: 'Follow it in an account',\n thisBrowserCanNoLonger: 'This browser can no longer add the application to an account.',\n claimWindow: 'For the next 30 minutes, this browser can add the application to an account, where its status is shown.',\n createAnAccountToTrack: 'Create an account to track this',\n signInToAdd: 'Sign in to add it',\n thisIsAShared: 'This is a shared device',\n checkItsStatus: 'Check its status',\n anyTimeWithYourReference: 'any time with your reference.',\n notSavedYet: 'Not saved yet',\n yourApplicationIsSaved: 'Your application is saved. Carry on where you left off; what you saved is not shown again.',\n eachStepIsSaved:\n 'Each step is saved as you go. We don’t show your details back to you; keep this tab open to review them before you submit.',\n checkingForAnApplication: 'Checking for an application in progress…',\n});\n","/**\n * A public form saved on every step, drawn. Each Next saves the step into the\n * App's own tables (savedFormApi.ts); the last step is the review, and the\n * submit finishes the application.\n *\n * The server never answers back what was typed — not the earlier steps, not\n * with the cookie — so the review is drawn from this page's memory alone:\n * each step's answers as they were sent, held in React state and nowhere\n * else. No storage API, no address, no cache ever holds them. After a reload\n * the server still has the saved steps and the page no longer has their\n * values: the review says so (\"Saved — not shown for your privacy\"), offers\n * Change to enter them again, and still lets the applicant submit.\n *\n * While anything is held or saved and not yet submitted, leaving is guarded:\n * the platform's own exit guard in the App, the browser's prompt outside it.\n */\nimport { useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { AppCommandField } from '../../shared/command.js';\nimport type { FormStep } from '../../shared/formRules.js';\nimport { CommandFields, blankCommandValues, commandInput, commandProblems, type CommandValues } from './CommandFields.js';\nimport { MultiStepForm } from '@mistriwork/kit/client/components/MultiStepForm.js';\nimport { Button, buttonClass } from '@mistriwork/ui/Button.js';\nimport {\n drawsField,\n formRefusal,\n PublicGuard,\n shownOnReview,\n submitPublicForm,\n type FormPresentation,\n type FormReceipt,\n} from './FormSurface.js';\nimport type { GuardHandle } from './PublicGuard.js';\nimport {\n answerClaim,\n confirmEmailProof,\n intakeAddress,\n saveStep,\n savedSteps,\n sendEmailProof,\n type SavedFormFailure,\n} from './savedFormApi.js';\nimport { armLeaveGuard } from './formLeaveGuard.js';\nimport { Field } from '@mistriwork/ui/Field.js';\nimport { IntakeNote } from './IntakeNote.js';\nimport { say } from '../copy/forms/components/SavedFormSurface.js';\n\nexport { sayInput } from './reviewValues.js';\nimport './FormSurface.css';\nimport { ReviewValue } from './ReviewValue.js';\n\n/** A saved form's presentation: its steps, which inputs the submit itself asks on the review, and what follows it. */\nexport type SavedFormPresentation = FormPresentation & {\n steps: FormStep[];\n save: { submit: string[]; statusCheck?: unknown; link?: { sameDevice?: true; statusCheck?: true; email?: { prove?: string } } };\n};\n\nconst REVIEW = '#review';\nconst PRIVATE = say('savedNotShownForYourPrivacy');\nconst GONE = say('thisApplicationCanNoLonger');\n\n/** Whether the step's answers are all still blank: a saved step left as it is keeps what the server has. */\nfunction untouched(fields: readonly AppCommandField[], values: CommandValues): boolean {\n return fields.every((field) => {\n const value = values[field.name];\n if (field.type === 'group')\n return Array.isArray(value) ? value.length === 0 : !value || untouched(field.fields, value as CommandValues);\n return value === undefined || value === '' || value === false;\n });\n}\n\n/**\n * On the review, optional: prove the address typed is the applicant's with a\n * code sent to it. An account with that email then finds the application and\n * adds it without asking (formLink.ts); unproved, it asks first.\n */\nfunction EmailProof({ form, typed }: { form: string; typed: string }) {\n const id = useId();\n const [email, setEmail] = useState(typed);\n const [sent, setSent] = useState(false);\n const [code, setCode] = useState('');\n const [done, setDone] = useState(false);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState(false);\n const run = async (work: () => Promise<void>) => {\n setPending(true);\n setFailure('');\n try {\n await work();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n return (\n <section className=\"form-proof\" aria-labelledby={`${id}-proof`}>\n <h3 id={`${id}-proof`}>{say('confirmYourEmail')}</h3>\n {done ? (\n <p role=\"status\">{say('isConfirmedAnAccount', { email: email.trim() })}</p>\n ) : (\n <>\n <p>{say('optionalWeEmailACode')}</p>\n <Field label={say('common.email')}>\n <input\n className=\"field-control\"\n type=\"email\"\n autoComplete=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.currentTarget.value);\n setSent(false);\n }}\n />\n </Field>\n {sent && (\n <Field label={say('codeFromTheEmail')}>\n <input\n className=\"field-control\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n maxLength={6}\n value={code}\n onChange={(event) => setCode(event.currentTarget.value)}\n />\n </Field>\n )}\n <div className=\"form-claim-actions\">\n {sent && (\n <Button\n intent=\"secondary\"\n size=\"compact\"\n busy={pending}\n onClick={() =>\n void run(async () => {\n await confirmEmailProof(form, email.trim(), code.trim());\n setDone(true);\n })\n }\n >\n {say('confirm')}\n </Button>\n )}\n <Button\n intent={sent ? 'quiet' : 'secondary'}\n size=\"compact\"\n busy={pending && !sent}\n onClick={() =>\n void run(async () => {\n await sendEmailProof(form, email.trim());\n setSent(true);\n setCode('');\n })\n }\n >\n {sent ? say('sendAnotherCode') : say('emailMeACode')}\n </Button>\n </div>\n </>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </section>\n );\n}\n\nexport function SavedFormSurface({\n form,\n appName,\n base,\n}: {\n form: SavedFormPresentation;\n appName: string;\n /** The form's own address (`/{app}/form/{key}`): its status check and account pages are under it. */\n base?: string;\n}) {\n const id = useId();\n const byName = useMemo(() => new Map(form.input.map((field) => [field.name, field])), [form.input]);\n const fieldsOf = (names: readonly string[]) => names.flatMap((name) => byName.get(name) ?? []);\n const submitFields = fieldsOf(form.save.submit);\n const steps = useMemo(\n () => [\n ...form.steps,\n form.style === 'intake'\n ? { id: REVIEW, label: say('review'), fields: form.save.submit, title: say('reviewTitle'), lead: say('reviewLead') }\n : { id: REVIEW, label: say('review'), fields: form.save.submit },\n ],\n [form.steps, form.save.submit, form.style],\n );\n const intake = form.style === 'intake';\n const [values, setValues] = useState<CommandValues>(() => blankCommandValues(form.input));\n /** Each step's answers as they were saved, by step: memory only. */\n const [held, setHeld] = useState<Record<string, Record<string, unknown>>>({});\n /** The steps the server has, by id; null until the resume has answered. */\n const [saved, setSaved] = useState<string[] | null>(null);\n const [current, setCurrent] = useState(0);\n /** A step opened by Change on the review: its Next goes back to the review. */\n const [changing, setChanging] = useState(false);\n const [problems, setProblems] = useState<Record<string, string>>({});\n const [failure, setFailure] = useState('');\n const [receipt, setReceipt] = useState<FormReceipt | null>(null);\n /** Counts refusals at the submit, which the stepper does not see: each sends the focus to what needs fixing. */\n const [refusedAt, setRefusedAt] = useState(0);\n const page = useRef<HTMLElement>(null);\n useEffect(() => {\n if (!refusedAt) return;\n (\n page.current?.querySelector<HTMLElement>('[aria-invalid=\"true\"]') ??\n page.current?.querySelector<HTMLElement>('.form-page-failure:not([hidden])')\n )?.focus();\n }, [refusedAt]);\n /** The done screen's \"This is a shared device\": the claim is burned, and said so. */\n const [shared, setShared] = useState<'no' | 'burning' | 'burned'>('no');\n /* One key per attempt at a step: a retry after a lost answer carries the\n same one, and the server replays rather than saving twice. */\n const keys = useRef(new Map<string, string>());\n /* The App's human check (PublicGuard.tsx): a fresh token for every step and the submit, each asked after an answer. */\n const guarded = useRef<GuardHandle | undefined>(undefined);\n const token = async () => (await guarded.current?.take())?.challenge;\n const keyFor = (step: string) => {\n let key = keys.current.get(step);\n if (!key) keys.current.set(step, (key = crypto.randomUUID()));\n return key;\n };\n\n useEffect(() => {\n let live = true;\n savedSteps(form.id).then(\n (list) => {\n if (!live) return;\n setSaved(list);\n // Resumed: on at the first step not saved, or the review when all are.\n if (list.length)\n setCurrent(\n Math.max(\n 0,\n steps.findIndex((step) => step.id === REVIEW || !list.includes(step.id)),\n ),\n );\n },\n () => {\n if (live) setSaved([]);\n },\n );\n return () => {\n live = false;\n };\n }, [form.id, steps]);\n\n const forget = () => {\n setHeld({});\n setValues(blankCommandValues(form.input));\n };\n const armed = !receipt && (Object.keys(held).length > 0 || (saved?.length ?? 0) > 0);\n // pagehide drops the answers the page holds: a page kept in the back-forward cache keeps none.\n useEffect(() => (armed ? armLeaveGuard(forget) : undefined), [armed]);\n\n const check = (fields: readonly AppCommandField[]): boolean => {\n const names = new Set(fields.map((field) => field.name));\n const found = commandProblems(fields, Object.fromEntries(Object.entries(values).filter(([name]) => names.has(name))));\n setProblems((before) => ({\n ...Object.fromEntries(Object.entries(before).filter(([path]) => !names.has(path.split(/[.[]/)[0]))),\n ...found,\n }));\n return Object.keys(found).length === 0;\n };\n const change = (next: CommandValues, path: string) => {\n setValues(next);\n setProblems((before) =>\n Object.fromEntries(\n Object.entries(before).filter(\n ([problem]) => problem !== path && !problem.startsWith(`${path}.`) && !problem.startsWith(`${path}[`),\n ),\n ),\n );\n };\n const refused = (error: unknown, fields: readonly AppCommandField[]) => {\n const failed = error as SavedFormFailure;\n if (failed.gone) {\n // Forged, expired or finished: the server has nothing for this browser any more.\n keys.current.clear();\n forget();\n setSaved([]);\n setCurrent(0);\n setFailure(GONE);\n return;\n }\n /* One place for each problem: a refusal about a field on this step is\n said beside it, and only there; anything else is the form's line. */\n const refusal = formRefusal(failed, form.input, values);\n if (refusal.field) setProblems((before) => ({ ...before, [refusal.field!]: refusal.beside }));\n if (!drawsField(fields, refusal.field)) setFailure(refusal.alone);\n setRefusedAt((before) => before + 1);\n };\n\n /** Next on a step: check it here, save it there, and hold what was sent for the review. */\n const leave = async (step: FormStep): Promise<boolean> => {\n if (step.id === REVIEW) return true;\n setFailure('');\n const fields = fieldsOf(step.fields);\n // A saved step whose answers this page no longer has, left blank: the server keeps what it has.\n if (saved?.includes(step.id) && !held[step.id] && untouched(fields, values)) return true;\n if (!check(fields)) return false;\n let input: Record<string, unknown>;\n try {\n input = commandInput(fields, values);\n } catch (error) {\n setFailure((error as Error).message);\n return false;\n }\n try {\n await saveStep(form.id, step.id, keyFor(step.id), input, await token());\n } catch (error) {\n refused(error, fields);\n return false;\n } finally {\n guarded.current?.reset();\n }\n keys.current.delete(step.id);\n setHeld((before) => ({ ...before, [step.id]: input }));\n setSaved((before) => [...new Set([...(before ?? []), step.id])]);\n return true;\n };\n\n const complete = async () => {\n setFailure('');\n const missing = form.steps.findIndex((step) => !saved?.includes(step.id));\n if (missing >= 0) {\n setCurrent(missing);\n setFailure(say('saveThisStepBefore'));\n return;\n }\n if (!check(submitFields)) {\n setRefusedAt((before) => before + 1);\n return;\n }\n try {\n const input = commandInput(submitFields, values);\n const challenge = await token();\n const answer = await submitPublicForm(form.id, keyFor(REVIEW), input, intakeAddress(), challenge ? { challenge } : {});\n // Received: the page lets go of every answer it held.\n keys.current.clear();\n forget();\n setReceipt(answer);\n } catch (error) {\n refused(error, submitFields);\n } finally {\n guarded.current?.reset();\n }\n };\n\n if (receipt) {\n // The receipt and fixed words: nothing typed is shown back, here either.\n const message = form.done?.description ?? (receipt.reference ? say('keepThisReference') : undefined);\n return (\n <section className=\"form-page form-page-done\" aria-labelledby={`${id}-done`}>\n <p className=\"eyebrow\">{appName}</p>\n <h1 id={`${id}-done`} tabIndex={-1} ref={(node) => node?.focus()}>\n {form.done?.title ?? say('received')}\n </h1>\n {receipt.reference && (\n <>\n <p className=\"form-page-reference-label\">{say('yourReference')}</p>\n <p className=\"form-page-reference\">\n <strong>{receipt.reference}</strong>\n </p>\n </>\n )}\n {message && <p className=\"form-page-done-message\">{message}</p>}\n {base && form.save.link?.sameDevice && (\n <section className=\"form-claim\" aria-labelledby={`${id}-claim`}>\n <h2 id={`${id}-claim`}>{say('followItInAnAccount')}</h2>\n {shared === 'burned' ? (\n <p className=\"form-page-done-message\" role=\"status\">\n {say('thisBrowserCanNoLonger')}\n </p>\n ) : (\n <>\n <p className=\"form-page-done-message\">{say('claimWindow')}</p>\n <div className=\"form-claim-actions\">\n <a className={buttonClass({ intent: 'primary' })} href={`${base}/claim?account=new`}>\n {say('createAnAccountToTrack')}\n </a>\n <a className={buttonClass({ intent: 'secondary' })} href={`${base}/claim`}>\n {say('signInToAdd')}\n </a>\n </div>\n <Button\n intent=\"quiet\"\n size=\"compact\"\n busy={shared === 'burning'}\n onClick={() => {\n setShared('burning');\n // Burned whether or not the answer arrives: the next person here must not inherit it.\n answerClaim(form.id, 'no').finally(() => setShared('burned'));\n }}\n >\n {say('thisIsAShared')}\n </Button>\n </>\n )}\n </section>\n )}\n {base && form.save.statusCheck !== undefined && (\n <p className=\"form-page-done-message\">\n <a href={`${base}/status`}>{say('checkItsStatus')}</a> {say('anyTimeWithYourReference')}\n </p>\n )}\n </section>\n );\n }\n\n const controls = (list: readonly AppCommandField[]) => (\n <CommandFields\n fields={list}\n values={values}\n problems={problems}\n idPrefix={id}\n disabled={false}\n identityEpoch={0}\n isCurrent={() => true}\n onChange={change}\n inputs={form.inputs}\n />\n );\n const review = () => (\n <div className=\"form-review\">\n {form.steps.map((step, index) => {\n const answers = held[step.id];\n return (\n <section key={step.id} aria-labelledby={`${id}-review-${index}`}>\n <div className=\"form-review-head\">\n <h3 id={`${id}-review-${index}`}>{step.label}</h3>\n <Button\n intent=\"quiet\"\n size=\"compact\"\n onClick={() => {\n setFailure('');\n setChanging(true);\n setCurrent(index);\n }}\n aria-label={say('change', { label: step.label })}\n >\n {say('changeStep')}\n </Button>\n </div>\n {answers ? (\n <dl>\n {fieldsOf(step.fields)\n .filter((field) => shownOnReview(field, answers[field.name]))\n .map((field) => (\n <div key={field.name}>\n <dt>{field.label}</dt>\n <dd>\n <ReviewValue field={field} value={answers[field.name]} />\n </dd>\n </div>\n ))}\n </dl>\n ) : (\n <p>{saved?.includes(step.id) ? PRIVATE : say('notSavedYet')}</p>\n )}\n </section>\n );\n })}\n {form.save.link?.email?.prove && (\n <EmailProof\n form={form.id}\n typed={String(\n Object.values(held).find((answers) => typeof answers[form.save.link!.email!.prove!] === 'string')?.[\n form.save.link.email.prove\n ] ?? '',\n )}\n />\n )}\n {submitFields.length > 0 && <fieldset className=\"command-fields\">{controls(submitFields)}</fieldset>}\n </div>\n );\n\n const resumed = (saved?.length ?? 0) > 0 && !Object.keys(held).length;\n return (\n <section\n ref={page}\n className=\"form-page\"\n {...(intake ? { 'data-style': 'intake', 'aria-label': form.label } : { 'aria-labelledby': `${id}-title` })}\n >\n {!intake && <p className=\"eyebrow\">{appName}</p>}\n {!intake && <h1 id={`${id}-title`}>{form.label}</h1>}\n {/* The description is the first step's alone (FormSurface's rule): over the bar it was read again on every step. */}\n <p className=\"form-note\">{resumed ? say('yourApplicationIsSaved') : say('eachStepIsSaved')}</p>\n {saved === null ? (\n <p className=\"form-page-description\" role=\"status\">\n {say('checkingForAnApplication')}\n </p>\n ) : (\n <form noValidate onSubmit={(event) => event.preventDefault()}>\n <PublicGuard handle={guarded} {...(form.challenge ? { widget: form.challenge } : {})} />\n <MultiStepForm\n steps={steps}\n step={current}\n className=\"form-page-steps\"\n onStepChange={(index) => {\n const back = changing && index > current;\n setChanging(false);\n setFailure('');\n setCurrent(back ? steps.length - 1 : index);\n }}\n completeLabel={form.submitLabel ?? say('submit')}\n validateStep={(step) => leave(step)}\n onComplete={complete}\n {...(intake ? { style: 'intake' as const, note: <IntakeNote note={form.note} /> } : {})}\n said={\n <p className=\"form-page-failure\" tabIndex={-1} role=\"alert\" aria-live=\"assertive\" hidden={!failure}>\n {failure}\n </p>\n }\n >\n {(step, index) =>\n step.id === REVIEW ? (\n review()\n ) : (\n <>\n {index === 0 && form.description && <p className=\"form-page-description\">{form.description}</p>}\n <fieldset className=\"command-fields\">{controls(fieldsOf(step.fields))}</fieldset>\n </>\n )\n }\n </MultiStepForm>\n </form>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Delayed } from "./shared-poc11xxo.js";
|
|
2
2
|
import { It as beginWork, gt as defineMessages } from "./shared-DJZjSi3J.js";
|
|
3
|
-
import { B as toast } from "./shared-
|
|
3
|
+
import { B as toast } from "./shared-BoLbc2WD.js";
|
|
4
4
|
import { createElement, useEffect, useState } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
// packages/kit/src/client/copy/shell/components/onDemand.ts
|
|
@@ -142,4 +142,4 @@ function useArrived(part, wanted = true) {
|
|
|
142
142
|
}
|
|
143
143
|
export { useArrived as n, onDemand as t };
|
|
144
144
|
|
|
145
|
-
//# sourceMappingURL=shared-
|
|
145
|
+
//# sourceMappingURL=shared-B-BUF9fx.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-
|
|
1
|
+
{"version":3,"file":"shared-B-BUF9fx.js","names":[],"sources":["../../../kit/src/client/copy/shell/components/onDemand.ts","../../../kit/src/client/components/onDemand.tsx"],"sourcesContent":["/** What onDemand says, in the shell room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '../../../messages.js';\n\nexport const say = defineMessages({\n couldNotLoad: 'This part of the page could not be loaded. The server may have been updated since the page was opened.',\n});\n","/**\n * The parts of the client that load the first time they are used.\n *\n * The published client is split (vite.config.ts): the Workbench's tools,\n * the builders, boards, charts and the tenancy dialogs are chunks of their\n * own, fetched when someone first opens one, so an App's first page does\n * not wait for them. An import site names its part with `onDemand` and\n * draws it like any component; this module is what shows while the chunk\n * is on its way, and what shows when it cannot come.\n *\n * Waiting is quiet. Nothing for the first moments — a cached chunk arrives\n * within a frame, and a placeholder that flashes reads as a glitch — then\n * one still line of text: no spinner, no pulse (docs/design.md, motion\n * rules 1 and 8). A part that is a dialog or a control waits with nothing at\n * all, since there is no place of its own to say anything in. A host that\n * draws a frame of its own — a modal panel, whose focus trap is the part's —\n * awaits `ready()` first, so the frame never stands empty and open to Tab.\n *\n * A chunk that cannot load is almost always a deploy: the page was opened\n * before it, and the file it names is gone. The only cure is the new page,\n * so that is what is offered — a sentence and a Reload button where the\n * part would have been, or the same offer as a toast for a part with no\n * place of its own. Never a blank room. Only the load is caught: an error\n * inside a part that did load goes wherever it went before it was split.\n *\n * Not React.lazy: a lazy component suspends on its first draw even when its\n * module is already here, and a part that has arrived must draw at once.\n *\n * No stylesheet may be imported here or by anything this imports: Node's\n * suites load client modules that use it.\n */\nimport { createElement, useEffect, useState, type ComponentType } from 'react';\nimport { toast } from '../core.js';\nimport { Delayed } from './Skeleton.js';\nimport { beginWork } from '../pendingWork.js';\nimport { say } from '../copy/shell/components/onDemand.js';\n\nconst reload = () => {\n window.location.reload();\n};\n\nfunction tracked<M>(load: () => Promise<M>): Promise<M> {\n const settled = beginWork();\n return load().finally(settled);\n}\n\nfunction Unavailable() {\n return (\n <p className=\"note\" role=\"alert\">\n {say('couldNotLoad')}{' '}\n <button type=\"button\" className=\"ghost\" onClick={reload}>\n {say('common.reload')}\n </button>\n </p>\n );\n}\n\n/** The same offer as a toast, for a part with no place of its own — or a module loaded by hand. */\nexport function sayUnavailable(): void {\n toast(say('couldNotLoad'), 'error', { label: say('common.reload'), run: reload });\n}\n\nfunction UnavailableQuietly() {\n useEffect(sayUnavailable, []);\n return null;\n}\n\nconst waiting = (\n <Delayed>\n <p className=\"loading\" role=\"status\">\n {say('common.loading')}\n </p>\n </Delayed>\n);\n\n/** The part's own component, plus the way to have it here before it is drawn, and whether it is. */\ntype OnDemand<C> = C & { ready(): Promise<void>; here(): boolean };\n\n/**\n * The named export of a module the bundler may put in a chunk of its own,\n * as a component that loads it on its first draw. The type is the export's\n * own, so the call sites and their props read as they did with a static\n * import. `quiet` is for dialogs and controls: nothing while waiting, and a\n * toast if the load fails.\n */\nexport function onDemand<M, K extends keyof M>(load: () => Promise<M>, name: K, { quiet = false } = {}): OnDemand<M[K]> {\n let part: ComponentType<object> | undefined;\n let arriving: Promise<void> | undefined;\n /* Counted while it travels, so a navigation holds for the part as it does for a request (pendingWork.ts). */\n const ready = () =>\n (arriving ??= tracked(load).then(\n (module) => {\n part = module[name] as ComponentType<object>;\n },\n (error: unknown) => {\n console.error(`The ${String(name)} chunk did not load.`, error);\n part = quiet ? UnavailableQuietly : Unavailable;\n },\n ));\n function OnDemandPart(props: object) {\n const [, arrived] = useState(0);\n useEffect(() => {\n if (part) return;\n let drawn = true;\n void ready().then(() => {\n if (drawn) arrived((n) => n + 1);\n });\n return () => {\n drawn = false;\n };\n }, []);\n if (part) return createElement(part, props);\n return quiet ? null : waiting;\n }\n OnDemandPart.displayName = `OnDemand(${String(name)})`;\n OnDemandPart.ready = ready;\n OnDemandPart.here = () => part !== undefined;\n return OnDemandPart as unknown as OnDemand<M[K]>;\n}\n\n/**\n * Whether a part is here to draw, fetching it if not. For a host that waits\n * in words of its own rather than the part's: a page section keeps its own\n * skeleton until both its read and its drawing have arrived, so the one\n * placeholder stands throughout, and a grid draws its cells as plain values\n * until their editor has come. A part that could not load is \"here\" as the\n * part's Reload offer, which the host draws in its place.\n */\nexport function useArrived(part: { ready(): Promise<void>; here(): boolean }, wanted = true): boolean {\n const [, arrived] = useState(0);\n const here = part.here();\n useEffect(() => {\n if (here || !wanted) return;\n let drawn = true;\n void part.ready().then(() => {\n if (drawn) arrived((n) => n + 1);\n });\n return () => {\n drawn = false;\n };\n }, [part, here, wanted]);\n return here;\n}\n"],"mappings":";;;;;;;AAGA,IAAa,MAAM,eAAe,EAChC,cAAc,yGAChB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACgCD,IAAM,eAAe;CACnB,OAAO,SAAS,OAAO;AACzB;AAEA,SAAS,QAAW,MAAoC;CACtD,MAAM,UAAU,UAAU;CAC1B,OAAO,KAAK,CAAC,CAAC,QAAQ,OAAO;AAC/B;AAEA,SAAS,cAAc;CACrB,OACE,qBAAC,KAAD;EAAG,WAAU;EAAO,MAAK;EAAzB,UAAA;GACG,IAAI,cAAc;GAAG;GACtB,oBAAC,UAAD;IAAQ,MAAK;IAAS,WAAU;IAAQ,SAAS;IAC9C,UAAA,IAAI,eAAe;GACd,CAAA;EACP;;AAEP;;AAGA,SAAgB,iBAAuB;CACrC,MAAM,IAAI,cAAc,GAAG,SAAS;EAAE,OAAO,IAAI,eAAe;EAAG,KAAK;CAAO,CAAC;AAClF;AAEA,SAAS,qBAAqB;CAC5B,UAAU,gBAAgB,CAAC,CAAC;CAC5B,OAAO;AACT;AAEA,IAAM,UACJ,oBAAC,SAAD,EAAA,UACE,oBAAC,KAAD;CAAG,WAAU;CAAU,MAAK;CACzB,UAAA,IAAI,gBAAgB;AACpB,CAAA,EACI,CAAA;;;;;;;;AAaX,SAAgB,SAA+B,MAAwB,MAAS,EAAE,QAAQ,UAAU,CAAC,GAAmB;CACtH,IAAI;CACJ,IAAI;CAEJ,MAAM,cACH,aAAa,QAAQ,IAAI,CAAC,CAAC,MACzB,WAAW;EACV,OAAO,OAAO;CAChB,IACC,UAAmB;EAClB,QAAQ,MAAM,OAAO,OAAO,IAAI,EAAE,uBAAuB,KAAK;EAC9D,OAAO,QAAQ,qBAAqB;CACtC,CACF;CACF,SAAS,aAAa,OAAe;EACnC,MAAM,GAAG,WAAW,SAAS,CAAC;EAC9B,gBAAgB;GACd,IAAI,MAAM;GACV,IAAI,QAAQ;GACZ,MAAW,CAAC,CAAC,WAAW;IACtB,IAAI,OAAO,SAAS,MAAM,IAAI,CAAC;GACjC,CAAC;GACD,aAAa;IACX,QAAQ;GACV;EACF,GAAG,CAAC,CAAC;EACL,IAAI,MAAM,OAAO,cAAc,MAAM,KAAK;EAC1C,OAAO,QAAQ,OAAO;CACxB;CACA,aAAa,cAAc,YAAY,OAAO,IAAI,EAAE;CACpD,aAAa,QAAQ;CACrB,aAAa,aAAa,SAAS,KAAA;CACnC,OAAO;AACT;;;;;;;;;AAUA,SAAgB,WAAW,MAAmD,SAAS,MAAe;CACpG,MAAM,GAAG,WAAW,SAAS,CAAC;CAC9B,MAAM,OAAO,KAAK,KAAK;CACvB,gBAAgB;EACd,IAAI,QAAQ,CAAC,QAAQ;EACrB,IAAI,QAAQ;EACZ,KAAU,MAAM,CAAC,CAAC,WAAW;GAC3B,IAAI,OAAO,SAAS,MAAM,IAAI,CAAC;EACjC,CAAC;EACD,aAAa;GACX,QAAQ;EACV;CACF,GAAG;EAAC;EAAM;EAAM;CAAM,CAAC;CACvB,OAAO;AACT"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { r as sdk_exports } from "./shared-
|
|
1
|
+
import { r as sdk_exports } from "./shared-CdiPYlTh.js";
|
|
2
2
|
import { A as tenantLeaseActive, D as subscribeSessionIdentity, E as sessionIdentity, O as subscribeTenantLease, S as assertSessionCurrent, T as captureTenantLease, x as fetchServer } from "./shared-poc11xxo.js";
|
|
3
3
|
import { Ct as addHostListener, F as primaryKey, Ft as shellRoot, R as tableNamed, a as setPageHost, gt as defineMessages } from "./shared-DJZjSi3J.js";
|
|
4
|
-
import { G as resolvePath, L as state, _ as openRecord, c as columnLabel, dt as subscribeAppPresentation, ft as PAGE_LOAD_PATH, i as api, lt as appPresentation, s as columnDisplay, st as ownedBy, v as pageApi, w as quote } from "./shared-
|
|
4
|
+
import { G as resolvePath, L as state, _ as openRecord, c as columnLabel, dt as subscribeAppPresentation, ft as PAGE_LOAD_PATH, i as api, lt as appPresentation, s as columnDisplay, st as ownedBy, v as pageApi, w as quote } from "./shared-BoLbc2WD.js";
|
|
5
5
|
import { a as served$1, s as shownUnplaced, t as appFile } from "./shared-sZ8B7ZTw.js";
|
|
6
6
|
import { a as EXPERIMENT_VISITOR_PATH, i as EXPERIMENT_FORM_HEADER, n as EXPERIMENT_ADDRESS_HEADER, o as captureAppFlagValues, t as APP_FLAG_VALUES_PATH } from "./shared-C8J7hNvA.js";
|
|
7
7
|
import { t as sayAppMessage } from "./shared-DLAPtdKj.js";
|
|
8
|
-
import { h as page_exports } from "./shared-
|
|
9
|
-
import { A as batchedBreakdown } from "./shared-
|
|
10
|
-
import { g as pageBridge } from "./shared-
|
|
11
|
-
import { t as densityChoice } from "./shared-
|
|
12
|
-
import { n as viewPath } from "./shared-
|
|
8
|
+
import { h as page_exports } from "./shared-hAayNSRA.js";
|
|
9
|
+
import { A as batchedBreakdown } from "./shared-XcSKDp6N.js";
|
|
10
|
+
import { g as pageBridge } from "./shared-Chp88all.js";
|
|
11
|
+
import { t as densityChoice } from "./shared-CPjpSFGh.js";
|
|
12
|
+
import { n as viewPath } from "./shared-CiqNkoE1.js";
|
|
13
13
|
import "./shared-D_CtFPwG.js";
|
|
14
|
-
import "./shared-
|
|
14
|
+
import "./shared-CL3RLKDA.js";
|
|
15
15
|
import * as React$1 from "react";
|
|
16
16
|
import * as JsxRuntime from "react/jsx-runtime";
|
|
17
17
|
import * as ReactDOM$1 from "react-dom";
|
|
@@ -655,4 +655,4 @@ function loadEntry(id, entry) {
|
|
|
655
655
|
}
|
|
656
656
|
export { loadComponent, loadServedComponent, rowsByPath as t };
|
|
657
657
|
|
|
658
|
-
//# sourceMappingURL=shared-
|
|
658
|
+
//# sourceMappingURL=shared-B-MhiPIN.js.map
|