localization of query builder

This commit is contained in:
Lone Iversen
2023-12-13 12:10:54 +01:00
committed by Jacob Overgaard
parent e117289d0b
commit 98dd608f5c
3 changed files with 184 additions and 38 deletions

View File

@@ -1,5 +1,14 @@
import { localizeOperators, localizePropertyType } from './utils.js';
import { type UUIComboboxListElement } from '@umbraco-cms/backoffice/external/uui';
import { PropertyValueMap, css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import {
PropertyValueMap,
css,
html,
customElement,
property,
state,
ifDefined,
} from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import {
OperatorModel,
@@ -73,20 +82,23 @@ export class UmbQueryBuilderFilterElement extends UmbLitElement {
}
private _renderOperatorsDropdown() {
return html`<umb-dropdown look="outline" id="operator-dropdown" label="choose operator">
if (!this.settings?.operators) return;
const operators = localizeOperators(this.settings?.operators, this.currentPropertyType);
return html`<umb-dropdown look="outline" id="operator-dropdown" label="Choose operator">
<span slot="label">${this.filter?.operator ?? ''}</span>
<uui-combobox-list @change=${this.#setOperator} class="options-list">
${this.settings?.operators
${operators
?.filter((operator) =>
this.currentPropertyType ? operator.applicableTypes?.includes(this.currentPropertyType) : true,
)
.map(
(operator) =>
html`<uui-combobox-list-option .value=${(operator.operator as string) ?? ''}
>${operator.operator}</uui-combobox-list-option
>`,
)}</uui-combobox-list
>
html`<uui-combobox-list-option .value=${(operator.operator as string) ?? ''}>
<umb-localize .key=${operator.localizeKey!}> ${operator.operator} </umb-localize>
</uui-combobox-list-option>`,
)}
</uui-combobox-list>
</umb-dropdown>`;
}
@@ -104,26 +116,35 @@ export class UmbQueryBuilderFilterElement extends UmbLitElement {
}
render() {
const properties = localizePropertyType(this.settings?.properties);
return html`
<span>${this.unremovable ? this.localize.term('template_where') : this.localize.term('template_and')}</span>
<umb-dropdown look="outline" id="property-alias-dropdown" label="Property alias">
<span slot="label">${this.filter?.propertyAlias ?? ''}</span>
<uui-combobox-list @change=${this.#setPropertyAlias} class="options-list">
${this.settings?.properties?.map(
${properties?.map(
(property) =>
html`<uui-combobox-list-option tabindex="0" .value=${property.alias ?? ''}
>${property.alias}</uui-combobox-list-option
>`,
html`<uui-combobox-list-option tabindex="0" .value=${property.alias ?? ''}>
<umb-localize key=${ifDefined(property.localizeKey)}> ${property.alias}</umb-localize>
</uui-combobox-list-option>`,
)}
</uui-combobox-list></umb-dropdown
>
${this.filter?.propertyAlias ? this._renderOperatorsDropdown() : ''}
${this.filter?.operator ? this._renderConstraintValueInput() : ''}
<uui-button-group>
<uui-button title="Add filter" label="Add filter" compact @click=${this.#addFilter}>
<uui-button
title=${this.localize.term('general_add')}
label=${this.localize.term('general_add')}
compact
@click=${this.#addFilter}>
<uui-icon name="icon-add"></uui-icon>
</uui-button>
<uui-button title="Remove filter" label="Remove filter" compact @click=${this.#removeOrReset}>
<uui-button
title=${this.localize.term('general_remove')}
label=${this.localize.term('general_remove')}
compact
@click=${this.#removeOrReset}>
<uui-icon name="delete"></uui-icon>
</uui-button>
</uui-button-group>

View File

@@ -1,7 +1,8 @@
import { UmbTemplateRepository } from '../../repository/template.repository.js';
import { localizePropertyType, localizeSort } from './utils.js';
import type { UmbQueryBuilderFilterElement } from './query-builder-filter.element.js';
import { UUIComboboxListElement } from '@umbraco-cms/backoffice/external/uui';
import { css, html, customElement, state, query, queryAll } from '@umbraco-cms/backoffice/external/lit';
import { css, html, customElement, state, query, queryAll, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import {
UmbModalBaseElement,
UMB_DOCUMENT_PICKER_MODAL,
@@ -198,27 +199,33 @@ export default class UmbChooseInsertTypeModalElement extends UmbModalBaseElement
};
render() {
const properties = localizePropertyType(this._queryBuilderSettings?.properties);
const sort = localizeSort(this._queryRequest.sort);
return html`
<umb-body-layout headline="Query builder">
<div id="main">
<uui-box>
<div class="row">
I want
<umb-localize key="template_iWant">I want</umb-localize>
<umb-dropdown look="outline" id="content-type-dropdown" label="Choose content type">
<span slot="label">${this._queryRequest?.contentTypeAlias ?? 'all content'}</span>
<span slot="label">
${this._queryRequest?.contentTypeAlias ?? this.localize.term('template_allContent')}
</span>
<uui-combobox-list @change=${this.#setContentType} class="options-list">
<uui-combobox-list-option value="">all content</uui-combobox-list-option>
${this._queryBuilderSettings?.contentTypeAliases?.map(
(alias) =>
html`<uui-combobox-list-option .value=${alias}
>content of type "${alias}"</uui-combobox-list-option
>`,
html`<uui-combobox-list-option .value=${alias}>
<umb-localize key="template_contentOfType" .args=${[alias]}>
content of type "${alias}"
</umb-localize>
</uui-combobox-list-option>`,
)}
</uui-combobox-list></umb-dropdown
>
from
<uui-button look="outline" @click=${this.#openDocumentPicker} label="Choose root content"
>${this._selectedRootContentName}
<umb-localize key="template_from">from</umb-localize>
<uui-button look="outline" @click=${this.#openDocumentPicker} label="Choose root content">
${this._selectedRootContentName}
</uui-button>
</div>
<div id="filter-container">
@@ -231,30 +238,33 @@ export default class UmbChooseInsertTypeModalElement extends UmbModalBaseElement
@remove-filter=${this.#removeFilter}></umb-query-builder-filter>
</div>
<div class="row">
ordered by
<umb-localize key="template_orderBy">order by</umb-localize>
<umb-dropdown look="outline" id="sort-dropdown" label="Property alias">
<span slot="label">${this._queryRequest.sort?.propertyAlias ?? ''}</span>
<uui-combobox-list @change=${this.#setSortProperty} class="options-list">
${this._queryBuilderSettings?.properties?.map(
${properties?.map(
(property) =>
html`<uui-combobox-list-option .value=${property.alias ?? ''}
>${property.alias}</uui-combobox-list-option
>`,
html`<uui-combobox-list-option .value=${property.alias ?? ''}>
<umb-localize key=${ifDefined(property.localizeKey)}>${property.alias}</umb-localize>
</uui-combobox-list-option>`,
)}
</uui-combobox-list></umb-dropdown
>
</uui-combobox-list>
</umb-dropdown>
${this._queryRequest.sort?.propertyAlias
? html`<uui-button look="outline" @click=${this.#setSortDirection}
>${this._queryRequest.sort.direction ?? this._defaultSortDirection}</uui-button
>`
${sort?.propertyAlias
? html`<uui-button look="outline" @click=${this.#setSortDirection}>
<umb-localize key=${ifDefined(sort.localizeKey)}>
${sort.direction ?? this._defaultSortDirection}
</umb-localize>
</uui-button>`
: ''}
</div>
<div class="row">
<span id="results-count"
>${this._templateQuery?.resultCount ?? 0} items returned, in ${this._templateQuery?.executionTime ?? 0}
ms</span
>
<span id="results-count">
${this._templateQuery?.resultCount ?? 0}
<umb-localize key="template_itemsReturned">items returned, in</umb-localize>
${this._templateQuery?.executionTime ?? 0} ms
</span>
</div>
<umb-code-block language="C#" copy>${this._templateQuery?.queryExpression ?? ''}</umb-code-block>
</uui-box>

View File

@@ -0,0 +1,115 @@
import {
OperatorModel,
TemplateQueryExecuteSortModel,
TemplateQueryOperatorModel,
TemplateQueryPropertyPresentationModel,
TemplateQueryPropertyTypeModel,
UserOrderModel,
} from '@umbraco-cms/backoffice/backend-api';
type TemplateOperatorModel = TemplateQueryOperatorModel & { localizeKey?: string };
type TemplatePropertyModel = TemplateQueryPropertyPresentationModel & { localizeKey?: string };
type TemplateSortModel = TemplateQueryExecuteSortModel & { localizeKey?: string };
export function localizeOperators(
operators: Array<TemplateQueryOperatorModel>,
currentPropertyType: TemplateQueryPropertyTypeModel | null,
): Array<TemplateOperatorModel> {
switch (currentPropertyType) {
case TemplateQueryPropertyTypeModel.STRING:
return isString(operators);
case TemplateQueryPropertyTypeModel.INTEGER:
return isInteger(operators);
case TemplateQueryPropertyTypeModel.DATE_TIME:
return isDateTime(operators);
default:
return operators;
}
}
export function localizePropertyType(propertyTypes?: Array<TemplateQueryPropertyPresentationModel>) {
if (!propertyTypes) return;
return propertyTypes.map((propertyType): TemplatePropertyModel => {
switch (propertyType.alias) {
case UserOrderModel.NAME:
return { ...propertyType, localizeKey: 'template_name' };
case UserOrderModel.ID:
return { ...propertyType, localizeKey: 'template_id' };
case UserOrderModel.CREATE_DATE:
return { ...propertyType, localizeKey: 'template_createdDate' };
case UserOrderModel.UPDATE_DATE:
return { ...propertyType, localizeKey: 'template_lastUpdatedDate' };
default:
return propertyType;
}
});
}
export function localizeSort(sort?: TemplateQueryExecuteSortModel | null): TemplateSortModel | undefined {
if (!sort?.direction) return undefined;
switch (sort.direction) {
case 'ascending':
return { ...sort, localizeKey: 'template_ascending' };
case 'descending':
return { ...sort, localizeKey: 'template_descending' };
default:
return sort;
}
}
// Following code is for localization of operators (checks on property type);
function isString(operators: Array<TemplateQueryOperatorModel>): Array<TemplateOperatorModel> {
return operators.map((operator): TemplateOperatorModel => {
switch (operator.operator) {
case OperatorModel.EQUALS:
return { ...operator, localizeKey: 'template_is' };
case OperatorModel.NOT_EQUALS:
return { ...operator, localizeKey: 'template_isNot' };
case OperatorModel.CONTAINS:
return { ...operator, localizeKey: 'template_contains' };
case OperatorModel.NOT_CONTAINS:
return { ...operator, localizeKey: 'template_doesNotContain' };
default:
return operator;
}
});
}
function isInteger(operators: Array<TemplateQueryOperatorModel>): Array<TemplateOperatorModel> {
return operators.map((operator): TemplateOperatorModel => {
switch (operator.operator) {
case OperatorModel.EQUALS:
return { ...operator, localizeKey: 'template_equals' };
case OperatorModel.NOT_EQUALS:
return { ...operator, localizeKey: 'template_doesNotEqual' };
case OperatorModel.GREATER_THAN:
return { ...operator, localizeKey: 'template_greaterThan' };
case OperatorModel.GREATER_THAN_EQUAL_TO:
return { ...operator, localizeKey: 'template_greaterThanEqual' };
case OperatorModel.LESS_THAN:
return { ...operator, localizeKey: 'template_lessThan' };
case OperatorModel.LESS_THAN_EQUAL_TO:
return { ...operator, localizeKey: 'template_lessThanEqual' };
default:
return operator;
}
});
}
function isDateTime(operators: Array<TemplateQueryOperatorModel>): Array<TemplateOperatorModel> {
return operators.map((operator): TemplateOperatorModel => {
switch (operator.operator) {
case OperatorModel.GREATER_THAN:
return { ...operator, localizeKey: 'template_before' };
case OperatorModel.GREATER_THAN_EQUAL_TO:
return { ...operator, localizeKey: 'template_beforeIncDate' };
case OperatorModel.LESS_THAN:
return { ...operator, localizeKey: 'template_after' };
case OperatorModel.LESS_THAN_EQUAL_TO:
return { ...operator, localizeKey: 'template_afterIncDate' };
default:
return operator;
}
});
}