translateMessages preparations

This commit is contained in:
Niels Lyngsø
2024-04-09 10:56:16 +02:00
parent f157c3ca39
commit 44ec3be4dc
9 changed files with 73 additions and 18 deletions

View File

@@ -6,6 +6,20 @@ export type UmbEntityBase = {
name?: string;
};
export interface UmbVariantableValueModel<T = unknown> extends UmbInvariantValueModel<T> {
culture?: string | null;
segment?: string | null;
}
export interface UmbVariantValueModel<T = unknown> extends UmbInvariantValueModel<T> {
culture: string | null;
segment: string | null;
}
export interface UmbInvariantValueModel<T = unknown> {
alias: string;
value: T;
}
export interface UmbSwatchDetails {
label: string;
value: string;

View File

@@ -1,3 +1,4 @@
import type { UmbValidationMessageTranslator } from '../interfaces/validation-message-translator.interface.js';
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import { UmbId } from '@umbraco-cms/backoffice/id';
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
@@ -11,12 +12,37 @@ export interface UmbValidationMessage {
}
export class UmbValidationMessagesManager {
#translators: Array<UmbValidationMessageTranslator> = [];
#messages = new UmbArrayState<UmbValidationMessage>([], (x) => x.key);
/*
constructor() {
this.#messages.asObservable().subscribe((x) => console.log('messages:', x));
}
addTranslator(translator: UmbValidationMessageTranslator): void {
if (this.#translators.indexOf(translator) === -1) {
this.#translators.push(translator);
}
}
removeTranslator(translator: UmbValidationMessageTranslator): void {
const index = this.#translators.indexOf(translator);
if (index !== -1) {
this.#translators.splice(index, 1);
}
}
/*
serializeMessages(fromPath: string, toPath: string): void {
this.#messages.setValue(
this.#messages.getValue().map((x) => {
if (x.path.indexOf(fromPath) === 0) {
x.path = toPath + x.path.substring(fromPath.length);
}
return x;
}),
);
}
*/
getHasAnyMessages(): boolean {
@@ -64,9 +90,7 @@ export class UmbValidationMessagesManager {
}
addMessages(type: UmbValidationMessageType, path: string, messages: Array<string>): void {
messages.forEach((message) => {
this.#messages.appendOne({ type, key: UmbId.new(), path, message });
});
this.#messages.append(messages.map((message) => ({ type, key: UmbId.new(), path, message })));
}
/*

View File

@@ -64,6 +64,7 @@ export class UmbValidationContext extends UmbContextBase<UmbValidationContext> i
* @returns succeed {Promise<boolean>} - Returns a promise that resolves to true if the validator succeeded, this depends on the validators and wether forceSucceed is set.
*/
async validate(): Promise<boolean> {
// TODO: clear server messages here?, well maybe only if we know we will get new server messages? Do the server messages hook into the system like another validator?
this.#validationMode = true;
const results = await Promise.all(this.#validators.map((v) => v.validate()));

View File

@@ -1 +1,2 @@
export type * from './validator.interface.js';
export type * from './validation-message-translator.interface.js';

View File

@@ -0,0 +1,4 @@
export interface UmbValidationMessageTranslator {
match(message: string): boolean;
translate(message: string): string;
}

View File

@@ -0,0 +1,19 @@
import type { UmbVariantableValueModel } from '@umbraco-cms/backoffice/models';
/**
* write a JSON-Path filter similar to `?(@.alias = 'myAlias' && @.culture == 'en-us' && @.segment == 'mySegment')`
* where culture and segment are optional
* @param property
* @returns
*/
export function UmbDataPathValueFilter(property: Partial<UmbVariantableValueModel>): string {
// write a array of strings for each property, where alias must be present and culture and segment are optional
const filters: Array<string> = [`@.alias = '${property.alias}'`];
if (property.culture) {
filters.push(`@.culture == '${property.culture}'`);
}
if (property.segment) {
filters.push(`@.segment == '${property.segment}'`);
}
return `?(${filters.join(' && ')})`;
}

View File

@@ -18,7 +18,7 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
// TODO: We could make a base type for workspace modal data, and use this here: As well as a base for the result, to make sure we always include the unique (instead of the object type)
public readonly modalContext?: UmbModalContext<{ preset: object }>;
readonly #validation = new UmbValidationContext(this);
public readonly validation = new UmbValidationContext(this);
#submitPromise: Promise<void> | undefined;
#submitResolve: (() => void) | undefined;
@@ -48,17 +48,8 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
});
}
/*
protected passValidation() {
this.#validation.preventFail();
}
protected failValidation() {
this.#validation.allowFail();
}
*/
protected resetState() {
this.#validation.reset();
this.validation.reset();
this.#isNew.setValue(undefined);
}
@@ -85,7 +76,7 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
this.#submitResolve = resolve;
this.#submitReject = reject;
});
this.#validation.validate().then(
this.validation.validate().then(
async () => {
onValid().then(this.#completeSubmit, this.#rejectSubmit);
},
@@ -125,7 +116,7 @@ export abstract class UmbSubmittableWorkspaceContextBase<WorkspaceDataModelType>
this.#resolveSubmit();
// Calling reset on the validation context here. [NL]
this.#validation.reset();
this.validation.reset();
};
//abstract getIsDirty(): Promise<boolean>;

View File

@@ -44,8 +44,9 @@ export class UmbPropertyEditorConfigElement extends UmbLitElement {
this._properties,
(property) => property.alias,
(property, index) =>
// TODO: Make a helper method to generate data-path entry for a property.
html`<umb-property
.dataPath="values[${index}]"
.dataPath="values[?(@.alias = '${property.alias}'}]"
label=${property.label}
description=${ifDefined(property.description)}
alias=${property.alias}