@templatical/editor 0.20.0 → 0.21.1
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 +1 -0
- package/dist/{AiChatSidebar-ChrE6pUq.js → AiChatSidebar-K_AehWc-.js} +9 -9
- package/dist/{AiFeatureMenu-DkQ9HhQ6.js → AiFeatureMenu-CcqQDHzJ.js} +6 -6
- package/dist/{BlockIssueBadge-B4QjePax.js → BlockIssueBadge-Dmj9rVra.js} +4 -4
- package/dist/{CloudEditor-CfX-aMiV.js → CloudEditor-Dnww6og-.js} +263 -315
- package/dist/{CollaboratorBar-DTibhQ1j.js → CollaboratorBar-Bj4NZiie.js} +3 -3
- package/dist/{ColorPicker-4vDYhdGe.js → ColorPicker-s9GHXjZs.js} +4 -4
- package/dist/CommentsSidebar-DvNEdugN.js +435 -0
- package/dist/CountdownBlock-J_Q9JRQM.js +91 -0
- package/dist/{CountdownToolbar-D7yQqnA2.js → CountdownToolbar-DPRcv3Fu.js} +3 -4
- package/dist/{DesignReferenceSidebar-DnO6ZdwS.js → DesignReferenceSidebar-DNmK3dxp.js} +8 -8
- package/dist/{IssuesPanel-X_vkNGrs.js → IssuesPanel-CEnEGFtd.js} +7 -7
- package/dist/{MergeTagSuggestion-DCuaSOPQ.js → MergeTagSuggestion-DMe4rqn0.js} +2 -2
- package/dist/NumberWithSuffix-CCPN_oCh.js +121 -0
- package/dist/{ParagraphEditor-C5ixOIYb.js → ParagraphEditor--_zWfxps.js} +47 -47
- package/dist/{RichTextEditorContent-DwhDnMsG.js → RichTextEditorContent-FbnWsh46.js} +6 -6
- package/dist/SaveBlockDialog-CYIEHABH.js +264 -0
- package/dist/SavedBlockPreviewCanvas-2-mzAnZE.js +109 -0
- package/dist/SavedBlocksBrowserModal-D5V5yF_3.js +323 -0
- package/dist/SavedBlocksPanels-Dff38YXu.js +36 -0
- package/dist/SavedBlocksPickBar-rB6iyji6.js +52 -0
- package/dist/{SnapshotHistory-DaVueFv6.js → SnapshotHistory-FtzDq8f0.js} +8 -8
- package/dist/{TemplateScoringPanel-B0UHoTLx.js → TemplateScoringPanel-ifGGGWs5.js} +14 -14
- package/dist/{TestEmailModal-BkauxF7j.js → TestEmailModal-DL2O1H8M.js} +4 -4
- package/dist/{TitleEditor-n6WDVDjW.js → TitleEditor-CPda5lh-.js} +11 -11
- package/dist/{TplModal-BDDyvT-C.js → TplModal-C7Koj5gM.js} +3 -3
- package/dist/{blockTypeIcons-4D0aFXNg.js → blockTypeIcons-CgwECCut.js} +6 -6
- package/dist/bundle-stats.json +8 -8
- package/dist/{cdn/chunks/ca-DbWoy4rG.js → ca-BBgad6y5.js} +50 -5
- package/dist/cdn/chunks/AiChatSidebar-A1CuWGY0.js +203 -0
- package/dist/cdn/chunks/AiChatSidebar-A1CuWGY0.js.map +1 -0
- package/dist/cdn/chunks/{AiFeatureMenu-CIBHAGSz.js → AiFeatureMenu-Duwg413F.js} +12 -8
- package/dist/cdn/chunks/{AiFeatureMenu-CIBHAGSz.js.map → AiFeatureMenu-Duwg413F.js.map} +1 -1
- package/dist/cdn/chunks/{BlockIssueBadge-CxMiLo3p.js → BlockIssueBadge-Da4yR-mh.js} +7 -5
- package/dist/cdn/chunks/{BlockIssueBadge-CxMiLo3p.js.map → BlockIssueBadge-Da4yR-mh.js.map} +1 -1
- package/dist/cdn/chunks/{CloudEditor-CEa3Xgqh.js → CloudEditor-B3hqbwfP.js} +275 -318
- package/dist/cdn/chunks/CloudEditor-B3hqbwfP.js.map +1 -0
- package/dist/cdn/chunks/{CollaboratorBar-Bk1gD02G.js → CollaboratorBar-BS3rJy6-.js} +7 -6
- package/dist/cdn/chunks/{CollaboratorBar-Bk1gD02G.js.map → CollaboratorBar-BS3rJy6-.js.map} +1 -1
- package/dist/cdn/chunks/{ColorPicker-ll8pynws.js → ColorPicker-DZSzZ5ZP.js} +168 -164
- package/dist/cdn/chunks/{ColorPicker-ll8pynws.js.map → ColorPicker-DZSzZ5ZP.js.map} +1 -1
- package/dist/cdn/chunks/CommentsSidebar-DHdRiGPX.js +412 -0
- package/dist/cdn/chunks/CommentsSidebar-DHdRiGPX.js.map +1 -0
- package/dist/cdn/chunks/CountdownBlock-Bffpoppw.js +93 -0
- package/dist/cdn/chunks/{CountdownBlock-eGUE7hhw.js.map → CountdownBlock-Bffpoppw.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownToolbar-C1bkSjUR.js → CountdownToolbar-DAnmIZjq.js} +4 -5
- package/dist/cdn/chunks/{CountdownToolbar-C1bkSjUR.js.map → CountdownToolbar-DAnmIZjq.js.map} +1 -1
- package/dist/cdn/chunks/DesignReferenceSidebar-Dre99DTH.js +223 -0
- package/dist/cdn/chunks/DesignReferenceSidebar-Dre99DTH.js.map +1 -0
- package/dist/cdn/chunks/{IssuesPanel-Csasylf_.js → IssuesPanel-D80JedOj.js} +11 -10
- package/dist/cdn/chunks/{IssuesPanel-Csasylf_.js.map → IssuesPanel-D80JedOj.js.map} +1 -1
- package/dist/cdn/chunks/LoadingTrack-D-CW2tUa.js +12 -0
- package/dist/cdn/chunks/LoadingTrack-D-CW2tUa.js.map +1 -0
- package/dist/cdn/chunks/{MergeTagSuggestion-BmMmdcRg.js → MergeTagSuggestion-D7TsECll.js} +2 -2
- package/dist/cdn/chunks/{MergeTagSuggestion-BmMmdcRg.js.map → MergeTagSuggestion-D7TsECll.js.map} +1 -1
- package/dist/cdn/chunks/NumberWithSuffix-CjlVNIEe.js +123 -0
- package/dist/cdn/chunks/NumberWithSuffix-CjlVNIEe.js.map +1 -0
- package/dist/cdn/chunks/{ParagraphEditor-v0_XEL-v.js → ParagraphEditor-CtaRa1vr.js} +90 -85
- package/dist/cdn/chunks/{ParagraphEditor-v0_XEL-v.js.map → ParagraphEditor-CtaRa1vr.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-NQExNsaV.js → RichTextEditorContent-BbdgJqWM.js} +9 -6
- package/dist/cdn/chunks/{RichTextEditorContent-NQExNsaV.js.map → RichTextEditorContent-BbdgJqWM.js.map} +1 -1
- package/dist/cdn/chunks/SaveBlockDialog-Bb3fdUEZ.js +263 -0
- package/dist/cdn/chunks/SaveBlockDialog-Bb3fdUEZ.js.map +1 -0
- package/dist/cdn/chunks/SavedBlockPreviewCanvas-DZOMgNsz.js +111 -0
- package/dist/cdn/chunks/SavedBlockPreviewCanvas-DZOMgNsz.js.map +1 -0
- package/dist/cdn/chunks/SavedBlocksBrowserModal-CeUWcPv0.js +322 -0
- package/dist/cdn/chunks/SavedBlocksBrowserModal-CeUWcPv0.js.map +1 -0
- package/dist/cdn/chunks/SavedBlocksPanels-D-pA_wfk.js +38 -0
- package/dist/cdn/chunks/SavedBlocksPanels-D-pA_wfk.js.map +1 -0
- package/dist/cdn/chunks/SavedBlocksPickBar-1rf1KpqS.js +54 -0
- package/dist/cdn/chunks/SavedBlocksPickBar-1rf1KpqS.js.map +1 -0
- package/dist/cdn/chunks/SnapshotHistory-Bf1uovti.js +121 -0
- package/dist/cdn/chunks/SnapshotHistory-Bf1uovti.js.map +1 -0
- package/dist/cdn/chunks/TemplateScoringPanel-CTk8WwxU.js +231 -0
- package/dist/cdn/chunks/TemplateScoringPanel-CTk8WwxU.js.map +1 -0
- package/dist/cdn/chunks/TestEmailModal-BJTDxFHh.js +96 -0
- package/dist/cdn/chunks/TestEmailModal-BJTDxFHh.js.map +1 -0
- package/dist/cdn/chunks/{TitleEditor-CS-_MzYs.js → TitleEditor-BJ7LFykI.js} +18 -15
- package/dist/cdn/chunks/{TitleEditor-CS-_MzYs.js.map → TitleEditor-BJ7LFykI.js.map} +1 -1
- package/dist/cdn/chunks/TplModal-CH9RzKF7.js +50 -0
- package/dist/cdn/chunks/TplModal-CH9RzKF7.js.map +1 -0
- package/dist/cdn/chunks/_plugin-vue_export-helper-B3ysoDQm.js +8 -0
- package/dist/cdn/chunks/blockTypeIcons-etMMQoVv.js +21 -0
- package/dist/cdn/chunks/{blockTypeIcons-B0Hjh42a.js.map → blockTypeIcons-etMMQoVv.js.map} +1 -1
- package/dist/{ca-DbWoy4rG.js → cdn/chunks/ca-BBgad6y5.js} +52 -3
- package/dist/cdn/chunks/ca-BBgad6y5.js.map +1 -0
- package/dist/cdn/chunks/cloud-BJlbXGTJ.js +1787 -0
- package/dist/cdn/chunks/cloud-BJlbXGTJ.js.map +1 -0
- package/dist/{de-CTYXVU9v.js → cdn/chunks/de-Bw6fB5JU.js} +2 -24
- package/dist/cdn/chunks/{de-CTYXVU9v.js.map → de-Bw6fB5JU.js.map} +1 -1
- package/dist/cdn/chunks/{de-CgGOnerg.js → de-D7WbpFBR.js} +50 -3
- package/dist/cdn/chunks/de-D7WbpFBR.js.map +1 -0
- package/dist/cdn/chunks/dist-CiBEt0VR.js +163 -0
- package/dist/cdn/chunks/dist-CiBEt0VR.js.map +1 -0
- package/dist/cdn/chunks/dist-CxTt8FRE.js +403 -0
- package/dist/cdn/chunks/dist-CxTt8FRE.js.map +1 -0
- package/dist/{en-DrUV9xth.js → cdn/chunks/en-BrZ0uGK2.js} +51 -2
- package/dist/cdn/chunks/en-BrZ0uGK2.js.map +1 -0
- package/dist/{en-BtmIaJeb.js → cdn/chunks/en-DAdHJz7h.js} +2 -24
- package/dist/cdn/chunks/{en-BtmIaJeb.js.map → en-DAdHJz7h.js.map} +1 -1
- package/dist/{es-DwbKjU7q.js → cdn/chunks/es-tLSLysPs.js} +51 -2
- package/dist/cdn/chunks/es-tLSLysPs.js.map +1 -0
- package/dist/cdn/chunks/{extensions-Di3hdIRT.js → extensions-ZX2oarW6.js} +28 -26
- package/dist/cdn/chunks/{extensions-Di3hdIRT.js.map → extensions-ZX2oarW6.js.map} +1 -1
- package/dist/cdn/chunks/formatRelativeTime-CtUU-QZ8.js +12 -0
- package/dist/cdn/chunks/formatRelativeTime-CtUU-QZ8.js.map +1 -0
- package/dist/cdn/chunks/htmlparser-CZa2V5cF.js +1008 -0
- package/dist/cdn/chunks/htmlparser-CZa2V5cF.js.map +1 -0
- package/dist/cdn/chunks/icons-CYWw8Xfp.js +1190 -0
- package/dist/cdn/chunks/icons-CYWw8Xfp.js.map +1 -0
- package/dist/cdn/chunks/keys-D7kUmfpE.js +12 -0
- package/dist/cdn/chunks/keys-D7kUmfpE.js.map +1 -0
- package/dist/cdn/chunks/{pt-BR-Bcc5Tjed.js → pt-BR-BWFokdTU.js} +50 -3
- package/dist/cdn/chunks/pt-BR-BWFokdTU.js.map +1 -0
- package/dist/{pt-BR-B2ZvFlRL.js → cdn/chunks/pt-BR-w2sGzHNX.js} +2 -24
- package/dist/cdn/chunks/{pt-BR-B2ZvFlRL.js.map → pt-BR-w2sGzHNX.js.map} +1 -1
- package/dist/cdn/chunks/src-BKI1x1k7.js +546 -0
- package/dist/cdn/chunks/src-BKI1x1k7.js.map +1 -0
- package/dist/cdn/chunks/src-CM0gCvAS.js +1176 -0
- package/dist/cdn/chunks/src-CM0gCvAS.js.map +1 -0
- package/dist/cdn/chunks/{media-library-yYAkAagU.js → src-D6F_3XkE.js} +1754 -1252
- package/dist/cdn/chunks/src-D6F_3XkE.js.map +1 -0
- package/dist/cdn/chunks/{renderer-DpBGiXOg.js → src-DYji-wXB.js} +117 -133
- package/dist/cdn/chunks/src-DYji-wXB.js.map +1 -0
- package/dist/cdn/chunks/{styles-DHSmjlpX.js → styles-DMOEiSX9.js} +1448 -1354
- package/dist/cdn/chunks/styles-DMOEiSX9.js.map +1 -0
- package/dist/cdn/chunks/timeouts-Bmi_yePw.js +6 -0
- package/dist/cdn/chunks/timeouts-Bmi_yePw.js.map +1 -0
- package/dist/cdn/chunks/{tiptap-C2indasq.js → tiptap-BMZ-OENR.js} +2012 -1863
- package/dist/cdn/chunks/tiptap-BMZ-OENR.js.map +1 -0
- package/dist/cdn/chunks/useAliveFlag-aanU8uqB.js +12 -0
- package/dist/cdn/chunks/useAliveFlag-aanU8uqB.js.map +1 -0
- package/dist/cdn/chunks/useCloudI18n-BjNENqkM.js +25 -0
- package/dist/cdn/chunks/useCloudI18n-BjNENqkM.js.map +1 -0
- package/dist/cdn/chunks/useEditorCore-BA6mspzD.js +3019 -0
- package/dist/cdn/chunks/useEditorCore-BA6mspzD.js.map +1 -0
- package/dist/cdn/chunks/useI18n-8Wd7G-cq.js +19 -0
- package/dist/cdn/chunks/useI18n-8Wd7G-cq.js.map +1 -0
- package/dist/cdn/chunks/useMergeTag-C7G31KV-.js +46 -0
- package/dist/cdn/chunks/useMergeTag-C7G31KV-.js.map +1 -0
- package/dist/cdn/chunks/usePopoverPosition-Bx0QewTv.js +61 -0
- package/dist/cdn/chunks/usePopoverPosition-Bx0QewTv.js.map +1 -0
- package/dist/cdn/editor.css +1 -1
- package/dist/cdn/editor.js +132 -120
- package/dist/cdn/editor.js.map +1 -1
- package/dist/{check-Bl4J_tYV.js → check-BpQDKiPz.js} +1 -1
- package/dist/{chevron-down-COEcl2iP.js → chevron-down-j8GrdTyz.js} +1 -1
- package/dist/chevron-up-BACyVhyC.js +7 -0
- package/dist/{circle-alert-CvHi5etc.js → circle-alert-CgtE46ND.js} +1 -1
- package/dist/{clock-CZZw62e8.js → clock-BzKLLW5L.js} +1 -1
- package/dist/{cloud-B-RebwxI.js → cloud-Du7mnkz2.js} +19 -47
- package/dist/{createLucideIcon-_peTZQtY.js → createLucideIcon-JWHwTI6N.js} +2 -2
- package/dist/{cdn/chunks/de-CTYXVU9v.js → de-Bw6fB5JU.js} +0 -26
- package/dist/{de-CgGOnerg.js → de-D7WbpFBR.js} +49 -2
- package/dist/{dist-CgTKuIUN.js → dist-BEpCh2mG.js} +1158 -1125
- package/dist/{dist-Cx7IUM7J.js → dist-BgPYC_8-.js} +14 -6
- package/dist/{dist-BKKo5wPC.js → dist-BkM8A17N.js} +2 -2
- package/dist/{dist-CcX5sLpz.js → dist-BuNDAAVp.js} +361 -256
- package/dist/{dist-COSN3oDJ.js → dist-CBzCU-a-.js} +2 -2
- package/dist/{dist-YSCPD13F.js → dist-CDO52Rxy.js} +2 -2
- package/dist/{dist-Dk5AdwoQ.js → dist-CrjzhIxB.js} +2 -2
- package/dist/{dist-DXAZUjj3.js → dist-CtcgoC_R.js} +2 -2
- package/dist/{dist-D6M5FAY7.js → dist-CuXha2_7.js} +2 -2
- package/dist/dist-CweLDZrs.js +5 -0
- package/dist/dist-DOsdqAEZ.js +5 -0
- package/dist/{dist-8TKf-Jpg.js → dist-DYClLqy8.js} +6 -3
- package/dist/{cdn/chunks/en-DrUV9xth.js → en-BrZ0uGK2.js} +49 -4
- package/dist/{cdn/chunks/en-BtmIaJeb.js → en-DAdHJz7h.js} +0 -26
- package/dist/{cdn/chunks/es-DwbKjU7q.js → es-tLSLysPs.js} +49 -4
- package/dist/{extensions-BCA9pyer.js → extensions-ClY5Sh7S.js} +5 -5
- package/dist/{image-up-D26rNdfX.js → image-up-CQdtq8ge.js} +1 -1
- package/dist/index.d.ts +81 -4
- package/dist/{info-CE3JSTqk.js → info-BUJBXoE6.js} +1 -1
- package/dist/{keys-DFaIbGR8.js → keys-CHPcp-Nz.js} +2 -2
- package/dist/{list-checks-BQsLrtBB.js → list-checks-BGHaCSD5.js} +1 -1
- package/dist/{loader-circle-s9Rh5lLd.js → loader-circle-C-Z6kgI6.js} +1 -1
- package/dist/{message-circle-CI62d690.js → message-circle-CEm5qckV.js} +1 -1
- package/dist/pencil-DdwmkKLb.js +10 -0
- package/dist/{pt-BR-Bcc5Tjed.js → pt-BR-BWFokdTU.js} +49 -2
- package/dist/{cdn/chunks/pt-BR-B2ZvFlRL.js → pt-BR-w2sGzHNX.js} +0 -26
- package/dist/{refresh-cw-DlYfl65Y.js → refresh-cw-maKlg0dl.js} +1 -1
- package/dist/{scan-line-CHadrYVb.js → scan-line-BFgesTOY.js} +1 -1
- package/dist/{send-CbP40otC.js → send-B70aQDrA.js} +1 -1
- package/dist/{shield-check-Bnj9aRoJ.js → shield-check-B7x5OKt5.js} +1 -1
- package/dist/{sparkles-CncWT57a.js → sparkles-DVlm1Ipp.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/{styles-DkF_-uX8.js → styles-PcOPXvLO.js} +1235 -1151
- package/dist/templatical-editor.js +134 -125
- package/dist/{text-align-start-B458vzYw.js → text-align-start-Vay3Kvo2.js} +1 -1
- package/dist/{trash-2-DO0yjSU1.js → trash-2-DE8CmxAG.js} +1 -1
- package/dist/{triangle-alert-C18_ima6.js → triangle-alert-Djg6IG8N.js} +1 -1
- package/dist/{upload-DsCd2zTR.js → upload-BwwE0U6G.js} +1 -1
- package/dist/{useCloudI18n-PCDOC2kz.js → useCloudI18n-BmiygEM4.js} +1 -1
- package/dist/{useEditorCore-kKUemYY6.js → useEditorCore-CT1slufs.js} +997 -817
- package/dist/{useI18n-BNMzZTM5.js → useI18n-D2L9Mkik.js} +1 -1
- package/dist/{useMergeTag-DfEY0eK5.js → useMergeTag-BTdDq5DC.js} +1 -1
- package/dist/{usePopoverPosition-F9STHRIr.js → usePopoverPosition-BO2LNy5n.js} +1 -1
- package/dist/{x-BCFQuE_q.js → x-CkD6A1iB.js} +1 -1
- package/package.json +21 -21
- package/dist/CommentsSidebar-D-o5Stlg.js +0 -442
- package/dist/CountdownBlock-Bn5w7C-p.js +0 -92
- package/dist/ModuleBrowserModal-AJt--JPh.js +0 -202
- package/dist/ModulePreviewCanvas-BKYOcVCh.js +0 -106
- package/dist/NumberWithSuffix-Bf3rNxza.js +0 -89
- package/dist/SaveModuleDialog-B4QX9eiv.js +0 -125
- package/dist/ToggleSwitch-DUNuUPsZ.js +0 -37
- package/dist/cdn/chunks/CloudEditor-CEa3Xgqh.js.map +0 -1
- package/dist/cdn/chunks/CountdownBlock-eGUE7hhw.js +0 -93
- package/dist/cdn/chunks/ModuleBrowserModal-DznWWtBI.js +0 -198
- package/dist/cdn/chunks/ModuleBrowserModal-DznWWtBI.js.map +0 -1
- package/dist/cdn/chunks/ModulePreviewCanvas-D-h7fr87.js +0 -107
- package/dist/cdn/chunks/ModulePreviewCanvas-D-h7fr87.js.map +0 -1
- package/dist/cdn/chunks/NumberWithSuffix-Dt-0odUN.js +0 -91
- package/dist/cdn/chunks/NumberWithSuffix-Dt-0odUN.js.map +0 -1
- package/dist/cdn/chunks/SaveModuleDialog-BpFhTi-k.js +0 -120
- package/dist/cdn/chunks/SaveModuleDialog-BpFhTi-k.js.map +0 -1
- package/dist/cdn/chunks/ToggleSwitch-OrmX_w18.js +0 -39
- package/dist/cdn/chunks/ToggleSwitch-OrmX_w18.js.map +0 -1
- package/dist/cdn/chunks/blockTypeIcons-B0Hjh42a.js +0 -22
- package/dist/cdn/chunks/ca-DbWoy4rG.js.map +0 -1
- package/dist/cdn/chunks/de-CgGOnerg.js.map +0 -1
- package/dist/cdn/chunks/en-DrUV9xth.js.map +0 -1
- package/dist/cdn/chunks/es-DwbKjU7q.js.map +0 -1
- package/dist/cdn/chunks/features-CLIZ7Q-Y.js +0 -7657
- package/dist/cdn/chunks/features-CLIZ7Q-Y.js.map +0 -1
- package/dist/cdn/chunks/icons-GX40Qm2W.js +0 -690
- package/dist/cdn/chunks/icons-GX40Qm2W.js.map +0 -1
- package/dist/cdn/chunks/media-library-yYAkAagU.js.map +0 -1
- package/dist/cdn/chunks/pt-BR-Bcc5Tjed.js.map +0 -1
- package/dist/cdn/chunks/quality-DffYv9j5.js +0 -2180
- package/dist/cdn/chunks/quality-DffYv9j5.js.map +0 -1
- package/dist/cdn/chunks/renderer-DpBGiXOg.js.map +0 -1
- package/dist/cdn/chunks/src-9K6uFiuK.js +0 -509
- package/dist/cdn/chunks/src-9K6uFiuK.js.map +0 -1
- package/dist/cdn/chunks/styles-DHSmjlpX.js.map +0 -1
- package/dist/cdn/chunks/tiptap-C2indasq.js.map +0 -1
- package/dist/dist-BDVm2MrW.js +0 -5
- package/dist/dist-DbekZDmJ.js +0 -5
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { M as e, P as t, V as n, Z as r, ct as i, f as a, g as o, h as s, it as c, l, n as u, ot as d, p as f, u as p, x as m, y as h, z as g } from "./draggable-D840DIZB.js";
|
|
2
|
+
import "./useEditorCore-BA6mspzD.js";
|
|
3
|
+
import { t as _ } from "./dist-CxTt8FRE.js";
|
|
4
|
+
import { t as v } from "./useI18n-8Wd7G-cq.js";
|
|
5
|
+
import { Dt as y, Mt as b, Nt as x, Pt as S, rt as C } from "./icons-CYWw8Xfp.js";
|
|
6
|
+
import { n as w } from "./useCloudI18n-BjNENqkM.js";
|
|
7
|
+
import { t as T } from "./formatRelativeTime-CtUU-QZ8.js";
|
|
8
|
+
//#region src/cloud/components/SnapshotHistory.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
var E = ["disabled", "title"], D = ["title"], O = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg-elevated)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]",
|
|
12
|
+
style: {
|
|
13
|
+
"backdrop-filter": "blur(8px)",
|
|
14
|
+
"-webkit-backdrop-filter": "blur(8px)"
|
|
15
|
+
}
|
|
16
|
+
}, k = { class: "tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]" }, A = {
|
|
17
|
+
key: 0,
|
|
18
|
+
class: "tpl:flex tpl:items-center tpl:justify-center tpl:py-8"
|
|
19
|
+
}, j = {
|
|
20
|
+
key: 1,
|
|
21
|
+
class: "tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]"
|
|
22
|
+
}, M = {
|
|
23
|
+
key: 2,
|
|
24
|
+
class: "tpl:max-h-64 tpl:overflow-y-auto"
|
|
25
|
+
}, N = ["disabled", "onClick"], P = { class: "tpl:flex tpl:flex-col tpl:gap-0.5" }, F = { class: "tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]" }, I = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-[10px] tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]"
|
|
28
|
+
}, L = ["disabled", "title"], R = /* @__PURE__ */ m({
|
|
29
|
+
__name: "SnapshotHistory",
|
|
30
|
+
props: {
|
|
31
|
+
snapshots: {},
|
|
32
|
+
isLoading: { type: Boolean },
|
|
33
|
+
isRestoring: { type: Boolean }
|
|
34
|
+
},
|
|
35
|
+
emits: ["load", "navigate"],
|
|
36
|
+
setup(m, { emit: R }) {
|
|
37
|
+
let z = m, B = R, { format: V } = v(), { t: H } = w(), U = r(!1), W = r(null), G = r(-1);
|
|
38
|
+
g(() => z.snapshots.length, () => {
|
|
39
|
+
G.value = -1;
|
|
40
|
+
});
|
|
41
|
+
let K = a(() => G.value > 0 && z.snapshots.length > 0 && !z.isRestoring), q = a(() => G.value < z.snapshots.length - 1 && z.snapshots.length > 0 && !z.isRestoring);
|
|
42
|
+
function J() {
|
|
43
|
+
K.value && (G.value--, B("navigate", z.snapshots[G.value]));
|
|
44
|
+
}
|
|
45
|
+
function Y() {
|
|
46
|
+
q.value && (G.value++, B("navigate", z.snapshots[G.value]));
|
|
47
|
+
}
|
|
48
|
+
function X() {
|
|
49
|
+
U.value = !U.value, U.value && z.snapshots.length === 0 && B("load");
|
|
50
|
+
}
|
|
51
|
+
function Z(e) {
|
|
52
|
+
let t = z.snapshots.findIndex((t) => t.id === e);
|
|
53
|
+
t !== -1 && (G.value = t, B("navigate", z.snapshots[t])), U.value = !1;
|
|
54
|
+
}
|
|
55
|
+
function Q(e) {
|
|
56
|
+
let t = T(e, H.snapshotHistory, V, 7);
|
|
57
|
+
return t === null ? new Date(e).toLocaleDateString(void 0, {
|
|
58
|
+
month: "short",
|
|
59
|
+
day: "numeric",
|
|
60
|
+
hour: "2-digit",
|
|
61
|
+
minute: "2-digit"
|
|
62
|
+
}) : t;
|
|
63
|
+
}
|
|
64
|
+
return _(W, () => {
|
|
65
|
+
U.value = !1;
|
|
66
|
+
}), (r, a) => (e(), o("div", {
|
|
67
|
+
ref_key: "dropdownRef",
|
|
68
|
+
ref: W,
|
|
69
|
+
class: "tpl:relative tpl:flex tpl:items-center tpl:gap-0.5"
|
|
70
|
+
}, [
|
|
71
|
+
f("button", {
|
|
72
|
+
class: "tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]",
|
|
73
|
+
disabled: !q.value,
|
|
74
|
+
title: c(H).snapshotHistory.olderSnapshot,
|
|
75
|
+
onClick: l(Y, ["stop"])
|
|
76
|
+
}, [h(c(x), {
|
|
77
|
+
size: 14,
|
|
78
|
+
"stroke-width": 2
|
|
79
|
+
})], 8, E),
|
|
80
|
+
f("button", {
|
|
81
|
+
class: "tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]",
|
|
82
|
+
title: c(H).snapshotHistory.tooltip,
|
|
83
|
+
onClick: l(X, ["stop"])
|
|
84
|
+
}, [h(c(y), {
|
|
85
|
+
size: 16,
|
|
86
|
+
"stroke-width": 1.5
|
|
87
|
+
}), h(c(S), {
|
|
88
|
+
class: d(["tpl:transition-transform tpl:duration-150", { "tpl:rotate-180": U.value }]),
|
|
89
|
+
size: 10,
|
|
90
|
+
"stroke-width": 2
|
|
91
|
+
}, null, 8, ["class"])], 8, D),
|
|
92
|
+
h(u, { name: "tpl-dropdown" }, {
|
|
93
|
+
default: n(() => [U.value ? (e(), o("div", O, [f("div", k, i(c(H).snapshotHistory.dropdownTitle), 1), m.isLoading ? (e(), o("div", A, [h(c(C), {
|
|
94
|
+
class: "tpl:animate-spin tpl:text-[var(--tpl-primary)]",
|
|
95
|
+
size: 20,
|
|
96
|
+
"stroke-width": 2
|
|
97
|
+
})])) : m.snapshots.length === 0 ? (e(), o("div", j, i(c(H).snapshotHistory.noSnapshots), 1)) : (e(), o("div", M, [(e(!0), o(p, null, t(m.snapshots, (t) => (e(), o("button", {
|
|
98
|
+
key: t.id,
|
|
99
|
+
class: "tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-b tpl:border-b-[var(--tpl-border-light)] tpl:border-l-2 tpl:border-l-transparent tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:duration-150 last:tpl:border-b-0 hover:tpl:border-l-[var(--tpl-primary)] hover:tpl:bg-[var(--tpl-bg-hover)]",
|
|
100
|
+
style: { "background-color": "transparent" },
|
|
101
|
+
disabled: m.isRestoring,
|
|
102
|
+
onClick: (e) => Z(t.id)
|
|
103
|
+
}, [f("div", P, [f("div", F, [f("span", null, i(Q(t.created_at)), 1), t.is_autosave ? (e(), o("span", I, i(c(H).snapshotHistory.auto), 1)) : s("", !0)])])], 8, N))), 128))]))])) : s("", !0)]),
|
|
104
|
+
_: 1
|
|
105
|
+
}),
|
|
106
|
+
f("button", {
|
|
107
|
+
class: "tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]",
|
|
108
|
+
disabled: !K.value,
|
|
109
|
+
title: c(H).snapshotHistory.newerSnapshot,
|
|
110
|
+
onClick: l(J, ["stop"])
|
|
111
|
+
}, [h(c(b), {
|
|
112
|
+
size: 14,
|
|
113
|
+
"stroke-width": 2
|
|
114
|
+
})], 8, L)
|
|
115
|
+
], 512));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
//#endregion
|
|
119
|
+
export { R as default };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=SnapshotHistory-Bf1uovti.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapshotHistory-Bf1uovti.js","names":[],"sources":["../../../src/cloud/components/SnapshotHistory.vue","../../../src/cloud/components/SnapshotHistory.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { formatRelativeTime } from \"../../utils/formatRelativeTime\";\nimport type { TemplateSnapshot } from \"@templatical/types\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n snapshots: TemplateSnapshot[];\n isLoading: boolean;\n isRestoring: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"load\"): void;\n (e: \"navigate\", snapshot: TemplateSnapshot): void;\n}>();\n\nconst { format } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n// Track current position in snapshot history (0 = most recent)\nconst currentIndex = ref(-1);\n\n// Reset index when snapshots change (e.g., after a save creates a new snapshot)\nwatch(\n () => props.snapshots.length,\n () => {\n currentIndex.value = -1;\n },\n);\n\nconst canGoNewer = computed(() => {\n return (\n currentIndex.value > 0 && props.snapshots.length > 0 && !props.isRestoring\n );\n});\n\nconst canGoOlder = computed(() => {\n return (\n currentIndex.value < props.snapshots.length - 1 &&\n props.snapshots.length > 0 &&\n !props.isRestoring\n );\n});\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n currentIndex.value--;\n emit(\"navigate\", props.snapshots[currentIndex.value]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n currentIndex.value++;\n emit(\"navigate\", props.snapshots[currentIndex.value]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n if (isOpen.value && props.snapshots.length === 0) {\n emit(\"load\");\n }\n}\n\nfunction handleRestore(snapshotId: string): void {\n const index = props.snapshots.findIndex((s) => s.id === snapshotId);\n if (index !== -1) {\n currentIndex.value = index;\n emit(\"navigate\", props.snapshots[index]);\n }\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(\n dateString,\n cloudT.snapshotHistory,\n format,\n 7,\n );\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n >\n <!-- Go to older snapshot -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n :disabled=\"!canGoOlder\"\n :title=\"cloudT.snapshotHistory.olderSnapshot\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n :title=\"cloudT.snapshotHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform tpl:duration-150\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg-elevated)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n style=\"backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px)\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ cloudT.snapshotHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"snapshots.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.snapshotHistory.noSnapshots }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"snapshot in snapshots\"\n :key=\"snapshot.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-b tpl:border-b-[var(--tpl-border-light)] tpl:border-l-2 tpl:border-l-transparent tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:duration-150 last:tpl:border-b-0 hover:tpl:border-l-[var(--tpl-primary)] hover:tpl:bg-[var(--tpl-bg-hover)]\"\n style=\"background-color: transparent\"\n :disabled=\"isRestoring\"\n @click=\"handleRestore(snapshot.id)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{ formatDate(snapshot.created_at) }}</span>\n <span\n v-if=\"snapshot.is_autosave\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-[10px] tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.snapshotHistory.auto }}\n </span>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Go to newer snapshot -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n :disabled=\"!canGoNewer\"\n :title=\"cloudT.snapshotHistory.newerSnapshot\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { formatRelativeTime } from \"../../utils/formatRelativeTime\";\nimport type { TemplateSnapshot } from \"@templatical/types\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport { computed, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n snapshots: TemplateSnapshot[];\n isLoading: boolean;\n isRestoring: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"load\"): void;\n (e: \"navigate\", snapshot: TemplateSnapshot): void;\n}>();\n\nconst { format } = useI18n();\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n// Track current position in snapshot history (0 = most recent)\nconst currentIndex = ref(-1);\n\n// Reset index when snapshots change (e.g., after a save creates a new snapshot)\nwatch(\n () => props.snapshots.length,\n () => {\n currentIndex.value = -1;\n },\n);\n\nconst canGoNewer = computed(() => {\n return (\n currentIndex.value > 0 && props.snapshots.length > 0 && !props.isRestoring\n );\n});\n\nconst canGoOlder = computed(() => {\n return (\n currentIndex.value < props.snapshots.length - 1 &&\n props.snapshots.length > 0 &&\n !props.isRestoring\n );\n});\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n currentIndex.value--;\n emit(\"navigate\", props.snapshots[currentIndex.value]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n currentIndex.value++;\n emit(\"navigate\", props.snapshots[currentIndex.value]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n if (isOpen.value && props.snapshots.length === 0) {\n emit(\"load\");\n }\n}\n\nfunction handleRestore(snapshotId: string): void {\n const index = props.snapshots.findIndex((s) => s.id === snapshotId);\n if (index !== -1) {\n currentIndex.value = index;\n emit(\"navigate\", props.snapshots[index]);\n }\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(\n dateString,\n cloudT.snapshotHistory,\n format,\n 7,\n );\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n >\n <!-- Go to older snapshot -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n :disabled=\"!canGoOlder\"\n :title=\"cloudT.snapshotHistory.olderSnapshot\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n :title=\"cloudT.snapshotHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform tpl:duration-150\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg-elevated)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n style=\"backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px)\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ cloudT.snapshotHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"snapshots.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.snapshotHistory.noSnapshots }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"snapshot in snapshots\"\n :key=\"snapshot.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-b tpl:border-b-[var(--tpl-border-light)] tpl:border-l-2 tpl:border-l-transparent tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:duration-150 last:tpl:border-b-0 hover:tpl:border-l-[var(--tpl-primary)] hover:tpl:bg-[var(--tpl-bg-hover)]\"\n style=\"background-color: transparent\"\n :disabled=\"isRestoring\"\n @click=\"handleRestore(snapshot.id)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{ formatDate(snapshot.created_at) }}</span>\n <span\n v-if=\"snapshot.is_autosave\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-[10px] tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.snapshotHistory.auto }}\n </span>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Go to newer snapshot -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:duration-150 hover:tpl:bg-[var(--tpl-bg-hover)] disabled:tpl:cursor-not-allowed disabled:tpl:opacity-30 disabled:hover:tpl:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n :disabled=\"!canGoNewer\"\n :title=\"cloudT.snapshotHistory.newerSnapshot\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { L as e, M as t, P as n, T as r, V as ee, Z as i, ct as a, g as o, h as s, it as c, m as l, n as u, ot as te, p as d, st as f, u as p, v as m, x as h, y as g, z as ne } from "./draggable-D840DIZB.js";
|
|
2
|
+
import { B as _, F as v, T as y, h as b } from "./keys-D7kUmfpE.js";
|
|
3
|
+
import { At as x, D as re, O as S, Pt as ie, R as C, St as ae, n as oe, rt as se, t as ce, u as le, ut as ue, w } from "./icons-CYWw8Xfp.js";
|
|
4
|
+
import { t as T } from "./LoadingTrack-D-CW2tUa.js";
|
|
5
|
+
import { t as E } from "./_plugin-vue_export-helper-B3ysoDQm.js";
|
|
6
|
+
import { n as D } from "./useCloudI18n-BjNENqkM.js";
|
|
7
|
+
//#region src/cloud/utils/scoringStyles.ts
|
|
8
|
+
function O(e) {
|
|
9
|
+
return e >= 80 ? "var(--tpl-success)" : e >= 60 ? "var(--tpl-warning)" : "var(--tpl-danger)";
|
|
10
|
+
}
|
|
11
|
+
function k(e) {
|
|
12
|
+
return e >= 80 ? "var(--tpl-success-light)" : e >= 60 ? "var(--tpl-warning-light)" : "var(--tpl-danger-light)";
|
|
13
|
+
}
|
|
14
|
+
function A(e) {
|
|
15
|
+
return e === "high" ? "var(--tpl-danger)" : e === "medium" ? "var(--tpl-warning)" : "var(--tpl-text-muted)";
|
|
16
|
+
}
|
|
17
|
+
function j(e) {
|
|
18
|
+
return e === "high" ? "var(--tpl-danger-light)" : e === "medium" ? "var(--tpl-warning-light)" : "var(--tpl-bg-hover)";
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/cloud/components/TemplateScoringPanel.vue?vue&type=script&setup=true&lang.ts
|
|
22
|
+
var M = {
|
|
23
|
+
key: 0,
|
|
24
|
+
class: "tpl-scoring-panel tpl:absolute tpl:top-14 tpl:right-0 tpl:bottom-0 tpl:z-panel tpl:flex tpl:w-[360px] tpl:flex-col tpl:border-l tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg-elevated)]"
|
|
25
|
+
}, N = { class: "tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:border-[var(--tpl-border)] tpl:px-4 tpl:py-3" }, P = { class: "tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-primary)]" }, F = { class: "tpl:flex tpl:items-center tpl:gap-1" }, I = ["title"], L = { class: "tpl:flex-1 tpl:overflow-y-auto tpl:p-4" }, R = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center"
|
|
28
|
+
}, z = { class: "tpl:text-sm tpl:text-[var(--tpl-text-muted)]" }, B = {
|
|
29
|
+
key: 1,
|
|
30
|
+
class: "tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center"
|
|
31
|
+
}, V = { class: "tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]" }, H = {
|
|
32
|
+
key: 2,
|
|
33
|
+
class: "tpl:flex tpl:flex-col tpl:gap-4"
|
|
34
|
+
}, U = { class: "tpl:text-xs tpl:font-medium tpl:uppercase tpl:tracking-wider tpl:text-[var(--tpl-text-muted)]" }, de = {
|
|
35
|
+
key: 0,
|
|
36
|
+
class: "tpl:text-xs tpl:text-[var(--tpl-text-dim)]"
|
|
37
|
+
}, fe = {
|
|
38
|
+
key: 0,
|
|
39
|
+
class: "tpl:flex tpl:items-start tpl:gap-2 tpl:rounded-lg tpl:px-3 tpl:py-2 tpl:text-xs tpl:bg-[var(--tpl-danger-light)] tpl:text-[var(--tpl-danger)]"
|
|
40
|
+
}, pe = ["onClick"], me = { class: "tpl:flex-1 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]" }, he = {
|
|
41
|
+
key: 0,
|
|
42
|
+
class: "tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]"
|
|
43
|
+
}, ge = {
|
|
44
|
+
key: 0,
|
|
45
|
+
class: "tpl:border-t tpl:border-[var(--tpl-border)]"
|
|
46
|
+
}, _e = {
|
|
47
|
+
key: 0,
|
|
48
|
+
class: "tpl:px-3 tpl:py-3 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]"
|
|
49
|
+
}, ve = { class: "tpl:flex tpl:items-start tpl:gap-2" }, ye = { class: "tpl:flex-1 tpl:min-w-0" }, be = { class: "tpl:flex tpl:items-start tpl:gap-1.5" }, xe = { class: "tpl:text-xs tpl:leading-snug tpl:text-[var(--tpl-text)]" }, Se = {
|
|
50
|
+
key: 0,
|
|
51
|
+
class: "tpl:mt-1 tpl:text-[11px] tpl:leading-snug tpl:text-[var(--tpl-text-dim)]"
|
|
52
|
+
}, Ce = {
|
|
53
|
+
key: 1,
|
|
54
|
+
class: "tpl:mt-2 tpl:flex tpl:justify-center"
|
|
55
|
+
}, we = ["disabled", "onClick"], Te = {
|
|
56
|
+
key: 0,
|
|
57
|
+
class: "tpl:mt-1.5 tpl:text-[11px] tpl:text-[var(--tpl-danger)]"
|
|
58
|
+
}, Ee = {
|
|
59
|
+
key: 3,
|
|
60
|
+
class: "tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center"
|
|
61
|
+
}, De = { class: "tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]" }, Oe = { class: "tpl:m-0 tpl:px-4 tpl:pb-2 tpl:pt-2 tpl:text-center tpl:text-[11px] tpl:text-[var(--tpl-text-dim)]" }, W = /*#__PURE__*/ E(/* @__PURE__ */ h({
|
|
62
|
+
__name: "TemplateScoringPanel",
|
|
63
|
+
props: { visible: { type: Boolean } },
|
|
64
|
+
emits: ["close"],
|
|
65
|
+
setup(h, { emit: E }) {
|
|
66
|
+
let W = h, G = E, { t: K } = D(), q = _(b, "TemplateScoringPanel"), J = _(v, "TemplateScoringPanel"), Y = r(y, []), X = i({
|
|
67
|
+
spam: !0,
|
|
68
|
+
readability: !0,
|
|
69
|
+
accessibility: !0,
|
|
70
|
+
bestPractices: !0
|
|
71
|
+
});
|
|
72
|
+
function ke(e) {
|
|
73
|
+
X.value[e] = !X.value[e];
|
|
74
|
+
}
|
|
75
|
+
let Z = [
|
|
76
|
+
"spam",
|
|
77
|
+
"readability",
|
|
78
|
+
"accessibility",
|
|
79
|
+
"bestPractices"
|
|
80
|
+
], Ae = {
|
|
81
|
+
spam: re,
|
|
82
|
+
readability: ae,
|
|
83
|
+
accessibility: w,
|
|
84
|
+
bestPractices: ce
|
|
85
|
+
};
|
|
86
|
+
function Q() {
|
|
87
|
+
J.score(q.content.value, Y);
|
|
88
|
+
}
|
|
89
|
+
ne(() => W.visible, (e) => {
|
|
90
|
+
e && !J.scoringResult.value && !J.isScoring.value && Q();
|
|
91
|
+
});
|
|
92
|
+
async function je(e) {
|
|
93
|
+
if (!e.blockId) return;
|
|
94
|
+
let t = q.content.value.blocks.find((t) => t.id === e.blockId);
|
|
95
|
+
if (!t) return;
|
|
96
|
+
let n = t.content;
|
|
97
|
+
if (!n) return;
|
|
98
|
+
let r = await J.fixFinding(n, e, Y);
|
|
99
|
+
r && (q.updateBlock(e.blockId, { content: r }), J.removeFinding(e.category, e.id));
|
|
100
|
+
}
|
|
101
|
+
function $() {
|
|
102
|
+
return J.scoringResult.value ? Z.reduce((e, t) => e + (J.scoringResult.value?.categories[t]?.findings.length ?? 0), 0) : 0;
|
|
103
|
+
}
|
|
104
|
+
return (r, i) => (t(), l(u, {
|
|
105
|
+
"enter-active-class": "tpl-scoring-slide-enter-active",
|
|
106
|
+
"enter-from-class": "tpl:translate-x-full",
|
|
107
|
+
"enter-to-class": "tpl:translate-x-0",
|
|
108
|
+
"leave-active-class": "tpl-scoring-slide-leave-active",
|
|
109
|
+
"leave-from-class": "tpl:translate-x-0",
|
|
110
|
+
"leave-to-class": "tpl:translate-x-full"
|
|
111
|
+
}, {
|
|
112
|
+
default: ee(() => [h.visible ? (t(), o("div", M, [d("div", N, [d("div", P, [g(c(S), {
|
|
113
|
+
size: 13,
|
|
114
|
+
"stroke-width": 2
|
|
115
|
+
}), d("span", null, a(c(K).scoring.title), 1)]), d("div", F, [c(J).scoringResult.value && !c(J).isScoring.value ? (t(), o("button", {
|
|
116
|
+
key: 0,
|
|
117
|
+
class: "tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]",
|
|
118
|
+
title: c(K).scoring.rescore,
|
|
119
|
+
onClick: i[0] ||= (e) => Q()
|
|
120
|
+
}, [g(c(C), {
|
|
121
|
+
size: 14,
|
|
122
|
+
"stroke-width": 2
|
|
123
|
+
})], 8, I)) : s("", !0), d("button", {
|
|
124
|
+
class: "tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]",
|
|
125
|
+
onClick: i[1] ||= (e) => G("close")
|
|
126
|
+
}, [g(c(oe), {
|
|
127
|
+
size: 14,
|
|
128
|
+
"stroke-width": 2
|
|
129
|
+
})])])]), d("div", L, [c(J).isScoring.value ? (t(), o("div", R, [d("p", z, a(c(K).scoring.scoring), 1), g(T, { class: "tpl:w-3/4" })])) : c(J).error.value && !c(J).scoringResult.value ? (t(), o("div", B, [
|
|
130
|
+
g(c(x), {
|
|
131
|
+
size: 32,
|
|
132
|
+
"stroke-width": 1.5,
|
|
133
|
+
class: "tpl:text-[var(--tpl-danger)]"
|
|
134
|
+
}),
|
|
135
|
+
d("p", V, a(c(K).scoring.error), 1),
|
|
136
|
+
d("button", {
|
|
137
|
+
class: "tpl:mt-2 tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text-muted)]",
|
|
138
|
+
onClick: i[2] ||= (e) => Q()
|
|
139
|
+
}, [g(c(C), {
|
|
140
|
+
size: 12,
|
|
141
|
+
"stroke-width": 2
|
|
142
|
+
}), m(" " + a(c(K).scoring.rescore), 1)])
|
|
143
|
+
])) : c(J).scoringResult.value ? (t(), o("div", H, [
|
|
144
|
+
d("div", {
|
|
145
|
+
class: "tpl:flex tpl:flex-col tpl:items-center tpl:gap-2 tpl:rounded-[var(--tpl-radius)] tpl:p-5",
|
|
146
|
+
style: f({ backgroundColor: c(k)(c(J).scoringResult.value.score) })
|
|
147
|
+
}, [
|
|
148
|
+
d("span", {
|
|
149
|
+
class: "tpl:text-4xl tpl:font-bold tpl:tabular-nums",
|
|
150
|
+
style: f({ color: c(O)(c(J).scoringResult.value.score) })
|
|
151
|
+
}, a(c(J).scoringResult.value.score), 5),
|
|
152
|
+
d("span", U, a(c(K).scoring.overallScore), 1),
|
|
153
|
+
$() > 0 ? (t(), o("span", de, a($()) + " " + a(c(K).scoring.findings), 1)) : s("", !0)
|
|
154
|
+
], 4),
|
|
155
|
+
c(J).fixError.value ? (t(), o("div", fe, [g(c(x), {
|
|
156
|
+
size: 14,
|
|
157
|
+
"stroke-width": 2,
|
|
158
|
+
class: "tpl:mt-0.5 tpl:shrink-0"
|
|
159
|
+
}), d("span", null, a(c(K).scoring.fixError), 1)])) : s("", !0),
|
|
160
|
+
(t(), o(p, null, n(Z, (r) => d("div", {
|
|
161
|
+
key: r,
|
|
162
|
+
class: "tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:border tpl:border-[var(--tpl-border)]"
|
|
163
|
+
}, [d("button", {
|
|
164
|
+
class: "tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:gap-2.5 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-colors tpl:duration-100 tpl:bg-[var(--tpl-bg)]",
|
|
165
|
+
onClick: (e) => ke(r)
|
|
166
|
+
}, [
|
|
167
|
+
(t(), l(e(Ae[r]), {
|
|
168
|
+
size: 14,
|
|
169
|
+
"stroke-width": 2,
|
|
170
|
+
style: f({ color: c(O)(c(J).scoringResult.value.categories[r].score) })
|
|
171
|
+
}, null, 8, ["style"])),
|
|
172
|
+
d("span", me, a(c(K).scoring.categories[r]), 1),
|
|
173
|
+
d("span", {
|
|
174
|
+
class: "tpl:rounded-full tpl:px-2 tpl:py-0.5 tpl:text-xs tpl:font-semibold tpl:tabular-nums",
|
|
175
|
+
style: f({
|
|
176
|
+
color: c(O)(c(J).scoringResult.value.categories[r].score),
|
|
177
|
+
backgroundColor: c(k)(c(J).scoringResult.value.categories[r].score)
|
|
178
|
+
})
|
|
179
|
+
}, a(c(J).scoringResult.value.categories[r].score), 5),
|
|
180
|
+
c(J).scoringResult.value.categories[r].findings.length > 0 ? (t(), o("span", he, a(c(J).scoringResult.value.categories[r].findings.length), 1)) : s("", !0),
|
|
181
|
+
g(c(ie), {
|
|
182
|
+
size: 12,
|
|
183
|
+
"stroke-width": 2,
|
|
184
|
+
class: te(["tpl:transition-transform tpl:duration-200 tpl:text-[var(--tpl-text-dim)]", X.value[r] ? "tpl:rotate-0" : "tpl:-rotate-90"])
|
|
185
|
+
}, null, 8, ["class"])
|
|
186
|
+
], 8, pe), X.value[r] ? (t(), o("div", ge, [c(J).scoringResult.value.categories[r].findings.length === 0 ? (t(), o("div", _e, a(c(K).scoring.noFindings), 1)) : s("", !0), (t(!0), o(p, null, n(c(J).scoringResult.value.categories[r].findings, (n) => (t(), o("div", {
|
|
187
|
+
key: n.id,
|
|
188
|
+
class: "tpl:border-t tpl:px-3 tpl:py-2.5 first:tpl:border-t-0 tpl:border-[var(--tpl-border-light)]"
|
|
189
|
+
}, [d("div", ve, [(t(), l(e(c(n.severity === "high" ? x : n.severity === "medium" ? le : ue)), {
|
|
190
|
+
size: 13,
|
|
191
|
+
"stroke-width": 2,
|
|
192
|
+
class: "tpl:mt-0.5 tpl:shrink-0",
|
|
193
|
+
style: f({ color: c(A)(n.severity) })
|
|
194
|
+
}, null, 8, ["style"])), d("div", ye, [
|
|
195
|
+
d("div", be, [d("span", {
|
|
196
|
+
class: "tpl:mt-0.5 tpl:shrink-0 tpl:rounded tpl:px-1 tpl:py-px tpl:text-[10px] tpl:font-medium tpl:leading-tight",
|
|
197
|
+
style: f({
|
|
198
|
+
color: c(A)(n.severity),
|
|
199
|
+
backgroundColor: c(j)(n.severity)
|
|
200
|
+
})
|
|
201
|
+
}, a(c(K).scoring.severity[n.severity]), 5), d("span", xe, a(n.message), 1)]),
|
|
202
|
+
n.suggestion ? (t(), o("p", Se, a(n.suggestion), 1)) : s("", !0),
|
|
203
|
+
n.blockId ? (t(), o("div", Ce, [d("button", {
|
|
204
|
+
class: "tpl-scoring-fix-btn tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded tpl:border tpl:px-3 tpl:py-1.5 tpl:text-[11px] tpl:font-medium tpl:transition-all tpl:duration-150 tpl:disabled:opacity-50 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-primary)]",
|
|
205
|
+
style: { "background-color": "transparent" },
|
|
206
|
+
disabled: c(J).fixingFindingId.value !== null,
|
|
207
|
+
onClick: (e) => je(n)
|
|
208
|
+
}, [c(J).fixingFindingId.value === n.id ? (t(), l(c(se), {
|
|
209
|
+
key: 0,
|
|
210
|
+
class: "tpl-spinner",
|
|
211
|
+
size: 11,
|
|
212
|
+
"stroke-width": 2
|
|
213
|
+
})) : (t(), l(c(w), {
|
|
214
|
+
key: 1,
|
|
215
|
+
size: 11,
|
|
216
|
+
"stroke-width": 2
|
|
217
|
+
})), m(" " + a(c(J).fixingFindingId.value === n.id ? c(K).scoring.fixing : c(K).scoring.fix), 1)], 8, we), c(J).fixError.value ? (t(), o("p", Te, a(c(J).fixError.value), 1)) : s("", !0)])) : s("", !0)
|
|
218
|
+
])])]))), 128))])) : s("", !0)])), 64))
|
|
219
|
+
])) : (t(), o("div", Ee, [g(c(S), {
|
|
220
|
+
size: 32,
|
|
221
|
+
"stroke-width": 1.5,
|
|
222
|
+
class: "tpl:text-[var(--tpl-text-dim)]"
|
|
223
|
+
}), d("p", De, a(c(K).scoring.emptyState), 1)])), d("p", Oe, a(c(K).aiMenu.disclaimer), 1)])])) : s("", !0)]),
|
|
224
|
+
_: 1
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
}), [["__scopeId", "data-v-c23c73d4"]]);
|
|
228
|
+
//#endregion
|
|
229
|
+
export { W as default };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=TemplateScoringPanel-CTk8WwxU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TemplateScoringPanel-CTk8WwxU.js","names":[],"sources":["../../../src/cloud/utils/scoringStyles.ts","../../../src/cloud/components/TemplateScoringPanel.vue","../../../src/cloud/components/TemplateScoringPanel.vue"],"sourcesContent":["export type ScoringSeverity = \"high\" | \"medium\" | \"low\" | string;\n\nexport function scoreColor(score: number): string {\n if (score >= 80) return \"var(--tpl-success)\";\n if (score >= 60) return \"var(--tpl-warning)\";\n return \"var(--tpl-danger)\";\n}\n\nexport function scoreBgColor(score: number): string {\n if (score >= 80) return \"var(--tpl-success-light)\";\n if (score >= 60) return \"var(--tpl-warning-light)\";\n return \"var(--tpl-danger-light)\";\n}\n\nexport function severityColor(severity: ScoringSeverity): string {\n if (severity === \"high\") return \"var(--tpl-danger)\";\n if (severity === \"medium\") return \"var(--tpl-warning)\";\n return \"var(--tpl-text-muted)\";\n}\n\nexport function severityBgColor(severity: ScoringSeverity): string {\n if (severity === \"high\") return \"var(--tpl-danger-light)\";\n if (severity === \"medium\") return \"var(--tpl-warning-light)\";\n return \"var(--tpl-bg-hover)\";\n}\n","<script setup lang=\"ts\">\nimport LoadingTrack from \"../../components/LoadingTrack.vue\";\nimport {\n EDITOR_KEY,\n SCORING_KEY,\n MERGE_TAGS_KEY,\n requireInject,\n} from \"../../keys\";\nimport {\n scoreColor,\n scoreBgColor,\n severityColor,\n severityBgColor,\n} from \"../utils/scoringStyles\";\nimport { useCloudI18nStrict } from \"../../composables/useCloudI18n\";\nimport type { ScoringCategory, ScoringFinding } from \"@templatical/types\";\nimport {\n CircleAlert,\n TriangleAlert,\n ChevronDown,\n Eye,\n Info,\n LoaderCircle,\n RefreshCw,\n ShieldCheck,\n ShieldX,\n Sparkles,\n X,\n Zap,\n} from \"@lucide/vue\";\nimport { inject, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"TemplateScoringPanel\");\nconst scoring = requireInject(SCORING_KEY, \"TemplateScoringPanel\");\nconst mergeTags = inject(MERGE_TAGS_KEY, []);\n\nconst expandedCategories = ref<Record<string, boolean>>({\n spam: true,\n readability: true,\n accessibility: true,\n bestPractices: true,\n});\n\nfunction toggleCategory(category: string): void {\n expandedCategories.value[category] = !expandedCategories.value[category];\n}\n\nconst categoryOrder: ScoringCategory[] = [\n \"spam\",\n \"readability\",\n \"accessibility\",\n \"bestPractices\",\n];\n\nconst categoryIcons: Record<ScoringCategory, typeof ShieldCheck> = {\n spam: ShieldX,\n readability: Eye,\n accessibility: Sparkles,\n bestPractices: Zap,\n};\n\nfunction triggerScore(): void {\n scoring.score(editor.content.value, mergeTags);\n}\n\nwatch(\n () => props.visible,\n (isVisible) => {\n if (isVisible && !scoring.scoringResult.value && !scoring.isScoring.value) {\n triggerScore();\n }\n },\n);\n\nasync function handleFix(finding: ScoringFinding): Promise<void> {\n if (!finding.blockId) {\n return;\n }\n\n // Get the block content from the editor\n const block = editor.content.value.blocks.find(\n (b) => b.id === finding.blockId,\n );\n if (!block) {\n return;\n }\n\n // Extract HTML content from the block (text blocks have content property)\n const blockContent = (block as unknown as Record<string, unknown>).content as\n string | undefined;\n if (!blockContent) {\n return;\n }\n\n const fixedContent = await scoring.fixFinding(\n blockContent,\n finding,\n mergeTags,\n );\n\n if (fixedContent) {\n editor.updateBlock(finding.blockId, { content: fixedContent });\n scoring.removeFinding(finding.category, finding.id);\n }\n}\n\nfunction totalFindings(): number {\n if (!scoring.scoringResult.value) {\n return 0;\n }\n return categoryOrder.reduce((sum, cat) => {\n return (\n sum + (scoring.scoringResult.value?.categories[cat]?.findings.length ?? 0)\n );\n }, 0);\n}\n</script>\n\n<template>\n <Transition\n enter-active-class=\"tpl-scoring-slide-enter-active\"\n enter-from-class=\"tpl:translate-x-full\"\n enter-to-class=\"tpl:translate-x-0\"\n leave-active-class=\"tpl-scoring-slide-leave-active\"\n leave-from-class=\"tpl:translate-x-0\"\n leave-to-class=\"tpl:translate-x-full\"\n >\n <div\n v-if=\"visible\"\n class=\"tpl-scoring-panel tpl:absolute tpl:top-14 tpl:right-0 tpl:bottom-0 tpl:z-panel tpl:flex tpl:w-[360px] tpl:flex-col tpl:border-l tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg-elevated)]\"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:border-[var(--tpl-border)] tpl:px-4 tpl:py-3\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-primary)]\"\n >\n <ShieldCheck :size=\"13\" :stroke-width=\"2\" />\n <span>{{ cloudT.scoring.title }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-1\">\n <button\n v-if=\"scoring.scoringResult.value && !scoring.isScoring.value\"\n class=\"tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]\"\n :title=\"cloudT.scoring.rescore\"\n @click=\"triggerScore()\"\n >\n <RefreshCw :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]\"\n @click=\"emit('close')\"\n >\n <X :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <!-- Content -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <!-- Loading state -->\n <div\n v-if=\"scoring.isScoring.value\"\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <p class=\"tpl:text-sm tpl:text-[var(--tpl-text-muted)]\">\n {{ cloudT.scoring.scoring }}\n </p>\n <LoadingTrack class=\"tpl:w-3/4\" />\n </div>\n\n <!-- Error state -->\n <div\n v-else-if=\"scoring.error.value && !scoring.scoringResult.value\"\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <CircleAlert\n :size=\"32\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-danger)]\"\n />\n <p\n class=\"tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.error }}\n </p>\n <button\n class=\"tpl:mt-2 tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text-muted)]\"\n @click=\"triggerScore()\"\n >\n <RefreshCw :size=\"12\" :stroke-width=\"2\" />\n {{ cloudT.scoring.rescore }}\n </button>\n </div>\n\n <!-- Results -->\n <div\n v-else-if=\"scoring.scoringResult.value\"\n class=\"tpl:flex tpl:flex-col tpl:gap-4\"\n >\n <!-- Overall score -->\n <div\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:gap-2 tpl:rounded-[var(--tpl-radius)] tpl:p-5\"\n :style=\"{\n backgroundColor: scoreBgColor(scoring.scoringResult.value.score),\n }\"\n >\n <span\n class=\"tpl:text-4xl tpl:font-bold tpl:tabular-nums\"\n :style=\"{\n color: scoreColor(scoring.scoringResult.value.score),\n }\"\n >\n {{ scoring.scoringResult.value.score }}\n </span>\n <span\n class=\"tpl:text-xs tpl:font-medium tpl:uppercase tpl:tracking-wider tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.overallScore }}\n </span>\n <span\n v-if=\"totalFindings() > 0\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ totalFindings() }}\n {{ cloudT.scoring.findings }}\n </span>\n </div>\n\n <!-- Fix error -->\n <div\n v-if=\"scoring.fixError.value\"\n class=\"tpl:flex tpl:items-start tpl:gap-2 tpl:rounded-lg tpl:px-3 tpl:py-2 tpl:text-xs tpl:bg-[var(--tpl-danger-light)] tpl:text-[var(--tpl-danger)]\"\n >\n <CircleAlert\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:mt-0.5 tpl:shrink-0\"\n />\n <span>{{ cloudT.scoring.fixError }}</span>\n </div>\n\n <!-- Category cards -->\n <div\n v-for=\"category in categoryOrder\"\n :key=\"category\"\n class=\"tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:border tpl:border-[var(--tpl-border)]\"\n >\n <!-- Category header -->\n <button\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:gap-2.5 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-colors tpl:duration-100 tpl:bg-[var(--tpl-bg)]\"\n @click=\"toggleCategory(category)\"\n >\n <component\n :is=\"categoryIcons[category]\"\n :size=\"14\"\n :stroke-width=\"2\"\n :style=\"{\n color: scoreColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n }\"\n />\n <span\n class=\"tpl:flex-1 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.scoring.categories[category] }}\n </span>\n <span\n class=\"tpl:rounded-full tpl:px-2 tpl:py-0.5 tpl:text-xs tpl:font-semibold tpl:tabular-nums\"\n :style=\"{\n color: scoreColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n backgroundColor: scoreBgColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n }\"\n >\n {{ scoring.scoringResult.value.categories[category].score }}\n </span>\n <span\n v-if=\"\n scoring.scoringResult.value.categories[category].findings\n .length > 0\n \"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n {{\n scoring.scoringResult.value.categories[category].findings\n .length\n }}\n </span>\n <ChevronDown\n :size=\"12\"\n :stroke-width=\"2\"\n class=\"tpl:transition-transform tpl:duration-200 tpl:text-[var(--tpl-text-dim)]\"\n :class=\"\n expandedCategories[category]\n ? 'tpl:rotate-0'\n : 'tpl:-rotate-90'\n \"\n />\n </button>\n\n <!-- Findings list -->\n <div\n v-if=\"expandedCategories[category]\"\n class=\"tpl:border-t tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"\n scoring.scoringResult.value.categories[category].findings\n .length === 0\n \"\n class=\"tpl:px-3 tpl:py-3 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.scoring.noFindings }}\n </div>\n <div\n v-for=\"finding in scoring.scoringResult.value.categories[\n category\n ].findings\"\n :key=\"finding.id\"\n class=\"tpl:border-t tpl:px-3 tpl:py-2.5 first:tpl:border-t-0 tpl:border-[var(--tpl-border-light)]\"\n >\n <div class=\"tpl:flex tpl:items-start tpl:gap-2\">\n <!-- Severity icon -->\n <component\n :is=\"\n finding.severity === 'high'\n ? CircleAlert\n : finding.severity === 'medium'\n ? TriangleAlert\n : Info\n \"\n :size=\"13\"\n :stroke-width=\"2\"\n class=\"tpl:mt-0.5 tpl:shrink-0\"\n :style=\"{\n color: severityColor(finding.severity),\n }\"\n />\n <div class=\"tpl:flex-1 tpl:min-w-0\">\n <!-- Severity badge + message -->\n <div class=\"tpl:flex tpl:items-start tpl:gap-1.5\">\n <span\n class=\"tpl:mt-0.5 tpl:shrink-0 tpl:rounded tpl:px-1 tpl:py-px tpl:text-[10px] tpl:font-medium tpl:leading-tight\"\n :style=\"{\n color: severityColor(finding.severity),\n backgroundColor: severityBgColor(finding.severity),\n }\"\n >\n {{ cloudT.scoring.severity[finding.severity] }}\n </span>\n <span\n class=\"tpl:text-xs tpl:leading-snug tpl:text-[var(--tpl-text)]\"\n >\n {{ finding.message }}\n </span>\n </div>\n <!-- Suggestion -->\n <p\n v-if=\"finding.suggestion\"\n class=\"tpl:mt-1 tpl:text-[11px] tpl:leading-snug tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ finding.suggestion }}\n </p>\n <!-- Fix button -->\n <div\n v-if=\"finding.blockId\"\n class=\"tpl:mt-2 tpl:flex tpl:justify-center\"\n >\n <button\n class=\"tpl-scoring-fix-btn tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded tpl:border tpl:px-3 tpl:py-1.5 tpl:text-[11px] tpl:font-medium tpl:transition-all tpl:duration-150 tpl:disabled:opacity-50 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-primary)]\"\n style=\"background-color: transparent\"\n :disabled=\"scoring.fixingFindingId.value !== null\"\n @click=\"handleFix(finding)\"\n >\n <LoaderCircle\n v-if=\"scoring.fixingFindingId.value === finding.id\"\n class=\"tpl-spinner\"\n :size=\"11\"\n :stroke-width=\"2\"\n />\n <Sparkles v-else :size=\"11\" :stroke-width=\"2\" />\n {{\n scoring.fixingFindingId.value === finding.id\n ? cloudT.scoring.fixing\n : cloudT.scoring.fix\n }}\n </button>\n <p\n v-if=\"scoring.fixError.value\"\n class=\"tpl:mt-1.5 tpl:text-[11px] tpl:text-[var(--tpl-danger)]\"\n >\n {{ scoring.fixError.value }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Empty state (no result, no loading, no error) -->\n <div\n v-else\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <ShieldCheck\n :size=\"32\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.emptyState }}\n </p>\n </div>\n\n <!-- AI disclaimer -->\n <p\n class=\"tpl:m-0 tpl:px-4 tpl:pb-2 tpl:pt-2 tpl:text-center tpl:text-[11px] tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.aiMenu.disclaimer }}\n </p>\n </div>\n </div>\n </Transition>\n</template>\n\n<style scoped>\n.tpl-scoring-slide-enter-active {\n transition: transform 280ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.tpl-scoring-slide-leave-active {\n transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.tpl-scoring-fix-btn:not(:disabled):hover {\n border-color: var(--tpl-primary) !important;\n background-color: var(--tpl-primary-light) !important;\n}\n</style>\n","<script setup lang=\"ts\">\nimport LoadingTrack from \"../../components/LoadingTrack.vue\";\nimport {\n EDITOR_KEY,\n SCORING_KEY,\n MERGE_TAGS_KEY,\n requireInject,\n} from \"../../keys\";\nimport {\n scoreColor,\n scoreBgColor,\n severityColor,\n severityBgColor,\n} from \"../utils/scoringStyles\";\nimport { useCloudI18nStrict } from \"../../composables/useCloudI18n\";\nimport type { ScoringCategory, ScoringFinding } from \"@templatical/types\";\nimport {\n CircleAlert,\n TriangleAlert,\n ChevronDown,\n Eye,\n Info,\n LoaderCircle,\n RefreshCw,\n ShieldCheck,\n ShieldX,\n Sparkles,\n X,\n Zap,\n} from \"@lucide/vue\";\nimport { inject, ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\nconst editor = requireInject(EDITOR_KEY, \"TemplateScoringPanel\");\nconst scoring = requireInject(SCORING_KEY, \"TemplateScoringPanel\");\nconst mergeTags = inject(MERGE_TAGS_KEY, []);\n\nconst expandedCategories = ref<Record<string, boolean>>({\n spam: true,\n readability: true,\n accessibility: true,\n bestPractices: true,\n});\n\nfunction toggleCategory(category: string): void {\n expandedCategories.value[category] = !expandedCategories.value[category];\n}\n\nconst categoryOrder: ScoringCategory[] = [\n \"spam\",\n \"readability\",\n \"accessibility\",\n \"bestPractices\",\n];\n\nconst categoryIcons: Record<ScoringCategory, typeof ShieldCheck> = {\n spam: ShieldX,\n readability: Eye,\n accessibility: Sparkles,\n bestPractices: Zap,\n};\n\nfunction triggerScore(): void {\n scoring.score(editor.content.value, mergeTags);\n}\n\nwatch(\n () => props.visible,\n (isVisible) => {\n if (isVisible && !scoring.scoringResult.value && !scoring.isScoring.value) {\n triggerScore();\n }\n },\n);\n\nasync function handleFix(finding: ScoringFinding): Promise<void> {\n if (!finding.blockId) {\n return;\n }\n\n // Get the block content from the editor\n const block = editor.content.value.blocks.find(\n (b) => b.id === finding.blockId,\n );\n if (!block) {\n return;\n }\n\n // Extract HTML content from the block (text blocks have content property)\n const blockContent = (block as unknown as Record<string, unknown>).content as\n string | undefined;\n if (!blockContent) {\n return;\n }\n\n const fixedContent = await scoring.fixFinding(\n blockContent,\n finding,\n mergeTags,\n );\n\n if (fixedContent) {\n editor.updateBlock(finding.blockId, { content: fixedContent });\n scoring.removeFinding(finding.category, finding.id);\n }\n}\n\nfunction totalFindings(): number {\n if (!scoring.scoringResult.value) {\n return 0;\n }\n return categoryOrder.reduce((sum, cat) => {\n return (\n sum + (scoring.scoringResult.value?.categories[cat]?.findings.length ?? 0)\n );\n }, 0);\n}\n</script>\n\n<template>\n <Transition\n enter-active-class=\"tpl-scoring-slide-enter-active\"\n enter-from-class=\"tpl:translate-x-full\"\n enter-to-class=\"tpl:translate-x-0\"\n leave-active-class=\"tpl-scoring-slide-leave-active\"\n leave-from-class=\"tpl:translate-x-0\"\n leave-to-class=\"tpl:translate-x-full\"\n >\n <div\n v-if=\"visible\"\n class=\"tpl-scoring-panel tpl:absolute tpl:top-14 tpl:right-0 tpl:bottom-0 tpl:z-panel tpl:flex tpl:w-[360px] tpl:flex-col tpl:border-l tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg-elevated)]\"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:border-[var(--tpl-border)] tpl:px-4 tpl:py-3\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-primary)]\"\n >\n <ShieldCheck :size=\"13\" :stroke-width=\"2\" />\n <span>{{ cloudT.scoring.title }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-1\">\n <button\n v-if=\"scoring.scoringResult.value && !scoring.isScoring.value\"\n class=\"tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]\"\n :title=\"cloudT.scoring.rescore\"\n @click=\"triggerScore()\"\n >\n <RefreshCw :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:rounded-md tpl:p-0.5 tpl:transition-colors tpl:duration-150 tpl:text-[var(--tpl-text-muted)]\"\n @click=\"emit('close')\"\n >\n <X :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <!-- Content -->\n <div class=\"tpl:flex-1 tpl:overflow-y-auto tpl:p-4\">\n <!-- Loading state -->\n <div\n v-if=\"scoring.isScoring.value\"\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <p class=\"tpl:text-sm tpl:text-[var(--tpl-text-muted)]\">\n {{ cloudT.scoring.scoring }}\n </p>\n <LoadingTrack class=\"tpl:w-3/4\" />\n </div>\n\n <!-- Error state -->\n <div\n v-else-if=\"scoring.error.value && !scoring.scoringResult.value\"\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <CircleAlert\n :size=\"32\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-danger)]\"\n />\n <p\n class=\"tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.error }}\n </p>\n <button\n class=\"tpl:mt-2 tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text-muted)]\"\n @click=\"triggerScore()\"\n >\n <RefreshCw :size=\"12\" :stroke-width=\"2\" />\n {{ cloudT.scoring.rescore }}\n </button>\n </div>\n\n <!-- Results -->\n <div\n v-else-if=\"scoring.scoringResult.value\"\n class=\"tpl:flex tpl:flex-col tpl:gap-4\"\n >\n <!-- Overall score -->\n <div\n class=\"tpl:flex tpl:flex-col tpl:items-center tpl:gap-2 tpl:rounded-[var(--tpl-radius)] tpl:p-5\"\n :style=\"{\n backgroundColor: scoreBgColor(scoring.scoringResult.value.score),\n }\"\n >\n <span\n class=\"tpl:text-4xl tpl:font-bold tpl:tabular-nums\"\n :style=\"{\n color: scoreColor(scoring.scoringResult.value.score),\n }\"\n >\n {{ scoring.scoringResult.value.score }}\n </span>\n <span\n class=\"tpl:text-xs tpl:font-medium tpl:uppercase tpl:tracking-wider tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.overallScore }}\n </span>\n <span\n v-if=\"totalFindings() > 0\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ totalFindings() }}\n {{ cloudT.scoring.findings }}\n </span>\n </div>\n\n <!-- Fix error -->\n <div\n v-if=\"scoring.fixError.value\"\n class=\"tpl:flex tpl:items-start tpl:gap-2 tpl:rounded-lg tpl:px-3 tpl:py-2 tpl:text-xs tpl:bg-[var(--tpl-danger-light)] tpl:text-[var(--tpl-danger)]\"\n >\n <CircleAlert\n :size=\"14\"\n :stroke-width=\"2\"\n class=\"tpl:mt-0.5 tpl:shrink-0\"\n />\n <span>{{ cloudT.scoring.fixError }}</span>\n </div>\n\n <!-- Category cards -->\n <div\n v-for=\"category in categoryOrder\"\n :key=\"category\"\n class=\"tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:border tpl:border-[var(--tpl-border)]\"\n >\n <!-- Category header -->\n <button\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:gap-2.5 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-colors tpl:duration-100 tpl:bg-[var(--tpl-bg)]\"\n @click=\"toggleCategory(category)\"\n >\n <component\n :is=\"categoryIcons[category]\"\n :size=\"14\"\n :stroke-width=\"2\"\n :style=\"{\n color: scoreColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n }\"\n />\n <span\n class=\"tpl:flex-1 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.scoring.categories[category] }}\n </span>\n <span\n class=\"tpl:rounded-full tpl:px-2 tpl:py-0.5 tpl:text-xs tpl:font-semibold tpl:tabular-nums\"\n :style=\"{\n color: scoreColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n backgroundColor: scoreBgColor(\n scoring.scoringResult.value.categories[category].score,\n ),\n }\"\n >\n {{ scoring.scoringResult.value.categories[category].score }}\n </span>\n <span\n v-if=\"\n scoring.scoringResult.value.categories[category].findings\n .length > 0\n \"\n class=\"tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]\"\n >\n {{\n scoring.scoringResult.value.categories[category].findings\n .length\n }}\n </span>\n <ChevronDown\n :size=\"12\"\n :stroke-width=\"2\"\n class=\"tpl:transition-transform tpl:duration-200 tpl:text-[var(--tpl-text-dim)]\"\n :class=\"\n expandedCategories[category]\n ? 'tpl:rotate-0'\n : 'tpl:-rotate-90'\n \"\n />\n </button>\n\n <!-- Findings list -->\n <div\n v-if=\"expandedCategories[category]\"\n class=\"tpl:border-t tpl:border-[var(--tpl-border)]\"\n >\n <div\n v-if=\"\n scoring.scoringResult.value.categories[category].findings\n .length === 0\n \"\n class=\"tpl:px-3 tpl:py-3 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.scoring.noFindings }}\n </div>\n <div\n v-for=\"finding in scoring.scoringResult.value.categories[\n category\n ].findings\"\n :key=\"finding.id\"\n class=\"tpl:border-t tpl:px-3 tpl:py-2.5 first:tpl:border-t-0 tpl:border-[var(--tpl-border-light)]\"\n >\n <div class=\"tpl:flex tpl:items-start tpl:gap-2\">\n <!-- Severity icon -->\n <component\n :is=\"\n finding.severity === 'high'\n ? CircleAlert\n : finding.severity === 'medium'\n ? TriangleAlert\n : Info\n \"\n :size=\"13\"\n :stroke-width=\"2\"\n class=\"tpl:mt-0.5 tpl:shrink-0\"\n :style=\"{\n color: severityColor(finding.severity),\n }\"\n />\n <div class=\"tpl:flex-1 tpl:min-w-0\">\n <!-- Severity badge + message -->\n <div class=\"tpl:flex tpl:items-start tpl:gap-1.5\">\n <span\n class=\"tpl:mt-0.5 tpl:shrink-0 tpl:rounded tpl:px-1 tpl:py-px tpl:text-[10px] tpl:font-medium tpl:leading-tight\"\n :style=\"{\n color: severityColor(finding.severity),\n backgroundColor: severityBgColor(finding.severity),\n }\"\n >\n {{ cloudT.scoring.severity[finding.severity] }}\n </span>\n <span\n class=\"tpl:text-xs tpl:leading-snug tpl:text-[var(--tpl-text)]\"\n >\n {{ finding.message }}\n </span>\n </div>\n <!-- Suggestion -->\n <p\n v-if=\"finding.suggestion\"\n class=\"tpl:mt-1 tpl:text-[11px] tpl:leading-snug tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ finding.suggestion }}\n </p>\n <!-- Fix button -->\n <div\n v-if=\"finding.blockId\"\n class=\"tpl:mt-2 tpl:flex tpl:justify-center\"\n >\n <button\n class=\"tpl-scoring-fix-btn tpl:inline-flex tpl:items-center tpl:gap-1.5 tpl:rounded tpl:border tpl:px-3 tpl:py-1.5 tpl:text-[11px] tpl:font-medium tpl:transition-all tpl:duration-150 tpl:disabled:opacity-50 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-primary)]\"\n style=\"background-color: transparent\"\n :disabled=\"scoring.fixingFindingId.value !== null\"\n @click=\"handleFix(finding)\"\n >\n <LoaderCircle\n v-if=\"scoring.fixingFindingId.value === finding.id\"\n class=\"tpl-spinner\"\n :size=\"11\"\n :stroke-width=\"2\"\n />\n <Sparkles v-else :size=\"11\" :stroke-width=\"2\" />\n {{\n scoring.fixingFindingId.value === finding.id\n ? cloudT.scoring.fixing\n : cloudT.scoring.fix\n }}\n </button>\n <p\n v-if=\"scoring.fixError.value\"\n class=\"tpl:mt-1.5 tpl:text-[11px] tpl:text-[var(--tpl-danger)]\"\n >\n {{ scoring.fixError.value }}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Empty state (no result, no loading, no error) -->\n <div\n v-else\n class=\"tpl:flex tpl:h-full tpl:flex-col tpl:items-center tpl:justify-center tpl:gap-3 tpl:text-center\"\n >\n <ShieldCheck\n :size=\"32\"\n :stroke-width=\"1.5\"\n class=\"tpl:text-[var(--tpl-text-dim)]\"\n />\n <p\n class=\"tpl:max-w-[240px] tpl:text-sm tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.scoring.emptyState }}\n </p>\n </div>\n\n <!-- AI disclaimer -->\n <p\n class=\"tpl:m-0 tpl:px-4 tpl:pb-2 tpl:pt-2 tpl:text-center tpl:text-[11px] tpl:text-[var(--tpl-text-dim)]\"\n >\n {{ cloudT.aiMenu.disclaimer }}\n </p>\n </div>\n </div>\n </Transition>\n</template>\n\n<style scoped>\n.tpl-scoring-slide-enter-active {\n transition: transform 280ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.tpl-scoring-slide-leave-active {\n transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n.tpl-scoring-fix-btn:not(:disabled):hover {\n border-color: var(--tpl-primary) !important;\n background-color: var(--tpl-primary-light) !important;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { H as e, M as t, P as n, V as r, Z as i, a, ct as o, g as s, h as c, it as l, m as u, ot as d, p as f, u as p, v as m, x as h, y as g, z as _ } from "./draggable-D840DIZB.js";
|
|
2
|
+
import "./useEditorCore-BA6mspzD.js";
|
|
3
|
+
import { rt as v } from "./icons-CYWw8Xfp.js";
|
|
4
|
+
import { n as y } from "./useCloudI18n-BjNENqkM.js";
|
|
5
|
+
import { t as b } from "./TplModal-CH9RzKF7.js";
|
|
6
|
+
//#region src/cloud/components/TestEmailModal.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
+
var x = ["aria-busy"], S = {
|
|
8
|
+
id: "tpl-test-email-title",
|
|
9
|
+
class: "tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]"
|
|
10
|
+
}, C = { class: "tpl:mb-3" }, w = { class: "tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]" }, T = ["value"], E = ["disabled"], D = ["value"], O = {
|
|
11
|
+
key: 0,
|
|
12
|
+
role: "alert",
|
|
13
|
+
class: "tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]"
|
|
14
|
+
}, k = { class: "tpl:flex tpl:justify-end tpl:gap-2" }, A = ["disabled"], j = ["disabled"], M = {
|
|
15
|
+
key: 0,
|
|
16
|
+
class: "tpl:flex tpl:items-center tpl:gap-1.5"
|
|
17
|
+
}, N = { key: 1 }, P = /* @__PURE__ */ h({
|
|
18
|
+
__name: "TestEmailModal",
|
|
19
|
+
props: {
|
|
20
|
+
visible: { type: Boolean },
|
|
21
|
+
allowedEmails: {},
|
|
22
|
+
isSending: { type: Boolean },
|
|
23
|
+
error: {}
|
|
24
|
+
},
|
|
25
|
+
emits: ["send", "close"],
|
|
26
|
+
setup(h, { emit: P }) {
|
|
27
|
+
let F = h, I = P, { t: L } = y(), R = i("");
|
|
28
|
+
_(() => F.visible, (e) => {
|
|
29
|
+
e && (R.value = F.allowedEmails[0] ?? "");
|
|
30
|
+
});
|
|
31
|
+
function z() {
|
|
32
|
+
!R.value || F.isSending || I("send", R.value);
|
|
33
|
+
}
|
|
34
|
+
function B() {
|
|
35
|
+
F.isSending || I("close");
|
|
36
|
+
}
|
|
37
|
+
function V(e) {
|
|
38
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), z()), e.key === "Escape" && B();
|
|
39
|
+
}
|
|
40
|
+
return (i, _) => (t(), u(b, {
|
|
41
|
+
visible: h.visible,
|
|
42
|
+
onClose: B,
|
|
43
|
+
onKeydown: V
|
|
44
|
+
}, {
|
|
45
|
+
default: r(() => [f("div", {
|
|
46
|
+
role: "dialog",
|
|
47
|
+
"aria-modal": "true",
|
|
48
|
+
"aria-busy": h.isSending,
|
|
49
|
+
"aria-labelledby": "tpl-test-email-title",
|
|
50
|
+
class: "tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5",
|
|
51
|
+
style: {
|
|
52
|
+
"background-color": "var(--tpl-bg-elevated)",
|
|
53
|
+
"box-shadow": "var(--tpl-shadow-xl)"
|
|
54
|
+
}
|
|
55
|
+
}, [
|
|
56
|
+
f("h3", S, o(l(L).testEmail.title), 1),
|
|
57
|
+
f("div", C, [f("label", w, o(l(L).testEmail.recipientLabel), 1), h.allowedEmails.length === 1 ? (t(), s("input", {
|
|
58
|
+
key: 0,
|
|
59
|
+
type: "text",
|
|
60
|
+
value: R.value,
|
|
61
|
+
disabled: "",
|
|
62
|
+
class: "tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:opacity-70 tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]"
|
|
63
|
+
}, null, 8, T)) : e((t(), s("select", {
|
|
64
|
+
key: 1,
|
|
65
|
+
"onUpdate:modelValue": _[0] ||= (e) => R.value = e,
|
|
66
|
+
class: "tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]",
|
|
67
|
+
disabled: h.isSending
|
|
68
|
+
}, [(t(!0), s(p, null, n(h.allowedEmails, (e) => (t(), s("option", {
|
|
69
|
+
key: e,
|
|
70
|
+
value: e
|
|
71
|
+
}, o(e), 9, D))), 128))], 8, E)), [[a, R.value]])]),
|
|
72
|
+
h.error ? (t(), s("p", O, o(h.error), 1)) : c("", !0),
|
|
73
|
+
f("div", k, [f("button", {
|
|
74
|
+
type: "button",
|
|
75
|
+
class: d(["tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]", { "tpl:cursor-not-allowed tpl:opacity-50": h.isSending }]),
|
|
76
|
+
disabled: h.isSending,
|
|
77
|
+
onClick: B
|
|
78
|
+
}, o(l(L).testEmail.cancel), 11, A), f("button", {
|
|
79
|
+
type: "button",
|
|
80
|
+
class: "tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]",
|
|
81
|
+
disabled: !R.value || h.isSending,
|
|
82
|
+
onClick: z
|
|
83
|
+
}, [h.isSending ? (t(), s("span", M, [g(l(v), {
|
|
84
|
+
class: "tpl:animate-spin",
|
|
85
|
+
size: 12,
|
|
86
|
+
"stroke-width": 2
|
|
87
|
+
}), m(" " + o(l(L).testEmail.sending), 1)])) : (t(), s("span", N, o(l(L).testEmail.send), 1))], 8, j)])
|
|
88
|
+
], 8, x)]),
|
|
89
|
+
_: 1
|
|
90
|
+
}, 8, ["visible"]));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
//#endregion
|
|
94
|
+
export { P as default };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=TestEmailModal-BJTDxFHh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestEmailModal-BJTDxFHh.js","names":[],"sources":["../../../src/cloud/components/TestEmailModal.vue","../../../src/cloud/components/TestEmailModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n allowedEmails: string[];\n isSending: boolean;\n error: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"send\", recipient: string): void;\n (e: \"close\"): void;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst recipient = ref(\"\");\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n recipient.value = props.allowedEmails[0] ?? \"\";\n }\n },\n);\n\nfunction handleSend(): void {\n if (!recipient.value || props.isSending) {\n return;\n }\n\n emit(\"send\", recipient.value);\n}\n\nfunction handleClose(): void {\n if (!props.isSending) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSend();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSending\"\n aria-labelledby=\"tpl-test-email-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-test-email-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.testEmail.title }}\n </h3>\n\n <!-- Recipient -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.testEmail.recipientLabel }}\n </label>\n <input\n v-if=\"allowedEmails.length === 1\"\n type=\"text\"\n :value=\"recipient\"\n disabled\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:opacity-70 tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n <select\n v-else\n v-model=\"recipient\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSending\"\n >\n <option v-for=\"email in allowedEmails\" :key=\"email\" :value=\"email\">\n {{ email }}\n </option>\n </select>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSending\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSending,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.testEmail.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!recipient || isSending\"\n @click=\"handleSend\"\n >\n <span v-if=\"isSending\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.testEmail.sending }}\n </span>\n <span v-else>\n {{ cloudT.testEmail.send }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n","<script setup lang=\"ts\">\nimport TplModal from \"../../components/TplModal.vue\";\nimport { useCloudI18nStrict } from \"../../composables\";\nimport { LoaderCircle } from \"@lucide/vue\";\nimport { ref, watch } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n allowedEmails: string[];\n isSending: boolean;\n error: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"send\", recipient: string): void;\n (e: \"close\"): void;\n}>();\n\nconst { t: cloudT } = useCloudI18nStrict();\n\nconst recipient = ref(\"\");\n\nwatch(\n () => props.visible,\n (visible) => {\n if (visible) {\n recipient.value = props.allowedEmails[0] ?? \"\";\n }\n },\n);\n\nfunction handleSend(): void {\n if (!recipient.value || props.isSending) {\n return;\n }\n\n emit(\"send\", recipient.value);\n}\n\nfunction handleClose(): void {\n if (!props.isSending) {\n emit(\"close\");\n }\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n handleSend();\n }\n if (event.key === \"Escape\") {\n handleClose();\n }\n}\n</script>\n\n<template>\n <TplModal :visible=\"visible\" @close=\"handleClose\" @keydown=\"handleKeydown\">\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-busy=\"isSending\"\n aria-labelledby=\"tpl-test-email-title\"\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n id=\"tpl-test-email-title\"\n class=\"tpl:mb-4 tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]\"\n >\n {{ cloudT.testEmail.title }}\n </h3>\n\n <!-- Recipient -->\n <div class=\"tpl:mb-3\">\n <label\n class=\"tpl:mb-1.5 tpl:block tpl:text-sm tpl:font-medium tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ cloudT.testEmail.recipientLabel }}\n </label>\n <input\n v-if=\"allowedEmails.length === 1\"\n type=\"text\"\n :value=\"recipient\"\n disabled\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:opacity-70 tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n />\n <select\n v-else\n v-model=\"recipient\"\n class=\"tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:px-3 tpl:py-1 tpl:text-sm tpl:shadow-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]\"\n :disabled=\"isSending\"\n >\n <option v-for=\"email in allowedEmails\" :key=\"email\" :value=\"email\">\n {{ email }}\n </option>\n </select>\n </div>\n\n <!-- Error message -->\n <p\n v-if=\"error\"\n role=\"alert\"\n class=\"tpl:mb-3 tpl:text-xs tpl:text-[var(--tpl-danger)]\"\n >\n {{ error }}\n </p>\n\n <!-- Actions -->\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]\"\n :disabled=\"isSending\"\n :class=\"{\n 'tpl:cursor-not-allowed tpl:opacity-50': isSending,\n }\"\n @click=\"handleClose\"\n >\n {{ cloudT.testEmail.cancel }}\n </button>\n <button\n type=\"button\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]\"\n :disabled=\"!recipient || isSending\"\n @click=\"handleSend\"\n >\n <span v-if=\"isSending\" class=\"tpl:flex tpl:items-center tpl:gap-1.5\">\n <LoaderCircle\n class=\"tpl:animate-spin\"\n :size=\"12\"\n :stroke-width=\"2\"\n />\n {{ cloudT.testEmail.sending }}\n </span>\n <span v-else>\n {{ cloudT.testEmail.send }}\n </span>\n </button>\n </div>\n </div>\n </TplModal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;EAMA,IAAM,IAAQ,GAOR,IAAO,GAKP,EAAE,GAAG,MAAW,EAAmB,GAEnC,IAAY,EAAI,EAAE;EAExB,QACQ,EAAM,UACX,MAAY;GACX,AAAI,MACF,EAAU,QAAQ,EAAM,cAAc,MAAM;EAEhD,CACF;EAEA,SAAS,IAAmB;GACtB,CAAC,EAAU,SAAS,EAAM,aAI9B,EAAK,QAAQ,EAAU,KAAK;EAC9B;EAEA,SAAS,IAAoB;GAC3B,AAAK,EAAM,aACT,EAAK,OAAO;EAEhB;EAEA,SAAS,EAAc,GAA4B;GAKjD,AAJI,EAAM,QAAQ,WAAW,CAAC,EAAM,aAClC,EAAM,eAAe,GACrB,EAAW,IAET,EAAM,QAAQ,YAChB,EAAY;EAEhB;yBAIE,EAuFW,GAAA;GAvFA,SAAS,EAAA;GAAU,SAAO;GAAc,WAAS;;oBAsFpD,CArFN,EAqFM,OAAA;IApFJ,MAAK;IACL,cAAW;IACV,aAAW,EAAA;IACZ,mBAAgB;IAChB,OAAM;IACN,OAAA;KAAA,oBAAA;KAAA,cAAA;IAAA;;IAKA,EAKK,MALL,GAKK,EADA,EAAA,CAAA,CAAM,CAAC,UAAU,KAAK,GAAA,CAAA;IAI3B,EAuBM,OAvBN,GAuBM,CAtBJ,EAIQ,SAJR,GAIQ,EADH,EAAA,CAAA,CAAM,CAAC,UAAU,cAAc,GAAA,CAAA,GAG5B,EAAA,cAAc,WAAM,KAAA,EAAA,GAD5B,EAME,SAAA;;KAJA,MAAK;KACJ,OAAO,EAAA;KACR,UAAA;KACA,OAAM;8BAER,EASS,UAAA;;8CAPW,QAAA;KAClB,OAAM;KACL,UAAU,EAAA;gBAEX,EAES,GAAA,MAAA,EAFe,EAAA,gBAAT,YAAf,EAES,UAAA;KAF+B,KAAK;KAAQ,OAAO;SACvD,CAAK,GAAA,GAAA,CAAA,0BALD,EAAA,KAAS,CAAA,CAAA,CAAA,CAAA;IAYd,EAAA,SAAA,EAAA,GADR,EAMI,KANJ,GAMI,EADC,EAAA,KAAK,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA;IAIV,EA8BM,OA9BN,GA8BM,CA7BJ,EAUS,UAAA;KATP,MAAK;KACL,OAAK,EAAA,CAAC,mOAAiO,EAAA,yCAExK,EAAA,UAAA,CAAA,CAAA;KAD9D,UAAU,EAAA;KAIV,SAAO;SAEL,EAAA,CAAA,CAAM,CAAC,UAAU,MAAM,GAAA,IAAA,CAAA,GAE5B,EAiBS,UAAA;KAhBP,MAAK;KACL,OAAM;KACL,UAAQ,CAAG,EAAA,SAAa,EAAA;KACxB,SAAO;QAEI,EAAA,aAAA,EAAA,GAAZ,EAOO,QAPP,GAOO,CANL,EAIE,EAAA,CAAA,GAAA;KAHA,OAAM;KACL,MAAM;KACN,gBAAc;UACf,MACF,EAAG,EAAA,CAAA,CAAM,CAAC,UAAU,OAAO,GAAA,CAAA,CAAA,CAAA,MAAA,EAAA,GAE7B,EAEO,QAAA,GAAA,EADF,EAAA,CAAA,CAAM,CAAC,UAAU,IAAI,GAAA,CAAA,EAAA,GAAA,GAAA,CAAA,CAAA,CAAA"}
|