import functools from roundup.rest import calculate_etag def column_names(request): """column_names - get list of active column names from the first group spec :param: request - a request object from the template Fetch the column names (labelprop) that define the kanban board. All active column names are returned and sorted by the class orderprop. The sort direction (ascending or descending) is also maintained. If the group property is mandatory or has a preset value in the parent class (such as issue), you cannot remove the property value. In this situation, a "No value" column is not created. When a "No value" column is included, it appears first when sorted in ascending order. """ db = request.client.db column_prop = request.group[0][1] direction = request.group[0][0] column_class = db.getclass(column_prop) labelprop = column_class.labelprop() parent_class = db.getclass(request.classname) required_props = parent_class.get_required_props() default_prop_value = parent_class.properties[column_prop].get_default_value() # get column names (labelprop) from first group preserving sort # order direction sorted by orderprop. col_names = [column_class.getnode(nid)[labelprop] for nid in column_class.filter( None, None, sort=(direction, column_class.orderprop()))] if column_prop in required_props or default_prop_value: # the property is required or has a non-empty default value, # so we can't unset the property. Don't add an unset column. return col_names elif direction == "-": # unset items sort lower than any valid item. # We are descending sort, append column for them. col_names.append("") else: # insert column for unset item. col_names.insert(0,"") return col_names def etag(node): """etag - return etag for node :param: node - a hyperdb node Calculate the etag needed for REST submission to detect chnges in the underlying node when submitting a change. """ db_node = node._db.getclass(node._classname).getnode(node._nodeid) tag = calculate_etag(db_node, node._db.config.WEB_SECRET_KEY) return tag def is_open(col_name, request_form): """is_open - determine if the column should be displayed closed :param: col_name - the name of the column (from the class labelprop) :param: request_form - the form used to submit the request. The "@closed" param is used to determine if column should be displayed closed. This function returns an empty string if the column should be open or ``None`` if the column should be closed. An empty string indicates a boolean attribute and includes only the attribute name without any value. None forces the templating code to omit the attribute. """ if '@closed' not in request_form: return "" if col_name in get_closed_columns(request_form): return None return "" ## supporting functions @functools.cache def get_closed_columns(request_form): """parse the list of closed column names from the request form :param: a request.form object with a '@closed' element. Use a hashable parameter so it can be cached saving the parsing for every column in the kanban. """ closed = request_form['@closed'] if isinstance(closed, list): # @closed specified multiple times - MiniFeldStorage list value_list = [mfs.value for mfs in closed] # join segments which might be comma separated strings # and resplit as a single comma delimited string closed_list = ",".join(value_list).split(',') else: # @closed is single MiniFieldStorage with a comma separated list of # column names closed_list = closed.value.split(',') return closed_list def init(instance): instance.registerUtil('column_names', column_names) instance.registerUtil('etag', etag) instance.registerUtil('is_open', is_open)