Skip to content
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: 4 additions & 3 deletions lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
"Admin.EditChallenge.form.includeCheckinHashtag.value.true.label": "Automatically append `#maproulette` hashtag (highly recommended)",
"Admin.EditChallenge.form.instruction.description": "The instruction tells a mapper how to resolve a Task in your Challenge. This is what mappers see in the Instructions box every time a task is loaded, and is the primary piece of information for the mapper about how to solve the task, so think about this field carefully. You can include links to the OSM wiki or any other hyperlink if you want, because this field supports [Markdown](https://learn.maproulette.org/documentation/markdown/). You can also reference feature properties from your GeoJSON with simple [mustache tags](https://learn.maproulette.org/documentation/mustache-tag-replacement/): e.g. `'{{address}}'` would be replaced with the value of the `address` property, allowing for basic customization of instructions for each task. This field is required.",
"Admin.EditChallenge.form.instruction.label": "Detailed Instructions for Mappers",
"Admin.EditChallenge.form.instructionsDescription": "Instructions must be longer than {minLength} characters.",
"Admin.EditChallenge.form.instructionsDescription": "We recommend instructions be longer than {minLength} characters.",
"Admin.EditChallenge.form.limitReviewTags.description": "Allow other tags during task review?",
"Admin.EditChallenge.form.limitTags.description": "Allow other tags during task completion?",
"Admin.EditChallenge.form.localGeoJson.description": "Please upload the local GeoJSON file from your computer",
Expand Down Expand Up @@ -924,14 +924,14 @@
"Form.textUpload.promptGeoJSON": "Drop GeoJSON file here or click to select file",
"Form.textUpload.promptJSON": "Drop JSON file here or click to select file",
"Form.textUpload.readonly": "Existing file will be used",
"GeoJSONUploadModal.countingTasks": "Counting tasks…",
"GeoJSONUploadModal.dropzone.label": "Drop a GeoJSON file here or click to upload",
"GeoJSONUploadModal.error.invalid": "Invalid GeoJSON: {error}",
"GeoJSONUploadModal.error.noPolygons": "No Polygon features found in file",
"GeoJSONUploadModal.error.tooManyTasks": "Too many tasks ({count}). Maximum allowed is {max}.",
"GeoJSONUploadModal.header": "Create Virtual Challenge from GeoJSON",
"GeoJSONUploadModal.success.polygonsLoaded": "{count, plural, one {# polygon} other {# polygons}} loaded",
"GeoJSONUploadModal.taskCount": "{count, plural, one {# task} other {# tasks}} found in area",
"GeoJSONUploadModal.countingTasks": "Counting tasks\u2026",
"GeoJSONUploadModal.error.tooManyTasks": "Too many tasks ({count}). Maximum allowed is {max}.",
"GlobalActivity.title": "Global Activity",
"Grant.Role.admin": "Admin",
"Grant.Role.read": "Read",
Expand Down Expand Up @@ -1510,6 +1510,7 @@
"WidgetWorkspace.controls.editConfiguration.label": "Edit Layout",
"WidgetWorkspace.controls.exportConfiguration.label": "Export Layout",
"WidgetWorkspace.controls.importConfiguration.label": "Import Layout",
"WidgetWorkspace.controls.layoutName.label": "Layout Name",
"WidgetWorkspace.controls.resetConfiguration.label": "Reset Layout to Default",
"WidgetWorkspace.controls.saveAsDefault.label": "Save as My Default",
"WidgetWorkspace.controls.saveConfiguration.label": "Done Editing",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ export class EditChallenge extends Component {
.finally(() => {
this.validationPromise = null;
});

return errors;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ will not be able to make sense of it.

instructionsDescription: {
id: "Admin.EditChallenge.form.instructionsDescription",
defaultMessage: "Instructions must be longer than {minLength} characters.",
defaultMessage: "We recommend instructions be longer than {minLength} characters.",
},

nameDescription: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,13 @@ const validateMinLength = (val) => {
};

export const jsSchema = (intl) => {
const minLengthEnvValue = window.env.REACT_APP_CHALLENGE_INSTRUCTIONS_MIN_LENGTH;
const instructionsMinLength = validateMinLength(minLengthEnvValue);

const schemaFields = {
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
instruction: {
title: intl.formatMessage(messages.instructionLabel),
type: "string",
minLength: instructionsMinLength,
description: intl.formatMessage(messages.instructionsDescription, {
minLength: `${instructionsMinLength}`,
}),
},
difficulty: {
title: intl.formatMessage(messages.difficultyLabel),
Expand Down Expand Up @@ -75,12 +68,19 @@ export const jsSchema = (intl) => {
* > proper markup
*/
export const uiSchema = (intl, user, challengeData, extraErrors, options = {}) => {
const minLengthEnvValue = 150;
const instructionsMinLength = validateMinLength(minLengthEnvValue);

const uiSchemaFields = {
"ui:order": ["instruction", "difficulty"],
instruction: {
"ui:field": "markdown",
"ui:help": intl.formatMessage(messages.instructionDescription),
"ui:previewNote": intl.formatMessage(messages.addMustachePreviewNote),
"ui:recommendedMinLength": instructionsMinLength,
"ui:recommendedMinLengthMessage": intl.formatMessage(messages.instructionsDescription, {
minLength: `${instructionsMinLength}`,
}),
"ui:groupHeader": options.longForm
? intl.formatMessage(messages.instructionsStepHeader)
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,19 @@ export const MarkdownEditField = (props) => {
const [showingPreview, setShowingPreview] = useState(false);
const [formValues, setFormValues] = useState({});

const recommendedMinLength = props.uiSchema["ui:recommendedMinLength"];
const recommendedMinLengthMessage = props.uiSchema["ui:recommendedMinLengthMessage"];
const isBelowRecommended =
recommendedMinLength > 0 && (props.formData || "").length < recommendedMinLength;

return (
<Fragment>
<LabelWithHelp {...props} />
{isBelowRecommended && recommendedMinLengthMessage && (
<div className="mr-text-orange mr-text-xs mr-mb-2">
{recommendedMinLengthMessage} (current character count: {(props.formData || "").length})
</div>
)}
<div className="mr-flex mr-items-center mr-mb-2 mr-leading-tight mr-text-xxs">
<button
type="button"
Expand Down
10 changes: 2 additions & 8 deletions src/services/Challenge/Challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -1043,14 +1043,11 @@ export const saveChallenge = function (originalChallengeData, storeResponse = tr
}

// Validate the fields before saving
const { instruction, description, name, checkinComment } = challengeData;
const { description, name, checkinComment } = challengeData;

const instructionsMinLength = window.env.REACT_APP_CHALLENGE_INSTRUCTIONS_MIN_LENGTH || 150;
if (
challengeData.parent != undefined &&
(!instruction ||
instruction.length < instructionsMinLength ||
!description?.trim()?.length ||
(!description?.trim()?.length ||
!name ||
name.length <= 3 ||
!checkinComment ||
Expand All @@ -1062,9 +1059,6 @@ export const saveChallenge = function (originalChallengeData, storeResponse = tr
errorMessage = AppErrors.challengeSaveFailure.saveNameFailure;
} else if (description === undefined || description === "") {
errorMessage = AppErrors.challengeSaveFailure.saveDescriptionFailure;
} else if (instruction === undefined || instruction.length < instructionsMinLength) {
errorMessage = AppErrors.challengeSaveFailure.saveInstructionsFailure;
errorMessage.values = { minLength: `${instructionsMinLength}` };
} else if (
checkinComment === undefined ||
checkinComment === "" ||
Expand Down
Loading