Skip to content

Commit 81ebf3f

Browse files
committed
Merge branch 'v15/bugfix/fix-omitted-callback' into v15/bugfix/17312
2 parents 82b740e + bd456a1 commit 81ebf3f

File tree

5 files changed

+61
-28
lines changed

5 files changed

+61
-28
lines changed

src/Umbraco.Web.UI.Client/src/libs/class-api/class.mixin.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,26 @@ export const UmbClassMixin = <T extends ClassConstructor<EventTarget>>(superClas
5353
>(
5454
// This type dance checks if the Observable given could be undefined, if it potentially could be undefined it means that this potentially could return undefined and then call the callback with undefined. [NL]
5555
source: ObservableType,
56-
callback: ObserverCallback<SpecificT>,
56+
callback?: ObserverCallback<SpecificT>,
5757
controllerAlias?: UmbControllerAlias | null,
5858
): SpecificR {
59-
// Fallback to use a hash of the provided method, but only if the alias is undefined.
60-
controllerAlias ??= controllerAlias === undefined ? simpleHashCode(callback.toString()) : undefined;
59+
// Fallback to use a hash of the provided method, but only if the alias is undefined and there is a callback.
60+
if (controllerAlias === undefined && callback) {
61+
controllerAlias = simpleHashCode(callback.toString());
62+
} else if (controllerAlias === null) {
63+
// if value is null, then reset it to undefined. Null is used to explicitly tell that we do not want a controller alias. [NL]
64+
controllerAlias = undefined;
65+
}
6166

6267
if (source) {
6368
return new UmbObserverController<T>(
6469
this,
6570
source,
66-
callback as unknown as ObserverCallback<T>,
71+
callback as unknown as ObserverCallback<T> | undefined,
6772
controllerAlias,
6873
) as unknown as SpecificR;
6974
} else {
70-
callback(undefined as SpecificT);
75+
callback?.(undefined as SpecificT);
7176
this.removeUmbControllerByAlias(controllerAlias);
7277
return undefined as SpecificR;
7378
}

src/Umbraco.Web.UI.Client/src/libs/controller-api/controller-host-element.mixin.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ export const UmbControllerHostElementMixin = <T extends HTMLElementConstructor>(
2626
super.disconnectedCallback?.();
2727
this.hostDisconnected();
2828
}
29-
30-
override destroy(): void {}
3129
}
3230

3331
return UmbControllerHostElementClass as unknown as HTMLElementConstructor<UmbControllerHostElement> & T;

src/Umbraco.Web.UI.Client/src/libs/element-api/element.mixin.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,26 @@ export const UmbElementMixin = <T extends HTMLElementConstructor>(superClass: T)
2929
>(
3030
// This type dance checks if the Observable given could be undefined, if it potentially could be undefined it means that this potentially could return undefined and then call the callback with undefined. [NL]
3131
source: ObservableType,
32-
callback: ObserverCallback<SpecificT>,
32+
callback?: ObserverCallback<SpecificT>,
3333
controllerAlias?: UmbControllerAlias | null,
3434
): SpecificR {
35-
// Fallback to use a hash of the provided method, but only if the alias is undefined.
36-
controllerAlias ??= controllerAlias === undefined ? simpleHashCode(callback.toString()) : undefined;
35+
// Fallback to use a hash of the provided method, but only if the alias is undefined and there is a callback.
36+
if (controllerAlias === undefined && callback) {
37+
controllerAlias = simpleHashCode(callback.toString());
38+
} else if (controllerAlias === null) {
39+
// if value is null, then reset it to undefined. Null is used to explicitly tell that we do not want a controller alias. [NL]
40+
controllerAlias = undefined;
41+
}
3742

3843
if (source) {
3944
return new UmbObserverController<T>(
4045
this,
4146
source,
42-
callback as unknown as ObserverCallback<T>,
47+
callback as unknown as ObserverCallback<T> | undefined,
4348
controllerAlias,
4449
) as unknown as SpecificR;
4550
} else {
46-
callback(undefined as SpecificT);
51+
callback?.(undefined as SpecificT);
4752
this.removeUmbControllerByAlias(controllerAlias);
4853
return undefined as SpecificR;
4954
}

src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/duplicate/duplicate-document.action.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from '../../entity.js';
12
import { UMB_DUPLICATE_DOCUMENT_MODAL } from './modal/index.js';
23
import { UmbDuplicateDocumentRepository } from './repository/index.js';
34
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
45
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
5-
import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action';
6+
import { UmbEntityActionBase, UmbRequestReloadChildrenOfEntityEvent } from '@umbraco-cms/backoffice/entity-action';
67

78
export class UmbDuplicateDocumentEntityAction extends UmbEntityActionBase<never> {
89
override async execute() {
@@ -32,22 +33,28 @@ export class UmbDuplicateDocumentEntityAction extends UmbEntityActionBase<never>
3233
});
3334

3435
if (!error) {
35-
this.#reloadMenu();
36+
this.#reloadMenu(destinationUnique);
3637
}
3738
} catch (error) {
3839
console.log(error);
3940
}
4041
}
4142

42-
async #reloadMenu() {
43+
async #reloadMenu(destinationUnique: string | null) {
4344
const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
44-
const event = new UmbRequestReloadStructureForEntityEvent({
45-
unique: this.args.unique,
46-
entityType: this.args.entityType,
45+
46+
// When duplicating, the destination entity type may or may not be the same as that of
47+
// the item selected for duplication (that is available in this.args).
48+
// For documents though, we know the entity type will be "document", unless we are duplicating
49+
// to the root (when the destinationUnique will be null).
50+
const destinationEntityType = destinationUnique === null ? UMB_DOCUMENT_ROOT_ENTITY_TYPE : UMB_DOCUMENT_ENTITY_TYPE;
51+
52+
const event = new UmbRequestReloadChildrenOfEntityEvent({
53+
unique: destinationUnique,
54+
entityType: destinationEntityType,
4755
});
4856

4957
actionEventContext.dispatchEvent(event);
50-
// TODO: Reload destination
5158
}
5259
}
5360

src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/document-workspace-view-info-links.element.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
1010
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
1111
import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
1212
import { debounce } from '@umbraco-cms/backoffice/utils';
13+
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
1314

1415
interface UmbDocumentInfoViewLink {
1516
culture: string;
@@ -36,6 +37,9 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
3637
@state()
3738
private _links: Array<UmbDocumentInfoViewLink> = [];
3839

40+
@state()
41+
private _defaultCulture?: string;
42+
3943
#urls: Array<UmbDocumentUrlModel> = [];
4044

4145
#documentWorkspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE;
@@ -75,24 +79,38 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
7579
this.#setLinks();
7680
});
7781
});
82+
83+
this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => {
84+
this.observe(instance.appDefaultLanguage, (value) => {
85+
this._defaultCulture = value?.unique;
86+
this.#setLinks();
87+
});
88+
});
7889
}
7990

8091
#setLinks() {
81-
const possibleVariantCultures = this._variantOptions?.map((variantOption) => variantOption.culture) ?? [];
82-
const possibleUrlCultures = this.#urls.map((link) => link.culture);
83-
const possibleCultures = [...new Set([...possibleVariantCultures, ...possibleUrlCultures])].filter(
84-
Boolean,
85-
) as string[];
86-
87-
const links: Array<UmbDocumentInfoViewLink> = possibleCultures.map((culture) => {
88-
const url = this.#urls.find((link) => link.culture === culture)?.url;
92+
const links: Array<UmbDocumentInfoViewLink> = this.#urls.map((u) => {
93+
const culture = u.culture ?? this._defaultCulture ?? "";
94+
const url = u.url;
8995
const state = this._variantOptions?.find((variantOption) => variantOption.culture === culture)?.variant?.state;
9096
return { culture, url, state };
9197
});
9298

9399
this._links = links;
94100
}
95101

102+
#getTargetUrl (url: string | undefined) {
103+
if (!url || url.length === 0) {
104+
return url;
105+
}
106+
107+
if (url.includes(".") && !url.includes("//")) {
108+
return "//" + url;
109+
}
110+
111+
return url;
112+
}
113+
96114
async #requestUrls() {
97115
if (this._isNew) return;
98116
if (!this._unique) return;
@@ -181,7 +199,7 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
181199
}
182200

183201
return html`
184-
<a class="link-item" href=${link.url} target="_blank">
202+
<a class="link-item" href=${this.#getTargetUrl(link.url)} target="_blank">
185203
<span>
186204
${this.#renderLinkCulture(link.culture)}
187205
<span>${link.url}</span>

0 commit comments

Comments
 (0)