From 44267619b60e8ff8fcdb7579462022be187a56cc Mon Sep 17 00:00:00 2001 From: IMB11 Date: Wed, 16 Jul 2025 23:28:42 +0100 Subject: [PATCH] Author Validation Improvements (#3970) * feat: set up typed nag (validators) system * feat: start on frontend impl * fix: shouldShow issues * feat: continue work * feat: re add submitting/re-submit nags * feat: start work implementing validation checks using new nag system * fix: links page + add more validations * feat: tags validations * fix: lint issues * fix: lint * fix: issues * feat: start on i18nifying nags * feat: impl intl * fix: minecraft title clause update --------- Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> --- apps/frontend/nuxt.config.ts | 35 +- .../src/components/ui/ProjectMemberHeader.vue | 816 ++++++++---------- apps/frontend/src/locales/en-US/index.json | 63 ++ .../[type]/[id]/settings/description.vue | 18 +- .../src/pages/[type]/[id]/settings/index.vue | 26 +- .../src/pages/[type]/[id]/settings/links.vue | 39 +- .../src/pages/[type]/[id]/settings/tags.vue | 318 ++++--- packages/moderation/README.md | 145 +++- packages/moderation/data/nags.ts | 7 + packages/moderation/data/nags/core.i18n.ts | 116 +++ packages/moderation/data/nags/core.ts | 151 ++++ .../moderation/data/nags/description.i18n.ts | 88 ++ packages/moderation/data/nags/description.ts | 226 +++++ packages/moderation/data/nags/index.ts | 4 + packages/moderation/data/nags/links.i18n.ts | 48 ++ packages/moderation/data/nags/links.ts | 155 ++++ packages/moderation/data/nags/tags.i18n.ts | 35 + packages/moderation/data/nags/tags.ts | 107 +++ packages/moderation/index.ts | 3 + packages/moderation/locales/en-US/index.json | 191 ++++ packages/moderation/package.json | 7 +- packages/moderation/types/nags.ts | 96 +++ pnpm-lock.yaml | 178 +++- 23 files changed, 2212 insertions(+), 660 deletions(-) create mode 100644 packages/moderation/data/nags.ts create mode 100644 packages/moderation/data/nags/core.i18n.ts create mode 100644 packages/moderation/data/nags/core.ts create mode 100644 packages/moderation/data/nags/description.i18n.ts create mode 100644 packages/moderation/data/nags/description.ts create mode 100644 packages/moderation/data/nags/index.ts create mode 100644 packages/moderation/data/nags/links.i18n.ts create mode 100644 packages/moderation/data/nags/links.ts create mode 100644 packages/moderation/data/nags/tags.i18n.ts create mode 100644 packages/moderation/data/nags/tags.ts create mode 100644 packages/moderation/locales/en-US/index.json create mode 100644 packages/moderation/types/nags.ts diff --git a/apps/frontend/nuxt.config.ts b/apps/frontend/nuxt.config.ts index 354bff294..e84ae0c0f 100644 --- a/apps/frontend/nuxt.config.ts +++ b/apps/frontend/nuxt.config.ts @@ -34,7 +34,7 @@ const enabledLocales: string[] = []; /** * Overrides for the categories of the certain locales. */ -const localesCategoriesOverrides: Partial> = { +const localesCategoriesOverrides: Partial = { "en-x-pirate": "fun", "en-x-updown": "fun", "en-x-lolcat": "fun", @@ -260,21 +260,28 @@ export default defineNuxtConfig({ const omorphiaLocales: string[] = []; const omorphiaLocaleSets = new Map(); - for await (const localeDir of globIterate("node_modules/@modrinth/ui/src/locales/*", { - posix: true, - })) { - const tag = basename(localeDir); - omorphiaLocales.push(tag); + const externalLocales = [ + "node_modules/@modrinth/ui/src/locales/en-US", + "node_modules/@modrinth/moderation/locales/en-US", + ]; - const localeFiles: { from: string; format?: string }[] = []; + for (const localePath of externalLocales) { + for await (const localeDir of globIterate(localePath, { + posix: true, + })) { + const tag = basename(localeDir); + omorphiaLocales.push(tag); - omorphiaLocaleSets.set(tag, { files: localeFiles }); + const localeFiles: { from: string; format?: string }[] = []; - for await (const localeFile of globIterate(`${localeDir}/*`, { posix: true })) { - localeFiles.push({ - from: pathToFileURL(localeFile).toString(), - format: "default", - }); + omorphiaLocaleSets.set(tag, { files: localeFiles }); + + for await (const localeFile of globIterate(`${localeDir}/*`, { posix: true })) { + localeFiles.push({ + from: pathToFileURL(localeFile).toString(), + format: "default", + }); + } } } @@ -301,7 +308,7 @@ export default defineNuxtConfig({ format: "crowdin", }); } else if (fileName === "meta.json") { - const meta: Record = await fs + const meta: Record = await fs .readFile(localeFile, "utf8") .then((date) => JSON.parse(date)); const localeMeta = (locale.meta ??= {}); diff --git a/apps/frontend/src/components/ui/ProjectMemberHeader.vue b/apps/frontend/src/components/ui/ProjectMemberHeader.vue index 9bef20859..9afe2d16d 100644 --- a/apps/frontend/src/components/ui/ProjectMemberHeader.vue +++ b/apps/frontend/src/components/ui/ProjectMemberHeader.vue @@ -1,510 +1,442 @@ - diff --git a/apps/frontend/src/locales/en-US/index.json b/apps/frontend/src/locales/en-US/index.json index e6a708f7b..bf910c1e9 100644 --- a/apps/frontend/src/locales/en-US/index.json +++ b/apps/frontend/src/locales/en-US/index.json @@ -533,6 +533,69 @@ "profile.user-id": { "message": "User ID: {id}" }, + "project-member-header.accept": { + "message": "Accept" + }, + "project-member-header.decline": { + "message": "Decline" + }, + "project-member-header.error": { + "message": "Error" + }, + "project-member-header.error-decline": { + "message": "Failed to decline team invitation" + }, + "project-member-header.error-join": { + "message": "Failed to accept team invitation" + }, + "project-member-header.invitation-no-role": { + "message": "You've been invited to join this project. Please accept or decline the invitation." + }, + "project-member-header.invitation-title": { + "message": "Invitation to join project" + }, + "project-member-header.invitation-with-role": { + "message": "You've been invited be a member of this project with the role of '{role}'." + }, + "project-member-header.publishing-checklist": { + "message": "Publishing checklist" + }, + "project-member-header.required": { + "message": "Required" + }, + "project-member-header.resubmit-for-review": { + "message": "Resubmit for review" + }, + "project-member-header.resubmit-for-review-desc": { + "message": "Your project has been {status} by Modrinth's staff. In most cases, you can resubmit for review after addressing the staff's message." + }, + "project-member-header.submit-checklist-tooltip": { + "message": "You must complete the required steps in the publishing checklist!" + }, + "project-member-header.submit-for-review": { + "message": "Submit for review" + }, + "project-member-header.submit-for-review-desc": { + "message": "Your project is only viewable by members of the project. It must be reviewed by moderators in order to be published." + }, + "project-member-header.success": { + "message": "Success" + }, + "project-member-header.success-decline": { + "message": "You have declined the team invitation" + }, + "project-member-header.success-join": { + "message": "You have joined the project team" + }, + "project-member-header.suggestion": { + "message": "Suggestion" + }, + "project-member-header.visit-moderation-page": { + "message": "Visit moderation page" + }, + "project-member-header.warning": { + "message": "Warning" + }, "project-type.collection.plural": { "message": "Collections" }, diff --git a/apps/frontend/src/pages/[type]/[id]/settings/description.vue b/apps/frontend/src/pages/[type]/[id]/settings/description.vue index 174d4bc9c..45f0a8eb8 100644 --- a/apps/frontend/src/pages/[type]/[id]/settings/description.vue +++ b/apps/frontend/src/pages/[type]/[id]/settings/description.vue @@ -22,6 +22,10 @@ " :on-image-upload="onUploadHandler" /> +
+ + {{ descriptionWarning }} +