diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts index 387d22bdf6..d64f6f160b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts @@ -1,17 +1,249 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; +import { css, html } from 'lit'; +import { customElement, state, query } from 'lit/decorators.js'; +import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../core/modal'; +import { UmbLitElement } from '@umbraco-cms/element'; +import { RedirectManagementResource, RedirectStatus, RedirectUrl, RedirectUrlStatus } from '@umbraco-cms/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/resources'; @customElement('umb-dashboard-redirect-management') -export class UmbDashboardRedirectManagementElement extends LitElement { - static styles = [UUITextStyles, css``]; +export class UmbDashboardRedirectManagementElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + .actions { + display: flex; + gap: 4px; + justify-content: space-between; + margin-bottom: 12px; + } + + uui-input uui-icon { + padding-top: var(--uui-size-space-2); + padding-left: var(--uui-size-space-3); + } + + uui-table { + table-layout: fixed; + } + + uui-table-head-cell:nth-child(2*n) { + width: 10%; + } + + uui-table-head-cell:last-child, + uui-table-cell:last-child { + text-align: right; + } + + uui-table uui-icon { + vertical-align: sub; + } + + .trackerDisabled { + position: relative; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + } + .trackerDisabled::after { + content: ''; + background-color: rgba(250, 250, 250, 0.7); + position: absolute; + border-radius: 2px; + left: 0; + right: 0; + top: 0; + bottom: 0; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + } + + a { + color: var(--uui-color-interactive); + } + a:hover, + a:focus { + color: var(--uui-color-interactive-emphasis); + } + `, + ]; + + @state() + private _redirectData?: RedirectUrl[]; + + @state() + private _redirectDataFiltered?: RedirectUrl[]; + + @state() + private _trackerStatus = true; + + @query('#search') + private _searchField!: HTMLInputElement; + + private _modalService?: UmbModalService; + + constructor() { + super(); + this.consumeContext(UMB_MODAL_SERVICE_CONTEXT_TOKEN, (_instance) => { + this._modalService = _instance; + }); + } + + connectedCallback() { + super.connectedCallback(); + this._getTrackerStatus(); + this._setup(); + } + + private async _getTrackerStatus() { + const { data } = await tryExecuteAndNotify(this, RedirectManagementResource.getRedirectManagementStatus()); + //console.log(data); + //if (data?.status) this._trackerStatus = data.status; + } + + private async _setup() { + const { data } = await tryExecuteAndNotify( + this, + RedirectManagementResource.getRedirectManagement({ take: 9999, skip: 0 }) + ); + this._redirectData = data?.items; + this._searchHandler(); + } + + private _removeRedirectHandler(data: RedirectUrl) { + const modalHandler = this._modalService?.confirm({ + headline: 'Delete', + content: html` +
+

This will remove the redirect

+ Original URL: ${data.originalUrl}
+ Redirected To: ${data.destinationUrl} +

Are you sure you want to delete?

+
+ `, + color: 'danger', + confirmLabel: 'Delete', + }); + modalHandler?.onClose().then(({ confirmed }: any) => { + if (confirmed) this._removeRedirect(data); + }); + } + + private async _removeRedirect(r: RedirectUrl) { + if (r.contentKey) { + const { data } = await tryExecuteAndNotify( + this, + RedirectManagementResource.deleteRedirectManagementByKey({ key: r.contentKey }) + ); + this._setup(); + } + } + + private _disableRedirectHandler() { + const modalHandler = this._modalService?.confirm({ + headline: 'Disable URL tracker', + content: html`Are you sure you want to disable the URL tracker?`, + color: 'danger', + confirmLabel: 'Disable', + }); + modalHandler?.onClose().then(({ confirmed }: any) => { + if (confirmed) this._toggleRedirect(); + }); + } + private async _toggleRedirect() { + /*//TODO: postRedirectManagementStatus returns 404 for whatever reason... + const { data } = await tryExecuteAndNotify( + this, + RedirectManagementResource.postRedirectManagementStatus({ status: RedirectStatus.ENABLED }) + );*/ + + this._trackerStatus = !this._trackerStatus; + } + + private _searchHandler() { + this._redirectDataFiltered = this._redirectData?.filter((data) => { + return data.originalUrl?.includes(this._searchField.value); + }); + } render() { - return html` - -

Redirect Management

-
- `; + return html`
+ ${this._trackerStatus + ? html` + + + + + Disable URL tracker + + ` + : html` + Enable URL tracker + `} +
+ + ${this._redirectDataFiltered?.length + ? html`
${this.renderTable()}
` + : this.renderNoRedirects()} `; + } + + renderNoRedirects() { + return html` + No redirects have been made +

When a published page gets renamed or moved, a redirect will automatically be made to the new page.

+
`; + } + + renderTable() { + return html` + + + Culture + Original URL + + Redirected To + Actions + + ${this._redirectDataFiltered?.map((data) => { + return html` + ${data.culture || '*'} + + ${data.originalUrl} + + + + + + + ${data.destinationUrl} + + + + + + + + + + `; + })} + + `; } }