@simmalugnt-se/payload-content-health 0.5.2 → 0.6.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/CHANGELOG.md +13 -0
- package/README.md +17 -9
- package/dist/categories.d.ts +21 -0
- package/dist/categories.js +43 -0
- package/dist/copy.d.ts +12 -17
- package/dist/copy.js +19 -65
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/links.d.ts +6 -0
- package/dist/links.js +8 -2
- package/dist/styles/tokens.css +26 -0
- package/dist/styles/view.css +157 -74
- package/dist/styles/widget.css +71 -85
- package/dist/view/ContentHealthView.d.ts +4 -3
- package/dist/view/ContentHealthView.js +32 -9
- package/dist/view/WorkList.d.ts +12 -5
- package/dist/view/WorkList.js +47 -11
- package/dist/widget/ContentHealthWidget.d.ts +3 -2
- package/dist/widget/ContentHealthWidget.js +16 -29
- package/package.json +1 -1
package/dist/styles/view.css
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
/* The work list. Colors come from Payload's theme;
|
|
1
|
+
/* The work list. Colors come from Payload's theme; tokens.css has the accent, red and amber. */
|
|
2
2
|
.content-health-list {
|
|
3
|
-
--content-health-accent: #2563eb;
|
|
4
|
-
--content-health-control-height: calc(var(--base) * 1.6);
|
|
5
3
|
padding-bottom: calc(var(--base) * 2);
|
|
6
4
|
}
|
|
7
5
|
|
|
8
|
-
html[data-theme="dark"] .content-health-list {
|
|
9
|
-
--content-health-accent: #60a5fa;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
6
|
.content-health-list__header {
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
gap: calc(var(--base) * 1.1);
|
|
13
10
|
padding: calc(var(--base) * 1.5) 0 var(--base);
|
|
14
11
|
}
|
|
15
12
|
|
|
@@ -17,22 +14,121 @@ html[data-theme="dark"] .content-health-list {
|
|
|
17
14
|
margin: 0;
|
|
18
15
|
}
|
|
19
16
|
|
|
17
|
+
.content-health-list__ring {
|
|
18
|
+
flex: none;
|
|
19
|
+
width: 5rem;
|
|
20
|
+
height: 5rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.content-health-list__ring .content-health__ring-track,
|
|
24
|
+
.content-health-list__ring-track {
|
|
25
|
+
stroke: var(--theme-elevation-100);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.content-health-list__ring .content-health__ring-ok {
|
|
29
|
+
stroke: var(--content-health-accent);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.content-health-list__ring .content-health__ring-value {
|
|
33
|
+
fill: var(--theme-text);
|
|
34
|
+
font-size: 24px;
|
|
35
|
+
font-weight: 600;
|
|
36
|
+
font-variant-numeric: tabular-nums;
|
|
37
|
+
}
|
|
38
|
+
|
|
20
39
|
.content-health-list__intro {
|
|
21
|
-
margin: calc(var(--base) * 0.
|
|
22
|
-
|
|
40
|
+
margin: calc(var(--base) * 0.25) 0 0;
|
|
41
|
+
color: var(--theme-elevation-600);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Category tabs: the selected one is filled with the accent tint and outlined in the accent. */
|
|
45
|
+
.content-health-list__tabs {
|
|
46
|
+
display: grid;
|
|
47
|
+
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
|
|
48
|
+
gap: calc(var(--base) * 0.6);
|
|
49
|
+
margin-bottom: var(--base);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.content-health-list__tab {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
align-items: flex-start;
|
|
56
|
+
gap: calc(var(--base) * 0.15);
|
|
57
|
+
padding: calc(var(--base) * 0.6) calc(var(--base) * 0.75);
|
|
58
|
+
border: 1px solid var(--theme-elevation-150);
|
|
59
|
+
border-radius: var(--style-radius-m);
|
|
60
|
+
background: var(--theme-elevation-0);
|
|
23
61
|
color: var(--theme-elevation-600);
|
|
62
|
+
font: inherit;
|
|
63
|
+
text-align: start;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.content-health-list__tab:hover {
|
|
68
|
+
border-color: var(--theme-elevation-400);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.content-health-list__tab:focus-visible {
|
|
72
|
+
outline: 2px solid var(--content-health-accent);
|
|
73
|
+
outline-offset: 2px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.content-health-list__tab--selected,
|
|
77
|
+
.content-health-list__tab--selected:hover {
|
|
78
|
+
border-color: var(--content-health-accent);
|
|
79
|
+
background: var(--content-health-accent-tint);
|
|
80
|
+
color: var(--theme-text);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.content-health-list__tab-name {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: calc(var(--base) * 0.3);
|
|
87
|
+
font-size: 0.9em;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.content-health-list__tab--selected .content-health-list__tab-name {
|
|
91
|
+
font-weight: 600;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.content-health-list__tab-count {
|
|
95
|
+
color: var(--theme-text);
|
|
96
|
+
font-size: 1.6rem;
|
|
97
|
+
font-weight: 600;
|
|
98
|
+
line-height: 1.2;
|
|
99
|
+
font-variant-numeric: tabular-nums;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.content-health-list__dot {
|
|
103
|
+
width: 8px;
|
|
104
|
+
height: 8px;
|
|
105
|
+
border-radius: 50%;
|
|
106
|
+
background: var(--content-health-accent);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.content-health-list__dot--bad {
|
|
110
|
+
background: var(--content-health-bad);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.content-health-list__dot--warn {
|
|
114
|
+
background: var(--content-health-warn);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.content-health-list__dot--none {
|
|
118
|
+
background: var(--theme-elevation-400);
|
|
24
119
|
}
|
|
25
120
|
|
|
26
121
|
.content-health-list__filters {
|
|
27
122
|
display: flex;
|
|
28
123
|
flex-wrap: wrap;
|
|
29
|
-
|
|
124
|
+
justify-content: flex-end;
|
|
30
125
|
gap: calc(var(--base) * 0.75);
|
|
126
|
+
margin-bottom: var(--base);
|
|
31
127
|
}
|
|
32
128
|
|
|
33
129
|
.content-health-list__filter {
|
|
34
130
|
display: flex;
|
|
35
|
-
flex:
|
|
131
|
+
flex: 0 1 12rem;
|
|
36
132
|
min-width: 0;
|
|
37
133
|
flex-direction: column;
|
|
38
134
|
gap: calc(var(--base) * 0.25);
|
|
@@ -46,97 +142,90 @@ html[data-theme="dark"] .content-health-list {
|
|
|
46
142
|
|
|
47
143
|
.content-health-list__filter .rs__control {
|
|
48
144
|
box-sizing: border-box;
|
|
49
|
-
min-height: var(--
|
|
50
|
-
height: var(--
|
|
145
|
+
min-height: calc(var(--base) * 1.6);
|
|
146
|
+
height: calc(var(--base) * 1.6);
|
|
51
147
|
padding: 0 calc(var(--base) * 0.5);
|
|
52
148
|
}
|
|
53
149
|
|
|
54
|
-
.
|
|
55
|
-
.content-health-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
box-sizing: border-box;
|
|
61
|
-
min-height: var(--content-health-control-height);
|
|
62
|
-
padding-inline: calc(var(--base) * 0.6);
|
|
150
|
+
/* One section per check inside the selected category. */
|
|
151
|
+
.content-health-list__panel {
|
|
152
|
+
border: 1px solid var(--theme-elevation-150);
|
|
153
|
+
border-radius: var(--style-radius-m);
|
|
154
|
+
background: var(--theme-elevation-0);
|
|
155
|
+
padding: 0 calc(var(--base) * 1.25);
|
|
63
156
|
}
|
|
64
157
|
|
|
65
|
-
.content-health-
|
|
66
|
-
|
|
67
|
-
|
|
158
|
+
.content-health-list__section {
|
|
159
|
+
padding: var(--base) 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.content-health-list__section + .content-health-list__section {
|
|
163
|
+
border-top: 1px solid var(--theme-elevation-100);
|
|
68
164
|
}
|
|
69
165
|
|
|
70
|
-
.content-health-
|
|
166
|
+
.content-health-list__section-head {
|
|
71
167
|
display: flex;
|
|
72
168
|
flex-wrap: wrap;
|
|
73
|
-
gap: calc(var(--base) * 0.5) var(--base);
|
|
74
169
|
align-items: center;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
margin: var(--base) 0 calc(var(--base) * 0.75);
|
|
78
|
-
color: var(--theme-elevation-600);
|
|
170
|
+
gap: calc(var(--base) * 0.5);
|
|
171
|
+
margin-bottom: calc(var(--base) * 0.4);
|
|
79
172
|
}
|
|
80
173
|
|
|
81
|
-
.content-health-
|
|
174
|
+
.content-health-list__section-head h2 {
|
|
82
175
|
margin: 0;
|
|
176
|
+
font-size: 1rem;
|
|
177
|
+
font-weight: 600;
|
|
83
178
|
}
|
|
84
179
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
display: grid;
|
|
88
|
-
grid-template-columns: minmax(12rem, 1fr) minmax(12rem, 1.5fr) auto;
|
|
89
|
-
margin: 0;
|
|
90
|
-
padding: 0;
|
|
91
|
-
list-style: none;
|
|
92
|
-
border: 1px solid var(--theme-elevation-150);
|
|
93
|
-
border-radius: var(--style-radius-m);
|
|
94
|
-
background: var(--theme-elevation-0);
|
|
180
|
+
.content-health-list__batch {
|
|
181
|
+
margin-inline-start: auto;
|
|
95
182
|
}
|
|
96
183
|
|
|
97
|
-
.content-health-
|
|
98
|
-
display:
|
|
99
|
-
grid-column: 1 / -1;
|
|
100
|
-
grid-template-columns: subgrid;
|
|
184
|
+
.content-health-list__section-head .btn {
|
|
185
|
+
display: inline-flex;
|
|
101
186
|
align-items: center;
|
|
102
|
-
|
|
103
|
-
|
|
187
|
+
justify-content: center;
|
|
188
|
+
min-height: calc(var(--base) * 1.6);
|
|
189
|
+
padding-inline: calc(var(--base) * 0.6);
|
|
104
190
|
}
|
|
105
191
|
|
|
106
|
-
.content-health-
|
|
107
|
-
|
|
192
|
+
.content-health-list__items {
|
|
193
|
+
margin: 0;
|
|
194
|
+
padding: 0;
|
|
195
|
+
list-style: none;
|
|
108
196
|
}
|
|
109
197
|
|
|
110
|
-
.content-health-
|
|
111
|
-
.content-health-list__document {
|
|
198
|
+
.content-health-list__item {
|
|
112
199
|
display: flex;
|
|
113
200
|
flex-wrap: wrap;
|
|
114
201
|
align-items: baseline;
|
|
115
202
|
gap: calc(var(--base) * 0.25) calc(var(--base) * 0.5);
|
|
116
|
-
|
|
203
|
+
padding: calc(var(--base) * 0.25) 0;
|
|
117
204
|
}
|
|
118
205
|
|
|
119
|
-
.content-health-
|
|
120
|
-
|
|
121
|
-
|
|
206
|
+
.content-health-list__item a {
|
|
207
|
+
color: var(--content-health-accent-text);
|
|
208
|
+
text-decoration: none;
|
|
122
209
|
}
|
|
123
210
|
|
|
124
|
-
.content-health-
|
|
125
|
-
|
|
211
|
+
.content-health-list__item a:hover {
|
|
212
|
+
text-decoration: underline;
|
|
126
213
|
}
|
|
127
214
|
|
|
128
|
-
.
|
|
215
|
+
/* The assistant link sits at the end of the row and stays quiet next to the batch button. */
|
|
216
|
+
.content-health-list__item a.content-health-list__fix {
|
|
217
|
+
margin-inline-start: auto;
|
|
129
218
|
color: var(--theme-elevation-600);
|
|
130
219
|
font-size: 0.9em;
|
|
131
220
|
}
|
|
132
221
|
|
|
133
|
-
.content-health-
|
|
134
|
-
color: var(--content-health-accent);
|
|
135
|
-
text-decoration: none;
|
|
222
|
+
.content-health-list__item a.content-health-list__fix:hover {
|
|
223
|
+
color: var(--content-health-accent-text);
|
|
136
224
|
}
|
|
137
225
|
|
|
138
|
-
.content-health-
|
|
139
|
-
|
|
226
|
+
.content-health-list__detail {
|
|
227
|
+
color: var(--theme-elevation-600);
|
|
228
|
+
font-size: 0.9em;
|
|
140
229
|
}
|
|
141
230
|
|
|
142
231
|
.content-health-list__pill {
|
|
@@ -152,11 +241,9 @@ html[data-theme="dark"] .content-health-list {
|
|
|
152
241
|
text-transform: none;
|
|
153
242
|
}
|
|
154
243
|
|
|
155
|
-
.content-health-list__actions {
|
|
156
|
-
justify-self: end;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
244
|
.content-health-list__empty {
|
|
245
|
+
margin: 0;
|
|
246
|
+
padding: var(--base) 0;
|
|
160
247
|
color: var(--theme-elevation-600);
|
|
161
248
|
}
|
|
162
249
|
|
|
@@ -166,11 +253,7 @@ html[data-theme="dark"] .content-health-list {
|
|
|
166
253
|
}
|
|
167
254
|
|
|
168
255
|
@media (max-width: 768px) {
|
|
169
|
-
.content-health-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.content-health-list__actions {
|
|
174
|
-
justify-self: start;
|
|
256
|
+
.content-health-list__panel {
|
|
257
|
+
padding: 0 var(--base);
|
|
175
258
|
}
|
|
176
259
|
}
|
package/dist/styles/widget.css
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/* Laid out like Payload's collection cards: a section heading, then the content. */
|
|
2
|
-
/* The accent is the blue the editor assistant and visual editing use. */
|
|
3
2
|
.content-health {
|
|
4
|
-
--content-health-accent: #2563eb;
|
|
5
3
|
display: flex;
|
|
6
4
|
flex-direction: column;
|
|
7
5
|
gap: var(--base);
|
|
@@ -17,7 +15,7 @@
|
|
|
17
15
|
.content-health__panel {
|
|
18
16
|
display: flex;
|
|
19
17
|
flex-direction: column;
|
|
20
|
-
gap:
|
|
18
|
+
gap: var(--base);
|
|
21
19
|
padding: calc(var(--base) * 1.25);
|
|
22
20
|
border: 1px solid var(--theme-elevation-150);
|
|
23
21
|
border-radius: var(--style-radius-m);
|
|
@@ -27,7 +25,12 @@
|
|
|
27
25
|
.content-health__overview {
|
|
28
26
|
display: flex;
|
|
29
27
|
align-items: center;
|
|
30
|
-
gap: calc(var(--base) * 1.
|
|
28
|
+
gap: calc(var(--base) * 1.1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.content-health__overview-text {
|
|
32
|
+
flex: 1;
|
|
33
|
+
min-width: 0;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
.content-health__overall {
|
|
@@ -41,30 +44,21 @@
|
|
|
41
44
|
color: var(--theme-elevation-600);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
/*
|
|
47
|
+
/* The ring */
|
|
45
48
|
.content-health__ring {
|
|
46
49
|
flex: none;
|
|
47
|
-
width:
|
|
48
|
-
height:
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.content-health__ring--large {
|
|
52
|
-
width: 7.5rem;
|
|
53
|
-
height: 7.5rem;
|
|
50
|
+
width: 5rem;
|
|
51
|
+
height: 5rem;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
.content-health__ring-track {
|
|
57
|
-
stroke: var(--theme-elevation-
|
|
55
|
+
stroke: var(--theme-elevation-100);
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
.content-health__ring-ok {
|
|
61
59
|
stroke: var(--content-health-accent);
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
html[data-theme="dark"] .content-health {
|
|
65
|
-
--content-health-accent: #60a5fa;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
62
|
.content-health__ring-value {
|
|
69
63
|
fill: var(--theme-text);
|
|
70
64
|
/* viewBox units: scales with the ring. */
|
|
@@ -73,98 +67,79 @@ html[data-theme="dark"] .content-health {
|
|
|
73
67
|
font-variant-numeric: tabular-nums;
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
/* One
|
|
77
|
-
.content-
|
|
78
|
-
display: grid;
|
|
79
|
-
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
|
80
|
-
gap: 12px;
|
|
70
|
+
/* One row per category: name, bar and status. The whole row links to its part of the work list. */
|
|
71
|
+
.content-health__categories {
|
|
81
72
|
margin: 0;
|
|
82
73
|
padding: 0;
|
|
83
74
|
list-style: none;
|
|
84
75
|
}
|
|
85
76
|
|
|
86
|
-
.content-
|
|
87
|
-
|
|
88
|
-
flex-direction: column;
|
|
89
|
-
gap: calc(var(--base) * 0.75);
|
|
90
|
-
padding: var(--base);
|
|
91
|
-
/* Same as Payload's collection cards. */
|
|
92
|
-
border: 1px solid var(--theme-elevation-150);
|
|
93
|
-
border-radius: var(--style-radius-m);
|
|
94
|
-
background: var(--theme-elevation-50);
|
|
77
|
+
.content-health__categories li + li {
|
|
78
|
+
border-top: 1px solid var(--theme-elevation-100);
|
|
95
79
|
}
|
|
96
80
|
|
|
97
|
-
.content-
|
|
98
|
-
display:
|
|
81
|
+
.content-health__category {
|
|
82
|
+
display: grid;
|
|
83
|
+
grid-template-columns: 8rem minmax(0, 1fr) 9rem;
|
|
99
84
|
align-items: center;
|
|
100
|
-
gap:
|
|
85
|
+
gap: var(--base);
|
|
86
|
+
padding: calc(var(--base) * 0.6) 0;
|
|
87
|
+
color: var(--theme-text);
|
|
88
|
+
text-decoration: none;
|
|
101
89
|
}
|
|
102
90
|
|
|
103
|
-
.content-
|
|
104
|
-
|
|
105
|
-
font-size: 1rem;
|
|
106
|
-
line-height: 1.3;
|
|
91
|
+
.content-health__category:hover .content-health__category-name {
|
|
92
|
+
text-decoration: underline;
|
|
107
93
|
}
|
|
108
94
|
|
|
109
|
-
.content-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
95
|
+
.content-health__bar {
|
|
96
|
+
height: 6px;
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
border-radius: 3px;
|
|
99
|
+
background: var(--theme-elevation-100);
|
|
113
100
|
}
|
|
114
101
|
|
|
115
|
-
.content-
|
|
116
|
-
display:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
border-top: 1px solid var(--theme-elevation-100);
|
|
122
|
-
list-style: none;
|
|
102
|
+
.content-health__bar-fill {
|
|
103
|
+
display: block;
|
|
104
|
+
height: 100%;
|
|
105
|
+
border-radius: 3px;
|
|
106
|
+
background: var(--content-health-accent);
|
|
107
|
+
transition: width 0.4s ease-out;
|
|
123
108
|
}
|
|
124
109
|
|
|
125
|
-
.content-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
110
|
+
.content-health__bar-fill--bad {
|
|
111
|
+
background: var(--content-health-bad);
|
|
112
|
+
/* A bar at 0% is still a mark: the row reads as "nothing in order", not "no bar". */
|
|
113
|
+
min-width: 4px;
|
|
129
114
|
}
|
|
130
115
|
|
|
131
|
-
.content-
|
|
132
|
-
|
|
133
|
-
flex-wrap: wrap;
|
|
134
|
-
gap: calc(var(--base) * 0.25);
|
|
135
|
-
margin: 0;
|
|
136
|
-
padding: 0;
|
|
137
|
-
list-style: none;
|
|
116
|
+
.content-health__bar-fill--warn {
|
|
117
|
+
background: var(--content-health-warn);
|
|
138
118
|
}
|
|
139
119
|
|
|
140
|
-
.content-
|
|
141
|
-
|
|
120
|
+
.content-health__bar-fill--none {
|
|
121
|
+
width: 0 !important;
|
|
142
122
|
}
|
|
143
123
|
|
|
144
|
-
.content-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
gap: calc(var(--base) * 0.3);
|
|
124
|
+
.content-health__category-status {
|
|
125
|
+
text-align: end;
|
|
126
|
+
font-variant-numeric: tabular-nums;
|
|
148
127
|
}
|
|
149
128
|
|
|
150
|
-
.content-
|
|
151
|
-
|
|
152
|
-
border-radius: var(--style-radius-s);
|
|
153
|
-
background: var(--theme-elevation-150);
|
|
154
|
-
color: var(--theme-elevation-800);
|
|
155
|
-
font-size: 0.75em;
|
|
156
|
-
text-decoration: none;
|
|
157
|
-
text-transform: uppercase;
|
|
129
|
+
.content-health__tone--ok {
|
|
130
|
+
color: var(--content-health-accent-text);
|
|
158
131
|
}
|
|
159
132
|
|
|
160
|
-
.content-
|
|
161
|
-
|
|
133
|
+
.content-health__tone--warn {
|
|
134
|
+
color: var(--content-health-warn-text);
|
|
162
135
|
}
|
|
163
136
|
|
|
164
|
-
.content-
|
|
165
|
-
|
|
137
|
+
.content-health__tone--bad {
|
|
138
|
+
color: var(--content-health-bad-text);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.content-health__tone--none {
|
|
166
142
|
color: var(--theme-elevation-500);
|
|
167
|
-
font-size: 0.9em;
|
|
168
143
|
}
|
|
169
144
|
|
|
170
145
|
.content-health__problems {
|
|
@@ -178,12 +153,23 @@ html[data-theme="dark"] .content-health {
|
|
|
178
153
|
}
|
|
179
154
|
|
|
180
155
|
@media (max-width: 768px) {
|
|
181
|
-
.content-
|
|
182
|
-
|
|
183
|
-
|
|
156
|
+
.content-health__overview {
|
|
157
|
+
flex-wrap: wrap;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.content-health__category {
|
|
161
|
+
grid-template-columns: 1fr auto;
|
|
162
|
+
gap: calc(var(--base) * 0.25) var(--base);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.content-health__bar {
|
|
166
|
+
grid-column: 1 / -1;
|
|
167
|
+
grid-row: 2;
|
|
184
168
|
}
|
|
185
169
|
}
|
|
186
170
|
|
|
187
|
-
|
|
188
|
-
|
|
171
|
+
@media (prefers-reduced-motion: reduce) {
|
|
172
|
+
.content-health__bar-fill {
|
|
173
|
+
transition: none;
|
|
174
|
+
}
|
|
189
175
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { AdminViewServerProps } from "payload";
|
|
2
|
+
import "../styles/tokens.css";
|
|
2
3
|
import "../styles/view.css";
|
|
3
4
|
/**
|
|
4
|
-
* The work list: every finding
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* The work list: every finding, one category at a time. Each row opens the document in the
|
|
6
|
+
* finding's locale with the field selected; where the editor assistant works, a second link opens it
|
|
7
|
+
* with a ready prompt too. Scans once per visit; the tabs and filters work in the browser.
|
|
7
8
|
* Only for visitors who may use Admin: Payload leaves custom views public.
|
|
8
9
|
*/
|
|
9
10
|
export declare function ContentHealthView({ initPageResult, params, searchParams, }: AdminViewServerProps): Promise<import("react").JSX.Element>;
|
|
@@ -2,16 +2,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { DefaultTemplate } from "@payloadcms/next/templates";
|
|
3
3
|
import { Gutter, SetStepNav } from "@payloadcms/ui";
|
|
4
4
|
import { redirect } from "next/navigation";
|
|
5
|
-
import {
|
|
5
|
+
import { categoryOf, categoryStats, categoryTone, defaultCategory, } from "../categories.js";
|
|
6
|
+
import { ASK, BATCH_ASK, CATEGORY_LABELS, CHECK_LABELS, COPY, findingDetail, LIST_COPY, uiLanguage, } from "../copy.js";
|
|
7
|
+
import { checkStats, countDocuments } from "../group.js";
|
|
6
8
|
import { accessRedirect, assistantCollections, BATCH_CHECKS, batchCollections, batchTarget, editURL, readFilters, } from "../links.js";
|
|
7
9
|
import { scanContentHealth } from "../scan.js";
|
|
8
10
|
import { CHECK_IDS } from "../types.js";
|
|
9
|
-
import {
|
|
11
|
+
import { Ring } from "../widget/Ring.js";
|
|
12
|
+
import { WorkList, } from "./WorkList.js";
|
|
13
|
+
import "../styles/tokens.css";
|
|
10
14
|
import "../styles/view.css";
|
|
11
15
|
/**
|
|
12
|
-
* The work list: every finding
|
|
13
|
-
*
|
|
14
|
-
*
|
|
16
|
+
* The work list: every finding, one category at a time. Each row opens the document in the
|
|
17
|
+
* finding's locale with the field selected; where the editor assistant works, a second link opens it
|
|
18
|
+
* with a ready prompt too. Scans once per visit; the tabs and filters work in the browser.
|
|
15
19
|
* Only for visitors who may use Admin: Payload leaves custom views public.
|
|
16
20
|
*/
|
|
17
21
|
export async function ContentHealthView({ initPageResult, params, searchParams, }) {
|
|
@@ -27,6 +31,7 @@ export async function ContentHealthView({ initPageResult, params, searchParams,
|
|
|
27
31
|
}
|
|
28
32
|
const language = uiLanguage(req.i18n?.language);
|
|
29
33
|
const copy = LIST_COPY[language];
|
|
34
|
+
const common = COPY[language];
|
|
30
35
|
const { config } = req.payload;
|
|
31
36
|
const adminRoute = config.routes.admin;
|
|
32
37
|
const result = await scanContentHealth({ payload: req.payload, user: req.user });
|
|
@@ -55,10 +60,26 @@ export async function ContentHealthView({ initPageResult, params, searchParams,
|
|
|
55
60
|
...(batchable ? { batchTarget: batchTarget(finding) } : {}),
|
|
56
61
|
};
|
|
57
62
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
const stats = checkStats(result.checks, result.checked, result.findings);
|
|
64
|
+
const categoryList = categoryStats(stats);
|
|
65
|
+
const categories = categoryList.map((stat) => ({
|
|
66
|
+
id: stat.category,
|
|
67
|
+
label: CATEGORY_LABELS[language][stat.category],
|
|
68
|
+
tone: categoryTone(stat),
|
|
61
69
|
}));
|
|
70
|
+
// A link may name a category or, as older ones do, a check.
|
|
71
|
+
const requested = readFilters(searchParams);
|
|
72
|
+
const named = requested.category ?? (requested.check ? categoryOf(requested.check) : undefined);
|
|
73
|
+
const category = categories.some((entry) => entry.id === named)
|
|
74
|
+
? named
|
|
75
|
+
: defaultCategory(categoryList);
|
|
76
|
+
const initialFilters = {
|
|
77
|
+
...(category ? { category } : {}),
|
|
78
|
+
...(requested.collection ? { collection: requested.collection } : {}),
|
|
79
|
+
...(requested.locale ? { locale: requested.locale } : {}),
|
|
80
|
+
};
|
|
81
|
+
const total = stats.reduce((sum, stat) => sum + stat.checked, 0);
|
|
82
|
+
const failing = stats.reduce((sum, stat) => sum + stat.failing, 0);
|
|
62
83
|
const collections = Object.keys(result.documents).map((slug) => ({
|
|
63
84
|
value: slug,
|
|
64
85
|
label: label(config.collections.find((collection) => collection.slug === slug)?.labels?.plural, language) ?? slug,
|
|
@@ -70,7 +91,9 @@ export async function ContentHealthView({ initPageResult, params, searchParams,
|
|
|
70
91
|
}))
|
|
71
92
|
: [];
|
|
72
93
|
// Payload wraps only its own views in the Admin shell; a custom view brings nav and header itself.
|
|
73
|
-
return (_jsx(DefaultTemplate, { i18n: req.i18n, locale: locale, params: params, payload: req.payload, permissions: permissions, req: req, searchParams: searchParams, user: req.user ?? undefined, viewActions: req.payload.config.admin?.components?.actions, visibleEntities: visibleEntities, children: _jsxs(Gutter, { className: "content-health-list", children: [_jsx(SetStepNav, { nav: [{ label: copy.title }] }), _jsxs("header", { className: "content-health-list__header", children: [_jsx(
|
|
94
|
+
return (_jsx(DefaultTemplate, { i18n: req.i18n, locale: locale, params: params, payload: req.payload, permissions: permissions, req: req, searchParams: searchParams, user: req.user ?? undefined, viewActions: req.payload.config.admin?.components?.actions, visibleEntities: visibleEntities, children: _jsxs(Gutter, { className: "content-health-list", children: [_jsx(SetStepNav, { nav: [{ label: copy.title }] }), _jsxs("header", { className: "content-health-list__header", children: [_jsx(Ring, { className: "content-health-list__ring", failing: failing, label: common.ok(total - failing, total), total: total }), _jsxs("div", { children: [_jsx("h1", { children: copy.title }), _jsx("p", { className: "content-health-list__intro", children: result.findings.length
|
|
95
|
+
? copy.summary(result.findings.length, countDocuments(result.findings))
|
|
96
|
+
: copy.none })] })] }), _jsx(WorkList, { adminRoute: adminRoute, batchAsk: batchAsk, categories: categories, collections: collections, initialFilters: initialFilters, language: language, locales: locales, rows: rows }), result.problems.length ? (_jsx("ul", { className: "content-health-list__problems", children: result.problems.map((problem) => (_jsx("li", { children: problem }, problem))) })) : null] }) }));
|
|
74
97
|
}
|
|
75
98
|
/** By check, then document, then locale, so a document's locales sit together. */
|
|
76
99
|
function sortFindings(findings) {
|
package/dist/view/WorkList.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import { type CategoryId, type Tone } from "../categories.ts";
|
|
1
2
|
import { type UiLanguage } from "../copy.ts";
|
|
2
3
|
import { type ListFilters } from "../links.ts";
|
|
3
|
-
import type
|
|
4
|
+
import { type CheckId } from "../types.ts";
|
|
4
5
|
export type WorkListOption = {
|
|
5
6
|
value: string;
|
|
6
7
|
label: string;
|
|
7
8
|
};
|
|
9
|
+
export type WorkListCategory = {
|
|
10
|
+
id: CategoryId;
|
|
11
|
+
label: string;
|
|
12
|
+
tone: Tone;
|
|
13
|
+
};
|
|
8
14
|
/** One finding, ready to show: labels and links are made on the server. */
|
|
9
15
|
export type WorkListRow = {
|
|
10
16
|
key: string;
|
|
@@ -23,14 +29,15 @@ export type WorkListRow = {
|
|
|
23
29
|
batchTarget?: string;
|
|
24
30
|
};
|
|
25
31
|
/**
|
|
26
|
-
* The findings
|
|
27
|
-
* kept in the address, so the view can be linked to
|
|
32
|
+
* The findings, one category at a time and one section per check. The category and the collection
|
|
33
|
+
* and locale filters apply in the browser and are kept in the address, so the view can be linked to
|
|
34
|
+
* and reloaded with them.
|
|
28
35
|
*/
|
|
29
|
-
export declare function WorkList({ adminRoute, batchAsk,
|
|
36
|
+
export declare function WorkList({ adminRoute, batchAsk, categories, collections, initialFilters, language, locales, rows, }: {
|
|
30
37
|
adminRoute: string;
|
|
31
38
|
/** The assistant's prompt per check that it can fix in many documents at once. */
|
|
32
39
|
batchAsk: Partial<Record<CheckId, string>>;
|
|
33
|
-
|
|
40
|
+
categories: WorkListCategory[];
|
|
34
41
|
collections: WorkListOption[];
|
|
35
42
|
initialFilters: ListFilters;
|
|
36
43
|
language: UiLanguage;
|