diff --git a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts index 59efba5054..69cda7ce89 100644 --- a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts +++ b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts @@ -8,8 +8,7 @@ export const manifests: Array = [ api: () => import('./custom-ufm-component.js'), meta: { alias: 'myCustomComponent', - marker: '%', - alias: 'myCustomComponent', + marker: '%' }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/de-ch.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/de-ch.ts new file mode 100644 index 0000000000..cd33f22eab --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/de-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: de_CH + * Language Int Name: German Switzerland (DE-CH) + * Language Local Name: Deutsch Schweiz (DE-CH) + * Language LCID: 7 + * Language Culture: de-CH + */ +import de_de from './de-de.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the German (Germany) localizations, so that any German (Switzerland) localizations can be override them. [LK] + ...de_de, +} as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 27fb01708b..e5a5eeadc2 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -1978,7 +1978,7 @@ export default { passwordCurrent: 'Current password', passwordInvalid: 'Invalid current password', passwordIsDifferent: - 'There was a difference between the new password and the confirmed password. Please\n try again!\n ', + 'There was a difference between the new password and the confirmed password. Please try again!', passwordMismatch: "The confirmed password doesn't match the new password!", passwordRequiresDigit: "The password must have at least one digit ('0'-'9')", passwordRequiresLower: "The password must have at least one lowercase ('a'-'z')", diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/fr-ch.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/fr-ch.ts new file mode 100644 index 0000000000..712e9fc0fd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/fr-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: fr_ch + * Language Int Name: French Switzerland (FR-CH) + * Language Local Name: Français Suisse (FR-CH) + * Language LCID: 12 + * Language Culture: fr-CH + */ +import fr_fr from './fr-fr.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the French (France) localizations, so that any French (Switzerland) localizations can be override them. [LK] + ...fr_fr, +} as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/it-ch.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/it-ch.ts new file mode 100644 index 0000000000..bdba6cf8c1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/it-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: it_ch + * Language Int Name: Italian Switzerland (IT-CH) + * Language Local Name: Italiano Svizerra (IT-CH) + * Language LCID: 16 + * Language Culture: it-CH + */ +import it_it from './it-it.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the Italian (Italy) localizations, so that any Italian (Switzerland) localizations can be override them. [LK] + ...it_it, +} as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/localization/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/localization/manifests.ts index 576c677f65..e8741a538a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/localization/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/localization/manifests.ts @@ -61,6 +61,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/de-de.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.De-CH', + weight: -100, + name: 'Deutsch (Schweiz)', + meta: { + culture: 'de-ch', + }, + js: () => import('../../../assets/lang/de-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.En-GB', @@ -101,6 +111,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/fr-fr.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.Fr-CH', + weight: -100, + name: 'Français (Suisse)', + meta: { + culture: 'fr-ch', + }, + js: () => import('../../../assets/lang/fr-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.He-IL', @@ -131,6 +151,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/it-it.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.It-CH', + weight: -100, + name: 'Italiano (Svizerra)', + meta: { + culture: 'it-ch', + }, + js: () => import('../../../assets/lang/it-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.Ja-JP', diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/change-password-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/change-password-modal.element.ts index bdff723460..d0fcbf4afd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/change-password-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/change-password-modal.element.ts @@ -1,18 +1,24 @@ import type { UmbChangePasswordModalData, UmbChangePasswordModalValue } from './change-password-modal.token.js'; -import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; -import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; -import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, query, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; +import type { UUIInputPasswordElement } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-change-password-modal') export class UmbChangePasswordModalElement extends UmbModalBaseElement< UmbChangePasswordModalData, UmbChangePasswordModalValue > { + @query('#newPassword') + private _newPasswordInput?: UUIInputPasswordElement; + + @query('#confirmPassword') + private _confirmPasswordInput?: UUIInputPasswordElement; + @state() - private _headline: string = 'Change password'; + private _headline: string = this.localize.term('general_changePassword'); @state() private _isCurrentUser: boolean = false; @@ -35,10 +41,8 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< const formData = new FormData(form); - // TODO: validate that the new password and confirm password match const oldPassword = formData.get('oldPassword') as string; const newPassword = formData.get('newPassword') as string; - //const confirmPassword = formData.get('confirmPassword') as string; this.value = { oldPassword, newPassword }; this.modalContext?.submit(); @@ -54,12 +58,7 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< } async #setIsCurrentUser() { - if (!this.data?.user.unique) { - this._isCurrentUser = false; - return; - } - - if (!this.#currentUserContext) { + if (!this.#currentUserContext || !this.data?.user.unique) { this._isCurrentUser = false; return; } @@ -67,7 +66,13 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< this._isCurrentUser = await this.#currentUserContext.isUserCurrentUser(this.data.user.unique); } - protected override async firstUpdated(): Promise { + protected override async firstUpdated() { + this._confirmPasswordInput?.addValidator( + 'customError', + () => this.localize.term('user_passwordMismatch'), + () => this._confirmPasswordInput?.value !== this._newPasswordInput?.value, + ); + if (!this.data?.user.unique) return; const { data } = await this.#userItemRepository.requestItems([this.data.user.unique]); @@ -81,55 +86,60 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< return html` -
- ${this._isCurrentUser ? this.#renderOldPasswordInput() : nothing} + + ${when( + this._isCurrentUser, + () => html` + + + Current password + + + + + `, + )} - New password + + New password + + required-message="New password is required"> + - Confirm password + + Confirm new password + + required-message="Confirm password is required"> +
- - + + look="primary" + label=${this.localize.term('general_confirm')}>
`; } - #renderOldPasswordInput() { - return html` - - Old password - - - `; - } - - static override styles: CSSResultGroup = [ + static override readonly styles = [ UmbTextStyles, css` uui-input-password { diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/manifests.ts index f08d08322a..b3e3f0c901 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/change-password/modal/manifests.ts @@ -3,6 +3,6 @@ export const manifests: Array = [ type: 'modal', alias: 'Umb.Modal.ChangePassword', name: 'Change Password Modal', - js: () => import('./change-password-modal.element.js'), + element: () => import('./change-password-modal.element.js'), }, ];