tags repository and store

This commit is contained in:
Lone Iversen
2023-05-08 12:52:18 +02:00
parent 576473197f
commit 6bfb660d3f
7 changed files with 89 additions and 21 deletions

View File

@@ -25,6 +25,7 @@ const CORE_PACKAGES = [
import('./search/umbraco-package'),
import('./templating/umbraco-package'),
import('./umbraco-news/umbraco-package'),
import('./tags/umbraco-package'),
];
@defineElement('umb-backoffice')

View File

@@ -4,15 +4,18 @@ import { customElement, property, query, queryAll, state } from 'lit/decorators.
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
import { repeat } from 'lit/directives/repeat.js';
import { UUIInputElement, UUIInputEvent, UUITagElement } from '@umbraco-ui/uui';
import { UmbTagRepository } from '../../../tags/repository/tag.repository';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { TagResource, TagResponseModel } from '@umbraco-cms/backoffice/backend-api';
import { TagResponseModel } from '@umbraco-cms/backoffice/backend-api';
@customElement('umb-tags-input')
export class UmbTagsInputElement extends FormControlMixin(UmbLitElement) {
@property({ type: String })
group?: string;
@property({ type: String })
culture?: string | null;
_items: string[] = [];
@property({ type: Array })
public set items(newTags: string[]) {
@@ -41,6 +44,8 @@ export class UmbTagsInputElement extends FormControlMixin(UmbLitElement) {
@queryAll('.options')
private _optionCollection?: HTMLCollectionOf<HTMLInputElement>;
#repository = new UmbTagRepository(this);
public focus() {
this._tagInput.focus();
}
@@ -50,11 +55,8 @@ export class UmbTagsInputElement extends FormControlMixin(UmbLitElement) {
}
async #getExistingTags(query: string) {
//TODO: Culture
const { data } = await tryExecuteAndNotify(
this,
TagResource.getTag({ query, skip: 0, take: 5, tagGroup: this.group })
);
if (!this.group || this.culture === undefined) return;
const { data } = await this.#repository.queryTags(this.group, this.culture, query);
if (!data) return;
this._matches = data.items;
}

View File

@@ -3,6 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { UmbTagsInputElement } from '../../../components/tags-input/tags-input.element';
import { UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN } from '../../../components/workspace-property/workspace-property.context';
import { UmbPropertyEditorExtensionElement } from '@umbraco-cms/backoffice/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api';
@@ -18,6 +19,10 @@ export class UmbPropertyEditorUITagsElement extends UmbLitElement implements Umb
@state()
private _group?: string;
@state()
private _culture?: string | null;
//TODO: Use type from VariantID
@property({ type: Array, attribute: false })
public set config(config: Array<DataTypePropertyPresentationModel>) {
const group = config.find((x) => x.alias === 'group');
@@ -27,6 +32,17 @@ export class UmbPropertyEditorUITagsElement extends UmbLitElement implements Umb
if (items) this.value = items.value as Array<string>;
}
constructor() {
super();
this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, (context) => {
this.observe(context.variantId, (id) => {
if (id && id.culture !== undefined) {
this._culture = id.culture;
}
});
});
}
private _onChange(event: CustomEvent) {
this.value = ((event.target as UmbTagsInputElement).value as string).split(',');
this.dispatchEvent(new CustomEvent('property-value-change'));
@@ -35,8 +51,9 @@ export class UmbPropertyEditorUITagsElement extends UmbLitElement implements Umb
render() {
return html`<umb-tags-input
group="${ifDefined(this._group)}"
.items="${this.value}"
@change="${this._onChange}"></umb-tags-input>`;
.culture=${this._culture}
.items=${this.value}
@change=${this._onChange}></umb-tags-input>`;
}
static styles = [UUITextStyles];

View File

@@ -0,0 +1,10 @@
import { manifests as repositoryManifests } from './repository/manifests';
import { UmbEntrypointOnInit } from '@umbraco-cms/backoffice/extensions-api';
export const manifests = [...repositoryManifests];
export const onInit: UmbEntrypointOnInit = (host, extensionRegistry) => {
console.log('tags registrer');
extensionRegistry.registerMany(manifests);
};

View File

@@ -2,8 +2,6 @@ import { UmbTagServerDataSource } from './sources/tag.server.data';
import { UmbTagStore, UMB_TAG_STORE_CONTEXT_TOKEN } from './tag.store';
import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification';
import { TagResponseModel, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api';
export class UmbTagRepository {
#init!: Promise<unknown>;
@@ -26,16 +24,36 @@ export class UmbTagRepository {
}
async requestTags(
{ query, skip, take, tagGroup, culture } = { query: '', skip: 0, take: 1000, tagGroup: 'default', culture: '' }
tagGroupName: string,
culture: string | null,
{ skip, take, query } = { skip: 0, take: 1000, query: '' }
) {
await this.#init;
const { data, error } = await this.#dataSource.getCollection({ query, skip, take, tagGroup, culture });
const requestCulture = culture || '';
const { data, error } = await this.#dataSource.getCollection({
skip,
take,
tagGroup: tagGroupName,
culture: requestCulture,
query,
});
if (data) {
this.#tagStore?.appendItems(data.items);
// TODO: allow to append an array of items to the store
data.items.forEach((x) => this.#tagStore?.append(x));
}
return { data, error, asObservable: () => this.#tagStore?.byGroup(tagGroup) };
return { data, error, asObservable: () => this.#tagStore!.byQuery(tagGroupName, requestCulture, query) };
}
async queryTags(
tagGroupName: string,
culture: string | null,
query: string,
{ skip, take } = { skip: 0, take: 1000 }
) {
return this.requestTags(tagGroupName, culture, { skip, take, query });
}
}

View File

@@ -12,6 +12,8 @@ export const UMB_TAG_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbTagStore>('Umb
* @description - Data Store for Template Details
*/
export class UmbTagStore extends UmbStoreBase {
public readonly data = this._data.asObservable();
/**
* Creates an instance of UmbTagStore.
* @param {UmbControllerHostElement} host
@@ -19,6 +21,7 @@ export class UmbTagStore extends UmbStoreBase {
*/
constructor(host: UmbControllerHostElement) {
super(host, UMB_TAG_STORE_CONTEXT_TOKEN.toString(), new UmbArrayState<TagResponseModel>([], (x) => x.id));
console.log('Store is open');
}
/**
@@ -39,15 +42,22 @@ export class UmbTagStore extends UmbStoreBase {
return this._data.getObservablePart((x) => x.find((y) => y.id === id));
}
// TODO
byGroup(group: TagResponseModel['group']) {
return this._data.getObservablePart((x) => x.filter((y) => y.group === group));
items(group: TagResponseModel['group'], culture: string) {
return this._data.getObservablePart((items) =>
items.filter((item) => item.group === group && item.culture === culture)
);
}
// TODO
byText(text: string) {
//TODO Skriv god kommentar til filter/exclude
byQuery(group: TagResponseModel['group'], culture: string, query: string) {
return this._data.getObservablePart((items) =>
items.filter((item) => item.text?.toLocaleLowerCase().includes(text.toLocaleLowerCase()))
items.filter(
(item) =>
item.group === group &&
item.culture === culture &&
item.query?.toLocaleLowerCase().includes(query.toLocaleLowerCase())
)
);
}

View File

@@ -0,0 +1,10 @@
export const name = 'Umbraco.Core.UserManagement';
export const version = '0.0.1';
export const extensions = [
{
name: 'Tags Management Entry Point',
alias: 'Umb.EntryPoint.TagsManagement',
type: 'entryPoint',
loader: () => import('./index'),
},
];