Merge branch 'main' into v14/chore/bundling-language-package
This commit is contained in:
@@ -46,7 +46,7 @@ export default {
|
||||
logout: 'Exit',
|
||||
move: 'Move to',
|
||||
notify: 'Notifications',
|
||||
protect: 'Restrict Public Access',
|
||||
protect: 'Public Access',
|
||||
publish: 'Publish',
|
||||
refreshNode: 'Reload',
|
||||
remove: 'Remove',
|
||||
|
||||
@@ -45,7 +45,7 @@ export default {
|
||||
logout: 'Exit',
|
||||
move: 'Move to',
|
||||
notify: 'Notifications',
|
||||
protect: 'Restrict Public Access',
|
||||
protect: 'Public Access',
|
||||
publish: 'Publish',
|
||||
refreshNode: 'Reload',
|
||||
remove: 'Remove',
|
||||
|
||||
@@ -25,6 +25,10 @@ const entityActions: Array<ManifestTypes> = [
|
||||
{
|
||||
alias: UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS,
|
||||
},
|
||||
{
|
||||
alias: 'Umb.Condition.SectionUserPermission',
|
||||
match: 'Umb.Section.Members',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { UmbDocumentPublicAccessRepository } from '../repository/public-access.repository.js';
|
||||
import { UmbDocumentDetailRepository } from '../../../repository/index.js';
|
||||
import { UmbDocumentItemRepository } from '../../../repository/index.js';
|
||||
import type { UmbInputDocumentElement } from '../../../components/index.js';
|
||||
import type { UmbPublicAccessModalData, UmbPublicAccessModalValue } from './public-access-modal.token.js';
|
||||
import { css, customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { UmbInputMemberElement } from '@umbraco-cms/backoffice/member';
|
||||
import type { UmbInputMemberGroupElement } from '@umbraco-cms/backoffice/member-group';
|
||||
import { UmbMemberDetailRepository, type UmbInputMemberElement } from '@umbraco-cms/backoffice/member';
|
||||
import { UmbMemberGroupItemRepository, type UmbInputMemberGroupElement } from '@umbraco-cms/backoffice/member-group';
|
||||
import type { PublicAccessRequestModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UUIRadioEvent } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@@ -32,56 +32,52 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
private _selection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _loginPageId?: string;
|
||||
private _loginDocumentId?: string;
|
||||
|
||||
@state()
|
||||
private _errorPageId?: string;
|
||||
private _errorDocumentId?: string;
|
||||
|
||||
// Init
|
||||
|
||||
firstUpdated() {
|
||||
this.#unique = this.data?.unique;
|
||||
this.#getDocumentName();
|
||||
this.#getPublicAccessModel();
|
||||
}
|
||||
|
||||
async #getDocumentName() {
|
||||
if (!this.#unique) return;
|
||||
// Should this be done here or in the action file?
|
||||
const { data } = await new UmbDocumentDetailRepository(this).requestByUnique(this.#unique);
|
||||
const { data } = await new UmbDocumentItemRepository(this).requestItems([this.#unique]);
|
||||
if (!data) return;
|
||||
const item = data[0];
|
||||
//TODO How do we ensure we get the correct variant?
|
||||
this._documentName = data.variants[0]?.name;
|
||||
this._documentName = item.variants[0]?.name;
|
||||
|
||||
if (item.isProtected) {
|
||||
this.#getPublicAccessModel();
|
||||
}
|
||||
}
|
||||
|
||||
async #getPublicAccessModel() {
|
||||
if (!this.#unique) return;
|
||||
//const { data } = (await this.#publicAccessRepository.read(this.#unique));
|
||||
// TODO Currently returning "void". Remove mock data when API is ready. Will it be Response or Request model?
|
||||
const data: any = undefined;
|
||||
/*const data: PublicAccessResponseModel = {
|
||||
members: [{ name: 'Agent', id: '007' }],
|
||||
groups: [],
|
||||
loginPageId: '123',
|
||||
errorPageId: '456',
|
||||
};*/
|
||||
const { data } = await this.#publicAccessRepository.read(this.#unique);
|
||||
|
||||
if (!data) return;
|
||||
this.#isNew = false;
|
||||
this._startPage = false;
|
||||
|
||||
// Specific or Groups
|
||||
this._specific = data.members.length > 0 ? true : false;
|
||||
this._specific = data.members.length > 0;
|
||||
|
||||
//selection
|
||||
if (data.members.length > 0) {
|
||||
this._selection = data.members.map((m: any) => m.id);
|
||||
this._selection = data.members.map((m) => m.id);
|
||||
} else if (data.groups.length > 0) {
|
||||
this._selection = data.groups.map((g: any) => g.id);
|
||||
this._selection = data.groups.map((g) => g.id);
|
||||
}
|
||||
|
||||
this._loginPageId = data.loginPageId;
|
||||
this._errorPageId = data.errorPageId;
|
||||
this._loginDocumentId = data.loginDocument.id;
|
||||
this._errorDocumentId = data.errorDocument.id;
|
||||
}
|
||||
|
||||
// Modal events
|
||||
@@ -91,30 +87,54 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
}
|
||||
|
||||
async #handleSave() {
|
||||
if (!this._loginPageId || !this._errorPageId || !this.#unique) return;
|
||||
|
||||
const groups = this._specific ? [] : this._selection;
|
||||
const members = this._specific ? this._selection : [];
|
||||
if (!this._loginDocumentId || !this._errorDocumentId || !this.#unique) return;
|
||||
|
||||
// TODO: [v15] Currently the Management API doesn't support passing the member/group ids, only the userNames/names.
|
||||
// This is a temporary solution where we have to look them up until the API is updated to support this.
|
||||
const requestBody: PublicAccessRequestModel = {
|
||||
memberGroupNames: groups,
|
||||
memberUserNames: members,
|
||||
loginDocument: { id: this._loginPageId },
|
||||
errorDocument: { id: this._errorPageId },
|
||||
memberGroupNames: [],
|
||||
memberUserNames: [],
|
||||
loginDocument: { id: this._loginDocumentId },
|
||||
errorDocument: { id: this._errorDocumentId },
|
||||
};
|
||||
|
||||
if (this.#isNew) {
|
||||
this.#publicAccessRepository.create(this.#unique, requestBody);
|
||||
if (this._specific) {
|
||||
// Members
|
||||
// user name is not part of the item model, so we need to look it up from the member detail repository
|
||||
// be aware that the detail repository requires access to the member section.
|
||||
const repo = new UmbMemberDetailRepository(this);
|
||||
const promises = this._selection.map((memberId) => repo.requestByUnique(memberId));
|
||||
const responses = await Promise.all(promises);
|
||||
const memberUserNames = responses
|
||||
.filter((response) => response.data)
|
||||
.map((response) => response.data?.username) as string[];
|
||||
|
||||
requestBody.memberUserNames = memberUserNames;
|
||||
} else {
|
||||
this.#publicAccessRepository.update(this.#unique, requestBody);
|
||||
// Groups
|
||||
const repo = new UmbMemberGroupItemRepository(this);
|
||||
const { data } = await repo.requestItems(this._selection);
|
||||
if (!data) throw new Error('No Member groups returned');
|
||||
|
||||
const groupNames = data
|
||||
.filter((groupItem) => this._selection.includes(groupItem.unique))
|
||||
.map((groupItem) => groupItem.name);
|
||||
|
||||
requestBody.memberGroupNames = groupNames;
|
||||
}
|
||||
|
||||
if (this.#isNew) {
|
||||
await this.#publicAccessRepository.create(this.#unique, requestBody);
|
||||
} else {
|
||||
await this.#publicAccessRepository.update(this.#unique, requestBody);
|
||||
}
|
||||
|
||||
this.modalContext?.submit();
|
||||
}
|
||||
|
||||
#handleDelete() {
|
||||
async #handleDelete() {
|
||||
if (!this.#unique) return;
|
||||
this.#publicAccessRepository.delete(this.#unique);
|
||||
await this.#publicAccessRepository.delete(this.#unique);
|
||||
this.modalContext?.submit();
|
||||
}
|
||||
|
||||
@@ -125,11 +145,11 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
// Change Events
|
||||
|
||||
#onChangeLoginPage(e: CustomEvent) {
|
||||
this._loginPageId = (e.target as UmbInputDocumentElement).selection[0];
|
||||
this._loginDocumentId = (e.target as UmbInputDocumentElement).selection[0];
|
||||
}
|
||||
|
||||
#onChangeErrorPage(e: CustomEvent) {
|
||||
this._errorPageId = (e.target as UmbInputDocumentElement).selection[0];
|
||||
this._errorDocumentId = (e.target as UmbInputDocumentElement).selection[0];
|
||||
}
|
||||
|
||||
#onChangeGroup(e: CustomEvent) {
|
||||
@@ -182,7 +202,10 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
<small>
|
||||
<umb-localize key="publicAccess_paLoginPageHelp"> Choose the page that contains the login form </umb-localize>
|
||||
</small>
|
||||
<umb-input-document max="1" @change=${this.#onChangeLoginPage}></umb-input-document>
|
||||
<umb-input-document
|
||||
.value=${this._loginDocumentId ? this._loginDocumentId : ''}
|
||||
max="1"
|
||||
@change=${this.#onChangeLoginPage}></umb-input-document>
|
||||
</div>
|
||||
<br />
|
||||
<div class="select-item">
|
||||
@@ -192,7 +215,10 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
Used when people are logged on, but do not have access
|
||||
</umb-localize>
|
||||
</small>
|
||||
<umb-input-document max="1" @change=${this.#onChangeErrorPage}></umb-input-document>
|
||||
<umb-input-document
|
||||
.value=${this._errorDocumentId ? this._errorDocumentId : ''}
|
||||
max="1"
|
||||
@change=${this.#onChangeErrorPage}></umb-input-document>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -220,7 +246,7 @@ export class UmbPublicAccessModalElement extends UmbModalBaseElement<
|
||||
look="primary"
|
||||
color="positive"
|
||||
label=${this.localize.term('buttons_save')}
|
||||
?disabled=${!this._loginPageId || !this._errorPageId || this._selection.length === 0}
|
||||
?disabled=${!this._loginDocumentId || !this._errorDocumentId || this._selection.length === 0}
|
||||
@click="${this.#handleSave}"></uui-button>`
|
||||
: html`<uui-button
|
||||
slot="actions"
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { UMB_PUBLIC_ACCESS_MODAL } from './modal/public-access-modal.token.js';
|
||||
import type { UmbEntityActionArgs } from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
|
||||
import {
|
||||
UmbEntityActionBase,
|
||||
UmbRequestReloadChildrenOfEntityEvent,
|
||||
UmbRequestReloadStructureForEntityEvent,
|
||||
} from '@umbraco-cms/backoffice/entity-action';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import type { UmbDocumentDetailRepository } from '@umbraco-cms/backoffice/document';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
|
||||
export class UmbDocumentPublicAccessEntityAction extends UmbEntityActionBase<never> {
|
||||
constructor(host: UmbDocumentDetailRepository, args: UmbEntityActionArgs<never>) {
|
||||
@@ -14,5 +19,23 @@ export class UmbDocumentPublicAccessEntityAction extends UmbEntityActionBase<nev
|
||||
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
|
||||
const modal = modalManager.open(this, UMB_PUBLIC_ACCESS_MODAL, { data: { unique: this.args.unique } });
|
||||
await modal.onSubmit();
|
||||
this.#requestReloadEntity();
|
||||
}
|
||||
|
||||
async #requestReloadEntity() {
|
||||
const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
|
||||
|
||||
const entityStructureEvent = new UmbRequestReloadStructureForEntityEvent({
|
||||
unique: this.args.unique,
|
||||
entityType: this.args.entityType,
|
||||
});
|
||||
|
||||
const entityChildrenEvent = new UmbRequestReloadChildrenOfEntityEvent({
|
||||
unique: this.args.unique,
|
||||
entityType: this.args.entityType,
|
||||
});
|
||||
|
||||
actionEventContext.dispatchEvent(entityStructureEvent);
|
||||
actionEventContext.dispatchEvent(entityChildrenEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class UmbDocumentPublicAccessRepository extends UmbControllerBase impleme
|
||||
if (!unique) throw new Error('unique is missing');
|
||||
if (!data) throw new Error('Data is missing');
|
||||
|
||||
const { error } = await this.#dataSource.update(unique, data);
|
||||
const { error } = await this.#dataSource.create(unique, data);
|
||||
if (!error) {
|
||||
const notification = { data: { message: `Public acccess setting created` } };
|
||||
this.#notificationContext?.peek('positive', notification);
|
||||
|
||||
@@ -74,6 +74,7 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase<UmbDocume
|
||||
${this.item?.documentType.icon
|
||||
? html`
|
||||
<umb-icon id="icon" slot="icon" name="${this.item.documentType.icon}"></umb-icon>
|
||||
${this.item.isProtected ? this.#renderIsProtectedIcon() : nothing}
|
||||
<!--
|
||||
// TODO: implement correct status symbol
|
||||
<span id="status-symbol"></span>
|
||||
@@ -90,6 +91,10 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase<UmbDocume
|
||||
> `;
|
||||
}
|
||||
|
||||
#renderIsProtectedIcon() {
|
||||
return html`<umb-icon id="icon-lock" slot="icon" name="icon-lock" title="Protected"></umb-icon>`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
@@ -113,6 +118,45 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase<UmbDocume
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
#icon-lock {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
right: -5px;
|
||||
font-size: 10px;
|
||||
background: var(--uui-color-surface);
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 100%;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
:hover #icon-lock {
|
||||
background: var(--uui-color-surface-emphasis);
|
||||
}
|
||||
|
||||
/** Active */
|
||||
[active] #icon-lock {
|
||||
background: var(--uui-color-current);
|
||||
}
|
||||
|
||||
[active]:hover #icon-lock {
|
||||
background: var(--uui-color-current-emphasis);
|
||||
}
|
||||
|
||||
/** Selected */
|
||||
[selected] #icon-lock {
|
||||
background-color: var(--uui-color-selected);
|
||||
}
|
||||
|
||||
[selected]:hover #icon-lock {
|
||||
background-color: var(--uui-color-selected-emphasis);
|
||||
}
|
||||
|
||||
/** Disabled */
|
||||
[disabled] #icon-lock {
|
||||
background-color: var(--uui-color-disabled);
|
||||
}
|
||||
|
||||
.draft {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user