def task(obj): """Render task layout""" return Container( Row( Column6( Panel( _('General'), TableDescription( 'description', 'status', 'user', 'started_at', { 'field': 'execution_time', 'renderer': lambda value, **options: str( timezone.timedelta(seconds=value)), }, 'result=class:pre', ))), Column6( Panel( _('Process'), TableDescription( { 'field': 'progress', 'value': ProgressBar('progress'), }, { 'field': 'progress_output', 'renderer': lambda value, **options: '<br/>'.join(value), })))))
def account_overview(obj): """Create layout for user profile""" token, created = Token.objects.get_or_create(user=obj) return Container( Row( Column2( Panel( _('Avatar'), Img(src="{}{}".format( settings.MEDIA_URL if obj.avatar else settings. STATIC_URL, obj.avatar if obj.avatar else 'img/avatar.png')), collapse=True, ), ), Column10( Column6( Panel( _('Account information'), DescriptionList( 'email', 'first_name', 'last_name', ), )), Column6( Panel( _('Settings'), DescriptionList( { 'label': _('Language'), 'value': _(obj.get_language_display()), }, 'timezone', { 'label': _('API Token'), 'value': Component( Html(token.key), OnclickLink( _('Reset'), model_url='dialog-edit', model_code='reset-api-token', dialog=True, dialog_reload_layout=True, ), ), }, ), ))), ))
def auditlog(obj): """Create auditlog history layout""" content_type = ContentType.objects.get_for_model(obj) return [ Column12( Panel( _('{action} on {date} by {user}').format( action=auditlog.get_action_display(), date=datetime_value_renderer(auditlog.created_at), user=auditlog.user if auditlog.user else 'System'), Table( [[field, *changes] for field, changes in auditlog.changes.items()], { 'label': _('Field'), 'width': '10%', }, { 'label': _('Old value'), 'width': '45%', }, { 'label': _('New value'), 'width': '45%', }, ))) for auditlog in AuditLogEntry.objects.filter(content_type=content_type, object_id=obj.id).order_by('-created_at') ]
def general_layout(obj): return Layout( Column12( Panel( 'info', DescriptionList(*[ f.name for f in models_config.get_config( obj).get_fields() ]))))
def auth_group(obj): """Create layout for permission group""" from trionyx.trionyx.views import create_permission_jstree return [ Column12(Panel(_('Info'), TableDescription('name'))), Column12( Panel( _('Permissions'), HtmlTemplate( template_name='trionyx/base/permissions.html', context={ 'permission_jstree': create_permission_jstree(obj.permissions.all(), disabled=True), }, css_files=['plugins/jstree/themes/default/style.css'], js_files=['plugins/jstree/jstree.min.js'], ), ), ) ]
def trionyx_log(obj): """Create log layout""" return Container( Row( Column6( Panel( _('Log info'), TableDescription( { 'label': _('Level'), 'value': render_level(obj) }, 'message', { 'label': _('Location'), 'value': '{}:{}'.format(obj.file_path, obj.file_line) }, 'last_event', 'log_count', )), Panel( _('Backtrace'), Html( '<pre>{}</pre>'.format(obj.traceback ) if obj.traceback else '<div class="alert alert-info" style="margin: 0;border-radius: 0;">No traceback</div>' ))), Column6( Panel( _('Last log entries'), Table(obj.entries.select_related('user').order_by('-id') [:25], 'log_time', 'user', 'path', 'user_agent', object=LogEntry())))))
def order_general(obj): """Account general tab""" return Container( Row( Column9( Panel( _('General'), DescriptionList( 'name', 'type', 'debtor_id', 'website', 'phone', 'email', { 'label': _('Shipping address'), 'value': str(obj.shipping_address), } if obj.shipping_address else None, { 'label': _('Billing address'), 'value': str(obj.billing_address), } if obj.billing_address else None, )), Panel(_('Info'), DescriptionList( 'assigned_user', 'description', )), Panel( Component( ButtonGroup( Button( '<i class="fa fa-plus"></i>', model_url='dialog-create', model_params={ 'account': obj.id, }, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat btn-success btn-xs', object=Contact(), ), css_class='btn-group pull-right', ), Html(_('Contacts')), ), Table( obj.contacts.all(), 'title', 'first_name', 'last_name', 'email', 'phone', 'mobile_phone', { 'field': 'address', 'renderer': lambda value, **options: str(value) if value else '', }, 'description', 'assigned_user=width:100px', { 'label': _('Options'), 'width': '80px', 'value': ButtonGroup( Button( label='<i class="fa fa-edit"></i>', model_url='dialog-edit', model_params={ 'account': obj.id, }, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat bg-theme btn-sm'), Button( label='<i class="fa fa-times"></i>', model_url='dialog-delete', model_params={ 'account': obj.id, }, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat btn-danger btn-sm' ), ) }, ))), Column3(*[ Panel( Component( ButtonGroup( Button( label='<i class="fa fa-edit"></i>', model_url='dialog-edit', model_params={ 'account': obj.id, }, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat bg-theme btn-xs', object=address, ), Button( label='<i class="fa fa-times"></i>', model_url='dialog-delete', model_params={ 'account': obj.id, }, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat btn-danger btn-xs', object=address, ), css_class='btn-group pull-right', ), Html(_('Address'))), DescriptionList( 'street', 'postcode', 'city', 'state', 'country', { 'label': _('Default shipping'), 'value': True } if address == obj.shipping_address else None, { 'label': _('Default billing'), 'value': True } if address == obj.billing_address else None, object=address, ), object=address, ) for address in obj.addresses.all() ]), ), )
def trionyx_user(obj): """Create layout for admin user""" from trionyx.trionyx.views import create_permission_jstree from django.contrib.auth.models import Permission permissions = [] if obj.is_superuser: permissions = Permission.objects.all() else: permissions.extend(list(obj.user_permissions.all())) for group in obj.groups.all(): permissions.extend(list(group.permissions.all())) token, created = Token.objects.get_or_create(user=obj) return Container( Row( Column2( Panel( _('Avatar'), Img(src="{}{}".format( settings.MEDIA_URL if obj.avatar else settings. STATIC_URL, obj.avatar if obj.avatar else 'img/avatar.png')), collapse=True, ), ), Column10( Panel( _('Account information'), DescriptionList( 'email', 'first_name', 'last_name', 'created_at', 'last_login', 'last_online', 'is_active', 'is_superuser', 'groups', { 'label': _('API Token'), 'value': Component( Html(token.key), OnclickLink( _('Reset'), model_url='dialog-edit', model_code='reset-api-token', dialog=True, dialog_reload_layout=True, ), ), }, ), ), Panel( _('All active permissions'), HtmlTemplate( template_name='trionyx/base/permissions.html', context={ 'permission_jstree': create_permission_jstree(permissions, disabled=True), }, css_files=['plugins/jstree/themes/default/style.css'], js_files=['plugins/jstree/jstree.min.js'], ), id='all-active-permissions-panel', ), ), ), )
def project_overview(obj): return Container( Row( Column8( Panel( 'Backlog', Table(obj.items.order_by( '-priority', 'item_type', 'code' ), { 'field': 'item_type', 'renderer': lambda value, **options: Item.get_type_icon(value) }, { 'field': 'priority', 'renderer': lambda value, **options: Item.get_priority_icon(value) }, { 'field': 'code', 'value': OnclickLink( Field('code'), sidebar=True, ) }, { 'field': 'name', 'class': 'width-100' }, { 'field': 'estimate', 'value': Badge(Field( 'estimate', renderer=lambda value, data_object: f"{value}h" if value else ' '), css_class="badge estimate-badge"), 'class': 'text-right', }, header=False), Button('Add item', model_url='dialog-create', model_params={'project': obj.id}, dialog=True, dialog_reload_tab='general', css_class='btn btn-flat bg-theme btn-block', object=Item()), )), Column4( Panel( 'Project details', TableDescription( { 'field': 'status', 'renderer': lambda value, data_object, **options: render_status(data_object), }, 'created_at', 'project_type', { 'label': 'deadline', 'value': obj.deadline if obj.deadline else 'n/a', 'format': '<strong>{}</strong>' }, { 'field': 'hour_rate', 'value': price_value_renderer( app_settings.HOURLY_RATE if obj.project_type == Project.TYPE_FIXED else obj.hourly_rate) }, { 'field': 'total_items_estimate', 'label': 'Total hours' } if obj.project_type == Project.TYPE_HOURLY_BASED else { 'field': 'Calculated hours', 'value': float(obj.fixed_priceif if obj.fixed_price else 0) / float(obj.hourly_rate), }, # 'total_worked' if obj.project_type == Project.TYPE_HOURLY_BASED else None, # 'total_billed' if obj.project_type == Project.TYPE_HOURLY_BASED else None, { 'label': 'Calculated price', 'value': price_value_renderer( float(obj.total_billed) * float(obj.hourly_rate)), 'format': '<strong>{}</strong>' } if obj.project_type == Project.TYPE_HOURLY_BASED else { 'field': 'fixed_price', 'format': '<strong>{}</strong>' }, )), Panel( 'Logged hours', TableDescription( 'total_worked', 'total_billed', ), ), Panel('Description', Html(obj.description), collapse=False))))
def item_sidebar(request, obj): content = Component( Panel( 'Description', Html(obj.description), ), Panel( 'Info', TableDescription( { 'field': 'item_type', 'renderer': lambda value, data_object, **options: "{} {}".format( data_object.get_type_icon(data_object.item_type), data_object.get_item_type_display(), ) }, { 'field': 'priority', 'renderer': lambda value, data_object, **options: "{} {}".format( data_object.get_priority_icon(data_object.priority), data_object.get_priority_display(), ) }, 'created_at', 'updated_at', ), ), Panel( 'Comments', Button('Add comment', model_url='dialog-create', model_params={'item': obj.id}, dialog=True, dialog_reload_sidebar=True, css_class='btn btn-flat bg-theme btn-block', object=Comment()), *[ Component( HtmlTemplate('trionyx_projects/project_comment.html', object=comment, lock_object=True), ) for comment in obj.comments.order_by('-created_at') ]), Panel( 'Worklogs', Button('Add worklog', model_url='dialog-create', model_params={'item': obj.id}, dialog=True, dialog_reload_sidebar=True, css_class='btn btn-flat bg-theme btn-block', object=WorkLog()), Table(obj.worklogs.order_by('-date', 'id'), 'date', { 'field': 'created_by', 'label': 'User', }, 'description', { 'field': 'worked', 'label': 'W', }, { 'field': 'billed', 'label': 'B', }, { 'label': 'Options', 'width': '60px', 'value': ButtonGroup( Button( '<i class="fa fa-edit"></i>', css_class='btn bg-theme btn-xs', dialog=True, model_url='dialog-edit', dialog_reload_sidebar=True, should_render=lambda comp: comp.object.created_by == get_current_request().user or get_current_request( ).user.is_superuser, ), Button( '<i class="fa fa-times"></i>', css_class='btn bg-red btn-xs', dialog=True, model_url='dialog-delete', dialog_reload_sidebar=True, should_render=lambda comp: comp.object.created_by == get_current_request().user or get_current_request( ).user.is_superuser, ), ) }), ), ) content.set_object(obj) return { 'title': f"{obj.code} - {obj.name}", 'fixed_content': TableDescription( { 'field': 'estimate', 'renderer': lambda value, **options: f"{value}h" if value else '0h', 'class': 'text-right' }, { 'field': 'total_worked', 'label': 'Logged', 'renderer': lambda value, **options: f"{value}h" if value else '0h', 'class': 'text-right' }, { 'field': 'total_billed', 'label': 'Billed', 'renderer': lambda value, **options: f"{value}h" if value else '0h', 'class': 'text-right' }, css_class='no-margin', object=obj, ).render({}, request), 'content': content.render({}, request), 'actions': [{ 'label': 'Edit', 'url': model_url(obj, 'dialog-edit'), 'dialog': True, 'dialog_options': { 'callback': """ if (data.success) { trionyx_reload_tab('general'); reloadSidebar(); dialog.close(); }; """ }, }, { 'label': 'Delete', 'class': 'text-danger', 'url': model_url(obj, 'dialog-delete'), 'dialog': True, 'dialog_options': { 'callback': """ if (data.success) { trionyx_reload_tab('general'); closeSidebar(); dialog.close(); }; """ }, 'divider': True, }] }