Merge branch 'release/17.0' into v17/dev
This commit is contained in:
@@ -16,7 +16,6 @@ public class DocumentUrlFactory : IDocumentUrlFactory
|
||||
private readonly UrlProviderCollection _urlProviders;
|
||||
private readonly IPreviewService _previewService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IAbsoluteUrlBuilder _absoluteUrlBuilder;
|
||||
private readonly ILogger<DocumentUrlFactory> _logger;
|
||||
|
||||
public DocumentUrlFactory(
|
||||
@@ -24,14 +23,12 @@ public class DocumentUrlFactory : IDocumentUrlFactory
|
||||
UrlProviderCollection urlProviders,
|
||||
IPreviewService previewService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IAbsoluteUrlBuilder absoluteUrlBuilder,
|
||||
ILogger<DocumentUrlFactory> logger)
|
||||
{
|
||||
_publishedUrlInfoProvider = publishedUrlInfoProvider;
|
||||
_urlProviders = urlProviders;
|
||||
_previewService = previewService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_absoluteUrlBuilder = absoluteUrlBuilder;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -39,7 +36,7 @@ public class DocumentUrlFactory : IDocumentUrlFactory
|
||||
{
|
||||
ISet<UrlInfo> urlInfos = await _publishedUrlInfoProvider.GetAllAsync(content);
|
||||
return urlInfos
|
||||
.Select(urlInfo => CreateDocumentUrlInfo(urlInfo, false))
|
||||
.Select(CreateDocumentUrlInfo)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
@@ -89,18 +86,16 @@ public class DocumentUrlFactory : IDocumentUrlFactory
|
||||
}
|
||||
}
|
||||
|
||||
return CreateDocumentUrlInfo(previewUrlInfo, previewUrlInfo.IsExternal is false);
|
||||
return CreateDocumentUrlInfo(previewUrlInfo);
|
||||
}
|
||||
|
||||
private DocumentUrlInfo CreateDocumentUrlInfo(UrlInfo urlInfo, bool ensureAbsoluteUrl)
|
||||
private DocumentUrlInfo CreateDocumentUrlInfo(UrlInfo urlInfo)
|
||||
{
|
||||
var url = urlInfo.Url?.ToString();
|
||||
return new DocumentUrlInfo
|
||||
{
|
||||
Culture = urlInfo.Culture,
|
||||
Url = ensureAbsoluteUrl && url is not null
|
||||
? _absoluteUrlBuilder.ToAbsoluteUrl(url).ToString()
|
||||
: url,
|
||||
Url = url,
|
||||
Message = urlInfo.Message,
|
||||
Provider = urlInfo.Provider,
|
||||
};
|
||||
|
||||
@@ -144,7 +144,7 @@ public class NewDefaultUrlProvider : IUrlProvider
|
||||
public Task<UrlInfo?> GetPreviewUrlAsync(IContent content, string? culture, string? segment)
|
||||
=> Task.FromResult<UrlInfo?>(
|
||||
UrlInfo.AsUrl(
|
||||
$"/{Constants.System.UmbracoPathSegment}/preview?id={content.Key}&culture={culture}&segment={segment}",
|
||||
$"preview?id={content.Key}&culture={culture}&segment={segment}",
|
||||
Alias,
|
||||
culture,
|
||||
isExternal: false));
|
||||
@@ -182,7 +182,7 @@ public class NewDefaultUrlProvider : IUrlProvider
|
||||
// We have the published content now, so we can check if the culture is published, and thus avoid the DB hit.
|
||||
string route;
|
||||
var isDraft = _umbracoContextAccessor.GetRequiredUmbracoContext().InPreviewMode;
|
||||
if(isDraft is false && string.IsNullOrWhiteSpace(culture) is false && content.Cultures.Any() && content.IsInvariantOrHasCulture(culture) is false)
|
||||
if (isDraft is false && string.IsNullOrWhiteSpace(culture) is false && content.Cultures.Any() && content.IsInvariantOrHasCulture(culture) is false)
|
||||
{
|
||||
route = "#";
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@ import { UmbModalBaseElement, umbOpenModal } from '@umbraco-cms/backoffice/modal
|
||||
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
const elementName = 'umb-restore-from-recycle-bin-modal';
|
||||
|
||||
@customElement(elementName)
|
||||
@customElement('umb-restore-from-recycle-bin-modal')
|
||||
export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
UmbRestoreFromRecycleBinModalData,
|
||||
UmbRestoreFromRecycleBinModalValue
|
||||
@@ -21,10 +19,13 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
private _isAutomaticRestore = false;
|
||||
|
||||
@state()
|
||||
private _restoreItem?: any;
|
||||
private _destinationItem?: any;
|
||||
|
||||
@state()
|
||||
private _destinationItem?: any;
|
||||
private _destinationItemName?: string;
|
||||
|
||||
@state()
|
||||
private _restoreItemName?: string;
|
||||
|
||||
#recycleBinRepository?: UmbRecycleBinRepository;
|
||||
|
||||
@@ -34,7 +35,16 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
super.firstUpdated(_changedProperties);
|
||||
if (!this.data?.unique) throw new Error('Cannot restore an item without a unique identifier.');
|
||||
|
||||
this._restoreItem = await this.#requestItem(this.data.unique);
|
||||
const restoreItem = await this.#requestItem(this.data.unique);
|
||||
|
||||
if (this.data.itemDataResolver) {
|
||||
const resolver = new this.data.itemDataResolver(this);
|
||||
resolver.setData(restoreItem);
|
||||
this._restoreItemName = await resolver.getName();
|
||||
} else {
|
||||
this._restoreItemName = restoreItem.name;
|
||||
}
|
||||
|
||||
const unique = await this.#requestAutomaticRestoreDestination();
|
||||
|
||||
if (unique !== undefined) {
|
||||
@@ -47,9 +57,7 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
// TODO: handle ROOT lookup. Currently, we can't look up the root in the item repository.
|
||||
// This is a temp solution to show something in the UI.
|
||||
if (unique === null) {
|
||||
this._destinationItem = {
|
||||
name: 'ROOT',
|
||||
};
|
||||
this._destinationItemName = 'Root';
|
||||
|
||||
this.#setDestinationValue({
|
||||
unique: null,
|
||||
@@ -61,6 +69,14 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
this._destinationItem = await this.#requestItem(unique);
|
||||
if (!this._destinationItem) throw new Error('Cant find destination item.');
|
||||
|
||||
if (this.data?.itemDataResolver) {
|
||||
const resolver = new this.data.itemDataResolver(this);
|
||||
resolver.setData(this._destinationItem);
|
||||
this._destinationItemName = await resolver.getName();
|
||||
} else {
|
||||
this._destinationItemName = this._destinationItem.name;
|
||||
}
|
||||
|
||||
this.#setDestinationValue({
|
||||
unique: this._destinationItem.unique,
|
||||
entityType: this._destinationItem.entityType,
|
||||
@@ -138,7 +154,7 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
<umb-body-layout headline="Restore">
|
||||
<uui-box>
|
||||
${this._isAutomaticRestore
|
||||
? html` Restore ${this._restoreItem?.name} to ${this._destinationItem?.name}`
|
||||
? html` Restore ${this._restoreItemName} to ${this._destinationItemName}`
|
||||
: this.#renderCustomSelectDestination()}
|
||||
</uui-box>
|
||||
${this.#renderActions()}
|
||||
@@ -151,8 +167,8 @@ export class UmbRestoreFromRecycleBinModalElement extends UmbModalBaseElement<
|
||||
<h4>Cannot automatically restore this item.</h4>
|
||||
<p>There is no location where this item can be automatically restored. You can select a new location below.</p>
|
||||
<h5>Restore to:</h5>
|
||||
${this._destinationItem
|
||||
? html`<uui-ref-node name=${this._destinationItem.name}>
|
||||
${this._destinationItem && this._destinationItemName
|
||||
? html`<uui-ref-node name=${this._destinationItemName}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button @click=${() => (this._destinationItem = undefined)} label="Remove"
|
||||
>${this.localize.term('general_remove')}</uui-button
|
||||
@@ -186,6 +202,6 @@ export default UmbRestoreFromRecycleBinModalElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[elementName]: UmbRestoreFromRecycleBinModalElement;
|
||||
['umb-restore-from-recycle-bin-modal']: UmbRestoreFromRecycleBinModalElement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
|
||||
import type { UmbItemDataResolverConstructor } from '@umbraco-cms/backoffice/entity-item';
|
||||
import type { UmbPickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
@@ -7,6 +8,7 @@ export interface UmbRestoreFromRecycleBinModalData {
|
||||
entityType: string;
|
||||
recycleBinRepositoryAlias: string;
|
||||
itemRepositoryAlias: string;
|
||||
itemDataResolver?: UmbItemDataResolverConstructor;
|
||||
pickerModal: UmbModalToken<UmbPickerModalData<any>, UmbPickerModalValue> | string;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ export class UmbRestoreFromRecycleBinEntityAction extends UmbEntityActionBase<Me
|
||||
entityType: this.args.entityType,
|
||||
recycleBinRepositoryAlias: this.args.meta.recycleBinRepositoryAlias,
|
||||
itemRepositoryAlias: this.args.meta.itemRepositoryAlias,
|
||||
itemDataResolver: this.args.meta.itemDataResolver,
|
||||
pickerModal: this.args.meta.pickerModal,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ManifestEntityAction, MetaEntityActionDefaultKind } from '@umbraco-cms/backoffice/entity-action';
|
||||
import type { UmbItemDataResolverConstructor } from '@umbraco-cms/backoffice/entity-item';
|
||||
import type { UmbModalToken, UmbPickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export interface ManifestEntityActionRestoreFromRecycleBinKind
|
||||
@@ -10,6 +11,7 @@ export interface ManifestEntityActionRestoreFromRecycleBinKind
|
||||
export interface MetaEntityActionRestoreFromRecycleBinKind extends MetaEntityActionDefaultKind {
|
||||
recycleBinRepositoryAlias: string;
|
||||
itemRepositoryAlias: string;
|
||||
itemDataResolver?: UmbItemDataResolverConstructor;
|
||||
pickerModal: UmbModalToken<UmbPickerModalData<any>, UmbPickerModalValue> | string;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ export const manifests: Array<UmbExtensionManifest> = [
|
||||
forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE],
|
||||
meta: {
|
||||
itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS,
|
||||
itemDataResolver: UmbDocumentItemDataResolver,
|
||||
recycleBinRepositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS,
|
||||
pickerModal: UMB_DOCUMENT_PICKER_MODAL,
|
||||
},
|
||||
|
||||
@@ -40,6 +40,7 @@ import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/documen
|
||||
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
|
||||
import type { UmbVariantPropertyGuardRule } from '@umbraco-cms/backoffice/property';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
|
||||
|
||||
type ContentModel = UmbDocumentDetailModel;
|
||||
type ContentTypeModel = UmbDocumentTypeDetailModel;
|
||||
@@ -70,6 +71,7 @@ export class UmbDocumentWorkspaceContext
|
||||
#isTrashedContext = new UmbIsTrashedEntityContext(this);
|
||||
#documentSegmentRepository = new UmbDocumentSegmentRepository(this);
|
||||
#actionEventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE;
|
||||
#localize = new UmbLocalizationController(this);
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
@@ -350,7 +352,11 @@ export class UmbDocumentWorkspaceContext
|
||||
}
|
||||
|
||||
if (previewUrlData.message) {
|
||||
umbPeekError(this._host, { color: 'danger', headline: 'Preview error', message: previewUrlData.message });
|
||||
umbPeekError(this._host, {
|
||||
color: 'danger',
|
||||
headline: this.#localize.term('general_preview'),
|
||||
message: previewUrlData.message,
|
||||
});
|
||||
throw new Error(previewUrlData.message);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user