Refactored "Installed Packages" view
This commit is contained in:
@@ -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`
|
||||
<uui-ref-node-package
|
||||
name=${ifDefined(this.name)}
|
||||
version="${ifDefined(this.version ?? undefined)}"
|
||||
@open=${this._onConfigure}
|
||||
?disabled="${!this._packageView}">
|
||||
${this.customIcon ? html`<umb-icon slot="icon" name="${this.customIcon}"></umb-icon>` : nothing}
|
||||
<div slot="tag">
|
||||
${this.hasPendingMigrations
|
||||
? html`<uui-button
|
||||
@click="${this._onMigration}"
|
||||
.state=${this._migrationButtonState}
|
||||
color="warning"
|
||||
look="primary"
|
||||
label="Run pending package migrations">
|
||||
Run pending migrations
|
||||
</uui-button>`
|
||||
: nothing}
|
||||
</div>
|
||||
</uui-ref-node-package>
|
||||
`
|
||||
: '';
|
||||
}
|
||||
|
||||
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`
|
||||
<uui-ref-node-package
|
||||
name=${ifDefined(this.name)}
|
||||
version="${ifDefined(this.version ?? undefined)}"
|
||||
@open=${this.#onConfigure}
|
||||
?disabled="${!this._packageView}">
|
||||
${this.customIcon ? html`<umb-icon slot="icon" name=${this.customIcon}></umb-icon>` : nothing}
|
||||
<div slot="tag">
|
||||
${this.hasPendingMigrations
|
||||
? html`<uui-button
|
||||
@click="${this.#onMigration}"
|
||||
.state=${this._migrationButtonState}
|
||||
color="warning"
|
||||
look="primary"
|
||||
label=${this.localize.term('packageMigrationsRun')}>
|
||||
Run pending migrations
|
||||
</uui-button>`
|
||||
: nothing}
|
||||
</div>
|
||||
</uui-ref-node-package>
|
||||
`
|
||||
: '';
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
|
||||
@@ -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`<div class="no-packages">
|
||||
<h2><strong>No packages have been installed</strong></h2>
|
||||
<p>
|
||||
Browse through the available packages using the <strong>'Packages'</strong> icon in the top right of your screen
|
||||
</p>
|
||||
</div>`;
|
||||
if (!this._installedPackages.length) return this.#renderNoPackages();
|
||||
return html`${this.#renderCustomMigrations()} ${this.#renderInstalled()} `;
|
||||
}
|
||||
|
||||
private _renderInstalled() {
|
||||
return html`<uui-box headline="Installed packages" style="--uui-box-default-padding:0">
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._installedPackages,
|
||||
(item) => item.name,
|
||||
(item) =>
|
||||
html`<umb-installed-packages-section-view-item
|
||||
.name=${item.name}
|
||||
.version=${item.version}
|
||||
.hasPendingMigrations=${item.hasPendingMigrations}></umb-installed-packages-section-view-item>`,
|
||||
)}
|
||||
</uui-ref-list>
|
||||
</uui-box>`;
|
||||
#renderNoPackages() {
|
||||
return html`
|
||||
<div class="no-packages">
|
||||
<h2><strong>${this.localize.term('packager_noPackages')}</strong></h2>
|
||||
<p>${unsafeHTML(this.localize.term('packager_noPackagesDescription'))}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderCustomMigrations() {
|
||||
if (!this._migrationPackages) return;
|
||||
return html`<uui-box headline="Migrations" style="--uui-box-default-padding:0">
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._migrationPackages,
|
||||
(item) => item.name,
|
||||
(item) =>
|
||||
html`<umb-installed-packages-section-view-item
|
||||
.name=${item.name}
|
||||
.version=${item.version}
|
||||
.customIcon="${'icon-sync'}"
|
||||
.hasPendingMigrations=${item.hasPendingMigrations}></umb-installed-packages-section-view-item>`,
|
||||
)}
|
||||
</uui-ref-list>
|
||||
</uui-box>`;
|
||||
#renderInstalled() {
|
||||
return html`
|
||||
<uui-box headline=${this.localize.term('packager_installedPackages')} style="--uui-box-default-padding:0">
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._installedPackages,
|
||||
(item) => item.name,
|
||||
(item) => html`
|
||||
<umb-installed-packages-section-view-item
|
||||
.name=${item.name}
|
||||
.version=${item.version}
|
||||
.hasPendingMigrations=${item.hasPendingMigrations}>
|
||||
</umb-installed-packages-section-view-item>
|
||||
`,
|
||||
)}
|
||||
</uui-ref-list>
|
||||
</uui-box>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderCustomMigrations() {
|
||||
if (!this._migrationPackages.length) return nothing;
|
||||
return html`
|
||||
<uui-box headline="Migrations" style="--uui-box-default-padding:0">
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._migrationPackages,
|
||||
(item) => item.name,
|
||||
(item) => html`
|
||||
<umb-installed-packages-section-view-item
|
||||
custom-icon="icon-sync"
|
||||
.name=${item.name}
|
||||
.version=${item.version}
|
||||
.hasPendingMigrations=${item.hasPendingMigrations}>
|
||||
</umb-installed-packages-section-view-item>
|
||||
`,
|
||||
)}
|
||||
</uui-ref-list>
|
||||
</uui-box>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
|
||||
Reference in New Issue
Block a user