Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Document Workspace Info Link State #2497

Merged
merged 2 commits into from
Oct 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import { UmbDocumentUrlRepository } from '../../../repository/url/document-url.repository.js';
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../document-workspace.context-token.js';
import type { UmbDocumentUrlModel } from '../../../repository/url/types.js';
import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit';
import type { UmbDocumentVariantOptionModel } from '../../../types.js';
import { css, customElement, html, map, nothing, state, when } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';

@customElement('umb-document-workspace-view-info-links')
export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
#documentUrlRepository = new UmbDocumentUrlRepository(this);

#workspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE;
@state()
private _isNew = false;

@state()
private _unique?: string;

@state()
private _invariantCulture = 'en-US';
private _variantOptions?: Array<UmbDocumentVariantOptionModel>;

@state()
private _items?: Array<UmbDocumentUrlModel>;
private _lookup: Record<string, string> = {};

constructor() {
super();
Expand All @@ -29,96 +34,135 @@ export class UmbDocumentWorkspaceViewInfoLinksElement extends UmbLitElement {
});

this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (context) => {
this.#workspaceContext = context;
this.#requestUrls();
this.observe(
observeMultiple([context.isNew, context.unique, context.variantOptions]),
([isNew, unique, variantOptions]) => {
this._isNew = isNew === true;
this._unique = unique;
this._variantOptions = variantOptions;
this.#requestUrls();
},
);
});
}

async #requestUrls() {
const unique = this.#workspaceContext?.getUnique();
if (!unique) throw new Error('Document unique is required');
if (this._isNew) return;

if (!this._unique) throw new Error('Document unique is required');

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

if (data?.length) {
this._items = data[0].urls;
data[0].urls.forEach((item) => {
if (item.culture && item.url) {
this._lookup[item.culture] = item.url;
}
});
this.requestUpdate('_lookup');
}
}

override render() {
return html`
<uui-box headline=${this.localize.term('general_links')} style="--uui-box-default-padding: 0;">
<div id="link-section">
${when(
this._items?.length,
() => this.#renderUrls(),
() => this.#renderUnpublished(),
)}
</div>
</uui-box>
`;
#getStateLocalizationKey(variantOption: UmbDocumentVariantOptionModel) {
switch (variantOption.variant?.state) {
case null:
case undefined:
case DocumentVariantStateModel.NOT_CREATED:
return 'content_notCreated';
case DocumentVariantStateModel.DRAFT:
return 'content_itemNotPublished';
case DocumentVariantStateModel.PUBLISHED:
return 'content_routeErrorCannotRoute';
default:
return 'content_parentNotPublishedAnomaly';
}
}

#renderUrls() {
if (!this._items) return nothing;
override render() {
return html`
${repeat(
this._items!,
(item) => item.culture,
(item) => html`
<a href=${item.url ?? '#'} target="_blank" class="link-item">
<span class="culture">${item.culture}</span>
<span class="url">${item.url}</span>
<uui-icon name="icon-out"></uui-icon>
</a>
`,
)}
<uui-box headline=${this.localize.term('general_links')}>
${when(
this._isNew,
() => this.#renderNotCreated(),
() => this.#renderUrls(),
)}
</uui-box>
`;
}

#renderUnpublished() {
#renderNotCreated() {
return html`
<div class="link-item">
<span class="culture">${this._invariantCulture}</span>
<span class="url">
<em><umb-localize key="content_parentNotPublishedAnomaly"></umb-localize></em>
<span>
<em><umb-localize key="content_notCreated"></umb-localize></em>
</span>
</div>
`;
}

#renderUrls() {
if (!this._variantOptions?.length) return nothing;
return map(this._variantOptions, (variantOption) => this.#renderUrl(variantOption));
}

#renderUrl(variantOption: UmbDocumentVariantOptionModel) {
const varies = !!variantOption.culture;
const culture = varies ? variantOption.culture! : variantOption.language.unique;
const url = this._lookup[culture];
return when(
url,
() => html`
<a class="link-item" href=${url} target="_blank">
<span>
<span class="culture">${varies ? culture : nothing}</span>
<span>${url}</span>
</span>
<uui-icon name="icon-out"></uui-icon>
</a>
`,
() => html`
<div class="link-item">
<span>
${when(varies, () => html`<span class="culture">${culture}</span>`)}
<em><umb-localize key=${this.#getStateLocalizationKey(variantOption)}></umb-localize></em>
</span>
</div>
`,
);
}

static override styles = [
UmbTextStyles,
css`
#link-section {
display: flex;
flex-direction: column;
text-align: left;
uui-box {
--uui-box-default-padding: 0;
}

.link-item {
padding: var(--uui-size-space-4) var(--uui-size-space-6);
display: grid;
grid-template-columns: auto 1fr auto;
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--uui-size-6);
color: inherit;
text-decoration: none;

padding: var(--uui-size-space-4) var(--uui-size-space-6);

&:is(a) {
cursor: pointer;
color: inherit;
text-decoration: none;
}

&:is(a):hover {
background: var(--uui-color-divider);
}

.culture {
color: var(--uui-color-divider-emphasis);
& > span {
display: flex;
align-items: center;
gap: var(--uui-size-6);
}

uui-icon {
margin-right: var(--uui-size-space-2);
vertical-align: middle;
.culture {
color: var(--uui-color-divider-emphasis);
}
}
`,
Expand Down
Loading