@justanarthur/payload-plugin-translator 3.1.0 → 3.1.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/dist/client.css +0 -184
- package/dist/client.d.ts +1 -3
- package/dist/client.js +0 -4
- package/dist/rsc.js +357 -137
- package/package.json +1 -1
package/dist/client.css
CHANGED
|
@@ -39,187 +39,3 @@
|
|
|
39
39
|
flex-wrap: wrap;
|
|
40
40
|
gap: .5rem;
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
/* src/client/components/Review/styles.css */
|
|
44
|
-
.translator-review {
|
|
45
|
-
padding-bottom: calc(var(--base) * 3);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.translator-review__header {
|
|
49
|
-
display: flex;
|
|
50
|
-
justify-content: space-between;
|
|
51
|
-
align-items: baseline;
|
|
52
|
-
gap: var(--base);
|
|
53
|
-
margin: calc(var(--base) * 1.5) 0;
|
|
54
|
-
flex-wrap: wrap;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.translator-review__header h1 {
|
|
58
|
-
margin: 0;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.translator-review__tabs {
|
|
62
|
-
display: flex;
|
|
63
|
-
gap: calc(var(--base) / 2);
|
|
64
|
-
margin-bottom: var(--base);
|
|
65
|
-
flex-wrap: wrap;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.translator-review__tab {
|
|
69
|
-
border: 1px solid var(--theme-elevation-150);
|
|
70
|
-
color: var(--theme-elevation-800);
|
|
71
|
-
text-decoration: none;
|
|
72
|
-
border-radius: 999px;
|
|
73
|
-
padding: 4px 12px;
|
|
74
|
-
font-size: 13px;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.translator-review__tab[aria-current="true"] {
|
|
78
|
-
background: var(--theme-elevation-900);
|
|
79
|
-
border-color: var(--theme-elevation-900);
|
|
80
|
-
color: var(--theme-elevation-0);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.translator-review__scroll {
|
|
84
|
-
overflow-x: auto;
|
|
85
|
-
border: 1px solid var(--theme-elevation-100);
|
|
86
|
-
border-radius: var(--style-radius-m);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.translator-review table {
|
|
90
|
-
border-collapse: collapse;
|
|
91
|
-
width: 100%;
|
|
92
|
-
font-size: 13px;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.translator-review th, .translator-review td {
|
|
96
|
-
border-bottom: 1px solid var(--theme-elevation-100);
|
|
97
|
-
text-align: left;
|
|
98
|
-
vertical-align: top;
|
|
99
|
-
padding: 8px 10px;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.translator-review th {
|
|
103
|
-
background: var(--theme-elevation-50);
|
|
104
|
-
white-space: nowrap;
|
|
105
|
-
font-weight: 600;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.translator-review tr:last-child td {
|
|
109
|
-
border-bottom: 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.translator-review__doc {
|
|
113
|
-
min-width: 220px;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.translator-review__doc small {
|
|
117
|
-
display: block;
|
|
118
|
-
color: var(--theme-elevation-500);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.translator-review__cell {
|
|
122
|
-
display: inline-flex;
|
|
123
|
-
font-variant-numeric: tabular-nums;
|
|
124
|
-
text-decoration: none;
|
|
125
|
-
color: var(--theme-elevation-1000);
|
|
126
|
-
border: 1px solid #0000;
|
|
127
|
-
border-radius: 999px;
|
|
128
|
-
align-items: center;
|
|
129
|
-
gap: 4px;
|
|
130
|
-
min-width: 64px;
|
|
131
|
-
padding: 2px 8px;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.translator-review__cell--ok {
|
|
135
|
-
background: var(--theme-success-100);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.translator-review__cell--partial {
|
|
139
|
-
background: var(--theme-warning-100);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.translator-review__cell--missing {
|
|
143
|
-
background: var(--theme-error-100);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.translator-review__cell--stale {
|
|
147
|
-
border-color: var(--theme-warning-500);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.translator-review__legend {
|
|
151
|
-
display: flex;
|
|
152
|
-
gap: var(--base);
|
|
153
|
-
color: var(--theme-elevation-600);
|
|
154
|
-
margin-top: calc(var(--base) / 2);
|
|
155
|
-
flex-wrap: wrap;
|
|
156
|
-
font-size: 12px;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.translator-review__pager {
|
|
160
|
-
display: flex;
|
|
161
|
-
gap: var(--base);
|
|
162
|
-
margin-top: var(--base);
|
|
163
|
-
align-items: center;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.translator-review__state {
|
|
167
|
-
white-space: nowrap;
|
|
168
|
-
border-radius: 999px;
|
|
169
|
-
padding: 1px 8px;
|
|
170
|
-
font-size: 12px;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.translator-review__state--ok {
|
|
174
|
-
background: var(--theme-success-100);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.translator-review__state--missing {
|
|
178
|
-
background: var(--theme-error-100);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.translator-review__state--identical, .translator-review__state--placeholders {
|
|
182
|
-
background: var(--theme-warning-100);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.translator-review__text {
|
|
186
|
-
white-space: pre-wrap;
|
|
187
|
-
word-break: break-word;
|
|
188
|
-
max-width: 420px;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.translator-review__text--empty {
|
|
192
|
-
color: var(--theme-elevation-400);
|
|
193
|
-
font-style: italic;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.translator-review__path {
|
|
197
|
-
font-family: var(--font-mono, monospace);
|
|
198
|
-
color: var(--theme-elevation-600);
|
|
199
|
-
word-break: break-all;
|
|
200
|
-
max-width: 240px;
|
|
201
|
-
font-size: 12px;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
.translator-review__meta {
|
|
205
|
-
display: flex;
|
|
206
|
-
gap: calc(var(--base) * 1.5);
|
|
207
|
-
color: var(--theme-elevation-600);
|
|
208
|
-
margin-bottom: var(--base);
|
|
209
|
-
flex-wrap: wrap;
|
|
210
|
-
font-size: 13px;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.translator-review__actions {
|
|
214
|
-
display: flex;
|
|
215
|
-
gap: calc(var(--base) / 2);
|
|
216
|
-
flex-wrap: wrap;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.translator-review__actions .btn {
|
|
220
|
-
margin: 0;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
.translator-review__error {
|
|
224
|
-
color: var(--theme-error-500);
|
|
225
|
-
}
|
package/dist/client.d.ts
CHANGED
|
@@ -10,9 +10,7 @@ declare const ReviewActions: ({ entity, locale, reviewed }: {
|
|
|
10
10
|
locale: string;
|
|
11
11
|
reviewed: boolean;
|
|
12
12
|
}) => Element_12xgc2;
|
|
13
|
-
/** loads the review view styles; the view itself is a server component */
|
|
14
|
-
declare const ReviewStyles: () => null;
|
|
15
13
|
import { JSX as JSX_1kxb3 } from "react";
|
|
16
14
|
type Element_12xgc3 = JSX_1kxb3["Element"];
|
|
17
15
|
declare const TranslationsNavLink: () => Element_12xgc3;
|
|
18
|
-
export { CustomButtonWithTranslator, ReviewActions,
|
|
16
|
+
export { CustomButtonWithTranslator, ReviewActions, TranslationsNavLink, CustomButtonWithTranslator as default };
|
package/dist/client.js
CHANGED
|
@@ -373,9 +373,6 @@ var ReviewActions = ({ entity, locale, reviewed }) => {
|
|
|
373
373
|
]
|
|
374
374
|
});
|
|
375
375
|
};
|
|
376
|
-
// src/client/components/Review/ReviewStyles.tsx
|
|
377
|
-
|
|
378
|
-
var ReviewStyles = () => null;
|
|
379
376
|
// src/client/components/Review/TranslationsNavLink.tsx
|
|
380
377
|
import { useConfig as useConfig4 } from "@payloadcms/ui";
|
|
381
378
|
import { formatAdminURL } from "payload/shared";
|
|
@@ -400,7 +397,6 @@ var client_default = CustomButtonWithTranslator;
|
|
|
400
397
|
export {
|
|
401
398
|
CustomButtonWithTranslator,
|
|
402
399
|
ReviewActions,
|
|
403
|
-
ReviewStyles,
|
|
404
400
|
TranslationsNavLink,
|
|
405
401
|
client_default as default
|
|
406
402
|
};
|
package/dist/rsc.js
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
// src/review/view/TranslationsView.tsx
|
|
13
13
|
import { DefaultTemplate } from "@payloadcms/next/templates";
|
|
14
14
|
import { Gutter } from "@payloadcms/ui";
|
|
15
|
-
import { ReviewStyles } from "@justanarthur/payload-plugin-translator/client";
|
|
16
15
|
|
|
17
16
|
// src/review/view/Detail.tsx
|
|
18
17
|
import { ReviewActions } from "@justanarthur/payload-plugin-translator/client";
|
|
@@ -30,38 +29,50 @@ var editHref = (adminRoute, { collectionSlug, globalSlug, id }, locale) => `${fo
|
|
|
30
29
|
|
|
31
30
|
// src/review/view/Detail.tsx
|
|
32
31
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
33
|
-
var
|
|
34
|
-
identical: "same as source",
|
|
35
|
-
missing: "missing",
|
|
36
|
-
ok: "translated",
|
|
37
|
-
placeholders: "placeholders differ"
|
|
32
|
+
var STATE = {
|
|
33
|
+
identical: { label: "same as source", tone: "warn" },
|
|
34
|
+
missing: { label: "missing", tone: "bad" },
|
|
35
|
+
ok: { label: "translated", tone: "ok" },
|
|
36
|
+
placeholders: { label: "placeholders differ", tone: "warn" }
|
|
38
37
|
};
|
|
39
38
|
var preview = (text) => text.length > 600 ? `${text.slice(0, 597)}…` : text;
|
|
40
39
|
var readablePath = (path) => path.replace(/\[(\d+)\]/g, (_, index) => ` ${Number(index) + 1}`).replace(/\(([^)]+)\)/g, " · $1").replace(/#(\d+)$/, (_, index) => ` (part ${Number(index) + 1})`).split(".").join(" › ");
|
|
41
|
-
var Detail = ({ adminRoute, review, onlyIssues, tab }) => {
|
|
40
|
+
var Detail = ({ adminRoute, review, onlyIssues, tab, page }) => {
|
|
42
41
|
const rows = onlyIssues ? review.fields.filter((field) => field.state !== "ok") : review.fields;
|
|
43
42
|
const { summary } = review;
|
|
43
|
+
const tone = summary.slugMissing || summary.coverage < 50 ? "bad" : summary.coverage < 100 ? "warn" : "ok";
|
|
44
|
+
const counters = [
|
|
45
|
+
{ label: "translated", value: `${summary.coverage}%`, note: `${summary.ok} of ${summary.total} fields`, bar: true },
|
|
46
|
+
{ label: "missing", value: summary.missing, note: "empty in this locale" },
|
|
47
|
+
{ label: "same as source", value: summary.identical, note: `identical to ${review.defaultLocale}` },
|
|
48
|
+
{ label: "placeholders", value: summary.placeholders, note: "differ from source" }
|
|
49
|
+
];
|
|
44
50
|
return /* @__PURE__ */ jsxs(Fragment, {
|
|
45
51
|
children: [
|
|
46
52
|
/* @__PURE__ */ jsxs("div", {
|
|
47
|
-
className: "
|
|
53
|
+
className: "tr__head",
|
|
48
54
|
children: [
|
|
49
55
|
/* @__PURE__ */ jsxs("div", {
|
|
50
56
|
children: [
|
|
51
57
|
/* @__PURE__ */ jsxs("a", {
|
|
52
|
-
|
|
58
|
+
className: "tr__back",
|
|
59
|
+
href: reviewHref(adminRoute, { tab, page }),
|
|
53
60
|
children: [
|
|
54
61
|
"← All ",
|
|
55
|
-
tab
|
|
62
|
+
tab
|
|
56
63
|
]
|
|
57
64
|
}),
|
|
58
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ jsx("h1", {
|
|
66
|
+
children: review.label
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ jsxs("p", {
|
|
69
|
+
className: "tr__lead",
|
|
59
70
|
children: [
|
|
60
|
-
review.
|
|
61
|
-
" · ",
|
|
62
|
-
review.defaultLocale,
|
|
71
|
+
review.defaultLocale.toUpperCase(),
|
|
63
72
|
" → ",
|
|
64
|
-
review.locale
|
|
73
|
+
review.locale.toUpperCase(),
|
|
74
|
+
" · ",
|
|
75
|
+
review.entity
|
|
65
76
|
]
|
|
66
77
|
})
|
|
67
78
|
]
|
|
@@ -73,86 +84,106 @@ var Detail = ({ adminRoute, review, onlyIssues, tab }) => {
|
|
|
73
84
|
})
|
|
74
85
|
]
|
|
75
86
|
}),
|
|
87
|
+
/* @__PURE__ */ jsx("div", {
|
|
88
|
+
className: "tr__stats",
|
|
89
|
+
children: counters.map((counter) => /* @__PURE__ */ jsxs("div", {
|
|
90
|
+
className: "tr__stat",
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx("span", {
|
|
93
|
+
className: "tr__stat-label",
|
|
94
|
+
children: counter.label
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ jsx("span", {
|
|
97
|
+
className: "tr__stat-value",
|
|
98
|
+
children: counter.value
|
|
99
|
+
}),
|
|
100
|
+
counter.bar && /* @__PURE__ */ jsx("div", {
|
|
101
|
+
className: "tr__bar",
|
|
102
|
+
style: { ["--tr-tone"]: `var(--tr-${tone})` },
|
|
103
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
104
|
+
style: { width: `${summary.coverage}%` }
|
|
105
|
+
})
|
|
106
|
+
}),
|
|
107
|
+
/* @__PURE__ */ jsx("span", {
|
|
108
|
+
className: "tr__stat-note",
|
|
109
|
+
children: counter.note
|
|
110
|
+
})
|
|
111
|
+
]
|
|
112
|
+
}, counter.label))
|
|
113
|
+
}),
|
|
76
114
|
/* @__PURE__ */ jsxs("div", {
|
|
77
|
-
className: "
|
|
115
|
+
className: "tr__meta",
|
|
78
116
|
children: [
|
|
79
|
-
/* @__PURE__ */ jsxs("span", {
|
|
80
|
-
children: [
|
|
81
|
-
summary.ok,
|
|
82
|
-
"/",
|
|
83
|
-
summary.total,
|
|
84
|
-
" translated (",
|
|
85
|
-
summary.coverage,
|
|
86
|
-
"%)"
|
|
87
|
-
]
|
|
88
|
-
}),
|
|
89
|
-
summary.missing > 0 && /* @__PURE__ */ jsxs("span", {
|
|
90
|
-
children: [
|
|
91
|
-
summary.missing,
|
|
92
|
-
" missing"
|
|
93
|
-
]
|
|
94
|
-
}),
|
|
95
|
-
summary.identical > 0 && /* @__PURE__ */ jsxs("span", {
|
|
96
|
-
children: [
|
|
97
|
-
summary.identical,
|
|
98
|
-
" same as ",
|
|
99
|
-
review.defaultLocale
|
|
100
|
-
]
|
|
101
|
-
}),
|
|
102
|
-
summary.placeholders > 0 && /* @__PURE__ */ jsxs("span", {
|
|
103
|
-
children: [
|
|
104
|
-
summary.placeholders,
|
|
105
|
-
" placeholder mismatches"
|
|
106
|
-
]
|
|
107
|
-
}),
|
|
108
117
|
summary.slugMissing && /* @__PURE__ */ jsxs("span", {
|
|
109
|
-
className: "
|
|
118
|
+
className: "tr__chip tr__chip--bad",
|
|
110
119
|
children: [
|
|
111
|
-
"no slug
|
|
120
|
+
"no slug: the page 404s in ",
|
|
112
121
|
review.locale
|
|
113
122
|
]
|
|
114
123
|
}),
|
|
115
124
|
review.stale && /* @__PURE__ */ jsx("span", {
|
|
116
|
-
|
|
125
|
+
className: "tr__chip",
|
|
126
|
+
children: "↻ source changed since the last translation"
|
|
117
127
|
}),
|
|
118
128
|
review.translatedAt && /* @__PURE__ */ jsxs("span", {
|
|
129
|
+
className: "tr__chip",
|
|
119
130
|
children: [
|
|
120
131
|
"translated ",
|
|
121
132
|
new Date(review.translatedAt).toLocaleString()
|
|
122
133
|
]
|
|
123
134
|
}),
|
|
124
135
|
review.reviewedAt && /* @__PURE__ */ jsxs("span", {
|
|
136
|
+
className: "tr__chip",
|
|
125
137
|
children: [
|
|
126
|
-
"reviewed ",
|
|
138
|
+
"✓ reviewed ",
|
|
127
139
|
new Date(review.reviewedAt).toLocaleString(),
|
|
128
140
|
" by ",
|
|
129
141
|
review.reviewedBy
|
|
130
142
|
]
|
|
131
143
|
}),
|
|
132
144
|
review.lastJob && /* @__PURE__ */ jsxs("span", {
|
|
133
|
-
className: review.lastJob.error ? "
|
|
145
|
+
className: `tr__chip${review.lastJob.error ? " tr__chip--bad" : ""}`,
|
|
146
|
+
title: review.lastJob.error,
|
|
134
147
|
children: [
|
|
135
|
-
"
|
|
148
|
+
"job #",
|
|
136
149
|
review.lastJob.id,
|
|
137
150
|
": ",
|
|
138
|
-
review.lastJob.error ? `failed — ${preview(review.lastJob.error)}` : review.lastJob.completedAt ? "completed" : review.lastJob.processing ? "running" : "queued"
|
|
151
|
+
review.lastJob.error ? `failed — ${preview(review.lastJob.error).slice(0, 80)}` : review.lastJob.completedAt ? "completed" : review.lastJob.processing ? "running" : "queued"
|
|
139
152
|
]
|
|
140
153
|
}),
|
|
141
154
|
/* @__PURE__ */ jsxs("a", {
|
|
155
|
+
className: "tr__chip",
|
|
142
156
|
href: editHref(adminRoute, review, review.locale),
|
|
143
157
|
children: [
|
|
144
158
|
"Edit in ",
|
|
145
|
-
review.locale
|
|
159
|
+
review.locale.toUpperCase(),
|
|
160
|
+
" ↗"
|
|
161
|
+
]
|
|
162
|
+
})
|
|
163
|
+
]
|
|
164
|
+
}),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", {
|
|
166
|
+
className: "tr__toolbar",
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsxs("span", {
|
|
169
|
+
className: "tr__filters",
|
|
170
|
+
children: [
|
|
171
|
+
rows.length,
|
|
172
|
+
" of ",
|
|
173
|
+
review.fields.length,
|
|
174
|
+
" fields"
|
|
146
175
|
]
|
|
147
176
|
}),
|
|
148
177
|
/* @__PURE__ */ jsx("a", {
|
|
149
|
-
|
|
150
|
-
|
|
178
|
+
"aria-pressed": onlyIssues,
|
|
179
|
+
className: "tr__toggle",
|
|
180
|
+
href: reviewHref(adminRoute, { tab, page, entity: review.entity, locale: review.locale, issues: onlyIssues ? undefined : 1 }),
|
|
181
|
+
children: "Only problems"
|
|
151
182
|
})
|
|
152
183
|
]
|
|
153
184
|
}),
|
|
154
185
|
/* @__PURE__ */ jsx("div", {
|
|
155
|
-
className: "
|
|
186
|
+
className: "tr__card",
|
|
156
187
|
children: /* @__PURE__ */ jsxs("table", {
|
|
157
188
|
children: [
|
|
158
189
|
/* @__PURE__ */ jsx("thead", {
|
|
@@ -165,10 +196,10 @@ var Detail = ({ adminRoute, review, onlyIssues, tab }) => {
|
|
|
165
196
|
children: "State"
|
|
166
197
|
}),
|
|
167
198
|
/* @__PURE__ */ jsx("th", {
|
|
168
|
-
children: review.defaultLocale
|
|
199
|
+
children: review.defaultLocale.toUpperCase()
|
|
169
200
|
}),
|
|
170
201
|
/* @__PURE__ */ jsx("th", {
|
|
171
|
-
children: review.locale
|
|
202
|
+
children: review.locale.toUpperCase()
|
|
172
203
|
})
|
|
173
204
|
]
|
|
174
205
|
})
|
|
@@ -178,28 +209,30 @@ var Detail = ({ adminRoute, review, onlyIssues, tab }) => {
|
|
|
178
209
|
rows.map((field) => /* @__PURE__ */ jsxs("tr", {
|
|
179
210
|
children: [
|
|
180
211
|
/* @__PURE__ */ jsx("td", {
|
|
181
|
-
className: "
|
|
212
|
+
className: "tr__path",
|
|
182
213
|
title: field.path,
|
|
183
214
|
children: readablePath(field.path)
|
|
184
215
|
}),
|
|
185
216
|
/* @__PURE__ */ jsx("td", {
|
|
186
217
|
children: /* @__PURE__ */ jsx("span", {
|
|
187
|
-
className:
|
|
188
|
-
|
|
218
|
+
className: "tr__pill",
|
|
219
|
+
"data-tone": STATE[field.state].tone,
|
|
220
|
+
children: STATE[field.state].label
|
|
189
221
|
})
|
|
190
222
|
}),
|
|
191
223
|
/* @__PURE__ */ jsx("td", {
|
|
192
|
-
className: "
|
|
224
|
+
className: "tr__text",
|
|
193
225
|
children: preview(field.sourceText)
|
|
194
226
|
}),
|
|
195
227
|
/* @__PURE__ */ jsx("td", {
|
|
196
|
-
className: `
|
|
228
|
+
className: `tr__text${field.targetText.trim() ? "" : " tr__text--empty"}`,
|
|
197
229
|
children: field.targetText.trim() ? preview(field.targetText) : "empty"
|
|
198
230
|
})
|
|
199
231
|
]
|
|
200
232
|
}, field.path)),
|
|
201
233
|
rows.length === 0 && /* @__PURE__ */ jsx("tr", {
|
|
202
234
|
children: /* @__PURE__ */ jsx("td", {
|
|
235
|
+
className: "tr__empty",
|
|
203
236
|
colSpan: 4,
|
|
204
237
|
children: "Every field is translated."
|
|
205
238
|
})
|
|
@@ -215,24 +248,55 @@ var Detail = ({ adminRoute, review, onlyIssues, tab }) => {
|
|
|
215
248
|
|
|
216
249
|
// src/review/view/Overview.tsx
|
|
217
250
|
import { jsx as jsx2, jsxs as jsxs2, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
218
|
-
var
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab }) => {
|
|
225
|
-
const rows = onlyIssues ? entities.filter((entity) => Object.values(entity.locales).some((each) => each.summary.coverage < 100 || each.summary.slugMissing || each.stale)) : entities;
|
|
226
|
-
const totals = Object.fromEntries(locales.map((locale) => {
|
|
251
|
+
var toneOf = ({ summary }) => summary.slugMissing || summary.coverage < 50 ? "bad" : summary.coverage < 100 ? "warn" : "ok";
|
|
252
|
+
var coverageTone = (coverage) => coverage < 50 ? "bad" : coverage < 100 ? "warn" : "ok";
|
|
253
|
+
var isIncomplete = ({ summary, stale }) => summary.coverage < 100 || summary.slugMissing || stale;
|
|
254
|
+
var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab, page }) => {
|
|
255
|
+
const rows = onlyIssues ? entities.filter((entity) => Object.values(entity.locales).some(isIncomplete)) : entities;
|
|
256
|
+
const stats = locales.map((locale) => {
|
|
227
257
|
const reviews = entities.map((entity) => entity.locales[locale]);
|
|
228
258
|
const fields = reviews.reduce((sum, each) => sum + each.summary.total, 0);
|
|
229
259
|
const ok = reviews.reduce((sum, each) => sum + each.summary.ok, 0);
|
|
230
|
-
return
|
|
231
|
-
|
|
260
|
+
return {
|
|
261
|
+
locale,
|
|
262
|
+
coverage: fields ? Math.floor(ok / fields * 100) : 100,
|
|
263
|
+
incomplete: reviews.filter(isIncomplete).length
|
|
264
|
+
};
|
|
265
|
+
});
|
|
232
266
|
return /* @__PURE__ */ jsxs2(Fragment2, {
|
|
233
267
|
children: [
|
|
234
268
|
/* @__PURE__ */ jsx2("div", {
|
|
235
|
-
className: "
|
|
269
|
+
className: "tr__stats",
|
|
270
|
+
children: stats.map(({ locale, coverage, incomplete }) => /* @__PURE__ */ jsxs2("div", {
|
|
271
|
+
className: "tr__stat",
|
|
272
|
+
children: [
|
|
273
|
+
/* @__PURE__ */ jsx2("span", {
|
|
274
|
+
className: "tr__stat-label",
|
|
275
|
+
children: locale
|
|
276
|
+
}),
|
|
277
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
278
|
+
className: "tr__stat-value",
|
|
279
|
+
children: [
|
|
280
|
+
coverage,
|
|
281
|
+
"%"
|
|
282
|
+
]
|
|
283
|
+
}),
|
|
284
|
+
/* @__PURE__ */ jsx2("div", {
|
|
285
|
+
className: "tr__bar",
|
|
286
|
+
style: { ["--tr-tone"]: `var(--tr-${coverageTone(coverage)})` },
|
|
287
|
+
children: /* @__PURE__ */ jsx2("span", {
|
|
288
|
+
style: { width: `${coverage}%` }
|
|
289
|
+
})
|
|
290
|
+
}),
|
|
291
|
+
/* @__PURE__ */ jsx2("span", {
|
|
292
|
+
className: "tr__stat-note",
|
|
293
|
+
children: incomplete ? `${incomplete} incomplete` : "all complete"
|
|
294
|
+
})
|
|
295
|
+
]
|
|
296
|
+
}, locale))
|
|
297
|
+
}),
|
|
298
|
+
/* @__PURE__ */ jsx2("div", {
|
|
299
|
+
className: "tr__card",
|
|
236
300
|
children: /* @__PURE__ */ jsxs2("table", {
|
|
237
301
|
children: [
|
|
238
302
|
/* @__PURE__ */ jsx2("thead", {
|
|
@@ -241,17 +305,9 @@ var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab
|
|
|
241
305
|
/* @__PURE__ */ jsx2("th", {
|
|
242
306
|
children: "Document"
|
|
243
307
|
}),
|
|
244
|
-
locales.map((locale) => /* @__PURE__ */
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
" ",
|
|
248
|
-
/* @__PURE__ */ jsxs2("small", {
|
|
249
|
-
children: [
|
|
250
|
-
totals[locale],
|
|
251
|
-
"%"
|
|
252
|
-
]
|
|
253
|
-
})
|
|
254
|
-
]
|
|
308
|
+
locales.map((locale) => /* @__PURE__ */ jsx2("th", {
|
|
309
|
+
className: "tr__locale-col",
|
|
310
|
+
children: locale.toUpperCase()
|
|
255
311
|
}, locale))
|
|
256
312
|
]
|
|
257
313
|
})
|
|
@@ -261,37 +317,56 @@ var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab
|
|
|
261
317
|
rows.map((entity) => /* @__PURE__ */ jsxs2("tr", {
|
|
262
318
|
children: [
|
|
263
319
|
/* @__PURE__ */ jsxs2("td", {
|
|
264
|
-
className: "
|
|
320
|
+
className: "tr__doc",
|
|
265
321
|
children: [
|
|
266
322
|
/* @__PURE__ */ jsx2("a", {
|
|
267
323
|
href: editHref(adminRoute, entity, defaultLocale),
|
|
268
324
|
children: entity.label
|
|
269
325
|
}),
|
|
270
|
-
/* @__PURE__ */ jsx2("
|
|
326
|
+
/* @__PURE__ */ jsx2("span", {
|
|
327
|
+
className: "tr__key",
|
|
271
328
|
children: entity.key
|
|
272
329
|
})
|
|
273
330
|
]
|
|
274
331
|
}),
|
|
275
332
|
locales.map((locale) => {
|
|
276
333
|
const review = entity.locales[locale];
|
|
334
|
+
const { summary } = review;
|
|
277
335
|
const title = [
|
|
278
|
-
`${
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
review.stale &&
|
|
336
|
+
`${summary.ok}/${summary.total} fields translated`,
|
|
337
|
+
summary.missing && `${summary.missing} missing`,
|
|
338
|
+
summary.identical && `${summary.identical} same as ${defaultLocale}`,
|
|
339
|
+
summary.placeholders && `${summary.placeholders} broken placeholders`,
|
|
340
|
+
summary.slugMissing && "no slug: the page 404s",
|
|
341
|
+
review.stale && "source changed since translation",
|
|
284
342
|
review.reviewed && "reviewed"
|
|
285
343
|
].filter(Boolean).join(" · ");
|
|
286
344
|
return /* @__PURE__ */ jsx2("td", {
|
|
345
|
+
className: "tr__locale-col",
|
|
287
346
|
children: /* @__PURE__ */ jsxs2("a", {
|
|
288
|
-
className:
|
|
289
|
-
|
|
347
|
+
className: "tr__cell",
|
|
348
|
+
"data-tone": toneOf(review),
|
|
349
|
+
href: reviewHref(adminRoute, { tab, page, entity: entity.key, locale, issues: isIncomplete(review) ? 1 : undefined }),
|
|
290
350
|
title,
|
|
291
351
|
children: [
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
352
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
353
|
+
children: [
|
|
354
|
+
summary.slugMissing ? "404" : `${summary.coverage}%`,
|
|
355
|
+
(review.stale || review.reviewed) && /* @__PURE__ */ jsxs2("span", {
|
|
356
|
+
className: "tr__marks",
|
|
357
|
+
children: [
|
|
358
|
+
" ",
|
|
359
|
+
[review.stale && "↻", review.reviewed && "✓"].filter(Boolean).join(" ")
|
|
360
|
+
]
|
|
361
|
+
})
|
|
362
|
+
]
|
|
363
|
+
}),
|
|
364
|
+
/* @__PURE__ */ jsx2("span", {
|
|
365
|
+
className: "tr__bar",
|
|
366
|
+
children: /* @__PURE__ */ jsx2("span", {
|
|
367
|
+
style: { width: `${summary.slugMissing ? 100 : summary.coverage}%` }
|
|
368
|
+
})
|
|
369
|
+
})
|
|
295
370
|
]
|
|
296
371
|
})
|
|
297
372
|
}, locale);
|
|
@@ -300,8 +375,9 @@ var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab
|
|
|
300
375
|
}, entity.key)),
|
|
301
376
|
rows.length === 0 && /* @__PURE__ */ jsx2("tr", {
|
|
302
377
|
children: /* @__PURE__ */ jsx2("td", {
|
|
378
|
+
className: "tr__empty",
|
|
303
379
|
colSpan: locales.length + 1,
|
|
304
|
-
children: "
|
|
380
|
+
children: "Everything here is fully translated."
|
|
305
381
|
})
|
|
306
382
|
})
|
|
307
383
|
]
|
|
@@ -310,19 +386,40 @@ var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab
|
|
|
310
386
|
})
|
|
311
387
|
}),
|
|
312
388
|
/* @__PURE__ */ jsxs2("div", {
|
|
313
|
-
className: "
|
|
389
|
+
className: "tr__legend",
|
|
314
390
|
children: [
|
|
315
|
-
/* @__PURE__ */
|
|
316
|
-
children:
|
|
391
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
392
|
+
children: [
|
|
393
|
+
/* @__PURE__ */ jsx2("i", {
|
|
394
|
+
className: "tr__dot",
|
|
395
|
+
style: { ["--tr-tone"]: "var(--tr-ok)" }
|
|
396
|
+
}),
|
|
397
|
+
"fully translated"
|
|
398
|
+
]
|
|
317
399
|
}),
|
|
318
|
-
/* @__PURE__ */
|
|
319
|
-
children:
|
|
400
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
401
|
+
children: [
|
|
402
|
+
/* @__PURE__ */ jsx2("i", {
|
|
403
|
+
className: "tr__dot",
|
|
404
|
+
style: { ["--tr-tone"]: "var(--tr-warn)" }
|
|
405
|
+
}),
|
|
406
|
+
"partly translated"
|
|
407
|
+
]
|
|
408
|
+
}),
|
|
409
|
+
/* @__PURE__ */ jsxs2("span", {
|
|
410
|
+
children: [
|
|
411
|
+
/* @__PURE__ */ jsx2("i", {
|
|
412
|
+
className: "tr__dot",
|
|
413
|
+
style: { ["--tr-tone"]: "var(--tr-bad)" }
|
|
414
|
+
}),
|
|
415
|
+
"under half, or 404 without a slug"
|
|
416
|
+
]
|
|
320
417
|
}),
|
|
321
418
|
/* @__PURE__ */ jsx2("span", {
|
|
322
419
|
children: "↻ source changed since the last translation"
|
|
323
420
|
}),
|
|
324
421
|
/* @__PURE__ */ jsx2("span", {
|
|
325
|
-
children: "✓ reviewed
|
|
422
|
+
children: "✓ reviewed"
|
|
326
423
|
})
|
|
327
424
|
]
|
|
328
425
|
})
|
|
@@ -330,8 +427,89 @@ var Overview = ({ adminRoute, defaultLocale, entities, locales, onlyIssues, tab
|
|
|
330
427
|
});
|
|
331
428
|
};
|
|
332
429
|
|
|
430
|
+
// src/review/view/styles.ts
|
|
431
|
+
var reviewStyles = `
|
|
432
|
+
.tr { --tr-ok: var(--theme-success-500); --tr-ok-bg: var(--theme-success-100); --tr-warn: var(--theme-warning-500); --tr-warn-bg: var(--theme-warning-100); --tr-bad: var(--theme-error-500); --tr-bad-bg: var(--theme-error-100); --tr-line: var(--theme-elevation-100); --tr-muted: var(--theme-elevation-500); --tr-card: var(--theme-elevation-50); padding-block: calc(var(--base) * 2) calc(var(--base) * 4); }
|
|
433
|
+
.tr a { text-decoration: none; color: inherit; }
|
|
434
|
+
.tr__head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--base); margin-bottom: calc(var(--base) * 1.5); }
|
|
435
|
+
.tr__head h1 { margin: 0 0 4px; }
|
|
436
|
+
.tr__lead { margin: 0; color: var(--tr-muted); max-width: 60ch; }
|
|
437
|
+
.tr__back { display: inline-flex; gap: 6px; color: var(--tr-muted); font-size: 13px; margin-bottom: 8px; }
|
|
438
|
+
.tr__back:hover { color: var(--theme-text); }
|
|
439
|
+
|
|
440
|
+
.tr__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-bottom: calc(var(--base) * 1.5); }
|
|
441
|
+
.tr__stat { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border: 1px solid var(--tr-line); border-radius: var(--style-radius-m); background: var(--tr-card); }
|
|
442
|
+
.tr__stat-label { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--tr-muted); }
|
|
443
|
+
.tr__stat-value { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.1; }
|
|
444
|
+
.tr__stat-note { font-size: 12px; color: var(--tr-muted); }
|
|
445
|
+
|
|
446
|
+
.tr__bar { height: 4px; border-radius: 999px; background: var(--theme-elevation-150); overflow: hidden; }
|
|
447
|
+
.tr__bar > span { display: block; height: 100%; border-radius: inherit; background: var(--tr-tone, var(--tr-ok)); }
|
|
448
|
+
|
|
449
|
+
.tr__toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
|
|
450
|
+
.tr__tabs { display: inline-flex; padding: 3px; gap: 2px; border-radius: 999px; background: var(--theme-elevation-100); }
|
|
451
|
+
.tr__tab { padding: 5px 14px; border-radius: 999px; font-size: 13px; color: var(--theme-elevation-700); text-transform: capitalize; }
|
|
452
|
+
.tr__tab:hover { color: var(--theme-text); }
|
|
453
|
+
.tr__tab[aria-current='true'] { background: var(--theme-elevation-0); color: var(--theme-text); box-shadow: 0 1px 2px rgba(0,0,0,.2); }
|
|
454
|
+
.tr__filters { display: inline-flex; align-items: center; gap: 12px; font-size: 13px; color: var(--tr-muted); }
|
|
455
|
+
.tr__toggle { display: inline-flex; align-items: center; gap: 8px; padding: 5px 12px; border: 1px solid var(--tr-line); border-radius: 999px; color: var(--theme-elevation-800); }
|
|
456
|
+
.tr__toggle::before { content: ''; width: 26px; height: 14px; border-radius: 999px; background: var(--theme-elevation-200) radial-gradient(circle at 7px 50%, var(--theme-elevation-0) 4px, transparent 4.5px); }
|
|
457
|
+
.tr__toggle[aria-pressed='true']::before { background: var(--tr-ok) radial-gradient(circle at 19px 50%, var(--theme-elevation-0) 4px, transparent 4.5px); }
|
|
458
|
+
|
|
459
|
+
.tr__card { border: 1px solid var(--tr-line); border-radius: var(--style-radius-m); overflow: auto; background: var(--theme-elevation-0); }
|
|
460
|
+
.tr table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
|
|
461
|
+
.tr th { position: sticky; top: 0; z-index: 1; background: var(--tr-card); text-align: left; font-weight: 500; color: var(--tr-muted); padding: 10px 12px; border-bottom: 1px solid var(--tr-line); white-space: nowrap; }
|
|
462
|
+
.tr th small { display: block; font-size: 11px; font-weight: 400; }
|
|
463
|
+
.tr td { padding: 6px 12px; border-bottom: 1px solid var(--tr-line); vertical-align: middle; }
|
|
464
|
+
.tr tbody tr:last-child td { border-bottom: 0; }
|
|
465
|
+
.tr tbody tr:hover td { background: var(--theme-elevation-50); }
|
|
466
|
+
.tr__locale-col { text-align: center !important; }
|
|
467
|
+
.tr__doc { min-width: 240px; }
|
|
468
|
+
.tr__doc a { font-weight: 500; }
|
|
469
|
+
.tr__doc a:hover { text-decoration: underline; }
|
|
470
|
+
.tr__key { display: block; margin-top: 2px; font-family: var(--font-mono, ui-monospace, monospace); font-size: 11px; color: var(--tr-muted); }
|
|
471
|
+
|
|
472
|
+
.tr__cell { display: flex; flex-direction: column; gap: 4px; min-width: 64px; padding: 6px 8px; border-radius: 6px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 500; transition: background .12s; }
|
|
473
|
+
.tr__cell:hover { background: var(--theme-elevation-100); }
|
|
474
|
+
.tr__cell[data-tone='ok'] { --tr-tone: var(--tr-ok); color: var(--tr-ok); }
|
|
475
|
+
.tr__cell[data-tone='warn'] { --tr-tone: var(--tr-warn); color: var(--tr-warn); }
|
|
476
|
+
.tr__cell[data-tone='bad'] { --tr-tone: var(--tr-bad); color: var(--tr-bad); }
|
|
477
|
+
.tr__marks { font-size: 11px; color: var(--tr-muted); }
|
|
478
|
+
|
|
479
|
+
.tr__legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 12px; font-size: 12px; color: var(--tr-muted); }
|
|
480
|
+
.tr__legend span { display: inline-flex; align-items: center; gap: 6px; }
|
|
481
|
+
.tr__dot { width: 8px; height: 8px; border-radius: 999px; background: var(--tr-tone); }
|
|
482
|
+
|
|
483
|
+
.tr__pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; font-size: 13px; color: var(--tr-muted); }
|
|
484
|
+
.tr__pager nav { display: inline-flex; gap: 6px; }
|
|
485
|
+
.tr__pager a, .tr__pager span[aria-disabled] { padding: 5px 12px; border: 1px solid var(--tr-line); border-radius: 999px; color: var(--theme-elevation-800); }
|
|
486
|
+
.tr__pager span[aria-disabled] { opacity: .4; }
|
|
487
|
+
.tr__pager a:hover { background: var(--theme-elevation-100); }
|
|
488
|
+
|
|
489
|
+
.tr__pill { display: inline-flex; align-items: center; gap: 6px; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 500; white-space: nowrap; background: var(--theme-elevation-100); }
|
|
490
|
+
.tr__pill::before { content: ''; width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
|
|
491
|
+
.tr__pill[data-tone='ok'] { color: var(--tr-ok); background: var(--tr-ok-bg); }
|
|
492
|
+
.tr__pill[data-tone='warn'] { color: var(--tr-warn); background: var(--tr-warn-bg); }
|
|
493
|
+
.tr__pill[data-tone='bad'] { color: var(--tr-bad); background: var(--tr-bad-bg); }
|
|
494
|
+
|
|
495
|
+
.tr__meta { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
|
|
496
|
+
.tr__chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--tr-line); border-radius: 999px; font-size: 12px; color: var(--theme-elevation-800); }
|
|
497
|
+
.tr__chip--bad { color: var(--tr-bad); border-color: var(--tr-bad); }
|
|
498
|
+
a.tr__chip:hover { background: var(--theme-elevation-100); }
|
|
499
|
+
|
|
500
|
+
.tr__path { width: 22%; font-family: var(--font-mono, ui-monospace, monospace); font-size: 12px; color: var(--theme-elevation-700); word-break: break-word; }
|
|
501
|
+
.tr__text { width: 34%; white-space: pre-wrap; word-break: break-word; line-height: 1.45; }
|
|
502
|
+
.tr__text--empty { color: var(--tr-muted); font-style: italic; }
|
|
503
|
+
.tr__empty { padding: 32px; text-align: center; color: var(--tr-muted); }
|
|
504
|
+
.tr__error { color: var(--tr-bad); }
|
|
505
|
+
|
|
506
|
+
.translator-review__actions { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
507
|
+
.translator-review__actions .btn { margin: 0; }
|
|
508
|
+
`;
|
|
509
|
+
|
|
333
510
|
// src/review/view/TranslationsView.tsx
|
|
334
511
|
import { jsx as jsx3, jsxs as jsxs3, Fragment as Fragment3 } from "react/jsx-runtime";
|
|
512
|
+
var PAGE_SIZE = 50;
|
|
335
513
|
var param = (value) => Array.isArray(value) ? value[0] : value;
|
|
336
514
|
var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
337
515
|
const { req, permissions, visibleEntities, locale } = initPageResult;
|
|
@@ -350,6 +528,7 @@ var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
|
350
528
|
const content = async () => {
|
|
351
529
|
if (!req.user)
|
|
352
530
|
return /* @__PURE__ */ jsx3("p", {
|
|
531
|
+
className: "tr__empty",
|
|
353
532
|
children: "Log in to review translations."
|
|
354
533
|
});
|
|
355
534
|
if (!tab)
|
|
@@ -362,12 +541,13 @@ var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
|
362
541
|
return /* @__PURE__ */ jsx3(Detail, {
|
|
363
542
|
adminRoute,
|
|
364
543
|
onlyIssues,
|
|
544
|
+
page,
|
|
365
545
|
review,
|
|
366
546
|
tab
|
|
367
547
|
});
|
|
368
548
|
} catch (error) {
|
|
369
549
|
return /* @__PURE__ */ jsxs3("p", {
|
|
370
|
-
className: "
|
|
550
|
+
className: "tr__error",
|
|
371
551
|
children: [
|
|
372
552
|
"Could not load ",
|
|
373
553
|
entity,
|
|
@@ -388,7 +568,10 @@ var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
|
388
568
|
tab
|
|
389
569
|
});
|
|
390
570
|
}
|
|
391
|
-
const review = await loadCollectionReview({ req, collectionSlug: tab, page });
|
|
571
|
+
const review = await loadCollectionReview({ req, collectionSlug: tab, page, limit: PAGE_SIZE });
|
|
572
|
+
const first = review.totalDocs ? (review.page - 1) * PAGE_SIZE + 1 : 0;
|
|
573
|
+
const last = Math.min(review.page * PAGE_SIZE, review.totalDocs);
|
|
574
|
+
const pageHref = (target) => reviewHref(adminRoute, { tab, page: target, issues: onlyIssues ? 1 : undefined });
|
|
392
575
|
return /* @__PURE__ */ jsxs3(Fragment3, {
|
|
393
576
|
children: [
|
|
394
577
|
/* @__PURE__ */ jsx3(Overview, {
|
|
@@ -397,29 +580,47 @@ var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
|
397
580
|
entities: review.entities,
|
|
398
581
|
locales: review.locales,
|
|
399
582
|
onlyIssues,
|
|
583
|
+
page,
|
|
400
584
|
tab
|
|
401
585
|
}),
|
|
402
|
-
|
|
403
|
-
className: "
|
|
586
|
+
/* @__PURE__ */ jsxs3("div", {
|
|
587
|
+
className: "tr__pager",
|
|
404
588
|
children: [
|
|
405
|
-
page > 1 && /* @__PURE__ */ jsx3("a", {
|
|
406
|
-
href: reviewHref(adminRoute, { tab, page: page - 1, issues: onlyIssues ? 1 : undefined }),
|
|
407
|
-
children: "← Newer"
|
|
408
|
-
}),
|
|
409
589
|
/* @__PURE__ */ jsxs3("span", {
|
|
410
590
|
children: [
|
|
411
|
-
|
|
412
|
-
|
|
591
|
+
first,
|
|
592
|
+
"–",
|
|
593
|
+
last,
|
|
413
594
|
" of ",
|
|
414
|
-
review.totalPages,
|
|
415
|
-
" · ",
|
|
416
595
|
review.totalDocs,
|
|
417
|
-
" documents"
|
|
596
|
+
" documents",
|
|
597
|
+
onlyIssues ? " (complete ones hidden)" : ""
|
|
418
598
|
]
|
|
419
599
|
}),
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
600
|
+
review.totalPages > 1 && /* @__PURE__ */ jsxs3("nav", {
|
|
601
|
+
children: [
|
|
602
|
+
review.page > 1 ? /* @__PURE__ */ jsx3("a", {
|
|
603
|
+
href: pageHref(review.page - 1),
|
|
604
|
+
children: "← Newer"
|
|
605
|
+
}) : /* @__PURE__ */ jsx3("span", {
|
|
606
|
+
"aria-disabled": true,
|
|
607
|
+
children: "← Newer"
|
|
608
|
+
}),
|
|
609
|
+
/* @__PURE__ */ jsxs3("span", {
|
|
610
|
+
children: [
|
|
611
|
+
review.page,
|
|
612
|
+
" / ",
|
|
613
|
+
review.totalPages
|
|
614
|
+
]
|
|
615
|
+
}),
|
|
616
|
+
review.page < review.totalPages ? /* @__PURE__ */ jsx3("a", {
|
|
617
|
+
href: pageHref(review.page + 1),
|
|
618
|
+
children: "Older →"
|
|
619
|
+
}) : /* @__PURE__ */ jsx3("span", {
|
|
620
|
+
"aria-disabled": true,
|
|
621
|
+
children: "Older →"
|
|
622
|
+
})
|
|
623
|
+
]
|
|
423
624
|
})
|
|
424
625
|
]
|
|
425
626
|
})
|
|
@@ -439,32 +640,51 @@ var TranslationsView = async ({ initPageResult, params, searchParams }) => {
|
|
|
439
640
|
user: req.user || undefined,
|
|
440
641
|
visibleEntities,
|
|
441
642
|
children: [
|
|
442
|
-
/* @__PURE__ */ jsx3(
|
|
643
|
+
/* @__PURE__ */ jsx3("style", {
|
|
644
|
+
dangerouslySetInnerHTML: { __html: reviewStyles }
|
|
645
|
+
}),
|
|
443
646
|
/* @__PURE__ */ jsxs3(Gutter, {
|
|
444
|
-
className: "
|
|
647
|
+
className: "tr",
|
|
445
648
|
children: [
|
|
446
649
|
!entity && /* @__PURE__ */ jsxs3(Fragment3, {
|
|
447
650
|
children: [
|
|
651
|
+
/* @__PURE__ */ jsx3("div", {
|
|
652
|
+
className: "tr__head",
|
|
653
|
+
children: /* @__PURE__ */ jsxs3("div", {
|
|
654
|
+
children: [
|
|
655
|
+
/* @__PURE__ */ jsx3("h1", {
|
|
656
|
+
children: "Translations"
|
|
657
|
+
}),
|
|
658
|
+
/* @__PURE__ */ jsxs3("p", {
|
|
659
|
+
className: "tr__lead",
|
|
660
|
+
children: [
|
|
661
|
+
"How much of each document is translated from ",
|
|
662
|
+
defaultLocale.toUpperCase(),
|
|
663
|
+
". Open a cell to compare it field by field."
|
|
664
|
+
]
|
|
665
|
+
})
|
|
666
|
+
]
|
|
667
|
+
})
|
|
668
|
+
}),
|
|
448
669
|
/* @__PURE__ */ jsxs3("div", {
|
|
449
|
-
className: "
|
|
670
|
+
className: "tr__toolbar",
|
|
450
671
|
children: [
|
|
451
|
-
/* @__PURE__ */ jsx3("
|
|
452
|
-
|
|
672
|
+
/* @__PURE__ */ jsx3("nav", {
|
|
673
|
+
className: "tr__tabs",
|
|
674
|
+
children: tabs.map((each) => /* @__PURE__ */ jsx3("a", {
|
|
675
|
+
"aria-current": each === tab,
|
|
676
|
+
className: "tr__tab",
|
|
677
|
+
href: reviewHref(adminRoute, { tab: each, issues: onlyIssues ? 1 : undefined }),
|
|
678
|
+
children: each
|
|
679
|
+
}, each))
|
|
453
680
|
}),
|
|
454
681
|
/* @__PURE__ */ jsx3("a", {
|
|
682
|
+
"aria-pressed": onlyIssues,
|
|
683
|
+
className: "tr__toggle",
|
|
455
684
|
href: reviewHref(adminRoute, { tab, issues: onlyIssues ? undefined : 1 }),
|
|
456
|
-
children:
|
|
685
|
+
children: "Only incomplete"
|
|
457
686
|
})
|
|
458
687
|
]
|
|
459
|
-
}),
|
|
460
|
-
/* @__PURE__ */ jsx3("nav", {
|
|
461
|
-
className: "translator-review__tabs",
|
|
462
|
-
children: tabs.map((each) => /* @__PURE__ */ jsx3("a", {
|
|
463
|
-
"aria-current": each === tab,
|
|
464
|
-
className: "translator-review__tab",
|
|
465
|
-
href: reviewHref(adminRoute, { tab: each, issues: onlyIssues ? 1 : undefined }),
|
|
466
|
-
children: each
|
|
467
|
-
}, each))
|
|
468
688
|
})
|
|
469
689
|
]
|
|
470
690
|
}),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justanarthur/payload-plugin-translator",
|
|
3
3
|
"description": "Translator plugin for Payload CMS — automatic localization via Google, OpenAI, LibreTranslate, or custom resolvers.",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"files": [
|