diff --git a/app/assets/javascripts/discourse/app/components/modal/create-account.js b/app/assets/javascripts/discourse/app/components/modal/create-account.js index 1efd081b796..ad56ee7495c 100644 --- a/app/assets/javascripts/discourse/app/components/modal/create-account.js +++ b/app/assets/javascripts/discourse/app/components/modal/create-account.js @@ -1,6 +1,7 @@ import { A } from "@ember/array"; import Component from "@ember/component"; import EmberObject, { action } from "@ember/object"; +import { dependentKeyCompat } from "@ember/object/compat"; import { alias, notEmpty } from "@ember/object/computed"; import { service } from "@ember/service"; import { isEmpty } from "@ember/utils"; @@ -9,9 +10,9 @@ import { Promise } from "rsvp"; import { ajax } from "discourse/lib/ajax"; import { setting } from "discourse/lib/computed"; import cookie, { removeCookie } from "discourse/lib/cookie"; +import NameValidationHelper from "discourse/lib/name-validation-helper"; import { userPath } from "discourse/lib/url"; import { emailValid } from "discourse/lib/utilities"; -import NameValidation from "discourse/mixins/name-validation"; import PasswordValidation from "discourse/mixins/password-validation"; import UserFieldsValidation from "discourse/mixins/user-fields-validation"; import UsernameValidation from "discourse/mixins/username-validation"; @@ -24,7 +25,6 @@ import { i18n } from "discourse-i18n"; export default class CreateAccount extends Component.extend( PasswordValidation, UsernameValidation, - NameValidation, UserFieldsValidation ) { @service site; @@ -41,6 +41,7 @@ export default class CreateAccount extends Component.extend( maskPassword = true; passwordValidationVisible = false; emailValidationVisible = false; + nameValidationHelper = new NameValidationHelper(this); @notEmpty("model.authOptions") hasAuthOptions; @setting("enable_local_logins") canCreateLocal; @@ -69,6 +70,19 @@ export default class CreateAccount extends Component.extend( } } + get nameTitle() { + return this.nameValidationHelper.nameTitle; + } + + get nameValidation() { + return this.nameValidationHelper.nameValidation; + } + + @dependentKeyCompat + get forceValidationReason() { + return this.nameValidationHelper.forceValidationReason; + } + @bind actionOnEnter(event) { if (!this.submitDisabled && event.key === "Enter") { @@ -510,7 +524,7 @@ export default class CreateAccount extends Component.extend( @action createAccount() { this.set("flash", ""); - this.set("forceValidationReason", true); + this.nameValidationHelper.forceValidationReason = true; this.set("emailValidationVisible", true); this.set("passwordValidationVisible", true); @@ -538,7 +552,7 @@ export default class CreateAccount extends Component.extend( return; } - this.set("forceValidationReason", false); + this.nameValidationHelper.forceValidationReason = false; this.performAccountCreation(); } } diff --git a/app/assets/javascripts/discourse/app/controllers/invites-show.js b/app/assets/javascripts/discourse/app/controllers/invites-show.js index 6a98e19b7da..f285e57fa1e 100644 --- a/app/assets/javascripts/discourse/app/controllers/invites-show.js +++ b/app/assets/javascripts/discourse/app/controllers/invites-show.js @@ -1,12 +1,13 @@ import Controller from "@ember/controller"; import EmberObject, { action } from "@ember/object"; +import { dependentKeyCompat } from "@ember/object/compat"; import { alias, bool, not, readOnly } from "@ember/object/computed"; import { isEmpty } from "@ember/utils"; import { ajax } from "discourse/lib/ajax"; import { extractError } from "discourse/lib/ajax-error"; +import NameValidationHelper from "discourse/lib/name-validation-helper"; import DiscourseURL from "discourse/lib/url"; import { emailValid } from "discourse/lib/utilities"; -import NameValidation from "discourse/mixins/name-validation"; import PasswordValidation from "discourse/mixins/password-validation"; import UserFieldsValidation from "discourse/mixins/user-fields-validation"; import UsernameValidation from "discourse/mixins/username-validation"; @@ -18,10 +19,10 @@ import { i18n } from "discourse-i18n"; export default class InvitesShowController extends Controller.extend( PasswordValidation, UsernameValidation, - NameValidation, UserFieldsValidation ) { queryParams = ["t"]; + nameValidationHelper = new NameValidationHelper(this); @readOnly("model.invited_by") invitedBy; @alias("model.email") email; @@ -44,6 +45,15 @@ export default class InvitesShowController extends Controller.extend( rejectedEmails = []; maskPassword = true; + get nameTitle() { + return this.nameValidationHelper.nameTitle; + } + + @dependentKeyCompat + get nameValidation() { + return this.nameValidationHelper.nameValidation; + } + authenticationComplete(options) { const props = { accountUsername: options.username, diff --git a/app/assets/javascripts/discourse/app/controllers/signup.js b/app/assets/javascripts/discourse/app/controllers/signup.js index 69aeebf39df..161c12489af 100644 --- a/app/assets/javascripts/discourse/app/controllers/signup.js +++ b/app/assets/javascripts/discourse/app/controllers/signup.js @@ -1,6 +1,7 @@ import { A } from "@ember/array"; import Controller from "@ember/controller"; import EmberObject, { action } from "@ember/object"; +import { dependentKeyCompat } from "@ember/object/compat"; import { notEmpty } from "@ember/object/computed"; import { service } from "@ember/service"; import { isEmpty } from "@ember/utils"; @@ -9,9 +10,9 @@ import { Promise } from "rsvp"; import { ajax } from "discourse/lib/ajax"; import { setting } from "discourse/lib/computed"; import cookie, { removeCookie } from "discourse/lib/cookie"; +import NameValidationHelper from "discourse/lib/name-validation-helper"; import { userPath } from "discourse/lib/url"; import { emailValid } from "discourse/lib/utilities"; -import NameValidation from "discourse/mixins/name-validation"; import PasswordValidation from "discourse/mixins/password-validation"; import UserFieldsValidation from "discourse/mixins/user-fields-validation"; import UsernameValidation from "discourse/mixins/username-validation"; @@ -24,7 +25,6 @@ import { i18n } from "discourse-i18n"; export default class SignupPageController extends Controller.extend( PasswordValidation, UsernameValidation, - NameValidation, UserFieldsValidation ) { @service site; @@ -41,6 +41,7 @@ export default class SignupPageController extends Controller.extend( maskPassword = true; passwordValidationVisible = false; emailValidationVisible = false; + nameValidationHelper = new NameValidationHelper(this); @notEmpty("authOptions") hasAuthOptions; @setting("enable_local_logins") canCreateLocal; @@ -56,6 +57,19 @@ export default class SignupPageController extends Controller.extend( this.fetchConfirmationValue(); } + get nameTitle() { + return this.nameValidationHelper.nameTitle; + } + + get nameValidation() { + return this.nameValidationHelper.nameValidation; + } + + @dependentKeyCompat + get forceValidationReason() { + return this.nameValidationHelper.forceValidationReason; + } + @bind actionOnEnter(event) { if (!this.submitDisabled && event.key === "Enter") { @@ -502,7 +516,7 @@ export default class SignupPageController extends Controller.extend( @action createAccount() { this.set("flash", ""); - this.set("forceValidationReason", true); + this.nameValidationHelper.forceValidationReason = true; this.set("emailValidationVisible", true); this.set("passwordValidationVisible", true); @@ -530,7 +544,7 @@ export default class SignupPageController extends Controller.extend( return; } - this.set("forceValidationReason", false); + this.nameValidationHelper.forceValidationReason = false; this.performAccountCreation(); } } diff --git a/app/assets/javascripts/discourse/app/lib/name-validation-helper.js b/app/assets/javascripts/discourse/app/lib/name-validation-helper.js new file mode 100644 index 00000000000..13d18e8bdcf --- /dev/null +++ b/app/assets/javascripts/discourse/app/lib/name-validation-helper.js @@ -0,0 +1,36 @@ +import { tracked } from "@glimmer/tracking"; +import { isEmpty } from "@ember/utils"; +import { i18n } from "discourse-i18n"; + +export default class NameValidationHelper { + @tracked forceValidationReason = false; + + constructor(owner) { + this.owner = owner; + } + + get nameTitle() { + return i18n( + this.owner.site.full_name_required_for_signup + ? "user.name.title" + : "user.name.title_optional" + ); + } + + get nameValidation() { + if ( + this.owner.site.full_name_required_for_signup && + isEmpty(this.owner.get("accountName")) + ) { + return { + failed: true, + ok: false, + message: i18n("user.name.required"), + reason: this.forceValidationReason ? i18n("user.name.required") : null, + element: document.querySelector("#new-account-name"), + }; + } + + return { ok: true }; + } +} diff --git a/app/assets/javascripts/discourse/app/mixins/name-validation.js b/app/assets/javascripts/discourse/app/mixins/name-validation.js index 3677e7347d1..834fd1458bb 100644 --- a/app/assets/javascripts/discourse/app/mixins/name-validation.js +++ b/app/assets/javascripts/discourse/app/mixins/name-validation.js @@ -1,9 +1,22 @@ import EmberObject, { computed } from "@ember/object"; import Mixin from "@ember/object/mixin"; import { isEmpty } from "@ember/utils"; +import deprecated from "discourse-common/lib/deprecated"; import { i18n } from "discourse-i18n"; export default Mixin.create({ + init() { + this._super(...arguments); + + deprecated( + "NameValidation mixin is deprecated. Use the helper class from discourse/lib/name-validation-helper instead.", + { + id: "discourse.name-validation-mixin", + since: "v3.4.0.beta4-dev", + } + ); + }, + get nameTitle() { return i18n( this.site.full_name_required_for_signup diff --git a/app/assets/javascripts/discourse/app/templates/invites/show.hbs b/app/assets/javascripts/discourse/app/templates/invites/show.hbs index 1c1f9ea6b4d..49010cc7658 100644 --- a/app/assets/javascripts/discourse/app/templates/invites/show.hbs +++ b/app/assets/javascripts/discourse/app/templates/invites/show.hbs @@ -17,7 +17,9 @@ {{else}}
{{i18n "invites.invited_by"}}
-
+