Details
-
Improvement
-
Status: Closed
-
Normal
-
Resolution: Fixed
-
None
-
None
-
0.5
-
Quasar
-
Puma Sprint 237, Puma Sprint 238, Puma Sprint 239
Description
Currently all cms users get to see the [Page] and [Channel] menu button in CM. I think that is ok. However, a user who is not a webmaster of the channel should not get the options 'New', Copy', 'Delete' etc. This can be checked by whether the user is in role webmaster (for the current channel / page). Same goes for [Channel -> Settings] : only webmasters should get to see these I'd think.
abogaart, can you sort out on what basis the CM UI currently checks whether to show or not show the [Page] menu and how the CM UI decides which options (New, Copy, Delete) are enabled. Then we can solve this.
Note: when clicking on the [Page] button, a 'resty' call to
org.hippoecm.hst.pagecomposer.jaxrs.services.SiteMapResource#getSiteMapItem
is done. The HST backend could indicate which options the current user is allowed. Only need to first find out how the CM UI decides which menu options to enable. Same goes for the Channel Menu
Technical Approach
The HST will get a RESTY (rpc) call which menu items there are for Channel and for Page (and later for XPage) and then PER menu item indicate whether the menu item is visible and whether it is enabled or not. The response for example will be something like
{ "channel" : { "visible" : true "enabled" : true " settings" : { "visible" : true "enabled" : true } " publish" : { "visible" : true "enabled" : true } " discard" : { "visible" : true "enabled" : true } " manage" : { "visible" : true "enabled" : true } } "page" : { "visible" : true "enabled" : true " new" : { "visible" : true "enabled" : true } " copy" : { "visible" : true "enabled" : true } " delete" : { "visible" : true "enabled" : true } } "xpage" : { "visible" : false "enabled" : false " new" : { "visible" : false "enabled" : false } " copy" : { "visible" : false "enabled" : false } " delete" : { "visible" : false "enabled" : false } } }
Debatable
Note that we'll have to figure out whether we have separate REST endpoints for Channel, Page and XPage menu or that there is 1 REST endpoint. abogaart, WDYT?
Arthur: I think one endpoint would be ideal. Below I've listed the current available actions and I'll try to summarize the backend state they require to be executed.
Breakdown of current logic for displaying the "channel" and the "page" menu
channel menu
- visible: no check
- enabled: no check
- optional icon to indicate changes is triggered by checking local state
settings
- visible: SessionService.hasWriteAccess()
- enabled: SessionService.hasWriteAccess() && hasChannel() && channel.previewHstConfigExists && channel.hasCustomProperties;
publish
- visible: SessionService.hasWriteAccess() && !ProjectService.isBranch()
- enabled: local state check
confirm
- visible: SessionService.hasWriteAccess() && ProjectService.isBranch()
- enabled: local state check
discard-changes
- visible: SessionService.hasWriteAccess()
- enabled: local state check
manage-changes
- visible: SessionService.hasWriteAccess()
- enabled: SessionService.canManageChanges() && local state check
accept
- visible: SessionService.hasWriteAccess() && ProjectService.isBranch()
- enabled: ProjectService.isAcceptEnabled()
reject
- visible: SessionService.hasWriteAccess() && ProjectService.isBranch()
- enabled: ProjectService.isRejectEnabled()
delete
- visible: SessionService.hasWriteAccess()
- enabled: SessionService.canDeleteChannel()
close
- visible: always
- enabled: always
page menu
- visible: (SessionService.hasWriteAccess() && hasChannel() && channel.previewHstConfigExists)) || PageToolsService.hasExtensions()
- enabled: !channel.configurationLocked
- onClick:
- update state of SiteMapItemService by executing a GET http://localhost:8080/cms/_rp/<SITEMAP_ID>./item/<SITEMAP_ITEM_ID> where <SITEMAP_ID> is channel.siteMapId and <SITEMAP_ITEM_ID> is pageMeta.sitemapItemId
- response is something like #1
- update state of ChannelService.pageModifiableChannels by executing a GET http://localhost:8080/cms/_rp/cafebabe-cafe-babe-cafe-babecafebabe./channels?previewConfigRequired=true&workspaceRequired=true&skipBranches=true&skipConfigurationLocked=true&privilegeAllowed=hippo%3Achannel-webmaster
- response is something like #2
tools
- visible: PageToolsService.hasExtensions();
- enabled: always
- onclick: it constructs a pageUrl that is sent as a parameter to the page extension
- pageUrl: channel.url + page.pathInfo
properties
- visible: SessionService.hasWriteAccess()
- enabled: SitemapItemService.hasItem() && !item.isHomePage && !item.isLocked() && item.workspaceConfiguration && !item.inherited
- onclick: open the page-properties editor. The page properties are read from the SitemapItemService which has been updated when the page-menu is opened.
- We could decide to return these properties as part of the payload for the menu, or find a way to lazy-load them when the page-properties editor is actually openend (let the page-properties editor load them instead of the menu doing it)
copy
- visible: SessionService.hasWriteAccess()
- enabled: SiteMapItemService.hasItem() && !SiteMapItemService.isLocked() && (ChannelService.hasWorkspace() || (SessionService.isCrossChannelPageCopySupported() && ChannelService.hasPageModifiableChannels()))
- onclick: it opens the page-copy subpage that uses the sitemap-item in SitemapItemService and pageModifiableChannels in ChannelService (both are loaded when opening the pageMenu)
move
- visible: SessionService.hasWriteAccess()
- enabled: SitemapItemService.hasItem() && !item.isHomePage && !item.isLocked() && item.workspaceConfiguration && !item.inherited
- onclick: it opens the page-move subpage that uses the sitemap-item in SitemapItemService (loaded by opening pageMenu)
delete
- visible: SessionService.hasWriteAccess()
- enabled: SitemapItemService.hasItem() && !item.isHomePage && !item.isLocked() && item.workspaceConfiguration && !item.inherited
- onclick: shows a dialog based on data from the sitemap-item in SitemapItemService (loaded by opening pageMenu)
new
- visible: SessionService.hasWriteAccess()
- enabled: ChannelService.hasWorkspace() && ChannelService.hasPrototypes()
- onclick: opens the page-new subpage
Note:
- SessionService.hasWriteAccess() is deprecated
- ProjectService state is loaded when channel is initialised
- PageToolsService is updated when a page changes
#1
{ "name":"_any_", "id":"ffc78451-6546-4ed2-8c2c-f78473f2a9f2", "parentId":"2ca0e6e1-2b1a-4dac-a1eb-a7b88e057938", "pathInfo":"/land", "parentPathInfo":"land", "isHomePage":false, "pageTitle":null, "localParameters":{ }, "roles":[ ], "componentConfigurationId":null, "cacheable":false, "workspaceConfiguration":false, "inherited":true, "lockedBy":null, "lockedOn":null, "versionStamp":0, "relativeContentPath":"landingpages/${1}", "primaryDocumentRepresentation":{ "path":"/content/documents/myproject/landingpages/${1}", "displayName":"${1}", "exists":false, "selected":true, "document":false }, "availableDocumentRepresentations":[ { "path":"/content/documents/myproject/landingpages/${1}", "displayName":"${1}", "exists":false, "selected":true, "document":false } ], "scheme":"http", "wildCard":false, "any":true, "containsWildCard":false, "containsAny":false, "parentLocation":{ "location":"localhost/land/", "id":"2ca0e6e1-2b1a-4dac-a1eb-a7b88e057938" }, "hasContainerItemInPageDefinition":false, "numberOfChildren":0, "explicitElement":false }
#2
{ "id":"myproject-preview", "name":"My Project", "channelSettingsEditable":true, "type":"website", "hostname":"localhost", "hostGroup":"dev-localhost", "contextPath":"/site", "cmsPreviewPrefix":"_cmsinternal", "mountPath":"", "channelPath":"/hst:myproject/hst:configurations/myproject-preview/hst:workspace/hst:channel", "url":"http://localhost:8080/site", "hstMountPoint":"/hst:myproject/hst:sites/myproject", "hstConfigPath":"/hst:myproject/hst:configurations/myproject-preview", "contentRoot":"/content/documents/myproject", "composerModeEnabled":false, "properties":{ }, "channelInfoClassName":null, "channelInfoMixinNames":null, "mountId":"05bbf493-8220-49b0-9c83-43b06aa49e77", "siteMapId":"c6920f00-d73c-4892-a890-46d2f2d0f9e9", "locale":"en_US", "previewHstConfigExists":true, "workspaceExists":true, "hasCustomProperties":false, "deletable":false, "changedBySet":[ ], "defaultDevice":"default", "devices":[ ], "viewportMap":{ }, "channelNodeLockedBy":null, "lastModifiedBy":null, "lockedOn":null, "lastModified":null, "branchId":null, "branchOf":null, "configurationLocked":false, "preview":true }