← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wallyworld/launchpad/long-text-truncate into lp:launchpad

 

Ian Booth has proposed merging lp:~wallyworld/launchpad/long-text-truncate into lp:launchpad with lp:~wallyworld/launchpad/improve-dupe-bug-ui-227310 as a prerequisite.

Requested reviews:
  Curtis Hovey (sinzui)

For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/long-text-truncate/+merge/118879

== Implementation ==

This branch enhances the TestLineEditorWidget so that when the text is too long, it is truncated and an "..." is used. The fields with are enhanced are:

- project title
- bugtask title
- blueprint title
- archive display name
- source package recipe name

I didn't add a default max width to the widget because I felt we didn't want to enforce a truncation by default, but it it is deemed appropriate, I'll add it.

All uses of the widget use max-width=90% to allow room for the pencil icon to be rendered on the same line. So this is perhaps an argument for using a default value. Thoughts?

== Demo ==

http://people.canonical.com/~ianb/truncated-bugtask-title.png
http://people.canonical.com/~ianb/truncated-project-title.png

== Tests ==

Update the doctest lazr-js-widgets.txt

== Lint ==

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/app/browser/lazrjs.py
  lib/lp/app/doc/lazr-js-widgets.txt
  lib/lp/app/templates/text-line-editor.pt
  lib/lp/blueprints/browser/specification.py
  lib/lp/bugs/browser/bugtask.py
  lib/lp/code/browser/sourcepackagerecipe.py
  lib/lp/registry/browser/product.py
  lib/lp/soyuz/browser/archive.py
-- 
https://code.launchpad.net/~wallyworld/launchpad/long-text-truncate/+merge/118879
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
=== modified file 'lib/lp/app/browser/lazrjs.py'
--- lib/lp/app/browser/lazrjs.py	2012-07-07 14:00:30 +0000
+++ lib/lp/app/browser/lazrjs.py	2012-08-09 07:20:31 +0000
@@ -155,7 +155,7 @@
 
     def __init__(self, context, exported_field, title, tag, css_class=None,
                  content_box_id=None, edit_view="+edit", edit_url=None,
-                 edit_title='',
+                 edit_title='', max_width=None,
                  default_text=None, initial_value_override=None, width=None):
         """Create a widget wrapper.
 
@@ -165,6 +165,8 @@
         :param title: The string to use as the link title.
         :param tag: The HTML tag to use.
         :param css_class: The css class value to use.
+        :param max_width: The maximum width of the rendered text before it is
+            truncated with an '...'.
         :param content_box_id: The HTML id to use for this widget.
             Defaults to edit-<attribute name>.
         :param edit_view: The view name to use to generate the edit_url if
@@ -183,6 +185,7 @@
             edit_view, edit_url, edit_title)
         self.tag = tag
         self.css_class = css_class
+        self.max_width = max_width
         self.default_text = default_text
         self.initial_value_override = simplejson.dumps(initial_value_override)
         self.width = simplejson.dumps(width)
@@ -195,6 +198,12 @@
         else:
             return FormattersAPI(text).obfuscate_email()
 
+    @property
+    def css_style(self):
+        if self.max_width:
+            return 'max-width: %s;' % self.max_width
+        return ''
+
 
 class TextAreaEditorWidget(TextWidgetBase):
     """Wrapper for the multine-line lazr-js inlineedit/editor.js widget."""

=== modified file 'lib/lp/app/doc/lazr-js-widgets.txt'
--- lib/lp/app/doc/lazr-js-widgets.txt	2012-07-07 14:00:30 +0000
+++ lib/lp/app/doc/lazr-js-widgets.txt	2012-08-09 07:20:31 +0000
@@ -28,14 +28,18 @@
     ...     name='widget', title='Widgets > important')
     >>> title_field = IProduct['title']
     >>> title = 'Edit the title'
-    >>> widget = TextLineEditorWidget(product, title_field, title, 'h1')
+    >>> widget = TextLineEditorWidget(
+    ...     product, title_field, title, 'h1', max_width='90%')
 
 The widget is rendered by executing it, it prints out the attribute
 content.
 
     >>> print widget()
-    <h1 id="edit-title"><span class="yui3-editable_text-text">Widgets &gt;
-        important</span>
+    <h1 id="edit-title">
+    <span class="yui3-editable_text-text ellipsis"
+          style="max-width: 90%;">
+        Widgets &gt; important
+    </span>
     </h1>
 
 In addition, when the logged in user can edit the value, there is a link to
@@ -44,8 +48,11 @@
 
     >>> ignored = login_person(product.owner)
     >>> print widget()
-    <h1 id="edit-title"><span class="yui3-editable_text-text">Widgets
-        &gt; important</span>
+    <h1 id="edit-title">
+    <span class="yui3-editable_text-text ellipsis"
+          style="max-width: 90%;">
+        Widgets &gt; important
+    </span>
         <a class="yui3-editable_text-trigger sprite edit action-icon"
            href="http://launchpad.dev/widget/+edit";
            title="">Edit</a>

=== modified file 'lib/lp/app/templates/text-line-editor.pt'
--- lib/lp/app/templates/text-line-editor.pt	2012-06-15 16:23:50 +0000
+++ lib/lp/app/templates/text-line-editor.pt	2012-08-09 07:20:31 +0000
@@ -1,5 +1,8 @@
-<tal:open-tag replace="structure view/open_tag"/><span
-  class="yui3-editable_text-text"><tal:text replace="view/value"/></span>
+<tal:open-tag replace="structure view/open_tag"/>
+<span class="yui3-editable_text-text ellipsis"
+    tal:attributes="style string:${view/css_style}">
+    <tal:text replace="view/value"/>
+</span>
   <a tal:condition="view/can_write"
      tal:attributes="href view/edit_url;
                      title view/edit_title"

=== modified file 'lib/lp/blueprints/browser/specification.py'
--- lib/lp/blueprints/browser/specification.py	2012-06-29 08:40:05 +0000
+++ lib/lp/blueprints/browser/specification.py	2012-08-09 07:20:31 +0000
@@ -620,7 +620,8 @@
     def title_widget(self):
         field = ISpecification['title']
         title = "Edit the blueprint title"
-        return TextLineEditorWidget(self.context, field, title, 'h1')
+        return TextLineEditorWidget(
+            self.context, field, title, 'h1', max_width='90%')
 
     @property
     def summary_widget(self):

=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py	2012-08-07 02:58:20 +0000
+++ lib/lp/bugs/browser/bugtask.py	2012-08-09 07:20:31 +0000
@@ -733,7 +733,8 @@
 
         self.bug_title_edit_widget = TextLineEditorWidget(
             bug, IBug['title'], "Edit this summary", 'h1',
-            edit_url=canonical_url(self.context, view_name='+edit'))
+            edit_url=canonical_url(self.context, view_name='+edit'),
+            max_width='90%')
 
         # XXX 2010-10-05 gmb bug=655597:
         # This line of code keeps the view's query count down,

=== modified file 'lib/lp/code/browser/sourcepackagerecipe.py'
--- lib/lp/code/browser/sourcepackagerecipe.py	2012-06-29 08:40:05 +0000
+++ lib/lp/code/browser/sourcepackagerecipe.py	2012-08-09 07:20:31 +0000
@@ -301,7 +301,8 @@
     def name_widget(self):
         name = ISourcePackageRecipe['name']
         title = "Edit the recipe name"
-        return TextLineEditorWidget(self.context, name, title, 'h1')
+        return TextLineEditorWidget(
+            self.context, name, title, 'h1', max_width='90%')
 
     @property
     def distroseries_widget(self):

=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2012-07-30 19:57:10 +0000
+++ lib/lp/registry/browser/product.py	2012-08-09 07:20:31 +0000
@@ -960,7 +960,7 @@
         title_field = IProduct['title']
         title = "Edit this title"
         self.title_edit_widget = TextLineEditorWidget(
-            product, title_field, title, 'h1')
+            product, title_field, title, 'h1', max_width='90%')
         programming_lang = IProduct['programminglang']
         title = 'Edit programming languages'
         additional_arguments = {

=== modified file 'lib/lp/soyuz/browser/archive.py'
--- lib/lp/soyuz/browser/archive.py	2012-07-20 10:14:01 +0000
+++ lib/lp/soyuz/browser/archive.py	2012-08-09 07:20:31 +0000
@@ -900,7 +900,8 @@
     def displayname_edit_widget(self):
         display_name = IArchive['displayname']
         title = "Edit the displayname"
-        return TextLineEditorWidget(self.context, display_name, title, 'h1')
+        return TextLineEditorWidget(
+            self.context, display_name, title, 'h1', max_width='90%')
 
     @property
     def default_series_filter(self):


Follow ups