Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aggregated list of analyses set to read-only #684

Merged
merged 6 commits into from
Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Changelog

**Changed**

- #684 Aggregated lists of analyses set to read-only mode
- #674 Dashboard with slightly better performance
- #621 AnalysesView code refactoring
- #668 AR Add: Debounce expensive XHR calls
Expand Down
8 changes: 7 additions & 1 deletion bika/lims/browser/aggregatedanalyses/aggregatedanalyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, context, request, **kwargs):

# each editable item needs it's own allow_edit
# which is a list of field names.
self.allow_edit = True
self.allow_edit = False

self.columns['AnalysisRequest'] = {
'title': _('Analysis Request'),
Expand Down Expand Up @@ -144,6 +144,12 @@ def __init__(self, context, request, **kwargs):
def getPOSTAction(self):
return 'aggregatedanalyses_workflow_action'

def is_analysis_edition_allowed(self, analysis_brain):
"""Overrides the function from the parent, cause we don't want in any
case the analyses displayed in aggregated list to be editable. The
correct way to introduce results is by using Worksheets!"""
return False

def isItemAllowed(self, obj):
"""
Checks if the passed in Analysis must be displayed in the list. If the
Expand Down
62 changes: 43 additions & 19 deletions bika/lims/browser/analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,6 @@ def folderitem(self, obj, item, index):
item['service_uid'] = obj.getServiceUID
item['Keyword'] = obj.getKeyword
item['Unit'] = format_supsub(obj.getUnit) if obj.getUnit else ''
item['Remarks'] = obj.getRemarks
item['retested'] = obj.getRetested
item['class']['retested'] = 'center'

Expand Down Expand Up @@ -584,6 +583,8 @@ def folderitem(self, obj, item, index):
self._folder_item_fieldicons(obj)
# Renders DryMatter if necessary
self._folder_item_dry_matter(obj, item)
# Renders remarks toggle button
self._folder_item_remarks(obj, item)

return item

Expand Down Expand Up @@ -1041,7 +1042,7 @@ def _folder_item_verify_icons(self, analysis_brain, item):
# display a warning icon
msg = t(_("Submitted and verified by the same user: {}"))
icon = get_image('warning.png', title=msg.format(submitter))
self._append_after_element(item, 'state_title', icon)
self._append_html_element(item, 'state_title', icon)

num_verifications = analysis_brain.getNumberOfRequiredVerifications
if num_verifications > 1:
Expand All @@ -1060,7 +1061,7 @@ def _folder_item_verify_icons(self, analysis_brain, item):
str(scale),
str(done),
str(num_verifications))
self._append_after_element(item, 'state_title', anchor)
self._append_html_element(item, 'state_title', anchor)

if analysis_brain.review_state != 'to_be_verified':
# The verification of analysis has already been done or first
Expand All @@ -1084,13 +1085,13 @@ def _folder_item_verify_icons(self, analysis_brain, item):
# Same user who submitted can verify
title = t(_("Can verify, but submitted by current user"))
html = get_image('warning.png', title=title)
self._append_after_element(item, 'state_title', html)
self._append_html_element(item, 'state_title', html)
return

# User who submitted cannot verify
title = t(_("Cannot verify, submitted by current user"))
html = get_image('submitted-by-current-user.png', title=title)
self._append_after_element(item, 'state_title', html)
self._append_html_element(item, 'state_title', html)
return

# This user verified this analysis before
Expand All @@ -1099,21 +1100,21 @@ def _folder_item_verify_icons(self, analysis_brain, item):
# Multi verification by same user is not allowed
title = t(_("Cannot verify, was verified by current user"))
html = get_image('submitted-by-current-user.png', title=title)
self._append_after_element(item, 'state_title', html)
self._append_html_element(item, 'state_title', html)
return

# Multi-verification by same user, but non-consecutively, is allowed
if analysis_brain.getLastVerificator != username:
# Current user was not the last user to verify
title = t(_("Can verify, but was already verified by current user"))
html = get_image('warning.png', title=title)
self._append_after_element(item, 'state_title', html)
self._append_html_element(item, 'state_title', html)
return

# Last user who verified is the same as current user
title = t(_("Cannot verify, last verified by current user"))
html = get_image('submitted-by-current-user.png', title=title)
self._append_after_element(item, 'state_title', html)
self._append_html_element(item, 'state_title', html)
return

def _folder_item_assigned_worksheet(self, analysis_brain, item):
Expand Down Expand Up @@ -1142,7 +1143,7 @@ def _folder_item_assigned_worksheet(self, analysis_brain, item):
mapping={'worksheet_id': safe_unicode(worksheet.id)}))
img = get_image('worksheet.png', title=title)
anchor = get_link(worksheet.absolute_url(), img)
self._append_after_element(item, 'state_title', anchor)
self._append_html_element(item, 'state_title', anchor)

def _folder_item_reflex_icons(self, analysis_brain, item):
"""Adds an icon to the item dictionary if the analysis has been
Expand All @@ -1156,7 +1157,7 @@ def _folder_item_reflex_icons(self, analysis_brain, item):
return
img = get_image('reflexrule.png',
title=t(_('It comes form a reflex rule')))
self._append_after_element(item, 'Service', img)
self._append_html_element(item, 'Service', img)

def _folder_item_report_visibility(self, analysis_brain, item):
"""Set if the hidden field can be edited (enabled/disabled)
Expand Down Expand Up @@ -1216,19 +1217,42 @@ def _folder_item_dry_matter(self, analysis_brain, item):
item['after']['ResultDM'] = "<em class='discreet'>%</em>"
item['ResultDM'] = ''

def _append_after_element(self, item, element, html, glue="&nbsp;"):
"""Appends html value after element in the item dict
def _folder_item_remarks(self, analysis_brain, item):
"""Renders the Remarks field for the passed in analysis and if the
edition of the analysis is permitted, adds a button to toggle the
visibility of remarks field

:param analysis_brain: Brain that represents an analysis
:param item: analysis' dictionary counterpart that represents a row"""
item['Remarks'] = analysis_brain.getRemarks

if not self.is_analysis_edition_allowed(analysis_brain):
# Edition not allowed, do not add the remarks toggle button, the
# remarks field will be displayed without the option to hide it
return

# Analysis can be edited. Add the remarks toggle button
title = t(_("Add Remark"))
img = get_image('comment_ico.png', title=title)
kwargs = {'class': "add-remark"}
anchor = get_link('#', img, **kwargs)
self._append_html_element(item, 'Service', anchor, after=False)

def _append_html_element(self, item, element, html, glue="&nbsp;", after=True):
"""Appends an html value after or before the element in the item dict

:param item: dictionary that represents an analysis row
:element: id of the element the html must be added thereafter
:html: element to append
:glue: glue to use for appending"""
item['after'] = item.get('after', {})
original = item['after'].get(element, '')
:param element: id of the element the html must be added thereafter
:param html: element to append
:param glue: glue to use for appending
:param after: if the html content must be added after or before"""
position = after and 'after' or 'before'
item[position] = item.get(position, {})
original = item[position].get(element, '')
if not original:
item['after'][element] = html
item[position][element] = html
return
item['after'][element] = glue.join([original, html])
item[position][element] = glue.join([original, html])


class QCAnalysesView(AnalysesView):
Expand Down
11 changes: 2 additions & 9 deletions bika/lims/browser/js/bika.lims.worksheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,19 +259,12 @@ function WorksheetManageResultsView() {
}

function loadRemarksEventHandlers() {
// Add a baloon icon before Analyses' name when you'd add a remark. If you click on, it'll display remarks textarea.
var txt1 = '<a href="#" class="add-remark"><img src="'+window.portal_url+'/++resource++bika.lims.images/comment_ico.png" title="'+_('Add Remark')+'")"></a>';
var pointer = $(".listing_remarks:contains('')").closest('tr').prev().find('td.service_title span.before');
$(pointer).append(txt1);

// On click, toggle the remarks field
$("a.add-remark").click(function(e){
e.preventDefault();
var rmks = $(this).closest('tr').next('tr').find('td.remarks');
if (rmks.length > 0) {
rmks.toggle();
}
$(rmks).find('div.remarks-placeholder').toggle();
});
$("a.add-remark").click();
}

function loadDetectionLimitsEventHandlers() {
Expand Down
6 changes: 4 additions & 2 deletions bika/lims/browser/templates/bika_listing_table_items.pt
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,7 @@
isanalysis python:'obj' in item and item['obj'].meta_type in ['Analysis', 'DuplicateAnalysis', 'ReferenceAnalysis'];
hasremarks python:True if item.get('Remarks','') else False;
remarksedit python: remarksenabled and 'Remarks' in item.get('allow_edit',[]);
isforaggregatedlist python: True if review_state_id=='to_be_verified' else False;
showremarks python:isanalysis and (hasremarks or remarksedit or isforaggregatedlist)">
showremarks python:isanalysis and (hasremarks or remarksedit)">

<tr tal:condition="showremarks"
tal:define="keyword python:item.has_key('Keyword') and item['Keyword'] or '';"
Expand All @@ -467,6 +466,8 @@
<td tal:attributes="colspan python:int(nr_cols)-1;
class string:${item/state_class} result remarks"
style="padding-right:10px;padding-bottom:5px;">
<div class="remarks-placeholder"
tal:attributes="style python:'' if hasremarks else 'display:none'">
<span i18n:translate="">Remarks:</span>&nbsp;
<textarea style="width:100%;display:block;"
autocomplete="off"
Expand All @@ -485,6 +486,7 @@
tal:attributes="class python:'listing_remarks';
name string:Remarks.${item/uid}:records;"
tal:content="python:item.get('Remarks', '') if hasremarks else 'No Remarks.'"/>
</div>
</td>
</tr>
</tal:remarks_condition>
Expand Down
2 changes: 1 addition & 1 deletion bika/lims/skins/bika/bika_listing.css.dtml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ table.bika-listing-table {
}

.bika-listing-table .listing_remarks {
color:#444;
width:99%;
border:1px solid #ababab;
margin:2px 0px;
}

Expand Down