Esempio n. 1
0
    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
Esempio n. 2
0
    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()
Esempio n. 3
0
    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'
Esempio n. 4
0
    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'
Esempio n. 5
0
    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
Esempio n. 6
0
    def __init__(self, uid: str, **kwargs):
        """Init.
        """
        super().__init__(uid, **kwargs)

        self._html_em = htmler.A(href=kwargs.get('href', '#'))

        if self._dismiss:
            self._html_em.set_attr('data_dismiss', self._dismiss)
Esempio n. 7
0
    def _render_item(self, entity: _model.Menu) -> Optional[htmler.Li]:
        if not entity.enabled:
            return

        root = htmler.Li(css='nav-item {}'.format('active' if self._is_item_active(entity) else ''))
        a = root.append_child(htmler.A(entity.title, href=self._item_url(entity), css='nav-link'))

        if entity.new_window:
            a.set_attr('target', '_blank')

        return root
Esempio n. 8
0
    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
Esempio n. 9
0
    def _render_dropdown(self, entity: _model.Menu) -> Optional[htmler.Li]:
        if not entity.enabled:
            return

        # Dropdown's root
        root = htmler.Li(css='nav-item dropdown')

        # Toggler
        root.append_child(htmler.A(entity.title, id=entity.ref, href='#', css='nav-link dropdown-toggle', role='button',
                                   data_toggle='dropdown', aria_haspopup='true', aria_expanded='false'))

        # Dropdown
        dropdown = root.append_child(htmler.Div(css='dropdown-menu', aria_labelledby=entity.ref))
        for e in entity.children:  # type: _model.Menu
            if e.enabled:
                a_css = 'dropdown-item {}'.format('active' if self._is_item_active(e) else '')
                a = dropdown.append_child(htmler.A(e.title, href=self._item_url(e), css=a_css))

                if e.new_window:
                    a.set_attr('target', '_blank')

        return root
Esempio n. 10
0
    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
Esempio n. 11
0
    def odm_ui_browser_row(self) -> dict:
        """Hook
        """
        r = {}

        # Title
        if self.has_field('title'):
            r['title'] = (str(htmler.A(self.title, href=self.url)) if self.url else self.title)

        # Status
        if self.has_field('status'):
            status = self.status
            status_str = self.t('content_status_{}_{}'.format(self.model, status))
            label_css = badge_css = 'primary'
            if status == CONTENT_STATUS_WAITING:
                label_css = badge_css = 'warning'
            elif status == CONTENT_STATUS_UNPUBLISHED:
                label_css = 'default'
                badge_css = 'secondary'
            status = str(htmler.Span(status_str, css='label label-{} badge badge-{}'.format(label_css, badge_css)))
            r['status'] = status

        # Images
        if self.has_field('images'):
            label_css = 'default' if not len(self.images) else 'primary'
            badge_css = 'secondary' if not len(self.images) else 'primary'
            images_count = '<span class="label label-{} badge badge-{}">{}</span>'. \
                format(label_css, badge_css, len(self.images))
            r['images'] = images_count

        # Author
        if self.has_field('author') and self.odm_auth_check_model_permissions(self.model, PERM_MODIFY):
            r['author'] = self.author.first_last_name if self.author else '&nbsp;'

        # Publish time
        if self.has_field('publish_time'):
            r['publish_time'] = self.f_get('publish_time', fmt='%d.%m.%Y %H:%M')

        return r
Esempio n. 12
0
    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], '&nbsp;')

            # 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='&nbsp;')
                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
Esempio n. 13
0
    def process_img_tag(match):
        """Converts single body [img] tag into HTML <img> tag
        """
        nonlocal responsive_images, images_width

        # Image index
        img_index = int(match.group(1))

        # Does image exist?
        if entity_images_count < img_index:
            return ''

        img = entity_images[img_index - 1]

        # Additional parameters defaults
        link_orig = False
        link_target = '_blank'
        link_class = ''
        img_css = ''
        enlarge = enlarge_images_setting
        alt = entity.title if entity.has_field('title') else ''
        width = 0
        height = 0
        responsive = responsive_images

        for arg in match.group(2).split(':'):  # type: str
            arg = arg.strip()
            if arg in ('link_orig', 'link'):
                link_orig = True
            elif arg.startswith('link_target='):
                link_target = arg.split('=')[1]
            elif arg.startswith('link_class='):
                link_class = arg.split('=')[1]
            elif arg in ('skip_enlarge', 'no_enlarge'):
                enlarge = False
            elif arg.startswith('class='):
                img_css = arg.split('=')[1]
            elif arg.startswith('alt='):
                alt = arg.split('=')[1]
            elif arg.startswith('width='):
                responsive = False
                try:
                    width = int(arg.split('=')[1])
                except ValueError:
                    width = 0
            elif arg.startswith('height='):
                responsive = False
                try:
                    height = int(arg.split('=')[1])
                except ValueError:
                    height = 0

        if images_width:
            responsive = False
            width = images_width

        # HTML code
        if responsive:
            r = img.get_responsive_html(alt, enlarge=enlarge, css=util.escape_html(img_css))
        else:
            r = img.get_html(alt, width=width, height=height, enlarge=enlarge, css=util.escape_html(img_css))

        # Link to original file
        if link_orig:
            link = htmler.A(r, href=img.url, target=link_target, title=util.escape_html(alt))
            if link_class:
                link.set_attr('css', util.escape_html(link_class))

            r = str(link)

        return r