diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
index 9be9a1ab10..324658656f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts
@@ -1,22 +1,18 @@
import { html, css, nothing, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
-import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
-import { map } from '@umbraco-cms/backoffice/external/rxjs';
-import { umbConfirmModal } from '@umbraco-cms/backoffice/modal';
import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
-import type { ManifestPackageView } from '@umbraco-cms/backoffice/extension-registry';
+import { PackageResource } from '@umbraco-cms/backoffice/external/backend-api';
+import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
+import { umbConfirmModal } from '@umbraco-cms/backoffice/modal';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
-import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
-import { PackageResource } from '@umbraco-cms/backoffice/external/backend-api';
-import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification';
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
+import type { ManifestPackageView } from '@umbraco-cms/backoffice/extension-registry';
+import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification';
+import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-installed-packages-section-view-item')
export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
@property()
- public get name(): string | undefined {
- return this.#name;
- }
public set name(value: string | undefined) {
const oldValue = this.#name;
if (oldValue === value) return;
@@ -24,6 +20,9 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
this.#observePackageView();
this.requestUpdate('name', oldValue);
}
+ public get name(): string | undefined {
+ return this.#name;
+ }
#name?: string | undefined;
@property()
@@ -32,7 +31,7 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
@property({ type: Boolean, attribute: false })
hasPendingMigrations = false;
- @property()
+ @property({ attribute: 'custom-icon' })
customIcon?: string;
@state()
@@ -53,11 +52,7 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
#observePackageView() {
this.observe(
- umbExtensionsRegistry.byType('packageView').pipe(
- map((extensions) => {
- return extensions.filter((extension) => extension.meta.packageName === this.#name);
- }),
- ),
+ umbExtensionsRegistry.byTypeAndFilter('packageView', (manifest) => manifest.meta.packageName === this.#name),
(manifests) => {
if (manifests.length === 0) {
this._packageView = undefined;
@@ -69,54 +64,7 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
);
}
- async _onMigration() {
- if (!this.name) return;
-
- await umbConfirmModal(this, {
- color: 'positive',
- headline: `Run migrations for ${this.name}?`,
- content: `Do you want to start run migrations for ${this.name}`,
- confirmLabel: 'Run migrations',
- });
-
- 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 this.name
- ? html`
-
- ${this.customIcon ? html`` : nothing}
-
- ${this.hasPendingMigrations
- ? html`
- Run pending migrations
- `
- : nothing}
-
-
- `
- : '';
- }
-
- private async _onConfigure() {
+ async #onConfigure() {
if (!this._packageView) {
console.warn('Tried to configure package without view');
return;
@@ -140,6 +88,61 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement {
*/
}
+ async #onMigration() {
+ if (!this.name) return;
+
+ await umbConfirmModal(this, {
+ color: 'positive',
+ headline: `Run migrations for ${this.name}?`,
+ content: `Do you want to start run migrations for ${this.name}`,
+ confirmLabel: 'Run migrations',
+ });
+
+ this._migrationButtonState = 'waiting';
+ const { error } = await tryExecuteAndNotify(
+ this,
+ PackageResource.postPackageByNameRunMigration({ name: this.name }),
+ );
+
+ if (error) return;
+
+ this.#notificationContext?.peek('positive', {
+ data: {
+ headline: 'Migrations completed',
+ message: this.localize.term('packager_packageMigrationsComplete'),
+ },
+ });
+
+ this._migrationButtonState = 'success';
+ this.hasPendingMigrations = false;
+ }
+
+ render() {
+ return this.name
+ ? html`
+
+ ${this.customIcon ? html`` : nothing}
+
+ ${this.hasPendingMigrations
+ ? html`
+ Run pending migrations
+ `
+ : nothing}
+
+
+ `
+ : '';
+ }
+
static styles = css`
:host {
display: flex;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts
index 2b3b4dfda7..b530d73a29 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts
@@ -1,12 +1,12 @@
import { UmbPackageRepository } from '../../../package/repository/package.repository.js';
import type { UmbPackageWithMigrationStatus } from '../../../types.js';
-import { html, css, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
-import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { html, css, customElement, state, repeat, nothing, unsafeHTML } from '@umbraco-cms/backoffice/external/lit';
+import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbSectionViewElement } from '@umbraco-cms/backoffice/extension-registry';
import './installed-packages-section-view-item.element.js';
-import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
@customElement('umb-installed-packages-section-view')
export class UmbInstalledPackagesSectionViewElement extends UmbLitElement implements UmbSectionViewElement {
@@ -24,91 +24,90 @@ export class UmbInstalledPackagesSectionViewElement extends UmbLitElement implem
}
firstUpdated() {
- this._loadInstalledPackages();
+ this.#loadInstalledPackages();
}
- /**
- * Fetch the installed packages from the server
- */
- private async _loadInstalledPackages() {
+ async #loadInstalledPackages() {
const data = await Promise.all([this.#packageRepository.rootItems(), this.#packageRepository.migrations()]);
const [package$, migration$] = data;
this.observe(observeMultiple([package$, migration$]), ([packages, migrations]) => {
- this._installedPackages = packages.map((p) => {
- const migration = migrations.find((m) => m.packageName === p.name);
+ this._installedPackages = packages.map((pkg) => {
+ const migration = migrations.find((m) => m.packageName === pkg.name);
if (migration) {
// Remove that migration from the list
- migrations = migrations.filter((m) => m.packageName !== p.name);
+ migrations = migrations.filter((m) => m.packageName !== pkg.name);
}
return {
- ...p,
+ ...pkg,
hasPendingMigrations: migration?.hasPendingMigrations ?? false,
};
});
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- 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,
- })),
- ];*/
+ this._migrationPackages = migrations.map((m) => ({
+ name: m.packageName,
+ hasPendingMigrations: m.hasPendingMigrations ?? false,
+ extensions: [],
+ }));
});
}
render() {
- 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
-
-
`;
+ if (!this._installedPackages.length) return this.#renderNoPackages();
+ return html`${this.#renderCustomMigrations()} ${this.#renderInstalled()} `;
}
- private _renderInstalled() {
- return html`
-
- ${repeat(
- this._installedPackages,
- (item) => item.name,
- (item) =>
- html``,
- )}
-
- `;
+ #renderNoPackages() {
+ return html`
+
+
${this.localize.term('packager_noPackages')}
+
${unsafeHTML(this.localize.term('packager_noPackagesDescription'))}
+
+ `;
}
- private _renderCustomMigrations() {
- if (!this._migrationPackages) return;
- return html`
-
- ${repeat(
- this._migrationPackages,
- (item) => item.name,
- (item) =>
- html``,
- )}
-
- `;
+ #renderInstalled() {
+ return html`
+
+
+ ${repeat(
+ this._installedPackages,
+ (item) => item.name,
+ (item) => html`
+
+
+ `,
+ )}
+
+
+ `;
+ }
+
+ #renderCustomMigrations() {
+ if (!this._migrationPackages.length) return nothing;
+ return html`
+
+
+ ${repeat(
+ this._migrationPackages,
+ (item) => item.name,
+ (item) => html`
+
+
+ `,
+ )}
+
+
+ `;
}
static styles = [