${repeat(
this._searchProviders,
(searchProvider) => searchProvider,
@@ -143,7 +126,7 @@ export class UmbSearchModalElement extends UmbLitElement {
html`
this.#onSearchTagClick(searchProvider)}
@keydown=${() => ''}
- class="search-tag ${this._activeSearchTag === searchProvider.alias ? 'active' : ''}">
+ class="search-provider ${this._activeSearchTag === searchProvider.alias ? 'active' : ''}">
${searchProvider.name}
`,
)}
@@ -153,16 +136,12 @@ export class UmbSearchModalElement extends UmbLitElement {
#renderResults() {
return repeat(
this._searchResults,
- (item) => item.name,
- (item) => this.#renderItem(item),
+ (item) => item.unique,
+ (item) => this.#renderResultItem(item),
);
}
- #renderNoResults() {
- return html`
Only mock data for now Search for blog
`;
- }
-
- #renderItem(item: SearchItem) {
+ #renderResultItem(item: UmbSearchResultItemModel) {
return html`
manifest.forEntityTypes.includes(item.entityType)}
default-element="umb-search-result-item">
`;
- return html`
-
-
- ${item.icon ? html` ` : this.#renderHashTag()}
-
-
- ${item.name} ${item.url ? html`${item.url} ` : nothing}
-
- >
-
- `;
}
- #renderHashTag() {
- return html`
-
-
-
-
- `;
+ #renderNoResults() {
+ return html`
Only mock data for now Search for blog
`;
}
- #mockApi = {
- getDocuments: [
- {
- name: 'Blog',
- href: '#',
- icon: 'icon-thumbnail-list',
- url: '/blog/',
- },
- {
- name: 'Popular blogs',
- href: '#',
- icon: 'icon-article',
- url: '/blog/popular-blogs/',
- },
- {
- name: 'How to write a blog',
- href: '#',
- icon: 'icon-article',
- url: '/blog/how-to-write-a-blog/',
- },
- ],
- getMedia: [
- {
- name: 'Blog hero',
- href: '#',
- icon: 'icon-picture',
- },
- ],
- getDocumentTypes: [
- {
- name: 'Contact form for blog',
- href: '#',
- },
- {
- name: 'Blog',
- href: '#',
- },
- {
- name: 'Blog link item',
- href: '#',
- },
- ],
- };
-
static styles = [
UmbTextStyles,
css`
- #search-tags {
+ #search-providers {
display: flex;
flex-wrap: wrap;
gap: var(--uui-size-space-2);
padding: 0 var(--uui-size-space-5);
padding-bottom: var(--uui-size-space-2);
}
- .search-tag {
+ .search-provider {
padding: var(--uui-size-space-3) var(--uui-size-space-4);
background: var(--uui-color-surface-alt);
line-height: 1;
@@ -258,11 +175,11 @@ export class UmbSearchModalElement extends UmbLitElement {
cursor: pointer;
border: 2px solid transparent;
}
- .search-tag:hover {
+ .search-provider:hover {
background: var(--uui-color-surface-emphasis);
color: var(--uui-color-interactive-emphasis);
}
- .search-tag.active {
+ .search-provider.active {
background: var(--uui-color-surface-emphasis);
color: var(--uui-color-interactive-emphasis);
border-color: var(--uui-color-focus);
@@ -305,52 +222,6 @@ export class UmbSearchModalElement extends UmbLitElement {
flex-direction: column;
height: 100%;
}
- .item {
- background: var(--uui-color-surface);
- padding: var(--uui-size-space-3) var(--uui-size-space-5);
- border-radius: var(--uui-border-radius);
- color: var(--uui-color-interactive);
- display: grid;
- grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
- align-items: center;
- }
- .item:hover {
- background-color: var(--uui-color-surface-emphasis);
- color: var(--uui-color-interactive-emphasis);
- }
- .item:hover .item-symbol {
- font-weight: unset;
- opacity: 1;
- }
- .item-icon {
- margin-bottom: auto;
- margin-top: 5px;
- }
- .item-icon,
- .item-symbol {
- opacity: 0.4;
- }
- .item-url {
- font-size: 0.8rem;
- line-height: 1.2;
- font-weight: 100;
- }
- .item-name {
- display: flex;
- flex-direction: column;
- }
- .item-icon > * {
- height: 1rem;
- display: flex;
- width: min-content;
- }
- .item-symbol {
- font-weight: 100;
- }
- a {
- text-decoration: none;
- color: inherit;
- }
#no-results {
display: flex;
flex-direction: column;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
index 103fa70187..41a9b41b09 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
@@ -1,6 +1,6 @@
import type { UmbSearchResultItemModel } from '../types.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
-import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
const elementName = 'umb-search-result-item';
@@ -10,9 +10,29 @@ export class UmbSearchResultItemElement extends UmbLitElement {
item?: UmbSearchResultItemModel;
render() {
+ if (!this.item) return nothing;
+
+ const url = 'url/goes/here';
+
return html`
-
ICON
-
${this.item?.name}
+
+
+ ${this.item.icon ? html` ` : this.#renderHashTag()}
+
+ ${this.item.name} ${url ? html`${url} ` : nothing}
+ >
+
+ `;
+ }
+
+ #renderHashTag() {
+ return html`
+
+
+
+
`;
}
@@ -22,6 +42,54 @@ export class UmbSearchResultItemElement extends UmbLitElement {
:host {
display: flex;
gap: 12px;
+ width: 100%;
+ }
+ .item {
+ background: var(--uui-color-surface);
+ padding: var(--uui-size-space-3) var(--uui-size-space-5);
+ border-radius: var(--uui-border-radius);
+ color: var(--uui-color-interactive);
+ display: grid;
+ grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
+ align-items: center;
+ width: 100%;
+ }
+ .item:hover {
+ background-color: var(--uui-color-surface-emphasis);
+ color: var(--uui-color-interactive-emphasis);
+ }
+ .item:hover .item-symbol {
+ font-weight: unset;
+ opacity: 1;
+ }
+ .item-icon {
+ margin-bottom: auto;
+ margin-top: 5px;
+ }
+ .item-icon,
+ .item-symbol {
+ opacity: 0.4;
+ }
+ .item-url {
+ font-size: 0.8rem;
+ line-height: 1.2;
+ font-weight: 100;
+ }
+ .item-name {
+ display: flex;
+ flex-direction: column;
+ }
+ .item-icon > * {
+ height: 1rem;
+ display: flex;
+ width: min-content;
+ }
+ .item-symbol {
+ font-weight: 100;
+ }
+ a {
+ text-decoration: none;
+ color: inherit;
}
`,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index e4952bdd42..1967a24bf4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -1,4 +1,5 @@
export type UmbSearchResultItemModel = {
+ entityType: string;
icon?: string;
name: string;
unique: string;
From 9f37bebdbe1d089deb5444f7271791d072046353 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:13:14 +0200
Subject: [PATCH 011/323] cleanup
---
.../search-modal/search-modal.element.ts | 38 +++++++------------
1 file changed, 13 insertions(+), 25 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 81bde5a234..ca9192cfb2 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -19,22 +19,6 @@ export class UmbSearchModalElement extends UmbLitElement {
@state()
private _searchResults: Array
= [];
- @state()
- private searchTags: Array = [
- 'Data Type',
- 'Document',
- 'Document Type',
- 'Media',
- 'Media Type',
- 'Member',
- 'Member Type',
- 'Users',
- 'User Group',
- ];
-
- @state()
- private _activeSearchTag = 'Document';
-
@state()
private _searchProviders: Array<{
name: string;
@@ -42,7 +26,11 @@ export class UmbSearchModalElement extends UmbLitElement {
alias: string;
}> = [];
- #currentProvider: any;
+ @state()
+ _currentProvider?: {
+ api: any;
+ alias: string;
+ };
/**
*
@@ -79,16 +67,16 @@ export class UmbSearchModalElement extends UmbLitElement {
}
async #onSearchTagClick(searchProvider: any) {
- console.log(searchProvider);
const api = await searchProvider.providerPromise;
-
- this.#currentProvider = api;
- this._activeSearchTag = searchProvider.alias;
+ this._currentProvider = {
+ api,
+ alias: searchProvider.alias,
+ };
}
async #updateSearchResults() {
- if (this._search) {
- const { data } = await this.#currentProvider.search({ query: this._search });
+ if (this._search && this._currentProvider) {
+ const { data } = await this._currentProvider.api.search({ query: this._search });
if (!data) return;
this._searchResults = data.items;
} else {
@@ -126,7 +114,7 @@ export class UmbSearchModalElement extends UmbLitElement {
html` this.#onSearchTagClick(searchProvider)}
@keydown=${() => ''}
- class="search-provider ${this._activeSearchTag === searchProvider.alias ? 'active' : ''}">
+ class="search-provider ${this._currentProvider?.alias === searchProvider.alias ? 'active' : ''}">
${searchProvider.name}
`,
)}
@@ -152,7 +140,7 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#renderNoResults() {
- return html`Only mock data for now Search for blog
`;
+ return html`No results found
`;
}
static styles = [
From d03adace843e0c20da0a955e1cd58ce8c2a1eaa8 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:15:20 +0200
Subject: [PATCH 012/323] cleanup
---
.../search/search-modal/search-modal.element.ts | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index ca9192cfb2..4a7b57fdc8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -32,9 +32,6 @@ export class UmbSearchModalElement extends UmbLitElement {
alias: string;
};
- /**
- *
- */
constructor() {
super();
@@ -55,10 +52,14 @@ export class UmbSearchModalElement extends UmbLitElement {
super.connectedCallback();
requestAnimationFrame(() => {
- this._input.focus();
+ this.#focusInput();
});
}
+ #focusInput() {
+ this._input.focus();
+ }
+
#onSearchChange(event: InputEvent) {
const target = event.target as HTMLInputElement;
this._search = target.value;
@@ -72,6 +73,8 @@ export class UmbSearchModalElement extends UmbLitElement {
api,
alias: searchProvider.alias,
};
+
+ this.#focusInput();
}
async #updateSearchResults() {
From ecb9857ae771b4afc20d59325924ea811c85ffc7 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:16:41 +0200
Subject: [PATCH 013/323] select first provider
---
.../packages/search/search-modal/search-modal.element.ts | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 4a7b57fdc8..fceaf940de 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -45,6 +45,10 @@ export class UmbSearchModalElement extends UmbLitElement {
providerPromise: createExtensionApi(this, provider.manifest),
alias: provider.alias,
}));
+
+ if (this._searchProviders.length > 0) {
+ this.#setCurrentProvider(this._searchProviders[0]);
+ }
});
}
@@ -67,7 +71,7 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#updateSearchResults();
}
- async #onSearchTagClick(searchProvider: any) {
+ async #setCurrentProvider(searchProvider: any) {
const api = await searchProvider.providerPromise;
this._currentProvider = {
api,
@@ -115,7 +119,7 @@ export class UmbSearchModalElement extends UmbLitElement {
(searchProvider) => searchProvider,
(searchProvider) =>
html` this.#onSearchTagClick(searchProvider)}
+ @click=${() => this.#setCurrentProvider(searchProvider)}
@keydown=${() => ''}
class="search-provider ${this._currentProvider?.alias === searchProvider.alias ? 'active' : ''}">
${searchProvider.name}
From ddcdfc8becfc44519ac121811e8f6564d1aed5bb Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:18:24 +0200
Subject: [PATCH 014/323] search on provider change
---
.../src/packages/search/search-modal/search-modal.element.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index fceaf940de..41c24268f4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -79,6 +79,7 @@ export class UmbSearchModalElement extends UmbLitElement {
};
this.#focusInput();
+ this.#updateSearchResults();
}
async #updateSearchResults() {
From cf62b8da2e2cbf0dcb889f9c2339e5b1aad81638 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:21:10 +0200
Subject: [PATCH 015/323] move model to search
---
.../documents/documents/search/document-search.repository.ts | 2 +-
.../documents/search/document-search.server.data-source.ts | 4 ++--
.../documents/documents/search/document.search-provider.ts | 2 +-
.../src/packages/documents/documents/search/types.ts | 3 ---
src/Umbraco.Web.UI.Client/src/packages/search/index.ts | 2 +-
src/Umbraco.Web.UI.Client/src/packages/search/types.ts | 4 ++++
6 files changed, 9 insertions(+), 8 deletions(-)
delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
index a852a74409..e49241d353 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
@@ -1,5 +1,5 @@
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDocumentSearchServerDataSource } from './document-search.server.data-source.js';
-import type { UmbSearchRequestArgs } from './types.js';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
index ae8446097a..e18b16d76c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
@@ -1,8 +1,8 @@
-import type { UmbSearchRequestArgs } from './types.js';
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
-import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
/**
* A data source for the Rollback that fetches data from the server
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
index 4072442ab3..03333995e1 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
@@ -1,5 +1,5 @@
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDocumentSearchRepository } from './document-search.repository.js';
-import type { UmbSearchRequestArgs } from './types.js';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts
deleted file mode 100644
index 20267d66ab..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export type UmbSearchRequestArgs = {
- query: string;
-};
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
index 9b7dfb03df..9a93dc74e0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
@@ -1 +1 @@
-export { type UmbSearchResultItemModel } from './types.js';
+export type { UmbSearchResultItemModel, UmbSearchRequestArgs } from './types.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index 1967a24bf4..0ddc671feb 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -4,3 +4,7 @@ export type UmbSearchResultItemModel = {
name: string;
unique: string;
};
+
+export type UmbSearchRequestArgs = {
+ query: string;
+};
From baa5dc1fcf300bc7cfc8a0ea8f38ec7e00a10b5e Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 13:38:19 +0200
Subject: [PATCH 016/323] data type search provider
---
.../search/data-type-search.repository.ts | 19 +++++++
.../data-type-search.server.data-source.ts | 53 +++++++++++++++++++
.../search/data-type.search-provider.ts | 13 ++---
.../packages/data-type/search/manifests.ts | 9 +++-
4 files changed, 87 insertions(+), 7 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
new file mode 100644
index 0000000000..5f7b594bac
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
@@ -0,0 +1,19 @@
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbDataTypeSearchServerDataSource } from './data-type-search.server.data-source.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbDataTypeSearchRepository extends UmbControllerBase implements UmbApi {
+ #dataSource: UmbDataTypeSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbDataTypeSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
new file mode 100644
index 0000000000..2c3dbae483
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
@@ -0,0 +1,53 @@
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_DATA_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbDataTypeSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbDataTypeSearchServerDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbDataTypeSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbDataTypeSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbDataTypeSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ DataTypeService.getItemDataTypeSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems = data.items.map((item) => {
+ return {
+ entityType: UMB_DATA_TYPE_ENTITY_TYPE,
+ unique: item.id,
+ name: item.name,
+ propertyEditorUiAlias: item.editorUiAlias || '',
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
index 4a13750fd6..a025d140e9 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
@@ -1,12 +1,13 @@
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbDataTypeSearchRepository } from './data-type-search.repository.js';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export class UmbDataTypeSearchProvider implements UmbApi {
- constructor() {
- console.log('UmbDataTypeSearchProvider hello world');
- }
+export class UmbDataTypeSearchProvider extends UmbControllerBase implements UmbApi {
+ #repository = new UmbDataTypeSearchRepository(this);
- search(): void {
- alert('search');
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
}
destroy(): void {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
index 3b79a769dc..fb63c8459a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
@@ -1,3 +1,4 @@
+import { UMB_DATA_TYPE_ENTITY_TYPE } from '../entity.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const manifests: Array = [
@@ -6,9 +7,15 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.DataType',
type: 'searchProvider',
api: () => import('./data-type.search-provider.js'),
- weight: 900,
+ weight: 1000,
meta: {
label: 'Data Types',
},
},
+ {
+ name: 'Data Type Search Result Item ',
+ alias: 'Umb.SearchResultItem.DataType',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_DATA_TYPE_ENTITY_TYPE],
+ },
];
From 324543cf2eb5ddb50792219129303cf4bf9b6c11 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 14:21:18 +0200
Subject: [PATCH 017/323] types
---
.../models/search-provider.model.ts | 3 +-
.../search/data-type.search-provider.ts | 5 +-
.../src/packages/search/index.ts | 2 +-
.../search-modal/search-modal.element.ts | 52 ++++++++++---------
.../src/packages/search/types.ts | 6 +++
5 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
index c59704ef48..05034ad9c6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
@@ -1,9 +1,10 @@
+import type { UmbSearchProvider } from '@umbraco-cms/backoffice/search';
import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api';
/**
* Represents an search provider that can be used to search.
*/
-export interface ManifestSearchProvider extends ManifestApi {
+export interface ManifestSearchProvider extends ManifestApi {
type: 'searchProvider';
meta?: MetaSearchProvider;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
index a025d140e9..c7ae6f191c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
@@ -1,9 +1,8 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDataTypeSearchRepository } from './data-type-search.repository.js';
-import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export class UmbDataTypeSearchProvider extends UmbControllerBase implements UmbApi {
+export class UmbDataTypeSearchProvider extends UmbControllerBase implements UmbSearchProvider {
#repository = new UmbDataTypeSearchRepository(this);
async search(args: UmbSearchRequestArgs) {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
index 9a93dc74e0..02be37aced 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
@@ -1 +1 @@
-export type { UmbSearchResultItemModel, UmbSearchRequestArgs } from './types.js';
+export type { UmbSearchResultItemModel, UmbSearchRequestArgs, UmbSearchProvider } from './types.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 41c24268f4..ba178e94ef 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -1,4 +1,4 @@
-import type { UmbSearchResultItemModel } from '../types.js';
+import type { UmbSearchProvider, UmbSearchResultItemModel } from '../types.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, nothing, repeat, customElement, query, state } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestSearchResultItem } from '@umbraco-cms/backoffice/extension-registry';
@@ -8,6 +8,12 @@ import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-c
import '../search-result/search-result-item.element.js';
+type SearchProvider = {
+ name: string;
+ api: UmbSearchProvider;
+ alias: string;
+};
+
@customElement('umb-search-modal')
export class UmbSearchModalElement extends UmbLitElement {
@query('input')
@@ -20,17 +26,10 @@ export class UmbSearchModalElement extends UmbLitElement {
private _searchResults: Array = [];
@state()
- private _searchProviders: Array<{
- name: string;
- providerPromise: any;
- alias: string;
- }> = [];
+ private _searchProviders: Array = [];
@state()
- _currentProvider?: {
- api: any;
- alias: string;
- };
+ _currentProvider?: SearchProvider;
constructor() {
super();
@@ -39,15 +38,24 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#observeViews() {
- new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'searchProvider', null, (providers) => {
- this._searchProviders = providers.map((provider) => ({
- name: provider.manifest.meta?.label || provider.manifest.name,
- providerPromise: createExtensionApi(this, provider.manifest),
- alias: provider.alias,
- }));
+ new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'searchProvider', null, async (providers) => {
+ const searchProviders: SearchProvider[] = [];
+
+ for (const provider of providers) {
+ const api = await createExtensionApi(this, provider.manifest);
+ if (api) {
+ searchProviders.push({
+ name: provider.manifest.meta?.label || provider.manifest.name,
+ api,
+ alias: provider.alias,
+ });
+ }
+ }
+
+ this._searchProviders = searchProviders;
if (this._searchProviders.length > 0) {
- this.#setCurrentProvider(this._searchProviders[0]);
+ this._currentProvider = this._searchProviders[0];
}
});
}
@@ -71,19 +79,15 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#updateSearchResults();
}
- async #setCurrentProvider(searchProvider: any) {
- const api = await searchProvider.providerPromise;
- this._currentProvider = {
- api,
- alias: searchProvider.alias,
- };
+ async #setCurrentProvider(searchProvider: SearchProvider) {
+ this._currentProvider = searchProvider;
this.#focusInput();
this.#updateSearchResults();
}
async #updateSearchResults() {
- if (this._search && this._currentProvider) {
+ if (this._search && this._currentProvider?.api) {
const { data } = await this._currentProvider.api.search({ query: this._search });
if (!data) return;
this._searchResults = data.items;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index 0ddc671feb..93514ed934 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -1,3 +1,5 @@
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
export type UmbSearchResultItemModel = {
entityType: string;
icon?: string;
@@ -8,3 +10,7 @@ export type UmbSearchResultItemModel = {
export type UmbSearchRequestArgs = {
query: string;
};
+
+export interface UmbSearchProvider extends UmbApi {
+ search(args: UmbSearchRequestArgs): Promise;
+}
From 2b62c95a44def7ac713ab2e59f9f69ab80fe190b Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 15:06:15 +0200
Subject: [PATCH 018/323] types
---
.../models/search-provider.model.ts | 4 ++--
.../src/packages/data-type/repository/item/types.ts | 3 +++
.../data-type/search/data-type-search.repository.ts | 8 ++++++--
.../search/data-type-search.server.data-source.ts | 7 ++++---
.../data-type/search/data-type.search-provider.ts | 10 ++++++++--
.../src/packages/search/index.ts | 2 ++
.../packages/search/search-data-source.interface.ts | 11 +++++++++++
.../search/search-modal/search-modal.element.ts | 8 ++++----
.../packages/search/search-repository.interface.ts | 6 ++++++
.../src/packages/search/types.ts | 5 +++--
10 files changed, 49 insertions(+), 15 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/search/search-data-source.interface.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/search/search-repository.interface.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
index 05034ad9c6..c5c7e7b6ed 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/search-provider.model.ts
@@ -1,10 +1,10 @@
-import type { UmbSearchProvider } from '@umbraco-cms/backoffice/search';
+import type { UmbSearchProvider, UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api';
/**
* Represents an search provider that can be used to search.
*/
-export interface ManifestSearchProvider extends ManifestApi {
+export interface ManifestSearchProvider extends ManifestApi> {
type: 'searchProvider';
meta?: MetaSearchProvider;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts
index 185aa5cba4..cbd229e067 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/types.ts
@@ -1,4 +1,7 @@
+import type { UmbDataTypeEntityType } from '../../entity.js';
+
export interface UmbDataTypeItemModel {
+ entityType: UmbDataTypeEntityType;
unique: string;
name: string;
propertyEditorUiAlias: string;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
index 5f7b594bac..edbb2d0ed0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
@@ -1,10 +1,14 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDataTypeSearchServerDataSource } from './data-type-search.server.data-source.js';
+import type { UmbDataTypeSearchItemModel } from './data-type.search-provider.js';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
-export class UmbDataTypeSearchRepository extends UmbControllerBase implements UmbApi {
+export class UmbDataTypeSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
#dataSource: UmbDataTypeSearchServerDataSource;
constructor(host: UmbControllerHost) {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
index 2c3dbae483..09c60af80c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
@@ -1,5 +1,6 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_DATA_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { UmbDataTypeSearchItemModel } from './data-type.search-provider.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
@@ -10,7 +11,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
* @class UmbDataTypeSearchServerDataSource
* @implements {RepositoryDetailDataSource}
*/
-export class UmbDataTypeSearchServerDataSource {
+export class UmbDataTypeSearchServerDataSource implements UmbSearchDataSource {
#host: UmbControllerHost;
/**
@@ -36,7 +37,7 @@ export class UmbDataTypeSearchServerDataSource {
);
if (data) {
- const mappedItems = data.items.map((item) => {
+ const mappedItems: Array = data.items.map((item) => {
return {
entityType: UMB_DATA_TYPE_ENTITY_TYPE,
unique: item.id,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
index c7ae6f191c..783484bbee 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
@@ -1,8 +1,14 @@
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbDataTypeItemModel } from '../index.js';
import { UmbDataTypeSearchRepository } from './data-type-search.repository.js';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export class UmbDataTypeSearchProvider extends UmbControllerBase implements UmbSearchProvider {
+export interface UmbDataTypeSearchItemModel extends UmbDataTypeItemModel {}
+
+export class UmbDataTypeSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
#repository = new UmbDataTypeSearchRepository(this);
async search(args: UmbSearchRequestArgs) {
@@ -10,7 +16,7 @@ export class UmbDataTypeSearchProvider extends UmbControllerBase implements UmbS
}
destroy(): void {
- throw new Error('Method not implemented.');
+ this.#repository.destroy();
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
index 02be37aced..264c82d513 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/index.ts
@@ -1 +1,3 @@
export type { UmbSearchResultItemModel, UmbSearchRequestArgs, UmbSearchProvider } from './types.js';
+export type { UmbSearchDataSource } from './search-data-source.interface.js';
+export type { UmbSearchRepository } from './search-repository.interface.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-data-source.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-data-source.interface.ts
new file mode 100644
index 0000000000..7b54ac9237
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-data-source.interface.ts
@@ -0,0 +1,11 @@
+import type { UmbSearchRequestArgs, UmbSearchResultItemModel } from './types.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbDataSourceResponse, UmbPagedModel } from '@umbraco-cms/backoffice/repository';
+
+export interface UmbSearchDataSourceConstructor {
+ new (host: UmbControllerHost): UmbSearchDataSource;
+}
+
+export interface UmbSearchDataSource {
+ search(args: UmbSearchRequestArgs): Promise>>;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index ba178e94ef..ff3d10887e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -10,7 +10,7 @@ import '../search-result/search-result-item.element.js';
type SearchProvider = {
name: string;
- api: UmbSearchProvider;
+ api: UmbSearchProvider;
alias: string;
};
@@ -39,10 +39,10 @@ export class UmbSearchModalElement extends UmbLitElement {
#observeViews() {
new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'searchProvider', null, async (providers) => {
- const searchProviders: SearchProvider[] = [];
+ const searchProviders: Array = [];
for (const provider of providers) {
- const api = await createExtensionApi(this, provider.manifest);
+ const api = await createExtensionApi>(this, provider.manifest);
if (api) {
searchProviders.push({
name: provider.manifest.meta?.label || provider.manifest.name,
@@ -79,7 +79,7 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#updateSearchResults();
}
- async #setCurrentProvider(searchProvider: SearchProvider) {
+ #setCurrentProvider(searchProvider: SearchProvider) {
this._currentProvider = searchProvider;
this.#focusInput();
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-repository.interface.ts
new file mode 100644
index 0000000000..d13705beb1
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-repository.interface.ts
@@ -0,0 +1,6 @@
+import type { UmbSearchRequestArgs, UmbSearchResultItemModel } from './types.js';
+import type { UmbRepositoryResponse, UmbPagedModel } from '@umbraco-cms/backoffice/repository';
+
+export interface UmbSearchRepository {
+ search(args: UmbSearchRequestArgs): Promise>>;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index 93514ed934..0b67498d21 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -1,4 +1,5 @@
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+import type { UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository';
export type UmbSearchResultItemModel = {
entityType: string;
@@ -11,6 +12,6 @@ export type UmbSearchRequestArgs = {
query: string;
};
-export interface UmbSearchProvider extends UmbApi {
- search(args: UmbSearchRequestArgs): Promise;
+export interface UmbSearchProvider extends UmbApi {
+ search(args: UmbSearchRequestArgs): Promise>>;
}
From 78b4610ff515d22c4cbd76f4635638789b231d98 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 15:20:36 +0200
Subject: [PATCH 019/323] document types search
---
.../documents/document-types/manifests.ts | 2 +
.../document-type-item.server.data-source.ts | 2 +
.../document-types/repository/item/types.ts | 3 +
.../search/document-type-search.repository.ts | 23 ++++++++
...document-type-search.server.data-source.ts | 55 +++++++++++++++++++
.../search/document-type.search-provider.ts | 23 ++++++++
.../document-types/search/manifests.ts | 21 +++++++
.../src/packages/search/types.ts | 2 +-
8 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/manifests.ts
index e582d0a40e..0db05d5144 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/manifests.ts
@@ -2,6 +2,7 @@ import { manifests as entityActionsManifests } from './entity-actions/manifests.
import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as propertyEditorManifests } from './property-editors/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
@@ -10,6 +11,7 @@ export const manifests = [
...menuManifests,
...propertyEditorManifests,
...repositoryManifests,
+ ...searchManifests,
...treeManifests,
...workspaceManifests,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts
index 3c14064764..33b7b69346 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts
@@ -1,3 +1,4 @@
+import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js';
import type { UmbDocumentTypeItemModel } from './types.js';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import type { DocumentTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
@@ -29,6 +30,7 @@ const getItems = (uniques: Array) => DocumentTypeService.getItemDocument
const mapper = (item: DocumentTypeItemResponseModel): UmbDocumentTypeItemModel => {
return {
+ entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
isElement: item.isElement,
icon: item.icon,
unique: item.id,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/types.ts
index 1079e8cf02..c7dd55055c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/types.ts
@@ -1,4 +1,7 @@
+import type { UmbDocumentTypeEntityType } from '../../entity.js';
+
export type UmbDocumentTypeItemModel = {
+ entityType: UmbDocumentTypeEntityType;
unique: string;
name: string;
isElement: boolean;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
new file mode 100644
index 0000000000..8a63ac0fda
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbDocumentTypeSearchServerDataSource } from './document-type-search.server.data-source.js';
+import type { UmbDocumentTypeSearchItemModel } from './document-type.search-provider.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbDocumentTypeSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbDocumentTypeSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbDocumentTypeSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
new file mode 100644
index 0000000000..a1e4f0c1e8
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
@@ -0,0 +1,55 @@
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { UmbDocumentTypeSearchItemModel } from './document-type.search-provider.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { DocumentTypeService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbDocumentTypeSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbDocumentTypeSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbDocumentTypeSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbDocumentTypeSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbDocumentTypeSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ DocumentTypeService.getItemDocumentTypeSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
+ isElement: item.isElement,
+ icon: item.icon,
+ unique: item.id,
+ name: item.name,
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
new file mode 100644
index 0000000000..ccf82a2b8d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbDocumentTypeItemModel } from '../index.js';
+import { UmbDocumentTypeSearchRepository } from './document-type-search.repository.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbDocumentTypeSearchItemModel extends UmbDocumentTypeItemModel {}
+
+export class UmbDocumentTypeSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
+ #repository = new UmbDocumentTypeSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbDocumentTypeSearchProvider as api };
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
new file mode 100644
index 0000000000..25d37e1f32
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Document Type Search Provider',
+ alias: 'Umb.SearchProvider.DocumentType',
+ type: 'searchProvider',
+ api: () => import('./document-type.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Document Types',
+ },
+ },
+ {
+ name: 'Document Type Search Result Item ',
+ alias: 'Umb.SearchResultItem.DocumentType',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_DOCUMENT_TYPE_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index 0b67498d21..f9218878e0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -3,7 +3,7 @@ import type { UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffi
export type UmbSearchResultItemModel = {
entityType: string;
- icon?: string;
+ icon?: string | null;
name: string;
unique: string;
};
From 11dfe0449648d31b8da2e866b1da92a0f04fd4a7 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 11 Apr 2024 15:23:39 +0200
Subject: [PATCH 020/323] cleanup
---
.../search/search-result/search-result-item.element.ts | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
index 41a9b41b09..a5bf344f2b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
@@ -12,14 +12,12 @@ export class UmbSearchResultItemElement extends UmbLitElement {
render() {
if (!this.item) return nothing;
- const url = 'url/goes/here';
-
return html`
${this.item.icon ? html` ` : this.#renderHashTag()}
- ${this.item.name} ${url ? html`${url} ` : nothing}
+ ${this.item.name}
>
`;
@@ -70,11 +68,6 @@ export class UmbSearchResultItemElement extends UmbLitElement {
.item-symbol {
opacity: 0.4;
}
- .item-url {
- font-size: 0.8rem;
- line-height: 1.2;
- font-weight: 100;
- }
.item-name {
display: flex;
flex-direction: column;
From 6ee54436c9f96e885aa7aedd34e56f9cb18f7698 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 12:22:37 +0200
Subject: [PATCH 021/323] media types
---
.../packages/media/media-types/manifests.ts | 2 +
.../media-types/repository/item/types.ts | 3 ++
.../media/media-types/search/manifests.ts | 21 ++++++++
.../search/media-type-search.repository.ts | 23 ++++++++
.../media-type-search.server.data-source.ts | 54 +++++++++++++++++++
.../search/media-type.search-provider.ts | 23 ++++++++
6 files changed, 126 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts
index a868fd5b1e..422f3cbb8c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/manifests.ts
@@ -4,6 +4,7 @@ import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
import { manifests as propertyEditorUiManifests } from './property-editors/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
export const manifests = [
...entityActionsManifests,
@@ -12,4 +13,5 @@ export const manifests = [
...treeManifests,
...workspaceManifests,
...propertyEditorUiManifests,
+ ...searchManifests,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/types.ts
index f284c5ca85..e905cf16b1 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/types.ts
@@ -1,4 +1,7 @@
+import type { UmbMediaTypeEntityType } from '../../entity.js';
+
export interface UmbMediaTypeItemModel {
+ entityType: UmbMediaTypeEntityType;
icon: string | null;
name: string;
unique: string;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
new file mode 100644
index 0000000000..d4db07db36
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_MEDIA_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Media Type Search Provider',
+ alias: 'Umb.SearchProvider.MediaType',
+ type: 'searchProvider',
+ api: () => import('./media-type.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Media Types',
+ },
+ },
+ {
+ name: 'Media Type Search Result Item ',
+ alias: 'Umb.SearchResultItem.MediaType',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_MEDIA_TYPE_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
new file mode 100644
index 0000000000..da37e717ca
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbMediaTypeSearchServerDataSource } from './media-type-search.server.data-source.js';
+import type { UmbMediaTypeSearchItemModel } from './media-type.search-provider.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbMediaTypeSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbMediaTypeSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbMediaTypeSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
new file mode 100644
index 0000000000..0b15c35bc3
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
@@ -0,0 +1,54 @@
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_MEDIA_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { UmbMediaTypeSearchItemModel } from './media-type.search-provider.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { MediaTypeService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbMediaTypeSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbMediaTypeSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbMediaTypeSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbMediaTypeSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbMediaTypeSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ MediaTypeService.getItemMediaTypeSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_MEDIA_TYPE_ENTITY_TYPE,
+ unique: item.id,
+ name: item.name,
+ icon: item.icon || null,
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
new file mode 100644
index 0000000000..a7e97024cb
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbMediaTypeItemModel } from '../index.js';
+import { UmbMediaTypeSearchRepository } from './media-type-search.repository.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbMediaTypeSearchItemModel extends UmbMediaTypeItemModel {}
+
+export class UmbMediaTypeSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
+ #repository = new UmbMediaTypeSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbMediaTypeSearchProvider as api };
From 1d098410978e6c32e73cb988bea59f0b6f0a7556 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 12:51:29 +0200
Subject: [PATCH 022/323] media
---
.../src/packages/media/media/manifests.ts | 2 +
.../item/media-item.server.data-source.ts | 2 +
.../media/media/repository/item/types.ts | 2 +
.../packages/media/media/search/manifests.ts | 21 ++++++
.../media/search/media-search.repository.ts | 23 +++++++
.../search/media-search.server.data-source.ts | 65 +++++++++++++++++++
.../media/search/media.search-provider.ts | 20 ++++++
7 files changed, 135 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts
index cbdd5167a5..b0276fdcdf 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts
@@ -5,6 +5,7 @@ import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as propertyEditorsManifests } from './property-editors/manifests.js';
import { manifests as recycleBinManifests } from './recycle-bin/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
import { manifests as sectionViewManifests } from './section-view/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
@@ -17,6 +18,7 @@ export const manifests = [
...propertyEditorsManifests,
...recycleBinManifests,
...repositoryManifests,
+ ...searchManifests,
...sectionViewManifests,
...treeManifests,
...workspaceManifests,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts
index a1ffb549c7..77c9bda32c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts
@@ -1,3 +1,4 @@
+import { UMB_MEDIA_ENTITY_TYPE, UmbMediaEntityType } from '../../entity.js';
import type { UmbMediaItemModel } from './types.js';
import type { MediaItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import { MediaService } from '@umbraco-cms/backoffice/external/backend-api';
@@ -32,6 +33,7 @@ const getItems = (uniques: Array) => MediaService.getItemMedia({ id: uni
const mapper = (item: MediaItemResponseModel): UmbMediaItemModel => {
return {
+ entityType: UMB_MEDIA_ENTITY_TYPE,
unique: item.id,
isTrashed: item.isTrashed,
mediaType: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/types.ts
index 5d9b42300e..5dd1780a06 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/types.ts
@@ -1,6 +1,8 @@
+import type { UmbMediaEntityType } from '../../entity.js';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
export interface UmbMediaItemModel {
+ entityType: UmbMediaEntityType;
unique: string;
isTrashed: boolean;
mediaType: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
new file mode 100644
index 0000000000..fa80755e07
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Media Search Provider',
+ alias: 'Umb.SearchProvider.Media',
+ type: 'searchProvider',
+ api: () => import('./media.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Media',
+ },
+ },
+ {
+ name: 'Media Search Result Item ',
+ alias: 'Umb.SearchResultItem.Media',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_MEDIA_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
new file mode 100644
index 0000000000..4d00fca682
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbMediaSearchServerDataSource } from './media-search.server.data-source.js';
+import type { UmbMediaSearchItemModel } from './media.search-provider.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbMediaSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbMediaSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbMediaSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
new file mode 100644
index 0000000000..998a7daa12
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
@@ -0,0 +1,65 @@
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js';
+import type { UmbMediaSearchItemModel } from './media.search-provider.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { MediaService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbMediaSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbMediaSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbMediaSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbMediaSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbMediaSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ MediaService.getItemMediaSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_MEDIA_ENTITY_TYPE,
+ unique: item.id,
+ isTrashed: item.isTrashed,
+ mediaType: {
+ unique: item.mediaType.id,
+ icon: item.mediaType.icon,
+ collection: item.mediaType.collection ? { unique: item.mediaType.collection.id } : null,
+ },
+ variants: item.variants.map((variant) => {
+ return {
+ culture: variant.culture || null,
+ name: variant.name,
+ };
+ }),
+ name: item.variants[0]?.name, // TODO: get correct variant name
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
new file mode 100644
index 0000000000..dd8c80a930
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
@@ -0,0 +1,20 @@
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbMediaItemModel } from '../index.js';
+import { UmbMediaSearchRepository } from './media-search.repository.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbMediaSearchItemModel extends UmbMediaItemModel {}
+
+export class UmbMediaSearchProvider extends UmbControllerBase implements UmbSearchProvider {
+ #repository = new UmbMediaSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbMediaSearchProvider as api };
From c6bdeaf5bfe9a90545dc4961eccb393397763f36 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 12:57:09 +0200
Subject: [PATCH 023/323] member types
---
.../packages/members/member-type/manifests.ts | 2 +
.../members/member-type/search/manifests.ts | 21 ++++++++
.../search/member-type-search.repository.ts | 23 ++++++++
.../member-type-search.server.data-source.ts | 54 +++++++++++++++++++
.../search/member-type.search-provider.ts | 23 ++++++++
5 files changed, 123 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/manifests.ts
index baad2b5948..254e63a930 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/manifests.ts
@@ -1,6 +1,7 @@
import { manifests as entityActionsManifests } from './entity-actions/manifests.js';
import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
@@ -10,6 +11,7 @@ export const manifests = [
...entityActionsManifests,
...menuManifests,
...repositoryManifests,
+ ...searchManifests,
...treeManifests,
...workspaceManifests,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
new file mode 100644
index 0000000000..e7fad6d7af
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Member Type Search Provider',
+ alias: 'Umb.SearchProvider.MemberType',
+ type: 'searchProvider',
+ api: () => import('./member-type.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Member Types',
+ },
+ },
+ {
+ name: 'Member Type Search Result Item ',
+ alias: 'Umb.SearchResultItem.MemberType',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
new file mode 100644
index 0000000000..12c26d0648
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbMemberTypeSearchServerDataSource } from './member-type-search.server.data-source.js';
+import type { UmbMemberTypeSearchItemModel } from './member-type.search-provider.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbMemberTypeSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbMemberTypeSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbMemberTypeSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
new file mode 100644
index 0000000000..736d517ea5
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
@@ -0,0 +1,54 @@
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../entity.js';
+import type { UmbMemberTypeSearchItemModel } from './member-type.search-provider.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbMemberTypeSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbMemberTypeSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbMemberTypeSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbMemberTypeSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbMemberTypeSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ MemberTypeService.getItemMemberTypeSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_MEMBER_TYPE_ENTITY_TYPE,
+ unique: item.id,
+ name: item.name,
+ icon: item.icon || '',
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
new file mode 100644
index 0000000000..ff690ae1e2
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
@@ -0,0 +1,23 @@
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbMemberTypeItemModel } from '../repository/item/types.js';
+import { UmbMemberTypeSearchRepository } from './member-type-search.repository.js';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbMemberTypeSearchItemModel extends UmbMemberTypeItemModel {}
+
+export class UmbMemberTypeSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
+ #repository = new UmbMemberTypeSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbMemberTypeSearchProvider as api };
From e695a389b3f58be7f1be11c0a6aeef2ebbdf8b2e Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 13:03:46 +0200
Subject: [PATCH 024/323] members
---
.../src/packages/members/member/manifests.ts | 10 +--
.../item/member-item.server.data-source.ts | 2 +
.../members/member/repository/item/types.ts | 2 +
.../members/member/search/manifests.ts | 21 ++++++
.../member/search/member-search.repository.ts | 23 +++++++
.../member-search.server.data-source.ts | 64 +++++++++++++++++++
.../member/search/member.search-provider.ts | 20 ++++++
7 files changed, 138 insertions(+), 4 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts
index db74e42f8a..608ea2a429 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts
@@ -1,15 +1,17 @@
+import { manifests as collectionManifests } from './collection/manifests.js';
import { manifests as entityActionManifests } from './entity-actions/manifests.js';
+import { manifests as memberPickerModalManifests } from './components/member-picker-modal/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
import { manifests as sectionViewManifests } from './section-view/manifests.js';
import { manifests as workspaceManifests } from './workspace/manifests.js';
-import { manifests as collectionManifests } from './collection/manifests.js';
-import { manifests as memberPickerModalManifests } from './components/member-picker-modal/manifests.js';
export const manifests = [
+ ...collectionManifests,
...entityActionManifests,
+ ...memberPickerModalManifests,
...repositoryManifests,
+ ...searchManifests,
...sectionViewManifests,
...workspaceManifests,
- ...collectionManifests,
- ...memberPickerModalManifests,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
index 02696b0afa..f21e4d5aca 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
@@ -3,6 +3,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'
import type { MemberItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import { MemberService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js';
/**
* A server data source for Member items
@@ -32,6 +33,7 @@ const getItems = (uniques: Array) => MemberService.getItemMember({ id: u
const mapper = (item: MemberItemResponseModel): UmbMemberItemModel => {
return {
+ entityType: UMB_MEMBER_ENTITY_TYPE,
unique: item.id,
name: item.variants[0].name || '',
memberType: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts
index fef6a44474..9b58f77ef6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts
@@ -1,6 +1,8 @@
+import type { UmbMemberEntityType } from '../../entity.js';
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
export interface UmbMemberItemModel {
+ entityType: UmbMemberEntityType;
unique: string;
name: string; // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
memberType: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
new file mode 100644
index 0000000000..dd26c7cecd
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Member Search Provider',
+ alias: 'Umb.SearchProvider.Member',
+ type: 'searchProvider',
+ api: () => import('./member.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Members',
+ },
+ },
+ {
+ name: 'Member Search Result Item ',
+ alias: 'Umb.SearchResultItem.Member',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_MEMBER_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.repository.ts
new file mode 100644
index 0000000000..67e270b90d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.repository.ts
@@ -0,0 +1,23 @@
+import { UmbMemberSearchServerDataSource } from './member-search.server.data-source.js';
+import type { UmbMemberSearchItemModel } from './member.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbMemberSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbMemberSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbMemberSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
new file mode 100644
index 0000000000..ec3ee432bd
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
@@ -0,0 +1,64 @@
+import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js';
+import type { UmbMemberSearchItemModel } from './member.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { MemberService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbMemberSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbMemberSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbMemberSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbMemberSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbMemberSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ MemberService.getItemMemberSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_MEMBER_ENTITY_TYPE,
+ unique: item.id,
+ name: item.variants[0].name || '',
+ memberType: {
+ unique: item.memberType.id,
+ icon: item.memberType.icon,
+ collection: item.memberType.collection ? { unique: item.memberType.collection.id } : null,
+ },
+ variants: item.variants.map((variant) => {
+ return {
+ name: variant.name,
+ culture: variant.culture || null,
+ };
+ }),
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
new file mode 100644
index 0000000000..99ec93e170
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
@@ -0,0 +1,20 @@
+import type { UmbMemberItemModel } from '../repository/item/types.js';
+import { UmbMemberSearchRepository } from './member-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbMemberSearchItemModel extends UmbMemberItemModel {}
+
+export class UmbMemberSearchProvider extends UmbControllerBase implements UmbSearchProvider {
+ #repository = new UmbMemberSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbMemberSearchProvider as api };
From aa777e9041d7b0492700135f991c7bd94b2311ad Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 13:08:14 +0200
Subject: [PATCH 025/323] templates
---
.../templating/templates/manifests.ts | 14 ++---
.../item/template-item.server.data-source.ts | 2 +
.../templates/repository/item/types.ts | 3 ++
.../templating/templates/search/manifests.ts | 21 ++++++++
.../search/template-search.repository.ts | 23 ++++++++
.../template-search.server.data-source.ts | 54 +++++++++++++++++++
.../search/template.search-provider.ts | 23 ++++++++
7 files changed, 134 insertions(+), 6 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.repository.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/manifests.ts
index 8eaf1de363..b2d2ef8559 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/manifests.ts
@@ -1,15 +1,17 @@
-import { manifests as repositoryManifests } from './repository/manifests.js';
-import { manifests as menuManifests } from './menu/manifests.js';
-import { manifests as treeManifests } from './tree/manifests.js';
import { manifests as entityActionsManifests } from './entity-actions/manifests.js';
-import { manifests as workspaceManifests } from './workspace/manifests.js';
+import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as modalManifests } from './modals/manifests.js';
+import { manifests as repositoryManifests } from './repository/manifests.js';
+import { manifests as searchManifests } from './search/manifests.js';
+import { manifests as treeManifests } from './tree/manifests.js';
+import { manifests as workspaceManifests } from './workspace/manifests.js';
export const manifests = [
+ ...entityActionsManifests,
+ ...menuManifests,
...modalManifests,
...repositoryManifests,
- ...menuManifests,
+ ...searchManifests,
...treeManifests,
- ...entityActionsManifests,
...workspaceManifests,
];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts
index d489a0ff3a..5d23912e28 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts
@@ -1,3 +1,4 @@
+import { UMB_TEMPLATE_ENTITY_TYPE } from '../../entity.js';
import type { UmbTemplateItemModel } from './types.js';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import type { TemplateItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
@@ -32,6 +33,7 @@ const getItems = (uniques: Array) => TemplateService.getItemTemplate({ i
const mapper = (item: TemplateItemResponseModel): UmbTemplateItemModel => {
return {
+ entityType: UMB_TEMPLATE_ENTITY_TYPE,
unique: item.id,
name: item.name,
alias: item.alias,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/types.ts
index 26c6cd7105..21b449e54f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/types.ts
@@ -1,4 +1,7 @@
+import type { UmbTemplateEntityType } from '../../entity.js';
+
export interface UmbTemplateItemModel {
+ entityType: UmbTemplateEntityType;
unique: string;
name: string;
alias: string;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
new file mode 100644
index 0000000000..65d4e6db7c
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
@@ -0,0 +1,21 @@
+import { UMB_TEMPLATE_ENTITY_TYPE } from '../entity.js';
+import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ name: 'Template Search Provider',
+ alias: 'Umb.SearchProvider.Template',
+ type: 'searchProvider',
+ api: () => import('./template.search-provider.js'),
+ weight: 1000,
+ meta: {
+ label: 'Templates',
+ },
+ },
+ {
+ name: 'Template Search Result Item ',
+ alias: 'Umb.SearchResultItem.Template',
+ type: 'searchResultItem',
+ forEntityTypes: [UMB_TEMPLATE_ENTITY_TYPE],
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.repository.ts
new file mode 100644
index 0000000000..8ff8d8dc75
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.repository.ts
@@ -0,0 +1,23 @@
+import { UmbTemplateSearchServerDataSource } from './template-search.server.data-source.js';
+import type { UmbTemplateSearchItemModel } from './template.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+
+export class UmbTemplateSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
+ #dataSource: UmbTemplateSearchServerDataSource;
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+
+ this.#dataSource = new UmbTemplateSearchServerDataSource(this);
+ }
+
+ search(args: UmbSearchRequestArgs) {
+ return this.#dataSource.search(args);
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
new file mode 100644
index 0000000000..a502683fbe
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
@@ -0,0 +1,54 @@
+import { UMB_TEMPLATE_ENTITY_TYPE } from '../entity.js';
+import type { UmbTemplateSearchItemModel } from './template.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { TemplateService } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+
+/**
+ * A data source for the Rollback that fetches data from the server
+ * @export
+ * @class UmbTemplateSearchServerDataSource
+ * @implements {RepositoryDetailDataSource}
+ */
+export class UmbTemplateSearchServerDataSource implements UmbSearchDataSource {
+ #host: UmbControllerHost;
+
+ /**
+ * Creates an instance of UmbTemplateSearchServerDataSource.
+ * @param {UmbControllerHost} host
+ * @memberof UmbTemplateSearchServerDataSource
+ */
+ constructor(host: UmbControllerHost) {
+ this.#host = host;
+ }
+
+ /**
+ * Get a list of versions for a data
+ * @return {*}
+ * @memberof UmbTemplateSearchServerDataSource
+ */
+ async search(args: UmbSearchRequestArgs) {
+ const { data, error } = await tryExecuteAndNotify(
+ this.#host,
+ TemplateService.getItemTemplateSearch({
+ query: args.query,
+ }),
+ );
+
+ if (data) {
+ const mappedItems: Array = data.items.map((item) => {
+ return {
+ entityType: UMB_TEMPLATE_ENTITY_TYPE,
+ unique: item.id,
+ name: item.name,
+ alias: item.alias,
+ };
+ });
+
+ return { data: { items: mappedItems, total: data.total } };
+ }
+
+ return { error };
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
new file mode 100644
index 0000000000..28477776d5
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
@@ -0,0 +1,23 @@
+import type { UmbTemplateItemModel } from '../repository/item/types.js';
+import { UmbTemplateSearchRepository } from './template-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+
+export interface UmbTemplateSearchItemModel extends UmbTemplateItemModel {}
+
+export class UmbTemplateSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
+ #repository = new UmbTemplateSearchRepository(this);
+
+ async search(args: UmbSearchRequestArgs) {
+ return this.#repository.search(args);
+ }
+
+ destroy(): void {
+ this.#repository.destroy();
+ }
+}
+
+export { UmbTemplateSearchProvider as api };
From dda5f477b0e41d7ce197cb917980892461f81500 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 15 Apr 2024 13:16:43 +0200
Subject: [PATCH 026/323] add entity type to mappers
---
.../repository/data-type-collection.server.data-source.ts | 2 ++
.../repository/item/data-type-item.server.data-source.ts | 2 ++
.../repository/item/media-type-item.server.data-source.ts | 2 ++
3 files changed, 6 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts
index d323766736..e516f6f973 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/collection/repository/data-type-collection.server.data-source.ts
@@ -1,5 +1,6 @@
import type { UmbDataTypeCollectionFilterModel } from '../types.js';
import type { UmbDataTypeItemModel } from '../../repository/index.js';
+import { UMB_DATA_TYPE_ENTITY_TYPE } from '../../entity.js';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbCollectionDataSource } from '@umbraco-cms/backoffice/collection';
@@ -53,6 +54,7 @@ export class UmbDataTypeCollectionServerDataSource implements UmbCollectionDataS
const mappedItems: Array = items.map((item: DataTypeItemResponseModel) => {
const dataTypeDetail: UmbDataTypeItemModel = {
+ entityType: UMB_DATA_TYPE_ENTITY_TYPE,
unique: item.id,
name: item.name,
propertyEditorUiAlias: item.editorUiAlias!,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts
index 87f394b514..9845ede662 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts
@@ -1,3 +1,4 @@
+import { UMB_DATA_TYPE_ENTITY_TYPE } from '../../entity.js';
import type { UmbDataTypeItemModel } from './types.js';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import type { DataTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
@@ -43,6 +44,7 @@ const getItems = (uniques: Array) => DataTypeService.getItemDataType({ i
const mapper = (item: DataTypeItemResponseModel): UmbDataTypeItemModel => {
return {
+ entityType: UMB_DATA_TYPE_ENTITY_TYPE,
unique: item.id,
name: item.name,
propertyEditorUiAlias: item.editorUiAlias || '', // TODO: why can this be undefined or null on the server?
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts
index 1eaa920d14..30eb55ee38 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts
@@ -1,3 +1,4 @@
+import { UMB_MEDIA_TYPE_ENTITY_TYPE } from '../../entity.js';
import type { UmbMediaTypeItemModel } from './types.js';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import type { MediaTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
@@ -32,6 +33,7 @@ const getItems = (uniques: Array) => MediaTypeService.getItemMediaType({
const mapper = (item: MediaTypeItemResponseModel): UmbMediaTypeItemModel => {
return {
+ entityType: UMB_MEDIA_TYPE_ENTITY_TYPE,
icon: item.icon || null,
name: item.name,
unique: item.id,
From 372689d4e0880f22066a8dbba8f799bf50424d0b Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:07:29 +0200
Subject: [PATCH 027/323] add timer to input
---
.../search-modal/search-modal.element.ts | 31 +++++++++++++++----
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index ff3d10887e..5f4b501e54 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -31,6 +31,12 @@ export class UmbSearchModalElement extends UmbLitElement {
@state()
_currentProvider?: SearchProvider;
+ @state()
+ _loading: boolean = false;
+
+ #inputTimer?: NodeJS.Timeout;
+ #inputTimerAmount = 300;
+
constructor() {
super();
@@ -74,9 +80,16 @@ export class UmbSearchModalElement extends UmbLitElement {
#onSearchChange(event: InputEvent) {
const target = event.target as HTMLInputElement;
- this._search = target.value;
+ this._search = target.value.trim();
- this.#updateSearchResults();
+ clearTimeout(this.#inputTimer);
+ if (!this._search) {
+ this._loading = false;
+ return;
+ }
+
+ this._loading = true;
+ this.#inputTimer = setTimeout(() => this.#updateSearchResults(), this.#inputTimerAmount);
}
#setCurrentProvider(searchProvider: SearchProvider) {
@@ -94,14 +107,14 @@ export class UmbSearchModalElement extends UmbLitElement {
} else {
this._searchResults = [];
}
+
+ this._loading = false;
}
render() {
return html`
-
-
-
+ ${this.#renderSearchIcon()}
+ ${this._loading ? html`
` : html`
`}
+
`;
+ }
+
#renderSearchTags() {
return html`
${repeat(
@@ -152,7 +171,7 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#renderNoResults() {
- return html`
No results found
`;
+ return this._loading ? nothing : html`
No results found
`;
}
static styles = [
From f76e93f7d930fd9798f4dcb0315340dff2151d22 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:12:08 +0200
Subject: [PATCH 028/323] lint
---
.../packages/data-type/search/data-type-search.repository.ts | 2 +-
.../data-type/search/data-type-search.server.data-source.ts | 2 +-
.../src/packages/data-type/search/data-type.search-provider.ts | 2 +-
.../document-types/search/document-type-search.repository.ts | 2 +-
.../search/document-type-search.server.data-source.ts | 2 +-
.../document-types/search/document-type.search-provider.ts | 2 +-
.../documents/documents/search/document-search.repository.ts | 2 +-
.../documents/search/document-search.server.data-source.ts | 2 +-
.../documents/documents/search/document.search-provider.ts | 2 +-
.../media/media-types/search/media-type-search.repository.ts | 2 +-
.../media-types/search/media-type-search.server.data-source.ts | 2 +-
.../media/media-types/search/media-type.search-provider.ts | 2 +-
.../src/packages/media/media/search/media-search.repository.ts | 2 +-
.../media/media/search/media-search.server.data-source.ts | 2 +-
.../src/packages/media/media/search/media.search-provider.ts | 2 +-
.../members/member-type/search/member-type-search.repository.ts | 2 +-
.../member-type/search/member-type-search.server.data-source.ts | 2 +-
.../members/member-type/search/member-type.search-provider.ts | 2 +-
.../member/repository/item/member-item.server.data-source.ts | 2 +-
19 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
index edbb2d0ed0..86af02b505 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.repository.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDataTypeSearchServerDataSource } from './data-type-search.server.data-source.js';
import type { UmbDataTypeSearchItemModel } from './data-type.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
index 09c60af80c..2dcd9a55aa 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_DATA_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbDataTypeSearchItemModel } from './data-type.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
index 783484bbee..a315d0904c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbDataTypeItemModel } from '../index.js';
import { UmbDataTypeSearchRepository } from './data-type-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbDataTypeSearchItemModel extends UmbDataTypeItemModel {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
index 8a63ac0fda..93a12bba8a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.repository.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDocumentTypeSearchServerDataSource } from './document-type-search.server.data-source.js';
import type { UmbDocumentTypeSearchItemModel } from './document-type.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
index a1e4f0c1e8..7b8c2c0f56 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbDocumentTypeSearchItemModel } from './document-type.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DocumentTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
index ccf82a2b8d..2d4a51bfc3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbDocumentTypeItemModel } from '../index.js';
import { UmbDocumentTypeSearchRepository } from './document-type-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbDocumentTypeSearchItemModel extends UmbDocumentTypeItemModel {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
index e49241d353..6a2f556a19 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
@@ -1,5 +1,5 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDocumentSearchServerDataSource } from './document-search.server.data-source.js';
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
index e18b16d76c..d9c71ab51a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
@@ -1,5 +1,5 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
index 03333995e1..e7822a5a47 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
@@ -1,5 +1,5 @@
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbDocumentSearchRepository } from './document-search.repository.js';
+import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
index da37e717ca..12486f5f16 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.repository.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbMediaTypeSearchServerDataSource } from './media-type-search.server.data-source.js';
import type { UmbMediaTypeSearchItemModel } from './media-type.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
index 0b15c35bc3..a05b50817a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_MEDIA_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbMediaTypeSearchItemModel } from './media-type.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { MediaTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
index a7e97024cb..e85cc21cc8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbMediaTypeItemModel } from '../index.js';
import { UmbMediaTypeSearchRepository } from './media-type-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbMediaTypeSearchItemModel extends UmbMediaTypeItemModel {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
index 4d00fca682..cda2d907f4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.repository.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbMediaSearchServerDataSource } from './media-search.server.data-source.js';
import type { UmbMediaSearchItemModel } from './media.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
index 998a7daa12..bc3a660932 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js';
import type { UmbMediaSearchItemModel } from './media.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { MediaService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
index dd8c80a930..89f3b95cfb 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbMediaItemModel } from '../index.js';
import { UmbMediaSearchRepository } from './media-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbMediaSearchItemModel extends UmbMediaItemModel {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
index 12c26d0648..ad96738a6d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.repository.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbMemberTypeSearchServerDataSource } from './member-type-search.server.data-source.js';
import type { UmbMemberTypeSearchItemModel } from './member-type.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
index 736d517ea5..79b16fed9e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbMemberTypeSearchItemModel } from './member-type.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
index ff690ae1e2..852f7089e0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
@@ -1,6 +1,6 @@
-import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbMemberTypeItemModel } from '../repository/item/types.js';
import { UmbMemberTypeSearchRepository } from './member-type-search.repository.js';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
export interface UmbMemberTypeSearchItemModel extends UmbMemberTypeItemModel {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
index f21e4d5aca..08515c6646 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts
@@ -1,9 +1,9 @@
+import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js';
import type { UmbMemberItemModel } from './types.js';
import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository';
import type { MemberItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import { MemberService } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js';
/**
* A server data source for Member items
From 74155bd2a89b1fca9ef959905ca1758055126c0d Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:18:19 +0200
Subject: [PATCH 029/323] destroy repo
---
.../documents/documents/search/document.search-provider.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
index e7822a5a47..760b37f3ce 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
@@ -11,7 +11,7 @@ export class UmbDocumentSearchProvider extends UmbControllerBase implements UmbA
}
destroy(): void {
- throw new Error('Method not implemented.');
+ this.#repository.destroy();
}
}
From cb85894856ed8401c84a950d3733bc6d1463100c Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:34:04 +0200
Subject: [PATCH 030/323] dont make a new request if same tag
---
.../src/packages/search/search-modal/search-modal.element.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 5f4b501e54..4108748cb9 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -93,9 +93,12 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#setCurrentProvider(searchProvider: SearchProvider) {
+ if (this._currentProvider === searchProvider) return;
+
this._currentProvider = searchProvider;
this.#focusInput();
+ this._loading = true;
this.#updateSearchResults();
}
From 8ecc36e61a7ac0450a32f05de8edc0d001fa0f50 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:46:36 +0200
Subject: [PATCH 031/323] update weights
---
.../src/packages/data-type/search/manifests.ts | 2 +-
.../src/packages/documents/document-types/search/manifests.ts | 2 +-
.../src/packages/documents/documents/search/manifests.ts | 2 +-
.../src/packages/media/media-types/search/manifests.ts | 2 +-
.../src/packages/media/media/search/manifests.ts | 2 +-
.../src/packages/members/member-type/search/manifests.ts | 2 +-
.../src/packages/members/member/search/manifests.ts | 2 +-
.../src/packages/templating/templates/search/manifests.ts | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
index fb63c8459a..594fd1be5a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array
= [
alias: 'Umb.SearchProvider.DataType',
type: 'searchProvider',
api: () => import('./data-type.search-provider.js'),
- weight: 1000,
+ weight: 800,
meta: {
label: 'Data Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
index 25d37e1f32..8deaf580bd 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.DocumentType',
type: 'searchProvider',
api: () => import('./document-type.search-provider.js'),
- weight: 1000,
+ weight: 600,
meta: {
label: 'Document Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
index 1514c91f3a..99fe053908 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Document',
type: 'searchProvider',
api: () => import('./document.search-provider.js'),
- weight: 1000,
+ weight: 700,
meta: {
label: 'Documents',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
index d4db07db36..973b2e6cc3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.MediaType',
type: 'searchProvider',
api: () => import('./media-type.search-provider.js'),
- weight: 1000,
+ weight: 400,
meta: {
label: 'Media Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
index fa80755e07..29749ffc80 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Media',
type: 'searchProvider',
api: () => import('./media.search-provider.js'),
- weight: 1000,
+ weight: 500,
meta: {
label: 'Media',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
index e7fad6d7af..786dd15a9d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.MemberType',
type: 'searchProvider',
api: () => import('./member-type.search-provider.js'),
- weight: 1000,
+ weight: 200,
meta: {
label: 'Member Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
index dd26c7cecd..9729f06efd 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Member',
type: 'searchProvider',
api: () => import('./member.search-provider.js'),
- weight: 1000,
+ weight: 300,
meta: {
label: 'Members',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
index 65d4e6db7c..04c046c23b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Template',
type: 'searchProvider',
api: () => import('./template.search-provider.js'),
- weight: 1000,
+ weight: 100,
meta: {
label: 'Templates',
},
From d3ecaa23ff51317df52287a9a2027269e1ce4c0d Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 14:46:45 +0200
Subject: [PATCH 032/323] styling
---
.../search/search-modal/search-modal.element.ts | 2 +-
.../search-result/search-result-item.element.ts | 11 +----------
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 4108748cb9..831f0bbe41 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -209,7 +209,7 @@ export class UmbSearchModalElement extends UmbLitElement {
:host {
display: flex;
flex-direction: column;
- width: min(600px, 100vw);
+ width: min(610px, 100vw);
height: 100%;
background-color: var(--uui-color-surface);
box-sizing: border-box;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
index a5bf344f2b..30ad17f984 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
@@ -18,7 +18,6 @@ export class UmbSearchResultItemElement extends UmbLitElement {
${this.item.icon ? html` ` : this.#renderHashTag()}
${this.item.name}
- >
`;
}
@@ -56,16 +55,11 @@ export class UmbSearchResultItemElement extends UmbLitElement {
background-color: var(--uui-color-surface-emphasis);
color: var(--uui-color-interactive-emphasis);
}
- .item:hover .item-symbol {
- font-weight: unset;
- opacity: 1;
- }
.item-icon {
margin-bottom: auto;
margin-top: 5px;
}
- .item-icon,
- .item-symbol {
+ .item-icon {
opacity: 0.4;
}
.item-name {
@@ -77,9 +71,6 @@ export class UmbSearchResultItemElement extends UmbLitElement {
display: flex;
width: min-content;
}
- .item-symbol {
- font-weight: 100;
- }
a {
text-decoration: none;
color: inherit;
From fac60e05733345cf968e4c91709e2a7b016f17b6 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 16:15:34 +0200
Subject: [PATCH 033/323] add custom document search result
---
.../document-search-result-item.element.ts | 140 ++++++++++++++++++
.../documents/documents/search/manifests.ts | 1 +
2 files changed, 141 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
new file mode 100644
index 0000000000..6dab21ad0b
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
@@ -0,0 +1,140 @@
+import type { UmbDocumentItemModel, UmbDocumentItemVariantModel } from '../repository/item/types.js';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
+import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language';
+import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
+
+const elementName = 'umb-document-search-result-item';
+@customElement(elementName)
+export class UmbSearchResultItemElement extends UmbLitElement {
+ @property({ type: Object })
+ item?: UmbSearchResultItemModel & UmbDocumentItemModel;
+
+ @state()
+ _currentCulture?: string;
+
+ @state()
+ _defaultCulture?: string;
+
+ @state()
+ _variant?: UmbDocumentItemVariantModel;
+
+ constructor() {
+ super();
+
+ this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => {
+ this.#observeAppCulture(instance);
+ this.#observeDefaultCulture(instance);
+ });
+ }
+
+ #observeAppCulture(context: UmbAppLanguageContext) {
+ this.observe(context.appLanguageCulture, (value) => {
+ this._currentCulture = value;
+ this._variant = this.#getVariant(value);
+ });
+ }
+
+ #observeDefaultCulture(context: UmbAppLanguageContext) {
+ this.observe(context.appDefaultLanguage, (value) => {
+ this._defaultCulture = value?.unique;
+ });
+ }
+
+ #getVariant(culture: string | undefined) {
+ return this.item?.variants.find((x) => x.culture === culture);
+ }
+
+ #isInvariant() {
+ const firstVariant = this.item?.variants[0];
+ return firstVariant?.culture === null;
+ }
+
+ #getLabel() {
+ if (this.#isInvariant()) {
+ return this.item?.name ?? 'Unknown';
+ }
+
+ const fallbackName = this.#getVariant(this._defaultCulture)?.name ?? this.item?.name ?? 'Unknown';
+ return this._variant?.name ?? `(${fallbackName})`;
+ }
+
+ render() {
+ if (!this.item) return nothing;
+
+ return html`
+
+
+ ${this.item.icon ? html` ` : this.#renderHashTag()}
+
+ ${this.#getLabel()}
+
+ `;
+ }
+
+ #renderHashTag() {
+ return html`
+
+
+
+
+ `;
+ }
+
+ static styles = [
+ UmbTextStyles,
+ css`
+ :host {
+ display: flex;
+ gap: 12px;
+ width: 100%;
+ }
+ .item {
+ background: var(--uui-color-surface);
+ padding: var(--uui-size-space-3) var(--uui-size-space-5);
+ border-radius: var(--uui-border-radius);
+ color: var(--uui-color-interactive);
+ display: grid;
+ grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
+ align-items: center;
+ width: 100%;
+ }
+ .item:hover {
+ background-color: var(--uui-color-surface-emphasis);
+ color: var(--uui-color-interactive-emphasis);
+ }
+ .item-icon {
+ margin-bottom: auto;
+ margin-top: 5px;
+ }
+ .item-icon {
+ opacity: 0.4;
+ }
+ .item-name {
+ display: flex;
+ flex-direction: column;
+ }
+ .item-icon > * {
+ height: 1rem;
+ display: flex;
+ width: min-content;
+ }
+ a {
+ text-decoration: none;
+ color: inherit;
+ }
+ `,
+ ];
+}
+
+export { UmbSearchResultItemElement as element };
+
+declare global {
+ interface HTMLElementTagNameMap {
+ [elementName]: UmbSearchResultItemElement;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
index 99fe053908..11b13dc5c0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
@@ -16,6 +16,7 @@ export const manifests: Array = [
name: 'Document Search Result Item ',
alias: 'Umb.SearchResultItem.Document',
type: 'searchResultItem',
+ js: () => import('./document-search-result-item.element.js'),
forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE],
},
];
From 7d7ef7af4439baf1a0e19ef0b9ec19b43cd2fe96 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 16 Apr 2024 16:30:06 +0200
Subject: [PATCH 034/323] translations
---
.../src/packages/search/search-modal/search-modal.element.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 831f0bbe41..2082d7313e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -174,7 +174,7 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#renderNoResults() {
- return this._loading ? nothing : html`No results found
`;
+ return this._loading ? nothing : html`${this.localize.term('general_searchNoResult')}
`;
}
static styles = [
From d2a482a92c4bb5ff6732defe5b7e6aabaaab2af8 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 17 Apr 2024 10:15:16 +0200
Subject: [PATCH 035/323] reset search results
---
.../src/packages/search/search-modal/search-modal.element.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 2082d7313e..076558d3d9 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -85,6 +85,7 @@ export class UmbSearchModalElement extends UmbLitElement {
clearTimeout(this.#inputTimer);
if (!this._search) {
this._loading = false;
+ this._searchResults = [];
return;
}
From 7ee8be055e9e0eabdcbeb83e75dc791537713841 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Fri, 19 Apr 2024 15:35:08 +0200
Subject: [PATCH 036/323] content type workspace getName method
---
.../workspace/content-type-workspace-context.interface.ts | 1 +
.../workspace/document-type-workspace.context.ts | 3 +++
.../media-types/workspace/media-type-workspace.context.ts | 3 +++
.../member-type/workspace/member-type-workspace.context.ts | 3 +++
4 files changed, 10 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context.interface.ts
index db4bbf3419..1405ff101c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context.interface.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/content-type-workspace-context.interface.ts
@@ -8,6 +8,7 @@ export interface UmbContentTypeWorkspaceContext;
+ getName(): string | undefined;
readonly alias: Observable;
readonly description: Observable;
readonly icon: Observable;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
index 08b2610991..c5c0766105 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
@@ -41,6 +41,9 @@ export class UmbDocumentTypeWorkspaceContext
//readonly data;
readonly unique;
readonly name;
+ getName(): string | undefined {
+ return this.structure.getOwnerContentType()?.name;
+ }
readonly alias;
readonly description;
readonly icon;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace.context.ts
index 86e1fd5a81..6253c452d1 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace.context.ts
@@ -40,6 +40,9 @@ export class UmbMediaTypeWorkspaceContext
readonly data;
readonly unique;
readonly name;
+ getName(): string | undefined {
+ return this.structure.getOwnerContentType()?.name;
+ }
readonly alias;
readonly description;
readonly icon;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace.context.ts
index 65ee4c3950..5ee915d1ce 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/member-type-workspace.context.ts
@@ -37,6 +37,9 @@ export class UmbMemberTypeWorkspaceContext
readonly data;
readonly unique;
readonly name;
+ getName(): string | undefined {
+ return this.structure.getOwnerContentType()?.name;
+ }
readonly alias;
readonly description;
readonly icon;
From 3e67d26add1876a9b591f07ad9e8ce2600a9dd98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Fri, 19 Apr 2024 15:35:21 +0200
Subject: [PATCH 037/323] compose data-type name
---
.../data-type-picker-flow-modal.element.ts | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
index 962abe0c73..0394356369 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
@@ -15,6 +15,8 @@ import type { UmbDataTypeItemModel } from '@umbraco-cms/backoffice/data-type';
import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/modal';
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
+import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/content-type';
+import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
interface GroupedItems {
[key: string]: Array;
@@ -78,8 +80,18 @@ export class UmbDataTypePickerFlowModalElement extends UmbModalBaseElement<
this._createDataTypeModal = new UmbModalRouteRegistrationController(this, UMB_DATATYPE_WORKSPACE_MODAL)
.addAdditionalPath(':uiAlias')
- .onSetup((params) => {
- return { data: { entityType: UMB_DATA_TYPE_ENTITY_TYPE, preset: { editorUiAlias: params.uiAlias } } };
+ .onSetup(async (params) => {
+ const contentContext = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
+ const propContext = await this.getContext(UMB_PROPERTY_CONTEXT);
+ const propertyEditorName = this.#propertyEditorUIs.find((ui) => ui.alias === params.uiAlias)?.name;
+ const dataTypeName = `${contentContext?.getName() ?? ''} - ${propContext.getLabel() ?? ''} - ${propertyEditorName}`;
+
+ return {
+ data: {
+ entityType: UMB_DATA_TYPE_ENTITY_TYPE,
+ preset: { editorUiAlias: params.uiAlias, name: dataTypeName },
+ },
+ };
})
.onSubmit((value) => {
this._select(value?.unique);
From f269c172eb4243515f68a0ce1c8f7e607a4093e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Fri, 19 Apr 2024 19:31:48 +0200
Subject: [PATCH 038/323] generate name based on data via context api
---
.../property-type-settings-modal.element.ts | 3 +-
.../core/content-type/workspace/index.ts | 1 +
...pe-design-editor-property.context-token.ts | 4 +++
...ent-type-design-editor-property.context.ts | 34 +++++++++++++++++++
...ent-type-design-editor-property.element.ts | 4 +++
.../data-type-picker-flow-modal.element.ts | 15 +++++---
6 files changed, 55 insertions(+), 6 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context-token.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/property-type-settings/property-type-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/property-type-settings/property-type-settings-modal.element.ts
index ff53f2f34e..463ef9497e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/property-type-settings/property-type-settings-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/property-type-settings/property-type-settings-modal.element.ts
@@ -64,8 +64,7 @@ export class UmbPropertyTypeSettingsModalElement extends UmbModalBaseElement<
super.connectedCallback();
this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (instance) => {
- if (!this.data?.contentTypeId) return;
- if (instance.getUnique() !== this.data.contentTypeId) {
+ if (!this.data?.contentTypeId || instance.getUnique() !== this.data.contentTypeId) {
// We can currently only edit properties that are part of a content type workspace, which has to be present outside of the modal. [NL]
throw new Error(
'The content type workspace context does not match the content type id of the property type settings modal.',
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/index.ts
index 1a9af36bce..352572934d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/index.ts
@@ -1,2 +1,3 @@
export type * from './content-type-workspace-context.interface.js';
export * from './content-type-workspace.context-token.js';
+export * from './views/design/content-type-design-editor-property.context-token.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context-token.ts
new file mode 100644
index 0000000000..931d48e3d6
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context-token.ts
@@ -0,0 +1,4 @@
+import type { UmbPropertyTypeContext } from './content-type-design-editor-property.context.js';
+import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+
+export const UMB_PROPERTY_TYPE_CONTEXT = new UmbContextToken('UmbPropertyTypeContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context.ts
new file mode 100644
index 0000000000..87234ec3f7
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.context.ts
@@ -0,0 +1,34 @@
+import { UMB_PROPERTY_TYPE_CONTEXT } from './content-type-design-editor-property.context-token.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
+import { UmbStringState } from '@umbraco-cms/backoffice/observable-api';
+
+export class UmbPropertyTypeContext extends UmbContextBase {
+ #alias = new UmbStringState(undefined);
+ public readonly alias = this.#alias.asObservable();
+ #label = new UmbStringState(undefined);
+ public readonly label = this.#label.asObservable();
+
+ constructor(host: UmbControllerHost) {
+ super(host, UMB_PROPERTY_TYPE_CONTEXT);
+ }
+
+ public setAlias(alias: string | undefined): void {
+ this.#alias.setValue(alias);
+ }
+ public getAlias(): string | undefined {
+ return this.#alias.getValue();
+ }
+ public setLabel(label: string | undefined): void {
+ this.#label.setValue(label);
+ }
+ public getLabel(): string | undefined {
+ return this.#label.getValue();
+ }
+
+ public destroy(): void {
+ super.destroy();
+ this.#alias.destroy();
+ this.#label.destroy();
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts
index 389040c68b..4a2a857964 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts
@@ -1,3 +1,4 @@
+import { UmbPropertyTypeContext } from './content-type-design-editor-property.context.js';
import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type';
import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui';
import { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
@@ -25,6 +26,7 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
#dataTypeDetailRepository = new UmbDataTypeDetailRepository(this);
#settingsModal;
#dataTypeUnique?: string;
+ #context = new UmbPropertyTypeContext(this);
@property({ attribute: false })
public set propertyStructureHelper(value: UmbContentTypePropertyStructureHelper | undefined) {
@@ -51,6 +53,8 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
const oldValue = this._property;
if (value === oldValue) return;
this._property = value;
+ this.#context.setAlias(value?.alias);
+ this.#context.setLabel(value?.name);
this.#checkInherited();
this.#settingsModal.setUniquePathValue('propertyId', value?.id);
this.#setDataType(this._property?.dataType?.unique);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
index 0394356369..8c3c42f62b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts
@@ -15,8 +15,7 @@ import type { UmbDataTypeItemModel } from '@umbraco-cms/backoffice/data-type';
import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/modal';
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
-import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/content-type';
-import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
+import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, UMB_PROPERTY_TYPE_CONTEXT } from '@umbraco-cms/backoffice/content-type';
interface GroupedItems {
[key: string]: Array;
@@ -81,8 +80,16 @@ export class UmbDataTypePickerFlowModalElement extends UmbModalBaseElement<
this._createDataTypeModal = new UmbModalRouteRegistrationController(this, UMB_DATATYPE_WORKSPACE_MODAL)
.addAdditionalPath(':uiAlias')
.onSetup(async (params) => {
- const contentContext = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
- const propContext = await this.getContext(UMB_PROPERTY_CONTEXT);
+ const contentContextConsumer = this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, () => {
+ //this.removeUmbController(contentContextConsumer);
+ }).passContextAliasMatches();
+ const propContextConsumer = this.consumeContext(UMB_PROPERTY_TYPE_CONTEXT, () => {
+ //this.removeUmbController(propContextConsumer);
+ }).passContextAliasMatches();
+ const [contentContext, propContext] = await Promise.all([
+ contentContextConsumer.asPromise(),
+ propContextConsumer.asPromise(),
+ ]);
const propertyEditorName = this.#propertyEditorUIs.find((ui) => ui.alias === params.uiAlias)?.name;
const dataTypeName = `${contentContext?.getName() ?? ''} - ${propContext.getLabel() ?? ''} - ${propertyEditorName}`;
From 12cc2df145b665710c9a480ea28c003bbd4def2b Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Mon, 22 Apr 2024 14:44:46 +0200
Subject: [PATCH 039/323] outline styling
---
.../packages/search/search-result/search-result-item.element.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
index 30ad17f984..2eda0519a4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
@@ -50,6 +50,7 @@ export class UmbSearchResultItemElement extends UmbLitElement {
grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
align-items: center;
width: 100%;
+ outline-offset: -3px;
}
.item:hover {
background-color: var(--uui-color-surface-emphasis);
From 90906148953cb654c59169c59e08560995d34d4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 09:34:13 +0200
Subject: [PATCH 040/323] preparation
---
.../tree-picker/tree-picker-modal.element.ts | 33 +++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
index c118899df7..b093cde9da 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
@@ -1,7 +1,11 @@
import type { UmbTreeSelectionConfiguration } from '../types.js';
import type { UmbTreePickerModalData, UmbTreePickerModalValue } from './tree-picker-modal.token.js';
import { html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
-import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
+import {
+ UMB_WORKSPACE_MODAL,
+ UmbModalBaseElement,
+ UmbModalRouteRegistrationController,
+} from '@umbraco-cms/backoffice/modal';
import { UmbDeselectedEvent, UmbSelectedEvent, UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event';
import type { UmbTreeElement, UmbTreeItemModelBase } from '@umbraco-cms/backoffice/tree';
@@ -17,17 +21,42 @@ export class UmbTreePickerModalElement {
this._selectionConfiguration.selection = value?.selection ?? [];
});
}
+ // Same here [NL]
this._selectionConfiguration.multiple = this.data?.multiple ?? false;
+
+ // TODO: If data.enableCreate is true, we should add a button to create a new item. [NL]
+ // Does the tree know enough about this, for us to be able to create a new item? [NL]
+ // I think we need to be able to get entityType and a parentId?, or do we only allow creation in the root? and then create via entity actions? [NL]
+ // To remove the hardcoded URLs for workspaces of entity types, we could make an create event from the tree, which either this or the sidebar impl. will pick up and react to. [NL]
+ // Or maybe the tree item context base can handle this? [NL]
+ // Maybe its a general item context problem to be solved. [NL]
+ if (this._createButton) {
+ new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL)
+ .addAdditionalPath('document-type')
+ .onSetup(() => {
+ return { data: { entityType: 'document-type', preset: {} } };
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ this._createPath = routeBuilder({});
+ });
+ }
}
#onSelectionChange(event: UmbSelectionChangeEvent) {
From 56d6959c0cf5a5a014ce8d55fb44c7d06c954b8a Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 10:57:10 +0200
Subject: [PATCH 041/323] new keyboard nav
---
.../document-search-result-item.element.ts | 21 ++++---
.../search-modal/search-modal.element.ts | 62 ++++++++++++++++---
.../search-result-item.element.ts | 21 ++-----
.../src/packages/search/types.ts | 1 +
4 files changed, 69 insertions(+), 36 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
index 6dab21ad0b..dec3375b56 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
@@ -1,8 +1,8 @@
+import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { UmbDocumentItemModel, UmbDocumentItemVariantModel } from '../repository/item/types.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
-import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language';
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
@@ -65,12 +65,10 @@ export class UmbSearchResultItemElement extends UmbLitElement {
if (!this.item) return nothing;
return html`
-
-
- ${this.item.icon ? html` ` : this.#renderHashTag()}
-
- ${this.#getLabel()}
-
+
+ ${this.item.icon ? html` ` : this.#renderHashTag()}
+
+ ${this.#getLabel()}
`;
}
@@ -89,8 +87,13 @@ export class UmbSearchResultItemElement extends UmbLitElement {
UmbTextStyles,
css`
:host {
- display: flex;
- gap: 12px;
+ background: var(--uui-color-surface);
+ padding: var(--uui-size-space-3) var(--uui-size-space-5);
+ border-radius: var(--uui-border-radius);
+ color: var(--uui-color-interactive);
+ display: grid;
+ grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
+ align-items: center;
width: 100%;
}
.item {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 076558d3d9..a004e6c8a6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -34,6 +34,12 @@ export class UmbSearchModalElement extends UmbLitElement {
@state()
_loading: boolean = false;
+ @state()
+ _searchItemNavIndex = 0;
+
+ @state()
+ _inputHasFocus = false;
+
#inputTimer?: NodeJS.Timeout;
#inputTimerAmount = 300;
@@ -69,11 +75,39 @@ export class UmbSearchModalElement extends UmbLitElement {
connectedCallback() {
super.connectedCallback();
+ this.addEventListener('keydown', this.#onKeydown);
+
requestAnimationFrame(() => {
this.#focusInput();
});
}
+ #onKeydown(event: KeyboardEvent) {
+ if (event.key !== 'Tab' && event.key !== 'Shift') {
+ this.#focusInput();
+ }
+
+ if (event.key === 'ArrowDown') {
+ this.#setSearchItemNavIndex(Math.min(this._searchItemNavIndex + 1, this._searchResults.length - 1));
+ }
+ if (event.key === 'ArrowUp') {
+ this.#setSearchItemNavIndex(Math.max(this._searchItemNavIndex - 1, 0));
+ }
+ }
+
+ async #setSearchItemNavIndex(index: number) {
+ this._searchItemNavIndex = index;
+ await this.updateComplete;
+ const element = this.shadowRoot?.querySelector(`a[data-item-index="${index}"]`) as HTMLElement | null;
+
+ console.log('element', element, 'index', this._searchResults.length);
+
+ if (!element) return;
+ if (!this._searchResults.length) return;
+
+ element.focus();
+ }
+
#focusInput() {
this._input.focus();
}
@@ -111,6 +145,7 @@ export class UmbSearchModalElement extends UmbLitElement {
} else {
this._searchResults = [];
}
+ this.#setSearchItemNavIndex(0);
this._loading = false;
}
@@ -160,17 +195,19 @@ export class UmbSearchModalElement extends UmbLitElement {
return repeat(
this._searchResults,
(item) => item.unique,
- (item) => this.#renderResultItem(item),
+ (item, index) => this.#renderResultItem(item, index),
);
}
- #renderResultItem(item: UmbSearchResultItemModel) {
+ #renderResultItem(item: UmbSearchResultItemModel, index: number) {
return html`
- manifest.forEntityTypes.includes(item.entityType)}
- default-element="umb-search-result-item">
+
+ manifest.forEntityTypes.includes(item.entityType)}
+ default-element="umb-search-result-item">
+
`;
}
@@ -203,9 +240,9 @@ export class UmbSearchModalElement extends UmbLitElement {
color: var(--uui-color-interactive-emphasis);
}
.search-provider.active {
- background: var(--uui-color-surface-emphasis);
- color: var(--uui-color-interactive-emphasis);
- border-color: var(--uui-color-focus);
+ background: var(--uui-color-focus);
+ color: var(--uui-color-selected-contrast);
+ border-color: transparent;
}
:host {
display: flex;
@@ -256,6 +293,11 @@ export class UmbSearchModalElement extends UmbLitElement {
color: var(--uui-color-text-alt);
margin: var(--uui-size-space-5) 0;
}
+ .search-item {
+ color: var(--uui-color-text);
+ text-decoration: none;
+ outline-offset: -3px;
+ }
`,
];
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
index 2eda0519a4..7929225caf 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-result/search-result-item.element.ts
@@ -13,12 +13,10 @@ export class UmbSearchResultItemElement extends UmbLitElement {
if (!this.item) return nothing;
return html`
-
-
- ${this.item.icon ? html` ` : this.#renderHashTag()}
-
- ${this.item.name}
-
+
+ ${this.item.icon ? html` ` : this.#renderHashTag()}
+
+ ${this.item.name}
`;
}
@@ -37,25 +35,14 @@ export class UmbSearchResultItemElement extends UmbLitElement {
UmbTextStyles,
css`
:host {
- display: flex;
- gap: 12px;
- width: 100%;
- }
- .item {
- background: var(--uui-color-surface);
padding: var(--uui-size-space-3) var(--uui-size-space-5);
border-radius: var(--uui-border-radius);
- color: var(--uui-color-interactive);
display: grid;
grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
align-items: center;
width: 100%;
outline-offset: -3px;
}
- .item:hover {
- background-color: var(--uui-color-surface-emphasis);
- color: var(--uui-color-interactive-emphasis);
- }
.item-icon {
margin-bottom: auto;
margin-top: 5px;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
index f9218878e0..a1309314d4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts
@@ -6,6 +6,7 @@ export type UmbSearchResultItemModel = {
icon?: string | null;
name: string;
unique: string;
+ href: string;
};
export type UmbSearchRequestArgs = {
From 939e92ef74d7708419b47c65478d30c695ce30c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 11:02:45 +0200
Subject: [PATCH 042/323] update interface names for workspace modal
---
...lock-grid-area-type-workspace.modal-token.ts | 8 ++++----
.../block-grid-workspace.modal-token.ts | 6 +++---
.../block-list-workspace.modal-token.ts | 6 +++---
.../block-rte-workspace.modal-token.ts | 6 +++---
.../workspace/block-workspace.modal-token.ts | 8 ++++----
.../core/modal/token/workspace-modal.token.ts | 17 ++++++++++-------
.../data-type-workspace.modal-token.ts | 8 ++++----
7 files changed, 31 insertions(+), 28 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/block-grid-area-type-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/block-grid-area-type-workspace.modal-token.ts
index 7a2595a4e9..11e024c726 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/block-grid-area-type-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/block-grid-area-type-workspace.modal-token.ts
@@ -1,11 +1,11 @@
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
-export interface UmbBlockGridAreaTypeWorkspaceData extends UmbWorkspaceData {}
+export interface UmbBlockGridAreaTypeWorkspaceData extends UmbWorkspaceModalData {}
export const UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_MODAL = new UmbModalToken<
UmbBlockGridAreaTypeWorkspaceData,
- UmbWorkspaceValue
+ UmbWorkspaceModalValue
>('Umb.Modal.Workspace', {
modal: {
type: 'sidebar',
@@ -13,4 +13,4 @@ export const UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_MODAL = new UmbModalToken<
},
data: { entityType: 'block-grid-area-type', preset: {} },
// Recast the type, so the entityType data prop is not required:
-}) as UmbModalToken, UmbWorkspaceValue>;
+}) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/block-grid-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/block-grid-workspace.modal-token.ts
index 0a58a16654..bbe0f6b456 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/block-grid-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/block-grid-workspace.modal-token.ts
@@ -1,5 +1,5 @@
import type { UmbBlockWorkspaceData } from '@umbraco-cms/backoffice/block';
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
export interface UmbBlockGridWorkspaceData
@@ -9,7 +9,7 @@ export interface UmbBlockGridWorkspaceData
areaKey?: string;
}> {}
-export const UMB_BLOCK_GRID_WORKSPACE_MODAL = new UmbModalToken(
+export const UMB_BLOCK_GRID_WORKSPACE_MODAL = new UmbModalToken(
'Umb.Modal.Workspace',
{
modal: {
@@ -19,4 +19,4 @@ export const UMB_BLOCK_GRID_WORKSPACE_MODAL = new UmbModalToken, UmbWorkspaceValue>;
+) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/workspace/block-list-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/workspace/block-list-workspace.modal-token.ts
index 091954dbe9..e86a26f97d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/workspace/block-list-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/workspace/block-list-workspace.modal-token.ts
@@ -1,5 +1,5 @@
import type { UmbBlockWorkspaceData } from '@umbraco-cms/backoffice/block';
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
export interface UmbBlockListWorkspaceData
@@ -7,7 +7,7 @@ export interface UmbBlockListWorkspaceData
index: number;
}> {}
-export const UMB_BLOCK_LIST_WORKSPACE_MODAL = new UmbModalToken(
+export const UMB_BLOCK_LIST_WORKSPACE_MODAL = new UmbModalToken(
'Umb.Modal.Workspace',
{
modal: {
@@ -17,4 +17,4 @@ export const UMB_BLOCK_LIST_WORKSPACE_MODAL = new UmbModalToken, UmbWorkspaceValue>;
+) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/block-rte-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/block-rte-workspace.modal-token.ts
index cdeb480d58..da51f16a31 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/block-rte-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/block-rte-workspace.modal-token.ts
@@ -1,5 +1,5 @@
import type { UmbBlockWorkspaceData } from '@umbraco-cms/backoffice/block';
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
export interface UmbBlockRTEWorkspaceData
@@ -7,7 +7,7 @@ export interface UmbBlockRTEWorkspaceData
index: number;
}> {}
-export const UMB_BLOCK_RTE_WORKSPACE_MODAL = new UmbModalToken(
+export const UMB_BLOCK_RTE_WORKSPACE_MODAL = new UmbModalToken(
'Umb.Modal.Workspace',
{
modal: {
@@ -17,4 +17,4 @@ export const UMB_BLOCK_RTE_WORKSPACE_MODAL = new UmbModalToken, UmbWorkspaceValue>;
+) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.modal-token.ts
index 0a2d21ccc1..5bf06ad44f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.modal-token.ts
@@ -1,11 +1,11 @@
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
-export interface UmbBlockWorkspaceData extends UmbWorkspaceData {
+export interface UmbBlockWorkspaceData extends UmbWorkspaceModalData {
originData: OriginDataType;
}
-export const UMB_BLOCK_WORKSPACE_MODAL = new UmbModalToken(
+export const UMB_BLOCK_WORKSPACE_MODAL = new UmbModalToken(
'Umb.Modal.Workspace',
{
modal: {
@@ -15,4 +15,4 @@ export const UMB_BLOCK_WORKSPACE_MODAL = new UmbModalToken, UmbWorkspaceValue>;
+) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts
index 7806a971be..f5b7edf84c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts
@@ -1,19 +1,22 @@
import { UmbModalToken } from './modal-token.js';
-export interface UmbWorkspaceData {
+export interface UmbWorkspaceModalData {
entityType: string;
preset: Partial;
}
// TODO: It would be good with a WorkspaceValueBaseType, to avoid the hardcoded type for unique here:
-export type UmbWorkspaceValue =
+export type UmbWorkspaceModalValue =
| {
unique: string;
}
| undefined;
-export const UMB_WORKSPACE_MODAL = new UmbModalToken('Umb.Modal.Workspace', {
- modal: {
- type: 'sidebar',
- size: 'large',
+export const UMB_WORKSPACE_MODAL = new UmbModalToken(
+ 'Umb.Modal.Workspace',
+ {
+ modal: {
+ type: 'sidebar',
+ size: 'large',
+ },
},
-});
+);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.modal-token.ts
index d0c0d0652a..457a0f5ff4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.modal-token.ts
@@ -1,10 +1,10 @@
import type { UmbDataTypeDetailModel } from '../types.js';
-import type { UmbWorkspaceData, UmbWorkspaceValue } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
export const UMB_DATATYPE_WORKSPACE_MODAL = new UmbModalToken<
- UmbWorkspaceData,
- UmbWorkspaceValue
+ UmbWorkspaceModalData,
+ UmbWorkspaceModalValue
>('Umb.Modal.Workspace', {
modal: {
type: 'sidebar',
@@ -12,4 +12,4 @@ export const UMB_DATATYPE_WORKSPACE_MODAL = new UmbModalToken<
},
data: { entityType: 'data-type', preset: {} },
// Recast the type, so the entityType data prop is not required:
-}) as UmbModalToken, 'entityType'>, UmbWorkspaceValue>;
+}) as UmbModalToken, 'entityType'>, UmbWorkspaceModalValue>;
From 262f2ba2745fbb01b0041f4026aad56d85bd0a68 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:05:59 +0200
Subject: [PATCH 043/323] wait to refresh the state
---
.../src/apps/app/app-auth.controller.ts | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
index 29bbf70527..951965918b 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
@@ -91,7 +91,7 @@ export class UmbAppAuthController extends UmbControllerBase {
if (availableProviders.length === 1) {
// One provider available (most likely the Umbraco provider), so initiate the authorization request to the default provider
- this.#authContext.makeAuthorizationRequest(availableProviders[0].forProviderName);
+ await this.#authContext.makeAuthorizationRequest(availableProviders[0].forProviderName);
return this.#updateState();
}
@@ -103,7 +103,7 @@ export class UmbAppAuthController extends UmbControllerBase {
if (redirectProvider) {
// Redirect directly to the provider
- this.#authContext.makeAuthorizationRequest(redirectProvider.forProviderName);
+ await this.#authContext.makeAuthorizationRequest(redirectProvider.forProviderName);
return this.#updateState();
}
@@ -129,7 +129,7 @@ export class UmbAppAuthController extends UmbControllerBase {
const denyLocalLogin = availableProviders.some((provider) => provider.meta?.behavior?.denyLocalLogin);
if (denyLocalLogin) {
// Unregister the Umbraco provider
- umbExtensionsRegistry.unregister('Umb.AuthProviders.Umbraco');
+ umbExtensionsRegistry.exclude('Umb.AuthProviders.Umbraco');
}
// Show the provider selection screen
@@ -150,7 +150,7 @@ export class UmbAppAuthController extends UmbControllerBase {
.onSubmit()
.catch(() => undefined);
- if (!selected) {
+ if (!selected?.success) {
return false;
}
@@ -162,9 +162,6 @@ export class UmbAppAuthController extends UmbControllerBase {
throw new Error('[Fatal] Auth context is not available');
}
- // Reinitialize the auth flow (load the state from local storage)
- this.#authContext.setInitialState();
-
// The authorization flow is finished, so let the caller know if the user is authorized
return this.#authContext.getIsAuthorized();
}
From e10fb61c3a72866e451246a070e55881a1fc7bcb Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:09:03 +0200
Subject: [PATCH 044/323] add route for oauth_complete and complete the
authorization flow
---
.../src/apps/app/app.element.ts | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
index 50974b1f58..ad2c17af0b 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
@@ -59,13 +59,9 @@ export class UmbAppElement extends UmbLitElement {
},
{
path: 'oauth_complete',
- resolve: () => {
+ resolve: async () => {
// Complete oauth
- console.log('congrats you hit the oauth complete');
this.#authContext?.completeAuthorizationRequest();
-
- // Let the opener know that we are done
- window.opener?.postMessage('oauth_complete', '*');
},
},
{
@@ -172,15 +168,15 @@ export class UmbAppElement extends UmbLitElement {
}
#redirect() {
- // If there is a ?code parameter in the url, then we are in the middle of the oauth flow
- // and we need to complete the login (the authorization notifier will redirect after this is done
- // essentially hitting this method again)
+ /** If there is a ?code parameter in the url, then we are in the middle of the oauth flow
+ * and we need to complete the login (the authorization notifier will redirect after this is done
+ * essentially hitting this method again)
+ * @deprecated This is a legacy way of handling oauth flow, it should be removed once the backend starts sending the oauth_complete route
+ * TODO: Remove this when the backend sends the oauth_complete route
+ */
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has('code')) {
this.#authContext?.completeAuthorizationRequest();
-
- // Let the opener know that we are done
- window.opener?.postMessage('oauth_complete', '*');
return;
}
From 9002f3f74a5921e0d3b3ad49c3480cb7ebf3b122 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:27:53 +0200
Subject: [PATCH 045/323] wait for authorization requests before proceeding
---
src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
index 951965918b..293bc916ed 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
@@ -91,7 +91,7 @@ export class UmbAppAuthController extends UmbControllerBase {
if (availableProviders.length === 1) {
// One provider available (most likely the Umbraco provider), so initiate the authorization request to the default provider
- await this.#authContext.makeAuthorizationRequest(availableProviders[0].forProviderName);
+ await this.#authContext.makeAuthorizationRequest(availableProviders[0].forProviderName, true);
return this.#updateState();
}
@@ -103,7 +103,7 @@ export class UmbAppAuthController extends UmbControllerBase {
if (redirectProvider) {
// Redirect directly to the provider
- await this.#authContext.makeAuthorizationRequest(redirectProvider.forProviderName);
+ await this.#authContext.makeAuthorizationRequest(redirectProvider.forProviderName, true);
return this.#updateState();
}
From 289cbc2512f281ab27c240903f122ea713bb7d51 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:28:09 +0200
Subject: [PATCH 046/323] return the url to be able to make a choice
---
.../src/external/openid/redirect_based_handler.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/external/openid/redirect_based_handler.ts b/src/Umbraco.Web.UI.Client/src/external/openid/redirect_based_handler.ts
index 8344c28cf2..e9bb94a8a7 100644
--- a/src/Umbraco.Web.UI.Client/src/external/openid/redirect_based_handler.ts
+++ b/src/Umbraco.Web.UI.Client/src/external/openid/redirect_based_handler.ts
@@ -69,11 +69,11 @@ export class RedirectRequestHandler extends AuthorizationRequestHandler {
this.storageBackend.setItem(authorizationServiceConfigurationKey(handle), JSON.stringify(configuration.toJson())),
]);
- persisted.then(() => {
+ return persisted.then(() => {
// make the redirect request
const url = this.buildRequestUrl(configuration, request);
log('Making a request to ', request, url);
- this.locationLike.assign(url);
+ return url;
});
}
From 3294d8c98333c72ed78364071f54b96ef6d38b3b Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:28:25 +0200
Subject: [PATCH 047/323] wait for the authorization signal after submitting a
login
---
.../auth/modals/umb-app-auth-modal.element.ts | 65 ++++---------------
1 file changed, 11 insertions(+), 54 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
index 32df7c60e6..88d04d69d2 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
@@ -31,36 +31,15 @@ export class UmbAppAuthModalElement extends UmbModalBaseElement {
- this.#authContext = authContext;
-
- // Observe the auth redirects
- this.observe(
- authContext.authRedirect,
- (url) => {
- if (url) {
- this.#openWindow = window.open(url, '_blank');
- }
- },
- '_redirect',
- );
+ this.consumeContext(UMB_AUTH_CONTEXT, (context) => {
+ this.observe(context.authorizationSignal, () => {}, '_authorizationSignal');
});
}
- disconnectedCallback(): void {
- super.disconnectedCallback();
- window.removeEventListener('message', this.#onMessage);
- }
-
render() {
return html`
@@ -80,38 +59,16 @@ export class UmbAppAuthModalElement extends UmbModalBaseElement {
const authContext = await this.getContext(UMB_AUTH_CONTEXT);
- const redirect = authContext.makeAuthorizationRequest(providerName);
-
- this.observe(
- redirect,
- (url) => {
- if (url) {
- this.#openWindow = window.open(url, '_blank');
- }
- },
- '_redirect',
- );
- };
-
- async #onMessage(evt: MessageEvent) {
- if (evt.data === 'oauth_complete') {
- if (this.#openWindow) {
- this.#openWindow.close();
- }
-
- // Refresh the state
- await this.#authContext?.setInitialState();
-
- // Test if we are authorized
- const isAuthed = this.#authContext?.getIsAuthorized();
- this.value = { success: isAuthed };
- if (isAuthed) {
- this._submitModal();
- } else {
- this._error = 'Failed to authenticate';
- }
+ await authContext.makeAuthorizationRequest(providerName);
+ console.log('[AuthModal] Received authorization signal');
+ const isAuthed = authContext.getIsAuthorized();
+ this.value = { success: isAuthed };
+ if (isAuthed) {
+ this._submitModal();
+ } else {
+ this._error = 'Failed to authenticate';
}
- }
+ };
static styles = [
UmbTextStyles,
From 315e05b8555a08f8a984e30842c7eec187fd7d8b Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:29:07 +0200
Subject: [PATCH 048/323] add an authorization signal
---
.../src/packages/core/auth/auth-flow.ts | 50 ++++---------------
1 file changed, 9 insertions(+), 41 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
index e9be945df9..1b07218c91 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
@@ -13,8 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { UMB_STORAGE_REDIRECT_URL, UMB_STORAGE_TOKEN_RESPONSE_NAME } from './auth.context.token.js';
+import { UMB_STORAGE_TOKEN_RESPONSE_NAME } from './auth.context.token.js';
import type { LocationLike, StringMap } from '@umbraco-cms/backoffice/external/openid';
import {
BaseTokenRequestHandler,
@@ -31,7 +30,7 @@ import {
TokenRequest,
TokenResponse,
} from '@umbraco-cms/backoffice/external/openid';
-import { UmbStringState } from '@umbraco-cms/backoffice/observable-api';
+import { Subject } from '@umbraco-cms/backoffice/external/rxjs';
const requestor = new FetchRequestor();
@@ -44,22 +43,6 @@ class UmbNoHashQueryStringUtils extends BasicQueryStringUtils {
}
}
-class UmbLocationInterceptor implements LocationLike {
- public redirect = new UmbStringState(undefined);
- hash = '';
- host = '';
- origin = '';
- hostname = '';
- pathname = '';
- port = '';
- protocol = '';
- search = '';
-
- assign(url: string | URL): void {
- this.redirect.setValue(url.toString());
- }
-}
-
/**
* This class is used to handle the auth flow through any backend supporting OpenID Connect.
* It needs to know the server url, the client id, the redirect uri and the scope.
@@ -113,7 +96,8 @@ export class UmbAuthFlow {
// tokens
#tokenResponse?: TokenResponse;
- #locationInterceptor = new UmbLocationInterceptor();
+
+ authorizationSignal = new Subject();
constructor(
openIdConnectUrl: string,
@@ -137,11 +121,7 @@ export class UmbAuthFlow {
this.#notifier = new AuthorizationNotifier();
this.#tokenHandler = new BaseTokenRequestHandler(requestor);
this.#storageBackend = new LocalStorageBackend();
- this.#authorizationHandler = new RedirectRequestHandler(
- this.#storageBackend,
- new UmbNoHashQueryStringUtils(),
- this.#locationInterceptor,
- );
+ this.#authorizationHandler = new RedirectRequestHandler(this.#storageBackend, new UmbNoHashQueryStringUtils());
// set notifier to deliver responses
this.#authorizationHandler.setAuthorizationNotifier(this.#notifier);
@@ -150,6 +130,7 @@ export class UmbAuthFlow {
this.#notifier.setAuthorizationListener(async (request, response, error) => {
if (error) {
console.error('Authorization error', error);
+ this.authorizationSignal.next();
throw error;
}
@@ -162,21 +143,10 @@ export class UmbAuthFlow {
await this.#makeTokenRequest(response.code, codeVerifier);
await this.performWithFreshTokens();
await this.#saveTokenState();
-
- // Redirect to the saved state or root
- let currentRoute = '/';
- const savedRoute = sessionStorage.getItem(UMB_STORAGE_REDIRECT_URL);
- if (savedRoute) {
- sessionStorage.removeItem(UMB_STORAGE_REDIRECT_URL);
- currentRoute = savedRoute;
- }
- //history.replaceState(null, '', currentRoute);
}
- });
- }
- authRedirect() {
- return this.#locationInterceptor.redirect.asObservable();
+ this.authorizationSignal.next();
+ });
}
/**
@@ -246,9 +216,7 @@ export class UmbAuthFlow {
true,
);
- this.#authorizationHandler.performAuthorizationRequest(this.#configuration, request);
-
- return this.#locationInterceptor.redirect.asObservable();
+ return this.#authorizationHandler.performAuthorizationRequest(this.#configuration, request);
}
/**
From 094e5538f35aac875325981023ef155cc61b7706 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 12:29:31 +0200
Subject: [PATCH 049/323] listen for authorization signals before
re-initialising the token + open popup for login
---
.../src/packages/core/auth/auth.context.ts | 68 +++++++++++++++++--
1 file changed, 61 insertions(+), 7 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
index 12422b77f4..51fe39049b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
@@ -1,12 +1,12 @@
import type { UmbBackofficeExtensionRegistry, ManifestAuthProvider } from '../extension-registry/index.js';
import { UmbAuthFlow } from './auth-flow.js';
-import { UMB_AUTH_CONTEXT } from './auth.context.token.js';
+import { UMB_AUTH_CONTEXT, UMB_STORAGE_TOKEN_RESPONSE_NAME } from './auth.context.token.js';
import type { UmbOpenApiConfiguration } from './models/openApiConfiguration.js';
import { OpenAPI } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
-import { ReplaySubject, filter, switchMap } from '@umbraco-cms/backoffice/external/rxjs';
+import { ReplaySubject, filter, firstValueFrom, switchMap } from '@umbraco-cms/backoffice/external/rxjs';
export class UmbAuthContext extends UmbContextBase {
#isAuthorized = new UmbBooleanState(false);
@@ -15,8 +15,8 @@ export class UmbAuthContext extends UmbContextBase {
#isInitialized = new ReplaySubject(1);
readonly isInitialized = this.#isInitialized.asObservable().pipe(filter((isInitialized) => isInitialized));
- get authRedirect() {
- return this.#authFlow.authRedirect();
+ get authorizationSignal() {
+ return this.#authFlow.authorizationSignal;
}
#isBypassed = false;
@@ -24,6 +24,9 @@ export class UmbAuthContext extends UmbContextBase {
#backofficePath;
#authFlow;
+ #authWindowProxy?: WindowProxy | null;
+ #previousAuthUrl?: string;
+
constructor(host: UmbControllerHost, serverUrl: string, backofficePath: string, isBypassed: boolean) {
super(host, UMB_AUTH_CONTEXT);
this.#isBypassed = isBypassed;
@@ -31,6 +34,37 @@ export class UmbAuthContext extends UmbContextBase {
this.#backofficePath = backofficePath;
this.#authFlow = new UmbAuthFlow(serverUrl, this.getRedirectUrl(), this.getPostLogoutRedirectUrl());
+
+ // Observe the authorization signal and close the auth window
+ this.observe(
+ this.authorizationSignal,
+ () => {
+ // Update the authorization state
+ this.getIsAuthorized();
+ },
+ '_authFlowAuthorizationSignal',
+ );
+
+ // Observe changes to local storage and update the authorization state
+ // This establishes the tab-to-tab communication
+ window.addEventListener('storage', this.#onStorageEvent.bind(this));
+ }
+
+ destroy(): void {
+ super.destroy();
+ window.removeEventListener('storage', this.#onStorageEvent.bind(this));
+ }
+
+ async #onStorageEvent(evt: StorageEvent) {
+ console.log('[AuthContext] Storage event', evt);
+ if (evt.key === UMB_STORAGE_TOKEN_RESPONSE_NAME) {
+ // Close any open auth windows
+ this.#authWindowProxy?.close();
+ // Refresh the local storage state into memory
+ await this.setInitialState();
+ // Let any auth listeners (such as the auth modal) know that the auth state has changed
+ this.authorizationSignal.next();
+ }
}
/**
@@ -38,8 +72,28 @@ export class UmbAuthContext extends UmbContextBase {
* @param identityProvider The provider to use for login. Default is 'Umbraco'.
* @param usernameHint The username hint to use for login.
*/
- makeAuthorizationRequest(identityProvider = 'Umbraco', usernameHint?: string) {
- return this.#authFlow.makeAuthorizationRequest(identityProvider, usernameHint);
+ async makeAuthorizationRequest(identityProvider = 'Umbraco', redirect?: boolean, usernameHint?: string) {
+ const redirectUrl = await this.#authFlow.makeAuthorizationRequest(identityProvider, usernameHint);
+ if (redirect) {
+ location.href = redirectUrl;
+ return;
+ }
+
+ if (!this.#authWindowProxy || this.#authWindowProxy.closed) {
+ // TODO: Add popup behavior configuration to the authProvider's manifest
+ this.#authWindowProxy = window.open(
+ redirectUrl,
+ 'umbracoAuthPopup',
+ 'popup,width=600,height=600,menubar=no,location=no,resizable=yes,scrollbars=yes,status=no,toolbar=no',
+ );
+ } else if (this.#previousAuthUrl !== redirectUrl) {
+ this.#authWindowProxy = window.open(redirectUrl, 'umbracoAuthPopup');
+ this.#authWindowProxy?.focus();
+ }
+
+ this.#previousAuthUrl = redirectUrl;
+
+ return firstValueFrom(this.authorizationSignal);
}
/**
@@ -173,7 +227,7 @@ export class UmbAuthContext extends UmbContextBase {
}
getRedirectUrl() {
- return `${window.location.origin}${this.#backofficePath}`;
+ return `${window.location.origin}${this.#backofficePath}oauth_complete`;
}
getPostLogoutRedirectUrl() {
From acaa0685787c864fc80afacdad70a9bd1c075825 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 12:34:27 +0200
Subject: [PATCH 050/323] export entities
---
.../src/packages/documents/document-types/index.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
index 7dafabe4cf..508c015868 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
@@ -1,5 +1,6 @@
import './components/index.js';
+export * from './entity.js';
export * from './components/index.js';
export * from './workspace/index.js';
From 0326b87cfdf9bd60ca6626a6af17aaaf5a8e6897 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 12:38:17 +0200
Subject: [PATCH 051/323] tree picker create action button
---
...i-block-grid-type-configuration.element.ts | 20 ++++-
.../input-block-type.element.ts | 88 ++++++++++++-------
.../tree-picker/tree-picker-modal.element.ts | 29 ++++--
.../tree-picker/tree-picker-modal.token.ts | 5 +-
.../modals/workspace-modal.element.ts | 4 +-
5 files changed, 100 insertions(+), 46 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.ts
index 8129fb2739..b309c9ceae 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-type-configuration/property-editor-ui-block-grid-type-configuration.element.ts
@@ -19,7 +19,11 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_BLOCK_GRID_TYPE, type UmbBlockGridTypeGroupType } from '@umbraco-cms/backoffice/block-grid';
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
-import { UMB_PROPERTY_DATASET_CONTEXT, type UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
+import {
+ UMB_PROPERTY_CONTEXT,
+ UMB_PROPERTY_DATASET_CONTEXT,
+ type UmbPropertyDatasetContext,
+} from '@umbraco-cms/backoffice/property';
import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
@@ -70,6 +74,9 @@ export class UmbPropertyEditorUIBlockGridTypeConfigurationElement
this.#mapValuesToBlockGroups();
}
+ @state()
+ public _alias?: string;
+
@property({ type: Object, attribute: false })
public config?: UmbPropertyEditorConfigCollection;
@@ -86,8 +93,13 @@ export class UmbPropertyEditorUIBlockGridTypeConfigurationElement
constructor() {
super();
- this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (instance) => {
- this.#datasetContext = instance;
+
+ this.consumeContext(UMB_PROPERTY_CONTEXT, async (context) => {
+ this._alias = context.getAlias();
+ });
+
+ this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (context) => {
+ this.#datasetContext = context;
//this.#observeBlocks();
this.#observeBlockGroups();
});
@@ -203,6 +215,7 @@ export class UmbPropertyEditorUIBlockGridTypeConfigurationElement
return html`
${this._notGroupedBlockTypes
? html`
{
+ // TODO: Investigate if onEnd is called when a container move has been performed, if not then I would say it should be. [NL]
this.dispatchEvent(new CustomEvent('change', { detail: { moveComplete: true } }));
},
});
+ #elementPickerModal;
@property({ type: Array, attribute: false })
public set value(items) {
@@ -42,9 +44,20 @@ export class UmbInputBlockTypeElement<
return this._items;
}
+ @property({ type: String })
+ public set propertyAlias(value: string | undefined) {
+ this.#elementPickerModal.setUniquePathValue('propertyAlias', value);
+ }
+ public get propertyAlias(): string | undefined {
+ return undefined;
+ }
+
@property({ type: String })
workspacePath?: string;
+ @state()
+ private _pickerPath?: string;
+
@state()
private _items: Array = [];
@@ -60,31 +73,42 @@ export class UmbInputBlockTypeElement<
this.#filter = value as Array;
});
});
- }
- async create() {
- const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
+ this.#elementPickerModal = new UmbModalRouteRegistrationController(this, UMB_DOCUMENT_TYPE_PICKER_MODAL)
+ .addUniquePaths(['propertyAlias'])
+ .onSetup(() => {
+ return {
+ data: {
+ hideTreeRoot: true,
+ multiple: false,
+ createAction: {
+ entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
+ preset: { isElementType: true },
+ },
+ pickableFilter: (docType) =>
+ // Only pick elements:
+ docType.isElement &&
+ // Prevent picking the an already used element type:
+ this.#filter &&
+ this.#filter.find((x) => x.contentElementTypeKey === docType.unique) === undefined,
+ },
+ value: {
+ selection: [],
+ },
+ };
+ })
+ .onSubmit((value) => {
+ const selectedElementType = value.selection[0];
- // TODO: Make as mode for the Picker Modal, so the click to select immediately submits the modal(And in that mode we do not want to see a Submit button).
- const modalContext = modalManager.open(this, UMB_DOCUMENT_TYPE_PICKER_MODAL, {
- data: {
- hideTreeRoot: true,
- multiple: false,
- pickableFilter: (docType) =>
- // Only pick elements:
- docType.isElement &&
- // Prevent picking the an already used element type:
- this.#filter &&
- this.#filter.find((x) => x.contentElementTypeKey === docType.unique) === undefined,
- },
- });
-
- const modalValue = await modalContext?.onSubmit();
- const selectedElementType = modalValue.selection[0];
-
- if (selectedElementType) {
- this.dispatchEvent(new CustomEvent('create', { detail: { contentElementTypeKey: selectedElementType } }));
- }
+ if (selectedElementType) {
+ this.dispatchEvent(new CustomEvent('create', { detail: { contentElementTypeKey: selectedElementType } }));
+ }
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ const oldPath = this._pickerPath;
+ this._pickerPath = routeBuilder({});
+ this.requestUpdate('_pickerPath', oldPath);
+ });
}
deleteItem(contentElementTypeKey: string) {
@@ -131,12 +155,14 @@ export class UmbInputBlockTypeElement<
};
#renderButton() {
- return html`
- this.create()} label="open">
-
- Add
-
- `;
+ return this._pickerPath
+ ? html`
+
+
+ Add
+
+ `
+ : null;
}
static styles = [
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
index b093cde9da..47bf3661af 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
@@ -1,6 +1,6 @@
import type { UmbTreeSelectionConfiguration } from '../types.js';
import type { UmbTreePickerModalData, UmbTreePickerModalValue } from './tree-picker-modal.token.js';
-import { html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
+import { html, customElement, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit';
import {
UMB_WORKSPACE_MODAL,
UmbModalBaseElement,
@@ -21,9 +21,6 @@ export class UmbTreePickerModalElement {
- return { data: { entityType: 'document-type', preset: {} } };
+ .onSetup(async () => {
+ return { data: createActionData };
+ })
+ .onSubmit((value) => {
+ console.log('got', value);
+ //this.value = value;
+ //this.modalContext?.dispatchEvent(new UmbSelectedEvent());
})
.observeRouteBuilder((routeBuilder) => {
- this._createPath = routeBuilder({});
+ const oldPath = this._createPath;
+ this._createPath = routeBuilder({}) + 'create';
+ this.requestUpdate('_createPath', oldPath);
});
}
}
@@ -95,6 +100,12 @@ export class UmbTreePickerModalElement
+ ${this._createPath
+ ? html`
`
+ : nothing}
extends UmbPickerModalData {
treeAlias?: string;
+ // Consider if it makes sense to move this into the UmbPickerModalData interface, but for now this is a TreePicker feature. [NL]
+ createAction?: UmbTreePickerModalCreateActionData;
}
export interface UmbTreePickerModalValue extends UmbPickerModalValue {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/modals/workspace-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/modals/workspace-modal.element.ts
index 5a9722e24d..9d702fc1d8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/modals/workspace-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/modals/workspace-modal.element.ts
@@ -1,13 +1,13 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit';
import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
-import type { UmbWorkspaceData } from '@umbraco-cms/backoffice/modal';
+import type { UmbWorkspaceModalData } from '@umbraco-cms/backoffice/modal';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
@customElement('umb-workspace-modal')
export class UmbWorkspaceModalElement extends UmbLitElement {
@property({ attribute: false })
- data?: UmbWorkspaceData;
+ data?: UmbWorkspaceModalData;
/**
* TODO: Consider if this binding and events integration is the right for communicating back the modal handler. Or if we should go with some Context API. like a Modal Context API.
From 5c79268b6abde3a82cae6a4633e0c0583f766865 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 13:38:11 +0200
Subject: [PATCH 052/323] url-pattern-to-string function
---
...nerate-route-path-builder.function.test.ts | 16 +++++++-------
.../generate-route-path-builder.function.ts | 21 ++++---------------
.../src/packages/core/router/route.context.ts | 4 ++--
.../src/packages/core/utils/index.ts | 1 +
.../path/url-pattern-to-string.function.ts | 12 +++++++++++
.../workspace-is-new-redirect.controller.ts | 6 +++---
6 files changed, 30 insertions(+), 30 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
index f6de7d9f86..b768e4d582 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
@@ -1,41 +1,41 @@
import { expect } from '@open-wc/testing';
-import { createRoutePathBuilder } from './generate-route-path-builder.function.js';
+import { umbCreateRoutePathBuilder } from './generate-route-path-builder.function.js';
describe('createRoutePathBuilder', () => {
it('should return a function that builds a route path without parameters', () => {
- const buildPath = createRoutePathBuilder('test/path');
+ const buildPath = umbCreateRoutePathBuilder('test/path');
expect(buildPath(null)).to.eq('/test/path/');
});
it('should return a function that builds a route path with parameters', () => {
- const buildPath = createRoutePathBuilder(':param0/test/:param1/path/:param2');
+ const buildPath = umbCreateRoutePathBuilder(':param0/test/:param1/path/:param2');
expect(buildPath({ param0: 'value0', param1: 'value1', param2: 'value2' })).to.eq(
'/value0/test/value1/path/value2/',
);
});
it('should convert number parameters to strings', () => {
- const buildPath = createRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
expect(buildPath({ param1: 123, param2: 456 })).to.eq('/test/123/path/456/');
});
it('should not consider route segments that resembles parameters as parameters', () => {
- const buildPath = createRoutePathBuilder('test/uc:store/path');
+ const buildPath = umbCreateRoutePathBuilder('test/uc:store/path');
expect(buildPath({ someOtherParam: 'test' })).to.eq('/test/uc:store/path/');
});
it('should support multiple parameters with the same name', () => {
- const buildPath = createRoutePathBuilder('test/:param1/path/:param1');
+ const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param1');
expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/value1/');
});
it('should not consider parameters that are not in the params object', () => {
- const buildPath = createRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/:param2/');
});
it('should support complex objects as parameters with a custom toString method', () => {
- const buildPath = createRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
const obj = {
toString() {
return 'value1';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
index 115a6c3f91..181abf6abf 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
@@ -1,21 +1,8 @@
-/* eslint-disable */
+import { type UrlParametersRecord, umbUrlPatternToString } from '../utils/path/url-pattern-to-string.function.js';
import { stripSlash } from '@umbraco-cms/backoffice/external/router-slot'; // This must only include the util to avoid side effects of registering the route element.
-const PARAM_IDENTIFIER = /:([^\/]+)/g;
-
-export function createRoutePathBuilder(path: string) {
- return (params: { [key: string]: string | number | { toString: () => string } } | null) => {
- return (
- '/' +
- stripSlash(
- params
- ? path.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => {
- // Replace the parameter with the value from the params object or the parameter name if it doesn't exist (args[0] is the parameter name without the colon)
- return typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`;
- })
- : path,
- ) +
- '/'
- );
+export function umbCreateRoutePathBuilder(path: string) {
+ return (params: UrlParametersRecord | null) => {
+ return '/' + stripSlash(umbUrlPatternToString(path, params)) + '/';
};
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
index 47576a4e0b..ee860f7d6f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
@@ -1,5 +1,5 @@
import type { UmbRoute } from './route.interface.js';
-import { createRoutePathBuilder } from './generate-route-path-builder.function.js';
+import { umbCreateRoutePathBuilder } from './generate-route-path-builder.function.js';
import type { IRoutingInfo, IRouterSlot } from '@umbraco-cms/backoffice/external/router-slot';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -147,7 +147,7 @@ export class UmbRouteContext extends UmbContextBase {
: this.#routerActiveLocalPath + '/'
: '';
const localPath = routeBasePath + routeActiveLocalPath + modalRegistration.generateModalPath();
- const urlBuilder = createRoutePathBuilder(localPath);
+ const urlBuilder = umbCreateRoutePathBuilder(localPath);
modalRegistration._internal_setRouteBuilder(urlBuilder);
};
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
index ad688e29d5..8b243bcb6c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
@@ -9,6 +9,7 @@ export * from './path/path-decode.function.js';
export * from './path/path-encode.function.js';
export * from './path/path-folder-name.function.js';
export * from './path/umbraco-path.function.js';
+export * from './path/url-pattern-to-string.function.js';
export * from './selection-manager/selection.manager.js';
export * from './string/from-camel-case.function.js';
export * from './string/generate-umbraco-alias.function.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
new file mode 100644
index 0000000000..8686c8c193
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
@@ -0,0 +1,12 @@
+export type UrlParametersRecord = Record string }>;
+
+const PARAM_IDENTIFIER = /:([^/]+)/g;
+
+export function umbUrlPatternToString(pattern: string, params: UrlParametersRecord | null): string {
+ return params
+ ? pattern.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => {
+ // Replace the parameter with the value from the params object or the parameter name if it doesn't exist (args[0] is the parameter name without the colon)
+ return typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`;
+ })
+ : pattern;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts
index fa3434a304..daabfc3140 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/controllers/workspace-is-new-redirect.controller.ts
@@ -1,8 +1,8 @@
import type { UmbSubmittableWorkspaceContextBase } from '../contexts/index.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-import { createRoutePathBuilder, type UmbRouterSlotElement } from '@umbraco-cms/backoffice/router';
-import { ensurePathEndsWithSlash } from '@umbraco-cms/backoffice/utils';
+import type { UmbRouterSlotElement } from '@umbraco-cms/backoffice/router';
+import { ensurePathEndsWithSlash, umbUrlPatternToString } from '@umbraco-cms/backoffice/utils';
/**
* Observe the workspace context to see if the entity is new or not.
@@ -28,7 +28,7 @@ export class UmbWorkspaceIsNewRedirectController extends UmbControllerBase {
if (router && unique) {
const routerPath = router.absoluteRouterPath;
if (routerPath) {
- const newPath: string = createRoutePathBuilder(ensurePathEndsWithSlash(routerPath) + 'edit/:id')({
+ const newPath: string = umbUrlPatternToString(ensurePathEndsWithSlash(routerPath) + 'edit/:id', {
id: unique,
});
this.destroy();
From abf94a94d89c2338a75eec8cf39dfcb3934bdd88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Tue, 23 Apr 2024 13:38:22 +0200
Subject: [PATCH 053/323] document type paths
---
.../src/packages/documents/document-types/paths.ts | 2 ++
.../workspace/document-type-workspace.context.ts | 5 +++--
2 files changed, 5 insertions(+), 2 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
new file mode 100644
index 0000000000..1b3fb9a636
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
@@ -0,0 +1,2 @@
+export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH = 'create/:entityType/:parentUnique/:presetAlias';
+export const UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH = 'edit/:id';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
index 08b2610991..09781411a0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
@@ -1,6 +1,7 @@
import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbDocumentTypeDetailModel } from '../types.js';
+import { UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH } from '../paths.js';
import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js';
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
@@ -89,7 +90,7 @@ export class UmbDocumentTypeWorkspaceContext
this.routes.setRoutes([
{
- path: 'create/:entityType/:parentUnique/:presetAlias',
+ path: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH,
component: UmbDocumentTypeWorkspaceEditorElement,
setup: (_component, info) => {
const parentEntityType = info.match.params.entityType;
@@ -105,7 +106,7 @@ export class UmbDocumentTypeWorkspaceContext
},
},
{
- path: 'edit/:id',
+ path: UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH,
component: UmbDocumentTypeWorkspaceEditorElement,
setup: (_component, info) => {
this.removeUmbControllerByAlias('isNewRedirectController');
From 3da46f49ad11414352918df1e033e8682f9bdbe6 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 13:53:03 +0200
Subject: [PATCH 054/323] rework
---
.../search-modal/search-modal.element.ts | 149 +++++++++++++-----
1 file changed, 111 insertions(+), 38 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index a004e6c8a6..e3599c0d7c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -34,11 +34,7 @@ export class UmbSearchModalElement extends UmbLitElement {
@state()
_loading: boolean = false;
- @state()
- _searchItemNavIndex = 0;
-
- @state()
- _inputHasFocus = false;
+ #searchItemNavIndex = 0;
#inputTimer?: NodeJS.Timeout;
#inputTimerAmount = 300;
@@ -83,24 +79,80 @@ export class UmbSearchModalElement extends UmbLitElement {
}
#onKeydown(event: KeyboardEvent) {
- if (event.key !== 'Tab' && event.key !== 'Shift') {
- this.#focusInput();
+ const root = this.shadowRoot;
+ if (!root) return;
+
+ if (event.key === 'Tab') {
+ const isFirstProvider = (element: Element) => element === root.querySelector('.search-provider:first-child');
+ const isLastProvider = (element: Element) => element === root.querySelector('.search-provider:last-child');
+ const setActiveProviderFocus = (element?: Element | null) => (element as HTMLElement)?.focus();
+
+ const activeProvider = root.querySelector('.search-provider.active') as HTMLElement | null;
+
+ if (!activeProvider) return;
+
+ if (event.shiftKey) {
+ if (this.#providerHasFocus) {
+ if (this.#isFocusingFirstProvider) {
+ setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
+ event.preventDefault();
+ }
+ return;
+ }
+
+ if (isFirstProvider(activeProvider)) {
+ setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
+ event.preventDefault();
+ return;
+ }
+
+ setActiveProviderFocus(activeProvider);
+ } else {
+ if (this.#providerHasFocus) {
+ if (this.#isFocusingLastProvider) {
+ setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
+ event.preventDefault();
+ }
+ return;
+ }
+
+ if (isLastProvider(activeProvider)) {
+ setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
+ event.preventDefault();
+ return;
+ }
+
+ setActiveProviderFocus(activeProvider);
+ return;
+ }
}
- if (event.key === 'ArrowDown') {
- this.#setSearchItemNavIndex(Math.min(this._searchItemNavIndex + 1, this._searchResults.length - 1));
- }
- if (event.key === 'ArrowUp') {
- this.#setSearchItemNavIndex(Math.max(this._searchItemNavIndex - 1, 0));
+ switch (event.key) {
+ case 'Tab':
+ case 'Shift':
+ case 'Escape':
+ case 'Enter':
+ break;
+ case 'ArrowDown':
+ event.preventDefault();
+ this.#setSearchItemNavIndex(Math.min(this.#searchItemNavIndex + 1, this._searchResults.length - 1));
+ break;
+ case 'ArrowUp':
+ event.preventDefault();
+ this.#setSearchItemNavIndex(Math.max(this.#searchItemNavIndex - 1, 0));
+ break;
+ default:
+ if (this._input === root.activeElement) return;
+ this.#focusInput();
+ break;
}
}
async #setSearchItemNavIndex(index: number) {
- this._searchItemNavIndex = index;
await this.updateComplete;
- const element = this.shadowRoot?.querySelector(`a[data-item-index="${index}"]`) as HTMLElement | null;
- console.log('element', element, 'index', this._searchResults.length);
+ this.#searchItemNavIndex = index;
+ const element = this.shadowRoot?.querySelector(`a[data-item-index="${index}"]`) as HTMLElement | null;
if (!element) return;
if (!this._searchResults.length) return;
@@ -112,6 +164,21 @@ export class UmbSearchModalElement extends UmbLitElement {
this._input.focus();
}
+ get #providerHasFocus() {
+ const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
+ return Array.from(providerElements).some((element) => element === this.shadowRoot?.activeElement);
+ }
+
+ get #isFocusingLastProvider() {
+ const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
+ return providerElements[providerElements.length - 1] === this.shadowRoot?.activeElement;
+ }
+
+ get #isFocusingFirstProvider() {
+ const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
+ return providerElements[0] === this.shadowRoot?.activeElement;
+ }
+
#onSearchChange(event: InputEvent) {
const target = event.target as HTMLInputElement;
this._search = target.value.trim();
@@ -145,9 +212,9 @@ export class UmbSearchModalElement extends UmbLitElement {
} else {
this._searchResults = [];
}
- this.#setSearchItemNavIndex(0);
this._loading = false;
+ this.#searchItemNavIndex = -1;
}
render() {
@@ -182,6 +249,7 @@ export class UmbSearchModalElement extends UmbLitElement {
(searchProvider) => searchProvider,
(searchProvider) =>
html` this.#setCurrentProvider(searchProvider)}
@keydown=${() => ''}
class="search-provider ${this._currentProvider?.alias === searchProvider.alias ? 'active' : ''}">
@@ -201,7 +269,7 @@ export class UmbSearchModalElement extends UmbLitElement {
#renderResultItem(item: UmbSearchResultItemModel, index: number) {
return html`
-
+
Date: Tue, 23 Apr 2024 14:27:33 +0200
Subject: [PATCH 055/323] comments and cleanup
---
.../search/search-modal/search-modal.element.ts | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index e3599c0d7c..f012f47cd0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -91,7 +91,9 @@ export class UmbSearchModalElement extends UmbLitElement {
if (!activeProvider) return;
+ // When moving backwards in search providers
if (event.shiftKey) {
+ // If the FOCUS is on a provider, and it is the first in the list, we need to wrap around and focus the LAST one
if (this.#providerHasFocus) {
if (this.#isFocusingFirstProvider) {
setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
@@ -100,14 +102,19 @@ export class UmbSearchModalElement extends UmbLitElement {
return;
}
+ // If the currently ACTIVE provider is the first in the list, we need to wrap around and focus the LAST one
if (isFirstProvider(activeProvider)) {
setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
event.preventDefault();
return;
}
+ // We set the focus to current provider, and because we don't prevent the default tab behavior, the previous provider will be focused
setActiveProviderFocus(activeProvider);
- } else {
+ }
+ // When moving forwards in search providers
+ else {
+ // If the FOCUS is on a provider, and it is the last in the list, we need to wrap around and focus the FIRST one
if (this.#providerHasFocus) {
if (this.#isFocusingLastProvider) {
setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
@@ -116,14 +123,15 @@ export class UmbSearchModalElement extends UmbLitElement {
return;
}
+ // If the currently ACTIVE provider is the last in the list, we need to wrap around and focus the FIRST one
if (isLastProvider(activeProvider)) {
setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
event.preventDefault();
return;
}
+ // We set the focus to current provider, and because we don't prevent the default tab behavior, the next provider will be focused
setActiveProviderFocus(activeProvider);
- return;
}
}
From 9ff4227822506e6822139de5a629b4264b8c5613 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 14:32:39 +0200
Subject: [PATCH 056/323] cleanup
---
.../src/packages/search/search-modal/search-modal.element.ts | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index f012f47cd0..f99b14acc5 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -376,9 +376,6 @@ export class UmbSearchModalElement extends UmbLitElement {
outline-offset: -3px;
display: flex;
}
- .search-item.focused {
- outline: 2px solid var(--uui-color-focus);
- }
`,
];
}
From b2a7234248fdf6037d7e0b84bb961eae1a19d329 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 14:56:03 +0200
Subject: [PATCH 057/323] cleanup modal
---
.../core/auth/modals/umb-app-auth-modal.element.ts | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
index 88d04d69d2..5338fb397e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts
@@ -32,14 +32,6 @@ export class UmbAppAuthModalElement extends UmbModalBaseElement {
- this.observe(context.authorizationSignal, () => {}, '_authorizationSignal');
- });
- }
-
render() {
return html`
@@ -60,7 +52,7 @@ export class UmbAppAuthModalElement extends UmbModalBaseElement {
const authContext = await this.getContext(UMB_AUTH_CONTEXT);
await authContext.makeAuthorizationRequest(providerName);
- console.log('[AuthModal] Received authorization signal');
+
const isAuthed = authContext.getIsAuthorized();
this.value = { success: isAuthed };
if (isAuthed) {
From 1b4ca8dd68056820ed83e6d5e9a268356cdd232c Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 14:56:38 +0200
Subject: [PATCH 058/323] cleanup popup
---
.../src/packages/core/auth/auth.context.ts | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
index 51fe39049b..f6496a3382 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
@@ -79,15 +79,16 @@ export class UmbAuthContext extends UmbContextBase {
return;
}
+ const popupTarget = 'umbracoAuthPopup';
+
if (!this.#authWindowProxy || this.#authWindowProxy.closed) {
- // TODO: Add popup behavior configuration to the authProvider's manifest
this.#authWindowProxy = window.open(
redirectUrl,
- 'umbracoAuthPopup',
- 'popup,width=600,height=600,menubar=no,location=no,resizable=yes,scrollbars=yes,status=no,toolbar=no',
+ popupTarget,
+ 'width=600,height=600,menubar=no,location=no,resizable=yes,scrollbars=yes,status=no,toolbar=no',
);
} else if (this.#previousAuthUrl !== redirectUrl) {
- this.#authWindowProxy = window.open(redirectUrl, 'umbracoAuthPopup');
+ this.#authWindowProxy = window.open(redirectUrl, popupTarget);
this.#authWindowProxy?.focus();
}
From 9088ea1129a7681d02c0133fdd0861b1b4e7f993 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:00:18 +0200
Subject: [PATCH 059/323] let the logout page listen for authorized events and
redirect back to the frontpage in case an event occurs
---
.../src/apps/app/app.element.ts | 12 ++++++++++++
src/Umbraco.Web.UI.Client/src/external/rxjs/index.ts | 1 +
2 files changed, 13 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
index ad2c17af0b..0f258c022d 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts
@@ -17,6 +17,7 @@ import {
UmbAppEntryPointExtensionInitializer,
umbExtensionsRegistry,
} from '@umbraco-cms/backoffice/extension-registry';
+import { filter, first } from '@umbraco-cms/backoffice/external/rxjs';
@customElement('umb-app')
export class UmbAppElement extends UmbLitElement {
@@ -74,6 +75,17 @@ export class UmbAppElement extends UmbLitElement {
resolve: () => {
this.#authContext?.clearTokenStorage();
this.#authController.makeAuthorizationRequest('loggedOut');
+
+ // Listen for the user to be authorized
+ this.#authContext?.isAuthorized
+ .pipe(
+ filter((x) => !!x),
+ first(),
+ )
+ .subscribe(() => {
+ // Redirect to the root
+ history.replaceState(null, '', '');
+ });
},
},
{
diff --git a/src/Umbraco.Web.UI.Client/src/external/rxjs/index.ts b/src/Umbraco.Web.UI.Client/src/external/rxjs/index.ts
index cc5b1fcd73..24fa9d1a5a 100644
--- a/src/Umbraco.Web.UI.Client/src/external/rxjs/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/external/rxjs/index.ts
@@ -18,4 +18,5 @@ export {
filter,
startWith,
skip,
+ first,
} from 'rxjs';
From 6d9684f5252b223abef11b4b710b75c620bc2762 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:11:23 +0200
Subject: [PATCH 060/323] init fake cursor
---
.../search-modal/search-modal.element.ts | 44 ++++++++++++++++---
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index f99b14acc5..726a953249 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -16,6 +16,8 @@ type SearchProvider = {
@customElement('umb-search-modal')
export class UmbSearchModalElement extends UmbLitElement {
+ @query('#input-wrapper-fake-cursor')
+ private _inputFakeCursor!: HTMLElement;
@query('input')
private _input!: HTMLInputElement;
@@ -202,6 +204,17 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#inputTimer = setTimeout(() => this.#updateSearchResults(), this.#inputTimerAmount);
}
+ async #setShowFakeCursor(show: boolean) {
+ if (show) {
+ await new Promise((resolve) => requestAnimationFrame(resolve));
+ const getTextBeforeCursor = this._search.substring(0, this._input.selectionStart ?? 0);
+ this._inputFakeCursor.textContent = getTextBeforeCursor;
+ this._inputFakeCursor.style.display = 'block';
+ } else {
+ this._inputFakeCursor.style.display = 'none';
+ }
+ }
+
#setCurrentProvider(searchProvider: SearchProvider) {
if (this._currentProvider === searchProvider) return;
@@ -229,12 +242,17 @@ export class UmbSearchModalElement extends UmbLitElement {
return html`
${this.#renderSearchTags()}
@@ -347,6 +365,20 @@ export class UmbSearchModalElement extends UmbLitElement {
height: 100%;
width: 100%;
}
+ #input-wrapper {
+ width: 100%;
+ position: relative;
+ }
+ #input-wrapper-fake-cursor {
+ position: absolute;
+ left: 0;
+ border-right: 1px solid hotpink;
+ height: 1.2rem;
+ color: transparent;
+ user-select: none;
+ pointer-events: none;
+ bottom: 14px;
+ }
button {
font-family: unset;
font-size: unset;
From 5fb669fa35582b914d90883e1d994f00eba84933 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:17:14 +0200
Subject: [PATCH 061/323] fake cursor animation
---
.../search/search-modal/search-modal.element.ts | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 726a953249..cfaa529744 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -372,12 +372,23 @@ export class UmbSearchModalElement extends UmbLitElement {
#input-wrapper-fake-cursor {
position: absolute;
left: 0;
- border-right: 1px solid hotpink;
+ border-right: 1px solid var(--uui-color-text);
height: 1.2rem;
color: transparent;
user-select: none;
pointer-events: none;
bottom: 14px;
+ animation: blink-animation 1s infinite;
+ }
+ @keyframes blink-animation {
+ 0%,
+ 50% {
+ border-color: var(--uui-color-text);
+ }
+ 51%,
+ 100% {
+ border-color: transparent;
+ }
}
button {
font-family: unset;
From d912f27f2e423a4c26c7aa8cccdbae83da5bb931 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:30:32 +0200
Subject: [PATCH 062/323] show item index status
---
.../search/search-modal/search-modal.element.ts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index cfaa529744..c462a0b08f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -161,8 +161,15 @@ export class UmbSearchModalElement extends UmbLitElement {
async #setSearchItemNavIndex(index: number) {
await this.updateComplete;
+ const prevElement = this.shadowRoot?.querySelector(
+ `a[data-item-index="${this.#searchItemNavIndex}"]`,
+ ) as HTMLElement | null;
+ prevElement?.classList.remove('active');
+
this.#searchItemNavIndex = index;
+
const element = this.shadowRoot?.querySelector(`a[data-item-index="${index}"]`) as HTMLElement | null;
+ element?.classList.add('active');
if (!element) return;
if (!this._searchResults.length) return;
@@ -419,6 +426,11 @@ export class UmbSearchModalElement extends UmbLitElement {
outline-offset: -3px;
display: flex;
}
+ .search-item.active:not(:focus-within) {
+ outline: 2px solid var(--uui-color-border);
+ border-radius: 6px;
+ outline-offset: -4px;
+ }
`,
];
}
From 743ca6be04fd11ab64f507ddb06ac34a474086b3 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:37:31 +0200
Subject: [PATCH 063/323] resolve to let the flow go through, but will of
course fail because the token is invalid
---
.../src/packages/core/auth/auth-flow.ts | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
index 1b07218c91..58f547d8a8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts
@@ -304,10 +304,9 @@ export class UmbAuthFlow {
return Promise.resolve(this.#tokenResponse.accessToken);
}
- // if the refresh token is not set (maybe the provider doesn't support them), sign out
+ // if the refresh token is not set (maybe the provider doesn't support them)
if (!this.#tokenResponse?.refreshToken) {
- this.signOut();
- return Promise.reject('Missing refreshToken.');
+ return Promise.resolve('Missing refreshToken.');
}
const request = new TokenRequest({
From bc6b6f2e99944b366a5e9601d4843e3a0b353d76 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:37:44 +0200
Subject: [PATCH 064/323] remove stored url
---
.../src/apps/app/app-auth.controller.ts | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
index 293bc916ed..462e05ef6b 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
@@ -1,9 +1,4 @@
-import {
- UMB_AUTH_CONTEXT,
- UMB_MODAL_APP_AUTH,
- UMB_STORAGE_REDIRECT_URL,
- type UmbUserLoginState,
-} from '@umbraco-cms/backoffice/auth';
+import { UMB_AUTH_CONTEXT, UMB_MODAL_APP_AUTH, type UmbUserLoginState } from '@umbraco-cms/backoffice/auth';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { filter, firstValueFrom, skip } from '@umbraco-cms/backoffice/external/rxjs';
@@ -66,11 +61,6 @@ export class UmbAppAuthController extends UmbControllerBase {
throw new Error('[Fatal] Auth context is not available');
}
- // Save location.href so we can redirect to it after login
- if (location.href !== this.#authContext.getPostLogoutRedirectUrl()) {
- window.sessionStorage.setItem(UMB_STORAGE_REDIRECT_URL, location.href);
- }
-
// Figure out which providers are available
const availableProviders = await firstValueFrom(this.#authContext.getAuthProviders(umbExtensionsRegistry));
From 766fa0787add2e7a8f96a3f1e28fab5f079a79d0 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:39:58 +0200
Subject: [PATCH 065/323] better focus visibility on active provider
---
.../src/packages/search/search-modal/search-modal.element.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index c462a0b08f..b3b01ec9ca 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -367,6 +367,10 @@ export class UmbSearchModalElement extends UmbLitElement {
color: var(--uui-color-selected-contrast);
border-color: transparent;
}
+ .search-provider.active:focus {
+ outline-offset: -4px;
+ outline-color: var(--uui-color-focus);
+ }
input {
all: unset;
height: 100%;
From e17a220d27f0be4fc9b3ea7ea3fc37923e2066f7 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:46:50 +0200
Subject: [PATCH 066/323] update weights
---
.../src/packages/data-type/search/manifests.ts | 2 +-
.../src/packages/documents/documents/search/manifests.ts | 2 +-
.../src/packages/media/media-types/search/manifests.ts | 2 +-
.../src/packages/media/media/search/manifests.ts | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
index 594fd1be5a..248c1d2ccf 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.DataType',
type: 'searchProvider',
api: () => import('./data-type.search-provider.js'),
- weight: 800,
+ weight: 400,
meta: {
label: 'Data Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
index 11b13dc5c0..cdc2e2e024 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Document',
type: 'searchProvider',
api: () => import('./document.search-provider.js'),
- weight: 700,
+ weight: 800,
meta: {
label: 'Documents',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
index 973b2e6cc3..b077dfb5be 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.MediaType',
type: 'searchProvider',
api: () => import('./media-type.search-provider.js'),
- weight: 400,
+ weight: 500,
meta: {
label: 'Media Types',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
index 29749ffc80..6da2255c34 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/manifests.ts
@@ -7,7 +7,7 @@ export const manifests: Array = [
alias: 'Umb.SearchProvider.Media',
type: 'searchProvider',
api: () => import('./media.search-provider.js'),
- weight: 500,
+ weight: 700,
meta: {
label: 'Media',
},
From b6a623922fefa703e8a62d73aa52e7b62bada327 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:50:24 +0200
Subject: [PATCH 067/323] destroy the auth modal if repeated events occur
---
.../src/apps/app/app-auth.controller.ts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
index 462e05ef6b..197c6b12be 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
@@ -123,15 +123,17 @@ export class UmbAppAuthController extends UmbControllerBase {
}
// Show the provider selection screen
+ const authModalKey = 'umbAuthModal';
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
- modalManager.remove('umbAuthModal');
+ modalManager.close(authModalKey);
+ modalManager.remove(authModalKey);
const selected = await modalManager
.open(this._host, UMB_MODAL_APP_AUTH, {
data: {
userLoginState,
},
modal: {
- key: 'umbAuthModal',
+ key: authModalKey,
backdropBackground: this.#firstTimeLoggingIn
? 'var(--umb-auth-backdrop, url("/umbraco/backoffice/assets/umbraco_logo_white.svg") 20px 20px / 200px no-repeat, radial-gradient(circle, rgba(2,0,36,1) 0%, rgba(40,58,151,.9) 50%, rgba(0,212,255,1) 100%))'
: 'var(--umb-auth-backdrop-timedout, rgba(0,0,0,0.75))',
From af91f95f1c00ac39bf2e263ac010d13cd94807a5 Mon Sep 17 00:00:00 2001
From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Date: Tue, 23 Apr 2024 15:54:09 +0200
Subject: [PATCH 068/323] use a timeout subject to consistently open the auth
modal
---
.../src/apps/app/app-auth.controller.ts | 10 ++--------
.../src/packages/core/auth/auth.context.ts | 7 ++++++-
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
index 197c6b12be..982824f5c2 100644
--- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts
@@ -18,12 +18,7 @@ export class UmbAppAuthController extends UmbControllerBase {
// Observe the user's authorization state and start the authorization flow if the user is not authorized
this.observe(
- context.isAuthorized.pipe(
- // Skip the first since it is always false
- skip(1),
- // Only continue if the value is false
- filter((x) => !x),
- ),
+ context.isTimeout,
() => {
this.#firstTimeLoggingIn = false;
this.makeAuthorizationRequest('timedOut');
@@ -125,8 +120,7 @@ export class UmbAppAuthController extends UmbControllerBase {
// Show the provider selection screen
const authModalKey = 'umbAuthModal';
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
- modalManager.close(authModalKey);
- modalManager.remove(authModalKey);
+
const selected = await modalManager
.open(this._host, UMB_MODAL_APP_AUTH, {
data: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
index f6496a3382..e366d31955 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts
@@ -6,12 +6,16 @@ import { OpenAPI } from '@umbraco-cms/backoffice/external/backend-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
-import { ReplaySubject, filter, firstValueFrom, switchMap } from '@umbraco-cms/backoffice/external/rxjs';
+import { ReplaySubject, Subject, filter, firstValueFrom, switchMap } from '@umbraco-cms/backoffice/external/rxjs';
export class UmbAuthContext extends UmbContextBase {
#isAuthorized = new UmbBooleanState(false);
readonly isAuthorized = this.#isAuthorized.asObservable();
+ // Timeout is different from `isAuthorized` because it can occur repeatedly
+ #isTimeout = new Subject();
+ readonly isTimeout = this.#isTimeout.asObservable();
+
#isInitialized = new ReplaySubject(1);
readonly isInitialized = this.#isInitialized.asObservable().pipe(filter((isInitialized) => isInitialized));
@@ -162,6 +166,7 @@ export class UmbAuthContext extends UmbContextBase {
timeOut() {
this.clearTokenStorage();
this.#isAuthorized.setValue(false);
+ this.#isTimeout.next();
}
/**
From 42c62a05a297af10f357b4475caa7b43963e8349 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 15:49:48 +0200
Subject: [PATCH 069/323] path consts and types for document type workspace
---
.../input-block-type.element.ts | 18 ++++++++++++---
.../tree-picker/tree-picker-modal.element.ts | 20 +++++++++-------
.../tree-picker/tree-picker-modal.token.ts | 16 ++++++++++---
.../path/url-pattern-to-string.function.ts | 7 +++---
.../documents/document-types/entity.ts | 5 ++++
.../documents/document-types/index.ts | 9 ++++----
.../document-type-picker-modal.token.ts | 18 +++++++++++++--
.../documents/document-types/paths.ts | 23 +++++++++++++++++++
.../document-type-workspace.context.ts | 12 +++++++---
.../document-type-workspace.modal-token.ts | 13 +++++++++++
.../document-types/workspace/index.ts | 1 +
11 files changed, 115 insertions(+), 27 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
index 67d33fb3d9..2e5ca4ecda 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
@@ -7,7 +7,11 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
import { UmbDeleteEvent } from '@umbraco-cms/backoffice/event';
-import { UMB_DOCUMENT_TYPE_PICKER_MODAL, UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/document-type';
+import {
+ UMB_DOCUMENT_TYPE_PICKER_MODAL,
+ UMB_DOCUMENT_TYPE_ENTITY_TYPE,
+ umbCreateDocumentTypeWorkspacePathGenerator,
+} from '@umbraco-cms/backoffice/document-type';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
/** TODO: Look into sending a "change" event when there is a change, rather than create, delete, and change event. Make sure it doesn't break move for RTE/List/Grid. [LI] */
@@ -82,8 +86,16 @@ export class UmbInputBlockTypeElement<
hideTreeRoot: true,
multiple: false,
createAction: {
- entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
- preset: { isElementType: true },
+ modalData: {
+ entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
+ preset: { isElementType: true },
+ },
+ additionalPathGenerator: umbCreateDocumentTypeWorkspacePathGenerator,
+ additionalPathParams: {
+ entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
+ parentUnique: null,
+ presetAlias: 'element',
+ },
},
pickableFilter: (docType) =>
// Only pick elements:
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
index 47bf3661af..41220920d7 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
@@ -45,20 +45,24 @@ export class UmbTreePickerModalElement {
- return { data: createActionData };
+ new UmbModalRouteRegistrationController(
+ this,
+ (createActionData.modalToken as typeof UMB_WORKSPACE_MODAL) ?? UMB_WORKSPACE_MODAL,
+ )
+ .onSetup(() => {
+ return { data: createActionData.modalData };
})
.onSubmit((value) => {
- console.log('got', value);
- //this.value = value;
- //this.modalContext?.dispatchEvent(new UmbSelectedEvent());
+ if (value) {
+ this.value = { selection: [value.unique] };
+ this._submitModal();
+ }
})
.observeRouteBuilder((routeBuilder) => {
const oldPath = this._createPath;
- this._createPath = routeBuilder({}) + 'create';
+ this._createPath =
+ routeBuilder({}) + createActionData.additionalPathGenerator(createActionData.additionalPathParams);
this.requestUpdate('_createPath', oldPath);
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
index 2e656d804c..a6ab0af664 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
@@ -2,11 +2,21 @@ import { UMB_TREE_PICKER_MODAL_ALIAS } from './constants.js';
import type { UmbPickerModalData, UmbPickerModalValue, UmbWorkspaceModalData } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
-export interface UmbTreePickerModalCreateActionData extends UmbWorkspaceModalData {}
-export interface UmbTreePickerModalData extends UmbPickerModalData {
+export type UmbPathGeneratorType = (params: any) => string;
+export interface UmbTreePickerModalCreateActionData {
+ modalData: UmbWorkspaceModalData;
+ modalToken?: UmbModalToken;
+ additionalPathGenerator: PathGeneratorType;
+ additionalPathParams: Parameters[0];
+}
+
+export interface UmbTreePickerModalData<
+ TreeItemType = any,
+ PathGeneratorType extends UmbPathGeneratorType = UmbPathGeneratorType,
+> extends UmbPickerModalData {
treeAlias?: string;
// Consider if it makes sense to move this into the UmbPickerModalData interface, but for now this is a TreePicker feature. [NL]
- createAction?: UmbTreePickerModalCreateActionData;
+ createAction?: UmbTreePickerModalCreateActionData;
}
export interface UmbTreePickerModalValue extends UmbPickerModalValue {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
index 8686c8c193..e927e3cf15 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
@@ -1,12 +1,13 @@
-export type UrlParametersRecord = Record string }>;
+export type UrlParametersRecord = Record string } | null>;
const PARAM_IDENTIFIER = /:([^/]+)/g;
export function umbUrlPatternToString(pattern: string, params: UrlParametersRecord | null): string {
return params
? pattern.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => {
- // Replace the parameter with the value from the params object or the parameter name if it doesn't exist (args[0] is the parameter name without the colon)
- return typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`;
+ const segmentName = args[0]; // (segmentName is the parameter name without the colon)
+ // Replace the path-segment with the value from the params object or 'null' if it doesn't exist
+ return params![segmentName]?.toString() ?? 'null';
})
: pattern;
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity.ts
index c19555dccf..7279881dac 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity.ts
@@ -5,3 +5,8 @@ export const UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE = 'document-type-folder';
export type UmbDocumentTypeEntityType = typeof UMB_DOCUMENT_TYPE_ENTITY_TYPE;
export type UmbDocumentTypeRootEntityType = typeof UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE;
export type UmbDocumentTypeFolderEntityType = typeof UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE;
+
+export type UmbDocumentTypeEntityTypeUnion =
+ | UmbDocumentTypeEntityType
+ | UmbDocumentTypeRootEntityType
+ | UmbDocumentTypeFolderEntityType;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
index 508c015868..058bd6dbfe 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/index.ts
@@ -1,11 +1,10 @@
import './components/index.js';
-export * from './entity.js';
export * from './components/index.js';
-export * from './workspace/index.js';
-
+export * from './entity.js';
+export * from './modals/index.js';
+export * from './paths.js';
export * from './repository/index.js';
export * from './tree/types.js';
export * from './types.js';
-
-export * from './modals/index.js';
+export * from './workspace/index.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
index b9ff521986..8fc9713972 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
@@ -1,3 +1,4 @@
+import { umbCreateDocumentTypeWorkspacePathGenerator } from '../paths.js';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
import type { UmbDocumentTypeTreeItemModel } from '@umbraco-cms/backoffice/document-type';
import {
@@ -6,8 +7,9 @@ import {
UMB_TREE_PICKER_MODAL_ALIAS,
} from '@umbraco-cms/backoffice/tree';
-export type UmbDocumentTypePickerModalData = UmbTreePickerModalData;
-export type UmbDocumentTypePickerModalValue = UmbTreePickerModalValue;
+export interface UmbDocumentTypePickerModalData
+ extends UmbTreePickerModalData {}
+export interface UmbDocumentTypePickerModalValue extends UmbTreePickerModalValue {}
export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
UmbDocumentTypePickerModalData,
@@ -19,5 +21,17 @@ export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
},
data: {
treeAlias: 'Umb.Tree.DocumentType',
+ createAction: {
+ modalData: {
+ entityType: 'documentType',
+ preset: {},
+ },
+ additionalPathGenerator: umbCreateDocumentTypeWorkspacePathGenerator,
+ additionalPathParams: {
+ entityType: 'documentType',
+ parentUnique: '',
+ presetAlias: '',
+ },
+ },
},
});
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
index 1b3fb9a636..93b117acb3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
@@ -1,2 +1,25 @@
+import type { UmbDocumentTypeEntityTypeUnion } from './entity.js';
+import { umbUrlPatternToString } from '@umbraco-cms/backoffice/utils';
+
+export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE = 'template';
+export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT = 'element';
+
+export type UmbCreateDocumentTypeWorkspacePresetTemplateType =
+ typeof UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE;
+export type UmbCreateDocumentTypeWorkspacePresetElementType = // line break thanks!
+ typeof UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT;
+
+export type UmbCreateDocumentTypeWorkspacePresetType =
+ | UmbCreateDocumentTypeWorkspacePresetTemplateType
+ | UmbCreateDocumentTypeWorkspacePresetElementType;
+
export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH = 'create/:entityType/:parentUnique/:presetAlias';
+export const umbCreateDocumentTypeWorkspacePathGenerator = (params: {
+ entityType: UmbDocumentTypeEntityTypeUnion;
+ parentUnique?: string | null;
+ presetAlias?: UmbCreateDocumentTypeWorkspacePresetType | null;
+}) => umbUrlPatternToString(UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, params);
+
export const UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH = 'edit/:id';
+export const umbEditDocumentTypeWorkspacePathGenerator = (params: { id: string }) =>
+ umbUrlPatternToString(UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, params);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
index 09781411a0..b5194e7080 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
@@ -1,7 +1,13 @@
import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js';
import type { UmbDocumentTypeDetailModel } from '../types.js';
-import { UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH } from '../paths.js';
+import {
+ UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH,
+ UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT,
+ UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE,
+ UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH,
+ type UmbCreateDocumentTypeWorkspacePresetType,
+} from '../paths.js';
import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js';
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
@@ -199,12 +205,12 @@ export class UmbDocumentTypeWorkspaceContext
if (!data) return undefined;
switch (presetAlias) {
- case 'template': {
+ case UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE satisfies UmbCreateDocumentTypeWorkspacePresetType: {
this.setIcon('icon-notepad');
this.createTemplateMode = true;
break;
}
- case 'element': {
+ case UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT satisfies UmbCreateDocumentTypeWorkspacePresetType: {
this.setIcon('icon-plugin');
this.setIsElement(true);
break;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts
new file mode 100644
index 0000000000..7d26329ecc
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts
@@ -0,0 +1,13 @@
+import type { UmbWorkspaceModalData, UmbWorkspaceModalValue } from '@umbraco-cms/backoffice/modal';
+import { UMB_WORKSPACE_MODAL, UmbModalToken } from '@umbraco-cms/backoffice/modal';
+
+export interface UmbDocumentTypeWorkspaceData extends UmbWorkspaceModalData {}
+
+export const UMB_DOCUMENT_TYPE_WORKSPACE_MODAL = new UmbModalToken<
+ UmbDocumentTypeWorkspaceData,
+ UmbWorkspaceModalValue
+>('Umb.Modal.Workspace', {
+ modal: UMB_WORKSPACE_MODAL.getDefaultModal(),
+ data: { entityType: 'block', preset: {} },
+ // Recast the type, so the entityType data prop is not required:
+}) as UmbModalToken, UmbWorkspaceModalValue>;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/index.ts
index b5c792e5ef..cf7ab5393f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/index.ts
@@ -1 +1,2 @@
export * from './document-type-workspace.context-token.js';
+export * from './document-type-workspace.modal-token.js';
From cdf17707e6ede95ccf15eef020219e0584672703 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 18:51:43 +0200
Subject: [PATCH 070/323] add document href
---
.../documents/search/document-search.server.data-source.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
index d9c71ab51a..46c99963cc 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
@@ -38,6 +38,7 @@ export class UmbDocumentSearchServerDataSource {
if (data) {
const mappedItems = data.items.map((item) => {
return {
+ href: '/section/content/workspace/document/edit/' + item.id,
entityType: UMB_DOCUMENT_ENTITY_TYPE,
unique: item.id,
isTrashed: item.isTrashed,
From 2f79ac82d36c50ec0192489e6dc4b3fca85c5797 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 18:52:03 +0200
Subject: [PATCH 071/323] close modal and styling
---
.../document-search-result-item.element.ts | 2 +-
.../search-modal/search-modal.element.ts | 32 +++++++++++++++++--
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
index dec3375b56..ad021f5241 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
@@ -1,5 +1,5 @@
-import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import type { UmbDocumentItemModel, UmbDocumentItemVariantModel } from '../repository/item/types.js';
+import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index b3b01ec9ca..71adab12b8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -1,12 +1,22 @@
import type { UmbSearchProvider, UmbSearchResultItemModel } from '../types.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
-import { css, html, nothing, repeat, customElement, query, state } from '@umbraco-cms/backoffice/external/lit';
+import {
+ css,
+ html,
+ nothing,
+ repeat,
+ customElement,
+ query,
+ state,
+ property,
+} from '@umbraco-cms/backoffice/external/lit';
import type { ManifestSearchResultItem } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbExtensionsManifestInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
import '../search-result/search-result-item.element.js';
+import type { UmbModalContext } from '@umbraco-cms/backoffice/modal';
type SearchProvider = {
name: string;
@@ -21,6 +31,9 @@ export class UmbSearchModalElement extends UmbLitElement {
@query('input')
private _input!: HTMLInputElement;
+ @property({ attribute: false })
+ modalContext?: UmbModalContext;
+
@state()
private _search = '';
@@ -302,7 +315,12 @@ export class UmbSearchModalElement extends UmbLitElement {
#renderResultItem(item: UmbSearchResultItemModel, index: number) {
return html`
-
+
${this.localize.term('general_searchNoResult')} `;
}
+ #closeModal(event: MouseEvent | KeyboardEvent) {
+ if (event instanceof KeyboardEvent && event.key !== 'Enter') return;
+ this.modalContext?.reject();
+ }
+
static styles = [
UmbTextStyles,
css`
@@ -430,6 +453,11 @@ export class UmbSearchModalElement extends UmbLitElement {
outline-offset: -3px;
display: flex;
}
+ .search-item:focus {
+ outline: 2px solid var(--uui-color-interactive-emphasis);
+ border-radius: 6px;
+ outline-offset: -4px;
+ }
.search-item.active:not(:focus-within) {
outline: 2px solid var(--uui-color-border);
border-radius: 6px;
From b4c7b6b8132b7d58ea2b4008d4236fd0d751ea52 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 18:56:05 +0200
Subject: [PATCH 072/323] responsive
---
.../src/packages/search/search-modal/search-modal.element.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 71adab12b8..ed2566b54f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -346,7 +346,8 @@ export class UmbSearchModalElement extends UmbLitElement {
display: flex;
flex-direction: column;
width: min(610px, 100vw);
- height: 80dvh;
+ height: max(600px, 80dvh);
+ max-height: 100dvh;
background-color: var(--uui-color-surface);
box-sizing: border-box;
color: var(--uui-color-text);
@@ -363,6 +364,7 @@ export class UmbSearchModalElement extends UmbLitElement {
display: flex;
flex-direction: column;
height: 100%;
+ overflow: auto;
}
#search-providers {
display: flex;
From 3dfba7e3913cdc91ed6a74a7d5dd2355a09be681 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:08:04 +0200
Subject: [PATCH 073/323] document types
---
.../documents/search/document-search.repository.ts | 8 ++++++--
.../search/document-search.server.data-source.ts | 7 ++++---
.../documents/search/document.search-provider.ts | 12 +++++++++---
3 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
index 6a2f556a19..c5471d0e5d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.repository.ts
@@ -1,10 +1,14 @@
import { UmbDocumentSearchServerDataSource } from './document-search.server.data-source.js';
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbDocumentSearchItemModel } from './document.search-provider.js';
+import type { UmbSearchRepository, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
-export class UmbDocumentSearchRepository extends UmbControllerBase implements UmbApi {
+export class UmbDocumentSearchRepository
+ extends UmbControllerBase
+ implements UmbSearchRepository, UmbApi
+{
#dataSource: UmbDocumentSearchServerDataSource;
constructor(host: UmbControllerHost) {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
index 46c99963cc..824dd544ec 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search.server.data-source.ts
@@ -1,5 +1,6 @@
import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
+import type { UmbDocumentSearchItemModel } from './document.search-provider.js';
+import type { UmbSearchDataSource, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
@@ -10,7 +11,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
* @class UmbDocumentSearchServerDataSource
* @implements {RepositoryDetailDataSource}
*/
-export class UmbDocumentSearchServerDataSource {
+export class UmbDocumentSearchServerDataSource implements UmbSearchDataSource {
#host: UmbControllerHost;
/**
@@ -36,7 +37,7 @@ export class UmbDocumentSearchServerDataSource {
);
if (data) {
- const mappedItems = data.items.map((item) => {
+ const mappedItems: Array = data.items.map((item) => {
return {
href: '/section/content/workspace/document/edit/' + item.id,
entityType: UMB_DOCUMENT_ENTITY_TYPE,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
index 760b37f3ce..7029cfba73 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document.search-provider.ts
@@ -1,9 +1,15 @@
+import type { UmbDocumentItemModel } from '../index.js';
import { UmbDocumentSearchRepository } from './document-search.repository.js';
-import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
-import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
+import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+export interface UmbDocumentSearchItemModel extends UmbDocumentItemModel {
+ href: string;
+}
-export class UmbDocumentSearchProvider extends UmbControllerBase implements UmbApi {
+export class UmbDocumentSearchProvider
+ extends UmbControllerBase
+ implements UmbSearchProvider
+{
#repository = new UmbDocumentSearchRepository(this);
search(args: UmbSearchRequestArgs) {
From 9d6239fc7c5ebd6b9cb430bfaa29b75a32cc2e9e Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:08:18 +0200
Subject: [PATCH 074/323] media href
---
.../media/media/search/media-search.server.data-source.ts | 1 +
.../src/packages/media/media/search/media.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
index bc3a660932..21a2ae1858 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbMediaSearchServerDataSource implements UmbSearchDataSource = data.items.map((item) => {
return {
+ href: '/section/media/workspace/media/edit/' + item.id,
entityType: UMB_MEDIA_ENTITY_TYPE,
unique: item.id,
isTrashed: item.isTrashed,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
index 89f3b95cfb..9b5655ec82 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/search/media.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbMediaSearchRepository } from './media-search.repository.js';
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbMediaSearchItemModel extends UmbMediaItemModel {}
+export interface UmbMediaSearchItemModel extends UmbMediaItemModel {
+ href: string;
+}
export class UmbMediaSearchProvider extends UmbControllerBase implements UmbSearchProvider {
#repository = new UmbMediaSearchRepository(this);
From 96e42e93b3f1a4b3fcb9c84ecbf767d7e9d0f645 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:09:19 +0200
Subject: [PATCH 075/323] data type href
---
.../data-type/search/data-type-search.server.data-source.ts | 1 +
.../packages/data-type/search/data-type.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
index 2dcd9a55aa..20f021a3c5 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbDataTypeSearchServerDataSource implements UmbSearchDataSource = data.items.map((item) => {
return {
+ href: '/section/settings/workspace/data-type/edit/' + item.id,
entityType: UMB_DATA_TYPE_ENTITY_TYPE,
unique: item.id,
name: item.name,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
index a315d0904c..276e663587 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/search/data-type.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbDataTypeSearchRepository } from './data-type-search.repository.js';
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbDataTypeSearchItemModel extends UmbDataTypeItemModel {}
+export interface UmbDataTypeSearchItemModel extends UmbDataTypeItemModel {
+ href: string;
+}
export class UmbDataTypeSearchProvider
extends UmbControllerBase
From 261e0eee36005074b80d7aad3446091762b1f41a Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:10:13 +0200
Subject: [PATCH 076/323] document type href
---
.../search/document-type-search.server.data-source.ts | 1 +
.../document-types/search/document-type.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
index 7b8c2c0f56..beb2bc9f0a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbDocumentTypeSearchServerDataSource implements UmbSearchDataSourc
if (data) {
const mappedItems: Array = data.items.map((item) => {
return {
+ href: '/section/settings/workspace/document-type/edit/' + item.id,
entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
isElement: item.isElement,
icon: item.icon,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
index 2d4a51bfc3..d70845fc0a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/search/document-type.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbDocumentTypeSearchRepository } from './document-type-search.reposito
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbDocumentTypeSearchItemModel extends UmbDocumentTypeItemModel {}
+export interface UmbDocumentTypeSearchItemModel extends UmbDocumentTypeItemModel {
+ href: string;
+}
export class UmbDocumentTypeSearchProvider
extends UmbControllerBase
From 4f6378a064ced1409ad0146f3d7ef6b4f5507025 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:11:04 +0200
Subject: [PATCH 077/323] media type href
---
.../search/media-type-search.server.data-source.ts | 1 +
.../media/media-types/search/media-type.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
index a05b50817a..b49edd53b6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbMediaTypeSearchServerDataSource implements UmbSearchDataSource = data.items.map((item) => {
return {
+ href: '/section/settings/workspace/media-type/edit/' + item.id,
entityType: UMB_MEDIA_TYPE_ENTITY_TYPE,
unique: item.id,
name: item.name,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
index e85cc21cc8..746805fd58 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/search/media-type.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbMediaTypeSearchRepository } from './media-type-search.repository.js'
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbMediaTypeSearchItemModel extends UmbMediaTypeItemModel {}
+export interface UmbMediaTypeSearchItemModel extends UmbMediaTypeItemModel {
+ href: string;
+}
export class UmbMediaTypeSearchProvider
extends UmbControllerBase
From efd3995f127566c26d07d397605ed656843de48e Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:14:29 +0200
Subject: [PATCH 078/323] member href
---
.../members/member/search/member-search.server.data-source.ts | 1 +
.../packages/members/member/search/member.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
index ec3ee432bd..b56ebd9dc6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbMemberSearchServerDataSource implements UmbSearchDataSource = data.items.map((item) => {
return {
+ href: '/section/member-management/workspace/member/edit/' + item.id,
entityType: UMB_MEMBER_ENTITY_TYPE,
unique: item.id,
name: item.variants[0].name || '',
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
index 99ec93e170..535a812f31 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/member.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbMemberSearchRepository } from './member-search.repository.js';
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbMemberSearchItemModel extends UmbMemberItemModel {}
+export interface UmbMemberSearchItemModel extends UmbMemberItemModel {
+ href: string;
+}
export class UmbMemberSearchProvider extends UmbControllerBase implements UmbSearchProvider {
#repository = new UmbMemberSearchRepository(this);
From 53f343bbb0509a8f8bc96023829453557e54fbc4 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:14:34 +0200
Subject: [PATCH 079/323] member type href
---
.../search/member-type-search.server.data-source.ts | 1 +
.../members/member-type/search/member-type.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
index 79b16fed9e..0fc23e69bb 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbMemberTypeSearchServerDataSource implements UmbSearchDataSource<
if (data) {
const mappedItems: Array = data.items.map((item) => {
return {
+ href: '/section/settings/workspace/member-type/edit/' + item.id,
entityType: UMB_MEMBER_TYPE_ENTITY_TYPE,
unique: item.id,
name: item.name,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
index 852f7089e0..f46a3093e3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/search/member-type.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbMemberTypeSearchRepository } from './member-type-search.repository.j
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbMemberTypeSearchItemModel extends UmbMemberTypeItemModel {}
+export interface UmbMemberTypeSearchItemModel extends UmbMemberTypeItemModel {
+ href: string;
+}
export class UmbMemberTypeSearchProvider
extends UmbControllerBase
From 3fb1f893a5d58bf131dd4931ebee9e8ba296cc23 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:14:40 +0200
Subject: [PATCH 080/323] template href
---
.../templates/search/template-search.server.data-source.ts | 1 +
.../templating/templates/search/template.search-provider.ts | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
index a502683fbe..ba85e4e73c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template-search.server.data-source.ts
@@ -39,6 +39,7 @@ export class UmbTemplateSearchServerDataSource implements UmbSearchDataSource = data.items.map((item) => {
return {
+ href: '/section/settings/workspace/template/edit/' + item.id,
entityType: UMB_TEMPLATE_ENTITY_TYPE,
unique: item.id,
name: item.name,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
index 28477776d5..a1e8b90235 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/search/template.search-provider.ts
@@ -3,7 +3,9 @@ import { UmbTemplateSearchRepository } from './template-search.repository.js';
import type { UmbSearchProvider, UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
-export interface UmbTemplateSearchItemModel extends UmbTemplateItemModel {}
+export interface UmbTemplateSearchItemModel extends UmbTemplateItemModel {
+ href: string;
+}
export class UmbTemplateSearchProvider
extends UmbControllerBase
From ea2fa841f6841c0ce66198723068dd7e7f605c22 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:17:38 +0200
Subject: [PATCH 081/323] remove results on provider change
---
.../src/packages/search/search-modal/search-modal.element.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index ed2566b54f..9c68c6a5d4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -242,6 +242,7 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#focusInput();
this._loading = true;
+ this._searchResults = [];
this.#updateSearchResults();
}
From f03db2b55ce53f258ff6702c37c75e8f316d47b5 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:32:38 +0200
Subject: [PATCH 082/323] fix document styling
---
.../document-search-result-item.element.ts | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
index ad021f5241..98d35db29e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts
@@ -87,28 +87,13 @@ export class UmbSearchResultItemElement extends UmbLitElement {
UmbTextStyles,
css`
:host {
- background: var(--uui-color-surface);
padding: var(--uui-size-space-3) var(--uui-size-space-5);
border-radius: var(--uui-border-radius);
- color: var(--uui-color-interactive);
display: grid;
grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
align-items: center;
width: 100%;
- }
- .item {
- background: var(--uui-color-surface);
- padding: var(--uui-size-space-3) var(--uui-size-space-5);
- border-radius: var(--uui-border-radius);
- color: var(--uui-color-interactive);
- display: grid;
- grid-template-columns: var(--uui-size-space-6) 1fr var(--uui-size-space-5);
- align-items: center;
- width: 100%;
- }
- .item:hover {
- background-color: var(--uui-color-surface-emphasis);
- color: var(--uui-color-interactive-emphasis);
+ outline-offset: -3px;
}
.item-icon {
margin-bottom: auto;
From e3215d2670da230b84f2a1306fbbe433cff1677f Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:32:50 +0200
Subject: [PATCH 083/323] fix keyboard navigation
---
.../search/search-modal/search-modal.element.ts | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 9c68c6a5d4..5bc1c8484f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -337,7 +337,12 @@ export class UmbSearchModalElement extends UmbLitElement {
#closeModal(event: MouseEvent | KeyboardEvent) {
if (event instanceof KeyboardEvent && event.key !== 'Enter') return;
- this.modalContext?.reject();
+
+ requestAnimationFrame(() => {
+ // In the case where the browser has not triggered focus-visible and we keyboard navigate and press enter.
+ // It is necessary to wait one frame.
+ this.modalContext?.reject();
+ });
}
static styles = [
@@ -456,6 +461,10 @@ export class UmbSearchModalElement extends UmbLitElement {
outline-offset: -3px;
display: flex;
}
+ .search-item:hover {
+ background: var(--uui-color-surface-emphasis);
+ color: var(--uui-color-interactive-emphasis);
+ }
.search-item:focus {
outline: 2px solid var(--uui-color-interactive-emphasis);
border-radius: 6px;
From e0db6f628265393b6254f9d3a76bae5b95ff19a6 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:44:14 +0200
Subject: [PATCH 084/323] cleanup
---
.../src/packages/search/search-modal/search-modal.element.ts | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index 5bc1c8484f..f2d6b6eb82 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -172,8 +172,6 @@ export class UmbSearchModalElement extends UmbLitElement {
}
async #setSearchItemNavIndex(index: number) {
- await this.updateComplete;
-
const prevElement = this.shadowRoot?.querySelector(
`a[data-item-index="${this.#searchItemNavIndex}"]`,
) as HTMLElement | null;
From 25e5d9ec500295976faffd7f5b1d3f5501bd4459 Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Wed, 24 Apr 2024 19:54:49 +0200
Subject: [PATCH 085/323] cleanup
---
.../search-modal/search-modal.element.ts | 257 +++++++++---------
1 file changed, 127 insertions(+), 130 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
index f2d6b6eb82..eccd95f917 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/search/search-modal/search-modal.element.ts
@@ -57,10 +57,20 @@ export class UmbSearchModalElement extends UmbLitElement {
constructor() {
super();
- this.#observeViews();
+ this.#observeProviders();
}
- #observeViews() {
+ connectedCallback() {
+ super.connectedCallback();
+
+ this.addEventListener('keydown', this.#onKeydown);
+
+ requestAnimationFrame(() => {
+ this.#focusInput();
+ });
+ }
+
+ #observeProviders() {
new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'searchProvider', null, async (providers) => {
const searchProviders: Array = [];
@@ -83,94 +93,6 @@ export class UmbSearchModalElement extends UmbLitElement {
});
}
- connectedCallback() {
- super.connectedCallback();
-
- this.addEventListener('keydown', this.#onKeydown);
-
- requestAnimationFrame(() => {
- this.#focusInput();
- });
- }
-
- #onKeydown(event: KeyboardEvent) {
- const root = this.shadowRoot;
- if (!root) return;
-
- if (event.key === 'Tab') {
- const isFirstProvider = (element: Element) => element === root.querySelector('.search-provider:first-child');
- const isLastProvider = (element: Element) => element === root.querySelector('.search-provider:last-child');
- const setActiveProviderFocus = (element?: Element | null) => (element as HTMLElement)?.focus();
-
- const activeProvider = root.querySelector('.search-provider.active') as HTMLElement | null;
-
- if (!activeProvider) return;
-
- // When moving backwards in search providers
- if (event.shiftKey) {
- // If the FOCUS is on a provider, and it is the first in the list, we need to wrap around and focus the LAST one
- if (this.#providerHasFocus) {
- if (this.#isFocusingFirstProvider) {
- setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
- event.preventDefault();
- }
- return;
- }
-
- // If the currently ACTIVE provider is the first in the list, we need to wrap around and focus the LAST one
- if (isFirstProvider(activeProvider)) {
- setActiveProviderFocus(root.querySelector('.search-provider:last-child'));
- event.preventDefault();
- return;
- }
-
- // We set the focus to current provider, and because we don't prevent the default tab behavior, the previous provider will be focused
- setActiveProviderFocus(activeProvider);
- }
- // When moving forwards in search providers
- else {
- // If the FOCUS is on a provider, and it is the last in the list, we need to wrap around and focus the FIRST one
- if (this.#providerHasFocus) {
- if (this.#isFocusingLastProvider) {
- setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
- event.preventDefault();
- }
- return;
- }
-
- // If the currently ACTIVE provider is the last in the list, we need to wrap around and focus the FIRST one
- if (isLastProvider(activeProvider)) {
- setActiveProviderFocus(root.querySelector('.search-provider:first-child'));
- event.preventDefault();
- return;
- }
-
- // We set the focus to current provider, and because we don't prevent the default tab behavior, the next provider will be focused
- setActiveProviderFocus(activeProvider);
- }
- }
-
- switch (event.key) {
- case 'Tab':
- case 'Shift':
- case 'Escape':
- case 'Enter':
- break;
- case 'ArrowDown':
- event.preventDefault();
- this.#setSearchItemNavIndex(Math.min(this.#searchItemNavIndex + 1, this._searchResults.length - 1));
- break;
- case 'ArrowUp':
- event.preventDefault();
- this.#setSearchItemNavIndex(Math.max(this.#searchItemNavIndex - 1, 0));
- break;
- default:
- if (this._input === root.activeElement) return;
- this.#focusInput();
- break;
- }
- }
-
async #setSearchItemNavIndex(index: number) {
const prevElement = this.shadowRoot?.querySelector(
`a[data-item-index="${this.#searchItemNavIndex}"]`,
@@ -192,36 +114,6 @@ export class UmbSearchModalElement extends UmbLitElement {
this._input.focus();
}
- get #providerHasFocus() {
- const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
- return Array.from(providerElements).some((element) => element === this.shadowRoot?.activeElement);
- }
-
- get #isFocusingLastProvider() {
- const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
- return providerElements[providerElements.length - 1] === this.shadowRoot?.activeElement;
- }
-
- get #isFocusingFirstProvider() {
- const providerElements = this.shadowRoot?.querySelectorAll('.search-provider') || [];
- return providerElements[0] === this.shadowRoot?.activeElement;
- }
-
- #onSearchChange(event: InputEvent) {
- const target = event.target as HTMLInputElement;
- this._search = target.value.trim();
-
- clearTimeout(this.#inputTimer);
- if (!this._search) {
- this._loading = false;
- this._searchResults = [];
- return;
- }
-
- this._loading = true;
- this.#inputTimer = setTimeout(() => this.#updateSearchResults(), this.#inputTimerAmount);
- }
-
async #setShowFakeCursor(show: boolean) {
if (show) {
await new Promise((resolve) => requestAnimationFrame(resolve));
@@ -257,6 +149,121 @@ export class UmbSearchModalElement extends UmbLitElement {
this.#searchItemNavIndex = -1;
}
+ #closeModal(event: MouseEvent | KeyboardEvent) {
+ if (event instanceof KeyboardEvent && event.key !== 'Enter') return;
+
+ requestAnimationFrame(() => {
+ // In the case where the browser has not triggered focus-visible and we keyboard navigate and press enter.
+ // It is necessary to wait one frame.
+ this.modalContext?.reject();
+ });
+ }
+
+ #onSearchChange(event: InputEvent) {
+ const target = event.target as HTMLInputElement;
+ this._search = target.value.trim();
+
+ clearTimeout(this.#inputTimer);
+ if (!this._search) {
+ this._loading = false;
+ this._searchResults = [];
+ return;
+ }
+
+ this._loading = true;
+ this.#inputTimer = setTimeout(() => this.#updateSearchResults(), this.#inputTimerAmount);
+ }
+
+ #onKeydown(event: KeyboardEvent) {
+ const root = this.shadowRoot;
+ if (!root) return;
+
+ if (event.key === 'Tab') {
+ const isFirstProvider = (element: Element) => element === root.querySelector('.search-provider:first-child');
+ const isLastProvider = (element: Element) => element === root.querySelector('.search-provider:last-child');
+ const setFocus = (element?: Element | null) => (element as HTMLElement)?.focus();
+ const providerHasFocus = () => {
+ const providerElements = root.querySelectorAll('.search-provider') || [];
+ return Array.from(providerElements).some((element) => element === root.activeElement);
+ };
+ const isFocusingLastProvider = () => {
+ const providerElements = root.querySelectorAll('.search-provider') || [];
+ return providerElements[providerElements.length - 1] === root.activeElement;
+ };
+ const isFocusingFirstProvider = () => {
+ const providerElements = root.querySelectorAll('.search-provider') || [];
+ return providerElements[0] === root.activeElement;
+ };
+
+ const activeProvider = root.querySelector('.search-provider.active') as HTMLElement | null;
+
+ if (!activeProvider) return;
+
+ // When moving backwards in search providers
+ if (event.shiftKey) {
+ // If the FOCUS is on a provider, and it is the first in the list, we need to wrap around and focus the LAST one
+ if (providerHasFocus()) {
+ if (isFocusingFirstProvider()) {
+ setFocus(root.querySelector('.search-provider:last-child'));
+ event.preventDefault();
+ }
+ return;
+ }
+
+ // If the currently ACTIVE provider is the first in the list, we need to wrap around and focus the LAST one
+ if (isFirstProvider(activeProvider)) {
+ setFocus(root.querySelector('.search-provider:last-child'));
+ event.preventDefault();
+ return;
+ }
+
+ // We set the focus to current provider, and because we don't prevent the default tab behavior, the previous provider will be focused
+ setFocus(activeProvider);
+ }
+ // When moving forwards in search providers
+ else {
+ // If the FOCUS is on a provider, and it is the last in the list, we need to wrap around and focus the FIRST one
+ if (providerHasFocus()) {
+ if (isFocusingLastProvider()) {
+ setFocus(root.querySelector('.search-provider:first-child'));
+ event.preventDefault();
+ }
+ return;
+ }
+
+ // If the currently ACTIVE provider is the last in the list, we need to wrap around and focus the FIRST one
+ if (isLastProvider(activeProvider)) {
+ setFocus(root.querySelector('.search-provider:first-child'));
+ event.preventDefault();
+ return;
+ }
+
+ // We set the focus to current provider, and because we don't prevent the default tab behavior, the next provider will be focused
+ setFocus(activeProvider);
+ }
+ }
+
+ switch (event.key) {
+ case 'Tab':
+ case 'Shift':
+ case 'Escape':
+ case 'Enter':
+ break;
+ case 'ArrowDown':
+ event.preventDefault();
+ this.#setSearchItemNavIndex(Math.min(this.#searchItemNavIndex + 1, this._searchResults.length - 1));
+ break;
+ case 'ArrowUp':
+ event.preventDefault();
+ this.#setSearchItemNavIndex(Math.max(this.#searchItemNavIndex - 1, 0));
+ break;
+ default:
+ if (this._input === root.activeElement) return;
+ this.#focusInput();
+ break;
+ }
+ }
+
render() {
return html`
@@ -333,16 +340,6 @@ export class UmbSearchModalElement extends UmbLitElement {
return this._loading ? nothing : html`
${this.localize.term('general_searchNoResult')}
`;
}
- #closeModal(event: MouseEvent | KeyboardEvent) {
- if (event instanceof KeyboardEvent && event.key !== 'Enter') return;
-
- requestAnimationFrame(() => {
- // In the case where the browser has not triggered focus-visible and we keyboard navigate and press enter.
- // It is necessary to wait one frame.
- this.modalContext?.reject();
- });
- }
-
static styles = [
UmbTextStyles,
css`
From 5bffe4366a14310504894dd32bab482ef584f457 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 21:21:11 +0200
Subject: [PATCH 086/323] deep merge
---
.../src/packages/core/utils/index.ts | 3 +-
.../core/utils/object/deep-merge.function.ts | 22 +++++++
.../core/utils/object/deep-merge.test.ts | 61 +++++++++++++++++++
3 files changed, 85 insertions(+), 1 deletion(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.test.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
index 8b243bcb6c..09d60ef911 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
@@ -16,4 +16,5 @@ export * from './string/generate-umbraco-alias.function.js';
export * from './string/increment-string.function.js';
export * from './string/split-string-to-array.js';
export * from './string/to-camel-case/to-camel-case.function.js';
-export * from './type/diff.type.js';
+export type * from './type/deep-partial.type.js';
+export type * from './type/diff.type.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
new file mode 100644
index 0000000000..b08629cb1d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
@@ -0,0 +1,22 @@
+import type { DeepPartial } from '../type/deep-partial.type.js';
+
+/**
+ * Deep merge two objects.
+ * @param target
+ * @param ...sources
+ */
+export function umbDeepMerge(source: DeepPartial, fallback: T) {
+ const result = { ...fallback };
+
+ for (const key in source) {
+ if (Object.prototype.hasOwnProperty.call(source, key) && source[key] !== undefined) {
+ if (source[key].constructor === Object && fallback[key].constructor === Object) {
+ result[key] = umbDeepMerge(source[key], fallback[key]);
+ } else {
+ result[key] = source[key] as any;
+ }
+ }
+ }
+
+ return result;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.test.ts
new file mode 100644
index 0000000000..61509c9162
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.test.ts
@@ -0,0 +1,61 @@
+import { expect } from '@open-wc/testing';
+import { umbDeepMerge } from './deep-merge.function.js';
+
+describe('UmbDeepMerge', () => {
+ beforeEach(() => {});
+
+ describe('merge just objects', () => {
+ it('transfers defined properties', () => {
+ const defaults = {
+ prop1: {
+ name: 'prop1',
+ value: 'value1',
+ },
+ prop2: {
+ name: 'prop2',
+ value: 'value2',
+ },
+ };
+ const source = {
+ prop2: {
+ name: 'prop2_updatedName',
+ },
+ };
+ const result = umbDeepMerge(source, defaults);
+
+ expect(result.prop1.name).to.equal('prop1');
+ expect(result.prop2.name).to.equal('prop2_updatedName');
+ });
+ });
+
+ describe('merge objects with arrays', () => {
+ // The arrays should not be merged, but take the value from the main object. [NL]
+ it('transfers defined properties', () => {
+ const defaults = {
+ prop1: {
+ name: 'prop1',
+ value: ['entry1', 'entry2', 'entry3'],
+ },
+ prop2: {
+ name: 'prop2',
+ value: ['entry4', 'entry4', 'entry5'],
+ },
+ };
+ const source = {
+ prop1: {
+ name: 'prop1_updatedName',
+ },
+ prop2: {
+ name: 'prop2_updatedName',
+ value: ['entry666'],
+ },
+ };
+ const result = umbDeepMerge(source, defaults);
+
+ expect(result.prop1.name).to.equal('prop1_updatedName');
+ expect(result.prop2.value.join(',')).to.equal(defaults.prop1.value.join(','));
+ expect(result.prop2.name).to.equal('prop2_updatedName');
+ expect(result.prop2.value.join(',')).to.equal(source.prop2.value.join(','));
+ });
+ });
+});
From a3069c619545067015b5c699b01e7b5a3c3589e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 21:21:51 +0200
Subject: [PATCH 087/323] url-pattern-to-string correction
---
.../core/utils/path/url-pattern-to-string.function.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
index e927e3cf15..1cd087a67e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/url-pattern-to-string.function.ts
@@ -5,9 +5,9 @@ const PARAM_IDENTIFIER = /:([^/]+)/g;
export function umbUrlPatternToString(pattern: string, params: UrlParametersRecord | null): string {
return params
? pattern.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => {
- const segmentName = args[0]; // (segmentName is the parameter name without the colon)
+ const segmentValue = params![args[0]]; // (segmentValue is the value to replace the parameter)
// Replace the path-segment with the value from the params object or 'null' if it doesn't exist
- return params![segmentName]?.toString() ?? 'null';
+ return segmentValue === undefined ? `:${args[0]}` : segmentValue === null ? 'null' : segmentValue.toString();
})
: pattern;
}
From e00975e64bada859f1492f138af31c3954280644 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 21:25:02 +0200
Subject: [PATCH 088/323] deep-partial type
---
.../src/packages/core/utils/type/deep-partial.type.ts | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
new file mode 100644
index 0000000000..65bb71bfa0
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
@@ -0,0 +1,5 @@
+export type DeepPartial = T extends object
+ ? {
+ [P in keyof T]?: DeepPartial;
+ }
+ : T;
From fdbe522a8ef3460d21ca9abec17044ed1b5918dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 22:20:31 +0200
Subject: [PATCH 089/323] eport util
---
src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
index 09d60ef911..572569ab13 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
@@ -3,6 +3,7 @@ export * from './direction/index.js';
export * from './download/blob-download.function.js';
export * from './get-processed-image-url.function.js';
export * from './math/math.js';
+export * from './object/deep-merge.function.js';
export * from './pagination-manager/pagination.manager.js';
export * from './path/ensure-path-ends-with-slash.function.js';
export * from './path/path-decode.function.js';
From 433bdc4c74ef6a620cc9bb02d1a47e7cf9aed220 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 23:42:36 +0200
Subject: [PATCH 090/323] deep partial modal data, for more fine grained
definitions
---
.../modal/context/modal-manager.context.ts | 2 +-
.../core/modal/context/modal.context.ts | 18 +++++++++--
.../modal-route-registration.controller.ts | 19 +++++++-----
.../modal-route-registration.interface.ts | 5 +++-
.../packages/core/modal/token/modal-token.ts | 10 +++++--
.../tree-picker/tree-picker-modal.token.ts | 4 +--
.../src/packages/core/utils/index.ts | 2 +-
.../core/utils/object/deep-merge.function.ts | 11 ++++---
.../utils/type/deep-partial-object.type.ts | 30 +++++++++++++++++++
.../core/utils/type/deep-partial.type.ts | 5 ----
10 files changed, 80 insertions(+), 26 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial-object.type.ts
delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
index eb74e7deca..0764a232c8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
@@ -38,7 +38,7 @@ export class UmbModalManagerContext extends UmbContextBase,
>(
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
index 05d6220b7a..2fc6c8da0c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
@@ -6,6 +6,7 @@ import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
import { UmbId } from '@umbraco-cms/backoffice/id';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import { type UmbDeepPartialObject, umbDeepMerge } from '@umbraco-cms/backoffice/utils';
export interface UmbModalRejectReason {
type: string;
@@ -13,7 +14,9 @@ export interface UmbModalRejectReason {
export type UmbModalContextClassArgs<
ModalAliasType extends string | UmbModalToken,
- ModalAliasTypeAsToken extends UmbModalToken = ModalAliasType extends UmbModalToken ? ModalAliasType : UmbModalToken,
+ ModalAliasTypeAsToken extends UmbModalToken = ModalAliasType extends UmbModalToken
+ ? ModalAliasType
+ : UmbModalToken,
> = {
router?: IRouterSlot | null;
data?: ModalAliasTypeAsToken['DATA'];
@@ -22,7 +25,10 @@ export type UmbModalContextClassArgs<
};
// TODO: consider splitting this into two separate handlers
-export class UmbModalContext extends UmbControllerBase {
+export class UmbModalContext<
+ ModalPreset extends { [key: string]: any } = { [key: string]: any },
+ ModalValue = any,
+> extends UmbControllerBase {
//
#submitPromise: Promise;
#submitResolver?: (value: ModalValue) => void;
@@ -60,7 +66,13 @@ export class UmbModalContext, defaultData) as ModalPreset)
+ : // otherwise pick one of them:
+ (args.data as ModalPreset) ?? defaultData,
+ );
const initValue =
args.value ?? (this.alias instanceof UmbModalToken ? (this.alias as UmbModalToken).getDefaultValue() : undefined);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.controller.ts
index b4de970109..b645cc0185 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.controller.ts
@@ -1,25 +1,30 @@
import type { UmbModalToken } from '../token/index.js';
import type { UmbModalConfig, UmbModalContext, UmbModalManagerContext, UmbModalRouteRegistration } from '../index.js';
+import type { UmbModalContextClassArgs } from '../context/modal.context.js';
import { type Params, type IRouterSlot, UMB_ROUTE_CONTEXT, encodeFolderName } from '@umbraco-cms/backoffice/router';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { UmbId } from '@umbraco-cms/backoffice/id';
+import type { UmbDeepPartialObject } from '@umbraco-cms/backoffice/utils';
export type UmbModalRouteBuilder = (params: { [key: string]: string | number } | null) => string;
export type UmbModalRouteSetupReturn = UmbModalTokenValue extends undefined
? {
- modal?: UmbModalConfig;
- data: UmbModalTokenData;
+ modal?: UmbDeepPartialObject;
+ data: UmbDeepPartialObject;
value?: UmbModalTokenValue;
}
: {
- modal?: UmbModalConfig;
- data: UmbModalTokenData;
+ modal?: UmbDeepPartialObject;
+ data: UmbDeepPartialObject;
value: UmbModalTokenValue;
};
-export class UmbModalRouteRegistrationController
+export class UmbModalRouteRegistrationController<
+ UmbModalTokenData extends { [key: string]: any } = { [key: string]: any },
+ UmbModalTokenValue = any,
+ >
extends UmbControllerBase
implements UmbModalRouteRegistration
{
@@ -293,8 +298,8 @@ export class UmbModalRouteRegistrationController>;
+ args.modal!.key = this.#key;
this.#modalContext = modalManagerContext.open(this, this.#modalAlias, args);
this.#modalContext.onSubmit().then(this.#onSubmit, this.#onReject);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.interface.ts
index e4113c2408..a1af2fbcf7 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.interface.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/route-registration/modal-route-registration.interface.ts
@@ -3,7 +3,10 @@ import type { UmbModalContext, UmbModalRouteBuilder } from '../index.js';
import type { UmbModalToken } from '../token/modal-token.js';
import type { IRouterSlot, Params } from '@umbraco-cms/backoffice/router';
-export interface UmbModalRouteRegistration {
+export interface UmbModalRouteRegistration<
+ UmbModalTokenData extends { [key: string]: any } = { [key: string]: any },
+ UmbModalTokenValue = any,
+> {
key: string;
alias: UmbModalToken | string;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
index 8d45fde4b9..61d66ce63e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
@@ -1,12 +1,18 @@
import type { UmbModalConfig } from '../context/modal-manager.context.js';
-export interface UmbModalTokenDefaults {
+export interface UmbModalTokenDefaults<
+ ModalDataType extends { [key: string]: any } = { [key: string]: any },
+ ModalValueType = unknown,
+> {
modal?: UmbModalConfig;
data?: ModalDataType;
value?: ModalValueType;
}
-export class UmbModalToken {
+export class UmbModalToken<
+ ModalDataType extends { [key: string]: any } = { [key: string]: any },
+ ModalValueType = unknown,
+> {
/**
* Get the data type of the token's data.
*
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
index a6ab0af664..d5d3affed0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
@@ -11,7 +11,7 @@ export interface UmbTreePickerModalCreateActionData extends UmbPickerModalData {
treeAlias?: string;
@@ -21,7 +21,7 @@ export interface UmbTreePickerModalData<
export interface UmbTreePickerModalValue extends UmbPickerModalValue {}
-export const UMB_TREE_PICKER_MODAL = new UmbModalToken(
+export const UMB_TREE_PICKER_MODAL = new UmbModalToken, UmbTreePickerModalValue>(
UMB_TREE_PICKER_MODAL_ALIAS,
{
modal: {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
index 572569ab13..6895540e28 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts
@@ -17,5 +17,5 @@ export * from './string/generate-umbraco-alias.function.js';
export * from './string/increment-string.function.js';
export * from './string/split-string-to-array.js';
export * from './string/to-camel-case/to-camel-case.function.js';
-export type * from './type/deep-partial.type.js';
+export type * from './type/deep-partial-object.type.js';
export type * from './type/diff.type.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
index b08629cb1d..94b67c9b94 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/object/deep-merge.function.ts
@@ -1,17 +1,20 @@
-import type { DeepPartial } from '../type/deep-partial.type.js';
+import type { UmbDeepPartialObject } from '../type/deep-partial-object.type.js';
/**
* Deep merge two objects.
* @param target
* @param ...sources
*/
-export function umbDeepMerge(source: DeepPartial, fallback: T) {
+export function umbDeepMerge<
+ T extends { [key: string]: any },
+ PartialType extends UmbDeepPartialObject = UmbDeepPartialObject,
+>(source: PartialType, fallback: T) {
const result = { ...fallback };
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key) && source[key] !== undefined) {
- if (source[key].constructor === Object && fallback[key].constructor === Object) {
- result[key] = umbDeepMerge(source[key], fallback[key]);
+ if (source[key]?.constructor === Object && fallback[key].constructor === Object) {
+ result[key] = umbDeepMerge(source[key] as any, fallback[key]);
} else {
result[key] = source[key] as any;
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial-object.type.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial-object.type.ts
new file mode 100644
index 0000000000..7961caf5d1
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial-object.type.ts
@@ -0,0 +1,30 @@
+/*export type DeepPartial = T extends { [key: string]: any }
+ ? {
+ [P in keyof T]?: DeepPartial;
+ }
+ : T;
+*/
+
+// Notice this can be way more complex, but in this case I just wanted to cover pure objects, to match our deep merge function [NL]
+// See https://stackoverflow.com/questions/61132262/typescript-deep-partial for more extensive solutions.
+/**
+ * Deep partial object type, making objects and their properties optional, but only until a property of a different type is encountered.
+ * This means if an object holds a property with an array that holds objects, the array will be made optional, but the properties of the objects inside the array will not be changed.
+ * @type UmbDeepPartialObject
+ * @generic T - The object to make partial.
+ * @returns A type with all properties of objects made optional.
+ */
+// eslint-disable-next-line @typescript-eslint/ban-types
+export type UmbDeepPartialObject = T extends Function
+ ? T
+ : // Thing extends Array
+ // ? DeepPartialArray :
+ T extends { [key: string]: any }
+ ? UmbDeepPartialObjectProperty
+ : T | undefined;
+
+//interface DeepPartialArray extends Array> {}
+
+type UmbDeepPartialObjectProperty = {
+ [Key in keyof Thing]?: UmbDeepPartialObject;
+};
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
deleted file mode 100644
index 65bb71bfa0..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/type/deep-partial.type.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type DeepPartial = T extends object
- ? {
- [P in keyof T]?: DeepPartial;
- }
- : T;
From 4875e1db14fed35d04d7719d1b7c01d47e84c048 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 23:43:04 +0200
Subject: [PATCH 091/323] remove unnesecary modal data in implementation
---
.../components/input-block-type/input-block-type.element.ts | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
index 2e5ca4ecda..c8a685055e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
@@ -86,13 +86,7 @@ export class UmbInputBlockTypeElement<
hideTreeRoot: true,
multiple: false,
createAction: {
- modalData: {
- entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
- preset: { isElementType: true },
- },
- additionalPathGenerator: umbCreateDocumentTypeWorkspacePathGenerator,
additionalPathParams: {
- entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
parentUnique: null,
presetAlias: 'element',
},
From 86ddab0c37b995b88ff605b30ea7454fcf5d12db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 23:45:04 +0200
Subject: [PATCH 092/323] improed modal token
---
.../modals/document-type-picker-modal.token.ts | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
index 8fc9713972..956ae78c1d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
@@ -7,8 +7,14 @@ import {
UMB_TREE_PICKER_MODAL_ALIAS,
} from '@umbraco-cms/backoffice/tree';
-export interface UmbDocumentTypePickerModalData
+/*export interface UmbDocumentTypePickerModalData
extends UmbTreePickerModalData {}
+*/
+export type UmbDocumentTypePickerModalData = UmbTreePickerModalData<
+ UmbDocumentTypeTreeItemModel,
+ typeof umbCreateDocumentTypeWorkspacePathGenerator
+>;
+
export interface UmbDocumentTypePickerModalValue extends UmbTreePickerModalValue {}
export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
@@ -23,14 +29,14 @@ export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
treeAlias: 'Umb.Tree.DocumentType',
createAction: {
modalData: {
- entityType: 'documentType',
+ entityType: 'document-type',
preset: {},
},
additionalPathGenerator: umbCreateDocumentTypeWorkspacePathGenerator,
additionalPathParams: {
- entityType: 'documentType',
- parentUnique: '',
- presetAlias: '',
+ entityType: 'document-type',
+ parentUnique: null,
+ presetAlias: null,
},
},
},
From f13ab36561b281d2591e93084b174a8fd454c351 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Wed, 24 Apr 2024 23:45:20 +0200
Subject: [PATCH 093/323] better rejection when failed workspace modal
---
.../core/tree/tree-picker/tree-picker-modal.element.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
index 41220920d7..dea4836ea8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
@@ -57,6 +57,9 @@ export class UmbTreePickerModalElement {
From e58087667a6b7d6e88366cf23d596d92968a1cf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20Lyngs=C3=B8?=
Date: Thu, 25 Apr 2024 12:50:27 +0200
Subject: [PATCH 094/323] refactor to use umbPathPattern
---
.../input-block-type.element.ts | 8 ++---
...nerate-route-path-builder.function.test.ts | 16 ++++-----
.../generate-route-path-builder.function.ts | 7 +++-
.../src/packages/core/router/index.ts | 2 +-
.../core/router/path-pattern.class.ts | 35 +++++++++++++++++++
.../src/packages/core/router/route.context.ts | 4 +--
.../tree-picker/tree-picker-modal.element.ts | 3 +-
.../tree-picker/tree-picker-modal.token.ts | 12 +++----
.../document-type-picker-modal.token.ts | 8 ++---
.../documents/document-types/paths.ts | 11 +++---
.../document-type-workspace.context.ts | 4 +--
11 files changed, 72 insertions(+), 38 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/router/path-pattern.class.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
index c8a685055e..ef77263298 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts
@@ -7,11 +7,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property';
import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
import { UmbDeleteEvent } from '@umbraco-cms/backoffice/event';
-import {
- UMB_DOCUMENT_TYPE_PICKER_MODAL,
- UMB_DOCUMENT_TYPE_ENTITY_TYPE,
- umbCreateDocumentTypeWorkspacePathGenerator,
-} from '@umbraco-cms/backoffice/document-type';
+import { UMB_DOCUMENT_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/document-type';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
/** TODO: Look into sending a "change" event when there is a change, rather than create, delete, and change event. Make sure it doesn't break move for RTE/List/Grid. [LI] */
@@ -86,7 +82,7 @@ export class UmbInputBlockTypeElement<
hideTreeRoot: true,
multiple: false,
createAction: {
- additionalPathParams: {
+ extendWithPathParams: {
parentUnique: null,
presetAlias: 'element',
},
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
index b768e4d582..59637c2db8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts
@@ -1,41 +1,41 @@
import { expect } from '@open-wc/testing';
-import { umbCreateRoutePathBuilder } from './generate-route-path-builder.function.js';
+import { umbGenerateRoutePathBuilder } from './generate-route-path-builder.function.js';
describe('createRoutePathBuilder', () => {
it('should return a function that builds a route path without parameters', () => {
- const buildPath = umbCreateRoutePathBuilder('test/path');
+ const buildPath = umbGenerateRoutePathBuilder('test/path');
expect(buildPath(null)).to.eq('/test/path/');
});
it('should return a function that builds a route path with parameters', () => {
- const buildPath = umbCreateRoutePathBuilder(':param0/test/:param1/path/:param2');
+ const buildPath = umbGenerateRoutePathBuilder(':param0/test/:param1/path/:param2');
expect(buildPath({ param0: 'value0', param1: 'value1', param2: 'value2' })).to.eq(
'/value0/test/value1/path/value2/',
);
});
it('should convert number parameters to strings', () => {
- const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbGenerateRoutePathBuilder('test/:param1/path/:param2');
expect(buildPath({ param1: 123, param2: 456 })).to.eq('/test/123/path/456/');
});
it('should not consider route segments that resembles parameters as parameters', () => {
- const buildPath = umbCreateRoutePathBuilder('test/uc:store/path');
+ const buildPath = umbGenerateRoutePathBuilder('test/uc:store/path');
expect(buildPath({ someOtherParam: 'test' })).to.eq('/test/uc:store/path/');
});
it('should support multiple parameters with the same name', () => {
- const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param1');
+ const buildPath = umbGenerateRoutePathBuilder('test/:param1/path/:param1');
expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/value1/');
});
it('should not consider parameters that are not in the params object', () => {
- const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbGenerateRoutePathBuilder('test/:param1/path/:param2');
expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/:param2/');
});
it('should support complex objects as parameters with a custom toString method', () => {
- const buildPath = umbCreateRoutePathBuilder('test/:param1/path/:param2');
+ const buildPath = umbGenerateRoutePathBuilder('test/:param1/path/:param2');
const obj = {
toString() {
return 'value1';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
index 181abf6abf..24db7b9dc6 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts
@@ -1,8 +1,13 @@
import { type UrlParametersRecord, umbUrlPatternToString } from '../utils/path/url-pattern-to-string.function.js';
import { stripSlash } from '@umbraco-cms/backoffice/external/router-slot'; // This must only include the util to avoid side effects of registering the route element.
-export function umbCreateRoutePathBuilder(path: string) {
+export function umbGenerateRoutePathBuilder(path: string) {
return (params: UrlParametersRecord | null) => {
return '/' + stripSlash(umbUrlPatternToString(path, params)) + '/';
};
}
+
+/**
+ * @deprecated Use `umbGenerateRoutePathBuilder` instead.
+ */
+export { umbGenerateRoutePathBuilder as umbCreateRoutePathBuilder };
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts
index c4b9ff29db..7aeb5ac6ec 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts
@@ -1,8 +1,8 @@
export * from '@umbraco-cms/backoffice/external/router-slot';
export * from './encode-folder-name.function.js';
-export * from './generate-route-path-builder.function.js';
export * from './route.context.js';
export * from './route.interface.js';
export * from './router-slot-change.event.js';
export * from './router-slot-init.event.js';
export * from './router-slot.element.js';
+export * from './path-pattern.class.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/path-pattern.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/path-pattern.class.ts
new file mode 100644
index 0000000000..31ed8b8b57
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/path-pattern.class.ts
@@ -0,0 +1,35 @@
+import { umbUrlPatternToString } from '../utils/path/url-pattern-to-string.function.js';
+
+export type UmbPathPatternParamsType = { [key: string]: any };
+
+export class UmbPathPattern {
+ #local: string;
+ #base: string;
+
+ /**
+ * Get the params type of the path pattern
+ *
+ * @public
+ * @type {T}
+ * @memberOf UmbPathPattern
+ * @example `typeof MyPathPattern.PARAMS`
+ * @returns undefined
+ */
+ readonly PARAMS!: LocalParamsType;
+
+ constructor(localPattern: string, basePath?: string) {
+ this.#local = localPattern;
+ this.#base = basePath ? (basePath.lastIndexOf('/') !== basePath.length - 1 ? basePath + '/' : basePath) : '';
+ }
+
+ generateLocal(params: LocalParamsType) {
+ return umbUrlPatternToString(this.#local, params);
+ }
+ generateGlobal(params: LocalParamsType) {
+ return this.#base + umbUrlPatternToString(this.#local, params);
+ }
+
+ toString() {
+ return this.#local;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
index ee860f7d6f..61213982e1 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts
@@ -1,5 +1,5 @@
import type { UmbRoute } from './route.interface.js';
-import { umbCreateRoutePathBuilder } from './generate-route-path-builder.function.js';
+import { umbGenerateRoutePathBuilder } from './generate-route-path-builder.function.js';
import type { IRoutingInfo, IRouterSlot } from '@umbraco-cms/backoffice/external/router-slot';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -147,7 +147,7 @@ export class UmbRouteContext extends UmbContextBase {
: this.#routerActiveLocalPath + '/'
: '';
const localPath = routeBasePath + routeActiveLocalPath + modalRegistration.generateModalPath();
- const urlBuilder = umbCreateRoutePathBuilder(localPath);
+ const urlBuilder = umbGenerateRoutePathBuilder(localPath);
modalRegistration._internal_setRouteBuilder(urlBuilder);
};
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
index dea4836ea8..dc441fe8df 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts
@@ -65,7 +65,8 @@ export class UmbTreePickerModalElement {
const oldPath = this._createPath;
this._createPath =
- routeBuilder({}) + createActionData.additionalPathGenerator(createActionData.additionalPathParams);
+ routeBuilder({}) +
+ createActionData.extendWithPathPattern.generateLocal(createActionData.extendWithPathParams);
this.requestUpdate('_createPath', oldPath);
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
index d5d3affed0..03f5152144 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts
@@ -1,22 +1,22 @@
import { UMB_TREE_PICKER_MODAL_ALIAS } from './constants.js';
import type { UmbPickerModalData, UmbPickerModalValue, UmbWorkspaceModalData } from '@umbraco-cms/backoffice/modal';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
+import type { UmbPathPattern, UmbPathPatternParamsType } from '@umbraco-cms/backoffice/router';
-export type UmbPathGeneratorType = (params: any) => string;
-export interface UmbTreePickerModalCreateActionData {
+export interface UmbTreePickerModalCreateActionData {
modalData: UmbWorkspaceModalData;
modalToken?: UmbModalToken;
- additionalPathGenerator: PathGeneratorType;
- additionalPathParams: Parameters[0];
+ extendWithPathPattern: UmbPathPattern;
+ extendWithPathParams: PathPatternParamsType;
}
export interface UmbTreePickerModalData<
TreeItemType,
- PathGeneratorType extends UmbPathGeneratorType = UmbPathGeneratorType,
+ PathPatternParamsType extends UmbPathPatternParamsType = UmbPathPatternParamsType,
> extends UmbPickerModalData {
treeAlias?: string;
// Consider if it makes sense to move this into the UmbPickerModalData interface, but for now this is a TreePicker feature. [NL]
- createAction?: UmbTreePickerModalCreateActionData;
+ createAction?: UmbTreePickerModalCreateActionData;
}
export interface UmbTreePickerModalValue extends UmbPickerModalValue {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
index 956ae78c1d..2221229a12 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts
@@ -1,4 +1,4 @@
-import { umbCreateDocumentTypeWorkspacePathGenerator } from '../paths.js';
+import { UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH } from '../paths.js';
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
import type { UmbDocumentTypeTreeItemModel } from '@umbraco-cms/backoffice/document-type';
import {
@@ -12,7 +12,7 @@ import {
*/
export type UmbDocumentTypePickerModalData = UmbTreePickerModalData<
UmbDocumentTypeTreeItemModel,
- typeof umbCreateDocumentTypeWorkspacePathGenerator
+ typeof UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH.PARAMS
>;
export interface UmbDocumentTypePickerModalValue extends UmbTreePickerModalValue {}
@@ -32,8 +32,8 @@ export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken<
entityType: 'document-type',
preset: {},
},
- additionalPathGenerator: umbCreateDocumentTypeWorkspacePathGenerator,
- additionalPathParams: {
+ extendWithPathPattern: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH,
+ extendWithPathParams: {
entityType: 'document-type',
parentUnique: null,
presetAlias: null,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
index 93b117acb3..c351f94b67 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/paths.ts
@@ -1,5 +1,5 @@
import type { UmbDocumentTypeEntityTypeUnion } from './entity.js';
-import { umbUrlPatternToString } from '@umbraco-cms/backoffice/utils';
+import { UmbPathPattern } from '@umbraco-cms/backoffice/router';
export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE = 'template';
export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_ELEMENT = 'element';
@@ -13,13 +13,10 @@ export type UmbCreateDocumentTypeWorkspacePresetType =
| UmbCreateDocumentTypeWorkspacePresetTemplateType
| UmbCreateDocumentTypeWorkspacePresetElementType;
-export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH = 'create/:entityType/:parentUnique/:presetAlias';
-export const umbCreateDocumentTypeWorkspacePathGenerator = (params: {
+export const UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH = new UmbPathPattern<{
entityType: UmbDocumentTypeEntityTypeUnion;
parentUnique?: string | null;
presetAlias?: UmbCreateDocumentTypeWorkspacePresetType | null;
-}) => umbUrlPatternToString(UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, params);
+}>('create/:entityType/:parentUnique/:presetAlias');
-export const UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH = 'edit/:id';
-export const umbEditDocumentTypeWorkspacePathGenerator = (params: { id: string }) =>
- umbUrlPatternToString(UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH, params);
+export const UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH = new UmbPathPattern<{ id: string }>('edit/:id');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
index b5194e7080..578df73d21 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts
@@ -96,7 +96,7 @@ export class UmbDocumentTypeWorkspaceContext
this.routes.setRoutes([
{
- path: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH,
+ path: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH.toString(),
component: UmbDocumentTypeWorkspaceEditorElement,
setup: (_component, info) => {
const parentEntityType = info.match.params.entityType;
@@ -112,7 +112,7 @@ export class UmbDocumentTypeWorkspaceContext
},
},
{
- path: UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH,
+ path: UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH.toString(),
component: UmbDocumentTypeWorkspaceEditorElement,
setup: (_component, info) => {
this.removeUmbControllerByAlias('isNewRedirectController');
From e9fdc4daef443d76b43dfbff72a1f0684bb05f56 Mon Sep 17 00:00:00 2001
From: Mads Rasmussen
Date: Thu, 25 Apr 2024 13:00:40 +0200
Subject: [PATCH 095/323] add interfaces for composition repo + data source
---
...-type-composition-data-source.interface.ts | 23 +++++++++++++++++++
...t-type-composition-repository.interface.ts | 18 +++++++++++++++
.../core/content-type/composition/index.ts | 4 ++++
.../core/content-type/composition/types.ts | 19 +++++++++++++++
.../src/packages/core/content-type/index.ts | 1 +
5 files changed, 65 insertions(+)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts
new file mode 100644
index 0000000000..e0a2c35635
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts
@@ -0,0 +1,23 @@
+import type {
+ UmbContentTypeCompositionCompatibleModel,
+ UmbContentTypeCompositionReferenceModel,
+ UmbContentTypeCompositionRequestModel,
+} from './types.js';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository';
+
+export interface UmbContentTypeCompositionDataSourceConstructor {
+ new (host: UmbControllerHost): UmbContentTypeCompositionDataSource;
+}
+
+export interface UmbContentTypeCompositionDataSource {
+ availableCompositions<
+ ResponseType extends UmbContentTypeCompositionCompatibleModel,
+ ArgsType extends UmbContentTypeCompositionRequestModel,
+ >(
+ args: ArgsType,
+ ): Promise>>;
+ getReferences(
+ unique: string,
+ ): Promise>>;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts
new file mode 100644
index 0000000000..ac9fb7ce59
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts
@@ -0,0 +1,18 @@
+import type {
+ UmbContentTypeCompositionCompatibleModel,
+ UmbContentTypeCompositionReferenceModel,
+ UmbContentTypeCompositionRequestModel,
+} from './types.js';
+import type { UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository';
+
+export interface UmbContentTypeCompositionRepository {
+ getReferences(
+ unique: string,
+ ): Promise>>;
+ availableCompositions<
+ ResponseType extends UmbContentTypeCompositionCompatibleModel,
+ ArgsType extends UmbContentTypeCompositionRequestModel,
+ >(
+ args: ArgsType,
+ ): Promise>>;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts
new file mode 100644
index 0000000000..c9b2fadc33
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts
@@ -0,0 +1,4 @@
+export type { UmbContentTypeCompositionRepository } from './content-type-composition-repository.interface.js';
+export type { UmbContentTypeCompositionDataSource } from './content-type-composition-data-source.interface.js';
+
+export * from './types.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts
new file mode 100644
index 0000000000..d6530f961d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts
@@ -0,0 +1,19 @@
+export interface UmbContentTypeCompositionReferenceModel {
+ unique: string;
+ name: string;
+ icon: string;
+}
+
+export interface UmbContentTypeCompositionRequestModel {
+ unique: string | null;
+ currentPropertyAliases: Array;
+ currentCompositeUniques: Array;
+}
+
+export interface UmbContentTypeCompositionCompatibleModel {
+ unique: string;
+ name: string;
+ icon: string;
+ folderPath: Array;
+ isCompatible: boolean;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts
index 6f9d7d26e5..03701d17e5 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts
@@ -4,3 +4,4 @@ export * from './repository/index.js';
export * from './structure/index.js';
export * from './types.js';
export * from './workspace/index.js';
+export * from './composition/index.js';
From 595652fd9163c63a4fddfa8948176f5389918a17 Mon Sep 17 00:00:00 2001
From: Mads Rasmussen