Skip to content

Commit b0b4571

Browse files
Bugfix: missing links for invariant documents with hostnames (#17808)
* always render the links we get from the server * render information about links with no url * pass correct state value * Update document-workspace-view-info-links.element.ts * reuse empty link, culture markup * remove state from urls --------- Co-authored-by: Niels Lyngsø <[email protected]>
1 parent 545d64d commit b0b4571

File tree

1 file changed

+78
-50
lines changed

1 file changed

+78
-50
lines changed

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

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { UmbDocumentUrlRepository } from '../../../repository/url/document-url.repository.js';
22
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../document-workspace.context-token.js';
33
import type { UmbDocumentVariantOptionModel } from '../../../types.js';
4-
import { css, customElement, html, map, nothing, state, when } from '@umbraco-cms/backoffice/external/lit';
4+
import type { UmbDocumentUrlModel } from '../../../repository/url/types.js';
5+
import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit';
56
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
67
import type { UmbEntityActionEvent } from '@umbraco-cms/backoffice/entity-action';
78
import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action';
@@ -10,6 +11,12 @@ import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
1011
import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
1112
import { debounce } from '@umbraco-cms/backoffice/utils';
1213

14+
interface UmbDocumentInfoViewLink {
15+
culture: string;
16+
url: string | undefined;
17+
state: DocumentVariantStateModel | null | undefined;
18+
}
19+
1320
@customElement('umb-document-workspace-view-info-links')
1421
export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
1522
#documentUrlRepository = new UmbDocumentUrlRepository(this);
@@ -24,10 +31,12 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
2431
private _variantOptions?: Array<UmbDocumentVariantOptionModel>;
2532

2633
@state()
27-
private _lookup: Record<string, string[]> = {};
34+
private _loading = false;
2835

2936
@state()
30-
private _loading = false;
37+
private _links: Array<UmbDocumentInfoViewLink> = [];
38+
39+
#urls: Array<UmbDocumentUrlModel> = [];
3140

3241
#documentWorkspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE;
3342
#eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE;
@@ -61,38 +70,49 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
6170
}
6271
});
6372

64-
this.observe(context.variantOptions, (variantOptions) => (this._variantOptions = variantOptions));
73+
this.observe(context.variantOptions, (variantOptions) => {
74+
this._variantOptions = variantOptions;
75+
this.#setLinks();
76+
});
6577
});
6678
}
6779

80+
#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;
89+
const state = this._variantOptions?.find((variantOption) => variantOption.culture === culture)?.variant?.state;
90+
return { culture, url, state };
91+
});
92+
93+
this._links = links;
94+
}
95+
6896
async #requestUrls() {
6997
if (this._isNew) return;
7098
if (!this._unique) return;
7199

72100
this._loading = true;
73-
this._lookup = {};
101+
this.#urls = [];
74102

75103
const { data } = await this.#documentUrlRepository.requestItems([this._unique]);
76104

77105
if (data?.length) {
78106
const item = data[0];
79-
80-
item.urls.forEach((item) => {
81-
if (item.culture && item.url) {
82-
if (this._lookup[item.culture] == null) {
83-
this._lookup[item.culture] = [];
84-
}
85-
this._lookup[item.culture].push(item.url);
86-
}
87-
});
88-
this.requestUpdate('_lookup');
107+
this.#urls = item.urls;
108+
this.#setLinks();
89109
}
90110

91111
this._loading = false;
92112
}
93113

94-
#getStateLocalizationKey(variantOption: UmbDocumentVariantOptionModel) {
95-
switch (variantOption.variant?.state) {
114+
#getStateLocalizationKey(state: DocumentVariantStateModel | null | undefined): string {
115+
switch (state) {
96116
case null:
97117
case undefined:
98118
case DocumentVariantStateModel.NOT_CREATED:
@@ -136,52 +156,60 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
136156
${when(
137157
this._isNew,
138158
() => this.#renderNotCreated(),
139-
() => this.#renderUrls(),
159+
() => (this._links.length === 0 ? this.#renderNoLinks() : this.#renderLinks()),
140160
)}
141161
`;
142162
}
143163

144164
#renderNotCreated() {
165+
return html`${this.#renderEmptyLink(null, null)}`;
166+
}
167+
168+
#renderLinks() {
169+
return html`
170+
${repeat(
171+
this._links,
172+
(link) => link.url,
173+
(link) => this.#renderLink(link),
174+
)}
175+
`;
176+
}
177+
178+
#renderLink(link: UmbDocumentInfoViewLink) {
179+
if (!link.url) {
180+
return this.#renderEmptyLink(link.culture, link.state);
181+
}
182+
145183
return html`
146-
<div class="link-item">
184+
<a class="link-item" href=${link.url} target="_blank">
147185
<span>
148-
<em><umb-localize key="content_notCreated"></umb-localize></em>
186+
${this.#renderLinkCulture(link.culture)}
187+
<span>${link.url}</span>
149188
</span>
150-
</div>
189+
<uui-icon name="icon-out"></uui-icon>
190+
</a>
151191
`;
152192
}
153193

154-
#renderUrls() {
155-
if (!this._variantOptions?.length) return nothing;
156-
return map(this._variantOptions, (variantOption) => this.#renderUrl(variantOption));
194+
#renderNoLinks() {
195+
return html` ${this._variantOptions?.map((variantOption) =>
196+
this.#renderEmptyLink(variantOption.culture, variantOption.variant?.state),
197+
)}`;
157198
}
158199

159-
#renderUrl(variantOption: UmbDocumentVariantOptionModel) {
160-
const varies = !!variantOption.culture;
161-
const culture = varies ? variantOption.culture! : variantOption.language.unique;
162-
const urls = this._lookup[culture];
163-
return when(
164-
urls && urls.length >= 1,
165-
() =>
166-
html` ${urls.map(
167-
(url) =>
168-
html` <a class="link-item" href=${url} target="_blank">
169-
<span>
170-
<span class="culture">${varies ? culture : nothing}</span>
171-
<span>${url}</span>
172-
</span>
173-
<uui-icon name="icon-out"></uui-icon>
174-
</a>`,
175-
)}`,
176-
() => html`
177-
<div class="link-item">
178-
<span>
179-
${when(varies, () => html`<span class="culture">${culture}</span>`)}
180-
<em><umb-localize key=${this.#getStateLocalizationKey(variantOption)}></umb-localize></em>
181-
</span>
182-
</div>
183-
`,
184-
);
200+
#renderEmptyLink(culture: string | null, state: DocumentVariantStateModel | null | undefined) {
201+
return html`<div class="link-item">
202+
<span>
203+
${this.#renderLinkCulture(culture)}
204+
<em><umb-localize key=${this.#getStateLocalizationKey(state)}></umb-localize></em>
205+
</span>
206+
</div>`;
207+
}
208+
209+
#renderLinkCulture(culture: string | null) {
210+
if (!culture) return nothing;
211+
if (this._links.length === 1) return nothing;
212+
return html`<span class="culture">${culture}</span>`;
185213
}
186214

187215
override disconnectedCallback(): void {

0 commit comments

Comments
 (0)