Skip to content

Commit 1feb627

Browse files
committed
issue2551353 - Add roundup-classhelper for 2.4.0 release
Changes to the classic template are not done yet. Still testing. This commit has document updates and changes to rest.py. rest.py: add /rest/data/user/role endpoint to core so the user doesn't have to add the /rest/roles endpoint via interfaces.py. It will only send roles for a user with Admin role and there is no way to override this currently. acknowledgements.txt: Added members of team3 to other contributors. Specified for all other contributes what they worked on. upgrading.txt: added classhelper section and basic template change directions. Linked to admin_guide for full directions. admin_guide.txt: documented install, translation, troubleshooting, config etc. user_guide.txt: added section on using the classhelper. Added reference to section earlier in the doc. Added image for section.
1 parent 8068270 commit 1feb627

File tree

6 files changed

+465
-1
lines changed

6 files changed

+465
-1
lines changed

doc/acknowledgements.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ Developer activity by changesets::
3232

3333
Other contributers
3434

35-
Norbert Schlemmer
35+
Norbert Schlemmer - docker support
36+
37+
Bharath Kanama, Nikunj Thakkar, Patel Malav - classhelper web
38+
component development.
3639

3740
2.3
3841
---

doc/admin_guide.txt

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,323 @@ handlers.
514514

515515
.. _CSP: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
516516

517+
Classhelper Web Component
518+
=========================
519+
520+
Version 2.4.0 provides a new classhelper popup written as a
521+
web component. By installing 3 files and adding a stanza to
522+
``interfaces.py`` you can enable the new component.
523+
524+
The `development of this component was done by team-03
525+
<https://github.com/UMB-CS-682-Team-03/tracker>`_ of the
526+
Spring 2024 CS682 graduate software engineering SDL capstone
527+
class at the University of Massachusetts - Boston. Their
528+
documentation is copied/adapted below.
529+
530+
File Installation
531+
-----------------
532+
533+
There are three files to install in your tracker. You can
534+
copy them from the template directory for the classic
535+
tracker. The location of the template file can be obtained
536+
by running: ``roundup-admin templates`` and looking for the
537+
path value of the classic template. If the path value is
538+
``/path/to/template``, copy::
539+
540+
/path/to/template/html/classhelper.js
541+
/path/to/template/html/classhelper.css
542+
/path/to/template/html/_generic.translation
543+
544+
to your tracker's html directory.
545+
546+
.. :
547+
remove in 2.5 release if /data/user/roles endpoint
548+
in rest.py is successful.
549+
550+
If you wish to search for user's by role, you have to do one more
551+
step. Because roles are not an actual class (e.g. like status or
552+
keyword), you have to set up a new REST endpoint for them. To do this,
553+
copy::
554+
555+
556+
from roundup.rest import Routing, RestfulInstance, _data_decorator
557+
558+
class RestfulInstance:
559+
560+
@Routing.route("/roles", 'GET')
561+
@_data_decorator
562+
def get_roles(self, input):
563+
"""Return all defined roles. The User class property
564+
roles is a string but simulate it as a MultiLink
565+
to an actual Roles class.
566+
"""
567+
return 200, {"collection":
568+
[{"id": rolename,"name": rolename}
569+
for rolename in list(self.db.security.role.keys())]}
570+
571+
into the file ``interfaces.py`` in your tracker's home
572+
directory. You can create this file if it doesn't exist.
573+
See the `REST documentation <rest.html>`_ for details on
574+
``interfaces.py``.
575+
576+
The classic tracker does not have the ``/roles`` REST endpoint
577+
configured. If you are creating a new tracker from the classic
578+
template, it will show a text based search not a select/dropdown based
579+
search. By modifying interfaces.py you will enable a dropdown search.
580+
581+
Wrapping the Classic Classhelper
582+
--------------------------------
583+
584+
To allow your users to select items in the web interface
585+
using the new classhelper, you should edit the template files
586+
in the ``html/`` subdirectory of your tracker. Where you see
587+
code like::
588+
589+
<th i18n:translate="">Superseder</th>
590+
<td>
591+
<span tal:replace="structure
592+
python:context.superseder.field(showid=1,size=20)" />
593+
<span tal:condition="context/is_edit_ok"
594+
tal:replace="structure
595+
python:db.issue.classhelp('id,title',
596+
property='superseder', pagesize=100)" />
597+
[...]
598+
</td>
599+
600+
change it to wrap the classhelp span like this::
601+
602+
<th i18n:translate="">Superseder</th>
603+
<td>
604+
<span tal:replace="structure
605+
python:context.superseder.field(showid=1,size=20)" />
606+
<roundup-classhelper
607+
data-popup-title="Superseder Classhelper - {itemDesignator}"
608+
data-search-with="title,status,keyword[]-name">
609+
<span tal:condition="context/is_edit_ok"
610+
tal:replace="structure
611+
python:db.issue.classhelp('id,title',
612+
property='superseder', pagesize=100)" />
613+
</roundup-classhelper>
614+
[...]
615+
</td>
616+
617+
which displays a three part classhelper.
618+
619+
1. the search pane includes a text search box for the `title`
620+
and `status` properties and a dropdown for the keyword property,
621+
sorted by name in descending order.
622+
2. the selection pane will show 100 search results per page.
623+
It also allows the user to move to the next or previous result
624+
page.
625+
3. the accumulator at the bottom shows all the selected items. It
626+
also has buttons to accept the items or cancel the
627+
classhelper, leaving the original page unchanged.
628+
629+
Note that the user class is a little different because users without
630+
an Admin role can't search for a user by Role. So we hide the Role
631+
search element for non admin users. Starting with::
632+
633+
<th i18n:translate="">Nosy List</th>
634+
<td>
635+
<span tal:replace="structure context/nosy/field" />
636+
<span tal:condition="context/is_edit_ok" tal:replace="structure
637+
python:db.user.classhelp('username,realname,address',
638+
property='nosy', width='600'" />
639+
</td>
640+
641+
wrap the classhelp span with ``<roundup-classhelper>`` like::
642+
643+
<th i18n:translate="">Nosy List</th>
644+
<td>
645+
<span tal:replace="structure context/nosy/field" />
646+
<roundup-classhelper tal:define="search string:name,phone,roles[]"
647+
tal:attributes="data-search-with python:search
648+
if request.user.hasRole('Admin') else
649+
','.join(search.split(',')[:-1])">
650+
<span tal:condition="context/is_edit_ok" tal:replace="structure
651+
python:db.user.classhelp('username,realname,address',
652+
property='nosy', width='600'" />
653+
</roundup-classhelper>
654+
</td>
655+
656+
The ``','.join(search.split(',')[:-1])`` removes the last element of
657+
the search string (``roles[]``) if the user does not have the Admin
658+
role.
659+
660+
<roundup-classhelper> configuration
661+
-----------------------------------
662+
663+
There are two attributes used to configure the classhelper.
664+
665+
data-popup-title:
666+
* this attribute is optional. A reasonable default is
667+
provided if it is missing.
668+
* Adding ``data-popup-title`` changes the title of the popup
669+
window with the value of the attribute.
670+
* ``{itemDesignator}`` can be used inside the attribute value
671+
to replace it with the current classhelper usage context.
672+
E.G. ``data-popup-title="Nosy List Classhelper - {itemDesignator}"``
673+
will display the popup window title as ``Nosy List Classhelper - issue24``
674+
675+
data-search-with:
676+
* this attribute is optional. If it is not set, a search
677+
panel is not created provided to allow the users search
678+
within the class.
679+
* Adding ``data-search-with`` specifies the fields that can
680+
be used for searching.
681+
E.G. ``data-search-with="title,status,keyword"``
682+
* The search can be customized using the following syntax:
683+
684+
* Adding ``[]`` at then end of a field (``"status[]"``)
685+
will displays a dropdown for the "status" field
686+
listing all the values the user can access. E.G.::
687+
688+
<roundup-classhelper
689+
data-search-with="title,status[],keyword[]">
690+
<span tal:condition="context/is_edit_ok"
691+
tal:replace="structure
692+
python:db.issue.classhelp('id,title',
693+
property='superseder', pagesize=100)" />
694+
</roundup-classhelper>
695+
696+
will create a search pane with a text search for title
697+
and dropdowns for status and keyword.
698+
699+
* Adding a sort key after the ``[]`` allows you to
700+
select the order of the elements in the dropdown. For
701+
example ``keyword[]+name`` sorts the keyword
702+
dropdown in ascending order by name. While
703+
``keyword[]-name`` sorts the keyword dropdown in
704+
descending order by name. If the sort order is not
705+
specified, the default order for the class is used.
706+
707+
.. :
708+
remove in 2.5 release if /data/user/roles endpoint
709+
in rest.py is successful.
710+
711+
* Note that the ``roles`` field for the user class is
712+
special. If you have not modified ``interfaces.py``,
713+
roles can not be displayed as a dropdown. It will be
714+
displayed as a text search field instead.
715+
716+
<roundup-classhelper> styling
717+
-----------------------------
718+
719+
The roundup-classhelper component uses minimal styling so it
720+
can blend in with most trackers. If you want to change the
721+
styling, you can modify the classhelper.css file in the html
722+
directory. Even though roundup-classhelper is a web
723+
component, it doesn't use the shadow DOM. If you don't know
724+
what this means, it just means that it's easy to style.
725+
726+
There is on trick however. Getting the web component to load
727+
changes to the css file is a bit tricky. Basically the
728+
browser caches the old file and you have to resort to tricks
729+
to make it get a new copy of the file.
730+
731+
One way to do this is to open to the ``classhelper.css``
732+
file in your browser and force refresh it. To do this:
733+
734+
1. Open the home page for your Roundup issue tracker in a
735+
web browser.
736+
737+
2. In the address bar, append ``@@file/classhelper.css``
738+
to the end of your Roundup URL. For example, if your
739+
Roundup URL is ``https://example.com/tracker/``, the
740+
URL you should visit would be
741+
``https://example.com/tracker/@@file/classhelper.css``.
742+
743+
3. This will open the `classhelper.css` file in your browser.
744+
745+
4. Press ``Ctrl+Shift+R`` (on Windows and Linux) or
746+
``Cmd+Shift+R`` (on macOS). This triggers a hard
747+
refresh of the page, which forces the browser to
748+
reload the file and associated resources from the
749+
server.
750+
751+
This should resolve any issues caused by cached or outdated
752+
files. It is possible that you have to open devtools and set
753+
the disable cache option in the network panel in extreme
754+
cases.
755+
756+
Also during development, you might want to `set a very low
757+
cache time
758+
<customizing.html#changing-cache-control-headers>`_ for
759+
classhelper.css using something like::
760+
761+
Client.Cache_Control['classhelper.css'] = "public, max-age=10"
762+
763+
764+
Translations
765+
------------
766+
767+
To set up translations for the <roundup-classhelper>
768+
component, follow these steps.
769+
770+
1. Create a ``messages.pot`` file by running
771+
``roundup-gettext <tracker_home_directory>``. This
772+
creates ``locale/messages.pot`` in your tracker's home
773+
directory. It extracts all translatable strings from
774+
your tracker. We will use it as a base template for the
775+
new strings you want to translate.
776+
2. See if you already have a ``.po`` translation file for
777+
your language in the tracker's locale/ directory. If you
778+
don't, copy ``messages.pot`` to a .po file for the
779+
language you want to translate. For example German
780+
would be at ``de.po`` English would be at ``en.po``
781+
(for example if you want to change the ``apply`` button
782+
to say ``Do It``.
783+
784+
3. Edit the new .po file. After the header, add the
785+
translation entries for the <roundup-classhelper>
786+
component. For example `next` and `submit` are
787+
displayed in English when the rest of the interface is
788+
in German. Add::
789+
790+
msgid "submit"
791+
msgstr "gehen"
792+
793+
msgid "next"
794+
msgstr "nächste"
795+
796+
msgid "name"
797+
msgstr "name"
798+
799+
Note: the value for `msgid` is case sensitive. You can
800+
see the msgid for static strings by looking for
801+
``CLASSHELPER_TRANSLATION_KEYWORDS`` in classhelper.js.
802+
803+
4. Save the .po file.
804+
805+
5. Restart your Roundup instance.
806+
807+
This should display the missing translations, for more
808+
details refer to the `translation (i18n) section of the
809+
developers documentation
810+
<developers.html#extracting-translatable-messages>`_.
811+
812+
Troubleshooting
813+
---------------
814+
815+
The roundup-classhelper will fallback to using the classic
816+
classhelper if:
817+
818+
* the user doesn't have REST access
819+
* the browser doesn't support web components
820+
821+
It will display an alert modal dialog to the user before triggering
822+
the classic classhelper as a fallback. A detailed error will be
823+
printed to the browser console. The console is visible in devtools and
824+
can be opened by pressing the ``F12`` key.
825+
826+
You can disable the classhelper on a per URL basis by adding
827+
``#classhelper-wc-toggle`` to the end of the URL. This will prevent
828+
the web component from starting up.
829+
830+
Also you can set ``DISABLE_CLASSHELP = true`` at the top of
831+
classhelper.js to disable the classhelper without having to make any
832+
changes to your templates.
833+
517834
Configuring native-fts Full Text Search
518835
=======================================
519836

126 KB
Loading

doc/upgrading.txt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,44 @@ production workloads so we count on users to help us with this.
250250
.. _issue2551282: https://issues.roundup-tracker.org/issue2551282
251251
.. _issue2551115: https://issues.roundup-tracker.org/issue2551115
252252

253+
Add new classhelper to your templates (optional)
254+
------------------------------------------------
255+
256+
The classic classhelper invoked by the ``(list)`` link in your
257+
issue.item.html template can be greatly improved by wrapping the
258+
links with the new web-component based ``roundup-classhelper``.
259+
260+
The new classhelper:
261+
262+
* allows you to select items from multiple pages
263+
* is usable with a content security policy
264+
* is more easily styled
265+
266+
To deploy it, install the required files and wrap classhelp calls
267+
in the new ``<roundup-classhelper>`` component. For example,
268+
wrap::
269+
270+
<span tal:condition="context/is_edit_ok" tal:replace="structure
271+
python:db.user.classhelp('username,realname,address',
272+
property='nosy', width='600'" />
273+
274+
so it looks like::
275+
276+
<roundup-classhelper
277+
data-search-with="username,phone,roles[]">
278+
279+
<span tal:condition="context/is_edit_ok" tal:replace="structure
280+
python:db.user.classhelp('username,realname,address',
281+
property='nosy', width='600')" />
282+
283+
</roundup-classhelper>
284+
285+
to allow the user to search by: username, phone number and use a
286+
select/dropdown to search by role. Full details about the
287+
attributes and installation instructions can be found in the
288+
`classhelper documentation`_ in the admin guide.
289+
290+
253291
Disable performance improvement for wsgi mode (optional)
254292
--------------------------------------------------------
255293

@@ -2606,6 +2644,7 @@ See the `historical migration <upgrading-history.html>`_ document.
26062644
.. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html
26072645
.. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search
26082646
.. _Configuring Compression: admin_guide.html#configuring-compression
2647+
.. _classhelper documentation: admin_guide.html#classhelper-web-component
26092648
.. _Software Upgrade: admin_guide.html#software-upgrade
26102649
.. _new search permissions for query in 1.4.17:
26112650
upgrading-history.html#new-search-permissions-for-query-in-1-4-17

0 commit comments

Comments
 (0)