diff --git a/CHANGES.rst b/CHANGES.rst index 416be0dd1c..6ed296e842 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -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 diff --git a/bika/lims/browser/aggregatedanalyses/aggregatedanalyses.py b/bika/lims/browser/aggregatedanalyses/aggregatedanalyses.py index 55418505c7..772fad046f 100644 --- a/bika/lims/browser/aggregatedanalyses/aggregatedanalyses.py +++ b/bika/lims/browser/aggregatedanalyses/aggregatedanalyses.py @@ -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'), @@ -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 diff --git a/bika/lims/browser/analyses.py b/bika/lims/browser/analyses.py index 41304ea37d..0641d4781e 100644 --- a/bika/lims/browser/analyses.py +++ b/bika/lims/browser/analyses.py @@ -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' @@ -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 @@ -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: @@ -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 @@ -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 @@ -1099,7 +1100,7 @@ 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 @@ -1107,13 +1108,13 @@ def _folder_item_verify_icons(self, analysis_brain, item): # 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): @@ -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 @@ -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) @@ -1216,19 +1217,42 @@ def _folder_item_dry_matter(self, analysis_brain, item): item['after']['ResultDM'] = "%" item['ResultDM'] = '' - def _append_after_element(self, item, element, html, glue=" "): - """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=" ", 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): diff --git a/bika/lims/browser/js/bika.lims.worksheet.js b/bika/lims/browser/js/bika.lims.worksheet.js index f67bb9b9ca..d2fcd552e3 100644 --- a/bika/lims/browser/js/bika.lims.worksheet.js +++ b/bika/lims/browser/js/bika.lims.worksheet.js @@ -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 = ''; - 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() { diff --git a/bika/lims/browser/templates/bika_listing_table_items.pt b/bika/lims/browser/templates/bika_listing_table_items.pt index 1ce41714f8..aada8e4d46 100644 --- a/bika/lims/browser/templates/bika_listing_table_items.pt +++ b/bika/lims/browser/templates/bika_listing_table_items.pt @@ -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)"> +
Remarks: