Skip to content

Commit 04c6b08

Browse files
authored
Merge pull request #2476 from umbraco/v15/feature/disable-readonly-when-unpulish-and-publish
Feature: Disable readonly languages when publishing and unpublishing a document
2 parents 6b59598 + da1652a commit 04c6b08

File tree

3 files changed

+170
-4
lines changed

3 files changed

+170
-4
lines changed

src/packages/documents/documents/entity-actions/publish.action.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
88
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
99
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
1010
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
11+
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
1112

1213
export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
1314
constructor(host: UmbControllerHost, args: UmbEntityActionArgs<never>) {
@@ -25,8 +26,16 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
2526

2627
if (!documentData) throw new Error('The document was not found');
2728

28-
const context = await this.getContext(UMB_APP_LANGUAGE_CONTEXT);
29-
const appCulture = context.getAppCulture();
29+
const appLanguageContext = await this.getContext(UMB_APP_LANGUAGE_CONTEXT);
30+
const appCulture = appLanguageContext.getAppCulture();
31+
32+
const currentUserContext = await this.getContext(UMB_CURRENT_USER_CONTEXT);
33+
const currentUserAllowedLanguages = currentUserContext.getLanguages();
34+
const currentUserHasAccessToAllLanguages = currentUserContext.getHasAccessToAllLanguages();
35+
36+
if (currentUserAllowedLanguages === undefined) throw new Error('The current user languages are missing');
37+
if (currentUserHasAccessToAllLanguages === undefined)
38+
throw new Error('The current user access to all languages is missing');
3039

3140
const options: Array<UmbDocumentVariantOptionModel> = documentData.variants.map<UmbDocumentVariantOptionModel>(
3241
(variant) => ({
@@ -76,6 +85,11 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<never> {
7685
.open(this, UMB_DOCUMENT_PUBLISH_MODAL, {
7786
data: {
7887
options,
88+
pickableFilter: (option) => {
89+
if (!option.culture) return false;
90+
if (currentUserHasAccessToAllLanguages) return true;
91+
return currentUserAllowedLanguages.includes(option.culture);
92+
},
7993
},
8094
value: { selection },
8195
})

src/packages/documents/documents/entity-actions/unpublish.action.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
1111
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
1212
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
1313
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
14+
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
1415

1516
export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase<never> {
1617
constructor(host: UmbControllerHost, args: UmbEntityActionArgs<never>) {
@@ -28,8 +29,16 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase<never>
2829

2930
if (!documentData) throw new Error('The document was not found');
3031

31-
const context = await this.getContext(UMB_APP_LANGUAGE_CONTEXT);
32-
const appCulture = context.getAppCulture();
32+
const appLanguageContext = await this.getContext(UMB_APP_LANGUAGE_CONTEXT);
33+
const appCulture = appLanguageContext.getAppCulture();
34+
35+
const currentUserContext = await this.getContext(UMB_CURRENT_USER_CONTEXT);
36+
const currentUserAllowedLanguages = currentUserContext.getLanguages();
37+
const currentUserHasAccessToAllLanguages = currentUserContext.getHasAccessToAllLanguages();
38+
39+
if (currentUserAllowedLanguages === undefined) throw new Error('The current user languages are missing');
40+
if (currentUserHasAccessToAllLanguages === undefined)
41+
throw new Error('The current user access to all languages is missing');
3342

3443
const options: Array<UmbDocumentVariantOptionModel> = documentData.variants.map<UmbDocumentVariantOptionModel>(
3544
(variant) => ({
@@ -65,6 +74,11 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase<never>
6574
data: {
6675
documentUnique: this.args.unique,
6776
options,
77+
pickableFilter: (option) => {
78+
if (!option.culture) return false;
79+
if (currentUserHasAccessToAllLanguages) return true;
80+
return currentUserAllowedLanguages.includes(option.culture);
81+
},
6882
},
6983
value: { selection },
7084
})
@@ -91,4 +105,5 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase<never>
91105
}
92106
}
93107
}
108+
94109
export default UmbUnpublishDocumentEntityAction;

src/packages/user/current-user/current-user.context.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr
1111
import { UMB_SECTION_PATH_PATTERN } from '@umbraco-cms/backoffice/section';
1212
import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app';
1313
import { ensurePathEndsWithSlash } from '@umbraco-cms/backoffice/utils';
14+
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
1415

1516
export class UmbCurrentUserContext extends UmbContextBase<UmbCurrentUserContext> {
1617
#currentUser = new UmbObjectState<UmbCurrentUserModel | undefined>(undefined);
@@ -83,6 +84,142 @@ export class UmbCurrentUserContext extends UmbContextBase<UmbCurrentUserContext>
8384
return currentUser?.isAdmin ?? false;
8485
}
8586

87+
/**
88+
* Get the allowed sections for the current user
89+
* @returns {Array<string> | undefined} The allowed sections for the current user
90+
*/
91+
getAllowedSection(): Array<string> | undefined {
92+
return this.#currentUser.getValue()?.allowedSections;
93+
}
94+
95+
/**
96+
* Get the avatar urls for the current user
97+
* @returns {Array<string> | undefined} The avatar urls for the current user
98+
*/
99+
getAvatarUrls(): Array<string> | undefined {
100+
return this.#currentUser.getValue()?.avatarUrls;
101+
}
102+
103+
/**
104+
* Get the document start node uniques for the current user
105+
* @returns {Array<UmbReferenceByUnique> | undefined} The document start node uniques for the current user
106+
*/
107+
getDocumentStartNodeUniques(): Array<UmbReferenceByUnique> | undefined {
108+
return this.#currentUser.getValue()?.documentStartNodeUniques;
109+
}
110+
111+
/**
112+
* Get the email for the current user
113+
* @returns {string | undefined} The email for the current user
114+
*/
115+
getEmail(): string | undefined {
116+
return this.#currentUser.getValue()?.email;
117+
}
118+
119+
/**
120+
* Get the fallback permissions for the current user
121+
* @returns {Array<string> | undefined} The fallback permissions for the current user
122+
*/
123+
getFallbackPermissions(): Array<string> | undefined {
124+
return this.#currentUser.getValue()?.fallbackPermissions;
125+
}
126+
127+
/**
128+
* Get if the current user has access to all languages
129+
* @returns {boolean | undefined} True if the current user has access to all languages, otherwise false
130+
*/
131+
getHasAccessToAllLanguages(): boolean | undefined {
132+
return this.#currentUser.getValue()?.hasAccessToAllLanguages;
133+
}
134+
135+
/**
136+
* Get if the current user has access to sensitive data
137+
* @returns {boolean | undefined} True if the current user has access to sensitive data, otherwise false
138+
*/
139+
getHasAccessToSensitiveData(): boolean | undefined {
140+
return this.#currentUser.getValue()?.hasAccessToSensitiveData;
141+
}
142+
143+
/**
144+
* Get if the current user has document root access
145+
* @returns {boolean | undefined} True if the current user has document root access, otherwise false
146+
*/
147+
getHasDocumentRootAccess(): boolean | undefined {
148+
return this.#currentUser.getValue()?.hasDocumentRootAccess;
149+
}
150+
151+
/**
152+
* Get if the current user has media root access
153+
* @returns {boolean | undefined} True if the current user has media root access, otherwise false
154+
*/
155+
getHasMediaRootAccess(): boolean | undefined {
156+
return this.#currentUser.getValue()?.hasMediaRootAccess;
157+
}
158+
159+
/**
160+
* Get if the current user is an admin
161+
* @returns {boolean | undefined} True if the current user is an admin, otherwise false
162+
*/
163+
getIsAdmin(): boolean | undefined {
164+
return this.#currentUser.getValue()?.isAdmin;
165+
}
166+
167+
/**
168+
* Get the language iso code for the current user
169+
* @returns {string | undefined} The language iso code for the current user
170+
*/
171+
getLanguageIsoCode(): string | undefined {
172+
return this.#currentUser.getValue()?.languageIsoCode;
173+
}
174+
175+
/**
176+
* Get the languages for the current user
177+
* @returns {Array<string> | undefined} The languages for the current user
178+
*/
179+
getLanguages(): Array<string> | undefined {
180+
return this.#currentUser.getValue()?.languages;
181+
}
182+
183+
/**
184+
* Get the media start node uniques for the current user
185+
* @returns {Array<UmbReferenceByUnique> | undefined} The media start node uniques for the current user
186+
*/
187+
getMediaStartNodeUniques(): Array<UmbReferenceByUnique> | undefined {
188+
return this.#currentUser.getValue()?.mediaStartNodeUniques;
189+
}
190+
191+
/**
192+
* Get the name for the current user
193+
* @returns {string | undefined} The name for the current user
194+
*/
195+
getName(): string | undefined {
196+
return this.#currentUser.getValue()?.name;
197+
}
198+
199+
/**
200+
* Get the permissions for the current user
201+
* @returns {Array<DocumentPermissionPresentationModel | UnknownTypePermissionPresentationModel> | undefined} The permissions for the current user
202+
*/
203+
getPermissions() {
204+
return this.#currentUser.getValue()?.permissions;
205+
}
206+
207+
/**
208+
* Get the unique for the current user
209+
* @returns {string | undefined} The unique for the current user
210+
*/
211+
getUnique(): string | undefined {
212+
return this.#currentUser.getValue()?.unique;
213+
}
214+
215+
/**
216+
* Get the user name for the current user
217+
* @returns {string | undefined} The user name for the current user
218+
*/
219+
getUserName(): string | undefined {
220+
return this.#currentUser.getValue()?.userName;
221+
}
222+
86223
#observeIsAuthorized() {
87224
if (!this.#authContext) return;
88225
this.observe(this.#authContext.isAuthorized, (isAuthorized) => {

0 commit comments

Comments
 (0)