@@ -157,7 +157,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement {
}
private _disableRedirectHandler() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: 'Disable URL tracker',
content: html`Are you sure you want to disable the URL tracker?`,
color: 'danger',
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts
index 085cd78f5e..683880d36e 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts
@@ -8,7 +8,7 @@ import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { ProblemDetailsModel, DocumentTypeModel } from '@umbraco-cms/backend-api';
import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface';
import { UmbDetailRepository } from '@umbraco-cms/repository';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
type ItemType = DocumentTypeModel;
@@ -27,7 +27,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe
#detailDataSource: UmbDocumentTypeServerDataSource;
#detailStore?: UmbDocumentTypeStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -45,8 +45,8 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe
this.#detailStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -159,7 +159,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe
if (!error) {
const notification = { data: { message: `Document created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -181,7 +181,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe
if (!error) {
const notification = { data: { message: `Document saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -207,7 +207,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe
if (!error) {
const notification = { data: { message: `Document deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts
index 1906d62454..7b38c47233 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts
@@ -19,7 +19,7 @@ export class UmbDocumentTypeStore extends UmbStoreBase {
* @memberof UmbDocumentTypeStore
*/
constructor(host: UmbControllerHostInterface) {
- super(host, UmbDocumentTypeStore.name);
+ super(host, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN.toString());
}
/**
@@ -51,5 +51,5 @@ export class UmbDocumentTypeStore extends UmbStoreBase {
}
export const UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken
(
- UmbDocumentTypeStore.name
+ 'UmbDocumentTypeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts
index b18c51f11a..0f1e5b38ca 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts
@@ -21,5 +21,5 @@ export class UmbDocumentTypeTreeStore extends UmbTreeStoreBase {
}
export const UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbDocumentTypeTreeStore.name
+ 'UmbDocumentTypeTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts
index bc9ff169a6..fd5c9537ea 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts
@@ -6,7 +6,7 @@ import type { UmbWorkspaceEntityElement } from '../../../shared/components/works
import { UmbWorkspaceDocumentTypeContext } from './document-type-workspace.context';
import type { DocumentTypeModel } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
@customElement('umb-document-type-workspace')
export class UmbDocumentTypeWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement {
@@ -51,13 +51,13 @@ export class UmbDocumentTypeWorkspaceElement extends UmbLitElement implements Um
@state()
private _documentType?: DocumentTypeModel;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
- this._modalService = instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
this.observe(this._workspaceContext.data, (data) => {
@@ -86,7 +86,7 @@ export class UmbDocumentTypeWorkspaceElement extends UmbLitElement implements Um
}
private async _handleIconClick() {
- const modalHandler = this._modalService?.iconPicker();
+ const modalHandler = this._modalContext?.iconPicker();
modalHandler?.onClose().then((saved) => {
if (saved) this._workspaceContext?.setIcon(saved.icon);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts
index 7e0188a602..42b9f407c9 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts
@@ -8,7 +8,7 @@ import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { ProblemDetailsModel, DocumentModel } from '@umbraco-cms/backend-api';
import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface';
import { UmbDetailRepository } from '@umbraco-cms/repository';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
type ItemType = DocumentModel;
@@ -27,7 +27,7 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi
#detailDataSource: UmbDocumentServerDataSource;
#detailStore?: UmbDocumentStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -45,8 +45,8 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi
this.#detailStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -154,7 +154,7 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -176,7 +176,7 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -202,7 +202,7 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts
index 274ef33130..9f7df54d24 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts
@@ -4,6 +4,8 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
+export const UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDocumentStore');
+
/**
* @export
* @class UmbDocumentDetailStore
@@ -19,7 +21,7 @@ export class UmbDocumentStore extends UmbStoreBase {
* @memberof UmbDocumentDetailStore
*/
constructor(host: UmbControllerHostInterface) {
- super(host, UmbDocumentStore.name);
+ super(host, UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
/**
@@ -49,5 +51,3 @@ export class UmbDocumentStore extends UmbStoreBase {
this.#data.remove(uniques);
}
}
-
-export const UMB_DOCUMENT_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbDocumentStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts
index 8cc4cd5aa3..71a563ed34 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts
@@ -20,5 +20,5 @@ export class UmbDocumentTreeStore extends UmbTreeStoreBase {
}
export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbDocumentTreeStore.name
+ 'UmbDocumentTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts
index cce9a30c50..fe520cf1d6 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts
@@ -100,6 +100,10 @@ export class UmbDocumentWorkspaceContext
this.#activeVariantsInfo.next(activeVariants);
}
+ openSplitView(culture: string | null, segment: string | null) {
+ this.setActiveVariant(1, culture, segment);
+ }
+
getVariant(variantId: UmbVariantId) {
return this.#draft.getValue()?.variants?.find((x) => variantId.compare(x));
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts
index ba0ffef964..e4fb29c8ad 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts
@@ -14,7 +14,7 @@ export class UmbDocumentWorkspaceElement extends UmbLitElement implements UmbWor
UUITextStyles,
css`
:host {
- display: block;
+ display: flex;
width: 100%;
height: 100%;
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts
index aadbc4f820..94480a883c 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts
@@ -160,7 +160,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement {
this._routerPath = event.target.absoluteRouterPath;
}}
@change=${(event: UmbRouterSlotChangeEvent) => {
- this._activePath = event.target.localActiveViewPath || '';
+ this._activePath = event.target.absoluteActiveViewPath || '';
}}>
`;
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts
index c6dfb6cbd7..841ca9822a 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts
@@ -16,7 +16,7 @@ export class UmbMediaTypeDetailStore
#data = new ArrayState([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
- super(host, UmbMediaTypeDetailStore.name);
+ super(host, UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
append(mediaType: MediaTypeDetails) {
@@ -25,9 +25,9 @@ export class UmbMediaTypeDetailStore
remove(uniques: string[]) {
this.#data.remove(uniques);
- }
+ }
}
export const UMB_MEDIA_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMediaTypeDetailStore.name
-);
\ No newline at end of file
+ 'UmbMediaTypeDetailStore'
+);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts
index bb3e3ff038..1ded02b0fe 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts
@@ -6,7 +6,7 @@ import { ProblemDetailsModel } from '@umbraco-cms/backend-api';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import type { MediaTypeDetails } from '@umbraco-cms/models';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
import { UmbTreeRepository, RepositoryTreeDataSource } from '@umbraco-cms/repository';
export class UmbMediaTypeRepository implements UmbTreeRepository {
@@ -20,7 +20,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository {
#detailSource: UmbMediaTypeDetailServerDataSource;
#detailStore?: UmbMediaTypeDetailStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -38,8 +38,8 @@ export class UmbMediaTypeRepository implements UmbTreeRepository {
this.#treeStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -144,7 +144,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository {
if (!error) {
const notification = { data: { message: `Media type '${mediaType.name}' saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -169,7 +169,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository {
if (!error) {
const notification = { data: { message: `Media type '${mediaType.name}' created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
return { data, error };
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts
index fa1d2ab1dc..0f82fd5a61 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts
@@ -21,5 +21,5 @@ export class UmbMediaTypeTreeStore extends UmbTreeStoreBase {
}
export const UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMediaTypeTreeStore.name
+ 'UmbMediaTypeTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts
index 03ae8d0722..30ae1aeac3 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts
@@ -2,22 +2,22 @@ import type { UmbMediaRepository } from '../../repository/media.repository';
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase {
- #modalService?: UmbModalService;
+ #modalContext?: UmbModalContext;
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) {
super(host, repositoryAlias, selection);
- new UmbContextConsumerController(host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#modalService = instance;
+ new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this.#modalContext = instance;
});
}
async execute() {
// TODO: the picker should be single picker by default
- const modalHandler = this.#modalService?.mediaPicker({ selection: [], multiple: false });
+ const modalHandler = this.#modalContext?.mediaPicker({ selection: [], multiple: false });
const selection = await modalHandler?.onClose();
const destination = selection[0];
await this.repository?.move(this.selection, destination);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/trash/trash.action.ts
index b767646fee..672bcc49b8 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/trash/trash.action.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/trash/trash.action.ts
@@ -3,29 +3,29 @@ import type { UmbMediaRepository } from '../../repository/media.repository';
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase {
- #modalService?: UmbModalService;
+ #modalContext?: UmbModalContext;
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) {
super(host, repositoryAlias, selection);
- new UmbContextConsumerController(host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#modalService = instance;
+ new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this.#modalContext = instance;
});
}
async execute() {
// TODO: show error
- if (!this.#modalService || !this.repository) return;
+ if (!this.#modalContext || !this.repository) return;
// TODO: should we subscribe in cases like this?
const { data } = await this.repository.requestTreeItems(this.selection);
if (data) {
// TODO: use correct markup
- const modalHandler = this.#modalService?.confirm({
+ const modalHandler = this.#modalContext?.confirm({
headline: `Deleting ${this.selection.length} items`,
content: html`
This will delete the following files:
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.detail.store.ts
index 7519f79e8f..9130ba65bf 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.detail.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.detail.store.ts
@@ -4,6 +4,8 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
+export const UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbMediaDetailStore');
+
/**
* @export
* @class UmbMediaDetailStore
@@ -19,7 +21,7 @@ export class UmbMediaDetailStore extends UmbStoreBase {
* @memberof UmbMediaDetailStore
*/
constructor(host: UmbControllerHostInterface) {
- super(host, UmbMediaDetailStore.name);
+ super(host, UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
/**
@@ -40,5 +42,3 @@ export class UmbMediaDetailStore extends UmbStoreBase {
this.#data.remove(uniques);
}
}
-
-export const UMB_MEDIA_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbMediaDetailStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts
index 831af8b644..c5fd5107e7 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts
@@ -9,7 +9,7 @@ import { ProblemDetailsModel } from '@umbraco-cms/backend-api';
import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface';
import { UmbDetailRepository } from '@umbraco-cms/repository';
import type { MediaDetails } from '@umbraco-cms/models';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
type ItemDetailType = MediaDetails;
@@ -28,7 +28,7 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor
#detailDataSource: UmbMediaDetailServerDataSource;
#detailStore?: UmbMediaDetailStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -46,8 +46,8 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor
this.#detailStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -152,7 +152,7 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor
if (!error) {
const notification = { data: { message: `Media created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -174,7 +174,7 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor
if (!error) {
const notification = { data: { message: `Document saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -200,7 +200,7 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor
if (!error) {
const notification = { data: { message: `Document deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts
index 572b71a06f..07299c5e8f 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts
@@ -4,6 +4,8 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
+export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbMediaTreeStore');
+
/**
* @export
* @class UmbMediaTreeStore
@@ -87,5 +89,3 @@ export class UmbMediaTreeStore extends UmbStoreBase {
return this.#data.getObservablePart((items) => items.filter((item) => keys.includes(item.key ?? '')));
}
}
-
-export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbMediaTreeStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.detail.store.ts
index 64c5973d5d..ce6053cbd6 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.detail.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.detail.store.ts
@@ -4,6 +4,10 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbStoreBase } from '@umbraco-cms/store';
+export const UMB_MEMBER_GROUP_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(
+ 'UmbMemberGroupDetailStore'
+);
+
/**
* @export
* @class UmbMemberGroupDetailStore
@@ -16,7 +20,7 @@ export class UmbMemberGroupDetailStore
#data = new ArrayState([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
- super(host, UmbMemberGroupDetailStore.name);
+ super(host, UMB_MEMBER_GROUP_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
append(memberGroup: MemberGroupDetails) {
@@ -25,9 +29,5 @@ export class UmbMemberGroupDetailStore
remove(uniques: string[]) {
this.#data.remove(uniques);
- }
+ }
}
-
-export const UMB_MEMBER_GROUP_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMemberGroupDetailStore.name
-);
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts
index 7f273071e5..80e323c25e 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts
@@ -3,7 +3,7 @@ import { UmbMemberGroupDetailServerDataSource } from './sources/member-group.det
import { UmbMemberGroupDetailStore, UMB_MEMBER_GROUP_DETAIL_STORE_CONTEXT_TOKEN } from './member-group.detail.store';
import { MemberGroupTreeServerDataSource } from './sources/member-group.tree.server.data';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import type { MemberGroupDetails } from '@umbraco-cms/models';
import { ProblemDetailsModel } from '@umbraco-cms/backend-api';
@@ -21,7 +21,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
#detailSource: UmbMemberGroupDetailServerDataSource;
#detailStore?: UmbMemberGroupDetailStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -37,8 +37,8 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
this.#detailStore = instance;
});
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
});
}
@@ -123,7 +123,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
if (!error) {
const notification = { data: { message: `Member group '${detail.name}' created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
return { data, error };
@@ -141,7 +141,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
if (!error) {
const notification = { data: { message: `Member group '${memberGroup.name} saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
this.#detailStore?.append(memberGroup);
@@ -162,7 +162,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep
if (!error) {
const notification = { data: { message: `Document deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts
index a1e5a29659..bad706d967 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts
@@ -91,5 +91,5 @@ export class UmbMemberGroupTreeStore extends UmbStoreBase {
}
export const UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMemberGroupTreeStore.name
+ 'UmbMemberGroupTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.detail.store.ts
index bba1a580fa..ebeb8af837 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.detail.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.detail.store.ts
@@ -16,7 +16,7 @@ export class UmbMemberTypeDetailStore
#data = new ArrayState([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
- super(host, UmbMemberTypeDetailStore.name);
+ super(host, UMB_MEMBER_TYPE_DETAIL_STORE_CONTEXT_TOKEN.toString());
}
append(MemberType: MemberTypeDetails) {
@@ -25,9 +25,9 @@ export class UmbMemberTypeDetailStore
remove(uniques: string[]) {
this.#data.remove(uniques);
- }
+ }
}
export const UMB_MEMBER_TYPE_DETAIL_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMemberTypeDetailStore.name
-);
\ No newline at end of file
+ 'UmbMemberTypeDetailStore'
+);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts
index c03d4eeb44..ec294e6ee6 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts
@@ -6,7 +6,7 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { RepositoryTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/repository';
import { ProblemDetailsModel } from '@umbraco-cms/backend-api';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
import type { MemberTypeDetails } from '@umbraco-cms/models';
// TODO => use correct type when available
@@ -23,7 +23,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo
#detailSource: UmbMemberTypeDetailServerDataSource;
#detailStore?: UmbMemberTypeDetailStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -41,8 +41,8 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo
this.#treeStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -140,7 +140,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo
if (!error) {
const notification = { data: { message: `Member type deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -167,7 +167,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo
if (!error) {
const notification = { data: { message: `Member type '${detail.name}' saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -192,7 +192,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo
if (!error) {
const notification = { data: { message: `Member type '${detail.name}' created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
return { data, error };
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts
index 7e3322625d..3b87c4988f 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts
@@ -16,5 +16,5 @@ export class UmbMemberTypeTreeStore extends UmbTreeStoreBase {
}
export const UMB_MEMBER_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbMemberTypeTreeStore.name
+ 'UmbMemberTypeTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts
index 685c54ee25..db2744a5ed 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts
@@ -1,7 +1,7 @@
import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from './member.tree.store';
import { MemberTreeServerDataSource } from './sources/member.tree.server.data';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { UmbTreeRepository } from '@umbraco-cms/repository';
import { ProblemDetailsModel } from '@umbraco-cms/backend-api';
@@ -10,7 +10,7 @@ export class UmbMemberRepository implements UmbTreeRepository {
#host: UmbControllerHostInterface;
#dataSource: MemberTreeServerDataSource;
#treeStore?: UmbMemberTreeStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
#initResolver?: () => void;
#initialized = false;
@@ -24,8 +24,8 @@ export class UmbMemberRepository implements UmbTreeRepository {
this.#checkIfInitialized();
});
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
this.#checkIfInitialized();
});
}
@@ -35,7 +35,7 @@ export class UmbMemberRepository implements UmbTreeRepository {
});
#checkIfInitialized() {
- if (this.#treeStore && this.#notificationService) {
+ if (this.#treeStore && this.#notificationContext) {
this.#initialized = true;
this.#initResolver?.();
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts
index dad2c697c0..c3ea8a4e18 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts
@@ -4,6 +4,8 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import type { UmbControllerHostInterface } from '@umbraco-cms/controller';
+export const UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbMemberTreeStore');
+
/**
* @export
* @class UmbMemberTreeStore
@@ -89,5 +91,3 @@ export class UmbMemberTreeStore extends UmbStoreBase {
return this.#data.getObservablePart((items) => items.filter((item) => keys.includes(item.key ?? '')));
}
}
-
-export const UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbMemberTreeStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/actions/action-member-delete.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/actions/action-member-delete.element.ts
index ff96119d59..e50dfad09b 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/actions/action-member-delete.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/actions/action-member-delete.element.ts
@@ -1,7 +1,7 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../core/modal';
import UmbTreeItemActionElement from '../../../../shared/components/tree/action/tree-item-action.element';
import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from '../../repository/member.tree.store';
@@ -9,14 +9,14 @@ import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from '../../r
export default class UmbTreeActionMemberDeleteElement extends UmbTreeItemActionElement {
static styles = [UUITextStyles, css``];
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
private _memberTreeStore?: UmbMemberTreeStore;
connectedCallback(): void {
super.connectedCallback();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._modalService = modalService;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
this.consumeContext(UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN, (memberTreeStore) => {
@@ -25,7 +25,7 @@ export default class UmbTreeActionMemberDeleteElement extends UmbTreeItemActionE
}
private _handleLabelClick() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: `Delete ${this._activeTreeItem?.name ?? 'item'}`,
content: 'Are you sure you want to delete this item?',
color: 'danger',
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts
index 3cafbfe2cc..26b897a91b 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts
@@ -1,24 +1,295 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
-import { css, html, LitElement } from 'lit';
-import { customElement } from 'lit/decorators.js';
+import { UUIBooleanInputEvent, UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui';
+import { css, html, nothing } from 'lit';
+import { customElement, property, query, state } from 'lit/decorators.js';
+import { ifDefined } from 'lit-html/directives/if-defined.js';
+import { UmbInputDocumentPickerElement } from '../../../shared/components/input-document-picker/input-document-picker.element';
+import { UmbInputMediaPickerElement } from '../../../shared/components/input-media-picker/input-media-picker.element';
+import { UmbInputLanguagePickerElement } from '../../../shared/components/input-language-picker/input-language-picker.element';
+import { UmbLitElement } from '@umbraco-cms/element';
+import { PackageDefinitionModel, PackageResource } from '@umbraco-cms/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/resources';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
@customElement('umb-workspace-package-builder')
-export class UmbWorkspacePackageBuilderElement extends LitElement {
+export class UmbWorkspacePackageBuilderElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
:host {
display: block;
- width: 100%;
height: 100%;
}
+
+ .header {
+ margin: 0 var(--uui-size-layout-1);
+ display: flex;
+ gap: var(--uui-size-space-4);
+ }
+
+ uui-box {
+ margin: var(--uui-size-layout-1);
+ }
+
+ uui-checkbox {
+ margin-top: var(--uui-size-space-4);
+ }
`,
];
+ @property()
+ entityKey?: string;
+
+ @state()
+ private _package: PackageDefinitionModel = {};
+
+ @query('#package-name-input')
+ private _packageNameInput!: UUIInputElement;
+
+ private _notificationContext?: UmbNotificationContext;
+
+ constructor() {
+ super();
+ this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this._notificationContext = instance;
+ });
+ }
+
+ connectedCallback(): void {
+ super.connectedCallback();
+ if (this.entityKey) this.#getPackageCreated();
+ }
+
+ async #getPackageCreated() {
+ if (!this.entityKey) return;
+ const { data } = await tryExecuteAndNotify(this, PackageResource.getPackageCreatedByKey({ key: this.entityKey }));
+ if (!data) return;
+ this._package = data as PackageDefinitionModel;
+ }
+
+ async #download() {
+ if (!this._package?.key) return;
+ const response = await tryExecuteAndNotify(
+ this,
+ PackageResource.getPackageCreatedByKeyDownload({ key: this._package.key })
+ );
+ }
+
+ #nameDefined() {
+ const valid = this._packageNameInput.checkValidity();
+ if (!valid) this._notificationContext?.peek('danger', { data: { message: 'Package missing a name' } });
+ return valid;
+ }
+
+ async #save() {
+ if (!this.#nameDefined()) return;
+ const response = await tryExecuteAndNotify(
+ this,
+ PackageResource.postPackageCreated({ requestBody: this._package })
+ );
+ if (!response.data || response.error) return;
+ this._package = response.data as PackageDefinitionModel;
+ this.#navigateBack();
+ }
+
+ async #update() {
+ if (!this.#nameDefined()) return;
+ if (!this._package?.key) return;
+ const response = await tryExecuteAndNotify(
+ this,
+ PackageResource.putPackageCreatedByKey({ key: this._package.key, requestBody: this._package })
+ );
+
+ if (response.error) return;
+ this.#navigateBack();
+ }
+
+ #navigateBack() {
+ window.history.pushState({}, '', '/section/packages/view/created');
+ }
+
render() {
- return html`PACKAGE BUILDER `;
+ return html`
+
+ ${this.#renderHeader()}
+ ${this.#renderEditors()}
+ ${this.#renderActions()}
+
+ `;
+ }
+
+ #renderHeader() {
+ return html``;
+ }
+
+ #renderActions() {
+ return html`
+ ${this._package?.key
+ ? html`
+ Download
+ `
+ : nothing}
+
+ Save
+
+
`;
+ }
+
+ #renderEditors() {
+ return html`
+ ${this.#renderContentSection()}
+
+
+ ${this.#renderMediaSection()}
+
+
+
+ ${this.#renderDocumentTypeSection()}
+
+
+
+ ${this.#renderMediaTypeSection()}
+
+
+
+ ${this.#renderLanguageSection()}
+
+
+
+ ${this.#renderDictionarySection()}
+
+
+
+ ${this.#renderDataTypeSection()}
+
+
+
+ ${this.#renderTemplateSection()}
+
+
+
+ ${this.#renderStylesheetsSection()}
+
+
+
+ ${this.#renderScriptsSection()}
+
+
+
+ ${this.#renderPartialViewSection()}
+ `;
+ }
+
+ #renderContentSection() {
+ return html`
+
+
+ (this._package.contentNodeId = (e.target as UmbInputDocumentPickerElement).selectedKeys[0])}">
+
+ (this._package.contentLoadChildNodes = e.target.checked)}">
+ Include child nodes
+
+
+ `;
+ }
+
+ #renderMediaSection() {
+ return html`
+
+
+ (this._package.mediaKeys = (
+ e.target as UmbInputMediaPickerElement
+ ).selectedKeys)}">
+ (this._package.mediaLoadChildNodes = e.target.checked)}">
+ Include child nodes
+
+
+ `;
+ }
+
+ #renderDocumentTypeSection() {
+ return html`
+
+
`;
+ }
+
+ #renderMediaTypeSection() {
+ return html`
+
+
`;
+ }
+
+ #renderLanguageSection() {
+ return html`
+ {
+ this._package.languages = (e.target as UmbInputLanguagePickerElement).selectedIsoCodes;
+ }}">
+
`;
+ }
+
+ #renderDictionarySection() {
+ return html`
+
+
`;
+ }
+
+ #renderDataTypeSection() {
+ return html`
+
+
`;
+ }
+
+ #renderTemplateSection() {
+ return html`
+
+
`;
+ }
+
+ #renderStylesheetsSection() {
+ return html`
+
+
`;
+ }
+
+ #renderScriptsSection() {
+ return html`
+
+
`;
+ }
+
+ #renderPartialViewSection() {
+ return html`
+
+
`;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-repo/workspace/workspace-package.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-repo/workspace/workspace-package.element.ts
index a11b56636c..466915fa9d 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-repo/workspace/workspace-package.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-repo/workspace/workspace-package.element.ts
@@ -1,22 +1,55 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
-import { customElement } from 'lit/decorators.js';
+import { customElement, property, state } from 'lit/decorators.js';
+import { path, stripSlash } from 'router-slot';
@customElement('umb-workspace-package')
export class UmbWorkspacePackageElement extends LitElement {
static styles = [
UUITextStyles,
css`
- :host {
- display: block;
- width: 100%;
- height: 100%;
+ .header {
+ display: flex;
+ font-size: var(--uui-type-h5-size);
}
`,
];
+ @property()
+ entityKey?: string;
+
+ @state()
+ _package?: any;
+
+ connectedCallback(): void {
+ super.connectedCallback();
+ if (this.entityKey) this._getPackageData();
+ }
+
+ private _getPackageData() {
+ //TODO
+
+ this._package = {
+ key: this.entityKey,
+ name: 'A created package',
+ };
+ }
+
+ private _navigateBack() {
+ window.history.pushState({}, '', '/section/packages/view/installed');
+ }
+
+ private _renderHeader() {
+ return html``;
+ }
+
render() {
- return html`PACKAGE Workspace `;
+ return html` ${this._renderHeader()} `;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts
index 24d577c5be..44beef5a18 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts
@@ -1,8 +1,8 @@
-import { html } from 'lit';
+import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { IRoute, IRoutingInfo } from 'router-slot';
-import type { ManifestWorkspace } from '@umbraco-cms/models';
-import { createExtensionElement , umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
+import type { ManifestTree, ManifestWorkspace } from '@umbraco-cms/models';
+import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-created-packages-section-view')
@@ -12,9 +12,10 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement {
private _workspaces: Array = [];
+ private _trees: Array = [];
+
constructor() {
super();
-
this.observe(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this._workspaces = workspaceExtensions;
this._createRoutes();
@@ -48,7 +49,7 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement {
routes.push({
path: '**',
- redirectTo: 'section/packages/view/created/overview', //TODO: this should be dynamic
+ redirectTo: 'overview',
});
this._routes = routes;
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-item.element.ts
deleted file mode 100644
index 941a137a86..0000000000
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-item.element.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { html, LitElement } from 'lit';
-import { customElement, property } from 'lit/decorators.js';
-
-@customElement('umb-packages-created-item')
-export class UmbPackagesCreatedItem extends LitElement {
- @property({ type: Object })
- package!: any;
-
- render() {
- return html`
-
- `;
- }
-
- private _onClick() {
- window.history.pushState({}, '', `/section/packages/view/created/packageBuilder/${this.package.key}`);
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- 'umb-packages-created-item': UmbPackagesCreatedItem;
- }
-}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts
index b57d787db1..20b33ad3f8 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts
@@ -1,35 +1,158 @@
-import { html, LitElement } from 'lit';
+import { html, css, nothing } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
-
-import './packages-created-item.element';
+import { UUIPaginationEvent } from '@umbraco-ui/uui';
+import { PackageDefinitionModel, PackageResource } from '@umbraco-cms/backend-api';
+import { UmbLitElement } from '@umbraco-cms/element';
+import { tryExecuteAndNotify } from '@umbraco-cms/resources';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
@customElement('umb-packages-created-overview')
-export class UmbPackagesCreatedOverviewElement extends LitElement {
- // TODO: implement call to backend
- // TODO: add correct model for created packages
- @state()
- private _createdPackages: any[] = [
- {
- alias: 'my.package',
- key: '2a0181ec-244b-4068-a1d7-2f95ed7e6da6',
- name: 'A created package',
- plans: [],
- version: '1.0.0',
- },
+export class UmbPackagesCreatedOverviewElement extends UmbLitElement {
+ static styles = [
+ css`
+ :host {
+ display: block;
+ margin: var(--uui-size-layout-1);
+ }
+ uui-box {
+ margin: var(--uui-size-space-5) 0;
+ padding-bottom: var(--uui-size-space-1);
+ }
+
+ .no-packages {
+ display: flex;
+ justify-content: space-around;
+ }
+ uui-pagination {
+ display: inline-block;
+ }
+
+ .pagination,
+ .loading {
+ display: flex;
+ justify-content: center;
+ }
+ `,
];
+ private take = 20;
+
+ @state()
+ private _loading = true;
+
+ @state()
+ private _createdPackages: PackageDefinitionModel[] = [];
+
+ @state()
+ private _currentPage = 1;
+
+ @state()
+ private _total?: number;
+
+ private _modalContext?: UmbModalContext;
+
+ constructor() {
+ super();
+ }
+
+ connectedCallback(): void {
+ super.connectedCallback();
+ this.#getPackages();
+
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
+ });
+ }
+
+ async #getPackages() {
+ const skip = this._currentPage * this.take - this.take;
+ const { data } = await tryExecuteAndNotify(this, PackageResource.getPackageCreated({ skip, take: this.take }));
+ if (data) {
+ this._total = data.total;
+ this._createdPackages = data.items;
+ }
+ this._loading = false;
+ }
+
+ #createNewPackage() {
+ window.history.pushState({}, '', `/section/packages/view/created/package-builder`);
+ }
+
render() {
- return html`
+ return html`
+ Create package
+
+ ${this._loading ? html`` : this.#renderCreatedPackages()}
+ ${this.#renderPagination()}`;
+ }
+
+ #renderCreatedPackages() {
+ if (!this._createdPackages.length) return html`No packages have been created yet
`;
+
+ return html`
${repeat(
this._createdPackages,
(item) => item.key,
- (item) => html``
+ (item) => this.#renderPackageItem(item)
)}
`;
}
+
+ #renderPackageItem(p: PackageDefinitionModel) {
+ return html` this.#packageBuilder(p)}">
+
+ this.#deletePackage(p)} label="Delete package">
+
+
+
+ `;
+ }
+
+ #packageBuilder(p: PackageDefinitionModel) {
+ if (!p.key) return;
+ window.history.pushState({}, '', `/section/packages/view/created/package-builder/${p.key}`);
+ }
+
+ #renderPagination() {
+ if (!this._total) return nothing;
+ const totalPages = Math.ceil(this._total / this.take);
+ if (totalPages <= 1) return nothing;
+ return html``;
+ }
+
+ #onPageChange(event: UUIPaginationEvent) {
+ if (this._currentPage === event.target.current) return;
+ this._currentPage = event.target.current;
+ this.#getPackages();
+ }
+
+ async #deletePackage(p: PackageDefinitionModel) {
+ if (!p.key) return;
+ const modalHandler = this._modalContext?.confirm({
+ color: 'danger',
+ headline: `Remove ${p.name}?`,
+ content: 'Are you sure you want to delete this package',
+ confirmLabel: 'Delete',
+ });
+
+ const deleteConfirmed = await modalHandler?.onClose().then(({ confirmed }: any) => {
+ return confirmed;
+ });
+
+ if (!deleteConfirmed == true) return;
+
+ const { error } = await tryExecuteAndNotify(this, PackageResource.deletePackageCreatedByKey({ key: p.key }));
+ if (error) return;
+ const index = this._createdPackages.findIndex((x) => x.key === p.key);
+ this._createdPackages.splice(index, 1);
+ this.requestUpdate();
+ }
}
export default UmbPackagesCreatedOverviewElement;
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
index 23025cb334..3df5afd999 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
@@ -1,37 +1,64 @@
-import { html, nothing } from 'lit';
-import { customElement, property, state } from 'lit/decorators.js';
+import { html, css, nothing } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
+import { customElement, property, state } from 'lit/decorators.js';
import { firstValueFrom, map } from 'rxjs';
+import { UUIButtonState } from '@umbraco-ui/uui';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../core/modal';
import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
-import type { ManifestPackageView, UmbPackage } from '@umbraco-cms/models';
+import type { ManifestPackageView } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
+import { tryExecuteAndNotify } from '@umbraco-cms/resources';
+import { PackageResource } from '@umbraco-cms/backend-api';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
@customElement('umb-installed-packages-section-view-item')
-export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
- @property({ type: Object })
- package!: UmbPackage;
+export class UmbInstalledPackagesSectionViewItem extends UmbLitElement {
+ static styles = css`
+ :host {
+ display: flex;
+ min-height: 47px;
+ }
+ `;
+
+ @property()
+ name?: string;
+
+ @property()
+ version?: string;
+
+ @property()
+ hasPendingMigrations = false;
+
+ @property()
+ customIcon?: string;
+
+ @state()
+ private _migrationButtonState?: UUIButtonState;
@state()
private _packageView?: ManifestPackageView;
- private _umbModalService?: UmbModalService;
+ private _notificationContext?: UmbNotificationContext;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._umbModalService = modalService;
+ this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this._notificationContext = instance;
+ });
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
connectedCallback(): void {
super.connectedCallback();
- if (this.package.name?.length) {
- this.findPackageView(this.package.name);
+ if (this.name?.length) {
+ this.findPackageView(this.name);
}
}
@@ -52,18 +79,51 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
this._packageView = views[0];
}
+ async _onMigration() {
+ if (!this.name) return;
+ const modalHandler = this._modalContext?.confirm({
+ color: 'positive',
+ headline: `Run migrations for ${this.name}?`,
+ content: `Do you want to start run migrations for ${this.name}`,
+ confirmLabel: 'Run migrations',
+ });
+
+ const migrationConfirmed = await modalHandler?.onClose().then(({ confirmed }: any) => {
+ return confirmed;
+ });
+
+ if (!migrationConfirmed == true) return;
+ this._migrationButtonState = 'waiting';
+ const { error } = await tryExecuteAndNotify(
+ this,
+ PackageResource.postPackageByNameRunMigration({ name: this.name })
+ );
+ if (error) return;
+ this._notificationContext?.peek('positive', { data: { message: 'Migrations completed' } });
+ this._migrationButtonState = 'success';
+ this.hasPendingMigrations = false;
+ }
+
render() {
return html`
-
-
- ${this._packageView
+
+ ${this.customIcon ? html`` : nothing}
+
+ ${this.hasPendingMigrations
? html``
+ label="Run pending package migrations">
+ Run pending migrations
+ `
: nothing}
-
+
`;
}
@@ -81,12 +141,16 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
return;
}
- this._umbModalService?.open(element, { data: this.package, size: 'small', type: 'sidebar' });
+ this._modalContext?.open(element, {
+ data: { name: this.name, version: this.version },
+ size: 'full',
+ type: 'sidebar',
+ });
}
}
declare global {
interface HTMLElementTagNameMap {
- 'umb-installed-packages-section-view-item': UmbInstalledPackagesSectionViewItemElement;
+ 'umb-installed-packages-section-view-item': UmbInstalledPackagesSectionViewItem;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts
index 256760912e..08449e0cad 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts
@@ -1,23 +1,56 @@
-import { html } from 'lit';
+import { html, css, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
+import { combineLatest } from 'rxjs';
+import { UUITextStyles } from '@umbraco-ui/uui-css';
import { UmbPackageRepository } from '../../../repository/package.repository';
-import type { UmbPackage } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
+import type { UmbPackageWithMigrationStatus } from '@umbraco-cms/models';
import './installed-packages-section-view-item.element';
@customElement('umb-installed-packages-section-view')
export class UmbInstalledPackagesSectionView extends UmbLitElement {
- @state()
- private _installedPackages: UmbPackage[] = [];
+ static styles = [
+ UUITextStyles,
+ css`
+ :host {
+ display: block;
+ margin: var(--uui-size-layout-1);
+ }
+ uui-box {
+ margin-top: var(--uui-size-space-5);
+ padding-bottom: var(--uui-size-space-1);
+ }
- private repository: UmbPackageRepository;
+ umb-installed-packages-section-view-item {
+ padding: var(--uui-size-space-3) 0 var(--uui-size-space-2);
+ }
+
+ umb-installed-packages-section-view-item:not(:first-child) {
+ border-top: 1px solid var(--uui-color-border, #d8d7d9);
+ }
+
+ .no-packages {
+ display: flex;
+ justify-content: space-around;
+ flex-direction: column;
+ align-items: center;
+ }
+ `,
+ ];
+
+ @state()
+ private _installedPackages: UmbPackageWithMigrationStatus[] = [];
+
+ @state()
+ private _migrationPackages: UmbPackageWithMigrationStatus[] = [];
+
+ #packageRepository: UmbPackageRepository;
constructor() {
super();
-
- this.repository = new UmbPackageRepository(this);
+ this.#packageRepository = new UmbPackageRepository(this);
}
firstUpdated() {
@@ -28,20 +61,77 @@ export class UmbInstalledPackagesSectionView extends UmbLitElement {
* Fetch the installed packages from the server
*/
private async _loadInstalledPackages() {
- const package$ = await this.repository.rootItems();
- package$.subscribe((packages) => {
- this._installedPackages = packages.filter((p) => !!p.name);
+ const data = await Promise.all([this.#packageRepository.rootItems(), this.#packageRepository.migrations()]);
+
+ const [package$, migration$] = data;
+
+ combineLatest([package$, migration$]).subscribe(([packages, migrations]) => {
+ this._installedPackages = packages.map((p) => {
+ const migration = migrations.find((m) => m.packageName === p.name);
+ if (migration) {
+ // Remove that migration from the list
+ migrations = migrations.filter((m) => m.packageName !== p.name);
+ }
+
+ return {
+ ...p,
+ hasPendingMigrations: migration?.hasPendingMigrations ?? false,
+ };
+ });
+
+ this._migrationPackages = [
+ ...migrations.map((m) => ({
+ name: m.packageName,
+ hasPendingMigrations: m.hasPendingMigrations ?? false,
+ })),
+ ];
+ /*this._installedPackages = [
+ ...this._installedPackages,
+ ...migrations.map((m) => ({
+ name: m.packageName,
+ hasPendingMigrations: m.hasPendingMigrations ?? false,
+ })),
+ ];*/
});
}
render() {
- return html`
+ if (this._installedPackages.length) return html`${this._renderCustomMigrations()} ${this._renderInstalled()} `;
+ return html`
+
No packages have been installed
+
+ Browse through the available packages using the 'Packages' icon in the top right of your screen
+
+
`;
+ }
+
+ private _renderInstalled() {
+ return html`
${repeat(
this._installedPackages,
(item) => item.name,
- (item) =>
- html``
+ (item) => html``
+ )}
+
+ `;
+ }
+
+ private _renderCustomMigrations() {
+ if (!this._migrationPackages) return;
+ return html`
+
+ ${repeat(
+ this._migrationPackages,
+ (item) => item.name,
+ (item) => html``
)}
`;
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts
index ec54c779b4..f28c63c378 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts
@@ -3,6 +3,8 @@ import { UmbPackageServerDataSource } from './sources/package.server.data';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { ManifestBase } from '@umbraco-cms/extensions-registry';
+import { isManifestJSType } from "@umbraco-cms/extensions-api";
+import { OpenAPI } from "@umbraco-cms/backend-api";
// TODO: Figure out if we should base stores like this on something more generic for "collections" rather than trees.
@@ -14,6 +16,7 @@ export class UmbPackageRepository {
#init!: Promise;
#packageStore?: UmbPackageStore;
#packageSource: UmbPackageServerDataSource;
+ #apiBaseUrl = OpenAPI.BASE;
constructor(host: UmbControllerHostInterface) {
this.#packageSource = new UmbPackageServerDataSource(host);
@@ -39,7 +42,8 @@ export class UmbPackageRepository {
const { data: packages } = await this.#packageSource.getRootItems();
if (packages) {
- store.appendItems(packages);
+ // Append packages to the store but only if they have a name
+ store.appendItems(packages.filter((p) => p.name?.length));
const extensions: ManifestBase[] = [];
packages.forEach((p) => {
@@ -47,6 +51,18 @@ export class UmbPackageRepository {
// Crudely validate that the extension at least follows a basic manifest structure
// Idea: Use `Zod` to validate the manifest
if (this.isManifestBase(e)) {
+
+ /**
+ * Crude check to see if extension is of type "js" since it is safe to assume we do not
+ * need to load any other types of extensions in the backoffice (we need a js file to load)
+ */
+ if (isManifestJSType(e)) {
+ // Add API base url if the js path is relative
+ if (!e.js.startsWith('http')) {
+ e.js = `${this.#apiBaseUrl}${e.js}`;
+ }
+ }
+
extensions.push(e);
}
});
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts
index f581b2045d..18120d46a9 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts
@@ -6,6 +6,8 @@ import type { ManifestBase, UmbPackage } from '@umbraco-cms/models';
import type { PackageMigrationStatusModel } from '@umbraco-cms/backend-api';
import { ArrayState } from '@umbraco-cms/observable-api';
+export const UMB_PACKAGE_STORE_TOKEN = new UmbContextToken('UmbPackageStore');
+
/**
* Store for Packages
* @export
@@ -39,7 +41,7 @@ export class UmbPackageStore extends UmbStoreBase {
* @memberof PackageStore
*/
constructor(host: UmbControllerHostInterface) {
- super(host, UmbPackageStore.name);
+ super(host, UMB_PACKAGE_STORE_TOKEN.toString());
}
/**
@@ -58,5 +60,3 @@ export class UmbPackageStore extends UmbStoreBase {
this.#migrations.append(migrations);
}
}
-
-export const UMB_PACKAGE_STORE_TOKEN = new UmbContextToken(UmbPackageStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts
index 0073576b89..74a3db7ea0 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts
@@ -1,15 +1,16 @@
import { Subject, takeUntil } from 'rxjs';
import { UmbPackageRepository } from './package.repository';
import { UmbController, UmbControllerHostInterface } from '@umbraco-cms/controller';
-import { isManifestJSType, UmbExtensionRegistry } from '@umbraco-cms/extensions-api';
+import { UmbExtensionRegistry } from '@umbraco-cms/extensions-api';
export class UmbServerExtensionController extends UmbController {
+ #host: UmbControllerHostInterface;
#unobserve = new Subject();
#repository: UmbPackageRepository;
constructor(host: UmbControllerHostInterface, private readonly extensionRegistry: UmbExtensionRegistry) {
super(host, UmbServerExtensionController.name);
-
+ this.#host = host;
this.#repository = new UmbPackageRepository(host);
}
@@ -32,13 +33,7 @@ export class UmbServerExtensionController extends UmbController {
)
.subscribe((extensions) => {
extensions.forEach((extension) => {
- /**
- * Crude check to see if extension is of type "js" since it is safe to assume we do not
- * need to load any other types of extensions in the backoffice (we need a js file to load)
- */
- if (isManifestJSType(extension)) {
- this.extensionRegistry.register(extension);
- }
+ this.extensionRegistry.register(extension, this.#host);
});
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts
index e2bdd212fa..251f76608c 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts
@@ -1,8 +1,6 @@
import { PackageResource } from '@umbraco-cms/backend-api';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
-import type { DataSourceResponse, UmbPackage } from '@umbraco-cms/models';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
-import { umbracoPath } from '@umbraco-cms/utils';
/**
* Data source for packages from the server
@@ -15,11 +13,10 @@ export class UmbPackageServerDataSource {
* Get the root items from the server
* @memberof UmbPackageServerDataSource
*/
- getRootItems(): Promise> {
- // TODO: Use real resource when available
+ getRootItems() {
return tryExecuteAndNotify(
this.host,
- fetch(umbracoPath('/package/manifest')).then((res) => res.json())
+ PackageResource.getPackageManifest()
);
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts
index 9518fb409f..64a53e5e3b 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts
@@ -1,7 +1,7 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html } from 'lit';
import { customElement } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-search-header-app')
@@ -16,18 +16,18 @@ export class UmbSearchHeaderApp extends UmbLitElement {
`,
];
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (_instance) => {
- this._modalService = _instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (_instance) => {
+ this._modalContext = _instance;
});
}
#onSearchClick() {
- this._modalService?.search();
+ this._modalContext?.search();
}
render() {
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts
index abdd4e6e72..8e68ea40b5 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts
@@ -1,7 +1,7 @@
import { UmbCultureServerDataSource } from './sources/culture.server.data';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
export class UmbCultureRepository {
#init!: Promise;
@@ -9,7 +9,7 @@ export class UmbCultureRepository {
#dataSource: UmbCultureServerDataSource;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -17,8 +17,8 @@ export class UmbCultureRepository {
this.#dataSource = new UmbCultureServerDataSource(this.#host);
this.#init = Promise.all([
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts
index 3c33a9195b..34c20af5d2 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts
@@ -4,7 +4,7 @@ import { customElement, property, state } from 'lit/decorators.js';
import { UUIButtonState } from '@umbraco-ui/uui-button';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../core/modal';
import './section-view-examine-searchers';
@@ -92,13 +92,13 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement {
@state()
private _loading = true;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (_instance) => {
- this._modalService = _instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (_instance) => {
+ this._modalContext = _instance;
});
this._getIndexData();
@@ -120,7 +120,7 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement {
}
private async _onRebuildHandler() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: `Rebuild ${this.indexName}`,
content: html`
This will cause the index to be rebuilt.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts
index 3b68117159..941f79b998 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts
@@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, nothing } from 'lit';
import { customElement, state, query, property } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../core/modal';
import { SearchResultModel, SearcherResource, FieldModel } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
@@ -101,7 +101,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement {
`,
];
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
@property()
searcherName!: string;
@@ -120,8 +120,8 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement {
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
- this._modalService = instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
@@ -175,7 +175,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement {
}
private _onFieldFilterClick() {
- const modalHandler = this._modalService?.open('umb-modal-layout-fields-settings', {
+ const modalHandler = this._modalContext?.open('umb-modal-layout-fields-settings', {
type: 'sidebar',
size: 'small',
data: { ...this._exposedFields },
@@ -241,7 +241,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement {
look="secondary"
label="Open sidebar to see all fields"
@click="${() =>
- this._modalService?.open('umb-modal-layout-fields-viewer', {
+ this._modalContext?.open('umb-modal-layout-fields-viewer', {
type: 'sidebar',
size: 'medium',
data: { ...rowData, name: this.getSearchResultNodeName(rowData) },
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts
index f4c41f1cbc..73f987fdea 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts
@@ -35,5 +35,5 @@ export class UmbHealthCheckDashboardContext {
}
export const UMB_HEALTHCHECK_DASHBOARD_CONTEXT_TOKEN = new UmbContextToken(
- UmbHealthCheckDashboardContext.name
+ 'UmbHealthCheckDashboardContext'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts
index c810211f9a..920af65be7 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts
@@ -41,4 +41,4 @@ export class UmbHealthCheckContext {
}
}
-export const UMB_HEALTHCHECK_CONTEXT_TOKEN = new UmbContextToken(UmbHealthCheckContext.name);
+export const UMB_HEALTHCHECK_CONTEXT_TOKEN = new UmbContextToken('UmbHealthCheckContext');
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts
index e7693ba27c..8235fd382f 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts
@@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../core/modal';
import { PublishedCacheResource } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
@@ -38,13 +38,13 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement {
@state()
private _buttonStateCollect: UUIButtonState = undefined;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (_instance) => {
- this._modalService = _instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
@@ -82,7 +82,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement {
}
}
private async _onReloadCacheHandler() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: 'Reload',
content: html` Trigger a in-memory and local file cache reload on all servers. `,
color: 'danger',
@@ -105,7 +105,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement {
}
private async _onRebuildCacheHandler() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: 'Rebuild',
content: html` Rebuild content in cmsContentNu database table. Expensive.`,
color: 'danger',
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts
index 0c52ff35ad..e440812256 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts
@@ -8,7 +8,7 @@ import { UmbContextConsumerController } from '@umbraco-cms/context-api';
import { ProblemDetailsModel, DataTypeModel } from '@umbraco-cms/backend-api';
import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface';
import { UmbDetailRepository } from '@umbraco-cms/repository';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
type ItemType = DataTypeModel;
@@ -27,7 +27,7 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi
#detailDataSource: UmbDataTypeServerDataSource;
#detailStore?: UmbDataTypeStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -45,8 +45,8 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi
this.#detailStore = instance;
}),
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
]);
}
@@ -159,7 +159,7 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -181,7 +181,7 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
@@ -207,7 +207,7 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi
if (!error) {
const notification = { data: { message: `Document deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
// TODO: we currently don't use the detail store for anything.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts
index 4cd7c8dad1..d6d8ef2d94 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts
@@ -4,6 +4,8 @@ import { ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
+export const UMB_DATA_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDataTypeStore');
+
/**
* @export
* @class UmbDataTypeStore
@@ -19,7 +21,7 @@ export class UmbDataTypeStore extends UmbStoreBase {
* @memberof UmbDataTypeStore
*/
constructor(host: UmbControllerHostInterface) {
- super(host, UmbDataTypeStore.name);
+ super(host, UMB_DATA_TYPE_STORE_CONTEXT_TOKEN.toString());
}
/**
@@ -49,5 +51,3 @@ export class UmbDataTypeStore extends UmbStoreBase {
this.#data.remove(uniques);
}
}
-
-export const UMB_DATA_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbDataTypeStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts
index 6cf869e5e1..a29ae02cf8 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts
@@ -21,5 +21,5 @@ export class UmbDataTypeTreeStore extends UmbTreeStoreBase {
}
export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken(
- UmbDataTypeTreeStore.name
+ 'UmbDataTypeTreeStore'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/actions/delete/action-data-type-delete.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/actions/delete/action-data-type-delete.element.ts
index cfbf8ffcc5..1554a4d1d7 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/actions/delete/action-data-type-delete.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/actions/delete/action-data-type-delete.element.ts
@@ -1,26 +1,26 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../../core/modal';
import UmbTreeItemActionElement from '../../../../../shared/components/tree/action/tree-item-action.element';
@customElement('umb-tree-action-data-type-delete')
export default class UmbTreeActionDataTypeDeleteElement extends UmbTreeItemActionElement {
static styles = [UUITextStyles, css``];
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
//private _dataTypeStore?: UmbDataTypeStore;
connectedCallback(): void {
super.connectedCallback();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._modalService = modalService;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
private _handleLabelClick() {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: `Delete ${this._activeTreeItem?.name ?? 'item'}`,
content: 'Are you sure you want to delete this item?',
color: 'danger',
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts
index fd77adf0e6..c3495deef6 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts
@@ -1,7 +1,7 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../../../core/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../../../core/modal';
import { UmbDataTypeWorkspaceContext } from '../../data-type-workspace.context';
import { UmbLitElement } from '@umbraco-cms/element';
import type { DataTypeModel } from '@umbraco-cms/backend-api';
@@ -41,13 +41,13 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement {
private _data: Array = [];
private _workspaceContext?: UmbDataTypeWorkspaceContext;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (_instance) => {
- this._modalService = _instance;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
// TODO: Figure out if this is the best way to consume a context or if it could be strongly typed using UmbContextToken
@@ -100,7 +100,7 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement {
private _openPropertyEditorUIPicker() {
if (!this._dataType) return;
- const modalHandler = this._modalService?.propertyEditorUIPicker({
+ const modalHandler = this._modalContext?.propertyEditorUIPicker({
selection: this._propertyEditorUiAlias ? [this._propertyEditorUiAlias] : [],
});
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts
index 563af4962a..3558e546ce 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts
@@ -3,21 +3,21 @@ import { customElement, state } from 'lit/decorators.js';
import { isManifestElementNameType, umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
import type { ManifestBase } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
@customElement('umb-extension-root-workspace')
export class UmbExtensionRootWorkspaceElement extends UmbLitElement {
@state()
private _extensions?: Array = undefined;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
connectedCallback(): void {
super.connectedCallback();
this._observeExtensions();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._modalService = modalService;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
@@ -28,7 +28,7 @@ export class UmbExtensionRootWorkspaceElement extends UmbLitElement {
}
#removeExtension(extension: ManifestBase) {
- const modalHandler = this._modalService?.confirm({
+ const modalHandler = this._modalContext?.confirm({
headline: 'Unload extension',
confirmLabel: 'Unload',
content: html`Are you sure you want to unload the extension ${extension.alias}?
`,
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts
index d0a2f1604d..a69f693017 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts
@@ -120,7 +120,7 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
#renderTrigger() {
return html``;
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts
index 82c2d32649..867f876579 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts
@@ -47,4 +47,4 @@ export class UmbAppLanguageContext {
}
}
-export const UMB_APP_LANGUAGE_CONTEXT_TOKEN = new UmbContextToken(UmbAppLanguageContext.name);
+export const UMB_APP_LANGUAGE_CONTEXT_TOKEN = new UmbContextToken('UmbAppLanguageContext');
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts
index 9fa8683457..ef87ea9abe 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts
@@ -2,7 +2,7 @@ import { UmbLanguageServerDataSource } from './sources/language.server.data';
import { UmbLanguageStore, UMB_LANGUAGE_STORE_CONTEXT_TOKEN } from './language.store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
-import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
+import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification';
import { LanguageModel, ProblemDetailsModel } from '@umbraco-cms/backend-api';
export class UmbLanguageRepository {
@@ -13,7 +13,7 @@ export class UmbLanguageRepository {
#dataSource: UmbLanguageServerDataSource;
#languageStore?: UmbLanguageStore;
- #notificationService?: UmbNotificationService;
+ #notificationContext?: UmbNotificationContext;
constructor(host: UmbControllerHostInterface) {
this.#host = host;
@@ -21,13 +21,13 @@ export class UmbLanguageRepository {
this.#dataSource = new UmbLanguageServerDataSource(this.#host);
this.#init = Promise.all([
- new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (instance) => {
- this.#notificationService = instance;
+ new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this.#notificationContext = instance;
}),
new UmbContextConsumerController(this.#host, UMB_LANGUAGE_STORE_CONTEXT_TOKEN, (instance) => {
this.#languageStore = instance;
- }),
+ }).asPromise(),
]);
}
@@ -92,7 +92,7 @@ export class UmbLanguageRepository {
if (!error) {
this.#languageStore?.append(language);
const notification = { data: { message: `Language created` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
return { error };
@@ -111,7 +111,7 @@ export class UmbLanguageRepository {
if (!error) {
const notification = { data: { message: `Language saved` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
this.#languageStore?.append(language);
}
@@ -137,7 +137,7 @@ export class UmbLanguageRepository {
if (!error) {
this.#languageStore?.remove([isoCode]);
const notification = { data: { message: `Language deleted` } };
- this.#notificationService?.peek('positive', notification);
+ this.#notificationContext?.peek('positive', notification);
}
return { error };
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts
index 7f13331aca..3da9a5a38a 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts
@@ -4,6 +4,8 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller';
import { ArrayState } from '@umbraco-cms/observable-api';
import { LanguageModel } from '@umbraco-cms/backend-api';
+export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbLanguageStore');
+
/**
* @export
* @class UmbLanguageStore
@@ -15,7 +17,7 @@ export class UmbLanguageStore extends UmbStoreBase {
data = this.#data.asObservable();
constructor(host: UmbControllerHostInterface) {
- super(host, UmbLanguageStore.name);
+ super(host, UMB_LANGUAGE_STORE_CONTEXT_TOKEN.toString());
}
append(language: LanguageModel) {
@@ -32,4 +34,3 @@ export class UmbLanguageStore extends UmbStoreBase {
}
}
-export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken(UmbLanguageStore.name);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts
index 27e008d1bf..7ad8352aa4 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts
@@ -175,5 +175,5 @@ export class UmbCollectionContext<
}
export const UMB_COLLECTION_CONTEXT_TOKEN = new UmbContextToken>(
- UmbCollectionContext.name
+ 'UmbCollectionContext'
);
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts
index 1bc842424b..cd352e751b 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts
@@ -77,7 +77,7 @@ export class UmbBackofficeMain extends UmbLitElement {
}
private _onRouteChange = (event: UmbRouterSlotChangeEvent) => {
- const currentPath = event.target.localActiveViewPath || ''
+ const currentPath = event.target.localActiveViewPath || '';
const section = this._sections.find((s) => this._routePrefix + s.meta.pathname === currentPath);
if (!section) return;
this._backofficeContext?.setActiveSectionAlias(section.alias);
@@ -94,11 +94,7 @@ export class UmbBackofficeMain extends UmbLitElement {
}
render() {
- return html`
- `;
+ return html` `;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts
index 49298c46ed..1ad3d99bf3 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts
@@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
-import { UmbModalHandler, UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../core/modal';
+import { UmbModalHandler, UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '../../../../core/modal';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-backoffice-modal-container')
@@ -19,21 +19,21 @@ export class UmbBackofficeModalContainer extends UmbLitElement {
@state()
private _modals?: UmbModalHandler[];
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._modalService = modalService;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
this._observeModals();
});
}
private _observeModals() {
- if (!this._modalService) return;
+ if (!this._modalContext) return;
- this.observe(this._modalService.modals, (modals) => {
+ this.observe(this._modalContext.modals, (modals) => {
this._modals = modals;
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts
index c222b88208..eb5268301e 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts
@@ -4,8 +4,8 @@ import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import {
UmbNotificationHandler,
- UmbNotificationService,
- UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN,
+ UmbNotificationContext,
+ UMB_NOTIFICATION_CONTEXT_TOKEN,
} from '@umbraco-cms/notification';
import { UmbLitElement } from '@umbraco-cms/element';
@@ -29,21 +29,21 @@ export class UmbBackofficeNotificationContainer extends UmbLitElement {
@state()
private _notifications?: UmbNotificationHandler[];
- private _notificationService?: UmbNotificationService;
+ private _notificationContext?: UmbNotificationContext;
constructor() {
super();
- this.consumeContext(UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN, (notificationService) => {
- this._notificationService = notificationService;
+ this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => {
+ this._notificationContext = instance;
this._observeNotifications();
});
}
private _observeNotifications() {
- if (!this._notificationService) return;
+ if (!this._notificationContext) return;
- this.observe(this._notificationService.notifications, (notifications) => {
+ this.observe(this._notificationContext.notifications, (notifications) => {
this._notifications = notifications;
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts
index 195e409e60..ae75471fe0 100644
--- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts
@@ -3,7 +3,7 @@ import { css, html, nothing, TemplateResult } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UmbContextDebugRequest } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
-import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
+import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
@customElement('umb-debug')
export class UmbDebug extends UmbLitElement {
@@ -64,12 +64,12 @@ export class UmbDebug extends UmbLitElement {
@state()
private _debugPaneOpen = false;
- private _modalService?: UmbModalService;
+ private _modalContext?: UmbModalContext;
constructor() {
super();
- this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (modalService) => {
- this._modalService = modalService;
+ this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
+ this._modalContext = instance;
});
}
@@ -102,10 +102,10 @@ export class UmbDebug extends UmbLitElement {
}
private _openDialog() {
- this._modalService?.openBasic({
+ this._modalContext?.openBasic({
header: html` Debug: Contexts`,
content: this._htmlContent(),
- overlaySize: 'small'
+ overlaySize: 'small',
});
}
@@ -125,15 +125,13 @@ export class UmbDebug extends UmbLitElement {
-
- ${this._htmlContent()}
-
+
${this._htmlContent()}
`;
}
private _htmlContent() {
- return html `
+ return html`