From 279ce0fae97ba58efdb7797861fb7bcdb683948e Mon Sep 17 00:00:00 2001
From: "Steven R. Loomis"
Date: Wed, 22 May 2024 18:04:03 -0500
Subject: [PATCH] CLDR-17560 Overall Errors
- add new CldrError and OverallErrors components
- add new REST endpoint for whole-locale-errors
- remove Report for supplemental data (whole locale errors) and references thereto
- remove link from info panel to supplemental chart
- add whole-locale widget to General Info
---
tools/cldr-apps/js/src/esm/cldrComponents.mjs | 12 +++-
tools/cldr-apps/js/src/esm/cldrDash.mjs | 11 +++
tools/cldr-apps/js/src/esm/cldrSurvey.mjs | 5 --
tools/cldr-apps/js/src/views/CldrError.vue | 59 ++++++++++++++++
tools/cldr-apps/js/src/views/GeneralInfo.vue | 2 +
.../cldr-apps/js/src/views/OverallErrors.vue | 44 ++++++++++++
.../org/unicode/cldr/web/api/VoteAPI.java | 68 +++++++++++++++++++
.../unicode/cldr/web/api/VoteAPIHelper.java | 40 +++++++++++
.../java/org/unicode/cldr/tool/Chart.java | 2 -
.../unicode/cldr/tool/ChartSupplemental.java | 1 +
.../unicode/cldr/util/VoterReportStatus.java | 1 -
11 files changed, 235 insertions(+), 10 deletions(-)
create mode 100644 tools/cldr-apps/js/src/views/CldrError.vue
create mode 100644 tools/cldr-apps/js/src/views/OverallErrors.vue
diff --git a/tools/cldr-apps/js/src/esm/cldrComponents.mjs b/tools/cldr-apps/js/src/esm/cldrComponents.mjs
index 44c2185a97c..80dcb462ec2 100644
--- a/tools/cldr-apps/js/src/esm/cldrComponents.mjs
+++ b/tools/cldr-apps/js/src/esm/cldrComponents.mjs
@@ -8,8 +8,10 @@ import { App } from "vue";
*/
// local components
+import CldrError from "../views/CldrError.vue";
import CldrValue from "../views/CldrValue.vue";
import LoginButton from "../views/LoginButton.vue";
+import OverallErrors from "../views/OverallErrors.vue";
import ReportResponse from "../views/ReportResponse.vue";
import SearchButton from "../views/SearchButton.vue";
@@ -19,6 +21,7 @@ import {
Alert,
Avatar,
Button,
+ Card,
Checkbox,
Collapse,
CollapsePanel,
@@ -31,9 +34,10 @@ import {
Select,
Spin,
Steps,
+ Tag,
Textarea,
- Tooltip,
Timeline,
+ Tooltip,
UploadDragger,
} from "ant-design-vue";
// Note: 'notification' is a function and is imported as a function in cldrVue.mjs,
@@ -52,9 +56,10 @@ function setup(app) {
app.component("a-alert", Alert);
app.component("a-avatar", Avatar);
app.component("a-button", Button);
+ app.component("a-card", Card);
app.component("a-checkbox", Checkbox);
- app.component("a-collapse", Collapse);
app.component("a-collapse-panel", CollapsePanel);
+ app.component("a-collapse", Collapse);
app.component("a-form-item", Form.Item);
app.component("a-form", Form);
app.component("a-input-password", Input.Password);
@@ -71,12 +76,15 @@ function setup(app) {
app.component("a-spin", Spin);
app.component("a-step", Steps.Step);
app.component("a-steps", Steps);
+ app.component("a-tag", Tag);
app.component("a-textarea", Textarea);
app.component("a-timeline-item", Timeline.Item);
app.component("a-timeline", Timeline);
app.component("a-tooltip", Tooltip);
app.component("a-upload-dragger", UploadDragger);
+ app.component("cldr-error", CldrError);
app.component("cldr-loginbutton", LoginButton);
+ app.component("cldr-overall-errors", OverallErrors);
app.component("cldr-report-response", ReportResponse);
app.component("cldr-searchbutton", SearchButton);
app.component("cldr-value", CldrValue);
diff --git a/tools/cldr-apps/js/src/esm/cldrDash.mjs b/tools/cldr-apps/js/src/esm/cldrDash.mjs
index 49e8356f9e6..db7c4a68945 100644
--- a/tools/cldr-apps/js/src/esm/cldrDash.mjs
+++ b/tools/cldr-apps/js/src/esm/cldrDash.mjs
@@ -2,6 +2,7 @@
* cldrDash: encapsulate dashboard data.
*/
import * as cldrAjax from "./cldrAjax.mjs";
+import * as cldrClient from "./cldrClient.mjs";
import * as cldrCoverage from "./cldrCoverage.mjs";
import * as cldrNotify from "./cldrNotify.mjs";
import * as cldrProgress from "./cldrProgress.mjs";
@@ -469,6 +470,15 @@ async function downloadXlsx(data, locale, cb) {
cb(null);
}
+/**
+ * @param {string} locale locale to list for
+ * @returns {Array}
+ */
+async function getLocaleErrors(locale) {
+ const client = await cldrClient.getClient();
+ return await client.apis.voting.getLocaleErrors({ locale });
+}
+
export {
doFetch,
getFetchError,
@@ -476,4 +486,5 @@ export {
setData,
updatePath,
downloadXlsx,
+ getLocaleErrors,
};
diff --git a/tools/cldr-apps/js/src/esm/cldrSurvey.mjs b/tools/cldr-apps/js/src/esm/cldrSurvey.mjs
index 5e02238e089..17a4356d752 100644
--- a/tools/cldr-apps/js/src/esm/cldrSurvey.mjs
+++ b/tools/cldr-apps/js/src/esm/cldrSurvey.mjs
@@ -788,11 +788,6 @@ function testsToHtml(tests) {
newHtml += "
\n";
}
- if (hadEntireLocale) {
- newHtml += `See also ${cldrText.get(
- "special_r_supplemental"
- )}
\n`;
- }
return newHtml;
}
diff --git a/tools/cldr-apps/js/src/views/CldrError.vue b/tools/cldr-apps/js/src/views/CldrError.vue
new file mode 100644
index 00000000000..54740fd083e
--- /dev/null
+++ b/tools/cldr-apps/js/src/views/CldrError.vue
@@ -0,0 +1,59 @@
+
+
+
+ {{
+ status.type
+ }}
+
+ {{ status.message }}
+
+ How to Fix…
+
+
+
+
+
+
+
diff --git a/tools/cldr-apps/js/src/views/GeneralInfo.vue b/tools/cldr-apps/js/src/views/GeneralInfo.vue
index 5a46ad0de2b..a0e17a8816c 100644
--- a/tools/cldr-apps/js/src/views/GeneralInfo.vue
+++ b/tools/cldr-apps/js/src/views/GeneralInfo.vue
@@ -10,6 +10,8 @@
>
Open Dashboard
+
+
diff --git a/tools/cldr-apps/js/src/views/OverallErrors.vue b/tools/cldr-apps/js/src/views/OverallErrors.vue
new file mode 100644
index 00000000000..7fadc6c419f
--- /dev/null
+++ b/tools/cldr-apps/js/src/views/OverallErrors.vue
@@ -0,0 +1,44 @@
+
+
+
+
Overall Errors
+
+ Check the following errors carefully. These issues often require a ticket
+ to be filed with CLDR to fix.
+
+
+
+
+
+
+
diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPI.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPI.java
index 7911e228e86..df988c0072f 100644
--- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPI.java
+++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPI.java
@@ -1,7 +1,11 @@
package org.unicode.cldr.web.api;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -136,6 +140,34 @@ public Response getPage(
return VoteAPIHelper.handleGetOnePage(loc, session, page, xpstrid);
}
+ /** Array of status items. Only stores one example entry per subtype. */
+ public static final class EntireLocaleStatusResponse {
+ public EntireLocaleStatusResponse() {}
+
+ void addAll(Collection list) {
+ for (final CheckStatus c : list) {
+ add(c);
+ }
+ }
+
+ void add(CheckStatus c) {
+ if (!allSubtypes.contains(c.getSubtype())) {
+ tests.add(new CheckStatusSummary(c));
+ allSubtypes.add(c.getSubtype());
+ }
+ }
+
+ @Schema(description = "list of test results")
+ public List tests = new ArrayList<>();
+
+ // we only want to store one example for each subtype.
+ private Set allSubtypes = new HashSet<>();
+
+ boolean isEmpty() {
+ return tests.isEmpty();
+ }
+ }
+
public static final class RowResponse {
public static final class Row {
@@ -372,4 +404,40 @@ public CheckStatusSummary(CheckStatus checkStatus) {
this.entireLocale = checkStatus.getEntireLocale();
}
}
+
+ @GET
+ @Path("/{locale}/errors")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Operation(summary = "Get overall errors", description = "Get overall errors for a locale")
+ @APIResponses(
+ value = {
+ @APIResponse(
+ responseCode = "200",
+ description = "Error results",
+ content =
+ @Content(
+ mediaType = "application/json",
+ schema =
+ @Schema(
+ implementation =
+ EntireLocaleStatusResponse.class))),
+ @APIResponse(responseCode = "204", description = "No errors in this locale"),
+ @APIResponse(
+ responseCode = "403",
+ description = "Forbidden, no access to this data"),
+ @APIResponse(responseCode = "404", description = "Locale does not exist"),
+ @APIResponse(
+ responseCode = "500",
+ description = "Internal Server Error",
+ content =
+ @Content(
+ mediaType = "application/json",
+ schema = @Schema(implementation = STError.class))),
+ })
+ public Response getLocaleErrors(
+ @Parameter(required = true, example = "br", schema = @Schema(type = SchemaType.STRING))
+ @PathParam("locale")
+ String loc) {
+ return VoteAPIHelper.handleGetLocaleErrors(loc);
+ }
}
diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java
index 9beee734bb2..efa531d45e3 100644
--- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java
+++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java
@@ -21,6 +21,7 @@
import org.unicode.cldr.web.DataPage.DataRow.CandidateItem;
import org.unicode.cldr.web.SurveyException.ErrorCode;
import org.unicode.cldr.web.UserRegistry.User;
+import org.unicode.cldr.web.api.VoteAPI.EntireLocaleStatusResponse;
import org.unicode.cldr.web.api.VoteAPI.RowResponse;
import org.unicode.cldr.web.api.VoteAPI.RowResponse.Row.Candidate;
import org.unicode.cldr.web.api.VoteAPI.VoteResponse;
@@ -82,6 +83,45 @@ static Response handleGetOneRow(
return handleGetRows(args);
}
+ static Response handleGetLocaleErrors(String loc) {
+ final SurveyMain sm = CookieSession.sm;
+ final CLDRLocale locale = CLDRLocale.getInstance(loc);
+ final STFactory factory = sm.getSTFactory();
+ if (!factory.getAvailableCLDRLocales().contains(locale)) {
+ // locale not found
+ return Response.status(404).build();
+ }
+
+ TestResultBundle test = factory.getTestResult(locale, DataPage.getSimpleOptions(locale));
+
+ CLDRFile cldrFile = factory.make(locale, true);
+
+ if (test != null) {
+ EntireLocaleStatusResponse resp = new VoteAPI.EntireLocaleStatusResponse();
+
+ // add any 'early' errors
+ resp.addAll(test.getPossibleProblems());
+
+ // add all non-path status
+ for (final String x : cldrFile) {
+ List result = new ArrayList();
+ test.check(x, result, cldrFile.getStringValue(x));
+ for (final CheckStatus s : result) {
+ if (s.getEntireLocale()) resp.add(s);
+ }
+ }
+
+ if (resp.isEmpty()) {
+ // nothing.
+ return Response.noContent().build();
+ }
+
+ return Response.ok(resp).build();
+ } else {
+ return Response.status(500, "could not load test data").build();
+ }
+ }
+
static Response handleGetOnePage(String loc, String session, String page, String xpstrid) {
ArgsForGet args = new ArgsForGet(loc, session);
if ("auto".equals(page) && xpstrid != null && !xpstrid.isEmpty()) {
diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/tool/Chart.java b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/Chart.java
index 080e361c8ad..697d1e24dd6 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/tool/Chart.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/Chart.java
@@ -234,8 +234,6 @@ public static Chart forReport(final ReportId report, final String locale) {
switch (report) {
case personnames:
return new ChartPersonName(locale);
- case supplemental:
- return new ChartSupplemental(locale);
default:
return null;
}
diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ChartSupplemental.java b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ChartSupplemental.java
index 2b287892939..68bb805d43f 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ChartSupplemental.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ChartSupplemental.java
@@ -14,6 +14,7 @@
import org.unicode.cldr.util.CLDRPaths;
import org.unicode.cldr.util.Factory;
+@Deprecated
public class ChartSupplemental extends Chart {
private static final CLDRConfig CLDR_CONFIG = CLDRConfig.getInstance();
static final CLDRFile ENGLISH = CLDR_CONFIG.getEnglish();
diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/VoterReportStatus.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/VoterReportStatus.java
index 2e4bd8d22bb..73e669af078 100644
--- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/VoterReportStatus.java
+++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/VoterReportStatus.java
@@ -21,7 +21,6 @@ public abstract class VoterReportStatus {
* 'Person Names' Also see {@link org.unicode.cldr.tool.Chart#forReport(ReportId, String)}
*/
public enum ReportId {
- supplemental, // non-Chart (Entire Locale)
datetime, // non-Chart
zones, // non-Chart
compact, // non-Chart, aka 'numbers'