Skip to content
Browse files

Merge branch 'ux2' of github.com:karlproject/karl into ux2

  • Loading branch information...
2 parents ad62841 + 39f6eb4 commit a78b9651551ff85718fa513cdf17e7b316651a73 @reebalazs reebalazs committed Apr 9, 2012
View
46 karl/content/views/blog.py
@@ -74,6 +74,9 @@
from karl.views.forms.filestore import get_filestore
def show_blog_view(context, request):
+ # add portlets to template
+ layout = request.layout_manager.layout
+ layout.add_portlet('blog_archive')
if 'year' in request.GET and 'month' in request.GET:
year = int(request.GET['year'])
@@ -283,6 +286,10 @@ def show_blogentry_view(context, request):
# add portlets to template
layout = request.layout_manager.layout
layout.add_portlet('popper.tagbox')
+ layout.add_portlet('blog_archive')
+ # editor width and height for comments textarea
+ layout.tinymce_height = 250
+ layout.tinymce_width = 700
return dict(
api=api,
@@ -537,35 +544,26 @@ def coarse_month_range(year, month):
class MonthlyActivity(object):
- def __init__(self, year, month, count):
+ def __init__(self, year, month, count, url):
self.year = year
self.month = month
self.month_name = calendar.month_name[month]
self.count = count
+ self.url = url
class BlogSidebar(object):
+ """
+ deprecated in ux2
+ """
implements(ISidebar)
def __init__(self, context, request):
self.context = context
self.request = request
def __call__(self, api):
- counts = {} # {(year, month): count}
- for entry in self.context.values():
- if not IBlogEntry.providedBy(entry):
- continue
- if not has_permission('view', entry, self.request):
- continue
- year = entry.created.year
- month = entry.created.month
- counts[(year, month)] = counts.get((year, month), 0) + 1
- counts = counts.items()
- counts.sort()
- counts.reverse()
- activity_list = [MonthlyActivity(year, month, count)
- for ((year, month), count) in counts]
+ activity_list = archive_portlet(self.context, self.request)['archive']
blog_url = resource_url(self.context, self.request)
return render(
'templates/blog_sidebar.pt',
@@ -575,3 +573,21 @@ def __call__(self, api):
request = self.request,
)
+
+def archive_portlet(context, request):
+ blog = find_interface(context, IBlog)
+ counts = {} # {(year, month): count}
+ for entry in blog.values():
+ if not IBlogEntry.providedBy(entry):
+ continue
+ if not has_permission('view', entry, request):
+ continue
+ year = entry.created.year
+ month = entry.created.month
+ counts[(year, month)] = counts.get((year, month), 0) + 1
+ counts = counts.items()
+ counts.sort()
+ counts.reverse()
+ return {'archive': [MonthlyActivity(year, month, count,
+ request.resource_url(blog, query={'year': year, 'month': month}))
+ for ((year, month), count) in counts]}
View
79 karl/content/views/tests/test_blog.py
@@ -56,6 +56,7 @@ def test_it(self):
from webob.multidict import MultiDict
request = testing.DummyRequest(
params=MultiDict({'year': 2009, 'month': 4}))
+ request.layout_manager = mock.Mock()
from karl.utilities.interfaces import IKarlDates
karl.testing.registerUtility(dummy, IKarlDates)
from datetime import datetime
@@ -99,6 +100,7 @@ def test_it_no_year_or_month(self):
context['profiles'] = profiles = testing.DummyModel()
profiles['dummy'] = DummyProfile(title='Dummy Creator')
request = testing.DummyRequest()
+ request.layout_manager = mock.Mock()
from karl.utilities.interfaces import IKarlDates
karl.testing.registerUtility(dummy, IKarlDates)
from datetime import datetime
@@ -144,6 +146,7 @@ def test_it_no_comments(self):
from webob.multidict import MultiDict
request = testing.DummyRequest(
params=MultiDict({'year': 2009, 'month': 4}))
+ request.layout_manager = mock.Mock()
from karl.utilities.interfaces import IKarlDates
karl.testing.registerUtility(dummy, IKarlDates)
from datetime import datetime
@@ -188,6 +191,7 @@ def test_it_two_comments(self):
from webob.multidict import MultiDict
request = testing.DummyRequest(
params=MultiDict({'year': 2009, 'month': 4}))
+ request.layout_manager = mock.Mock()
from karl.utilities.interfaces import IKarlDates
karl.testing.registerUtility(dummy, IKarlDates)
from datetime import datetime
@@ -232,6 +236,7 @@ def test_it_no_workflow(self):
from webob.multidict import MultiDict
request = testing.DummyRequest(
params=MultiDict({'year': 2009, 'month': 4}))
+ request.layout_manager = mock.Mock()
from karl.utilities.interfaces import IKarlDates
karl.testing.registerUtility(dummy, IKarlDates)
from datetime import datetime
@@ -557,9 +562,6 @@ def test_handle_submit_attachment_is_None(self):
recipients.sort()
self.assertEqual(["a@x.org", "b@x.org", "c@x.org",], recipients)
- blogentry_url = "http://example.com/communities/community/blog/foo/"
-
- attachments_url = "%sattachments" % blogentry_url
self.failUnless(context['foo']['attachments']['test1.txt'])
self.failUnless(context['foo']['attachments']['test2.txt'])
@@ -612,9 +614,6 @@ def test_handle_submit(self):
recipients.sort()
self.assertEqual(["a@x.org", "b@x.org", "c@x.org",], recipients)
- blogentry_url = "http://example.com/communities/community/blog/foo/"
-
- attachments_url = "%sattachments" % blogentry_url
self.failUnless(context['foo']['attachments']['test1.txt'])
self.failUnless(context['foo']['attachments']['test2.txt'])
@@ -763,7 +762,6 @@ def test_handle_submit_attachment_is_None(self):
There seems to be some set of circumstances under which formish will
return a None as a value in the attachments sequence.
"""
- from schemaish.type import File as SchemaFile
from karl.models.interfaces import IObjectModifiedEvent
from zope.interface import Interface
from karl.models.interfaces import ITagQuery
@@ -820,7 +818,10 @@ def _callFUT(self, context, request, api):
return b(api)
def test_render(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
context = testing.DummyModel()
+ directlyProvides(context, IBlog)
request = testing.DummyRequest()
api = object()
renderer = karl.testing.registerDummyRenderer(
@@ -831,7 +832,10 @@ def test_render(self):
self.assertEquals(renderer.blog_url, 'http://example.com/')
def test_render_with_content(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
context = testing.DummyModel()
+ directlyProvides(context, IBlog)
from datetime import datetime
from zope.interface import directlyProvides
from karl.content.interfaces import IBlogEntry
@@ -854,7 +858,10 @@ def test_render_with_content(self):
self.assertEquals(renderer.blog_url, 'http://example.com/')
def test_render_ten(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
context = testing.DummyModel()
+ directlyProvides(context, IBlog)
from datetime import datetime
from zope.interface import directlyProvides
from karl.content.interfaces import IBlogEntry
@@ -870,6 +877,64 @@ def test_render_ten(self):
self._callFUT(context, request, api)
self.assertEquals(len(renderer.activity_list), 10)
+
+class TestArchivePortlet(unittest.TestCase):
+ def setUp(self):
+ testing.cleanUp()
+
+ def tearDown(self):
+ testing.cleanUp()
+
+ def _callFUT(self, context, request):
+ from karl.content.views.blog import archive_portlet as fut
+ return fut(context, request)
+
+ def test_empty(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
+ context = testing.DummyModel()
+ directlyProvides(context, IBlog)
+ request = testing.DummyRequest()
+ archive = self._callFUT(context, request)['archive']
+ self.assertEqual(archive, [])
+
+ def test_render_with_content(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
+ context = testing.DummyModel()
+ directlyProvides(context, IBlog)
+ from datetime import datetime
+ from karl.content.interfaces import IBlogEntry
+ e1 = testing.DummyModel(created=datetime(2009, 1, 2))
+ directlyProvides(e1, IBlogEntry)
+ e2 = testing.DummyModel(created=datetime(2009, 1, 10))
+ directlyProvides(e2, IBlogEntry)
+ context['e1'] = e1
+ context['e2'] = e2
+ request = testing.DummyRequest()
+ archive = self._callFUT(context, request)['archive']
+ self.assertEquals(len(archive), 1)
+ self.assertEquals(archive[0].year, 2009)
+ self.assertEquals(archive[0].month_name, 'January')
+ self.assertEquals(archive[0].count, 2)
+
+ def test_render_ten(self):
+ from zope.interface import directlyProvides
+ from karl.content.interfaces import IBlog
+ context = testing.DummyModel()
+ directlyProvides(context, IBlog)
+ from datetime import datetime
+ from karl.content.interfaces import IBlogEntry
+ for month in range(1, 11):
+ for day in (4, 7):
+ e = testing.DummyModel(created=datetime(2008, month, day))
+ directlyProvides(e, IBlogEntry)
+ context['e%d-%d' % (month, day)] = e
+ request = testing.DummyRequest()
+ archive = self._callFUT(context, request)['archive']
+ self.assertEquals(len(archive), 10)
+
+
class Test_upload_attachments(unittest.TestCase):
def setUp(self):
testing.setUp()
View
5 karl/ux2/configure.zcml
@@ -204,6 +204,11 @@
panel=".panels.extra_head"
/>
+ <bc:panel
+ name="blog_archive"
+ panel="karl.content.views.blog.archive_portlet"
+ renderer="templates/blog_archive.pt"
+ />
<!-- Assets -->
<asset
View
2 karl/ux2/forms/templates/formish/field/main.html
@@ -1,4 +1,4 @@
-<div id="${field.cssname}--field" class="control-group${' required' if 'required' in field.classes else ''}"
+<div id="${field.cssname}--field" class="field control-group${' required' if 'required' in field.classes else ''}"
tal:define="show_label field.widget.show_label|True;
show_description field.widget.show_description|True">
<!-- field/main.html -->
View
2 karl/ux2/forms/templates/formish/sequence/main.html
@@ -2,7 +2,7 @@
tal:define="addremoveclass field.widget.addremove is True and ' addremove' or '';
sortableclass field.widget.sortable is True and ' sortable' or ''"
id="${field.cssname}--field"
- class="${field.classes}${addremoveclass}${sortableclass}">
+ class="${field.classes}${addremoveclass}${sortableclass} control-group">
<!-- sequence/main.html -->
<span class="formish-sequencedata"
title="batch_add_count=${field.widget.batch_add_count}"> </span>
View
4 karl/ux2/layout.py
@@ -42,6 +42,8 @@ def __init__(self, context, request):
self.project_name = settings.get('system_name', 'KARL')
self.page_title = getattr(context, 'title', 'Page Title')
self.userid = authenticated_userid(request)
+ self.tinymce_height = 400
+ self.tinymce_width = 500
@reify
def should_show_calendar_tab(self):
@@ -111,6 +113,8 @@ def head_data(self):
'karl_static_url': self.static(''),
'chatter_url': self.chatter_url,
'date_format': self.user_date_format,
+ 'tinymce_height': self.tinymce_height,
+ 'tinymce_width': self.tinymce_width,
})
return head_data
View
6 karl/ux2/panels.py
@@ -87,8 +87,10 @@ def actions_menu(context, request, actions):
for title, url in actions:
if title.startswith('Add '):
addables.append((title, url))
- elif title.startswith('Manage ') or (overflow_menu != [] and
- title == 'Advanced'):
+ # very difficult to convert a simple tuple structure into a full
+ # featured ux2 menu. Let's add the overflow menu if there's a manage
+ # option and put all remaining options after that there.
+ elif title.startswith('Manage ') or overflow_menu != []:
overflow_menu.append({'title': title, 'url': url})
else:
converted.append({'title': title, 'url': url})
View
9 karl/ux2/templates/blog_archive.pt
@@ -0,0 +1,9 @@
+<section id="blog-archive-portlet" class="portlet sectionRelated">
+ <h3>Archive</h3>
+ <ul id="blog-archive" class="portlet-list">
+ <li class="portlet-item" tal:repeat="item archive">
+ <a href="${item.url}">${item.month_name} ${item.year}
+ <span class="label label-inverse">${item.count}</span></a>
+ </li>
+ </ul>
+</section>
View
4 karl/ux2/templates/macros.pt
@@ -18,9 +18,9 @@
</a>
</div>
- <span metal:define-macro="privacy_badge" class="label label-private">Private</span>
+ <span metal:define-macro="privacy_badge" class="label label-private">P</span>
- <span metal:define-macro="moderator_badge" class="label label-moderator">Moderator</span>
+ <span metal:define-macro="moderator_badge" class="label label-moderator">M</span>
<metal:formish_js define-macro="formish_js">
<script type="text/javascript"
View
2 karl/ux2/templates/manage_communities.pt
@@ -64,7 +64,7 @@
<div class="buttons clearafter">
<button id="form-submit" name="form.submitted" value="submit"
- type="submit" class="btn">submit
+ type="submit" class="btn btn-primary">submit
</button>
<button id="form-cancel" name="form.cancel" value="cancel"
type="submit" class="btn">cancel
View
48 karl/ux2/templates/my_communities.pt
@@ -1,31 +1,31 @@
<section class="portlet sectionRelated" id="my-communities-portlet">
- <div id="my-communities-list">
- <h3>My Communities</h3>
- <div class="portlet-item" tal:repeat="my_community my_communities">
+ <h3>My Communities</h3>
+ <ul id="my-communities-list" class="portlet-list">
+ <li class="portlet-item" tal:repeat="my_community my_communities">
<a href="${my_community.url}">
${my_community.title}
</a> <span tal:omit-tag="not my_community.moderator" class="label label-moderator">M</span>
- </div>
- <div class="portlet-buttons">
- <a tal:condition="preferred_communities is None"
- class="btn btn-small"
- title="Personalize the list of communities that appear on this list"
- href="${layout.app_url}/jquery_edit_preferred.html">
- Set preferred
- </a>
- <a tal:condition="preferred_communities is not None"
- class="btn btn-small"
- title="Edit your personalized list of communities"
- href="${layout.app_url}/jquery_edit_preferred.html">
- Edit preferred
- </a>
- <a tal:condition="preferred_communities is not None"
- class="btn btn-small"
- title="Show all of your communities now"
- href="${layout.app_url}/jquery_list_my_communities.html">
- Show all
- </a>
- </div>
+ </li>
+ </ul>
+ <div class="portlet-buttons">
+ <a tal:condition="preferred_communities is None"
+ class="btn btn-small"
+ title="Personalize the list of communities that appear on this list"
+ href="${layout.app_url}/jquery_edit_preferred.html">
+ Set preferred
+ </a>
+ <a tal:condition="preferred_communities is not None"
+ class="btn btn-small"
+ title="Edit your personalized list of communities"
+ href="${layout.app_url}/jquery_edit_preferred.html">
+ Edit preferred
+ </a>
+ <a tal:condition="preferred_communities is not None"
+ class="btn btn-small"
+ title="Show all of your communities now"
+ href="${layout.app_url}/jquery_list_my_communities.html">
+ Show all
+ </a>
</div>
<script language="javascript" type="text/javascript">
//<![CDATA[
View
2 karl/ux2/templates/people_pictures.pt
@@ -50,7 +50,7 @@
<div class="visual-clear"></div>
</tal:row_loop>
</div>
-
+ <div class="visual-clear"></div>
${panel('popper.grid_footer', batch=batch)}
</div>
View
40 karl/ux2/templates/profile.pt
@@ -114,6 +114,46 @@
</div>
</div>
+ <div class="modal" id="deactivateModal">
+ <div class="modal-header">
+ <a class="close" data-dismiss="modal">×</a>
+ <h3>Deactivate Account</h3>
+ </div>
+ <div class="modal-body">
+ <p>
+Do you really want to deactivate the <b>${request.context.__name__}</b> user account? The account owner will no longer be able to log into the system and this profile will not appear in any searches or directories. The profile will remain linked from content which <b>${request.context.__name__}</b> has authored on the site and visible to other users.
+ </p>
+ </div>
+ <div class="modal-footer">
+ <a id="cancelDeactivate" href="#" class="btn">Cancel</a>
+ <a id="doDeactivate" href="${request.url}/deactivate.html?confirm=1" class="btn btn-primary">Deactivate</a>
+ </div>
+ </div>
+ <div class="modal" id="reactivateModal">
+ <div class="modal-header">
+ <a class="close" data-dismiss="modal">×</a>
+ <h3>Reactivate Account</h3>
+ </div>
+ <div class="modal-body">
+ <p>
+Are you sure? This operation will reactivate the user account for this profile. The user will be able to log into the system once again and this profile will appear in searches and directories.
+ </p>
+ </div>
+ <div class="modal-footer">
+ <a id="cancelReactivate" href="#" class="btn">Cancel</a>
+ <a id="doReactivate" href="${request.url}/reactivate.html?confirm=1" class="btn btn-primary">Reactivate</a>
+ </div>
+ </div>
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ $(document).ready(function() {
+ $('#cancelDeactivate').click(function () { $('#deactivateModal').modal('hide'); })
+ $('#cancelReactivate').click(function () { $('#reactivateModal').modal('hide'); })
+ });
+ var deactivate = function() { $('#deactivateModal').modal('show'); }
+ var reactivate = function() { $('#reactivateModal').modal('show'); }
+ //]]>
+ </script>
</div>
</body>
</html>
View
16 karl/ux2/templates/profile_edit_form.pt
@@ -19,26 +19,14 @@
<div tal:condition="include_blurb">
<p>
- Use the following form to edit your profile information. If
- you would like to deactivate your ${layout.project_name} account and remove
- yourself from all communities, click this <a
- href="${layout.here_url}deactivate.html" id="deleteuserlink">deactivate
- account</a> link and say <em>yes</em> to the confirmation
- window. If you would like to change your password, please click
+ Use the following form to edit your profile information.
+ If you would like to change your password, please click
<a href="${layout.here_url}change_password.html">Change Password</a>.
</p>
</div>
<span tal:content="structure request.form()" tal:omit-tag=""/>
- <a tal:condition="is_active and admin_edit|False"
- href="${layout.here_url}deactivate.html"
- id="deleteuserlink">deactivate this user</a>
-
- <a tal:condition="not is_active and admin_edit|False"
- href="${layout.here_url}reactivate.html"
- id="deleteuserlink">reactivate this user</a>
-
</div>
</div>
View
14 karl/ux2/templates/show_blog.pt
@@ -6,16 +6,13 @@
</metal:feed>
<div metal:fill-slot="content">
-
- ${panel('status_message')}
- ${panel('popper.actions_menu', actions=actions)}
-
- <div>
<div class="blogEntry ${repeat['entry'].start and 'noborder' or ''}"
tal:repeat="entry entries">
- <h2>
- <a href="${entry['href']}">${entry['title']}</a>
- </h2>
+ <header>
+ ${panel('status_message')}
+ ${panel('popper.actions_menu', actions=actions)}
+ <h2><a href="${entry['href']}">${entry['title']}</a></h2>
+ </header>
<tal:block condition="entry['description']">
<div tal:content="structure entry['description']"/>
@@ -54,6 +51,5 @@
id="RSSIcon"/></a>
</div>
- </div>
</metal:block>
View
2 karl/views/forms/templates/snippets.pt
@@ -27,7 +27,7 @@
Please enter your current password and a new password below, then
click the submit button. The password must be at least 8 characters
long. If you need additional help, please email the
- <a href="mailto:${api.settings.admin_email}">Site Administrator</a>.
+ <a href="mailto:${api.settings.admin_email|admin_email}">Site Administrator</a>.
</p>
</metal:change_password_blurb>
View
15 karl/views/people.py
@@ -587,6 +587,20 @@ def get_profile_actions(profile, request):
actions.append(('Manage Tags', 'manage_tags.html'))
if has_permission('administer', profile, request):
actions.append(('Advanced', 'advanced.html'))
+ if same_user:
+ actions.append(('Deactivate My Account', 'javascript:deactivate()'))
+ if has_permission('administer', profile, request) and not same_user:
+ users = find_users(profile)
+ userid = profile.__name__
+ user = users.get_by_id(userid)
+ if user is not None:
+ is_active = True
+ else:
+ is_active = False
+ if is_active:
+ actions.append(('Deactivate This User', 'javascript:deactivate()'))
+ if not is_active:
+ actions.append(('Reactivate This User', 'javascript:reactivate()'))
return actions
def show_profile_view(context, request):
@@ -918,6 +932,7 @@ def __call__(self):
blurb_macro = snippets.macros['change_password_blurb']
return {'api': api, 'old_layout': layout, # deprecated UX1
'actions': [],
+ 'admin_email': api.settings.admin_email, #ux2
'blurb_macro': blurb_macro}
def handle_cancel(self):
View
24 karl/views/static/ux2/main.css
@@ -10,10 +10,10 @@
.karl-wikitoc-gridwrapper .grid-canvas .even div{background:#f1eade;}
.karl-wikitoc-gridwrapper .grid-canvas .odd div{background:#f9f5f0;}
.karl-wikitoc-gridwrapper .grid-canvas .karl-wikitoc-grid-row-hover .slick-cell{background:#ffffff;}
-.karl-wikitoc-gridwrapper .grid-canvas .slick-cell{padding:0.375em 7.5834px;font-size:0.889em;}@media only screen and (min-width:640px){.karl-wikitoc-gridwrapper .grid-canvas .slick-cell{padding:0.375em 15.1667px;}}.karl-wikitoc-gridwrapper .grid-canvas .slick-cell a,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell a:visited,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell .ui-widget-content a,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell .ui-widget-content a:visited{color:#3d8fb3;text-decoration:none;}
+.karl-wikitoc-gridwrapper .grid-canvas .slick-cell{padding:0.375em 7.5834px;font-size:0.889em;}@media only screen and (min-width: 640px){padding:0.375em 15.1667px;}.karl-wikitoc-gridwrapper .grid-canvas .slick-cell a,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell a:visited,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell .ui-widget-content a,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell .ui-widget-content a:visited{color:#3d8fb3;text-decoration:none;}
.karl-wikitoc-gridwrapper .grid-canvas .slick-cell a:hover,.karl-wikitoc-gridwrapper .grid-canvas .slick-cell .ui-widget-content a:hover{color:#82bbd4;text-decoration:none;border-bottom:none;}
.karl-wikitoc-gridwrapper .slick-header{border-top:0;border-bottom:0;}
-.karl-wikitoc-gridwrapper .slick-header-columns{background:#8f806f;}.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column{height:24px;line-height:24px;margin:0;border-right:1px solid #FFFFFF;border-left:0px;border-top:0px;border-bottom:0px;background:none repeat scroll 0 0 #8F806F;color:#DBCFC1;background:#8f806f;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#dbcfc1;font-weight:bold;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.4);}.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default{padding:0.375em 7.5834px;font-size:0.889em;}@media only screen and (min-width:640px){.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default{padding:0.375em 15.1667px;}}
+.karl-wikitoc-gridwrapper .slick-header-columns{background:#8f806f;}.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column{height:24px;line-height:24px;margin:0;border-right:1px solid #FFFFFF;border-left:0px;border-top:0px;border-bottom:0px;background:none repeat scroll 0 0 #8F806F;color:#DBCFC1;background:#8f806f;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#dbcfc1;font-weight:bold;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.4);}.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default{padding:0.375em 7.5834px;font-size:0.889em;}@media only screen and (min-width: 640px){padding:0.375em 15.1667px;}
.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column a,.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column a:visited{color:#dbcfc1;}
.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column a:hover{color:#fff;}
.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default{background:#8f806f;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;color:#dbcfc1;font-weight:bold;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.4);}.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default a,.karl-wikitoc-gridwrapper .slick-header-columns .slick-header-column.ui-state-default a:visited{color:#dbcfc1;}
@@ -43,7 +43,7 @@
.karl-wikitoc-footer{height:36px;border:0 none;}.karl-wikitoc-footer .karl-wikitoc-button-inspector{float:right;margin:4px;}
#bcpanel-global-logo{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzA3REIwNjUyRjc0MTFFMUFERTREODE2MDdDQzRDMUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzA3REIwNjYyRjc0MTFFMUFERTREODE2MDdDQzRDMUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMDdEQjA2MzJGNzQxMUUxQURFNEQ4MTYwN0NDNEMxQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMDdEQjA2NDJGNzQxMUUxQURFNEQ4MTYwN0NDNEMxQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtAIhZYAAAQ6SURBVHjazFZNbBtVEJ6N1856vbE3/neTOIY6qfPTdpumaSr+LJAQFZeIA6oEhxy4IMSxJy49g4SQEBIHkHpBQsAhB1BBQpUlSolaYaxiV4aEyE4d4sR/u7Vjr39SMbPYVRy7jiMujPS0u2/fvu/NzDffLAPHsKfHxzm8BHBIOHyHXss44jhWN5JJ+eAL5hgAtOmS1SGKwVcX4fRCAPBee1fZU2H9fgJC363CeixBUyEECh0LBAHo5EuvLb8CLyBALyOQzz74koAjCLRCc7o+PbjyxjtL8MzL80ceyOoUYUryQ/h21D3EC1BQlATTZVOxGXOKvRvHonvMyblHHeAasWdHn/JkzywE0keBkUcfX7tOtx8xhwAoFkH/jI+7GJTA5hy2l/cqs9PnJkApFCH9IAOx8Bo0Gg310otzcd/kqNwL6ItPVuBOKBLRHQBYMpq4Z99+70328utBGPG5Qc4q3iGLIFisZsB34PDYYGZuAvbr++wvN8NunU6nonelJ4Ew6EL456jINgGCuIn07rVlbfOW1WsNzuaydnwsXZoGwczDTz/cDTg81pJnzNkV6PQFijhwbDMHwbeuXmkDaJmOHWh73ohvCn8nd/jcrszV1NrA9Q+/HsWcpYYsphKGLz1zfjJt5LnGwW/Ik+ACxh/z0NXl/cYj7ZrPKIbVm2EnwzDsBK49dfakVid/xRKsYDHx5VIF1u4n/N98fsM3JZ1MzD93JkX10wLxIVu6AugNrKrkH0JutyD8djtmJwJMnfO3raF8IRF4PGSZDrq5vsViGP2FrCIgI0kBZAIR/dPdvcANsn9GN7xbiR37hefPwvjESMcajh+EQlZlW89e/whctpjgxlch96+3ouTKihZwYk43s7mGs+uxpPmE19kVoOltZ0FiGKkEtjd36PSRgV48/+Pehh15+NB3agzUSrV7zvYfdcxRLiplFWbPT5KQSQSi/n433nWD7Qe7IjKmNmwXs0VlDyi5h61crJA3j9mk5IuaWJoEY3rxpTkC8ZGv8Xt34lKT022GSRdm5ibByA+W9HpdTZFLTvSIpfDqDXp0kqE1pFflfEaG/K5MB2nY3dbEiXFXi11aMYaw9KWLT6Ax0vNfGurZms0hpirlqlCr1vi9YoXLbOcGcjv5BkpP2cAZSqLVnKZawbWNg7lmqcFgQYZQnoOHK54MC67tmbyiQSevYp5m5wMR0WbuqWFa4qnBkP6Tajabjma8YFS3U5mOj9I4h/UAHq8r3gugmWv1sUCi7sdJ/zF0bkwcS/I8yA1SEp0BrO5atQ5yToHkWgowVCrWQ9SOFO/lwY8rt2ArkY62kZw8wtBF0BsJR4sJar1a50gUUZNkFMw0Km9f/QQPrLVips/OuEydkTSuH6N8vX/1U6oX+qn4/sj2i2GUh0VRxvgGeGQLsqevjtjs8d/+v/5W/ut/1z8CDAC7HuQpbPqu1AAAAABJRU5ErkJggg==);}
a#global-logo{padding-left:35px;}
-@media only screen and (min-width:768px){input,textarea,select,.uneditable-input,.help-block{width:550px;} .tagbox{display:block;width:550px;} #newTag{width:460px;}}.pushdownContent .avatar{width:48px;height:auto;}
+@media only screen and (min-width: 768px){input,textarea,select,.uneditable-input,.help-block{width:550px;} .tagbox{display:block;width:auto;} #newTag{width:auto;}}.pushdownContent .avatar{width:48px;height:auto;}
.pushdownContent .panel-item{overflow:hidden;}
.kscreentitle{margin-top:0;}
#recent-quips-add-form textarea{width:99%;}
@@ -59,13 +59,27 @@ a#global-logo{padding-left:35px;}
#radar-panel a.selected{color:#fff;}
#radar-panel .timeline{float:right;font-family:Verdana,sans-serif;font-size:0.75em;margin:4px 0 0 4px;}
.column{padding:0;}
-.save-attachments{margin-bottom:15px;}.save-attachments label{display:inline;}
+.save-attachments{margin-bottom:15px;}.save-attachments label{text-align:right;display:inline;}
.adderlink{margin-left:22.75%;}
.save-sendalert label{text-align:left !important;}
.save-attachments-n input{margin-left:0;margin-right:40px;}
.portrait{float:left;margin:5px 20px 5px 0;}
.profileDetails{float:left;}
+.profileDetails p{margin-bottom:0;}
.profileLabel{font-weight:bold;}
.profileBio{clear:both;margin-right:25px;}
.notification .actions{margin:1em 0 1em 2.75em;}
-#actions-overflow-menu{margin:0px 20px;}
+#actions-overflow-menu{margin:0;}
+.karlselectionradiofield label{display:inline;}
+.profilesWrapper{background-color:#ffffff;padding:0;margin:0;display:block;width:100%;}.profilesWrapper .photoProfile{height:130px;background-color:#F1EADE;padding:0;width:33%;margin:0 0.5% 0.5% 0;font-size:0.9em;float:left;display:inline;overflow:hidden;}.profilesWrapper .photoProfile img{font-size:1em;}
+.profilesWrapper .photoProfile h4{margin:10px 10px 0;font-weight:normal;font-size:1em;}
+.profilesWrapper .photoProfile p{line-height:1.5em;margin:0.5em 10px 10px;}
+.profilesWrapper .photoProfile p span{display:block;}
+.profilesWrapper .photoProfileEndRow{margin-right:0;}
+.profilesWrapper .photoProfileImage{float:left;display:inline;margin:10px;height:100px;width:75px;}.profilesWrapper .photoProfileImage img{border:none;-ms-interpolation-mode:bicubic;}
+.profilesWrapper .profileInfoBox{float:left;margin:1em 0 0.2em;line-height:1.5em;overflow:hidden;width:118px;}
+.profilesWrapper .profileNoWrap{white-space:nowrap;}
+.profilesWrapper a.rightFloatLink{float:right;text-decoration:none;}
+.profilesWrapper .visual-clear{clear:both;}
+#deactivateModal{display:none;}
+#reactivateModal{display:none;}
View
83 karl/views/static/ux2/main.less
@@ -24,11 +24,11 @@ a#global-logo {
.tagbox {
display: block;
- width: 550px;
+ width: auto;
}
#newTag {
- width: 460px;
+ width: auto;
}
}
@@ -133,6 +133,7 @@ a#global-logo {
margin-bottom:15px;
label {
display:inline;
+ text-align: right;
}
}
@@ -158,6 +159,10 @@ a#global-logo {
float: left;
}
+.profileDetails p {
+ margin-bottom:0;
+}
+
.profileLabel {
font-weight:bold;
}
@@ -174,5 +179,77 @@ a#global-logo {
}
#actions-overflow-menu {
- margin:0px 20px;
+ margin:0;
+}
+
+.karlselectionradiofield label {
+ display:inline;
+}
+
+/* PEOPLE PICTURE TRANSITION CSS */
+.profilesWrapper {
+ background-color: #ffffff;
+ padding: 0;
+ margin: 0;
+ display: block;
+ width: 100%;
+ .photoProfile {
+ height: 130px;
+ background-color: #F1EADE;
+ padding: 0;
+ width: 33%;
+ margin: 0 0.5% 0.5% 0;
+ font-size: 0.9em;
+ float: left;
+ display: inline;
+ overflow: hidden;
+ img {
+ font-size: 1em;
+ }
+ h4 {
+ margin: 10px 10px 0;
+ font-weight: normal;
+ font-size: 1em;
+ }
+ p {
+ line-height: 1.5em;
+ margin: 0.5em 10px 10px;
+ }
+ p span {
+ display: block;
+ }
+ }
+ .photoProfileEndRow {
+ margin-right: 0;
+ }
+ .photoProfileImage {
+ float: left;
+ display: inline;
+ margin: 10px;
+ height: 100px;
+ width: 75px;
+ img {
+ border: none;
+ -ms-interpolation-mode: bicubic; /* ie 7 */
+ }
+ }
+ .profileInfoBox {
+ float: left;
+ margin: 1em 0 0.2em;
+ line-height: 1.5em;
+ overflow: hidden;
+ width: 118px;
+ }
+ .profileNoWrap {
+ white-space: nowrap;
+ }
+ a.rightFloatLink {
+ float: right;
+ text-decoration: none;
+ }
+ .visual-clear {
+ clear: both;
+ }
}
+
+
View
8 karl/views/static/ux2/tinymce/karl-tiny-wire.js
@@ -26,6 +26,10 @@ $(document).ready(function() {
var tinymce_url = head_data.karl_static_url + 'tinymce/3.3.9.2';
// The root url of Karl
var app_url = head_data.app_url;
+ // Editor height
+ var tinymce_height = head_data.tinymce_height;
+ // Editor width
+ var tinymce_width= head_data.tinymce_width;
// initialize the editor widget(s)
$('.mceEditor').tinysafe({
@@ -38,8 +42,8 @@ $(document).ready(function() {
theme: 'advanced',
skin: 'karl',
mode: 'specific_textareas',
- height: 400,
- width: 550,
+ height: tinymce_height,
+ width: tinymce_width,
convert_urls : false,
gecko_spellcheck : true,
submit_patch: false,
View
6 karl/views/tests/test_people.py
@@ -917,7 +917,7 @@ def test_editable(self):
context['profiles'] = testing.DummyModel()
context['profiles']['userid'] = DummyProfile()
response = self._callFUT(context, request)
- self.assertEqual(len(response['actions']), 4)
+ self.assertEqual(len(response['actions']), 5)
self.assertEqual(response['actions'][0][1], 'admin_edit_profile.html')
self.assertEqual(response['actions'][1][1], 'manage_communities.html')
self.assertEqual(response['actions'][2][1], 'manage_tags.html')
@@ -943,7 +943,7 @@ def test_not_editable(self):
context['profiles'] = testing.DummyModel()
context['profiles']['userid'] = DummyProfile()
response = self._callFUT(context, request)
- self.assertEqual(len(response['actions']), 2)
+ self.assertEqual(len(response['actions']), 3)
self.assertEqual(response['actions'][0][1], 'admin_edit_profile.html')
def test_communities(self):
@@ -1152,7 +1152,7 @@ def test_system_user(self):
context['profiles'] = testing.DummyModel()
context['profiles']['userid'] = DummyProfile()
response = self._callFUT(context, request)
- self.assertEqual(len(response['actions']), 2)
+ self.assertEqual(len(response['actions']), 3)
self.assertEqual(response['actions'][0][1], 'admin_edit_profile.html')
def test_never_logged_in(self):

0 comments on commit a78b965

Please sign in to comment.
Something went wrong with that request. Please try again.