Multi URL Picker: change validation for url and anchor/querystring (#20920)

* Fix validation for url and anchor of multi url picker

* fix codesence warning

* remove redundant validation

---------

Co-authored-by: Lan Nguyen Thuy <lnt@umbraco.dk>
This commit is contained in:
NguyenThuyLan
2025-11-25 17:07:21 +07:00
committed by GitHub
parent cf265e248b
commit a41c48ad6c

View File

@@ -8,7 +8,6 @@ import { css, customElement, html, nothing, query, state, when } from '@umbraco-
import { isUmbracoFolder, UmbMediaTypeStructureRepository } from '@umbraco-cms/backoffice/media-type'; import { isUmbracoFolder, UmbMediaTypeStructureRepository } from '@umbraco-cms/backoffice/media-type';
import { import {
UMB_VALIDATION_CONTEXT, UMB_VALIDATION_CONTEXT,
umbBindToValidation,
UmbObserveValidationStateController, UmbObserveValidationStateController,
UmbValidationContext, UmbValidationContext,
type UmbValidator, type UmbValidator,
@@ -42,7 +41,6 @@ class UmbLinkPickerValueValidator extends UmbControllerBase implements UmbValida
setValue(value: unknown) { setValue(value: unknown) {
this.#value = value; this.#value = value;
this.validate();
} }
getValue(): unknown { getValue(): unknown {
@@ -139,10 +137,22 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
const validator = new UmbLinkPickerValueValidator(this, '$.type'); const validator = new UmbLinkPickerValueValidator(this, '$.type');
this.observe(this.modalContext?.value, (value) => { this.observe(this.modalContext?.value, (value) => {
validator.setValue(value?.link.type); const validatorValue = this.#getValidatorValue(value);
validator.setValue(validatorValue);
}); });
} }
#getValidatorValue(value: UmbLinkPickerModalValue | undefined) {
const { type, queryString: anchor, url } = value?.link ?? {};
const hasContent = anchor || url;
if (type === 'external') {
return hasContent ? type : null;
}
return type || anchor || null;
}
async #getMediaTypes() { async #getMediaTypes() {
// Get all the media types, excluding the folders, so that files are selectable media items. // Get all the media types, excluding the folders, so that files are selectable media items.
const mediaTypeStructureRepository = new UmbMediaTypeStructureRepository(this); const mediaTypeStructureRepository = new UmbMediaTypeStructureRepository(this);
@@ -183,6 +193,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
const query = (event.target.value as string) ?? ''; const query = (event.target.value as string) ?? '';
if (query.startsWith('#') || query.startsWith('?')) { if (query.startsWith('#') || query.startsWith('?')) {
this.#partialUpdateLink({ queryString: query }); this.#partialUpdateLink({ queryString: query });
this.#validationContext.messages.removeMessageByKey('UmbLinkPickerValueValidator');
return; return;
} }
@@ -193,6 +204,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
} else { } else {
this.#partialUpdateLink({ queryString: '' }); this.#partialUpdateLink({ queryString: '' });
} }
this.#validationContext.messages.removeMessageByKey('UmbLinkPickerValueValidator');
} }
#onLinkTitleInput(event: UUIInputEvent) { #onLinkTitleInput(event: UUIInputEvent) {
@@ -223,6 +235,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
type: 'external', type: 'external',
url, url,
}); });
this.#validationContext.messages.removeMessageByKey('UmbLinkPickerValueValidator');
} }
async #onPickerSelection(event: UmbInputPickerEvent, type: 'document' | 'media') { async #onPickerSelection(event: UmbInputPickerEvent, type: 'document' | 'media') {
@@ -272,8 +285,9 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
}; };
this.#partialUpdateLink(link); this.#partialUpdateLink(link);
if (unique) {
await this.#validationContext.validate(); this.#validationContext.messages.removeMessageByKey('UmbLinkPickerValueValidator');
}
} }
async #getUrlForDocument(unique: string) { async #getUrlForDocument(unique: string) {
@@ -353,7 +367,6 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
<umb-property-layout <umb-property-layout
orientation=${this.#propertyLayoutOrientation} orientation=${this.#propertyLayoutOrientation}
label=${this.localize.term('linkPicker_modalSource')} label=${this.localize.term('linkPicker_modalSource')}
mandatory
?invalid=${this._missingLinkUrl}> ?invalid=${this._missingLinkUrl}>
<div slot="editor"> <div slot="editor">
${this.#renderLinkTypeSelection()} ${this.#renderDocumentPicker()} ${this.#renderMediaPicker()} ${this.#renderLinkTypeSelection()} ${this.#renderDocumentPicker()} ${this.#renderMediaPicker()}
@@ -417,9 +430,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
placeholder=${this.localize.term('placeholders_enterUrl')} placeholder=${this.localize.term('placeholders_enterUrl')}
.value=${this.value.link.url ?? ''} .value=${this.value.link.url ?? ''}
?disabled=${!!this.value.link.unique} ?disabled=${!!this.value.link.unique}
required
@input=${this.#onLinkUrlInput} @input=${this.#onLinkUrlInput}
${umbBindToValidation(this)}
${umbFocus()}> ${umbFocus()}>
${when( ${when(
!this.value.link.unique, !this.value.link.unique,
@@ -449,6 +460,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
return html` return html`
<umb-property-layout <umb-property-layout
orientation=${this.#propertyLayoutOrientation} orientation=${this.#propertyLayoutOrientation}
?invalid=${this._missingLinkUrl}
label=${this.localize.term('defaultdialogs_anchorLinkPicker')}> label=${this.localize.term('defaultdialogs_anchorLinkPicker')}>
<uui-input <uui-input
data-mark="input:anchor" data-mark="input:anchor"
@@ -456,7 +468,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
label=${this.localize.term('placeholders_anchor')} label=${this.localize.term('placeholders_anchor')}
placeholder=${this.localize.term('placeholders_anchor')} placeholder=${this.localize.term('placeholders_anchor')}
.value=${this.value.link.queryString ?? ''} .value=${this.value.link.queryString ?? ''}
@change=${this.#onLinkAnchorInput}></uui-input> @input=${this.#onLinkAnchorInput}></uui-input>
</umb-property-layout> </umb-property-layout>
`; `;
} }