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 @@ + + + + + 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 @@ + + + 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'