Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLDR-18220 Dashboard Other category for all other paths #4273

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions tools/cldr-apps/js/src/esm/cldrDashData.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ let fetchErr = "";

let viewSetDataCallback = null;

function doFetch(callback) {
function doFetch(callback, opts) {
opts = opts || {};
const { includeOther } = opts;
viewSetDataCallback = callback;
fetchErr = "";
const locale = cldrStatus.getCurrentLocale();
Expand All @@ -257,7 +259,8 @@ function doFetch(callback) {
fetchErr = cldrText.get("dash_needs_locale_and_coverage");
return;
}
const url = `api/summary/dashboard/${locale}/${level}`;
const qs = includeOther ? "?includeOther=true" : "";
const url = `api/summary/dashboard/${locale}/${level}${qs}`;
cldrAjax
.doFetch(url)
.then(cldrAjax.handleFetchErrors)
Expand Down
1 change: 1 addition & 0 deletions tools/cldr-apps/js/src/esm/cldrText.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ const strings = {
notification_category_warning:
"The Survey Tool detected a warning about the winning value.",
notification_category_reports: "A Report has not been completed.",
notification_category_other: "All other values",

progress_page: "Your voting in this page",
progress_voter: "Your voting in this locale",
Expand Down
28 changes: 27 additions & 1 deletion tools/cldr-apps/js/src/views/DashboardWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
</template>
</span>
<span class="right-control">
<span
v-if="!includeOther"
class="cldr-nav-btn"
@click="reloadIncludeOther"
>
<input type="checkbox" />&nbsp;Other
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion for future improvement: hover text for this control with brief explanation what it does, e.g., "Include notifications for ALL paths within the chosen coverage level that do not belong to another notification category. Note: the number of 'other' notifications may be very large"

</span>
<a-spin v-if="downloadMessage">
<i>{{ downloadMessage }}</i>
</a-spin>
Expand Down Expand Up @@ -214,6 +221,7 @@ export default {
catCheckboxIsUnchecked: {}, // default unchecked = false, checked = true
catIsHidden: {}, // default hidden = false, visible = true
updatingVisibility: false,
includeOther: false,
};
},

Expand Down Expand Up @@ -287,6 +295,16 @@ export default {
this.fetchData();
},

reloadIncludeOther() {
this.catIsHidden["Other"] = false;
this.catCheckboxIsUnchecked["Other"] = false;
this.includeOther = true;
this.reloadDashboard();
},
reloadWithoutOther() {
this.includeOther = false;
this.reloadDashboard();
},
fetchData() {
this.locale = cldrStatus.getCurrentLocale();
this.level = cldrCoverage.effectiveName(this.locale);
Expand All @@ -298,7 +316,7 @@ export default {
}
this.localeName = cldrLoad.getLocaleName(this.locale);
this.loadingMessage = `Loading ${this.localeName} dashboard at ${this.level} level`;
cldrDashData.doFetch(this.setData);
cldrDashData.doFetch(this.setData, { includeOther: this.includeOther });
this.fetchErr = cldrDashData.getFetchError();
},

Expand Down Expand Up @@ -434,6 +452,14 @@ export default {
// long delay between the time the user clicks the checkbox and the time that the checkbox
// changes its state.
// NOTE: this complication may be unnecessary now that DashboardScroller is in use.
if (category === "Other") {
// special case: Unchecking Other reloads without Other.
nextTick().then(() => {
this.reloadWithoutOther();
});
return;
}

this.catCheckboxIsUnchecked[category] = !event.target.checked; // redundant?
const USE_NEXT_TICK = true;
this.updatingVisibility = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ public ReviewEntry(String code) {
* @return the ReviewOutput
*/
public ReviewOutput get(
CLDRLocale locale, UserRegistry.User user, Level coverageLevel, String xpath) {
CLDRLocale locale,
UserRegistry.User user,
Level coverageLevel,
String xpath,
boolean includeOther) {
final SurveyMain sm = CookieSession.sm;
Organization usersOrg = Organization.unaffiliated;
if (user != null) {
Expand All @@ -242,6 +246,10 @@ public ReviewOutput get(
sm.getSupplementalDataInfo(), sourceFactory, new STUsersChoice(sm));
EnumSet<NotificationCategory> choiceSet =
VettingViewer.getDashboardNotificationCategories(usersOrg);
if (includeOther) {
// user requested all categories
choiceSet.add(NotificationCategory.other);
}
VettingParameters args = new VettingParameters(choiceSet, locale, coverageLevel);
if (user != null) {
args.setUserAndOrganization(user.id, usersOrg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
Expand Down Expand Up @@ -476,6 +478,13 @@ public Response getDashboard(
@PathParam("locale") @Schema(required = true, description = "Locale ID") String locale,
@PathParam("level") @Schema(required = true, description = "Coverage Level")
String level,
@QueryParam("includeOther")
@DefaultValue("false")
@Schema(
required = false,
description = "Include all rows ('Other' category)",
example = "true")
boolean includeOther,
@HeaderParam(Auth.SESSION_HEADER) String sessionString) {
CLDRLocale loc = CLDRLocale.getInstance(locale);
CookieSession cs = Auth.getSession(sessionString);
Expand All @@ -486,7 +495,8 @@ public Response getDashboard(

// *Beware* org.unicode.cldr.util.Level (coverage) ≠ VoteResolver.Level (user)
Level coverageLevel = org.unicode.cldr.util.Level.fromString(level);
ReviewOutput ret = new Dashboard().get(loc, cs.user, coverageLevel, null /* xpath */);
ReviewOutput ret =
new Dashboard().get(loc, cs.user, coverageLevel, null /* xpath */, includeOther);
ret.coverageLevel = coverageLevel.name();

return Response.ok().entity(ret).build();
Expand Down Expand Up @@ -551,7 +561,7 @@ public Response getParticipationFor(
coverageLevel = org.unicode.cldr.util.Level.fromString(level);
}
ReviewOutput reviewOutput =
new Dashboard().get(loc, target, coverageLevel, null /* xpath */);
new Dashboard().get(loc, target, coverageLevel, null /* xpath */, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: never add a boolean without a comment what it is

Suggested change
new Dashboard().get(loc, target, coverageLevel, null /* xpath */, false);
new Dashboard().get(loc, target, coverageLevel, null /* xpath */, false /* includeOther */);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm used to getting that filled in by the IDE but sounds good

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! If you have a moment during the Stanford visit I'd love for your help setting up my IDE to for things like this. Do you use Eclipse or VSCode?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VS code with the red hat, Java package

reviewOutput.coverageLevel = coverageLevel.name();

ParticipationResults participationResults =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ private static Dashboard.ReviewNotification[] getOnePathDash(
String baseXp, CLDRLocale locale, CookieSession mySession) {
Level coverageLevel = Level.get(mySession.getEffectiveCoverageLevel(locale.toString()));
Dashboard.ReviewOutput ro =
new Dashboard().get(locale, mySession.user, coverageLevel, baseXp);
new Dashboard().get(locale, mySession.user, coverageLevel, baseXp, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nit

Suggested change
new Dashboard().get(locale, mySession.user, coverageLevel, baseXp, false);
new Dashboard().get(locale, mySession.user, coverageLevel, baseXp, false /* includeOther */);

return ro.getNotifications();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public enum NotificationCategory {

/** You have abstained, or not yet voted for any value */
abstained('A', "Abstained", "You have abstained, or not yet voted for any value."),
;

other('O', "Other", "All other values");
Comment on lines -60 to +61
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's without errors, warnings and it isn't abstained, that this group should be thought of as "voted, no issues"? To keep the name minimal we can call it other, but I wonder if we should make it clearer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • It's not 'voted' if the user's logged out.
  • How about just "No Issues"?


public final char abbreviation;
public final String buttonLabel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,37 +480,45 @@ private void handleOnePath(String path) {
(baselineFileUnresolved == null)
? null
: baselineFileUnresolved.getWinningValue(path);
if (skipForLimitedSubmission(path, errorStatus, oldValue)) {
return;
final boolean skip = skipForLimitedSubmission(path, errorStatus, oldValue);
if (!skip) {
if (!onlyRecordErrors
&& choices.contains(NotificationCategory.changedOldValue)
&& changedFromBaseline(path, value, oldValue, sourceFile)) {
problems.add(NotificationCategory.changedOldValue);
vc.problemCounter.increment(NotificationCategory.changedOldValue);
}
if (!onlyRecordErrors
&& choices.contains(NotificationCategory.inheritedChanged)
&& inheritedChangedFromBaseline(path, value, sourceFile)) {
problems.add(NotificationCategory.inheritedChanged);
vc.problemCounter.increment(NotificationCategory.inheritedChanged);
}
VoteResolver.VoteStatus voteStatus =
userVoteStatus.getStatusForUsersOrganization(
sourceFile, path, organization);
boolean itemsOkIfVoted = (voteStatus == VoteResolver.VoteStatus.ok);
MissingStatus missingStatus =
onlyRecordErrors
? null
: recordMissingChangedEtc(path, itemsOkIfVoted, value, oldValue);
recordChoice(errorStatus, itemsOkIfVoted, onlyRecordErrors);
if (!onlyRecordErrors) {
recordLosingDisputedEtc(path, voteStatus, missingStatus);
}
}
if (!onlyRecordErrors
&& choices.contains(NotificationCategory.changedOldValue)
&& changedFromBaseline(path, value, oldValue, sourceFile)) {
problems.add(NotificationCategory.changedOldValue);
vc.problemCounter.increment(NotificationCategory.changedOldValue);
}
if (!onlyRecordErrors
&& choices.contains(NotificationCategory.inheritedChanged)
&& inheritedChangedFromBaseline(path, value, sourceFile)) {
problems.add(NotificationCategory.inheritedChanged);
vc.problemCounter.increment(NotificationCategory.inheritedChanged);
}
VoteResolver.VoteStatus voteStatus =
userVoteStatus.getStatusForUsersOrganization(sourceFile, path, organization);
boolean itemsOkIfVoted = (voteStatus == VoteResolver.VoteStatus.ok);
MissingStatus missingStatus =
onlyRecordErrors
? null
: recordMissingChangedEtc(path, itemsOkIfVoted, value, oldValue);
recordChoice(errorStatus, itemsOkIfVoted, onlyRecordErrors);
if (!onlyRecordErrors) {
recordLosingDisputedEtc(path, voteStatus, missingStatus);
// add the catch-all value
if (!pathLevelIsTooHigh
&& problems.isEmpty()
&& choices.contains(NotificationCategory.other)) {
problems.add(NotificationCategory.other);
}
if (pathLevelIsTooHigh && problems.isEmpty()) {
return;
}
updateVotedOrAbstained(path);

if (!skip) {
updateVotedOrAbstained(path);
}
if (!problems.isEmpty() && sorted != null) {
reasonsToPaths.clear();
R2<SectionId, PageId> group = Row.of(ph.getSectionId(), ph.getPageId());
Expand Down Expand Up @@ -1705,9 +1713,9 @@ public static void getStatus(

public static EnumSet<NotificationCategory> getDashboardNotificationCategories(
Organization usersOrg) {
EnumSet<NotificationCategory> choiceSet = EnumSet.allOf(NotificationCategory.class);
EnumSet<NotificationCategory> choices = EnumSet.allOf(NotificationCategory.class);
if (orgIsNeutralForSummary(usersOrg)) {
choiceSet =
choices =
EnumSet.of(
NotificationCategory.error,
NotificationCategory.warning,
Expand All @@ -1716,14 +1724,16 @@ public static EnumSet<NotificationCategory> getDashboardNotificationCategories(
NotificationCategory.missingCoverage);
// skip weLost, englishChanged, changedOldValue, abstained
}
return choiceSet;
choices.remove(NotificationCategory.other); // expect this one to be added explicitly
return choices;
}

public static EnumSet<NotificationCategory> getPriorityItemsSummaryCategories(
Organization org) {
EnumSet<NotificationCategory> set = getDashboardNotificationCategories(org);
set.remove(NotificationCategory.abstained);
return set;
EnumSet<NotificationCategory> choices = getDashboardNotificationCategories(org);
choices.remove(NotificationCategory.abstained);
choices.remove(NotificationCategory.other); // expect this one to be added explicitly
return choices;
}

public static EnumSet<NotificationCategory> getLocaleCompletionCategories() {
Expand Down
Loading