From b18b5a5c1a9eb3ae57ad76cd08eeb4469104fcc9 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:51:37 +0100 Subject: [PATCH 01/33] add new local eslint rule to catch direct usage of resources without tryExecuteAndNotify --- src/Umbraco.Web.UI.Client/.eslintrc.json | 3 +- .../eslint-local-rules.cjs | 38 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/.eslintrc.json b/src/Umbraco.Web.UI.Client/.eslintrc.json index 4cd0e150db..5034e34797 100644 --- a/src/Umbraco.Web.UI.Client/.eslintrc.json +++ b/src/Umbraco.Web.UI.Client/.eslintrc.json @@ -33,7 +33,8 @@ "no-var": "error", "import/no-unresolved": "error", "import/order": "warn", - "local-rules/bad-type-import": "error" + "local-rules/bad-type-import": "error", + "local-rules/no-direct-api-import": "warn" }, "settings": { "import/parsers": { diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index eeddac50c8..bae4cd16b0 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -4,11 +4,11 @@ * A eslint rule that ensures the use of the `import type` operator from the `src/core/models/index.ts` file. */ // eslint-disable-next-line no-undef -/** @type {import('eslint').Rule.RuleModule} */ module.exports = { + /** @type {import('eslint').Rule.RuleModule} */ 'bad-type-import': { meta: { - type: 'problem', + type: 'suggestion', docs: { description: 'Ensures the use of the `import type` operator from the `src/core/models/index.ts` file.', category: 'Best Practices', @@ -20,7 +20,7 @@ module.exports = { create: function (context) { return { ImportDeclaration: function (node) { - if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('/models') || node.source.value.endsWith('/generated-schema') || node.source.value === 'router-slot/model')) { + if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('/models') || node.source.value === 'router-slot/model')) { const sourceCode = context.getSourceCode(); const nodeSource = sourceCode.getText(node); context.report({ @@ -32,5 +32,37 @@ module.exports = { }, }; } + }, + + /** @type {import('eslint').Rule.RuleModule} */ + 'no-direct-api-import': { + meta: { + type: 'suggestion', + docs: { + description: 'Ensures that any API resources from the `@umbraco-cms/backend-api` module are not used directly. Instead you should use the `tryExecuteAndNotify` function from the `@umbraco-cms/resources` module.', + category: 'Best Practices', + recommended: true + }, + fixable: 'code', + schema: [], + }, + create: function (context) { + return { + // If methods called on *Resource classes are not already wrapped with `await tryExecuteAndNotify()`, then we should suggest to wrap them. + CallExpression: function (node) { + if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name.endsWith('Resource') && node.callee.property.type === 'Identifier' && node.callee.property.name !== 'constructor') { + const hasTryExecuteAndNotify = node.parent.parent.type === 'AwaitExpression' && node.parent.callee.name === 'tryExecuteAndNotify'; + if (!hasTryExecuteAndNotify) { + context.report({ + node, + message: 'Wrap this call with `tryExecuteAndNotify()`. Make sure to `await` the result.', + fix: fixer => [fixer.insertTextBefore(node, 'tryExecuteAndNotify(this, '), fixer.insertTextAfter(node, ')')], + }); + } + } + } + }; + + }, } }; From 9c5b5368cebf4aa286da9693b84de0287c690d6b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:51:54 +0100 Subject: [PATCH 02/33] add shortcut to import UmbLitElement --- src/Umbraco.Web.UI.Client/src/core/element/index.ts | 2 ++ src/Umbraco.Web.UI.Client/tsconfig.json | 1 + src/Umbraco.Web.UI.Client/web-test-runner.config.mjs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/core/element/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/element/index.ts b/src/Umbraco.Web.UI.Client/src/core/element/index.ts new file mode 100644 index 0000000000..4048b79c02 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/element/index.ts @@ -0,0 +1,2 @@ +export * from './element.mixin'; +export * from './lit-element.element'; diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 6f278ee1d3..3b5a74a536 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -23,6 +23,7 @@ "@umbraco-cms/models": ["src/core/models"], "@umbraco-cms/backend-api": ["src/core/backend-api"], "@umbraco-cms/context-api": ["src/core/context-api"], + "@umbraco-cms/element": ["src/core/element"], "@umbraco-cms/extensions-api": ["src/core/extensions-api"], "@umbraco-cms/extensions-registry": ["src/core/extensions-registry"], "@umbraco-cms/observable-api": ["src/core/observable-api"], diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index bf55d97a2d..c4b63b7243 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -14,9 +14,9 @@ export default { '@umbraco-cms/models': './src/core/models/index.ts', '@umbraco-cms/backend-api': './src/core/backend-api/index.ts', '@umbraco-cms/context-api': './src/core/context-api/index.ts', + '@umbraco-cms/element': './src/core/element/index.ts', '@umbraco-cms/extensions-api': './src/core/extensions-api/index.ts', '@umbraco-cms/observable-api': './src/core/observable-api/index.ts', - '@umbraco-cms/resource-api': './src/core/resource-api', '@umbraco-cms/utils': './src/core/utils/index.ts', '@umbraco-cms/test-utils': './src/core/test-utils/index.ts', '@umbraco-cms/resources': './src/core/resources', From 6f3abc00a7219de006324db6bdcc1e4f7ab69c13 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:52:23 +0100 Subject: [PATCH 03/33] make tryExecuteAndNotify wrapper more straight forward --- src/Umbraco.Web.UI.Client/src/core/resources/index.ts | 1 + .../src/core/resources/tryExecuteAndNotify.method.ts | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/index.ts b/src/Umbraco.Web.UI.Client/src/core/resources/index.ts index b4dfcb2097..6da0dee4b6 100644 --- a/src/Umbraco.Web.UI.Client/src/core/resources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/core/resources/index.ts @@ -1 +1,2 @@ export * from './resource.controller'; +export * from './tryExecuteAndNotify.method'; diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/tryExecuteAndNotify.method.ts b/src/Umbraco.Web.UI.Client/src/core/resources/tryExecuteAndNotify.method.ts index 919ffcd7d9..ac1b9c860d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/resources/tryExecuteAndNotify.method.ts +++ b/src/Umbraco.Web.UI.Client/src/core/resources/tryExecuteAndNotify.method.ts @@ -1,13 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { UmbControllerHostInterface } from '../controller/controller-host.mixin'; -import type { ProblemDetails } from '../backend-api/models/ProblemDetails'; import { UmbResourceController } from './resource.controller'; import { UmbNotificationOptions } from 'src/core/notification'; -export async function tryExecuteAndNotify( +export function tryExecuteAndNotify( host: UmbControllerHostInterface, resource: Promise, options?: UmbNotificationOptions -): Promise<{ data?: T; error?: ProblemDetails }> { - return await new UmbResourceController(host, resource).tryExecuteAndNotify(options); +) { + return new UmbResourceController(host, resource).tryExecuteAndNotify(options); } From cd0baf9af4c4a175bc7264725385aff65aad58ac Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:52:57 +0100 Subject: [PATCH 04/33] installer-database: apply tryExecuteAndNotify --- .../database/installer-database.element.ts | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index 995e231b87..a9c8ef66d9 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -1,10 +1,8 @@ import { UUIButtonElement } from '@umbraco-ui/uui'; -import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; +import { css, CSSResultGroup, html, nothing } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { UmbInstallerContext } from '../installer.context'; -import { UmbObserverMixin } from '@umbraco-cms/observable-api'; -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import { ApiError, DatabaseInstall, @@ -14,9 +12,11 @@ import { InstallSettings, ProblemDetails, } from '@umbraco-cms/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbLitElement } from 'src/core/element/lit-element.element'; @customElement('umb-installer-database') -export class UmbInstallerDatabaseElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) { +export class UmbInstallerDatabaseElement extends UmbLitElement { static styles: CSSResultGroup = [ css` :host, @@ -115,7 +115,7 @@ export class UmbInstallerDatabaseElement extends UmbContextConsumerMixin(UmbObse if (!this._installerContext) return; this.observe(this._installerContext.settings, (settings) => { - this._databases = settings.databases ?? []; + this._databases = settings?.databases ?? []; // If there is an isConfigured database in the databases array then we can skip the database selection step // and just use that. @@ -134,8 +134,8 @@ export class UmbInstallerDatabaseElement extends UmbContextConsumerMixin(UmbObse if (!this._installerContext) return; this.observe(this._installerContext.data, (data) => { - this.databaseFormData = data.database ?? {}; - this._options.forEach((x, i) => (x.selected = data.database?.id === x.value || i === 0)); + this.databaseFormData = data?.database ?? ({} as DatabaseInstall); + this._options.forEach((x, i) => (x.selected = data?.database?.id === x.value || i === 0)); }); } @@ -190,27 +190,24 @@ export class UmbInstallerDatabaseElement extends UmbContextConsumerMixin(UmbObse } if (selectedDatabase.requiresConnectionTest) { - try { - const databaseDetails: DatabaseInstall = { - id, - username, - password, - server, - useIntegratedAuthentication, - name, - connectionString, - providerName: selectedDatabase.providerName, - }; + const databaseDetails: DatabaseInstall = { + id, + username, + password, + server, + useIntegratedAuthentication, + name, + connectionString, + providerName: selectedDatabase.providerName, + }; - await InstallResource.postInstallValidateDatabase({ requestBody: databaseDetails }); - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - console.warn('Database validation failed', error.detail); - this._validationErrorMessage = error.detail ?? 'Could not verify database connection'; - } else { - this._validationErrorMessage = 'A server error happened when trying to validate the database'; - } + const { error } = await tryExecuteAndNotify( + this, + InstallResource.postInstallValidateDatabase({ requestBody: databaseDetails }) + ); + + if (error) { + this._validationErrorMessage = error.detail; this._installButton.state = 'failed'; return; } From 86a7ed70e83451d9f5ab3f7abc16cb28589e7a4a Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:53:07 +0100 Subject: [PATCH 05/33] upgrader: apply tryExecuteAndNotify --- .../src/upgrader/upgrader.element.ts | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts index 803a2a4ae5..6d4f3b75f3 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts @@ -1,15 +1,17 @@ import '../installer/shared/layout/installer-layout.element'; import './upgrader-view.element'; -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ApiError, ProblemDetails, UpgradeResource, UpgradeSettings } from '@umbraco-cms/backend-api'; +import { UpgradeResource, UpgradeSettings } from '@umbraco-cms/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbLitElement } from '@umbraco-cms/element'; /** * @element umb-upgrader */ @customElement('umb-upgrader') -export class UmbUpgrader extends LitElement { +export class UmbUpgrader extends UmbLitElement { @state() private upgradeSettings?: UpgradeSettings; @@ -41,14 +43,12 @@ export class UmbUpgrader extends LitElement { private async _setup() { this.fetching = true; - try { - const data = await UpgradeResource.getUpgradeSettings(); + const { data, error } = await tryExecuteAndNotify(this, UpgradeResource.getUpgradeSettings()); + + if (data) { this.upgradeSettings = data; - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - this.errorMessage = error.detail; - } + } else if (error) { + this.errorMessage = error.detail; } this.fetching = false; @@ -59,18 +59,12 @@ export class UmbUpgrader extends LitElement { this.errorMessage = ''; this.upgrading = true; - try { - await UpgradeResource.postUpgradeAuthorize(); + const { error } = await tryExecuteAndNotify(this, UpgradeResource.postUpgradeAuthorize()); + + if (error) { + this.errorMessage = error.detail || 'Unknown error, please try again'; + } else { history.pushState(null, '', '/'); - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - if (e.status === 400) { - this.errorMessage = error.detail || 'Unknown error, please try again'; - } - } else { - this.errorMessage = 'Unknown error, please try again'; - } } this.upgrading = false; From d44a006b4bf955be2c23b3c40f9fba0e1cc84d0e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:53:16 +0100 Subject: [PATCH 06/33] remove unused import --- .../dashboard-performance-profiling.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts index 1590f0cedb..c499d4deb8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts @@ -1,7 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ProfilingResource, ProfilingStatus } from '@umbraco-cms/backend-api'; +import { ProfilingResource } from '@umbraco-cms/backend-api'; import { tryExecuteAndNotify } from 'src/core/resources/tryExecuteAndNotify.method'; import { UmbLitElement } from 'src/core/element/lit-element.element'; From a92959588fe20a145be4c695b5e2a6f831e4c453 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:53:36 +0100 Subject: [PATCH 07/33] add launch task to debug local eslint rules --- src/Umbraco.Web.UI.Client/.vscode/launch.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/.vscode/launch.json b/src/Umbraco.Web.UI.Client/.vscode/launch.json index 094ba1adaf..828c6a84f0 100644 --- a/src/Umbraco.Web.UI.Client/.vscode/launch.json +++ b/src/Umbraco.Web.UI.Client/.vscode/launch.json @@ -4,6 +4,12 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "command": "npx eslint", + "name": "Debug eslint", + "request": "launch", + "type": "node-terminal" + }, { "type": "chrome", "request": "launch", From 5eba08c5c1c3cf417ab949ad4ea8dd243fcd717e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:00:18 +0100 Subject: [PATCH 08/33] published-status: apply tryExecuteAndNotify --- .../dashboard-published-status.element.ts | 74 +++++++------------ 1 file changed, 26 insertions(+), 48 deletions(-) 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 b25e3452ab..5995c9aea8 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 @@ -1,17 +1,16 @@ import { UUIButtonState } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement } from 'lit'; +import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbModalService } from '../../../../core/modal'; -import { UmbNotificationService } from '../../../../core/notification'; -import { UmbNotificationDefaultData } from '../../../../core/notification/layouts/default'; -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; -import { ApiError, ProblemDetails, PublishedCacheResource } from '@umbraco-cms/backend-api'; +import { PublishedCacheResource } from '@umbraco-cms/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbLitElement } from '@umbraco-cms/element'; @customElement('umb-dashboard-published-status') -export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(LitElement) { +export class UmbDashboardPublishedStatusElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -39,14 +38,12 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( @state() private _buttonStateCollect: UUIButtonState = undefined; - private _notificationService?: UmbNotificationService; private _modalService?: UmbModalService; constructor() { super(); - this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => { - this._notificationService = instances['umbNotificationService']; + this.consumeAllContexts(['umbModalService'], (instances) => { this._modalService = instances['umbModalService']; }); } @@ -57,19 +54,13 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( } // Refresh - private async _getPublishedStatus() { - try { - const data = await PublishedCacheResource.getPublishedCacheStatus(); + const { data } = await tryExecuteAndNotify(this, PublishedCacheResource.getPublishedCacheStatus()); + if (data) { this._publishedStatusText = data; - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' }; - this._notificationService?.peek('danger', { data }); - } } } + private async _onRefreshCacheHandler() { this._buttonState = 'waiting'; await this._getPublishedStatus(); @@ -80,19 +71,14 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( private async _reloadMemoryCache() { this._buttonStateReload = 'waiting'; this._buttonState = 'waiting'; - try { - await PublishedCacheResource.postPublishedCacheReload(); + const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheReload()); + if (error) { + this._buttonStateReload = 'failed'; + this._buttonState = 'failed'; + } else { this._buttonStateReload = 'success'; this._getPublishedStatus(); this._buttonState = 'success'; - } catch (e) { - this._buttonStateReload = 'failed'; - this._buttonState = 'failed'; - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' }; - this._notificationService?.peek('danger', { data }); - } } } private async _onReloadCacheHandler() { @@ -102,7 +88,7 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( color: 'danger', confirmLabel: 'Continue', }); - modalHandler?.onClose().then(({ confirmed }: any) => { + modalHandler?.onClose().then(({ confirmed }) => { if (confirmed) this._reloadMemoryCache(); }); } @@ -110,18 +96,14 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( // Rebuild private async _rebuildDatabaseCache() { this._buttonStateRebuild = 'waiting'; - try { - await PublishedCacheResource.postPublishedCacheRebuild(); - this._buttonStateRebuild = 'success'; - } catch (e) { + const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheRebuild()); + if (error) { this._buttonStateRebuild = 'failed'; - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' }; - this._notificationService?.peek('danger', { data }); - } + } else { + this._buttonStateRebuild = 'success'; } } + private async _onRebuildCacheHandler() { const modalHandler = this._modalService?.confirm({ headline: 'Rebuild', @@ -129,25 +111,21 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin( color: 'danger', confirmLabel: 'Continue', }); - modalHandler?.onClose().then(({ confirmed }: any) => { + modalHandler?.onClose().then(({ confirmed }) => { if (confirmed) this._rebuildDatabaseCache(); }); } //Collect private async _cacheCollect() { - try { - await PublishedCacheResource.postPublishedCacheCollect(); - this._buttonStateCollect = 'success'; - } catch (e) { + const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheCollect()); + if (error) { this._buttonStateCollect = 'failed'; - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.data.detail ?? 'Something went wrong' }; - this._notificationService?.peek('danger', { data }); - } + } else { + this._buttonStateCollect = 'success'; } } + private async _onSnapshotCacheHandler() { this._buttonStateCollect = 'waiting'; await this._cacheCollect(); From 3a7136fffdacce0c8b5b615c690a307b5ec30c6f Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:03:41 +0100 Subject: [PATCH 09/33] models-builder: apply tryExecuteAndNotify --- .../dashboard-models-builder.element.ts | 42 +++++-------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts index 621c9a4ecd..a9f3fd38e9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts @@ -3,10 +3,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbNotificationService } from '../../../../core/notification'; -import { UmbNotificationDefaultData } from '../../../../core/notification/layouts/default'; import { ApiError, ModelsBuilder, ModelsBuilderResource, ModelsMode, ProblemDetails } from '@umbraco-cms/backend-api'; import { UmbLitElement } from 'src/core/element/lit-element.element'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-models-builder') export class UmbDashboardModelsBuilderElement extends UmbLitElement { @@ -41,8 +40,6 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement { `, ]; - private _notificationService?: UmbNotificationService; - @state() private _modelsBuilder?: ModelsBuilder; @@ -55,27 +52,15 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement { constructor() { super(); this._getDashboardData(); - - this.consumeContext('umbNotificationService', (instance) => { - this._notificationService = instance; - }); } private async _getDashboardData() { - try { - const modelsBuilder = await ModelsBuilderResource.getModelsBuilderDashboard(); - this._modelsBuilder = modelsBuilder; + const { data } = await tryExecuteAndNotify(this, ModelsBuilderResource.getModelsBuilderDashboard()); + if (data) { + this._modelsBuilder = data; return true; - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { - message: error.message ?? 'Something went wrong', - }; - this._notificationService?.peek('danger', { data }); - } - return false; } + return false; } private async _onGenerateModels() { @@ -85,20 +70,13 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement { } private async _postGenerateModels() { - try { - await ModelsBuilderResource.postModelsBuilderBuild(); - this._getDashboardData(); - return true; - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { - message: error.message ?? 'Model generation failed', - }; - this._notificationService?.peek('danger', { data }); - } + const { error } = await tryExecuteAndNotify(this, ModelsBuilderResource.postModelsBuilderBuild()); + if (error) { return false; } + + this._getDashboardData(); + return true; } private async _onDashboardReload() { From fa276e2226e09f586ea3685540823377e017b1dd Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:04:12 +0100 Subject: [PATCH 10/33] remove unused imports --- .../models-builder/dashboard-models-builder.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts index a9f3fd38e9..8f550d7bbd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts @@ -3,8 +3,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ApiError, ModelsBuilder, ModelsBuilderResource, ModelsMode, ProblemDetails } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from 'src/core/element/lit-element.element'; +import { ModelsBuilder, ModelsBuilderResource, ModelsMode } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-models-builder') From a0237bd77200bdc436108519a67531c2f970de95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:09:14 +0000 Subject: [PATCH 11/33] Bump @typescript-eslint/parser from 5.47.0 to 5.48.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.47.0 to 5.48.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.48.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 384 +++----------------- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 42 insertions(+), 344 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index fb45b1e96f..4f5f763a91 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -42,7 +42,7 @@ "@types/mocha": "^10.0.0", "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.48.0", - "@typescript-eslint/parser": "^5.47.0", + "@typescript-eslint/parser": "^5.48.0", "@web/dev-server-esbuild": "^0.3.3", "@web/dev-server-import-maps": "^0.0.7", "@web/test-runner": "^0.15.0", @@ -6425,53 +6425,6 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", - "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", - "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -6488,14 +6441,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz", - "integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz", + "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.47.0", - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "debug": "^4.3.4" }, "engines": { @@ -6515,13 +6468,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", - "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", + "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0" + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -6558,7 +6511,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "5.48.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", @@ -6571,7 +6524,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.48.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", @@ -6598,78 +6551,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", - "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", - "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -6711,80 +6592,6 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", - "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", - "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", - "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -6801,12 +6608,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", - "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", + "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/types": "5.48.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -33295,32 +33102,6 @@ "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", - "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0" - } - }, - "@typescript-eslint/types": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", - "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - } - }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -33333,25 +33114,25 @@ } }, "@typescript-eslint/parser": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz", - "integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz", + "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.47.0", - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/typescript-estree": "5.47.0", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", - "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", + "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0" + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0" } }, "@typescript-eslint/type-utils": { @@ -33364,64 +33145,22 @@ "@typescript-eslint/utils": "5.48.0", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", - "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", - "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/types": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", - "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", + "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", - "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", + "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", - "@typescript-eslint/visitor-keys": "5.47.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -33456,47 +33195,6 @@ "semver": "^7.3.7" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", - "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0" - } - }, - "@typescript-eslint/types": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", - "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", - "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "@typescript-eslint/visitor-keys": "5.48.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", - "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.48.0", - "eslint-visitor-keys": "^3.3.0" - } - }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -33509,12 +33207,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", - "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", + "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/types": "5.48.0", "eslint-visitor-keys": "^3.3.0" } }, diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 035c66d012..2ca695f048 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -87,7 +87,7 @@ "@types/mocha": "^10.0.0", "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.48.0", - "@typescript-eslint/parser": "^5.47.0", + "@typescript-eslint/parser": "^5.48.0", "@web/dev-server-esbuild": "^0.3.3", "@web/dev-server-import-maps": "^0.0.7", "@web/test-runner": "^0.15.0", From 4df3050575a56ef093131d629cdde43f2d224d49 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:38:48 +0100 Subject: [PATCH 12/33] use relative import --- .../src/installer/database/installer-database.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index a9c8ef66d9..754d2c2897 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -12,8 +12,8 @@ import { InstallSettings, ProblemDetails, } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbLitElement } from 'src/core/element/lit-element.element'; @customElement('umb-installer-database') export class UmbInstallerDatabaseElement extends UmbLitElement { From e82d095ed8603b25c0aa5667479bbf2b242997f9 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:38:59 +0100 Subject: [PATCH 13/33] use Option interface for database options --- .../database/installer-database.element.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index 754d2c2897..88cda151e7 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -88,7 +88,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { public databaseFormData!: DatabaseInstall; @state() - private _options: { name: string; value: string; selected?: boolean }[] = []; + private _options: Option[] = []; @state() private _databases: DatabaseSettings[] = []; @@ -121,11 +121,14 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { // and just use that. this._preConfiguredDatabase = this._databases.find((x) => x.isConfigured); if (!this._preConfiguredDatabase) { - this._options = this._databases.map((x, i) => ({ - name: x.displayName ?? 'Unknown database', - value: x.id!, - selected: i === 0, - })); + this._options = this._databases + .filter((x) => !!x.id) + .map((x, i) => ({ + name: x.displayName ?? 'Unknown database', + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + value: x.id!, + selected: i === 0, + })); } }); } From 75143770b2ee21733714303505ce422d10e6cc64 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:42:06 +0100 Subject: [PATCH 14/33] examine-searchers: apply tryExecuteAndNotify --- .../views/section-view-examine-searchers.ts | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) 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 a3e1e0c2fc..71a7a66fe3 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 @@ -1,14 +1,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement, nothing } from 'lit'; +import { css, html, nothing } from 'lit'; import { customElement, state, query, property } from 'lit/decorators.js'; import { UmbModalService } from '../../../../../core/modal'; -import { UmbNotificationService } from '../../../../../core/notification'; -import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default'; -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; - -import { ApiError, ProblemDetails, SearchResult, SearcherResource, Field } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { SearchResult, SearcherResource, Field } from '@umbraco-cms/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; import './modal-views/fields-viewer.element'; import './modal-views/fields-settings.element'; @@ -19,7 +17,7 @@ interface ExposedSearchResultField { } @customElement('umb-dashboard-examine-searcher') -export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin(LitElement) { +export class UmbDashboardExamineSearcherElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -103,7 +101,6 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin( `, ]; - private _notificationService?: UmbNotificationService; private _modalService?: UmbModalService; @property() @@ -123,15 +120,13 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin( constructor() { super(); - this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => { - this._notificationService = instances['umbNotificationService']; + this.consumeAllContexts(['umbModalService'], (instances) => { this._modalService = instances['umbModalService']; }); } private _onNameClick() { - const data: UmbNotificationDefaultData = { message: 'TODO: Open workspace for this' }; // TODO - this._notificationService?.peek('warning', { data }); + alert('TODO: Open workspace for ' + this.searcherName); } private _onKeyPress(e: KeyboardEvent) { @@ -141,22 +136,19 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin( private async _onSearch() { if (!this._searchInput.value.length) return; this._searchLoading = true; - try { - const res = await SearcherResource.getSearcherBySearcherNameQuery({ + + const { data } = await tryExecuteAndNotify( + this, + SearcherResource.getSearcherBySearcherNameQuery({ searcherName: this.searcherName, term: this._searchInput.value, take: 100, skip: 0, - }); - this._searchResults = res.items; - this._updateFieldFilter(); - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch search results' }; - this._notificationService?.peek('danger', { data }); - } - } + }) + ); + + this._searchResults = data?.items ?? []; + this._updateFieldFilter(); this._searchLoading = false; } From d03f2a78ac57c97ddf7789941def94e8e8c37fc3 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:44:28 +0100 Subject: [PATCH 15/33] examine-overview: apply tryExecuteAndNotify --- .../views/section-view-examine-overview.ts | 46 ++++--------------- 1 file changed, 9 insertions(+), 37 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts index dd17f71c5d..8b204624a5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts @@ -1,15 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement, nothing } from 'lit'; +import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbNotificationService } from '../../../../../core/notification'; -import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default'; - -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; -import { ApiError, ProblemDetails, Searcher, Index, IndexerResource, SearcherResource } from '@umbraco-cms/backend-api'; +import { Index, IndexerResource, Searcher, SearcherResource } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-examine-overview') -export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin(LitElement) { +export class UmbDashboardExamineOverviewElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -65,16 +63,6 @@ export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin( @state() private _loadingSearchers = false; - private _notificationService?: UmbNotificationService; - - constructor() { - super(); - - this.consumeAllContexts(['umbNotificationService'], (instances) => { - this._notificationService = instances['umbNotificationService']; - }); - } - connectedCallback() { super.connectedCallback(); this._getIndexers(); @@ -83,31 +71,15 @@ export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin( private async _getIndexers() { this._loadingIndexers = true; - try { - const indexers = await IndexerResource.getIndexer({ take: 9999, skip: 0 }); - this._indexers = indexers.items; - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch indexers' }; - this._notificationService?.peek('danger', { data }); - } - } + const { data } = await tryExecuteAndNotify(this, IndexerResource.getIndexer({ take: 9999, skip: 0 })); + this._indexers = data?.items ?? []; this._loadingIndexers = false; } private async _getSearchers() { this._loadingSearchers = true; - try { - const searchers = await SearcherResource.getSearcher({ take: 9999, skip: 0 }); - this._searchers = searchers.items; - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch searchers' }; - this._notificationService?.peek('danger', { data }); - } - } + const { data } = await tryExecuteAndNotify(this, SearcherResource.getSearcher({ take: 9999, skip: 0 })); + this._searchers = data?.items ?? []; this._loadingSearchers = false; } From b05fc90a36b7b9e6643e4f5a3e3611d3a1d4d9a4 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:47:21 +0100 Subject: [PATCH 16/33] examine-indexers: apply tryExecuteAndNotify --- .../views/section-view-examine-indexers.ts | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) 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 166c1749c8..9a48b508cb 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 @@ -1,20 +1,19 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement, nothing } from 'lit'; +import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUIButtonState } from '@umbraco-ui/uui-button'; import { UmbModalService } from '../../../../../core/modal'; -import { UmbNotificationService } from '../../../../../core/notification'; -import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default'; -import { UmbContextConsumerMixin } from '@umbraco-cms/context-api'; import './section-view-examine-searchers'; -import { ApiError, Index, IndexerResource, ProblemDetails } from '@umbraco-cms/backend-api'; +import { Index, IndexerResource } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-examine-index') -export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(LitElement) { +export class UmbDashboardExamineIndexElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -93,30 +92,24 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit @state() private _loading = true; - private _notificationService?: UmbNotificationService; private _modalService?: UmbModalService; constructor() { super(); - this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => { - this._notificationService = instances['umbNotificationService']; + this.consumeAllContexts(['umbModalService'], (instances) => { this._modalService = instances['umbModalService']; }); } private async _getIndexData() { - try { - this._indexData = await IndexerResource.getIndexerByIndexName({ indexName: this.indexName }); - if (!this._indexData?.isHealthy) { - this._buttonState = 'waiting'; - } - } catch (e) { - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch index' }; - this._notificationService?.peek('danger', { data }); - } + const { data } = await tryExecuteAndNotify( + this, + IndexerResource.getIndexerByIndexName({ indexName: this.indexName }) + ); + this._indexData = data; + if (!this._indexData?.isHealthy) { + this._buttonState = 'waiting'; } this._loading = false; } @@ -144,18 +137,17 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit } private async _rebuild() { this._buttonState = 'waiting'; - try { - await IndexerResource.postIndexerByIndexNameRebuild({ indexName: this.indexName }); - this._buttonState = 'success'; - await this._getIndexData(); - } catch (e) { + const { error } = await tryExecuteAndNotify( + this, + IndexerResource.postIndexerByIndexNameRebuild({ indexName: this.indexName }) + ); + if (error) { this._buttonState = 'failed'; - if (e instanceof ApiError) { - const error = e as ProblemDetails; - const data: UmbNotificationDefaultData = { message: error.message ?? 'Rebuild error' }; - this._notificationService?.peek('danger', { data }); - } + return; } + + this._buttonState = 'success'; + await this._getIndexData(); } render() { From 4287922f9ba36bcc9dd0fdc6922e1dcc13aaa092 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:49:55 +0100 Subject: [PATCH 17/33] uui-app: apply tryExecuteAndNotify --- src/Umbraco.Web.UI.Client/src/app.ts | 32 +++++++++++----------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index 1980d5f434..5660d1453d 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -1,28 +1,28 @@ -import './core/css/custom-properties.css'; +// TODO: remove these imports when they are part of UUI +import '@umbraco-ui/uui-color-swatch'; +import '@umbraco-ui/uui-color-swatches'; import '@umbraco-ui/uui-modal'; import '@umbraco-ui/uui-modal-container'; import '@umbraco-ui/uui-modal-dialog'; import '@umbraco-ui/uui-modal-sidebar'; -import '@umbraco-ui/uui-color-swatch'; -import '@umbraco-ui/uui-color-swatches'; -import 'router-slot'; import 'element-internals-polyfill'; +import 'router-slot'; +import './core/css/custom-properties.css'; +import './auth'; -// TODO: remove these imports when they are part of UUI import type { Guard, IRoute } from 'router-slot/model'; import { UUIIconRegistryEssential } from '@umbraco-ui/uui'; -import { css, html, LitElement } from 'lit'; +import { css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbIconStore } from '@umbraco-cms/stores/icon/icon.store'; +import { UmbLitElement } from './core/element/lit-element.element'; +import { tryExecuteAndNotify } from './core/resources/tryExecuteAndNotify.method'; import { OpenAPI, RuntimeLevel, ServerResource } from '@umbraco-cms/backend-api'; -import { UmbContextProviderMixin } from '@umbraco-cms/context-api'; - -import './auth'; +import { UmbIconStore } from '@umbraco-cms/stores/icon/icon.store'; @customElement('umb-app') -export class UmbApp extends UmbContextProviderMixin(LitElement) { +export class UmbApp extends UmbLitElement { static styles = css` :host { overflow: hidden; @@ -95,14 +95,8 @@ export class UmbApp extends UmbContextProviderMixin(LitElement) { } private async _setInitStatus() { - try { - const serverStatus = await ServerResource.getServerStatus(); - if (serverStatus.serverStatus) { - this._runtimeLevel = serverStatus.serverStatus; - } - } catch (error) { - console.log(error); - } + const { data } = await tryExecuteAndNotify(this, ServerResource.getServerStatus()); + this._runtimeLevel = data?.serverStatus ?? RuntimeLevel.UNKNOWN; } private _redirect() { From 36ed1f223c9a5f630016ad947ec60ab2ed95e1fb Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:53:29 +0100 Subject: [PATCH 18/33] fix ResourceController by correctly implementing hostConnected as stub --- .../src/core/resources/resource.controller.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts b/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts index 06cf06721e..3a7b268f10 100644 --- a/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts @@ -40,11 +40,11 @@ export class UmbResourceController extends UmbController { }); } - hostConnected() { - this.hostConnected(); + hostConnected(): void { + // Do nothing } - hostDisconnected() { + hostDisconnected(): void { this.cancel(); } From fa9e436b6836e3a6fe15e566158b161728b93504 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:00:00 +0100 Subject: [PATCH 19/33] do not be so strict about awaiting tryExecuteAndNotify --- src/Umbraco.Web.UI.Client/eslint-local-rules.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index bae4cd16b0..5ec1820eed 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -51,7 +51,7 @@ module.exports = { // If methods called on *Resource classes are not already wrapped with `await tryExecuteAndNotify()`, then we should suggest to wrap them. CallExpression: function (node) { if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name.endsWith('Resource') && node.callee.property.type === 'Identifier' && node.callee.property.name !== 'constructor') { - const hasTryExecuteAndNotify = node.parent.parent.type === 'AwaitExpression' && node.parent.callee.name === 'tryExecuteAndNotify'; + const hasTryExecuteAndNotify = node.parent.callee.name === 'tryExecuteAndNotify'; if (!hasTryExecuteAndNotify) { context.report({ node, From c1e45deef78922f1321de8ca1d2b87a58e2bcaca Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:05:03 +0100 Subject: [PATCH 20/33] optimise check of tryExecuteAndNotify --- src/Umbraco.Web.UI.Client/eslint-local-rules.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index 5ec1820eed..79508d0358 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -51,7 +51,7 @@ module.exports = { // If methods called on *Resource classes are not already wrapped with `await tryExecuteAndNotify()`, then we should suggest to wrap them. CallExpression: function (node) { if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name.endsWith('Resource') && node.callee.property.type === 'Identifier' && node.callee.property.name !== 'constructor') { - const hasTryExecuteAndNotify = node.parent.callee.name === 'tryExecuteAndNotify'; + const hasTryExecuteAndNotify = node.parent && node.parent.callee && node.parent.callee.name === 'tryExecuteAndNotify'; if (!hasTryExecuteAndNotify) { context.report({ node, From bc125ffdc9bf2f4832997296bc8b9c0efec242c3 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:23:22 +0100 Subject: [PATCH 21/33] scope static functions --- .../src/core/resources/resource.controller.ts | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts b/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts index 3a7b268f10..5668c41180 100644 --- a/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/core/resources/resource.controller.ts @@ -6,25 +6,6 @@ import { ApiError, CancelablePromise, ProblemDetails } from '@umbraco-cms/backen import { UmbNotificationOptions, UmbNotificationService } from 'src/core/notification'; import { UmbNotificationDefaultData } from 'src/core/notification/layouts/default'; -/** - * Extract the ProblemDetails object from an ApiError. - * - * This assumes that all ApiErrors contain a ProblemDetails object in their body. - */ -function toProblemDetails(error: unknown): ProblemDetails | undefined { - if (error instanceof ApiError) { - const errorDetails = error.body as ProblemDetails; - return errorDetails; - } else if (error instanceof Error) { - return { - title: error.name, - detail: error.message, - }; - } - - return undefined; -} - export class UmbResourceController extends UmbController { #promise: Promise; @@ -49,13 +30,32 @@ export class UmbResourceController extends UmbController { } /** - * Wrap the {execute} function in a try/catch block and return a tuple with the result and the error. + * Extract the ProblemDetails object from an ApiError. + * + * This assumes that all ApiErrors contain a ProblemDetails object in their body. */ - async tryExecute(): Promise<{ data?: T; error?: ProblemDetails }> { + static toProblemDetails(error: unknown): ProblemDetails | undefined { + if (error instanceof ApiError) { + const errorDetails = error.body as ProblemDetails; + return errorDetails; + } else if (error instanceof Error) { + return { + title: error.name, + detail: error.message, + }; + } + + return undefined; + } + + /** + * Base execute function with a try/catch block and return a tuple with the result and the error. + */ + static async tryExecute(promise: Promise): Promise<{ data?: T; error?: ProblemDetails }> { try { - return { data: await this.#promise }; + return { data: await promise }; } catch (e) { - return { error: toProblemDetails(e) }; + return { error: UmbResourceController.toProblemDetails(e) }; } } @@ -64,7 +64,7 @@ export class UmbResourceController extends UmbController { * If the executor function throws an error, then show the details in a notification. */ async tryExecuteAndNotify(options?: UmbNotificationOptions): Promise<{ data?: T; error?: ProblemDetails }> { - const { data, error } = await this.tryExecute(); + const { data, error } = await UmbResourceController.tryExecute(this.#promise); if (error) { const data: UmbNotificationDefaultData = { From 5be59495f0bde45bf57f73c939408c75800774d1 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:23:34 +0100 Subject: [PATCH 22/33] add new function tryExecute --- src/Umbraco.Web.UI.Client/src/core/resources/index.ts | 1 + .../src/core/resources/tryExecute.method.ts | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/core/resources/tryExecute.method.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/index.ts b/src/Umbraco.Web.UI.Client/src/core/resources/index.ts index 6da0dee4b6..b5aa810083 100644 --- a/src/Umbraco.Web.UI.Client/src/core/resources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/core/resources/index.ts @@ -1,2 +1,3 @@ export * from './resource.controller'; +export * from './tryExecute.method'; export * from './tryExecuteAndNotify.method'; diff --git a/src/Umbraco.Web.UI.Client/src/core/resources/tryExecute.method.ts b/src/Umbraco.Web.UI.Client/src/core/resources/tryExecute.method.ts new file mode 100644 index 0000000000..a65503d760 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/resources/tryExecute.method.ts @@ -0,0 +1,5 @@ +import { UmbResourceController } from './resource.controller'; + +export function tryExecute(promise: Promise) { + return UmbResourceController.tryExecute(promise); +} From 693d9a7fbd10a962d3d104bb8f5ecc3cae09c4ef Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:23:44 +0100 Subject: [PATCH 23/33] setup eslint to support `tryExecute` --- src/Umbraco.Web.UI.Client/eslint-local-rules.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index 79508d0358..63b68d3363 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -51,7 +51,7 @@ module.exports = { // If methods called on *Resource classes are not already wrapped with `await tryExecuteAndNotify()`, then we should suggest to wrap them. CallExpression: function (node) { if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name.endsWith('Resource') && node.callee.property.type === 'Identifier' && node.callee.property.name !== 'constructor') { - const hasTryExecuteAndNotify = node.parent && node.parent.callee && node.parent.callee.name === 'tryExecuteAndNotify'; + const hasTryExecuteAndNotify = node.parent && node.parent.callee && (node.parent.callee.name === 'tryExecute' || node.parent.callee.name === 'tryExecuteAndNotify'); if (!hasTryExecuteAndNotify) { context.report({ node, From c956fcd88f556281d5f596ea360e92cdd946666d Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:24:08 +0100 Subject: [PATCH 24/33] installer: apply tryExecute --- .../database/installer-database.element.ts | 24 ++++++++++--------- .../src/installer/installer.context.ts | 23 +++++++----------- .../src/installer/installer.element.ts | 13 +++++----- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index 88cda151e7..977f2e1815 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -232,25 +232,27 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { } this._installerContext?.nextStep(); - this._installerContext - .requestInstall() - .then(() => this._handleFulfilled()) - .catch((error: unknown) => this._handleRejected(error)); + + const { data, error } = await tryExecuteAndNotify( + this, + InstallResource.postInstallSetup({ requestBody: this._installerContext?.getData() }) + ); + if (data) { + this._handleFulfilled(); + } else if (error) { + this._handleRejected(error); + } }; private _handleFulfilled() { + // TODO: The post install will probably return a user in the future, so we have to set that context somewhere to let the client know that it is authenticated console.warn('TODO: Set up real authentication'); sessionStorage.setItem('is-authenticated', 'true'); history.replaceState(null, '', '/content'); } - private _handleRejected(e: unknown) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - if (e.status === 400) { - this._installerContext?.setInstallStatus(error); - } - } + private _handleRejected(e: ProblemDetails) { + this._installerContext?.setInstallStatus(e); this._installerContext?.nextStep(); } diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts index 717ae07817..f4b11e3c2a 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts @@ -1,5 +1,6 @@ import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs'; import { Install, InstallResource, InstallSettings, ProblemDetails, TelemetryLevel } from '@umbraco-cms/backend-api'; +import { tryExecute } from '@umbraco-cms/resources'; /** * Context API for the installer @@ -95,17 +96,6 @@ export class UmbInstallerContext { return this._data.getValue(); } - /** - * Post the installation data to the API - * @public - * @return {*} - * @memberof UmbInstallerContext - */ - public requestInstall() { - // TODO: The post install will probably return a user in the future, so we have to set that context somewhere to let the client know that it is authenticated - return InstallResource.postInstallSetup({ requestBody: this.getData() }); - } - /** * Set the install status * @public @@ -121,9 +111,12 @@ export class UmbInstallerContext { * @private * @memberof UmbInstallerContext */ - private _loadInstallerSettings() { - InstallResource.getInstallSettings().then((installSettings) => { - this._settings.next(installSettings); - }); + private async _loadInstallerSettings() { + const { data, error } = await tryExecute(InstallResource.getInstallSettings()); + if (data) { + this._settings.next(data); + } else if (error) { + console.error(error.detail, error); + } } } diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts index 66e04f97bf..19614a9964 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts @@ -1,8 +1,7 @@ -import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { css, CSSResultGroup, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbInstallerContext } from './installer.context'; -import { UmbObserverMixin } from '@umbraco-cms/observable-api'; -import { UmbContextProviderMixin } from '@umbraco-cms/context-api'; +import { UmbLitElement } from '@umbraco-cms/element'; import './consent/installer-consent.element'; import './database/installer-database.element'; @@ -12,7 +11,7 @@ import './shared/layout/installer-layout.element'; import './user/installer-user.element'; @customElement('umb-installer') -export class UmbInstallerElement extends UmbContextProviderMixin(UmbObserverMixin(LitElement)) { +export class UmbInstallerElement extends UmbLitElement { static styles: CSSResultGroup = [css``]; @state() @@ -31,8 +30,10 @@ export class UmbInstallerElement extends UmbContextProviderMixin(UmbObserverMixi } private _observeCurrentStep() { - this.observe(this._umbInstallerContext.currentStepChanges(), (step) => { - this.step = step; + this.observe(this._umbInstallerContext.currentStepChanges(), (step) => { + if (step) { + this.step = step; + } }); } From 3e1e82b6e2324dfed6a6f557f6c42f942476bc4a Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:31:55 +0100 Subject: [PATCH 25/33] dashboard-telemetry: apply tryExecuteAndNotify --- .../telemetry/dashboard-telemetry.element.ts | 67 +++++++++---------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts index 544b2b1fa2..140e3b94f7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts @@ -1,12 +1,14 @@ +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { UUIButtonState } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement } from 'lit'; -import { unsafeHTML } from 'lit/directives/unsafe-html.js'; -import { customElement, state } from 'lit/decorators.js'; -import { ApiError, ProblemDetails, Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api'; +import { Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-telemetry') -export class UmbDashboardTelemetryElement extends LitElement { +export class UmbDashboardTelemetryElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -38,46 +40,32 @@ export class UmbDashboardTelemetryElement extends LitElement { } private async _setup() { - try { - const consentLevels = await TelemetryResource.getTelemetry({skip: 0, take: 3}); - this._telemetryLevels = consentLevels.items ?? []; - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - this._errorMessage = error.detail; - } - } + const telemetryLevels = await tryExecuteAndNotify(this, TelemetryResource.getTelemetry({ skip: 0, take: 3 })); + this._telemetryLevels = telemetryLevels.data?.items ?? []; - try { - const consentSetting = await TelemetryResource.getTelemetryLevel(); - this._telemetryFormData = consentSetting.telemetryLevel ?? TelemetryLevel.BASIC; - } catch (e) { - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - this._errorMessage = error.detail; - } - } + const telemetryLevel = await tryExecuteAndNotify(this, TelemetryResource.getTelemetryLevel()); + this._telemetryFormData = telemetryLevel.data?.telemetryLevel ?? TelemetryLevel.BASIC; } private _handleSubmit = async (e: CustomEvent) => { e.stopPropagation(); + this._buttonState = 'waiting'; - try { - await TelemetryResource.postTelemetryLevel({ + + const { error } = await tryExecuteAndNotify( + this, + TelemetryResource.postTelemetryLevel({ requestBody: { telemetryLevel: this._telemetryFormData }, - }); - this._buttonState = 'success'; - } catch (e) { + }) + ); + + if (error) { this._buttonState = 'failed'; - if (e instanceof ApiError) { - const error = e.body as ProblemDetails; - if (e.status === 400) { - this._errorMessage = error.detail || 'Unknown error, please try again'; - } - } else { - this._errorMessage = 'Unknown error, please try again'; - } + this._errorMessage = error.detail; + return; } + + this._buttonState = 'success'; }; private _handleChange(e: InputEvent) { @@ -146,7 +134,12 @@ export class UmbDashboardTelemetryElement extends LitElement { will be fully anonymized.

${this._renderSettingSlider()} - + Save From 4924e4a3964d3408c54387429a7a63e59ce0c53e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:34:40 +0100 Subject: [PATCH 26/33] revert accidental change to suggestion --- src/Umbraco.Web.UI.Client/eslint-local-rules.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index 63b68d3363..a4d6a82658 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -8,7 +8,7 @@ module.exports = { /** @type {import('eslint').Rule.RuleModule} */ 'bad-type-import': { meta: { - type: 'suggestion', + type: 'problem', docs: { description: 'Ensures the use of the `import type` operator from the `src/core/models/index.ts` file.', category: 'Best Practices', From 0527df54a7db1ce39f06d8d85d76367c5f0f9481 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:35:24 +0100 Subject: [PATCH 27/33] fix accidental reorganize of imports --- src/Umbraco.Web.UI.Client/src/app.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index 5660d1453d..deac04fcb6 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -1,3 +1,5 @@ +import './core/css/custom-properties.css'; + // TODO: remove these imports when they are part of UUI import '@umbraco-ui/uui-color-swatch'; import '@umbraco-ui/uui-color-swatches'; @@ -7,7 +9,6 @@ import '@umbraco-ui/uui-modal-dialog'; import '@umbraco-ui/uui-modal-sidebar'; import 'element-internals-polyfill'; import 'router-slot'; -import './core/css/custom-properties.css'; import './auth'; import type { Guard, IRoute } from 'router-slot/model'; From a64d6eb26f3264cbf82db69f9af93ec3ef8795d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:38:08 +0000 Subject: [PATCH 28/33] Bump json5 from 1.0.1 to 1.0.2 Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- src/Umbraco.Web.UI.Client/package-lock.json | 89 +++++++-------------- 1 file changed, 30 insertions(+), 59 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 4f5f763a91..ba00451a4e 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -4081,24 +4081,6 @@ "node": ">=8" } }, - "node_modules/@storybook/builder-webpack4/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/@storybook/builder-webpack4/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -11191,9 +11173,9 @@ } }, "node_modules/css-loader/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -15326,9 +15308,9 @@ } }, "node_modules/html-webpack-plugin/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -16908,9 +16890,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -25563,9 +25545,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -27872,9 +27854,9 @@ "dev": true }, "node_modules/webpack/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -31264,17 +31246,6 @@ "p-limit": "^2.2.0" } }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -36997,9 +36968,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -40129,9 +40100,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -41279,9 +41250,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonfile": { @@ -47921,9 +47892,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -49495,9 +49466,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" From bcae1045400797542657914f3ba30e847411a6cf Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:03:21 +0100 Subject: [PATCH 29/33] add missing importmap --- src/Umbraco.Web.UI.Client/web-test-runner.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index c4b63b7243..c4bef5c1ca 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -19,7 +19,7 @@ export default { '@umbraco-cms/observable-api': './src/core/observable-api/index.ts', '@umbraco-cms/utils': './src/core/utils/index.ts', '@umbraco-cms/test-utils': './src/core/test-utils/index.ts', - '@umbraco-cms/resources': './src/core/resources', + '@umbraco-cms/resources': './src/core/resources/index.ts', '@umbraco-cms/services': './src/core/services', '@umbraco-cms/extensions-registry': './src/core/extensions-registry/index.ts', }, From c2d93f0181d3f75b19412eb81c85a59a56c6749b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:33:41 +0100 Subject: [PATCH 30/33] upgrader: use correct context --- src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts index 6d4f3b75f3..4374ffccc6 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts @@ -4,7 +4,7 @@ import './upgrader-view.element'; import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UpgradeResource, UpgradeSettings } from '@umbraco-cms/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { tryExecute } from '@umbraco-cms/resources'; import { UmbLitElement } from '@umbraco-cms/element'; /** @@ -43,7 +43,7 @@ export class UmbUpgrader extends UmbLitElement { private async _setup() { this.fetching = true; - const { data, error } = await tryExecuteAndNotify(this, UpgradeResource.getUpgradeSettings()); + const { data, error } = await tryExecute(UpgradeResource.getUpgradeSettings()); if (data) { this.upgradeSettings = data; @@ -59,7 +59,7 @@ export class UmbUpgrader extends UmbLitElement { this.errorMessage = ''; this.upgrading = true; - const { error } = await tryExecuteAndNotify(this, UpgradeResource.postUpgradeAuthorize()); + const { error } = await tryExecute(UpgradeResource.postUpgradeAuthorize()); if (error) { this.errorMessage = error.detail || 'Unknown error, please try again'; From cabfe6d3b08e5996e301df18288b856d4f53a9cd Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:36:55 +0100 Subject: [PATCH 31/33] use correct api path --- .../src/core/mocks/domains/install.handlers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts index 5684fbb522..620ef6b26b 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts @@ -72,7 +72,7 @@ export const handlers = [ ); }), - rest.post(umbracoPath('/install/validateDatabase'), async (req, res, ctx) => { + rest.post(umbracoPath('/install/validate-database'), async (req, res, ctx) => { const body = await req.json(); if (body.name === 'validate') { From 4124c56b27dac5d945e656ec5e25269d25403bdd Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:37:25 +0100 Subject: [PATCH 32/33] installer: use tryExecute to handle errors directly on-page --- .../database/installer-database.element.ts | 25 ++++++++----------- .../src/installer/installer.context.ts | 3 ++- .../src/installer/installer.element.ts | 6 +++++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index 977f2e1815..674917a6e9 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -4,7 +4,6 @@ import { customElement, property, query, state } from 'lit/decorators.js'; import { UmbInstallerContext } from '../installer.context'; import { - ApiError, DatabaseInstall, DatabaseSettings, Install, @@ -13,7 +12,7 @@ import { ProblemDetails, } from '@umbraco-cms/backend-api'; import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { tryExecute } from '@umbraco-cms/resources'; @customElement('umb-installer-database') export class UmbInstallerDatabaseElement extends UmbLitElement { @@ -204,13 +203,12 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { providerName: selectedDatabase.providerName, }; - const { error } = await tryExecuteAndNotify( - this, + const { error } = await tryExecute( InstallResource.postInstallValidateDatabase({ requestBody: databaseDetails }) ); if (error) { - this._validationErrorMessage = error.detail; + this._validationErrorMessage = `The server could not validate the database connection. Details: ${error.detail}`; this._installButton.state = 'failed'; return; } @@ -228,19 +226,19 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { providerName: selectedDatabase.providerName, }; - this._installerContext?.appendData({ database }); + this._installerContext.appendData({ database }); } - this._installerContext?.nextStep(); + this._installerContext.nextStep(); - const { data, error } = await tryExecuteAndNotify( - this, - InstallResource.postInstallSetup({ requestBody: this._installerContext?.getData() }) + const { error } = await tryExecute( + InstallResource.postInstallSetup({ requestBody: this._installerContext.getData() }) ); - if (data) { - this._handleFulfilled(); - } else if (error) { + + if (error) { this._handleRejected(error); + } else { + this._handleFulfilled(); } }; @@ -253,7 +251,6 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { private _handleRejected(e: ProblemDetails) { this._installerContext?.setInstallStatus(e); - this._installerContext?.nextStep(); } private _onBack() { diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts index f4b11e3c2a..2a0db363fa 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts @@ -72,8 +72,8 @@ export class UmbInstallerContext { * @memberof UmbInstallerContext */ public reset(): void { - this._currentStep.next(1); this._installStatus.next(null); + this._currentStep.next(1); } /** @@ -117,6 +117,7 @@ export class UmbInstallerContext { this._settings.next(data); } else if (error) { console.error(error.detail, error); + this._installStatus.next(error); } } } diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts index 19614a9964..13e3da22fc 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts @@ -35,6 +35,12 @@ export class UmbInstallerElement extends UmbLitElement { this.step = step; } }); + + this.observe(this._umbInstallerContext.installStatusChanges(), (error) => { + if (error) { + this.step = 5; + } + }); } private _renderSection() { From e35851521dbbc63ee9a6017a81e0d751fed08752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 4 Jan 2023 13:55:36 +0100 Subject: [PATCH 33/33] correct error message color --- .../src/installer/error/installer-error.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts index 5063330362..404372d9be 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts @@ -23,7 +23,7 @@ export class UmbInstallerErrorElement extends UmbContextConsumerMixin(UmbObserve } #error-message { - color: var(--uui-color-error, red); + color: var(--uui-color-danger, red); } `, ];