How to hide create site link for particular user - alfresco-share

I am on Alfresco 4.2e Community Edition.I am able to restrict site creation for a particular group by modifying the following files.
In public-services-security-context.xml
org.alfresco.service.cmr.site.SiteService.createSite=ACL_METHOD.ROLE_ADMINISTRATOR,ACL_METHOD.GROUP_SITECREATORS
In sites.get.js and mysites.get.js I added this
var createSiteVisible = userHasGroup(user.name, 'SITECREATORS');
model.createSiteVisible = createSiteVisible;
function userHasGroup(username, group) {
var result = remote.call("/api/people/" + stringUtils.urlEncode(username) + "?groups=true");
if (result.status == 200 && result != "{}")
{
var user = eval('(' + result + ')');
var groups = new Array();
groups = user.groups;
var mygroups = "";
for (i=0; i<groups.length; i++)
{
if (groups[i].itemName == "GROUP_"+group || groups[i].itemName == "GROUP_ALFRESCO_ADMINISTRATORS"){
return true; // found group
}else{
mygroup = mygroups+groups[i].displayName;
}
}
return false;
}
else return false;
}
In my-sites.get.html.ftl and sites.get.html.ftl I modified the condition as
<#if createSiteVisible>
<span class="align-right yui-button-align">
<#if showCreateSite>
<span class="first-child">
<a href="#" id="${id}-createSite-button" class="theme-color-1">
<img src="${url.context}/res/components/images/site-16.png" style="vertical-align: text-bottom" />
${msg("link.createSite")}</a>
</span>
</#if>
</span>
</#if>
User is not able to create site now.But still I am getting create site link in header menu. How to hide create site for the users.
!user.isAdmin refers to admin user. What is the java script to refer a group?. Thank you

Here is a version that removes the link from the header, the dashlet, AND the welcome dashlet (don't forget about that one). Plus, it changes the underlying permissions to prevent circumventing the UI. In my version I restrict the create site capability to members of a "Site Creators" group.

I found a work around for this. First I hided the Create Site from header for everyone except admin. I added the following files.
I created file in shared/classes/alfresco/web-extension/site-data/extension/remove-create-site-extension.xml and typed
<extension>
<modules>
<module>
<id>Remove create site menu option for non admin users</id>
<version>1.0</version>
<customizations>
<customization>
<targetPackageRoot>org.alfresco.share.header</targetPackageRoot>
<sourcePackageRoot>ingen.header</sourcePackageRoot>
</customization>
<customization>
<targetPackageRoot>org.alfresco.components.dashlets</targetPackageRoot>
<sourcePackageRoot>ingen.dashlets</sourcePackageRoot>
</customization>
</customizations>
</module>
</modules>
</extension>
Then I created file in shared/classes/alfresco/web-extension/site-webscripts/ingen/header/share-header.get.js and added
//Find the "Sites" menu...
var sitesMenu = widgetUtils.findObject(model.jsonModel, "id", "HEADER_SITES_MENU");
if (sitesMenu != null) {
if (!user.isAdmin) {
sitesMenu.config.showCreateSite = false;
}
}
Then I created file shared/classes/alfresco/web-extension/site-webscripts/ingen/dashlets/my-sites.get.js
if (!user.isAdmin) {
model.showCreateSite = false;
}

Related

Why does my screen reader not announce the selected tab when activated

I'm working on making my existing tab component accessible, I'm basing my design off of the W3C's Example of Tabs with Manual Activation.
You can access my demo here
HTML
<div class="tab-container" lang="en">
<div class="tabs" role="tablist">
<button class="tab" aria-selected="true" href="#" role="tab" data-tab-name="tab1" tabindex="0">
<!-- tab name -->
</button>
<!-- more tabs -->
</div>
<div class="tab-content" data-name="tab1" role="tabpanel" tabindex="0">
<!-- tab panel content -->
</div>
<!-- more tab panels -->
</div>
JQuery
function getTabContent($tabContents, tabName) {
return $tabContents.filter('[data-name="' + tabName + '"]');
}
function setSelectedTab($tab) {
var tabName = $tab.data('tab-name'),
$tabSet = $tab.closest('.tabs'),
$tabContents = $tab.closest('.tab-container').find('.tab-content');
// update the tab indices and aria attributes
$tabSet.find('.tab').attr('aria-selected', 'false').attr('tabindex', '-1');
$tab.attr('aria-selected', 'true').removeAttr('tabindex');
$tabContents.addClass('hidden');
getTabContent($tabContents, tabName).removeClass('hidden');
}
function handleTabSelection(event) {
var $tab = $(event.target);
if ($tab.data('tab-name')) {
event.preventDefault();
setSelectedTab($tab);
$tab.focus();
}
}
// Our tab control needs to be used in many places on our site, we cannot guarantee that all devs will use unique IDs
// so we need to generate them here
function initTabs($tabContainer) {
var $tabList = $tabContainer.find('.tabs'),
$tabContents = $tabContainer.find('.tab-content'),
tabSetName = $tabList.data.name,
tabIdPrefix = 'tab-',
contentIdPrefix = 'tab-content-';
// add unique ids and labels
$tabList.children().each(function() {
var $tab = $(this),
tabName = $tab.data('tab-name'),
$tabContent = getTabContent($tabContents, tabName),
tabId = getUniqueId(tabIdPrefix + tabName),
contentId = getUniqueId(contentIdPrefix + tabName);
// add the unique id and associate the link with the content
$tab.attr('id', tabId).attr('aria-controls', contentId);
// add the unique id and use the link as the label for the content
$tabContent.attr('id', contentId).attr('aria-labelledby', tabId);
});
}
function getUniqueId(id, index) {
var newId = id;
if (index) {
newId += '--' + index;
index++;
} else {
index = 1;
}
if (document.getElementById(newId)) {
return getUniqueId(id, index);
}
return newId;
}
function handleKeyPress(event) {
var $tab = $(event.target);
if ($tab.is('.tab')) {
var keyCode = event.which,
$tab = $(event.target);
if (keyCode === 13 || keyCode === 32) {
// user pressed enter, or space
setSelectedTab($tab);
event.preventDefault();
} else if (keyCode === 37 || keyCode === 39) {
// the user pressed left or right
var $newTab = $tab[keyCode === 39 ? 'next' : 'prev']();
// move the focus
if ($newTab.length > 0) {
$newTab.focus();
}
event.preventDefault();
}
}
}
$('.tabs').click(handleTabSelection);
$('.tabs').keyup(handleKeyPress);
$('.tab-container').each(function() {
initTabs($(this));
});
A user can use the left and right keys to move focus within the tab list, and enter or space to select a tab.
When a user selects a tab however, the screen reader simply announces "selected" where on the W3C's example, it announces the tab name followed by "selected".
I'm testing using NVDA in Firefox and here are my steps to reproduce:
Set the focus on the "Nils Frahm" tab
Press TAB
You should hear "Agnes Obel tab two of three"
Press ENTER
You should hear "Agnes Obel tab selected tab two of three"
This is exactly what happens in the W3C's example, but in mine, the final step only reads "selected".
I've tried to match their example as closely as possible but I have yet to figure out how to get my example to announce the tab name when activated.
What could cause NVDA to skip reading the tab name once it is activated?
I discovered how to solve the problem, but as of yet, not why the problem exists.
When I add an after CSS rule on my selected tab, the screen reader starts reading the content when selected.
.tab[aria-selected="true"]::after {
content: '';
}
If I add the after tag to all tabs, the problem persists; it needs to only be on the selected element.
My guess is that this is fooling the screen reader into thinking that the content has changed, so it reads the new tab name.
Here is the working demo

open "view details" page in new tab at alfresco workflow form

open "view details" page in new tab at alfresco workflow accept/reject page but ** also to retain focus on the current page (approval/rejection) page**
with target=_blank focus on current page is getting lost
****overriding object-finder.js here****
function ObjectFinder_fnRenderCellListItemName(elCell, oRecord, oColumn, oData)
{
if (scope.options.showLinkToTarget && scope.options.targetLinkTemplate !== null)
{
if(item.site=="######xxxxxxxxxxany site****"){
title = '**' + $html(item.displayName?item.displayName:item.name) + '';
}
}
ObjectFinder_fnRenderCellListItemActions(elCell, oRecord, oColumn, oData)
{
if (scope.options.disabled === false)
{
var links = "", link, listAction;
for (var i = 0, il = scope.options.listItemActions.length; i < il; i++)
{
listAction = scope.options.listItemActions[i];
if (listAction.event)
{
if(item.site=="xx Any RAndom Site xxxxx"){
links += '<div class="list-action">'** + scope.msg(listAction.label) + '</div>';
}
Staying in the current tab when opening a new tab is controlled by the browser and there are some workarounds are present here.
You may need to simulate "Ctrl" + Click event while clicking the link.Please refer the below links.
https://stackoverflow.com/a/36027776/405317
Open a new tab in the background?
https://www.quora.com/How-do-I-open-a-link-in-a-new-tab-but-stay-on-the-same-page-using-HTML-code
https://productforums.google.com/forum/#!topic/chrome/RCCFMX3b7NA
Hope you will get some idea.

Authorization of alfresco user while calling webscript inside IFrame

I'm developping a component to easily edit associations in document properties pages.
The visual part of the component is an IFRAME showing the myspaces webscript.
I'm having difficulties to transfer user authentication to the content of the IFRAME. The session is lost, so the browser ask for a new BasicAuthentication.
I can transfer the ticket using the alf_ticket url parameter, but it is not reused for other urls produced by the webscript.
How could I transfer the Alfresco authentication to the webscript included in the IFRAME ?
<script type="text/javascript">
var self = this;
var ticket;
var xmlHttpReq = false;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open("GET", "http://blrkec335927d:8080/alfresco/wcservice/api/login?u=admin&pw=admin", true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'json');
self.xmlHttpReq.setRequestHeader('X-Alfresco-Remote-User', 'admin');
xmlHttpReq.onreadystatechange = function() {//Call a function when the state changes.
alert(xmlHttpReq.status);
if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200)
{
var xml = xmlHttpReq.responseXML;
var getticket = xml.getElementsByTagName("ticket");
ticket = getticket[0].childNodes[0].nodeValue
var url1 = "http://blrkec335927d:8080/alfresco/wcservice/ui/myspaces?f=0&p=%2FCompany%20Home&alf_ticket="+ticket;
var aa='<iframe bgcolor="#edf6fc" width="100%" height="100%" frameborder=0 src="'+url1+'" />';
document.getElementById('uploaddoc').innerHTML = aa;
}
}
self.xmlHttpReq.send();
</script>
<body>
<span id="pageTitle">${label['ALFRESCO_DOCUMENT']}</span>
<div id="uploaddoc">
</div>
</body>
<span id="footerButtons" style="vertical-align: bottom;"></span>
I am using above code . But still while loading page its asking for username and password. Please help me
First of all, don't use an iFrames for a simple webscript. You're not loading an entire new page which should have his own session.
Just use Client-Side JavaScript to get the JSON backend data en draw your own UI.
In any case you're compelled to use an iFrame, then just create your own myspaces webscript. Copy all the content, rename it and add your alf_ticket behind every generated url.

How to customize the Document List in Alfresco?

In the repository there be will different document lists.i.e there will be Data dictionary, user homes,Guest homes etc. when I change the view to "detailed view", it displays Favorite, like, comments links. where will I have to modify if I dont want to show them. Can you tell in which file i have to comment the code for not displaying those links. Thank you in Advance.
I wanted a "modular" answer to this question, this answer is to show how I handled this issue.
Context: Alfresco 4.2.f, project Maven from the org.alfresco.maven.archetype:alfresco-amp-archetype:1.1.1 archetype, I put everything in the embedded JAR when possible.
Create a module extension for share (see this blog for more details). Here is my extension file:
src/main/resources/alfresco/site-data/extensions/my-custom-extension.xml
<extension>
<modules>
<module>
<id>Main module of my custom extension</id>
<version>${project.version}</version>
<auto-deploy>true</auto-deploy>
<customizations>
<customization>
<!-- Order matters here! target before source, always! -->
<targetPackageRoot>org.alfresco</targetPackageRoot>
<sourcePackageRoot>my-custom.main</sourcePackageRoot>
</customization>
</customizations>
</module>
</modules>
</extension>
In the documentlibrary component of your module package, create this FTL in order to declare a javascript:
src/main/resources/alfresco/site-webscripts/my-custom/main/components/documentlibrary/documentlist-v2.get.html.ftl
<#-- Add a Javascript declaration -->
<#markup id="my-custom-js" target="js" action="after">
<#script type="text/javascript" group="documentlibrary"
src="${url.context}/res/my-custom/main/components/documentlibrary/documentlist.js"/>
</#>
In the resources (META-INF), under documentlibrary component, create the Javascript:
src/main/resources/META-INF/my-custom/main/components/documentlibrary/documentlist.js
YAHOO.lang.augmentObject(Alfresco.DocumentList.prototype, {
// Possible values: i18nLabel, lockBanner, syncFailed, syncTransientError
// date, size, name, version, description, tags, categories
myCustomDisabledRenderers: ["description", "version", "tags"],
// Possible values: favourites, likes, comments, quickShare
myCustomDisabledSocials: ["favourites", "comments", "likes", "quickShare"],
myCustomIsSocialDisabled: function(propertyName) {
return Alfresco.util.arrayContains(
this.myCustomDisabledSocials, propertyName);
},
myCustomIsRendererDisabled: function(propertyName) {
if (Alfresco.util.arrayContains(
this.myCustomDisabledRenderers, propertyName)) {
return true;
}
// Disable the social renderer when all the social features are
// disabled
if (propertyName === "social" && this.myCustomDisabledSocials.length == 4) {
return true;
}
return false;
},
/** Helper function to disable socials
* propertyName must be one of "favourites", "comments", "likes", "quickShare"
*/
myCustomDisableSocial: function(propertyName) {
if (!Alfresco.util.arrayContains(
this.myCustomDisabledSocials, propertyName)) {
this.myCustomDisabledSocials.push(propertyName);
}
},
// Custom registerRenderer for social features, originally defined in:
// webapps/share/components/documentlibrary/documentlist.js:2134
myCustomSocialRegisterRenderer: function(record) {
var jsNode = record.jsNode;
var html = "";
// Current usage of the separator variable allow to change the order
// of the different social features (the 'if' blocks below) without
// changing their content
var separator = "";
/* Favourite / Likes / Comments */
if (!this.myCustomIsSocialDisabled("favourites")) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateFavourite(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("likes")) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateLikes(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("comments") &&
jsNode.permissions.user.CreateChildren) {
html += '<span class="item item-social' + separator + '">' +
Alfresco.DocumentList.generateComments(this, record) +
'</span>';
separator = " item-separator";
}
if (!this.myCustomIsSocialDisabled("quickShare") && !record.node.isContainer &&
Alfresco.constants.QUICKSHARE_URL) {
html += '<span class="item' + separator + '">' +
Alfresco.DocumentList.generateQuickShare(this, record) +
'</span>';
separator = " item-separator";
}
return html;
},
// Overwrite registerRenderer which was originally defined in:
// webapps/share/components/documentlibrary/documentlist.js:1789
registerRenderer: function DL_registerRenderer(propertyName, renderer) {
if (Alfresco.util.isValueSet(propertyName) &&
Alfresco.util.isValueSet(renderer) &&
!this.myCustomIsRendererDisabled(propertyName)) {
if (propertyName === "social") {
this.renderers[propertyName] = this.myCustomSocialRegisterRenderer;
} else {
this.renderers[propertyName] = renderer;
}
return true;
}
return false;
}
}, true);
Then you can disable the links by updating myCustomDisabledRenderers and/or mySocialDisabledRenderers.
This way also allows you to create a module that disable (for example) the "comments on documents" or "likes on document" feature independently in only 6 easy steps!
Example, how to make a module that only disable comments on documents in 6 steps
Important: first remove the "comment disabling" from the documentlist.js of the main module.
myCustomDisabledSocials: ["favourites", "likes", "quickShare"],
Create a new module "my-custom.nocomment" with the same structure.
<extension>
<modules>
<module>
<id>Main module of my custom extension</id>
[...]
</module>
<module>
<id>No comment module of my custom extension</id>
<version>${project.version}</version>
<customizations>
<customization>
<targetPackageRoot>org.alfresco</targetPackageRoot>
<sourcePackageRoot>my-custom.nocomment</sourcePackageRoot>
</customization>
</customizations>
</module>
</modules>
</extension>
Add the FTL...
src/main/resources/alfresco/site-webscripts/my-custom/nocomment/components/documentlibrary/documentlist-v2.get.html.ftl
<#-- Add a Javascript declaration -->
<#markup id="my-custom-js" target="js" action="after">
<#script type="text/javascript" group="documentlibrary"
src="${url.context}/res/my-custom/nocomment/components/documentlibrary/documentlist.js"/>
</#>
then the Javascript...
src/main/resources/META-INF/my-custom/nocomment/components/documentlibrary/documentlist.js
Alfresco.DocumentList.prototype.myCustomDisableSocial("comment");
and then I'm happy, clap along if you feel like everything's just got smooth!
Notes:
The nocomment module depends on the main module.
It is important for the nocomment module to be loaded after the main module (in http://localhost:8080/share/page/modules/deploy).
In order for the nocomment module to be complete, you also need to disable comments from the document details page, see below.
Disable comments from the document details page
Even if, this one is documented elsewhere, I spent so much time searching around these few days that I feel like I need to be as comprehensive as possible.
src/main/resources/alfresco/site-data/extensions/my-custom-extension.xml
Add this to your my-custom.nocomment module declaration and you will get rid of the comments form and list from the document details page.
[...]
<module>
<id>No comment module of my custom extension</id>
[...]
<components>
<component>
<region-id>comments</region-id>
<source-id>document-details</source-id>
<scope>template</scope>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation id="guaranteedToHide">
<render>false</render>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
</components>
</module>
[...]
src/main/resources/alfresco/site-webscripts/my-custom/nocomment/components/node-details/node-header.get.js
This is for disabling the button on the header of the document details page.
// Disable comments
for (var i = 0; i < model.widgets.length; i++) {
if (model.widgets[i].id == "NodeHeader") {
model.widgets[i].options.showComments = false;
}
}
// And since it does not work, disable comments this way too
model.showComments = "false";
Note: I did not test these snippets, they have been taken from my project after "anonymization" (basically renaming the module). Let me know if you find mistakes.
What you are looking for is more than likely generated by client-side JavaScript. You should use share-config-custom.xml to set Share to development mode, like this:
<alfresco-config>
<!-- Put Share Client in debug mode -->
<config replace="true">
<flags>
<client-debug>true</client-debug>
<client-debug-autologging>false</client-debug-autologging>
</flags>
</config>
</alfresco-config>
Then, use firebug or your browser's developer console to step through the client-side JavaScript. You should be able to find the point where the document library elements are rendered.
You can override Alfresco's client-side JavaScript components with your own components. Please put them in your own namespace to avoid collisions with Alfresco's.
I did it by commenting the {social} line in file share-documentlibrary-config.xml in share/src/alfresco/share-document-config
...
<metadata-templates>
<!-- Default (fallback) -->
<template id="default">
<line index="10" id="date">{date}{size}</line>
<line index="20" id="description" view="detailed">{description}</line>
<line index="30" id="tags" view="detailed">{tags}</line>
<line index="40" id="categories" view="detailed" evaluator="evaluator.doclib.metadata.hasCategories">{categories}</line> -->
<!-- <line index="50" id="social" view="detailed">{social}</line> -->
</template>
...
It works!
I'm not sure if I understand well your question - you're trying to hide some columns from particular view in alfresco explorer? If so, you need to edit /jsp/browse/browse.jsp file, but I think that's not a good idea. Maybe implementing your own NodePropertyResolver should be better way, have look at my older blogpost on this topic: http://www.shmoula.cz/adding-columns-to-custom-browse-jsp/
It looks like all of it is in: \opt\alfresco-4.0.d\tomcat\webapps\share\components\documentlibrary\documentlist.js
I think the trick is in this.registerRenderer("social"...) to return html before line 1981 (after favorites before likes) supposing you want to keep at least faorite

Problems with opening the link on another page

I am working on contact page where the client can enter the postcode which will take them to google maps for directions to the company, the problem which i am having is although the hyperlink is set to target_blank but still the window opens on the back hand instead of opening in front of the website page. I have no idea why it opens on the back hand and focus is on the current page instead of moving it to google map page
<a href="#" target="_blank">
<img alt="" src="/images/contactUs/directionbtn.png" onclick="return openDirections(1);" /></a>
<script type="text/javascript">
function openDirections(NumVal) {
if (NumVal == 1) {
if (document.getElementById("<%=txtPostcode.ClientID%>").value == "") {
alert("PostCode can not be blank");
document.getElementById("<%=txtPostcode.ClientID%>").focus();
return false;
}
else {
var regPostcode = /^([a-zA-Z]){1}([0-9][0-9]|[0-9]|[a-zA-Z][0-9][a-zA-Z]|[a-zA-Z][0-9][0-9]|[a-zA-Z][0-9]){1}([ ])([0-9][a-zA-z][a-zA-z]){1}$/;
var tempURL = document.getElementById("<%=txtPostcode.ClientID%>").value;
if (regPostcode.test(tempURL) == false) {
alert("Please Enter a Valid PostCode");
document.getElementById("<%=txtPostcode.ClientID%>").focus();
return false;
}
else {
var url = 'http://maps.google.co.uk/maps?saddr={' + $('#<%=txtPostcode.ClientID%>').val() + '}&daddr=&daddr=646+Preston+Rd,+Clayton-le-Woods,+Chorley+PR6+7EH,+United+Kingdom&iwloc=1&dq=Tangent+Design';
document.location = url;
return true;
}
}
}
</script>
Try window.open(url); instead of of document.location = url;
All I see you doing is setting the url of the current window. Maybe try using something like this to open a new window instead.
window.open('url to open',)
in place of document.location = url
Each browser can be configured to handle how new pages are opened. Take a look at the preferences in the browser you are using, and see if that is the behavior that you currently have configured.
I think this is what you are looking for:
var x = window.open(URL, 'name', '...');
x.focus();

Resources