def _get_element(self, **kwargs) -> htmler.Element: cont = htmler.TagLessElement() cont.append_child(htmler.H2(lang.t('theming@installed_themes'))) table = cont.append_child( htmler.Table(css='table table-striped table-bordered table-hover')) t_head = table.append_child(htmler.Tr()) t_head.append_child(htmler.Th(lang.t('theming@name'))) t_head.append_child(htmler.Th(lang.t('theming@version'))) t_head.append_child(htmler.Th(lang.t('theming@author'))) t_head.append_child(htmler.Th(lang.t('theming@url'))) t_head.append_child(htmler.Th(lang.t('theming@actions'))) t_body = table.append_child(htmler.Tbody()) for theme in _api.get_all().values(): tr = t_body.append_child(htmler.Tr()) tr.append_child(htmler.Td(theme.name)) tr.append_child(htmler.Td(theme.version)) tr.append_child( htmler.Td( htmler.A(theme.author['name'], href=theme.author['url'], target='_blank'))) tr.append_child( htmler.Td(htmler.A(theme.url, href=theme.url, target='_blank'))) actions = htmler.TagLessElement(child_sep=' ') if _api.get().name != theme.name: # 'Switch' button btn_switch = htmler.A( title=lang.t('theming@switch_to_this_theme'), href='#', role='button', css='btn btn-default btn-light btn-sm button-switch', data_package_name=theme.package_name) btn_switch.append_child(htmler.I(css='fa fas fa-power-off')) actions.append_child(btn_switch) # 'Uninstall' button btn_delete = htmler.A( title=lang.t('theming@uninstall_theme'), href='#', role='button', css='btn btn-danger btn-sm button-uninstall', data_package_name=theme.package_name) btn_delete.append_child(htmler.I(css='fa fas fa-trash')) actions.append_child(btn_delete) tr.append_child(htmler.Td(actions)) return cont
def render(self) -> str: # 'Create' toolbar button if self._model_class.odm_ui_creation_allowed( ) and odm_auth.check_model_permissions(self._model, PERM_CREATE): create_form_url = router.rule_url( self._m_form_rule, { 'model': self._model, 'eid': 0, '__redirect': router.current_url(), }) title = lang.t('odm_ui@create') btn = htmler.A(href=create_form_url, css='btn btn-default btn-light add-button', title=title) btn.append_child(htmler.I(css='fa fas fa-fw fa-plus')) self._widget.toolbar.append_child(btn) self._widget.toolbar.append_child(htmler.Span(' ')) # 'Delete' toolbar button if self._model_class.odm_ui_deletion_allowed(): delete_form_url = router.rule_url(self._d_form_rule, {'model': self._model}) title = lang.t('odm_ui@delete_selected') btn = htmler.A( href=delete_form_url, css='hidden btn btn-danger mass-action-button sr-only', title=title) btn.append_child(htmler.I(css='fa fas fa-fw fa-remove fa-times')) self._widget.toolbar.append_child(btn) self._widget.toolbar.append_child(htmler.Span(' ')) # Additional toolbar buttons for btn_data in self._model_class.odm_ui_browser_mass_action_buttons(): ep = btn_data.get('ep') url = router.rule_url(ep) if ep else '#' css = 'btn btn-{} mass-action-button'.format( btn_data.get('color', 'default btn-light')) icon = 'fa fas fa-fw fa-' + btn_data.get('icon', 'question') button = htmler.A(href=url, css=css, title=btn_data.get('title')) if icon: button.append_child(htmler.I(css=icon)) self._widget.toolbar.append_child(button) self._widget.toolbar.append_child(htmler.Span(' ')) frm = htmler.Form(self._widget.render(), action='#', method='post', css='table-responsive odm-ui-browser') return frm.render()
def __init__(self, uid: str, **kwargs): rows_url = http_api.url('auth_admin@browser_rows', {'e_type': 'user'}) data_fields = [ ('login', 'auth_admin@login', True), ('first_last_name', 'auth_admin@full_name', True), ('roles', 'auth_admin@roles', False), ('status', 'auth_admin@status', True), ('is_public', 'auth_admin@is_public', True), ('is_online', 'auth_admin@is_online', True), ('created', 'auth_admin@created', True), ('last_activity', 'auth_admin@last_activity', True), ('_actions', 'auth_admin@actions', False), ] super().__init__(uid, rows_url=rows_url, data_fields=data_fields, checkbox=False, **kwargs) add_btn_url = router.rule_url( 'auth_admin@form_user_modify', { 'uid': '0', '__redirect': router.rule_url('auth_admin@browse_users') }) add_btn = htmler.A(href=add_btn_url, css='btn btn-default btn-light') add_btn.append_child(htmler.I(css='fa fa-plus')) self.toolbar.append_child(add_btn) self._css += ' widget-auth-admin-browser'
def __init__(self, uid: str, **kwargs): rows_url = http_api.url('auth_admin@browser_rows', {'e_type': 'role'}) data_fields = [ ('name', 'auth_admin@name', True), ('description', 'auth_admin@description', False), ('permissions', 'auth_admin@permissions', False), ('_actions', 'auth_admin@actions', False), ] super().__init__(uid, rows_url=rows_url, data_fields=data_fields, checkbox=False, **kwargs) add_btn_url = router.rule_url( 'auth_admin@form_role_modify', { 'uid': '0', '__redirect': router.rule_url('auth_admin@browse_roles') }) add_btn = htmler.A(href=add_btn_url, css='btn btn-default btn-light') add_btn.append_child(htmler.I(css='fa fa-plus')) self.toolbar.append_child(add_btn) self._css += ' widget-auth-admin-browser'
def _get_row(self, widgets: List[Abstract], row_num: int = 0, add_css: str = '') -> htmler.Tr: """Build single row """ slot_tr = htmler.Tr(css='slot ' + add_css) slot_tr.append_child( htmler.Td('[{}]'.format(row_num + 1), css='order-col')) # Widgets for w in widgets: w.name = self._get_row_widget_name(w) w.form_group = False w_td = htmler.Td(css='widget-col widget-col-' + w.uid) w_td.append_child(w.renderable()) slot_tr.append_child(w_td) # Actions actions_td = htmler.Td(css='actions-col') slot_tr.append_child(actions_td) # 'Remove' button if self._enabled: remove_btn = htmler.A( href='#', css='button-remove-slot btn btn-sm btn-danger') remove_btn.append_child( htmler.I(css='fa fas fa-icon fa-remove fa-times')) actions_td.append_child(remove_btn) return slot_tr
def _get_element(self, **kwargs) -> htmler.Element: """Hook """ self._data['header-hidden'] = self._is_header_hidden if self._max_rows: self._data['max-rows'] = self._max_rows base_row = self._get_widgets() table = htmler.Table(css='content-table') # Header thead = htmler.Thead(css='hidden sr-only slots-header') table.append_child(thead) row = htmler.Tr() thead.append_child(row) row.append_child(htmler.Th(' ', css='order-col')) for w in self._get_widgets(): row.append_child(htmler.Th(w.label, css='widget-col')) row.append_child(htmler.Th(css='actions-col')) # Table body tbody = htmler.Tbody(css='slots') table.append_child(tbody) # Base slot tbody.append_child( self._get_row(base_row, add_css='base hidden sr-only')) # Rows for em in self._get_rows(): tbody.append_child(em) # Footer tfoot = htmler.Tfoot() tfoot_tr = htmler.Tr() tfoot_td = htmler.Td(colspan=len(self._get_widgets()) + 2) tfoot_tr.append_child(tfoot_td) tfoot.append_child(tfoot_tr) table.append_child(tfoot) if self._enabled: add_btn = htmler.A( href='#', css='button-add-slot btn btn-default btn-light btn-sm') if self._add_btn_icon: add_btn.append_child(htmler.I(css=self._add_btn_icon)) if self._add_btn_label: add_btn.append_child(self._add_btn_label) tfoot_td.append_child(add_btn) return table
def _render_sidebar(sidebar: admin.SideBar) -> htmler.Aside: """Render admin's sidebar """ aside = htmler.Aside(css='main-sidebar') sidebar_section_em = htmler.Section(css='sidebar') aside.append_child(sidebar_section_em) root_menu_ul = htmler.Ul(css='sidebar-menu') sidebar_section_em.append_child(root_menu_ul) sections, menus = sidebar.items # Do actual rendering for section in sections: li = htmler.Li(lang.t(section['title']), css='header', data_section_weight=section['weight']) root_menu_ul.append_child(li) # Building top level menu item for menu in menus[section['sid']]: # Link a = htmler.A( href=router.url(menu['path'], lang=lang.get_current())) # Icon if menu['icon']: a.append_child(htmler.I(css=menu['icon'])) # Title a.append_child(htmler.Span(lang.t(menu['title']))) # Label if menu['label']: label_class = 'label pull-right label-' + menu[ 'label_class'] a.append_child( htmler.Span(lang.t(menu['label']), css=label_class)) # List element li = htmler.Li(data_menu_weight=menu['weight']) # Active state if menu['active']: li.set_attr('css', 'active') li.append_child(a) root_menu_ul.append_child(li) return aside
def _get_element(self, **kwargs) -> htmler.Element: """Render the widget. :param **kwargs: """ self._html_em.set_attr('uid', self._uid) if isinstance(self._color, list): self._html_em.set_attr( 'css', 'btn ' + ' '.join('btn-' + c for c in self._color)) else: self._html_em.set_attr('css', 'btn btn-' + self._color) self._html_em.append_text(self.get_val()) if self._icon and not self._html_em.children: self._html_em.append_child(htmler.I(css=self._icon)) for k, v in self._data.items(): self._html_em.set_attr('data_' + k, v) return self._html_em
def get_rows(self, args: routing.ControllerArgs) -> dict: """Get browser rows. """ # Instantiate finder finder = odm.find(self._model) # Check if the user can modify/delete any entity if not odm_auth.check_model_permissions(self._model, [PERM_MODIFY, PERM_DELETE]) and \ odm_auth.check_model_permissions(self._model, [PERM_MODIFY_OWN, PERM_DELETE_OWN]): # Show only entities owned by user finder.mock.has_field('author') and finder.eq( 'author', self._current_user) # Let model to finish finder setup _api.dispense_entity(self._model).odm_ui_browser_setup_finder( finder, args) # Sort sort_order = odm.I_DESC if args.get( 'order', self.default_sort_order) in (-1, 'desc') else odm.I_ASC sort_field = args.get('sort') if sort_field and finder.mock.has_field(sort_field): finder.sort([(sort_field, sort_order)]) elif self.default_sort_field: finder.sort([(self.default_sort_field, sort_order)]) # Get root elements first finder.add_sort('_parent', pos=0) # Prepare result r = {'total': finder.count(), 'rows': []} # Build table rows cursor = finder.skip(args.get('offset', 0)).get(args.get('limit', 0)) for entity in cursor: row = entity.odm_ui_browser_row() events.fire('odm_ui@browser_row.{}'.format(self._model), entity=entity, row=row) if not row: continue # Build row's cells fields_data = { '__id': str(entity.id), '__parent': str(entity.parent.id) if entity.parent else None, } if not isinstance(row, dict): raise TypeError( '{}.odm_ui_browser_row() must return dict, got {}'.format( entity.__class__.__name__, type(row))) for df in self.data_fields: fields_data[df[0]] = row.get(df[0], ' ') # Action buttons if self._model_class.odm_ui_entity_actions_enabled() and \ (self._model_class.odm_ui_modification_allowed() or self._model_class.odm_ui_deletion_allowed()): actions = htmler.TagLessElement(child_sep=' ') for btn_data in entity.odm_ui_browser_entity_actions(self): color = 'btn btn-sm btn-' + btn_data.get( 'color', 'default btn-light') title = btn_data.get('title', '') url = btn_data.get('url') if not url: rule = btn_data.get('rule') url = router.rule_url( rule, {'ids': str(entity.id)}) if rule else '#' btn = htmler.A(href=url, css=color + ' ' + btn_data.get('css', ''), title=title, role='button') if btn_data.get('disabled'): btn.set_attr('aria_disabled', 'true') btn.add_css('disabled') btn.append_child( htmler.I(css=btn_data.get('icon', 'fa fas fa-fw fa-question'))) actions.append_child(btn) fields_data['entity-actions'] = actions.render() r['rows'].append(fields_data) return r