@reddoorla/maintenance 0.86.0 → 0.87.0
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/dist/airtable-ZBUPQJSC.js +9 -0
- package/dist/{announce-MXTUQ6C7.js → announce-I2Z4JN3I.js} +49 -28
- package/dist/announce-I2Z4JN3I.js.map +1 -0
- package/dist/attachments-NLZIJ5NU.js +9 -0
- package/dist/{bump-deps-EC74CPLS.js → bump-deps-CGVELRLK.js} +2 -2
- package/dist/{chunk-2ZPT7GLV.js → chunk-3JQ2FO3D.js} +3 -3
- package/dist/chunk-3JQ2FO3D.js.map +1 -0
- package/dist/{chunk-KTH5ZODA.js → chunk-7BZUOZPU.js} +2 -2
- package/dist/{chunk-LDWZSLSU.js → chunk-7NYN2P6I.js} +7 -4
- package/dist/{chunk-LDWZSLSU.js.map → chunk-7NYN2P6I.js.map} +1 -1
- package/dist/{chunk-3VQWSE3F.js → chunk-7UAYMAKR.js} +4 -4
- package/dist/{chunk-BYK66EWO.js → chunk-BBUSGEES.js} +52 -46
- package/dist/chunk-BBUSGEES.js.map +1 -0
- package/dist/{chunk-SLUQ7R6I.js → chunk-C6CLRKPV.js} +5 -5
- package/dist/{chunk-P2FE5AI6.js → chunk-CROKUHJB.js} +2 -2
- package/dist/{chunk-W7Z3BGCI.js → chunk-DEWJMMG3.js} +2 -2
- package/dist/{chunk-ACBRLLFT.js → chunk-F3JWOPTG.js} +7 -3
- package/dist/chunk-F3JWOPTG.js.map +1 -0
- package/dist/{chunk-TERE5SDF.js → chunk-HEWSRXYV.js} +4 -4
- package/dist/chunk-HHMMUR4P.js +335 -0
- package/dist/chunk-HHMMUR4P.js.map +1 -0
- package/dist/{chunk-X3B723J4.js → chunk-HSI6Q7MI.js} +38 -9
- package/dist/chunk-HSI6Q7MI.js.map +1 -0
- package/dist/{chunk-Z7AXYKQB.js → chunk-IY6256GK.js} +1 -1
- package/dist/{chunk-CQR4LIM7.js → chunk-MT2JINSS.js} +5 -1
- package/dist/{chunk-CQR4LIM7.js.map → chunk-MT2JINSS.js.map} +1 -1
- package/dist/{chunk-F5KM4LEQ.js → chunk-NCMZMLY7.js} +3 -3
- package/dist/{chunk-2NDRHXMR.js → chunk-NDWYJLRF.js} +17 -140
- package/dist/chunk-NDWYJLRF.js.map +1 -0
- package/dist/{chunk-PPE5KZJK.js → chunk-NXNPDCF3.js} +3 -3
- package/dist/{chunk-ITIOFN7A.js → chunk-P6AORG32.js} +29 -10
- package/dist/chunk-P6AORG32.js.map +1 -0
- package/dist/{chunk-N45M3FDK.js → chunk-SDDPUAWH.js} +4 -4
- package/dist/{chunk-ZKXSX4LO.js → chunk-TD2NNXLZ.js} +9 -9
- package/dist/{chunk-ILUNZHYV.js → chunk-YFAXOD7Z.js} +10 -6
- package/dist/chunk-YFAXOD7Z.js.map +1 -0
- package/dist/{chunk-2EVEFOZY.js → chunk-ZBDZTJUO.js} +2 -2
- package/dist/chunk-ZGBEIWSC.js +146 -0
- package/dist/chunk-ZGBEIWSC.js.map +1 -0
- package/dist/cli/bin.js +32 -27
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +15 -11
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/{convert-to-pnpm-6L6P74WR.js → convert-to-pnpm-QFJOEP5V.js} +2 -2
- package/dist/{db-B35OGV3G.js → db-UXNIZ2RG.js} +6 -6
- package/dist/{digest-BL6UJYKH.js → digest-FW6QMZZJ.js} +17 -16
- package/dist/{digest-BL6UJYKH.js.map → digest-FW6QMZZJ.js.map} +1 -1
- package/dist/{email-VTTTKKL5.js → email-KJXASVH5.js} +3 -3
- package/dist/{ensure-site-DFTB7MN3.js → ensure-site-4DCEBAPM.js} +19 -11
- package/dist/ensure-site-4DCEBAPM.js.map +1 -0
- package/dist/fleet-state-7TJ2GYT2.js +39 -0
- package/dist/{forms-notify-target-75U6OU7L.js → forms-notify-target-2EAWCWBW.js} +7 -4
- package/dist/forms-notify-target-2EAWCWBW.js.map +1 -0
- package/dist/{github-signals-IJUPGCUX.js → github-signals-E2WPYTBK.js} +9 -9
- package/dist/{header-image-AWLLQA4L.js → header-image-6IC53W27.js} +7 -7
- package/dist/{header-images-335L2AKB.js → header-images-SQBCE5OD.js} +21 -1
- package/dist/header-images-SQBCE5OD.js.map +1 -0
- package/dist/{health-endpoint-WJC2UMYS.js → health-endpoint-RFXL2F4A.js} +2 -2
- package/dist/health-mirror-L5JBEJVA.js +41 -0
- package/dist/health-mirror-L5JBEJVA.js.map +1 -0
- package/dist/{import-airtable-HE43FB4H.js → import-airtable-OHVY344G.js} +7 -5
- package/dist/index.d.ts +149 -0
- package/dist/index.js +147 -50
- package/dist/index.js.map +1 -1
- package/dist/{init-NJEOEO7I.js → init-XRAQZYID.js} +9 -9
- package/dist/{launch-XNAX427U.js → launch-IX4Y5JJC.js} +55 -26
- package/dist/launch-IX4Y5JJC.js.map +1 -0
- package/dist/{lighthouse-airtable-LBVIYYP5.js → lighthouse-airtable-3GUWHETW.js} +3 -3
- package/dist/{onboard-GK4PHPNI.js → onboard-O4IAHJMO.js} +2 -2
- package/dist/{orchestrate-77UO4BYJ.js → orchestrate-YLWQ6KK2.js} +10 -9
- package/dist/{parity-MWS24A3H.js → parity-56KA2DGR.js} +4 -4
- package/dist/{pipeline-S6CVHDGB.js → pipeline-3AANZFCR.js} +2 -2
- package/dist/{preflight-6WBNU2GZ.js → preflight-TNORKGCX.js} +11 -10
- package/dist/{preflight-6WBNU2GZ.js.map → preflight-TNORKGCX.js.map} +1 -1
- package/dist/{prismic-ci-3RHOZUUT.js → prismic-ci-G2AK53VL.js} +5 -5
- package/dist/{prismic-models-QBGUT2Q3.js → prismic-models-O6Z3OK3A.js} +13 -8
- package/dist/prismic-models-O6Z3OK3A.js.map +1 -0
- package/dist/prospect/types.d.ts +267 -0
- package/dist/prospect/types.js +1 -0
- package/dist/{prospect-audit-IUNCJ2LV.js → prospect-audit-KSXUNQ5J.js} +4 -4
- package/dist/recipes/sync-configs.js +2 -2
- package/dist/{render-AQAVQDPZ.js → render-IFOGFB5T.js} +3 -3
- package/dist/render-IFOGFB5T.js.map +1 -0
- package/dist/render-from-row-BWSOIYDS.js +17 -0
- package/dist/render-from-row-BWSOIYDS.js.map +1 -0
- package/dist/{renovate-dispatch-QJY75ODR.js → renovate-dispatch-6GQWTRKX.js} +10 -10
- package/dist/{renovate-dispatch-QJY75ODR.js.map → renovate-dispatch-6GQWTRKX.js.map} +1 -1
- package/dist/{report-4EVNDHOZ.js → report-R3E3Y7HR.js} +63 -21
- package/dist/report-R3E3Y7HR.js.map +1 -0
- package/dist/report-mirror-4MNORYQ4.js +49 -0
- package/dist/report-mirror-4MNORYQ4.js.map +1 -0
- package/dist/rerender-3FM6DNRH.js +32 -0
- package/dist/rerender-3FM6DNRH.js.map +1 -0
- package/dist/{self-updating-6DWI2Z56.js → self-updating-UCIWESAX.js} +2 -2
- package/dist/{selftest-RC36MTKP.js → selftest-VGHWPN72.js} +22 -20
- package/dist/{selftest-RC36MTKP.js.map → selftest-VGHWPN72.js.map} +1 -1
- package/dist/site-mirror-NIREX5ME.js +52 -0
- package/dist/site-mirror-NIREX5ME.js.map +1 -0
- package/dist/{smoke-suite-VYY2LXM2.js → smoke-suite-U3UKD3NS.js} +2 -2
- package/dist/{submissions-Q7DRFOCD.js → submissions-IQEJX6FK.js} +2 -2
- package/dist/{svelte-codemods-25J2FO22.js → svelte-codemods-GOKXTBHW.js} +2 -2
- package/dist/{sync-34HNZZ56.js → sync-CTUVXMCK.js} +4 -4
- package/dist/{sync-configs-3SE6PSCO.js → sync-configs-SPTLFJCC.js} +4 -4
- package/dist/{upgrade-WBRQ62FX.js → upgrade-W6ZR3FJH.js} +2 -2
- package/dist/{webflow-IRKOIT7S.js → webflow-624FEBFD.js} +4 -4
- package/dist/{websites-SXWTP72S.js → websites-D6WYFAES.js} +2 -2
- package/dist/websites-D6WYFAES.js.map +1 -0
- package/dist/{write-audits-to-airtable-MBEILLPU.js → write-audits-to-airtable-CMKHGJNQ.js} +4 -4
- package/dist/write-audits-to-airtable-CMKHGJNQ.js.map +1 -0
- package/package.json +5 -1
- package/dist/airtable-G7WBQQMI.js +0 -9
- package/dist/announce-MXTUQ6C7.js.map +0 -1
- package/dist/chunk-2NDRHXMR.js.map +0 -1
- package/dist/chunk-2ZPT7GLV.js.map +0 -1
- package/dist/chunk-ACBRLLFT.js.map +0 -1
- package/dist/chunk-BYK66EWO.js.map +0 -1
- package/dist/chunk-ILUNZHYV.js.map +0 -1
- package/dist/chunk-ITIOFN7A.js.map +0 -1
- package/dist/chunk-X3B723J4.js.map +0 -1
- package/dist/ensure-site-DFTB7MN3.js.map +0 -1
- package/dist/forms-notify-target-75U6OU7L.js.map +0 -1
- package/dist/header-images-335L2AKB.js.map +0 -1
- package/dist/health-mirror-4B2L7T2Y.js +0 -75
- package/dist/health-mirror-4B2L7T2Y.js.map +0 -1
- package/dist/launch-XNAX427U.js.map +0 -1
- package/dist/prismic-models-QBGUT2Q3.js.map +0 -1
- package/dist/report-4EVNDHOZ.js.map +0 -1
- /package/dist/{airtable-G7WBQQMI.js.map → airtable-ZBUPQJSC.js.map} +0 -0
- /package/dist/{import-airtable-HE43FB4H.js.map → attachments-NLZIJ5NU.js.map} +0 -0
- /package/dist/{bump-deps-EC74CPLS.js.map → bump-deps-CGVELRLK.js.map} +0 -0
- /package/dist/{chunk-KTH5ZODA.js.map → chunk-7BZUOZPU.js.map} +0 -0
- /package/dist/{chunk-3VQWSE3F.js.map → chunk-7UAYMAKR.js.map} +0 -0
- /package/dist/{chunk-SLUQ7R6I.js.map → chunk-C6CLRKPV.js.map} +0 -0
- /package/dist/{chunk-P2FE5AI6.js.map → chunk-CROKUHJB.js.map} +0 -0
- /package/dist/{chunk-W7Z3BGCI.js.map → chunk-DEWJMMG3.js.map} +0 -0
- /package/dist/{chunk-TERE5SDF.js.map → chunk-HEWSRXYV.js.map} +0 -0
- /package/dist/{chunk-Z7AXYKQB.js.map → chunk-IY6256GK.js.map} +0 -0
- /package/dist/{chunk-F5KM4LEQ.js.map → chunk-NCMZMLY7.js.map} +0 -0
- /package/dist/{chunk-PPE5KZJK.js.map → chunk-NXNPDCF3.js.map} +0 -0
- /package/dist/{chunk-N45M3FDK.js.map → chunk-SDDPUAWH.js.map} +0 -0
- /package/dist/{chunk-ZKXSX4LO.js.map → chunk-TD2NNXLZ.js.map} +0 -0
- /package/dist/{chunk-2EVEFOZY.js.map → chunk-ZBDZTJUO.js.map} +0 -0
- /package/dist/{convert-to-pnpm-6L6P74WR.js.map → convert-to-pnpm-QFJOEP5V.js.map} +0 -0
- /package/dist/{db-B35OGV3G.js.map → db-UXNIZ2RG.js.map} +0 -0
- /package/dist/{email-VTTTKKL5.js.map → email-KJXASVH5.js.map} +0 -0
- /package/dist/{lighthouse-airtable-LBVIYYP5.js.map → fleet-state-7TJ2GYT2.js.map} +0 -0
- /package/dist/{github-signals-IJUPGCUX.js.map → github-signals-E2WPYTBK.js.map} +0 -0
- /package/dist/{header-image-AWLLQA4L.js.map → header-image-6IC53W27.js.map} +0 -0
- /package/dist/{health-endpoint-WJC2UMYS.js.map → health-endpoint-RFXL2F4A.js.map} +0 -0
- /package/dist/{orchestrate-77UO4BYJ.js.map → import-airtable-OHVY344G.js.map} +0 -0
- /package/dist/{init-NJEOEO7I.js.map → init-XRAQZYID.js.map} +0 -0
- /package/dist/{parity-MWS24A3H.js.map → lighthouse-airtable-3GUWHETW.js.map} +0 -0
- /package/dist/{onboard-GK4PHPNI.js.map → onboard-O4IAHJMO.js.map} +0 -0
- /package/dist/{pipeline-S6CVHDGB.js.map → orchestrate-YLWQ6KK2.js.map} +0 -0
- /package/dist/{render-AQAVQDPZ.js.map → parity-56KA2DGR.js.map} +0 -0
- /package/dist/{websites-SXWTP72S.js.map → pipeline-3AANZFCR.js.map} +0 -0
- /package/dist/{prismic-ci-3RHOZUUT.js.map → prismic-ci-G2AK53VL.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-MBEILLPU.js.map → prospect/types.js.map} +0 -0
- /package/dist/{prospect-audit-IUNCJ2LV.js.map → prospect-audit-KSXUNQ5J.js.map} +0 -0
- /package/dist/{self-updating-6DWI2Z56.js.map → self-updating-UCIWESAX.js.map} +0 -0
- /package/dist/{smoke-suite-VYY2LXM2.js.map → smoke-suite-U3UKD3NS.js.map} +0 -0
- /package/dist/{submissions-Q7DRFOCD.js.map → submissions-IQEJX6FK.js.map} +0 -0
- /package/dist/{svelte-codemods-25J2FO22.js.map → svelte-codemods-GOKXTBHW.js.map} +0 -0
- /package/dist/{sync-34HNZZ56.js.map → sync-CTUVXMCK.js.map} +0 -0
- /package/dist/{sync-configs-3SE6PSCO.js.map → sync-configs-SPTLFJCC.js.map} +0 -0
- /package/dist/{upgrade-WBRQ62FX.js.map → upgrade-W6ZR3FJH.js.map} +0 -0
- /package/dist/{webflow-IRKOIT7S.js.map → webflow-624FEBFD.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import "./chunk-2SLED3NB.js";
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-NCMZMLY7.js";
|
|
3
3
|
import {
|
|
4
4
|
draftReportForSite
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BBUSGEES.js";
|
|
6
6
|
import {
|
|
7
7
|
approveBlockers
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SDDPUAWH.js";
|
|
9
9
|
import {
|
|
10
10
|
findDueReports
|
|
11
11
|
} from "./chunk-PZR4EBPY.js";
|
|
12
|
-
import {
|
|
13
|
-
upgradeSvelte4to5
|
|
14
|
-
} from "./chunk-Z3KYFUN6.js";
|
|
15
12
|
import {
|
|
16
13
|
DEFAULT_INIT_STEPS,
|
|
17
14
|
a11yFixturesPage,
|
|
18
15
|
init
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import {
|
|
21
|
-
convertToPnpm
|
|
22
|
-
} from "./chunk-XIDUYLSR.js";
|
|
23
|
-
import {
|
|
24
|
-
svelteCodemods
|
|
25
|
-
} from "./chunk-IYSEC543.js";
|
|
26
|
-
import "./chunk-J7SZQUCW.js";
|
|
16
|
+
} from "./chunk-TD2NNXLZ.js";
|
|
27
17
|
import "./chunk-BQRFQSGY.js";
|
|
28
18
|
import "./chunk-Y53WOQIJ.js";
|
|
29
19
|
import {
|
|
@@ -31,53 +21,71 @@ import {
|
|
|
31
21
|
selfCaretRange,
|
|
32
22
|
selfPackageVersion
|
|
33
23
|
} from "./chunk-7RJ2HMMJ.js";
|
|
34
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-YFAXOD7Z.js";
|
|
35
25
|
import {
|
|
36
26
|
bumpDeps
|
|
37
27
|
} from "./chunk-2NJQLSEU.js";
|
|
38
28
|
import "./chunk-R53VL3RI.js";
|
|
39
29
|
import {
|
|
40
|
-
|
|
41
|
-
} from "./chunk-
|
|
30
|
+
upgradeSvelte4to5
|
|
31
|
+
} from "./chunk-Z3KYFUN6.js";
|
|
32
|
+
import {
|
|
33
|
+
convertToPnpm
|
|
34
|
+
} from "./chunk-XIDUYLSR.js";
|
|
35
|
+
import {
|
|
36
|
+
svelteCodemods
|
|
37
|
+
} from "./chunk-IYSEC543.js";
|
|
38
|
+
import "./chunk-J7SZQUCW.js";
|
|
42
39
|
import {
|
|
43
40
|
parseAddresses,
|
|
44
41
|
sendApprovedReports,
|
|
45
42
|
withGlobalCc
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import "./chunk-
|
|
43
|
+
} from "./chunk-NDWYJLRF.js";
|
|
44
|
+
import "./chunk-NYUYNYQL.js";
|
|
48
45
|
import {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
isPendingApproval
|
|
47
|
+
} from "./chunk-F3JWOPTG.js";
|
|
48
|
+
import {
|
|
49
|
+
checklistFor,
|
|
50
|
+
gatingFields,
|
|
51
|
+
isHealthGateClear
|
|
52
|
+
} from "./chunk-VAD43MOR.js";
|
|
53
|
+
import {
|
|
54
|
+
fromAirtableBase
|
|
55
|
+
} from "./chunk-C6CLRKPV.js";
|
|
56
|
+
import "./chunk-IY6256GK.js";
|
|
57
|
+
import "./chunk-HN6I2XWI.js";
|
|
58
|
+
import "./chunk-ZGBEIWSC.js";
|
|
59
|
+
import "./chunk-GECESMVS.js";
|
|
54
60
|
import {
|
|
55
61
|
BLURRED_CID,
|
|
56
62
|
CHECK_CID,
|
|
57
63
|
loadBundledImages,
|
|
58
|
-
renderReportHtml
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
renderReportHtml,
|
|
65
|
+
rendersCommentary
|
|
66
|
+
} from "./chunk-MT2JINSS.js";
|
|
61
67
|
import {
|
|
62
68
|
escapeHtml,
|
|
63
69
|
safeUrl
|
|
64
70
|
} from "./chunk-DJZWYIPP.js";
|
|
65
71
|
import {
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
domainFromUrl,
|
|
73
|
+
generateHeaderImage,
|
|
74
|
+
loadHeadline,
|
|
75
|
+
loadPlate
|
|
76
|
+
} from "./chunk-5UINJNAJ.js";
|
|
68
77
|
import {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
CANONICAL_STATUSES,
|
|
79
|
+
SEVERITY_RANK,
|
|
80
|
+
siteSlug,
|
|
81
|
+
toAirtableStatus
|
|
82
|
+
} from "./chunk-7NYN2P6I.js";
|
|
74
83
|
import "./chunk-WEKL2HYJ.js";
|
|
75
|
-
import "./chunk-NYUYNYQL.js";
|
|
76
84
|
import {
|
|
77
85
|
syncConfigs
|
|
78
|
-
} from "./chunk-
|
|
79
|
-
import "./chunk-3G25KIWW.js";
|
|
86
|
+
} from "./chunk-7UAYMAKR.js";
|
|
80
87
|
import "./chunk-73UFRZKY.js";
|
|
88
|
+
import "./chunk-3G25KIWW.js";
|
|
81
89
|
import "./chunk-OTGB6YQO.js";
|
|
82
90
|
import {
|
|
83
91
|
ALL_AUDIT_NAMES,
|
|
@@ -87,7 +95,7 @@ import {
|
|
|
87
95
|
runAudits,
|
|
88
96
|
runAuditsAcross,
|
|
89
97
|
securityAudit
|
|
90
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-3JQ2FO3D.js";
|
|
91
99
|
import "./chunk-LKGVSM2O.js";
|
|
92
100
|
import "./chunk-GASBX52O.js";
|
|
93
101
|
import "./chunk-XHHMM5HX.js";
|
|
@@ -111,12 +119,6 @@ import "./chunk-UDRHAQT7.js";
|
|
|
111
119
|
import "./chunk-PTDMVGKL.js";
|
|
112
120
|
import "./chunk-LBYOLBW7.js";
|
|
113
121
|
import "./chunk-XXTZBPUY.js";
|
|
114
|
-
import {
|
|
115
|
-
CANONICAL_STATUSES,
|
|
116
|
-
SEVERITY_RANK,
|
|
117
|
-
siteSlug,
|
|
118
|
-
toAirtableStatus
|
|
119
|
-
} from "./chunk-LDWZSLSU.js";
|
|
120
122
|
import "./chunk-6VAL7XJT.js";
|
|
121
123
|
import "./chunk-NMAWXBJA.js";
|
|
122
124
|
import "./chunk-C6B4RHXR.js";
|
|
@@ -314,6 +316,14 @@ var SUBMISSION_STATUS_SCRIPT = `document.querySelectorAll("button.subm-status").
|
|
|
314
316
|
// src/dashboard/site-details.ts
|
|
315
317
|
var SITE_STATUS_OPTIONS = CANONICAL_STATUSES.map(toAirtableStatus);
|
|
316
318
|
var FREQ_OPTIONS = ["None", "Monthly", "Quarterly", "Yearly"];
|
|
319
|
+
var WATCH_CONDITION_OPTIONS = [
|
|
320
|
+
"Performance",
|
|
321
|
+
"Accessibility",
|
|
322
|
+
"Best Practices",
|
|
323
|
+
"SEO",
|
|
324
|
+
"stale repo",
|
|
325
|
+
"no custom domain"
|
|
326
|
+
];
|
|
317
327
|
|
|
318
328
|
// src/dashboard/render.ts
|
|
319
329
|
var DASH = "\u2014";
|
|
@@ -465,14 +475,27 @@ function recipientsLine(site) {
|
|
|
465
475
|
const ccPart = cc.length > 0 ? ` \xB7 CC ${cc.map(escapeHtml).join(", ")}` : "";
|
|
466
476
|
return `<span class="recipients">To ${to.map(escapeHtml).join(", ")}${ccPart}</span>`;
|
|
467
477
|
}
|
|
478
|
+
function rerenderButton(r) {
|
|
479
|
+
if (r.sentAt !== null) return "";
|
|
480
|
+
const url = `/api/reports/${encodeURIComponent(r.id)}/rerender`;
|
|
481
|
+
return `<button class="rerender" data-rerender-url="${escapeHtml(url)}" title="Re-render this report from its current row (runs in Actions; takes a minute or two)">refresh preview</button>`;
|
|
482
|
+
}
|
|
483
|
+
function reportPreviewUrl(reportId) {
|
|
484
|
+
return `/api/reports/${encodeURIComponent(reportId)}/preview`;
|
|
485
|
+
}
|
|
486
|
+
function commentaryEditor(r) {
|
|
487
|
+
if (!rendersCommentary(r.reportType)) return "";
|
|
488
|
+
const url = `/api/reports/${encodeURIComponent(r.id)}/commentary`;
|
|
489
|
+
return `<div class="commentary"><label for="commentary-${escapeHtml(r.id)}">Commentary <span class="muted">(re-rendered into the email at send)</span></label><textarea id="commentary-${escapeHtml(r.id)}" data-commentary-for="${escapeHtml(r.id)}" data-commentary-url="${escapeHtml(url)}" rows="3">${escapeHtml(r.commentary ?? "")}</textarea><span class="commentary-saved" data-for="${escapeHtml(r.id)}"></span></div>`;
|
|
490
|
+
}
|
|
468
491
|
function pendingRow(r, site, now) {
|
|
469
492
|
const type = escapeHtml(r.reportType);
|
|
470
493
|
const period = r.period ? escapeHtml(r.period) : "\u2014";
|
|
471
494
|
const findings = approveBlockers(site, r);
|
|
472
495
|
const blocked = findings.some((f) => f.level === "fail");
|
|
473
|
-
const preview = r.renderedHtmlAttachment ? `<a href="${escapeHtml(
|
|
496
|
+
const preview = r.renderedHtmlAttachment ? `<a href="${escapeHtml(reportPreviewUrl(r.id))}" rel="noopener noreferrer" title="rendered at draft time \u2014 Commentary/subject edits after drafting are not reflected">draft preview \u25B8</a>` : `<span class="muted">no preview yet</span>`;
|
|
474
497
|
const sendLine = sendTimingLine(now);
|
|
475
|
-
return `<li><div class="pending-head"><strong>${type}</strong> <span class="muted">${period}</span> ${preflightChip(findings)} ${preview} ${approveButton(r, blocked)}</div><div class="pending-info">${recipientsLine(site)} ${sendLine}</div>${checklistBlock(r)}${overrideControl(r)}</li>`;
|
|
498
|
+
return `<li><div class="pending-head"><strong>${type}</strong> <span class="muted">${period}</span> ${preflightChip(findings)} ${preview} ${rerenderButton(r)} ${approveButton(r, blocked)}</div><div class="pending-info">${recipientsLine(site)} ${sendLine}</div>${checklistBlock(r)}${commentaryEditor(r)}${overrideControl(r)}</li>`;
|
|
476
499
|
}
|
|
477
500
|
function pendingSection(reports, site, now) {
|
|
478
501
|
const pending = reports.filter(isPendingApproval);
|
|
@@ -502,12 +525,13 @@ function reportRow(r, site) {
|
|
|
502
525
|
const id = escapeHtml(r.reportId);
|
|
503
526
|
const ga = gaUsersCell(r);
|
|
504
527
|
const search = searchCell(r);
|
|
505
|
-
const link = r.renderedHtmlAttachment ? `<a href="${escapeHtml(
|
|
528
|
+
const link = r.renderedHtmlAttachment ? `<a href="${escapeHtml(reportPreviewUrl(r.id))}">view</a>` : `<span class="muted">no attachment</span>`;
|
|
506
529
|
const action = isPendingApproval(r) ? approveButton(
|
|
507
530
|
r,
|
|
508
531
|
approveBlockers(site, r).some((f) => f.level === "fail")
|
|
509
532
|
) : "";
|
|
510
|
-
|
|
533
|
+
const commentary = r.sentAt === null && !isPendingApproval(r) ? `<tr class="commentary-row"><td colspan="7">${commentaryEditor(r)}</td></tr>` : "";
|
|
534
|
+
return `<tr><td>${date}</td><td>${type}</td><td><code>${id}</code></td><td>${ga}</td><td>${search}</td><td>${link}</td><td>${action}</td></tr>${commentary}`;
|
|
511
535
|
}
|
|
512
536
|
var SUBMISSIONS_PER_SITE_CAP = 25;
|
|
513
537
|
function submissionsSection(submissions, site) {
|
|
@@ -586,9 +610,28 @@ function selectRow(label, field, options, current, url) {
|
|
|
586
610
|
function inputRow(label, field, value, url) {
|
|
587
611
|
return `<div class="detail"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><input type="text" id="detail-${field}" data-detail-field="${field}" data-details-url="${url}" value="${escapeHtml(value ?? "")}" />${savedSpan(field)}</dd></div>`;
|
|
588
612
|
}
|
|
613
|
+
var DETAIL_VALUE_FN = `function detailValue(el) {
|
|
614
|
+
if (el.type === "checkbox") return el.checked ? "true" : "false";
|
|
615
|
+
if (el.multiple) return Array.from(el.selectedOptions).map((o) => o.value).join(",");
|
|
616
|
+
return el.value;
|
|
617
|
+
}`;
|
|
589
618
|
function dateRow(label, field, value, url) {
|
|
590
619
|
return `<div class="detail"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><input type="date" id="detail-${field}" data-detail-field="${field}" data-details-url="${url}" value="${escapeHtml(value ?? "")}" />${savedSpan(field)}</dd></div>`;
|
|
591
620
|
}
|
|
621
|
+
function checkboxRow(label, field, checked, url) {
|
|
622
|
+
return `<div class="detail"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><input type="checkbox" id="detail-${field}" data-detail-field="${field}" data-details-url="${url}"${checked ? " checked" : ""} />${savedSpan(field)}</dd></div>`;
|
|
623
|
+
}
|
|
624
|
+
function multiSelectRow(label, field, options, selected, url) {
|
|
625
|
+
const sel = new Set(selected);
|
|
626
|
+
const opts = options.map(
|
|
627
|
+
(o) => `<option value="${escapeHtml(o)}"${sel.has(o) ? " selected" : ""}>${escapeHtml(o)}</option>`
|
|
628
|
+
).join("");
|
|
629
|
+
return `<div class="detail wide"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><select multiple id="detail-${field}" data-detail-field="${field}" data-details-url="${url}">${opts}</select>${savedSpan(field)}</dd></div>`;
|
|
630
|
+
}
|
|
631
|
+
function secretRow(label, field, isSet, url) {
|
|
632
|
+
const ph = isSet ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022 (set \u2014 type to replace)" : "not set";
|
|
633
|
+
return `<div class="detail"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><input type="password" autocomplete="off" id="detail-${field}" data-detail-field="${field}" data-details-url="${url}" placeholder="${escapeHtml(ph)}" />${savedSpan(field)}</dd></div>`;
|
|
634
|
+
}
|
|
592
635
|
function textareaRow(label, field, value, url) {
|
|
593
636
|
return `<div class="detail wide"><dt><label for="detail-${field}">${escapeHtml(label)}</label></dt><dd><textarea id="detail-${field}" data-detail-field="${field}" data-details-url="${url}">${escapeHtml(value ?? "")}</textarea>${savedSpan(field)}</dd></div>`;
|
|
594
637
|
}
|
|
@@ -621,6 +664,15 @@ function siteDetailsSection(site) {
|
|
|
621
664
|
// Raw JSON, and shown as the raw cell rather than the parsed object: what the
|
|
622
665
|
// operator edits has to be the thing `parseNotifyRouting` will read back.
|
|
623
666
|
textareaRow("Notify routing (JSON)", "notifyRouting", site.notifyRoutingRaw, url),
|
|
667
|
+
checkboxRow("Require Turnstile", "requireTurnstile", site.requireTurnstile, url),
|
|
668
|
+
secretRow("Mailchimp API key", "mailchimpApiKey", site.mailchimpApiKey !== null, url),
|
|
669
|
+
multiSelectRow(
|
|
670
|
+
"Accepted watch conditions",
|
|
671
|
+
"acceptedWatchConditions",
|
|
672
|
+
WATCH_CONDITION_OPTIONS,
|
|
673
|
+
site.acceptedWatchConditions,
|
|
674
|
+
url
|
|
675
|
+
),
|
|
624
676
|
textareaRow("Copy \u2014 Intro", "copyIntro", site.copyIntro, url),
|
|
625
677
|
textareaRow("Copy \u2014 Contact", "copyContact", site.copyContact, url),
|
|
626
678
|
textareaRow("Copy \u2014 Footer", "copyFooter", site.copyFooter, url),
|
|
@@ -963,12 +1015,13 @@ function renderSiteDashboardHtml(site, reports, submissions = [], spamTotals = n
|
|
|
963
1015
|
});
|
|
964
1016
|
// Site-details editor: save on change (selects) / blur (inputs+textareas, only
|
|
965
1017
|
// when the value actually changed). The per-field span shows \u2713 / \u2717.
|
|
1018
|
+
${DETAIL_VALUE_FN}
|
|
966
1019
|
function saveDetail(el) {
|
|
967
1020
|
const span = document.querySelector('.detail-saved[data-for="' + el.dataset.detailField + '"]');
|
|
968
1021
|
fetch(el.dataset.detailsUrl, {
|
|
969
1022
|
method: "POST",
|
|
970
1023
|
headers: { "content-type": "application/json" },
|
|
971
|
-
body: JSON.stringify({ field: el.dataset.detailField, value: el
|
|
1024
|
+
body: JSON.stringify({ field: el.dataset.detailField, value: detailValue(el) }),
|
|
972
1025
|
})
|
|
973
1026
|
.then((r) => {
|
|
974
1027
|
if (span) span.textContent = r.ok ? " \u2713" : " \u2717";
|
|
@@ -980,11 +1033,55 @@ function renderSiteDashboardHtml(site, reports, submissions = [], spamTotals = n
|
|
|
980
1033
|
document.querySelectorAll("select[data-detail-field]").forEach((s) => {
|
|
981
1034
|
s.addEventListener("change", () => saveDetail(s));
|
|
982
1035
|
});
|
|
983
|
-
|
|
1036
|
+
// Checkboxes save on CHANGE. They cannot use the blur path below: that path
|
|
1037
|
+
// only fires when \`value !== defaultValue\`, and for a checkbox both are the
|
|
1038
|
+
// "on" content attribute, so it would never save at all.
|
|
1039
|
+
document.querySelectorAll("input[type=checkbox][data-detail-field]").forEach((c) => {
|
|
1040
|
+
c.addEventListener("change", () => saveDetail(c));
|
|
1041
|
+
});
|
|
1042
|
+
document.querySelectorAll("input:not([type=checkbox])[data-detail-field], textarea[data-detail-field]").forEach((i) => {
|
|
984
1043
|
i.addEventListener("blur", () => {
|
|
985
1044
|
if (i.value !== i.defaultValue) saveDetail(i);
|
|
986
1045
|
});
|
|
987
1046
|
});
|
|
1047
|
+
// Refresh preview: dispatch the re-render workflow, then tell the operator to
|
|
1048
|
+
// reload once it lands. No polling \u2014 the run takes a minute or two and a
|
|
1049
|
+
// spinner that long reads as a hang.
|
|
1050
|
+
document.querySelectorAll("button.rerender").forEach((b) => {
|
|
1051
|
+
b.addEventListener("click", async () => {
|
|
1052
|
+
b.disabled = true;
|
|
1053
|
+
b.textContent = "Refreshing\u2026";
|
|
1054
|
+
try {
|
|
1055
|
+
const res = await fetch(b.dataset.rerenderUrl, { method: "POST" });
|
|
1056
|
+
b.textContent = res.ok ? "Queued \u2713 reload in ~2 min" : "Failed";
|
|
1057
|
+
if (!res.ok) b.disabled = false;
|
|
1058
|
+
} catch {
|
|
1059
|
+
b.textContent = "Failed";
|
|
1060
|
+
b.disabled = false;
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
});
|
|
1064
|
+
// Report commentary: save on blur, only when it actually changed. Same
|
|
1065
|
+
// shape as the site-details editor, but keyed on the REPORT id rather than a
|
|
1066
|
+
// field name, so it posts { text } to the report's own endpoint.
|
|
1067
|
+
document.querySelectorAll("textarea[data-commentary-for]").forEach((t) => {
|
|
1068
|
+
t.addEventListener("blur", () => {
|
|
1069
|
+
if (t.value === t.defaultValue) return;
|
|
1070
|
+
const span = document.querySelector('.commentary-saved[data-for="' + t.dataset.commentaryFor + '"]');
|
|
1071
|
+
fetch(t.dataset.commentaryUrl, {
|
|
1072
|
+
method: "POST",
|
|
1073
|
+
headers: { "content-type": "application/json" },
|
|
1074
|
+
body: JSON.stringify({ text: t.value }),
|
|
1075
|
+
})
|
|
1076
|
+
.then((r) => {
|
|
1077
|
+
if (span) span.textContent = r.ok ? " \u2713" : " \u2717";
|
|
1078
|
+
if (r.ok) t.defaultValue = t.value;
|
|
1079
|
+
})
|
|
1080
|
+
.catch(() => {
|
|
1081
|
+
if (span) span.textContent = " \u2717";
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
988
1085
|
${SUBMISSION_STATUS_SCRIPT}
|
|
989
1086
|
</script>
|
|
990
1087
|
</body>
|