From a2d5ee4123d92f7d460e98f5dd2853bfe68c06d6 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 13 Feb 2023 16:38:25 +0000 Subject: [PATCH 01/32] Hacking the planet - trying to add some DEBUG pane to help display what Contexts are available or events are firing --- src/Umbraco.Web.UI.Client/src/app.ts | 4 +- .../shared/components/debug/debug.element.ts | 103 ++++++++++++++++++ .../src/backoffice/shared/components/index.ts | 2 + 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index 22ab81b634..f556e4ae86 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -149,7 +149,9 @@ export class UmbApp extends UmbLitElement { } render() { - return html``; + return html` + + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts new file mode 100644 index 0000000000..5af1998733 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -0,0 +1,103 @@ +import { UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, LitElement, nothing } from 'lit'; +import { styleMap } from 'lit-html/directives/style-map'; +import { customElement, property, state } from 'lit/decorators.js'; + + +@customElement('umb-debug') +export class UmbDebug extends LitElement { + static styles = [ + UUITextStyles, + css` + :host { + } + + #debug { + display: block; + font-family: monospace; + /* background:red; */ + + position:absolute; + bottom:0; + left:0; + z-index:10000; + width:calc(100% - 20px); + + padding:10px; + } + + #debug:hover { + /* background-color:blue; */ + } + + .events { + background-color:var(--uui-color-danger); + color:var(--uui-color-selected-contrast); + height:0; + transition: height 0.3s ease-out; + } + + .events.open { + height:200px; + padding:10px; + } + + h4 { + margin:0; + } + + `, + ]; + + @property({reflect: true, type: Boolean}) + enabled = false; + + @state() + private _debugPaneOpen = false; + + private _toggleDebugPane() { + this._debugPaneOpen = !this._debugPaneOpen; + } + + constructor() { + super(); + + // Get outer element + const app = window.document.querySelector('umb-app'); + + console.log('root app', app); + app?.addEventListener(umbContextRequestEventType as unknown as UmbContextRequestEventImplementation, (e) => { + // Console.log event + console.log('Some event', e.type); + console.log('Some event thing', e); + console.log('Some event thing', e.contextAlias); + + }); + + //this.addEventListener('click', (e) => console.log(e.type, e.target.localName)); + } + + render() { + + if(this.enabled){ + return html` +
+ Debug +
+

Events

+ +
+
+ `; + } + + return nothing; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-debug': UmbDebug; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts index 77c784844f..31fabab8cb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts @@ -31,3 +31,5 @@ import './input-document-picker/input-document-picker.element'; import './empty-state/empty-state.element'; import './color-picker/color-picker.element'; + +import './debug/debug.element'; \ No newline at end of file From 98f98e2e2891697e197eb80b9d0dc75610f082e6 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 13 Feb 2023 21:37:35 +0000 Subject: [PATCH 02/32] Add bug icon into button If this is going to be placed into any child component/element - need to think how it will work in places woth tiny/limited space in UI --- .../shared/components/debug/debug.element.ts | 76 +++++++++---------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 5af1998733..4c5a1bb016 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,8 +1,7 @@ -import { UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement, nothing } from 'lit'; -import { styleMap } from 'lit-html/directives/style-map'; import { customElement, property, state } from 'lit/decorators.js'; +import { UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; @customElement('umb-debug') @@ -10,43 +9,34 @@ export class UmbDebug extends LitElement { static styles = [ UUITextStyles, css` - :host { - } - - #debug { - display: block; + #container { + display: block; font-family: monospace; - /* background:red; */ - position:absolute; - bottom:0; - left:0; - z-index:10000; - width:calc(100% - 20px); + position:absolute; + bottom:0; + left:0; + z-index:10000; - padding:10px; - } + width:calc(100% - 20px); + padding:10px; + } - #debug:hover { - /* background-color:blue; */ - } + .events { + background-color:var(--uui-color-danger); + color:var(--uui-color-selected-contrast); + height:0; + transition: height 0.3s ease-out; + } - .events { - background-color:var(--uui-color-danger); - color:var(--uui-color-selected-contrast); - height:0; - transition: height 0.3s ease-out; - } - - .events.open { - height:200px; - padding:10px; - } - - h4 { - margin:0; - } + .events.open { + height:200px; + padding:10px; + } + h4 { + margin:0; + } `, ]; @@ -66,7 +56,6 @@ export class UmbDebug extends LitElement { // Get outer element const app = window.document.querySelector('umb-app'); - console.log('root app', app); app?.addEventListener(umbContextRequestEventType as unknown as UmbContextRequestEventImplementation, (e) => { // Console.log event console.log('Some event', e.type); @@ -82,16 +71,19 @@ export class UmbDebug extends LitElement { if(this.enabled){ return html` -
- Debug -
-

Events

- -
+
+ + + Debug + + +
+

Events

+
- `; + `; } - + return nothing; } } From c4fa350b047a2bc5d9c5d09c97e07081d341e05d Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 14 Feb 2023 12:08:10 +0000 Subject: [PATCH 03/32] Remove debug element from main umb-app --- src/Umbraco.Web.UI.Client/src/app.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index f556e4ae86..22ab81b634 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -149,9 +149,7 @@ export class UmbApp extends UmbLitElement { } render() { - return html` - - `; + return html``; } } From c00b77791e2d3d636af28dade8cf63b29189214a Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 14 Feb 2023 12:08:30 +0000 Subject: [PATCH 04/32] Rework based on Mads notes --- .../context-api/provide/context-provider.ts | 14 ++++++ .../dashboard-published-status.element.ts | 1 + .../shared/components/debug/debug.element.ts | 46 +++++++++++-------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts index ddad843889..3f32cc247b 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts @@ -31,6 +31,9 @@ export class UmbContextProvider { public hostConnected() { this.host.addEventListener(umbContextRequestEventType, this._handleContextRequest); this.host.dispatchEvent(new UmbContextProvideEventImplementation(this._contextAlias)); + + // Listen to our debug event 'umb:debug-contexts' + this.host.addEventListener('umb:debug-contexts', this._handleDebugContextRequest); } /** @@ -54,6 +57,17 @@ export class UmbContextProvider { event.callback(this.#instance); }; + private _handleDebugContextRequest = (event: Event) => { + + + console.log('Context Alias:', this._contextAlias); + console.log('Context Instance:', this.#instance); + + // Do I update an array on the event which + // The Debug element can then render in UI?! + console.log('Event:', event); + }; + destroy(): void { // I want to make sure to call this, but for now it was too overwhelming to require the destroy method on context instances. 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 c91b095df2..58a1db4df7 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 @@ -133,6 +133,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { render() { return html` +

${this._publishedStatusText}

div { padding:10px; } @@ -43,6 +43,9 @@ export class UmbDebug extends LitElement { @property({reflect: true, type: Boolean}) enabled = false; + @property({type: Array}) + contextAliases = ['UmbTemplateDetailStore', 'umbLanguageStore']; + @state() private _debugPaneOpen = false; @@ -50,22 +53,18 @@ export class UmbDebug extends LitElement { this._debugPaneOpen = !this._debugPaneOpen; } - constructor() { - super(); + connectedCallback(): void { + super.connectedCallback(); - // Get outer element - const app = window.document.querySelector('umb-app'); + // Create event that bubbles up through the DOM + const event = new CustomEvent('umb:debug-contexts', { + bubbles: true, + composed: true + }); - app?.addEventListener(umbContextRequestEventType as unknown as UmbContextRequestEventImplementation, (e) => { - // Console.log event - console.log('Some event', e.type); - console.log('Some event thing', e); - console.log('Some event thing', e.contextAlias); - - }); - - //this.addEventListener('click', (e) => console.log(e.type, e.target.localName)); - } + // Dispatch it + this.dispatchEvent(event); + } render() { @@ -78,7 +77,14 @@ export class UmbDebug extends LitElement {
-

Events

+
+

Context Aliases to consume

+
    + ${this.contextAliases.map((ctxAlias) => + html`
  • ${ctxAlias}
  • ` + )} +
+
`; From 5c2236fe409c71ef905b2e6757e0637c57d67a94 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 14 Feb 2023 14:12:51 +0000 Subject: [PATCH 05/32] Some work witrh help of pairing with Mads to get the contexts collected and then passed to callback on original firing event --- .../consume/context-request.event.ts | 8 +++ .../context-api/provide/context-provider.ts | 24 ++++---- src/Umbraco.Web.UI.Client/src/app.ts | 11 ++++ .../shared/components/debug/debug.element.ts | 57 ++++++++++++++----- 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts index 9d8fa86dec..ab96c5bd51 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts @@ -1,6 +1,7 @@ import { UmbContextToken } from '../context-token'; export const umbContextRequestEventType = 'umb:context-request'; +export const umbDebugContextEventType = 'umb:debug-contexts'; export type UmbContextCallback = (instance: T) => void; @@ -31,3 +32,10 @@ export class UmbContextRequestEventImplementation extends Event imp export const isUmbContextRequestEvent = (event: Event): event is UmbContextRequestEventImplementation => { return event.type === umbContextRequestEventType; }; + + +export class UmbContextDebugRequest extends Event { + public constructor(public readonly callback:any) { + super(umbDebugContextEventType, { bubbles: true, composed: true, cancelable: false }); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts index 3f32cc247b..afeb0b50cb 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts @@ -1,4 +1,5 @@ -import { umbContextRequestEventType, isUmbContextRequestEvent } from '../consume/context-request.event'; +import { map } from 'rxjs'; +import { umbContextRequestEventType, isUmbContextRequestEvent, umbDebugContextEventType } from '../consume/context-request.event'; import { UmbContextToken } from '../context-token'; import { UmbContextProvideEventImplementation } from './context-provide.event'; @@ -33,7 +34,7 @@ export class UmbContextProvider { this.host.dispatchEvent(new UmbContextProvideEventImplementation(this._contextAlias)); // Listen to our debug event 'umb:debug-contexts' - this.host.addEventListener('umb:debug-contexts', this._handleDebugContextRequest); + this.host.addEventListener(umbDebugContextEventType, this._handleDebugContextRequest); } /** @@ -57,15 +58,18 @@ export class UmbContextProvider { event.callback(this.#instance); }; - private _handleDebugContextRequest = (event: Event) => { + private _handleDebugContextRequest = (event: any) => { + // If the event doesn't have an instances property, create it. + if(!event.instances){ + event.instances = new Map(); + } - - console.log('Context Alias:', this._contextAlias); - console.log('Context Instance:', this.#instance); - - // Do I update an array on the event which - // The Debug element can then render in UI?! - console.log('Event:', event); + // If the event doesn't have an instance for this context, add it. + // Nearest to the DOM element of will be added first + // as contexts can change/override deeper in the DOM + if(!event.instances.has(this._contextAlias)){ + event.instances.set(this._contextAlias, this.#instance); + } }; diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index 22ab81b634..18d11ccbf2 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -19,6 +19,7 @@ import { UmbLitElement } from '@umbraco-cms/element'; import { tryExecuteAndNotify } from '@umbraco-cms/resources'; import { OpenAPI, RuntimeLevelModel, ServerResource } from '@umbraco-cms/backend-api'; import { UmbIconStore } from '@umbraco-cms/store'; +import { UmbContextDebugRequest, umbDebugContextEventType } from '@umbraco-cms/context-api'; @customElement('umb-app') export class UmbApp extends UmbLitElement { @@ -83,6 +84,16 @@ export class UmbApp extends UmbLitElement { await this._setInitStatus(); await this._registerExtensionManifestsFromServer(); this._redirect(); + + // Listen for the debug event from the component + this.addEventListener(umbDebugContextEventType, (event: any) => { + // Once we got to the outter most component + // we can send the event containing all the contexts + // we have collected whilst coming up through the DOM + // and pass it back down to the callback in + // the component that originally fired the event + event.callback(event.instances); + }); } private async _setup() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index c3792acc7d..9afe71faab 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,7 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; +import { UmbContextDebugRequest, UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; @customElement('umb-debug') @@ -27,7 +27,7 @@ export class UmbDebug extends LitElement { } .events.open { - height:200px; + height:auto; } .events > div { @@ -43,8 +43,8 @@ export class UmbDebug extends LitElement { @property({reflect: true, type: Boolean}) enabled = false; - @property({type: Array}) - contextAliases = ['UmbTemplateDetailStore', 'umbLanguageStore']; + @property() + contextAliases = new Map(); @state() private _debugPaneOpen = false; @@ -55,15 +55,13 @@ export class UmbDebug extends LitElement { connectedCallback(): void { super.connectedCallback(); - - // Create event that bubbles up through the DOM - const event = new CustomEvent('umb:debug-contexts', { - bubbles: true, - composed: true - }); - + // Dispatch it - this.dispatchEvent(event); + this.dispatchEvent(new UmbContextDebugRequest((instances)=> { + console.log('I have contexts now', instances); + + this.contextAliases = instances; + })); } render() { @@ -80,9 +78,7 @@ export class UmbDebug extends LitElement {

Context Aliases to consume

    - ${this.contextAliases.map((ctxAlias) => - html`
  • ${ctxAlias}
  • ` - )} + ${this._renderContextAliases()}
@@ -92,6 +88,37 @@ export class UmbDebug extends LitElement { return nothing; } + + private _renderContextAliases() { + const aliases = []; + + for (const [alias, instance] of this.contextAliases) { + aliases.push( + html` +
  • + ${alias} +
      + ${this._renderInstance(instance)} +
    +
  • ` + ); + } + + return aliases; + } + + private _renderInstance(instance: any) { + const instanceKeys = []; + + for(const key in instance) { + // Goes KABOOM - if try to loop over the class/object + // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); + + instanceKeys.push(html`
  • ${key}
  • `); + } + + return instanceKeys; + } } declare global { From 0430b3b2e2174a0a15257a6d9c7e58f55c377f72 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 14 Feb 2023 14:59:29 +0000 Subject: [PATCH 06/32] Try and display simple string values --- .../shared/components/debug/debug.element.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 9afe71faab..eeddd4ec30 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -96,7 +96,7 @@ export class UmbDebug extends LitElement { aliases.push( html`
  • - ${alias} + Context: ${alias}
      ${this._renderInstance(instance)}
    @@ -114,7 +114,15 @@ export class UmbDebug extends LitElement { // Goes KABOOM - if try to loop over the class/object // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - instanceKeys.push(html`
  • ${key}
  • `); + // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); + + const value = instance[key]; + if(typeof value === 'string'){ + instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); + } + else { + instanceKeys.push(html`
  • ${key}
  • `); + } } return instanceKeys; From e311465a1e0d2d28ce0b98b8f1903fcba49d0bce Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 15 Feb 2023 09:06:31 +0000 Subject: [PATCH 07/32] Remove unused import --- .../libs/context-api/provide/context-provider.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts index f9b1bfd189..c9ce3ab9c3 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts @@ -1,4 +1,3 @@ -import { map } from 'rxjs'; import { umbContextRequestEventType, isUmbContextRequestEvent, umbDebugContextEventType } from '../consume/context-request.event'; import { UmbContextToken } from '../context-token'; import { UmbContextProvideEventImplementation } from './context-provide.event'; @@ -72,6 +71,7 @@ export class UmbContextProvider { if(!event.instances){ event.instances = new Map(); } + // If the event doesn't have an instance for this context, add it. // Nearest to the DOM element of will be added first // as contexts can change/override deeper in the DOM @@ -80,7 +80,6 @@ export class UmbContextProvider { } }; - destroy(): void { // I want to make sure to call this, but for now it was too overwhelming to require the destroy method on context instances. (this.#instance as any).destroy?.(); From 6da0a016f2dfea3c2af4576a3d34fa4979e4ff05 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:22:32 +0100 Subject: [PATCH 08/32] add method to get method names of instance --- .../shared/components/debug/debug.element.ts | 118 +++++++++++------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index eeddd4ec30..5bb8792dfc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,8 +1,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbContextDebugRequest, UmbContextRequestEventImplementation, umbContextRequestEventType } from '@umbraco-cms/context-api'; - +import { + UmbContextDebugRequest, + UmbContextRequestEventImplementation, + umbContextRequestEventType, +} from '@umbraco-cms/context-api'; @customElement('umb-debug') export class UmbDebug extends LitElement { @@ -13,63 +16,64 @@ export class UmbDebug extends LitElement { display: block; font-family: monospace; - z-index:10000; + z-index: 10000; - width:100%; - padding:10px 0; + width: 100%; + padding: 10px 0; } .events { - background-color:var(--uui-color-danger); - color:var(--uui-color-selected-contrast); - height:0; + background-color: var(--uui-color-danger); + color: var(--uui-color-selected-contrast); + height: 0; transition: height 0.3s ease-out; } .events.open { - height:auto; + height: auto; } .events > div { - padding:10px; + padding: 10px; } h4 { - margin:0; + margin: 0; } `, ]; - @property({reflect: true, type: Boolean}) - enabled = false; + @property({ reflect: true, type: Boolean }) + enabled = false; @property() contextAliases = new Map(); - @state() + @state() private _debugPaneOpen = false; - private _toggleDebugPane() { - this._debugPaneOpen = !this._debugPaneOpen; - } + private _toggleDebugPane() { + this._debugPaneOpen = !this._debugPaneOpen; + } connectedCallback(): void { super.connectedCallback(); - - // Dispatch it - this.dispatchEvent(new UmbContextDebugRequest((instances)=> { - console.log('I have contexts now', instances); - this.contextAliases = instances; - })); + // Dispatch it + this.dispatchEvent( + new UmbContextDebugRequest((instances) => { + console.log('I have contexts now', instances); + + this.contextAliases = instances; + }) + ); } render() { - - if(this.enabled){ - return html` -
    - + if (this.enabled) { + return html` +
    + Debug @@ -80,13 +84,13 @@ export class UmbDebug extends LitElement {
      ${this._renderContextAliases()}
    -
    +
    - + `; - } + } - return nothing; + return nothing; } private _renderContextAliases() { @@ -94,14 +98,13 @@ export class UmbDebug extends LitElement { for (const [alias, instance] of this.contextAliases) { aliases.push( - html` -
  • - Context: ${alias} -
      - ${this._renderInstance(instance)} -
    -
  • ` - ); + html`
  • + Context: ${alias} +
      + ${this._renderInstance(instance)} +
    +
  • ` + ); } return aliases; @@ -110,23 +113,48 @@ export class UmbDebug extends LitElement { private _renderInstance(instance: any) { const instanceKeys = []; - for(const key in instance) { + if (typeof instance === 'object') { + const methodNames = this.getClassMethodNames(instance); + instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); + // instanceKeys.push(html`
  • Method -
  • `); + } + + for (const key in instance) { + if (key.startsWith('_')) { + continue; + } // Goes KABOOM - if try to loop over the class/object // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); const value = instance[key]; - if(typeof value === 'string'){ - instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - } - else { + if (typeof value === 'string') { + instanceKeys.push(html`
  • ${key} = ${value}
  • `); + } else { instanceKeys.push(html`
  • ${key}
  • `); } } return instanceKeys; } + + private getClassMethodNames(klass: any) { + const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; + const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; + const deepFunctions = (x: any): any => + x !== Object.prototype && + Object.getOwnPropertyNames(x) + .filter((name) => isGetter(x, name) || isFunction(x, name)) + .concat(deepFunctions(Object.getPrototypeOf(x)) || []); + const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); + + const allMethods = + typeof klass.prototype === 'undefined' + ? distinctDeepFunctions(klass) + : Object.getOwnPropertyNames(klass.prototype); + return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); + } } declare global { From 00662c914494db8380d9661160afa55cb62aed24 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:32:34 +0100 Subject: [PATCH 09/32] add type information --- .../shared/components/debug/debug.element.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 5bb8792dfc..10e2f55e8c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,11 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement, nothing } from 'lit'; +import { css, html, LitElement, nothing, TemplateResult } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { - UmbContextDebugRequest, - UmbContextRequestEventImplementation, - umbContextRequestEventType, -} from '@umbraco-cms/context-api'; +import { UmbContextDebugRequest } from '@umbraco-cms/context-api'; @customElement('umb-debug') export class UmbDebug extends LitElement { @@ -61,7 +57,7 @@ export class UmbDebug extends LitElement { // Dispatch it this.dispatchEvent( - new UmbContextDebugRequest((instances) => { + new UmbContextDebugRequest((instances: Map) => { console.log('I have contexts now', instances); this.contextAliases = instances; @@ -100,6 +96,7 @@ export class UmbDebug extends LitElement { aliases.push( html`
  • Context: ${alias} + (${instance.toString()})
      ${this._renderInstance(instance)}
    @@ -111,12 +108,15 @@ export class UmbDebug extends LitElement { } private _renderInstance(instance: any) { - const instanceKeys = []; + const instanceKeys: TemplateResult[] = []; - if (typeof instance === 'object') { - const methodNames = this.getClassMethodNames(instance); + if (typeof instance !== 'object') { + return instanceKeys; + } + + const methodNames = this.getClassMethodNames(instance); + if (methodNames.length) { instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); - // instanceKeys.push(html`
  • Method -
  • `); } for (const key in instance) { @@ -132,7 +132,7 @@ export class UmbDebug extends LitElement { if (typeof value === 'string') { instanceKeys.push(html`
  • ${key} = ${value}
  • `); } else { - instanceKeys.push(html`
  • ${key}
  • `); + instanceKeys.push(html`
  • ${key} (${typeof value})
  • `); } } From c1ae1aae6b778c40664e72ee55f1db92a8aa067b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:34:30 +0100 Subject: [PATCH 10/32] use typeof instead as it works with simple types --- .../src/backoffice/shared/components/debug/debug.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 10e2f55e8c..ad695d592a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -96,7 +96,7 @@ export class UmbDebug extends LitElement { aliases.push( html`
  • Context: ${alias} - (${instance.toString()}) + (${typeof instance})
      ${this._renderInstance(instance)}
    From aee33197df6f369f422c4bb8f81a01e88785f995 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:39:39 +0100 Subject: [PATCH 11/32] add support for functions and primitives --- .../shared/components/debug/debug.element.ts | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index ad695d592a..3648a424bb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -110,30 +110,32 @@ export class UmbDebug extends LitElement { private _renderInstance(instance: any) { const instanceKeys: TemplateResult[] = []; - if (typeof instance !== 'object') { - return instanceKeys; - } - - const methodNames = this.getClassMethodNames(instance); - if (methodNames.length) { - instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); - } - - for (const key in instance) { - if (key.startsWith('_')) { - continue; + if (typeof instance === 'function') { + return instanceKeys.push(html`
  • Callable Function
  • `); + } else if (typeof instance === 'object') { + const methodNames = this.getClassMethodNames(instance); + if (methodNames.length) { + instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); } - // Goes KABOOM - if try to loop over the class/object - // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); + for (const key in instance) { + if (key.startsWith('_')) { + continue; + } + // Goes KABOOM - if try to loop over the class/object + // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - const value = instance[key]; - if (typeof value === 'string') { - instanceKeys.push(html`
  • ${key} = ${value}
  • `); - } else { - instanceKeys.push(html`
  • ${key} (${typeof value})
  • `); + // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); + + const value = instance[key]; + if (typeof value === 'string') { + instanceKeys.push(html`
  • ${key} = ${value}
  • `); + } else { + instanceKeys.push(html`
  • ${key} (${typeof value})
  • `); + } } + } else { + instanceKeys.push(html`
  • Context is a primitive with value: ${instance}
  • `); } return instanceKeys; From 1be4da9f3b802cf4b8f5050c5ee58b4d288e8cd6 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:56:32 +0100 Subject: [PATCH 12/32] fix height transition + add scroll --- .../backoffice/shared/components/debug/debug.element.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 3648a424bb..9208c35073 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -21,12 +21,14 @@ export class UmbDebug extends LitElement { .events { background-color: var(--uui-color-danger); color: var(--uui-color-selected-contrast); - height: 0; - transition: height 0.3s ease-out; + max-height: 0; + transition: max-height 0.15s ease-out; + overflow: hidden; } .events.open { - height: auto; + max-height: 500px; + overflow: auto; } .events > div { From c2fab69600a7424a86a7f56c494aaefaffd63d3b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 15 Feb 2023 16:42:50 +0000 Subject: [PATCH 13/32] Adds way to open debug info in a dialog * UI needs tidying up - spacing * Consider dropping the other UI approach and use dialog only * Need to ensure all typed * Neaten/refactor code if needed * Lint code --- .../modal-views/fields-viewer.element.ts | 6 +- .../dashboard-published-status.element.ts | 2 +- .../shared/components/debug/debug.element.ts | 115 ++++++++---- .../components/debug/debug.modal.element.ts | 163 ++++++++++++++++++ .../src/backoffice/shared/components/index.ts | 3 +- 5 files changed, 248 insertions(+), 41 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts index 6e81567c79..e55b6b4b22 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts @@ -16,11 +16,7 @@ export class UmbModalLayoutFieldsViewerElement extends UmbModalLayoutElement
    +

    ${this._publishedStatusText}

    { + this._modalService = modalService; + }); + } + connectedCallback(): void { super.connectedCallback(); // Dispatch it this.dispatchEvent( - new UmbContextDebugRequest((instances: Map) => { - console.log('I have contexts now', instances); + new UmbContextDebugRequest((contexts: Map) => { - this.contextAliases = instances; + // The Contexts are collected + // When travelling up through the DOM from this element + // to the root of which then uses the callback prop + // of the this event tha has been raised to assign the contexts + // back to this property of the WebComponent + this.contexts = contexts; }) ); } render() { - if (this.enabled) { - return html` -
    - - - Debug - + if (this.enabled) { + return this.useDialog ? this._renderDialog() : this._renderPanel(); + } else { + return nothing; + } + + } -
    -
    -

    Context Aliases to consume

    -
      - ${this._renderContextAliases()} -
    -
    + private _toggleDebugPane() { + this._debugPaneOpen = !this._debugPaneOpen; + } + + private _openDialog() { + const modalHandler = this._modalService?.open('umb-debug-modal-layout', { size: 'medium', type: 'sidebar', data:{ contexts: this.contexts }}); + + modalHandler?.onClose().then((data) => { + // if any data is supplied on close, it will be available here. + console.log('modal closed data', data); + }); + } + + + + private _renderDialog() { + return html` +
    + + Debug + +
    `; + } + + private _renderPanel(){ + return html` +
    + + + Debug + + +
    +
    +

    Context Aliases to consume

    +
      + ${this._renderContextAliases()} +
    - `; - } - - return nothing; +
    `; } private _renderContextAliases() { const aliases = []; - for (const [alias, instance] of this.contextAliases) { + for (const [alias, instance] of this.contexts) { aliases.push( html`
  • Context: ${alias} @@ -124,10 +175,6 @@ export class UmbDebug extends LitElement { if (key.startsWith('_')) { continue; } - // Goes KABOOM - if try to loop over the class/object - // instanceKeys.push(html`
  • ${key} = ${instance[key]}
  • `); - - // console.log(`key: ${key} = ${value} TYPEOF: ${typeof value}`); const value = instance[key]; if (typeof value === 'string') { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts new file mode 100644 index 0000000000..56f898c6d5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -0,0 +1,163 @@ +import { css, html, nothing, TemplateResult } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { UUITextStyles } from '@umbraco-ui/uui-css'; +import { UmbModalHandler, UmbModalLayoutElement } from '@umbraco-cms/modal'; + +@customElement('umb-debug-modal-layout') +export class UmbDebugModalLayout extends UmbModalLayoutElement { + static styles = [ + UUITextStyles, + css` + uui-dialog-layout { + display: flex; + flex-direction: column; + height: 100%; + + padding: var(--uui-size-space-5); + box-sizing: border-box; + } + + uui-scroll-container { + overflow-y: scroll; + max-height: 100%; + min-height: 0; + flex: 1; + } + + uui-icon { + vertical-align: text-top; + color: var(--uui-color-danger); + } + + .context { + padding:15px 0; + border-bottom:1px solid var(--uui-color-danger-emphasis); + } + + h3 { + margin-top: 0; + margin-bottom: 0; + } + + h3 > span { + border-radius: var(--uui-size-4); + background-color: var(--uui-color-danger); + color: var(--uui-color-danger-contrast); + padding: 8px; + font-size: 12px; + } + + + ul { + margin-top: 0; + } + `, + ]; + + + // the modal handler will be injected into the element when the modal is opened. + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + private _handleClose() { + /* Optional data of any type can be applied to the close method to pass it + to the modal parent through the onClose promise. */ + //this.modalHandler?.close('MY DATA'); + this.modalHandler?.close(); + } + + render() { + return html` + + + Debug: Contexts + + + ${this._renderContextAliases()} + + Close + + `; + } + + private _renderContextAliases() { + if(!this.data) { + return nothing; + } + + const aliases = []; + for (const [alias, instance] of this.data.contexts) { + aliases.push( + html` +
    +

    ${alias} ${typeof instance}

    + ${this._renderInstance(instance)} +
    ` + ); + } + + return aliases; + } + + private _renderInstance(instance: any) { + const instanceKeys: TemplateResult[] = []; + + if (typeof instance === 'function') { + return instanceKeys.push(html`
  • Callable Function
  • `); + } else if (typeof instance === 'object') { + const methodNames = this.getClassMethodNames(instance); + if (methodNames.length) { + instanceKeys.push( + html` +

    Methods

    +
      + ${methodNames.map((methodName) => html`
    • ${methodName}
    • `)} +
    + `); + } + + instanceKeys.push(html`

    Properties

    `); + + for (const key in instance) { + if (key.startsWith('_')) { + continue; + } + + const value = instance[key]; + if (typeof value === 'string') { + instanceKeys.push(html`
  • ${key} = ${value}
  • `); + } else { + instanceKeys.push(html`
  • ${key} Type (${typeof value})
  • `); + } + } + } else { + instanceKeys.push(html`
  • Context is a primitive with value: ${instance}
  • `); + } + + return instanceKeys; + } + + + private getClassMethodNames(klass: any) { + const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; + const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; + const deepFunctions = (x: any): any => + x !== Object.prototype && + Object.getOwnPropertyNames(x) + .filter((name) => isGetter(x, name) || isFunction(x, name)) + .concat(deepFunctions(Object.getPrototypeOf(x)) || []); + const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); + + const allMethods = + typeof klass.prototype === 'undefined' + ? distinctDeepFunctions(klass) + : Object.getOwnPropertyNames(klass.prototype); + return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-debug-modal-layout': UmbDebugModalLayout; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts index c9602d9759..b09a13320e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts @@ -31,4 +31,5 @@ import './input-document-picker/input-document-picker.element'; import './empty-state/empty-state.element'; import './color-picker/color-picker.element'; -import './debug/debug.element'; \ No newline at end of file +import './debug/debug.element'; +import './debug/debug.modal.element'; \ No newline at end of file From 16cde515c2698df89b7a3bcd1cfdf59f3b645ed9 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:12:39 +0000 Subject: [PATCH 14/32] Update src/backoffice/shared/components/debug/debug.modal.element.ts Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../backoffice/shared/components/debug/debug.modal.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index 56f898c6d5..d8e85fa64f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -4,7 +4,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbModalHandler, UmbModalLayoutElement } from '@umbraco-cms/modal'; @customElement('umb-debug-modal-layout') -export class UmbDebugModalLayout extends UmbModalLayoutElement { +export class UmbDebugModalLayout extends UmbModalLayoutElement { static styles = [ UUITextStyles, css` From 2e3aafbc01692215fe70bf353e4f19f2e776db88 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:12:54 +0000 Subject: [PATCH 15/32] Update src/backoffice/shared/components/debug/debug.element.ts Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../src/backoffice/shared/components/debug/debug.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 726fa1cb6c..3a9e3d9272 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -56,7 +56,7 @@ export class UmbDebug extends UmbLitElement { enabled = false; @property({ reflect: true, type: Boolean }) - useDialog = false; + dialog = false; @property() contexts = new Map(); From 64ecdc69aace616e8b532a32b5e69b88457d7bb3 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:13:42 +0000 Subject: [PATCH 16/32] Update src/backoffice/shared/components/debug/debug.element.ts Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../src/backoffice/shared/components/debug/debug.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 3a9e3d9272..76c4c34c89 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -92,7 +92,7 @@ export class UmbDebug extends UmbLitElement { render() { if (this.enabled) { - return this.useDialog ? this._renderDialog() : this._renderPanel(); + return this.dialog ? this._renderDialog() : this._renderPanel(); } else { return nothing; } From a42cc1bdb256ea579781ea60a2dde511490bd696 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:13:52 +0000 Subject: [PATCH 17/32] Update src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../published-status/dashboard-published-status.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c9aee3291c..e7693ba27c 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 @@ -133,7 +133,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { render() { return html` - +

    ${this._publishedStatusText}

    Date: Thu, 16 Feb 2023 20:26:36 +0000 Subject: [PATCH 18/32] Remove modalHandler as its in the base class --- .../backoffice/shared/components/debug/debug.modal.element.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index d8e85fa64f..8b93a125d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -55,10 +55,6 @@ export class UmbDebugModalLayout extends UmbModalLayoutElement { ]; - // the modal handler will be injected into the element when the modal is opened. - @property({ attribute: false }) - modalHandler?: UmbModalHandler; - private _handleClose() { /* Optional data of any type can be applied to the close method to pass it to the modal parent through the onClose promise. */ From 4e41078d46c713ac45c088bb248eafd68af36722 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:26:58 +0000 Subject: [PATCH 19/32] Remove comment copied from example code in Storybook docs --- .../backoffice/shared/components/debug/debug.modal.element.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index 8b93a125d9..b47b026e6c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -54,11 +54,7 @@ export class UmbDebugModalLayout extends UmbModalLayoutElement { `, ]; - private _handleClose() { - /* Optional data of any type can be applied to the close method to pass it - to the modal parent through the onClose promise. */ - //this.modalHandler?.close('MY DATA'); this.modalHandler?.close(); } From 5374215856eb3cdda15dd6aa0092aa927cc9b9a2 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 20:27:35 +0000 Subject: [PATCH 20/32] Move import for dialog into the main debug component TODO: Ask Jacob on how to lazily load it --- .../src/backoffice/shared/components/debug/debug.element.ts | 3 +++ .../src/backoffice/shared/components/index.ts | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 76c4c34c89..f05c0bf8f1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -5,6 +5,9 @@ import { UmbContextDebugRequest } from '@umbraco-cms/context-api'; import { UmbLitElement } from '@umbraco-cms/element'; import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +// TODO: Ask Jacob how to lazily load this depending on a property +import './debug.modal.element'; + @customElement('umb-debug') export class UmbDebug extends UmbLitElement { static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts index b09a13320e..c9602d9759 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts @@ -31,5 +31,4 @@ import './input-document-picker/input-document-picker.element'; import './empty-state/empty-state.element'; import './color-picker/color-picker.element'; -import './debug/debug.element'; -import './debug/debug.modal.element'; \ No newline at end of file +import './debug/debug.element'; \ No newline at end of file From afd5b6ad40ca0d603f5f63d2208b75389984830a Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 21:11:50 +0000 Subject: [PATCH 21/32] Make modal small - looks weird with too much whitespace Remove assigning to const as we don't need the onClose callback - nothing happens in the open dialog to be notified about --- .../shared/components/debug/debug.element.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index f05c0bf8f1..6f845983d5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -107,11 +107,13 @@ export class UmbDebug extends UmbLitElement { } private _openDialog() { - const modalHandler = this._modalService?.open('umb-debug-modal-layout', { size: 'medium', type: 'sidebar', data:{ contexts: this.contexts }}); - - modalHandler?.onClose().then((data) => { - // if any data is supplied on close, it will be available here. - console.log('modal closed data', data); + // Open a modal that uses the HTML component called 'umb-debug-modal-layout' + this._modalService?.open('umb-debug-modal-layout', { + size: 'small', + type: 'sidebar', + data:{ + content: this._renderContextAliases() + } }); } From a058ce01b801ff25e024611efd144509c999b66e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 21:19:58 +0000 Subject: [PATCH 22/32] Rename a few variables and try to improve the markup for use in dialog & non dialog mode as its now shared --- .../shared/components/debug/debug.element.ts | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 6f845983d5..324d7b84d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -138,7 +138,6 @@ export class UmbDebug extends UmbLitElement {
    -

    Context Aliases to consume

      ${this._renderContextAliases()}
    @@ -148,13 +147,14 @@ export class UmbDebug extends UmbLitElement { } private _renderContextAliases() { - const aliases = []; + const contextsTemplates: TemplateResult[] = []; for (const [alias, instance] of this.contexts) { - aliases.push( - html`
  • + contextsTemplates.push( + html` +
  • Context: ${alias} - (${typeof instance}) + (${typeof instance})
      ${this._renderInstance(instance)}
    @@ -162,20 +162,31 @@ export class UmbDebug extends UmbLitElement { ); } - return aliases; + return contextsTemplates; } private _renderInstance(instance: any) { - const instanceKeys: TemplateResult[] = []; + const instanceTemplates: TemplateResult[] = []; + // TODO: WB - Maybe make this a switch statement? if (typeof instance === 'function') { - return instanceKeys.push(html`
  • Callable Function
  • `); + return instanceTemplates.push(html`
  • Callable Function
  • `); } else if (typeof instance === 'object') { const methodNames = this.getClassMethodNames(instance); if (methodNames.length) { - instanceKeys.push(html`
  • Methods - ${methodNames.join(', ')}
  • `); + instanceTemplates.push( + html` +
  • + Methods +
      + ${methodNames.map((methodName) => html`
    • ${methodName}
    • `)} +
    +
  • + `); } + instanceTemplates.push(html`
  • Properties
  • `); + for (const key in instance) { if (key.startsWith('_')) { continue; @@ -183,16 +194,16 @@ export class UmbDebug extends UmbLitElement { const value = instance[key]; if (typeof value === 'string') { - instanceKeys.push(html`
  • ${key} = ${value}
  • `); + instanceTemplates.push(html`
  • ${key} = ${value}
  • `); } else { - instanceKeys.push(html`
  • ${key} (${typeof value})
  • `); + instanceTemplates.push(html`
  • ${key} (${typeof value})
  • `); } } } else { - instanceKeys.push(html`
  • Context is a primitive with value: ${instance}
  • `); + instanceTemplates.push(html`
  • Context is a primitive with value: ${instance}
  • `); } - return instanceKeys; + return instanceTemplates; } private getClassMethodNames(klass: any) { From fb54bd7ddd4bafa4d7f2e1373a2b227ba8e31aec Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 21:20:16 +0000 Subject: [PATCH 23/32] Remove uneeded code now --- .../components/debug/debug.modal.element.ts | 83 +------------------ 1 file changed, 4 insertions(+), 79 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index b47b026e6c..eed378d006 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -1,7 +1,7 @@ -import { css, html, nothing, TemplateResult } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { css, html } from 'lit'; +import { customElement } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { UmbModalHandler, UmbModalLayoutElement } from '@umbraco-cms/modal'; +import { UmbModalLayoutElement } from '@umbraco-cms/modal'; @customElement('umb-debug-modal-layout') export class UmbDebugModalLayout extends UmbModalLayoutElement { @@ -65,87 +65,12 @@ export class UmbDebugModalLayout extends UmbModalLayoutElement { Debug: Contexts - ${this._renderContextAliases()} + ${this.data.content} Close `; } - - private _renderContextAliases() { - if(!this.data) { - return nothing; - } - - const aliases = []; - for (const [alias, instance] of this.data.contexts) { - aliases.push( - html` -
    -

    ${alias} ${typeof instance}

    - ${this._renderInstance(instance)} -
    ` - ); - } - - return aliases; - } - - private _renderInstance(instance: any) { - const instanceKeys: TemplateResult[] = []; - - if (typeof instance === 'function') { - return instanceKeys.push(html`
  • Callable Function
  • `); - } else if (typeof instance === 'object') { - const methodNames = this.getClassMethodNames(instance); - if (methodNames.length) { - instanceKeys.push( - html` -

    Methods

    -
      - ${methodNames.map((methodName) => html`
    • ${methodName}
    • `)} -
    - `); - } - - instanceKeys.push(html`

    Properties

    `); - - for (const key in instance) { - if (key.startsWith('_')) { - continue; - } - - const value = instance[key]; - if (typeof value === 'string') { - instanceKeys.push(html`
  • ${key} = ${value}
  • `); - } else { - instanceKeys.push(html`
  • ${key} Type (${typeof value})
  • `); - } - } - } else { - instanceKeys.push(html`
  • Context is a primitive with value: ${instance}
  • `); - } - - return instanceKeys; - } - - - private getClassMethodNames(klass: any) { - const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; - const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; - const deepFunctions = (x: any): any => - x !== Object.prototype && - Object.getOwnPropertyNames(x) - .filter((name) => isGetter(x, name) || isFunction(x, name)) - .concat(deepFunctions(Object.getPrototypeOf(x)) || []); - const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); - - const allMethods = - typeof klass.prototype === 'undefined' - ? distinctDeepFunctions(klass) - : Object.getOwnPropertyNames(klass.prototype); - return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); - } } declare global { From 6bf96716ea2184a1bcb2e342a55c9ce5de9fccac Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 16 Feb 2023 21:24:48 +0000 Subject: [PATCH 24/32] Specify an interface/type for the modal like others in codebase --- .../shared/components/debug/debug.modal.element.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index eed378d006..d86045c85e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -1,10 +1,14 @@ -import { css, html } from 'lit'; +import { css, html, TemplateResult } from 'lit'; import { customElement } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbModalLayoutElement } from '@umbraco-cms/modal'; +export interface UmbDebugModalData { + content: TemplateResult | string; +} + @customElement('umb-debug-modal-layout') -export class UmbDebugModalLayout extends UmbModalLayoutElement { +export class UmbDebugModalLayout extends UmbModalLayoutElement { static styles = [ UUITextStyles, css` @@ -65,7 +69,7 @@ export class UmbDebugModalLayout extends UmbModalLayoutElement { Debug: Contexts - ${this.data.content} + ${this.data?.content} Close From 430ccc7ea405eee444ebb20d944d51e9e25f7bff Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:16:44 +0100 Subject: [PATCH 25/32] set class as default export --- .../components/debug/debug.modal.element.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts index d86045c85e..d9d370aaf0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.modal.element.ts @@ -8,7 +8,7 @@ export interface UmbDebugModalData { } @customElement('umb-debug-modal-layout') -export class UmbDebugModalLayout extends UmbModalLayoutElement { +export default class UmbDebugModalLayout extends UmbModalLayoutElement { static styles = [ UUITextStyles, css` @@ -34,8 +34,8 @@ export class UmbDebugModalLayout extends UmbModalLayoutElement - - Debug: Contexts - - - ${this.data?.content} - + Debug: Contexts + ${this.data?.content} Close `; From 6ab0bd77d11f2dd1d1f5c2560ff1fbb178d7ffa4 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:17:02 +0100 Subject: [PATCH 26/32] add properties to a sub-ul list --- .../shared/components/debug/debug.element.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index 324d7b84d9..d4f23a9f0f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -182,10 +182,11 @@ export class UmbDebug extends UmbLitElement { ${methodNames.map((methodName) => html`
  • ${methodName}
  • `)} - `); + ` + ); } - instanceTemplates.push(html`
  • Properties
  • `); + const props: TemplateResult[] = []; for (const key in instance) { if (key.startsWith('_')) { @@ -194,11 +195,20 @@ export class UmbDebug extends UmbLitElement { const value = instance[key]; if (typeof value === 'string') { - instanceTemplates.push(html`
  • ${key} = ${value}
  • `); + props.push(html`
  • ${key} = ${value}
  • `); } else { - instanceTemplates.push(html`
  • ${key} (${typeof value})
  • `); + props.push(html`
  • ${key} (${typeof value})
  • `); } } + + instanceTemplates.push(html` +
  • + Properties +
      + ${props} +
    +
  • + `); } else { instanceTemplates.push(html`
  • Context is a primitive with value: ${instance}
  • `); } From 29667b8bb70c23cfc6595a03b9f75954c935331d Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:17:30 +0100 Subject: [PATCH 27/32] lazily load the modal layout --- .../shared/components/debug/debug.element.ts | 73 ++++++++----------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index d4f23a9f0f..84aff299aa 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -5,21 +5,18 @@ import { UmbContextDebugRequest } from '@umbraco-cms/context-api'; import { UmbLitElement } from '@umbraco-cms/element'; import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -// TODO: Ask Jacob how to lazily load this depending on a property -import './debug.modal.element'; - @customElement('umb-debug') export class UmbDebug extends UmbLitElement { static styles = [ UUITextStyles, - css` + css` #container { display: block; font-family: monospace; z-index: 10000; - position:relative; + position: relative; width: 100%; padding: 10px 0; } @@ -75,14 +72,13 @@ export class UmbDebug extends UmbLitElement { this._modalService = modalService; }); } - + connectedCallback(): void { super.connectedCallback(); // Dispatch it this.dispatchEvent( new UmbContextDebugRequest((contexts: Map) => { - // The Contexts are collected // When travelling up through the DOM from this element // to the root of which then uses the callback prop @@ -94,56 +90,52 @@ export class UmbDebug extends UmbLitElement { } render() { - if (this.enabled) { - return this.dialog ? this._renderDialog() : this._renderPanel(); + if (this.enabled) { + return this.dialog ? this._renderDialog() : this._renderPanel(); } else { return nothing; } - } private _toggleDebugPane() { this._debugPaneOpen = !this._debugPaneOpen; } - private _openDialog() { + private async _openDialog() { // Open a modal that uses the HTML component called 'umb-debug-modal-layout' - this._modalService?.open('umb-debug-modal-layout', { - size: 'small', - type: 'sidebar', - data:{ - content: this._renderContextAliases() - } + await import('./debug.modal.element.js'); + this._modalService?.open('umb-debug-modal-layout', { + size: 'medium', + type: 'sidebar', + data: { + content: this._renderContextAliases(), + }, }); } - - private _renderDialog() { - return html` -
    - - Debug - -
    `; + return html`
    + + Debug + +
    `; } - private _renderPanel(){ - return html` -
    - - - Debug - + private _renderPanel() { + return html`
    + + + Debug + -
    -
    -
      - ${this._renderContextAliases()} -
    -
    +
    +
    +
      + ${this._renderContextAliases()} +
    -
    `; +
    +
    `; } private _renderContextAliases() { @@ -151,8 +143,7 @@ export class UmbDebug extends UmbLitElement { for (const [alias, instance] of this.contexts) { contextsTemplates.push( - html` -
  • + html`
  • Context: ${alias} (${typeof instance})