Project Spaces - first cut of summary template and some placeholder images

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7572 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mike Hatfield
2007-12-06 16:48:27 +00:00
parent bc3bd31e86
commit 511f6551f0
36 changed files with 602 additions and 6 deletions

View File

@@ -6,7 +6,7 @@
<#list blogSpace.pending as p>
<div class="blogPost">
<div class="blogPostName">
${p.name}, ${p.properties["cm:title"]}
${p.name}, ${p.properties["cm:title"]!""}
</div>
<div class="blogPostActions">
<span class="blogPostAction"><img src="${url.context}/images/icons/blog_post.png"><input type="button" href="${scripturl("?nodeRef=" + p.parent.nodeRef + "&n=" + p.nodeRef + "&a=p")}" value="Post" /></span>
@@ -20,7 +20,7 @@
<#list blogSpace.published as p>
<div class="blogPost">
<div class="blogPostName">
<a href="${p.properties["blg:link"]}" target="_blank">${p.properties["cm:title"]} (${p.name}) Published=${p.properties["blg:published"]?string}</a>
<a href="${p.properties["blg:link"]}" target="_blank">${p.properties["cm:title"]!""} (${p.name}) Published=${p.properties["blg:published"]?string}</a>
</div>
<div class="blogPostActions">
<span class="blogPostAction"><img src="${url.context}/images/icons/blog_update.png"><input type="button" href="${scripturl("?nodeRef=" + p.parent.nodeRef + "&n=" + p.nodeRef + "&a=u")}" value="Update" /></span>

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Blog Summary</shortname>
<description>Collaboration Blog Summary</description>
<url>/collaboration/blogSummary?nodeRef={noderef}</url>
<format default="html"/>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,2 @@
${blogSummary.numUpdates} articles need updating<br>
${blogSummary.numPending} articles pending

View File

@@ -0,0 +1,48 @@
/*
* blogSummary
*
* Inputs:
* nodeRef = blog space nodeRef
*
* Outputs:
* blogSummary - object containing
* numUpdates - number of articles updated since being published
* numPending - number of unpublished articles
*/
model.blogSummary = main(args["nodeRef"]);
function main(nodeRef)
{
var numUpdates = 0,
numPending = 0;
if (nodeRef != null)
{
var space = search.findNode(nodeRef);
if (space != null)
{
for each(node in space.children)
{
if ((node.hasAspect("blg:blogPost")) && (node.properties["blg:published"] == true))
{
if (node.properties["cm:modified"] > node.properties["blg:lastUpdate"])
{
++numUpdates;
}
}
else
{
++numPending;
}
}
}
}
var blogSummary =
{
"numUpdates": numUpdates,
"numPending": numPending
};
return blogSummary;
}

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Colleague Presence Custom View</shortname>
<description>Collaboration Colleague Presence view</description>
<url>/collaboration/colleaguePresence?nodeRef={noderef}</url>
<format default="html"/>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,138 @@
<script type="text/javascript" src="${url.context}/scripts/ajax/project_presence.js"></script>
<div class="collabHeader">
<span>Colleagues Online</span>
</div>
<div class="colleagueList" rel="${colleaguePresence.colleagues?size}">
<div id="colleaguesOnline">
<#list colleaguePresence.colleagues?keys as key>
<#assign c = colleaguePresence.colleagues[key]>
<div class="colleagueRow">
<div class="colleagueAvatar">
<#if (c.assocs["cm:avatar"]?exists)>
<#assign avatarURL = c.assocs["cm:avatar"][0].url>
<#else>
<#assign avatarURL = "images/icons/default_avatar.png">
</#if>
<img src="${url.context}/${avatarURL}" height="48" width="48" alt="avatar">
<div class="colleaguePresence" rel="${c.properties["presenceProvider"]!""}|${c.properties["presenceUsername"]!""}">
</div>
</div>
<div class="colleagueDetails">
<div class="colleagueName">${c.properties["firstName"]!""} ${c.properties["lastName"]!""}</div>
<div class="colleagueDetail">${c.properties["jobtitle"]!""}</div>
<div class="colleagueDetail">${c.properties["location"]!""}</div>
</div>
</div>
</#list>
</div>
<div id="colleaguesNotOnline">
</div>
</div>
<div class="collabFooter">
<span>&nbsp;</span>
</div>
<style>
/* Colleague Status */
#projectColleagues .collabHeader {
}
.colleagueList {
border-left: 1px solid #B9BEC4;
border-right: 1px solid #B9BEC4;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
}
#colleaguesOnline {
}
#colleaguesNotOnline {
}
.colleagueRow {
clear: both;
min-height: 56px;
padding: 8px 8px 0px;
}
.colleagueAvatar {
float: left;
position: relative;
height: 48px;
width: 48px;
padding-right: 8px;
}
.colleaguePresence {
background-image: url(${url.context}/images/icons/ajax_anim.gif);
position: absolute;
left: 32px;
top: 32px;
height: 16px;
width: 16px;
}
.colleaguePresence.skype-online
{
background-image: url(${url.context}/images/icons/presence_skype_online.png) !important;
}
.colleaguePresence.skype-offline
{
background-image: url(${url.context}/images/icons/presence_skype_offline.png) !important;
}
.colleaguePresence.yahoo-online
{
background-image: url(${url.context}/images/icons/presence_yahoo_online.png) !important;
}
.colleaguePresence.yahoo-offline
{
background-image: url(${url.context}/images/icons/presence_yahoo_offline.png) !important;
}
.colleaguePresence.unknown, .colleaguePresence.skype-unknown, .colleaguePresence.yahoo-unknown
{
background-image: url(${url.context}/images/icons/presence_status_unknown.png) !important;
}
.colleaguePresence.none
{
background-image: url(${url.context}/images/icons/presence_status_none.png) !important;
}
.colleagueDetails {
}
.colleagueName {
font-weight: bold;
}
.colleagueDetail {
}
.collabHeader {
background: url(${url.context}/images/parts/collab_topleft.png) no-repeat left top;
margin: 0px -1px;
padding: 0px 0px 0px 8px;
}
.collabHeader span {
background: url(${url.context}/images/parts/collab_topright.png) no-repeat right top;
display: block;
float: none;
padding: 5px 15px 4px 6px;
font-weight: bold;
font-size: 10pt;
}
.collabFooter {
background: url(${url.context}/images/parts/collab_bottomleft.png) no-repeat left top;
margin: 0px;
padding: 0px 0px 0px 4px;
}
.collabFooter span {
background: url(${url.context}/images/parts/collab_bottomright.png) no-repeat right top;
display: block;
float: none;
padding: 5px 15px 4px 6px;
}
</style>

View File

@@ -0,0 +1,72 @@
/*
* colleaguePresence
*
* Inputs:
* mandatory: nodeRef = parent space nodeRef
*
* Outputs: colleaguePresence - object containing presence data model
*/
model.colleaguePresence = main(args["nodeRef"]);
function main(nodeRef)
{
var space = search.findNode(nodeRef);
var colleagues = {};
if (space != null)
{
colleagues = parsePermissions(space);
}
if (person.assocs["cm:avatar"] != null)
{
model.img = person.assocs["cm:avatar"][0].url;
}
var colleaguePresence =
{
"colleagues": colleagues
};
return colleaguePresence;
}
function parsePermissions(space)
{
var tokens, user, group;
var userHash = {};
try
{
for each(perm in space.permissions)
{
tokens = perm.split(";");
if (tokens[0] == "ALLOWED")
{
if (("AllCollaboratorContributorCoordinatorEditor").indexOf(tokens[2]) != -1)
{
user = people.getPerson(tokens[1]);
if (user != null)
{
userHash[user.name] = user;
}
else
{
group = people.getGroup(tokens[1]);
if (group != null)
{
for each(user in people.getMembers(group))
{
userHash[user.name] = user;
}
}
}
}
}
}
}
catch (e)
{
}
return userHash;
}

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Project Space Custom View</shortname>
<description>Collaboration Project Space Space view</description>
<url>/collaboration/projectSpace?nodeRef={noderef}</url>
<format default="html"/>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,105 @@
<script type="text/javascript" src="${url.context}/scripts/ajax/project_space.js"></script>
<div class="collabHeader">
<span>${projectSpace.title} Summary</span>
</div>
<div class="collabContainer">
<table width="100%" cellpadding="16" cellspacing="0">
<tr valign="top">
<td>
<#list projectSpace.subSpaces?keys as key>
<#assign node = projectSpace.subSpaces[key]>
<#assign summary = node.properties["cm:summaryWebscript"]!"">
<div class="projectSpace">
<div class="projectSpaceIcon">
<img src="${url.context}${node.icon64}" height="64" width="64">
</div>
<div class="projectSpaceTitle"><a href="${url.context}${node.url}">${node.name}</a></div>
<div class="projectSpaceSummary" rel="<#if summary != "">${url.context}${summary}?nodeRef=${node.nodeRef}</#if>"></div>
</div>
</#list>
</td>
</tr>
</table>
</div>
<div class="collabFooter">
<span>&nbsp;</span>
</div>
<style>
/* Main Container elements */
#projectContainer {
width: 100%;
}
#projectSummary {
vertical-align: top;
}
#projectColleagues {
vertical-align: top;
width: 240px;
}
/* Project Summary */
.projectTitle {
font-family: "Trebuchet MS", Verdana, Helvetica, sans-serif;
font-size: medium;
font-weight: bold;
margin: -8px 0px 4px;
float: left;
}
.collabHeader {
background: url(${url.context}/images/parts/collab_topleft.png) no-repeat left top;
margin: 0px -1px;
padding: 0px 0px 0px 8px;
}
.collabHeader span {
background: url(${url.context}/images/parts/collab_topright.png) no-repeat right top;
display: block;
float: none;
padding: 5px 15px 4px 6px;
font-weight: bold;
font-size: 10pt;
}
.collabContainer {
border-left: 1px solid #B9BEC4;
border-right: 1px solid #B9BEC4;
min-height: 290px;
}
.projectSpace {
float: left;
padding: 1em 0px;
width: 50%;
}
.projectSpaceIcon {
float: left;
padding-right: 8px;
}
.projectSpaceTitle a {
font-weight: bold;
font-size: 10pt;
}
.projectSpaceSummary {
}
.collabFooter {
background: url(${url.context}/images/parts/collab_bottomleft.png) no-repeat left top;
margin: 0px;
padding: 0px 0px 0px 4px;
}
.collabFooter span {
background: url(${url.context}/images/parts/collab_bottomright.png) no-repeat right top;
display: block;
float: none;
padding: 5px 15px 4px 6px;
}
</style>

View File

@@ -0,0 +1,36 @@
/*
* projectSpace
*
* Inputs:
* mandatory: nodeRef = parent space nodeRef
*
* Outputs: projectSpace - object containing pproject space details
*/
model.projectSpace = main(args["nodeRef"]);
function main(nodeRef)
{
var title = "";
var subSpaces = {};
var space = search.findNode(nodeRef);
if (space != null)
{
title = space.name;
// Discover the nodeRef of each project subspace
for each(node in space.children)
{
if (node.hasAspect("{http://www.alfresco.org/model/content/1.0}projectsummary"))
{
subSpaces[node.nodeRef] = node;
}
}
}
var projectSpace =
{
"title": title,
"subSpaces": subSpaces
};
return projectSpace;
}

View File

@@ -410,6 +410,13 @@
<icon name="space-icon-pen" path="/images/icons/space-icon-pen.gif" />
<icon name="space-icon-cd" path="/images/icons/space-icon-cd.gif" />
<icon name="space-icon-image" path="/images/icons/space-icon-image.gif" />
<icon name="project-icon-blog" path="/images/icons/project-icon-blog.gif" />
<icon name="project-icon-calendar" path="/images/icons/project-icon-calendar.gif" />
<icon name="project-icon-doclibrary" path="/images/icons/project-icon-doclibrary.gif" />
<icon name="project-icon-emailarchive" path="/images/icons/project-icon-emailarchive.gif" />
<icon name="project-icon-forums" path="/images/icons/project-icon-forums.gif" />
<icon name="project-icon-gallery" path="/images/icons/project-icon-gallery.gif" />
<icon name="project-icon-wiki" path="/images/icons/project-icon-wiki.gif" />
</icons>
</config>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -109,10 +109,21 @@
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td>
<td style="padding:4px">
<table id="projectContainer" cellspacing="0" cellpadding="2" width="100%">
<tr>
<%-- TODO: Project View webscripts --%>
<r:webScript id="presence" scriptUrl="/wcs/ui/presence/status?nodeRef={noderef}" context="#{NavigationBean.currentNode.nodeRef}" />
<%-- Project Summary webscript --%>
<td id="projectSummary" valign="top">
<r:webScript id="projectSummary" scriptUrl="/wcs/collaboration/projectSpace?nodeRef={noderef}" context="#{NavigationBean.currentNode.nodeRef}" />
</td>
<%-- Colleague Presence Status webscript --%>
<td id="projectColleagues" valign="top">
<r:webScript id="projectColleagues" scriptUrl="/wcs/collaboration/colleaguePresence?nodeRef={noderef}" context="#{NavigationBean.currentNode.nodeRef}" />
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width=4></td>

View File

@@ -0,0 +1,126 @@
/*
* Prerequisites: mootools.v1.11.js
*/
var ProjectPresence =
{
OFFLINE_OPACITY: 0.2,
init: function()
{
window.contextPath = ProjectPresence.getContextPath();
var statuses = $$("#projectColleagues .colleaguePresence");
var rows = $$("#projectColleagues .colleagueRow");
$('colleaguesNotOnline').setStyle("opacity", ProjectPresence.OFFLINE_OPACITY);
statuses.each(function(status, i)
{
var userDetails = status.attributes["rel"].value.split("|");
var proxyURL = window.contextPath + "/ajax/invoke/PresenceProxyBean.proxyRequest";
var statusURL = ProjectPresence.getStatusURL(userDetails);
if (statusURL != "")
{
// ajax call to load online status
var myAjax = new Ajax(proxyURL, {
method: 'get',
headers: {'If-Modified-Since': 'Sat, 1 Jan 2000 00:00:00 GMT'},
onComplete: function(textResponse, xmlResponse)
{
var statusType = ProjectPresence.getStatusType(userDetails[0], textResponse);
status.addClass(userDetails[0] + "-" + statusType);
if (statusType == "unknown")
{
status.title = "User's status is unknown, possibly due to client privacy settings";
}
else
{
status.title = "User's status is " + statusType;
}
if (statusType == "online")
{
$('colleaguesOnline').adopt(rows[i]);
}
else
{
$('colleaguesNotOnline').adopt(rows[i]);
}
}
}).request("url=" + escape(statusURL));
}
else
{
status.addClass("none");
status.title = "User's presence provider has not been configured by Alfresco admin";
$('colleaguesNotOnline').adopt(rows[i]);
}
});
},
/* Calculates and returns the context path for the current page */
getContextPath: function()
{
var path = window.location.pathname;
var idx = path.indexOf("/", 1);
var contextPath = "";
if (idx != -1)
{
contextPath = path.substring(0, idx);
}
else
{
contextPath = "";
}
return contextPath;
},
getStatusURL: function(userDetails)
{
var provider = userDetails[0];
var username = userDetails[1];
var statusURL = "";
switch(provider)
{
case "skype":
statusURL = "http://mystatus.skype.com/" + username + ".txt";
break;
case "yahoo":
statusURL = "http://opi.yahoo.com/online?u=" + username + "&m=t&t=1";
break;
}
return statusURL;
},
getStatusType: function(provider, response)
{
var statusType = "unknown";
switch(provider)
{
case "skype":
switch (response)
{
case "Online":
statusType = "online";
break;
case "Offline":
statusType = "offline";
break;
default:
statusType = "unknown";
}
break;
case "yahoo":
statusType = (response == "01") ? "online" : "offline";
break;
}
return statusType;
}
}
window.addEvent('domready', ProjectPresence.init);

View File

@@ -0,0 +1,27 @@
/*
* Prerequisites: mootools.v1.11.js
*/
var ProjectSpace =
{
init: function()
{
var summaries = $$("#projectSummary .projectSpaceSummary");
summaries.each(function(summary, i)
{
var summaryURL = summary.attributes["rel"].value;
if (summaryURL != "")
{
// ajax call to load space summary
var myAjax = new Ajax(summaryURL, {
method: "get",
headers: {"If-Modified-Since": "Sat, 1 Jan 2000 00:00:00 GMT"},
update: summary
}).request();
}
});
}
}
window.addEvent('domready', ProjectSpace.init);