Compare commits

...
27 changed files with 343 additions and 5 deletions
@@ -0,0 +1 @@
export const UMB_WEBHOOK_EVENT_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.WebhookEvent.Collection';
@@ -0,0 +1 @@
export { UmbWebhookEventCollectionRepository } from './webhook-event-collection.repository.js';
@@ -0,0 +1,10 @@
import { UMB_WEBHOOK_EVENT_COLLECTION_REPOSITORY_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'repository',
alias: UMB_WEBHOOK_EVENT_COLLECTION_REPOSITORY_ALIAS,
name: 'Webhook Event Collection Repository',
api: () => import('./webhook-event-collection.repository.js'),
},
];
@@ -0,0 +1,7 @@
import type { UmbWebhookEventCollectionFilterModel, UmbWebhookEventCollectionItemModel } from '../types.js';
import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/collection';
export type UmbWebhookEventCollectionDataSource = UmbCollectionDataSource<
UmbWebhookEventCollectionItemModel,
UmbWebhookEventCollectionFilterModel
>;
@@ -0,0 +1,14 @@
import type { UmbWebhookEventCollectionFilterModel } from '../types.js';
import { UmbWebhookEventCollectionServerDataSource } from './webhook-event-collection.server.data-source.js';
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
import type { UmbCollectionRepository } from '@umbraco-cms/backoffice/collection';
export class UmbWebhookEventCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository {
#collectionSource = new UmbWebhookEventCollectionServerDataSource(this);
async requestCollection(filter: UmbWebhookEventCollectionFilterModel) {
return this.#collectionSource.getCollection(filter);
}
}
export default UmbWebhookEventCollectionRepository;
@@ -0,0 +1,45 @@
import type { UmbWebhookEventCollectionFilterModel, UmbWebhookEventCollectionItemModel } from '../types.js';
import { UMB_WEBHOOK_EVENT_ENTITY_TYPE } from '../../entity.js';
import { WebhookService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/collection';
import { tryExecute } from '@umbraco-cms/backoffice/resources';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
/**
* A data source that fetches the webhook event collection data from the server.
* @class UmbWebhookEventCollectionServerDataSource
* @implements {UmbCollectionDataSource}
*/
export class UmbWebhookEventCollectionServerDataSource
extends UmbControllerBase
implements UmbCollectionDataSource<UmbWebhookEventCollectionItemModel, UmbWebhookEventCollectionFilterModel>
{
/**
* Gets the Webhook Event collection filtered by the given filter.
* @param {UmbWebhookEventCollectionFilterModel} filter
* @returns {*}
* @memberof UmbWebhookEventCollectionServerDataSource
*/
async getCollection(filter: UmbWebhookEventCollectionFilterModel) {
const { data, error } = await tryExecute(
this,
WebhookService.getWebhookEvents({ query: { skip: filter.skip ?? 0, take: filter.take ?? 100 } }),
);
if (error || !data) {
return { error };
}
const items = data.items.map((item): UmbWebhookEventCollectionItemModel => {
return {
entityType: UMB_WEBHOOK_EVENT_ENTITY_TYPE,
unique: item.alias,
name: item.eventName,
eventType: item.eventType,
alias: item.alias,
};
});
return { data: { items, total: data.total } };
}
}
@@ -0,0 +1,15 @@
import type { UmbCollectionItemModel } from '@umbraco-cms/backoffice/collection';
import type { UmbWebhookEventEntityType } from '../entity.js';
export interface UmbWebhookEventCollectionItemModel extends UmbCollectionItemModel {
entityType: UmbWebhookEventEntityType;
unique: string;
name: string;
eventType: string;
alias: string;
}
export interface UmbWebhookEventCollectionFilterModel {
skip?: number;
take?: number;
}
@@ -0,0 +1,3 @@
export const UMB_WEBHOOK_EVENT_ENTITY_TYPE = 'webhook-event';
export type UmbWebhookEventEntityType = typeof UMB_WEBHOOK_EVENT_ENTITY_TYPE;
@@ -0,0 +1,53 @@
import { UmbWebhookEventPickerDataSource } from '../picker-data-source/webhook-event.picker-data-source.js';
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
@customElement('umb-input-webhook-event')
export class UmbInputWebhookEventElement extends UmbFormControlMixin<string | undefined, typeof UmbLitElement>(
UmbLitElement,
) {
#dataSource = new UmbWebhookEventPickerDataSource(this);
@property({ type: Number })
min = 0;
@property({ type: Number })
max = Infinity;
@property({ type: Array })
selection: Array<string> = [];
@property({ type: Boolean, reflect: true })
readonly = false;
protected override getFormElement() {
return undefined;
}
#onChange(event: Event) {
event.stopPropagation();
const target = event.target as HTMLElement & { selection: Array<string>; value: string | undefined };
this.selection = target.selection;
this.value = target.value;
this.dispatchEvent(new UmbChangeEvent());
}
override render() {
return html`<umb-input-entity-data
.dataSourceApi=${this.#dataSource}
.value=${this.value}
.selection=${this.selection}
.min=${this.min}
.max=${this.max}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-entity-data>`;
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-input-webhook-event': UmbInputWebhookEventElement;
}
}
@@ -1 +1,3 @@
export * from './entity.js';
export * from './collection/repository/index.js';
export * from './repository/index.js';
@@ -0,0 +1 @@
export * from './repository/constants.js';
@@ -0,0 +1 @@
export * from './repository/index.js';
@@ -0,0 +1,3 @@
import { manifests as repositoryManifests } from './repository/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...repositoryManifests];
@@ -0,0 +1,2 @@
export const UMB_WEBHOOK_EVENT_ITEM_REPOSITORY_ALIAS = 'Umb.Repository.WebhookEvent.Item';
export const UMB_WEBHOOK_EVENT_ITEM_STORE_ALIAS = 'Umb.Store.WebhookEvent.Item';
@@ -0,0 +1,4 @@
export { UmbWebhookEventItemRepository } from './webhook-event-item.repository.js';
export { UMB_WEBHOOK_EVENT_ITEM_REPOSITORY_ALIAS } from './constants.js';
export { UMB_WEBHOOK_EVENT_ITEM_STORE_CONTEXT } from './webhook-event-item.store.js';
export type { UmbWebhookEventItemModel } from './types.js';
@@ -0,0 +1,17 @@
import { UmbWebhookEventItemStore } from './webhook-event-item.store.js';
import { UMB_WEBHOOK_EVENT_ITEM_REPOSITORY_ALIAS, UMB_WEBHOOK_EVENT_ITEM_STORE_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'repository',
alias: UMB_WEBHOOK_EVENT_ITEM_REPOSITORY_ALIAS,
name: 'Webhook Event Item Repository',
api: () => import('./webhook-event-item.repository.js'),
},
{
type: 'itemStore',
alias: UMB_WEBHOOK_EVENT_ITEM_STORE_ALIAS,
name: 'Webhook Event Item Store',
api: UmbWebhookEventItemStore,
},
];
@@ -0,0 +1,9 @@
import type { UmbWebhookEventEntityType } from '../../entity.js';
import type { UmbItemModel } from '@umbraco-cms/backoffice/entity-item';
export interface UmbWebhookEventItemModel extends UmbItemModel {
entityType: UmbWebhookEventEntityType;
name: string;
eventType: string;
alias: string;
}
@@ -0,0 +1,13 @@
import { UmbWebhookEventItemServerDataSource } from './webhook-event-item.server.data-source.js';
import { UMB_WEBHOOK_EVENT_ITEM_STORE_CONTEXT } from './webhook-event-item.store.js';
import type { UmbWebhookEventItemModel } from './types.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository';
export class UmbWebhookEventItemRepository extends UmbItemRepositoryBase<UmbWebhookEventItemModel> {
constructor(host: UmbControllerHost) {
super(host, UmbWebhookEventItemServerDataSource, UMB_WEBHOOK_EVENT_ITEM_STORE_CONTEXT);
}
}
export { UmbWebhookEventItemRepository as api };
@@ -0,0 +1,49 @@
import { UMB_WEBHOOK_EVENT_ENTITY_TYPE } from '../../entity.js';
import type { UmbWebhookEventItemModel } from './types.js';
import type { WebhookEventResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import { WebhookService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import { tryExecute } from '@umbraco-cms/backoffice/resources';
/**
* A server data source for Webhook Event items.
* @class UmbWebhookEventItemServerDataSource
* @implements {UmbItemServerDataSourceBase}
*/
export class UmbWebhookEventItemServerDataSource extends UmbItemServerDataSourceBase<
WebhookEventResponseModel,
UmbWebhookEventItemModel
> {
/**
* Creates an instance of UmbWebhookEventItemServerDataSource.
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
* @memberof UmbWebhookEventItemServerDataSource
*/
constructor(host: UmbControllerHost) {
super(host, { mapper });
}
override async getItems(uniques: Array<string>) {
if (!uniques.length) return { data: [], error: undefined };
const { data, error } = await tryExecute(this, WebhookService.getWebhookEvents());
if (error || !data) {
return { data: undefined, error };
}
const filtered = data.items.filter((item) => uniques.includes(item.alias));
return { data: this._getMappedItems(filtered), error: undefined };
}
}
const mapper = (item: WebhookEventResponseModel): UmbWebhookEventItemModel => {
return {
entityType: UMB_WEBHOOK_EVENT_ENTITY_TYPE,
unique: item.alias,
name: item.eventName,
eventType: item.eventType,
alias: item.alias,
};
};
@@ -0,0 +1,26 @@
import type { UmbWebhookEventItemModel } from './types.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store';
/**
* @class UmbWebhookEventItemStore
* @augments {UmbItemStoreBase}
* @description - Data Store for Webhook Event items
*/
export class UmbWebhookEventItemStore extends UmbItemStoreBase<UmbWebhookEventItemModel> {
/**
* Creates an instance of UmbWebhookEventItemStore.
* @param {UmbControllerHost} host - The controller host
* @memberof UmbWebhookEventItemStore
*/
constructor(host: UmbControllerHost) {
super(host, UMB_WEBHOOK_EVENT_ITEM_STORE_CONTEXT);
}
}
export default UmbWebhookEventItemStore;
export const UMB_WEBHOOK_EVENT_ITEM_STORE_CONTEXT = new UmbContextToken<UmbWebhookEventItemStore>(
'UmbWebhookEventItemStore',
);
@@ -1,4 +1,11 @@
import { manifests as collectionManifests } from './collection/repository/manifests.js';
import { manifests as itemManifests } from './item/manifests.js';
import { manifests as modalManifests } from './modal/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...modalManifests, ...repositoryManifests];
export const manifests: Array<UmbExtensionManifest> = [
...collectionManifests,
...itemManifests,
...modalManifests,
...repositoryManifests,
];
@@ -0,0 +1,33 @@
import { UmbWebhookEventCollectionRepository } from '../collection/repository/webhook-event-collection.repository.js';
import type { UmbWebhookEventCollectionFilterModel, UmbWebhookEventCollectionItemModel } from '../collection/types.js';
import { UmbWebhookEventItemRepository } from '../item/repository/webhook-event-item.repository.js';
import type {
UmbPickerCollectionDataSource,
UmbPickerCollectionDataSourceTextFilterFeature,
} from '@umbraco-cms/backoffice/picker-data-source';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
export class UmbWebhookEventPickerDataSource
extends UmbControllerBase
implements UmbPickerCollectionDataSource<UmbWebhookEventCollectionItemModel>
{
#collectionRepository = new UmbWebhookEventCollectionRepository(this);
#itemRepository = new UmbWebhookEventItemRepository(this);
#supportsTextFilter = new UmbObjectState<UmbPickerCollectionDataSourceTextFilterFeature>({ enabled: false });
public readonly features = {
supportsTextFilter: this.#supportsTextFilter.asObservable(),
};
async requestCollection(args: UmbWebhookEventCollectionFilterModel) {
return this.#collectionRepository.requestCollection(args);
}
async requestItems(uniques: Array<string>) {
return this.#itemRepository.requestItems(uniques);
}
}
export { UmbWebhookEventPickerDataSource as api };
@@ -1,3 +1,5 @@
import { UMB_WEBHOOK_EVENT_ENTITY_TYPE } from '../entity.js';
import type { UmbWebhookEventModel } from '../types.js';
import { WebhookService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { tryExecute } from '@umbraco-cms/backoffice/resources';
@@ -26,8 +28,10 @@ export class UmbWebhookEventServerDataSource {
return { error };
}
const items = data.items.map((item) => {
const items: Array<UmbWebhookEventModel> = data.items.map((item) => {
return {
entityType: UMB_WEBHOOK_EVENT_ENTITY_TYPE,
unique: item.alias,
eventName: item.eventName,
eventType: item.eventType,
alias: item.alias,
@@ -19,7 +19,7 @@ export class UmbWebhookEventStore extends UmbStoreBase<UmbWebhookEventModel> {
super(
host,
UMB_WEBHOOK_EVENT_STORE_CONTEXT.toString(),
new UmbArrayState<UmbWebhookEventModel>([], (x) => x.alias),
new UmbArrayState<UmbWebhookEventModel>([], (x) => x.unique),
);
}
}
@@ -1,4 +1,8 @@
import type { UmbWebhookEventEntityType } from './entity.js';
export interface UmbWebhookEventModel {
entityType: UmbWebhookEventEntityType;
unique: string;
eventName: string;
eventType: string;
alias: string;
@@ -1,5 +1,6 @@
import type { UmbWebhookCollectionFilterModel } from '../types.js';
import { UMB_WEBHOOK_ENTITY_TYPE } from '../../../entity.js';
import { UMB_WEBHOOK_EVENT_ENTITY_TYPE } from '../../../webhook-event/entity.js';
import type { UmbWebhookDetailModel } from '../../types.js';
import { WebhookService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -45,7 +46,13 @@ export class UmbWebhookCollectionServerDataSource implements UmbWebhookCollectio
description: item.description,
enabled: item.enabled,
headers: item.headers,
events: item.events,
events: item.events.map((event) => ({
entityType: UMB_WEBHOOK_EVENT_ENTITY_TYPE,
unique: event.alias,
eventName: event.eventName,
eventType: event.eventType,
alias: event.alias,
})),
contentTypes: item.contentTypeKeys,
};
@@ -1,5 +1,6 @@
import type { UmbWebhookDetailModel } from '../../../types.js';
import { UMB_WEBHOOK_ENTITY_TYPE } from '../../../entity.js';
import { UMB_WEBHOOK_EVENT_ENTITY_TYPE } from '../../../webhook-event/entity.js';
import { UmbId } from '@umbraco-cms/backoffice/id';
import type { UmbDetailDataSource } from '@umbraco-cms/backoffice/repository';
import type {
@@ -70,7 +71,13 @@ export class UmbWebhookDetailServerDataSource implements UmbDetailDataSource<Umb
entityType: UMB_WEBHOOK_ENTITY_TYPE,
unique: data.id,
headers: data.headers,
events: data.events,
events: data.events.map((event) => ({
entityType: UMB_WEBHOOK_EVENT_ENTITY_TYPE,
unique: event.alias,
eventName: event.eventName,
eventType: event.eventType,
alias: event.alias,
})),
enabled: data.enabled,
url: data.url,
name: data.name ?? '',