Example #1
0
    def style_container(self, attrs, important=True, page=None):
        """
    Description:
    ------------
    Set the CSS style for the container page in a Jupyter Notebook.

    Usage::

      page = pk.Page()
      pk.jupyter.Notebook.display.full_width(page)

    Attributes:
    ----------
    :param attrs: Dictionary. Optional. The key, value pairs with the CSS attributes,
    :param important: Boolean. Optional. Set all the CSS attributes are important.
    :param page: Report. Optional. The web page or cell in the Jupyter notebook.
    """
        self.page = page or self.page
        if self.page is not None:
            self.page.properties.css.add_text(
                ".container {%s}" % Defaults_css.inline(attrs, important))
            return self

        else:
            return self.css(".container {%s}" %
                            Defaults_css.inline(attrs, important))
Example #2
0
  def left(self, components, title="", color=None, align="center", width=(100, "%"), height=(None, "px"), html_code=None,
           helper=None, options=None, profile=False):
    """
    Description:
    ------------
    Sliding panels with the arrow on the left.

    :tags:
    :categories:

    Usage::

    Attributes:
    ----------
    :param components: List. The different HTML objects to be added to the component.
    :param title: String. Optional. A panel title. This will be attached to the title property.
    :param color: String. Optional. The font color in the component. Default inherit.
    :param align: String. The text-align property within this component.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side).
    :param helper: String. Optional. A tooltip helper.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    """
    sliding = self.page.ui.panels.sliding(components, color=color, title=title, align=align, width=width, height=height,
                                          html_code=html_code, helper=helper, options=options, profile=profile)
    sliding.options.icon_closed = Defaults_css.get_icon("chevron_up")["icon"]
    sliding.options.icon_expanded = Defaults_css.get_icon("chevron_down")["icon"]
    sliding.style.css.width = "80%"
    sliding.style.css.border_bottom = "1px solid black"
    html.Html.set_component_skin(sliding)
    return sliding
Example #3
0
  def plus(self, components, title="", color=None, align="center", width=(100, "%"), height=(None, "px"), html_code=None,
           helper=None, options=None, profile=False):
    """
    Description:
    ------------
    Same component than sliding with a different style.

    :tags:
    :categories:

    Usage::

    Attributes:
    ----------
    :param components: List. The different HTML objects to be added to the component.
    :param title: String. Optional. A panel title. This will be attached to the title property.
    :param color: String. Optional. The font color in the component. Default inherit.
    :param align: String. The text-align property within this component.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side).
    :param helper: String. Optional. A tooltip helper.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    """
    html_slide = self.page.ui.panels.sliding(
      components, title, color, align, width, height, html_code, helper, options, profile)
    html_slide.title.style.css.padding = 0
    html_slide.title[1].style.css.margin_left = 15
    html_slide.options.icon_closed = Defaults_css.get_icon("plus")["icon"]
    html_slide.options.icon_expanded = Defaults_css.get_icon("minus")["icon"]
    html_slide.val[1].style.padding_left = 40
    html.Html.set_component_skin(html_slide)
    return html_slide
Example #4
0
    def __str__(self):
        header = [
            "<th style='width:%s%%;%s'>%s</th>" %
            (100 / len(self.labels), Defaults.inline(self.options.header), d)
            for d in self.labels
        ]
        body, row = [], []
        for i, day in enumerate(self.val):
            if 'number' in day:
                total_capacity, tooltip = 0, ["<b>%s</b>" % day['date']]
                for t in day.get("tasks", []):
                    c = t.get("capacity", 0)
                    total_capacity += c
                    tooltip.append("<div>%s: %s%%</div>" % (t['name'], c))
                if total_capacity > 100:
                    day["total_capacity"] = total_capacity
                    day["style"] = Defaults.inline(self.options.overload)
                    numer_day = "<div style='%(style)s' data-html='true' data-toggle='tooltip' title='overload: %(total_capacity)s%%'>%(number)s</div>" % day
                else:
                    day["style"] = Defaults.inline(self.options.number)
                    numer_day = "<div style='%(style)s'>%(number)s</div>" % day
                tasks = "<div>%s</div>" % "".join([
                    "<div style='width:100%%;height:20px;display:block;vertical-align:middle'><div style='background:%(color)s;width:100%%;height:%(capacity)s%%;display:inline-block' title='%(name)s: %(capacity)s%%'></div></div>"
                    % t for t in day.get("tasks", [])
                ])
                cell_style = Defaults.inline(self.options.today)
                if day.get("today", False):
                    row.append(
                        "<td data-placement='right' data-toggle='tooltip' data-html='true' title='<div>%s</div>' style='%s;background:%s'>%s%s</td>"
                        % ("".join(tooltip), cell_style,
                           self._report.theme.success[0], numer_day, tasks))
                else:
                    row.append(
                        "<td data-placement='right' data-toggle='tooltip' data-html='true' title='<div>%s</div>' style='%s'>%s%s</td>"
                        % ("".join(tooltip), cell_style, numer_day, tasks))
            else:
                row.append("<td style='padding:0'></td>")
            if i % len(self.labels) == 0:
                body.append("<tr>%s</tr>" % "".join(row))
                row = []
        if row:
            for i in range(7 - len(row)):
                row.append("<td style='padding:0'></td>")
            body.append("<tr>%s</tr>" % "".join(row))

        self._report._props['js']['onReady'].add(
            "%s.tooltip()" %
            JsQuery.decorate_var("'[data-toggle=tooltip]'", convert_var=False))
        return '<table %(strAttr)s><caption style="text-align:right">%(caption)s</caption><tr>%(header)s</tr>%(content)s</table>' % {
            'strAttr': self.get_attrs(pyClassNames=self.style.get_classes()),
            'caption': self.caption,
            'header': "".join(header),
            'content': "".join(body)
        }
Example #5
0
  def loading(self, status=True, color=None):
      """
      Description:
      ------------
      Display / hide the loading status for this component.

      Attributes:
      ----------
      :param status: Boolean. Optional. The loading status.
      :param color: String. Optional. The loading text color.
      """
      self.require.add(cssDefaults.get_icon(None)["icon_family"])
      if status:
        return ''' 
          if (typeof window['popup_loading_%(htmlId)s'] === 'undefined'){
            var divLoading = document.createElement("div"); 
            window['popup_loading_%(htmlId)s'] = divLoading; 
            divLoading.style.width = '100%%'; divLoading.style.height = '100%%'; divLoading.style.background = '%(background)s';
            divLoading.style.position = 'absolute'; divLoading.style.top = 0; divLoading.style.left = 0; 
            divLoading.style.display = 'flex'; divLoading.style.flexDirectio = 'column'; divLoading.style.justifyContent = 'center';
            divLoading.style.zIndex = 200; divLoading.style.alignItems = 'center';
            divLoading.style.color = '%(color)s'; divLoading.style.border = '1px solid %(color)s';
            divLoading.innerHTML = "<div style='font-size:%(size)spx'><i class='fas fa-spinner fa-spin' style='margin-right:10px'></i>Loading...</div>";
            document.getElementById('%(htmlId)s').appendChild(divLoading)
          } ''' % {"htmlId": self.htmlCode, 'color': color or self.page.theme.success[1],
                   'background': self.page.theme.greys[0],
                   "size": self.page.body.style.globals.font.size + 5}

      return '''
        if (typeof window['popup_loading_%(htmlId)s'] !== 'undefined'){
          document.getElementById('%(htmlId)s').removeChild(window['popup_loading_%(htmlId)s']); 
          window['popup_loading_%(htmlId)s'] = undefined}''' % {"htmlId": self.htmlCode}
Example #6
0
 def __init__(self, page: primitives.PageModel, records: list, width: tuple,
              height: tuple, html_code: Optional[str],
              helper: Optional[str], options: Optional[dict],
              profile: Optional[Union[bool, dict]]):
     options['is_root'] = True
     icon_details = cssDefaults.get_icon("folder_open")
     options['icon_open'] = icon_details["icon"]
     if icon_details['icon_family'] != 'bootstrap-icons':
         self.requirements = (icon_details['icon_family'], )
     options['style'] = {
         "list-style": 'none',
         'margin-left': '8px',
         'padding-left': 0
     }
     super(Tree, self).__init__(page,
                                records,
                                profile=profile,
                                options=options,
                                css_attrs={
                                    "width": width,
                                    'height': height
                                })
     self.add_helper(helper)
     self.css(options['style'])
     self._jsStyles['click_node'] = None
Example #7
0
 def __str__(self):
   divs = []
   css_inline = Defaults.inline(self.options.style)
   for val in self.val:
     val["css_inline"] = css_inline
     divs.append("<div><div style='background:%(color)s;%(css_inline)s'></div>%(name)s</div>" % val)
   return '<div %s>%s</div>' % (self.get_attrs(css_class_names=self.style.get_classes()), "".join(divs))
Example #8
0
 def __init__(self, page: primitives.PageModel, val, width: tuple, profile: Optional[Union[bool, dict]],
              options: Optional[dict]):
   icon_details = Defaults.get_icon("info")
   if icon_details['icon_family'] != 'bootstrap-icons':
     self.requirements = (icon_details['icon_family'],)
   super(Help, self).__init__(page, val, css_attrs={"width": width}, profile=profile)
   self.attr['class'].add(icon_details["icon"])
   self.attr['title'] = val
   self._jsStyles = options
Example #9
0
    def style_prompt(self, attrs, important=True, page=None):
        """
    Description:
    ------------

    :param attrs:
    :param important:
    :param page:
    :return:
    """
        self.page = page or self.page
        if self.page is not None:
            self.page.properties.css.add_text(
                ".prompt {%s}" % Defaults_css.inline(attrs, important))
            return self

        else:
            return self.css(".prompt {%s}" %
                            Defaults_css.inline(attrs, important))
Example #10
0
  def adv_text(self, section, title, content, background=""):
    """
    Description:
    ------------

    Attributes:
    ----------
    :param section:
    :param title:
    :param content:
    :return:
    """
    container = self.context.rptObj.ui.div()
    if section is not None:
      text = self.context.rptObj.ui.text(section, width=(100, '%'))
      text.style.css.text_align = "center"
      text.style.css.font_size = Defaults_css.font(-1)
      text.style.css.line_height = Defaults_css.font(5)
      text.style.css.font_weight = 500
      text.style.css.letter_spacing = "0.15em"
      text.style.css.text_transform = "uppercase"
      container.add(text)

    if title is not None:
      title = self.context.rptObj.ui.text(title, width=(100, '%'))
      title.style.css.text_align = "center"
      title.style.css.font_size = Defaults_css.font(12)
      title.style.css.font_weight = 300
      title.css({'margin-block-end': '0.67em', 'margin-block-start': '0'})
      container.add(title)

    if content is not None:
      content = self.context.rptObj.ui.text(content, width=(80, "%"))
      content.style.css.text_align = "center"
      content.style.css.font_size = Defaults_css.font(2)
      content.style.css.margin = "auto"

    container.add(content)
    # container0.style.css.border = "10px solid white"
    container.style.css.text_align = "center"
    container.style.css.background = background
    container.style.css.padding = 10
    return container
Example #11
0
  def search(self, text='', placeholder='Search..', align="left", color=None, width=(100, "%"), height=(None, "px"),
             html_code=None, tooltip='', extensible=False, options=None, profile=None):
    """
    Description:
    ------------
    Add an input search component.

    Usage::

      page.ui.inputs.search()

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlTextEditor.Cell`

    Related Pages:

      https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_anim_search

    Templates:

      https://github.com/epykure/epyk-templates/blob/master/locals/components/list_filter.py

    Attributes:
    ----------
    :param text:
    :param placeholder:
    :param align:
    :param color:
    :param width: Optional. A tuple with the integer for the component width and its unit
    :param height: Optional. A tuple with the integer for the component height and its unit
    :param html_code:
    :param tooltip:
    :param extensible:
    :param options: Dictionary. Optional. Specific Python options available for this component
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage
    """
    width = Arguments.size(width, unit="px")
    height = Arguments.size(height, unit="px")
    icon_details = Defaults_css.get_icon("search")
    dflt_options = {"icon": icon_details["icon"], 'position': 'left', 'select': True, "border": 1}
    if options is not None:
      dflt_options.update(options)
    html_s = html.HtmlInput.Search(self.page, text, placeholder, color, width, height, html_code, tooltip,
                                   extensible, dflt_options, profile)
    html_s.style.css.height = Defaults.LINE_HEIGHT + 5
    html_s.style.css.margin_bottom = 10
    if align == "center":
      html_s.style.css.margin = "auto"
      html_s.style.css.display = "block"
    html.Html.set_component_skin(html_s)
    return html_s
Example #12
0
  def __init__(self, report, text, level, name, contents, color, picture, icon, marginTop, htmlCode, width,
               height, align, options, profile):

    cssStyles = re.search(" css\{(.*)\}", text)
    if cssStyles is not None:
      text = text.replace(cssStyles.group(0), '')
      for cssAttr in cssStyles.group(1).split(","):
        cssKey, cssVal = cssAttr.split(":")
        options[cssKey.strip()] = cssVal.strip()
    super(Title, self).__init__(report, text, htmlCode=htmlCode, css_attrs={"width": width, "height": height}, profile=profile)
    self.__options = OptText.OptionsTitle(self, options)
    self._name, self.level, self.picture = name, level, picture
    self.add_icon(icon, htmlCode=self.htmlCode, family=options.get("icon_family"))
    if contents is not None:
      self._name = contents.add(text, level or 1, name)
    if level is not None and level < 5:
      getattr(self.style.add_classes.text, "title_%s" % level)()
      self.css({'color': color, 'margin': '%spx 0 5px 0' % marginTop, 'font-size': Default_css.font({1: 15, 2: 10, 3: 6, 4: 3}[level])})
    else:
      self.style.add_classes.text.title()
      self.css({'margin': '%spx 0 5px 0' % marginTop, 'font-size': Default_css.font(10)})
    if align == 'center':
      self.css({'margin': '5px auto 10px auto', 'display': 'block', 'text-align': 'center'})
    elif align is not None:
      self.css({'margin': '5px auto 10px auto', 'display': 'block', 'text-align': align})
    else:
      self.css({'display': 'block', "margin-right": "10px"})
    if hasattr(report, '_content_table') and self.__options.content_table:
      # Special attribute set in the base component interface
      div = self._report.ui.div(htmlCode="%s_anchor" % self.htmlCode)
      if self._report.body.css('padding-top') is None:
        div.style.css.margin_top = - 10
      else:
        div.style.css.margin_top = - int(self._report.body.css('padding-top')[:-2]) - 10
      div.style.css.position = "absolute"
      div.style.css.z_index = -1
      report._content_table.anchor(text, level or 4, "#%s_anchor" % self.htmlCode)
      report._content_table[-1].click([
        self.dom.transition(["color", "font-size"], ['red', '102%'], duration=[0.5, 0.5], reverse=True)])
Example #13
0
    def popup(self,
              components=None,
              width=(100, '%'),
              height=(None, 'px'),
              options=None,
              profile=None):
        """
    Description:
    ------------
    Display a generic popup.

    Usage::

      popup = page.ui.modals.popup(page.ui.title('Test'), color="red")
      popup.add(page.ui.texts.paragraph('Test'))

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlPopup.Popup`

    Related Pages:

      https://www.w3schools.com/tags/tag_div.asp

    Templates:

      https://github.com/epykure/epyk-templates/blob/master/locals/components/modals.py

    Attributes:
    ----------
    :param components: List. The different HTML objects to be added to the component.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage.
    """
        width = Arguments.size(width, unit="%")
        height = Arguments.size(height, unit="px")
        icon_details = Defaults_css.get_icon("close")
        dfl_options = {
            'margin': 10,
            'closure': icon_details["icon"],
            'top': 100
        }
        if options is not None:
            dfl_options.update(options)
        popup = html.HtmlPopup.Popup(self.page, components, width, height,
                                     dfl_options, profile)
        html.Html.set_component_skin(popup)
        return popup
Example #14
0
  def __str__(self):
    if not hasattr(self.page, 'user') or self.page.user == 'local':
      icon_details = cssDefaults.get_icon(self.icon or "user")
      self.attr["class"].add(icon_details["icon"])
      self.style.css.font_family = "Font Awesome 5 Free"
      self.style.css.padding = "2px"
      self.style.css.font_size = self.size
      return '<i title="Guest Mode" %(attrs)s></i>' % {
        'size': self.size, 'attrs': self.get_attrs(css_class_names=self.style.get_classes())}

    return '''
      <div title="%(user)s" %(attrs)s>
        <p style="font-size:%(size)s;line-height:%(height)s;margin:0;padding:0">%(letter)s</p>
      </div> ''' % {'size': self.size, 'height': self.style.css.height, 'letter': self.page.user[0].upper(),
                    'user': self.page.user, 'attrs': self.get_attrs(css_class_names=self.style.get_classes())}
Example #15
0
 def __init__(self, page: primitives.PageModel, text: str, color: str, size: tuple, options: Optional[dict],
              profile: Optional[Union[bool, dict]]):
   icon_details = Defaults.get_icon("spin")
   if icon_details['icon_family'] != 'bootstrap-icons':
     self.requirements = (icon_details['icon_family'],)
   super(Loading, self).__init__(page, text, profile=profile)
   self.color = self.page.theme.greys[-1] if color is None else color
   self.size = size[0]
   self.css({'color': self.color, 'font-size': "%s%s" % (size[0], size[1]), 'z-index': 5, 'margin': 0})
   self.add_icon("%s fa-spin" % icon_details["icon"], html_code=self.htmlCode,
                 css={"font-size": "%spx" % (self.size+8)}, family=icon_details["icon_family"])
   if options.get('fixed', False):
     self.icon.css({"margin-right": '5px', "font-size": 'inherit'})
     self.css({"position": 'fixed', 'bottom': '0px', 'right': '5px'})
     self.add_span("%s..." % text, position="after", css={"width": 'auto'})
   else:
     self.add_span("%s..." % text, position="after", css={"width": '100%', "margin": "5px"})
Example #16
0
  def jsAdd(self, data):
    """
    Description:
    -----------

    Attributes:
    ----------
    :param data:
    """
    data = JsUtils.jsConvertData(data, None)
    icon_details = cssDefaults.get_icon("close")
    self.page.properties.js.add_builders('RemoveSelection(srcObj, htmlCode)', 'srcObj.parent().remove()',
       func_dsc="Remove the item from the Tags Html component but also from the underlying javascript variable")
    return '''
      $('#%(htmlCode)s_tags').append("<span style='margin:2px;background:%(baseColor)s;color:%(whiteColor)s;border-radius:8px;1em;vertical-align:middle;display:inline-block;padding:0 2px 1px 10px;cursor:pointer'>"+ %(jsData)s +"<i onclick='RemoveSelection($(this), \\\"%(htmlCode)s\\\")' style='margin-left:10px' class='%(close)s'></i></span>")
      ''' % {"htmlCode": self.htmlCode, "jsData": data, 'whiteColor': self.page.theme.greys[0],
             "baseColor": self.page.theme.colors[9], "close": icon_details["icon"]}
Example #17
0
    def badge(self, report):
        """
    Description:
    ------------
    Add text object with badges to the list

    Attributes:
    ----------
    :param report: Page object. The internal page object
    """
        item_def = '''
    var item = document.createElement("DIV");  
    var span = document.createElement("span"); span.setAttribute('name', 'value'); span.innerHTML = data.text;  
    var badge = document.createElement("span"); badge.innerHTML = data.value;
    badge.style.backgroundColor = 'red'; badge.style.color = 'white'; badge.style.borderRadius = '50%%'; badge.style.padding = '0 3px';
    badge.style.marginLeft = '5px'; badge.style.fontSize = '%s'; 
    for(const attr in options.badge){badge.style[attr] = options.badge[attr]};
    item.appendChild(span); item.appendChild(badge)''' % Defaults.font(-2)
        return self._item(item_def)
Example #18
0
  def icons(self, data=None, width=('auto', ""), height=(None, 'px'), html_code: str = None, helper: str = None,
            options=None, profile=None):
    """
    Description:
    ------------

    Usage::

      page.ui.lists.badges([{'label': 'Python', 'value': 12}, {'label': 'R', 'value': 3}])

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlList.Badges`

    Related Pages:

      https://www.w3schools.com/bootstrap/bootstrap_list_groups.asp
      https://v4-alpha.getbootstrap.com/components/list-group/

    Attributes:
    ----------
    :param data:
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side)
    :param helper: String. Optional. A tooltip helper
    :param options: Dictionary. Optional. Specific Python options available for this component
    :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage
    """
    width = Arguments.size(width, unit="%")
    height = Arguments.size(height, unit="px")
    icon_details = Defaults_css.get_icon("check")
    dft_options = {"icon": icon_details["icon"], 'markdown': True, "items_type": 'icon'}
    if options is not None:
      dft_options.update(options)
    html_list = html.HtmlList.Items(self.page, data or [], width, height, dft_options, html_code, profile, helper)
    html_list.css({"list-style": 'none'})
    html.Html.set_component_skin(html_list)
    return html_list
Example #19
0
 def __init__(self, page: primitives.PageModel, val, label, color, align, best, html_code, helper, options, profile):
   icon_details = Defaults.get_icon("star")
   if icon_details['icon_family'] != 'bootstrap-icons':
     self.requirements = (icon_details['icon_family'],)
   super(Stars, self).__init__(page, val, html_code=html_code, profile=profile, options=options)
   # Add the HTML components
   self._spans = []
   self._jsStyles = {'color': self.page.theme.success[1] if color is None else color}
   for i in range(best):
     self.add_span("", position="after", css=False)
     self._sub_htmls[-1].attr['class'].add(icon_details["icon"])
     self._sub_htmls[-1].css({"margin": 0, "padding": 0})
     self._sub_htmls[-1].set_attrs(name="data-level", value=i)
     if i < val:
       self._sub_htmls[-1].css({"color": self._jsStyles['color']})
     self._spans.append(self._sub_htmls[-1])
   self.set_attrs(name='data-level', value=val)
   self.add_label(label, {"margin": "0 0 0 5px", 'height': 'none', "text-align": "left", "display": "inline-block",
                          'float': 'None'}, html_code=self.htmlCode, position="after")
   self.add_helper(helper)
   if self.helper:
     self.helper.css({"margin": '1px 4px'})
   self.css({'text-align': align, "display": 'block'})
Example #20
0
    def days(self,
             month=None,
             content=None,
             year=None,
             width=(None, "%"),
             height=(None, "px"),
             align=None,
             options=None,
             htmlCode=None,
             profile=None):
        """
    Description:
    ------------

    Usage::


    Related Pages:

        https://github.com/epykure/epyk-templates/blob/master/locals/components/calendar.py

    Attributes:
    ----------
    :param month:
    :param content:
    :param width:
    :param height:
    :param align:
    :param options:
    :param htmlCode:
    :param profile:
    """
        width = Arguments.size(width, unit="%")
        height = Arguments.size(height, unit="px")
        today = datetime.date.today()
        month = month or today.month
        content = content or {}
        dfl_options = {
            'overload': {
                'font-size': Defaults.font(5),
                'text-align': 'center',
                'color': self.context.rptObj.theme.danger[1],
                'font-weight': 'bold',
                'cursor': 'pointer'
            },
            'number': {
                "font-size": Defaults.font(5),
                "text-align": "center"
            },
            'today': {
                "padding": "0 0 5px 0",
                "border-bottom": "1px solid grey"
            },
            'header': {
                'font-size': Defaults.font(3),
                "background": self.context.rptObj.theme.colors[-1],
                "color": self.context.rptObj.theme.colors[0],
                "padding": "5px 2px",
                "text-align": "center"
            }
        }
        factor = 100 / options.get("unit", 100) if options is not None else 1
        if options is not None:
            dfl_options.update(options)
        year = year or today.year
        start = datetime.date(year, month, 1)
        days_data, tasks = [], {}
        for values in content.values():
            for t in values.keys():
                tasks[t] = None
        sorted_tasks = sorted(list(tasks))
        for i, t in enumerate(sorted_tasks):
            tasks[t] = dfl_options.get('colors', {}).get(
                t, self.context.rptObj.theme.charts[i])
        for _ in range(start.weekday() + 1):
            days_data.append({})
        while start.month == month:
            day_tasks = content.get(start.isoformat(), {})
            tasks_view = []
            for i, t in enumerate(sorted_tasks):
                tasks_view.append({
                    "name": t,
                    'capacity': factor * day_tasks.get(t, 0),
                    'color': tasks[t]
                })
            days_data.append({
                'today': today == start,
                "number": start.day,
                'tasks': tasks_view,
                'date': start.isoformat(),
                'weekend': start.weekday() >= 5
            })
            start += datetime.timedelta(days=1)
        html_table = html.HtmlDates.Calendar(self.context.rptObj, days_data,
                                             width, height, align, dfl_options,
                                             htmlCode, profile)
        html_table.tasks = tasks
        html_table.caption = "%s %s" % (datetime.date(year, month,
                                                      1).strftime("%B"), year)
        return html_table
Example #21
0
  def __init__(self, page: primitives.PageModel, start, width: tuple, height: tuple, options: Optional[dict],
               profile: Optional[Union[dict, bool]]):
    icon_details_right = Defaults.get_icon("arrow_right")
    if icon_details_right['icon_family'] != 'bootstrap-icons':
      self.requirements = (icon_details_right['icon_family'],)
    icon_details_left = Defaults.get_icon("arrow_left")
    super(Slides, self).__init__(page, [], options=options,
                                 css_attrs={"width": width, 'height': height}, profile=profile)
    self.attr['data-current_slide'] = start
    self.title = self.page.ui.title("")
    self.title.style.css.border_bottom = "1px solid %s" % page.theme.colors[7]
    self.title.style.css.color = page.theme.colors[7]
    self.title.style.css.margin = 0
    self.title.options.managed = False
    if 'contents' in options:
      del page._content_table

      self._content_table = options['contents']
      self._content_table.style.css.z_index = 100
    if 'timer' in options:
      self.page.ui.calendars.timer(options['timer']).css(
        {"position": 'fixed', "font-size": '15px', 'top': '8px', "padding": '8px', "right": '15px', 'width': 'none',
         'color': page.theme.greys[5]})
    self.next = self.page.ui.icon(icon_details_right["icon"]).css(
      {"position": 'fixed', "font-size": '35px', 'bottom': '0',  "padding": '8px', "right": '10px', 'width': 'none'})
    self.previous = self.page.ui.icon(icon_details_left["icon"]).css(
      {"position": 'fixed', "font-size": '35px', 'bottom': '0',  "padding": '8px', "left": '10px', 'width': 'none'})

    self.page_number = self.page.ui.text("").css(
      {"position": 'fixed', 'z-index': 101, "font-size": '25px', 'bottom': '0',  "padding": '8px', "left": '50%',
       'width': 'none'})

    self.next.click([
      self.page.js.getElementsByName(self.htmlCode).all([data.loops.dom_list.hide()]),
        data.primitives.float(self.dom.attr("data-current_slide").toString().parseFloat().add(1), 'slide_index'),

      self.js.if_(page.js.object('slide_index') <= self.dom.attr('data-last_slide'), [
        self.title.build(self.page.js.getElementsByName(
          self.htmlCode)[page.js.object('slide_index')].attr('data-slide_title')),
        self.dom.attr("data-current_slide", page.js.object('slide_index')),
        self.page.js.getElementsByName(self.htmlCode)[page.js.object('slide_index')].show(display_value='flex'),
        self.page.js.getElementById(
          "%s_count" % self.htmlCode).innerHTML(page.js.object('slide_index').toString().parseFloat().add(1)),
      ]).else_([
        self.title.build(self.page.js.getElementsByName(
          self.htmlCode)[page.js.object('slide_index').add(-1)].attr('data-slide_title')),
        self.page.js.getElementsByName(
          self.htmlCode)[page.js.object('slide_index').add(-1)].show(display_value='flex')]),

      self.js.if_(page.js.object('slide_index') > 0, [self.previous.dom.show()]),
      self.js.if_(page.js.object('slide_index') == self.dom.attr('data-last_slide'), [self.next.dom.hide()])
    ])

    self.previous.click([
      self.page.js.getElementsByName(self.htmlCode).all([data.loops.dom_list.hide()]),
      data.primitives.float(self.dom.attr("data-current_slide").toString().parseFloat().add(-1), 'slide_index'),

      self.js.if_(page.js.object('slide_index') >= 0, [
        self.title.build(self.page.js.getElementsByName(
          self.htmlCode)[page.js.object('slide_index')].attr('data-slide_title')),
        self.dom.attr("data-current_slide", page.js.object('slide_index')),
        self.page.js.getElementsByName(self.htmlCode)[page.js.object('slide_index')].show(display_value='flex'),
        self.page.js.getElementById(
          "%s_count" % self.htmlCode).innerHTML(page.js.object('slide_index').toString().parseFloat().add(1)),
      ]).else_([
        self.title.build(self.page.js.getElementsByName(self.htmlCode)[0].attr('data-slide_title')),
        self.page.js.getElementsByName(self.htmlCode)[0].show(display_value='flex')]),

      self.js.if_(page.js.object('slide_index') == 0, [self.previous.dom.hide()]),
      self.js.if_(page.js.object('slide_index') < self.dom.attr('data-last_slide'), [self.next.dom.show()])
    ])

    # Add the keyboard shortcut
    page.body.keydown.right([self.next.dom.events.trigger("click")])
    page.body.keydown.left([self.previous.dom.events.trigger("click")])

    self.style.css.padding = "0 20px 20px 20px"
Example #22
0
    def agenda(self,
               task,
               start,
               end,
               details=None,
               location=None,
               icon="far fa-calendar-alt",
               text="Add to Calendar",
               options=None,
               profile=None):
        """
    Description:
    ------------

    Usage::


    Related Pages:

      https://stackoverflow.com/questions/5179760/add-events-to-google-calendar-yahoo-calendar-outlook-and-ical
    https://codepen.io/vlemoine/pen/MLwygX

    TODO: improve the time management in this component

    Attributes:
    ----------
    :param task:
    :param start:
    :param end:
    :param details:
    :param location:
    :param icon:
    :param text:
    :param options:
    :param profile:
    """
        # Default options
        calendar_options = {'CALSCALE': 'GREGORIAN', 'VERSION': '2.0'}
        events_options = {
            'DTSTART;VALUE=DATE': start,
            'DTEND;VALUE=DATE': end,
            'SUMMARY': task or '',
            'LOCATION': location or '',
            'DESCRIPTION': details or '',
            'STATUS': 'CONFIRMED',
            'SEQUENCE': 3
        }

        str_calendar = "BEGIN:VCALENDAR\n%s\n%%s\nEND:VCALENDAR" % "\n".join(
            ["%s:%s" % (k, v) for k, v in calendar_options.items()])
        str_event = "BEGIN:VEVENT\n%s\nEND:VEVENT" % "\n".join(
            ["%s:%s" % (k, v) for k, v in events_options.items()])

        link = self.context.rptObj.ui.links.data(
            "<i style='font-size:%s;color:%s' class='%s'></i> %s" %
            (Defaults.font(5), self.context.rptObj.theme.greys[-1], icon,
             text), str_calendar % str_event)
        link.attr['download'] = 'event.ics'
        link.style.css.background = self.context.rptObj.theme.greys[0]
        link.style.css.color = self.context.rptObj.theme.greys[-1]
        link.style.css.padding = '2px 5px'
        link.style.css.margin = 2
        link.style.css.display = 'inline-block'
        link.style.css.border = "1px solid %s" % self.context.rptObj.theme.greys[
            3]
        link.style.css.border_radius = 20
        return link
Example #23
0
    def validation(self,
                   components=None,
                   width=(100, '%'),
                   height=(None, 'px'),
                   options=None,
                   profile=None):
        """
    Description:
    ------------

    Usage::

      popup = page.popup(page.ui.title('Test'), color="red")
      popup + page.paragraph('Test')

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlPopup.Popup`

    Related Pages:

      https://www.w3schools.com/tags/tag_div.asp

    Templates:

      https://github.com/epykure/epyk-templates/blob/master/locals/components/modals.py

    Attributes:
    ----------
    :param components: List. The different HTML objects to be added to the component.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    """
        width = Arguments.size(width, unit="%")
        height = Arguments.size(height, unit="px")
        icon_details = Defaults_css.get_icon("close")
        dfl_options = {
            'margin': 10,
            'closure': icon_details["icon"],
            'top': 100
        }
        if options is not None:
            dfl_options.update(options)
        if not isinstance(components, list):
            components = [components]
        validate = self.page.ui.buttons.validate("Validate")
        cancel = self.page.ui.buttons.cancel()
        row = self.page.ui.row([validate, cancel],
                               position="top",
                               align="center")
        row.options.autoSize = False
        components.append(row)
        popup = html.HtmlPopup.Popup(self.page, components, width, height,
                                     dfl_options, profile)
        popup.validate = validate
        popup.cancel = cancel
        cancel.click([popup.dom.hide()])
        html.Html.set_component_skin(popup)
        return popup
Example #24
0
  def select(self, records=None, html_code: str = None, selected: str = None, width=(100, "%"), height=(None, "%"),
             profile: Union[bool, dict] = None, multiple: bool = False, options: dict = None):
    """
    Description:
    ------------
    HTML Select component.

    Usage::

      record = [
        {"text": 'Text 1', "value": "text 1"},
        {"text": 'Text 2', "value": "text 2"},
        {"text": 'Text 3', "value": "text 3"},
      ]

      select = page.ui.select(record)


    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlSelect.Select`

    Related Pages:

      https://silviomoreto.github.io/bootstrap-select/examples/
      https://www.npmjs.com/package/bootstrap-select-v4
      https://www.jqueryscript.net/form/Bootstrap-4-Dropdown-Select-Plugin-jQuery.html

    Attributes:
    ----------
    :param records: List. Optional. The list of dictionaries with the input data.
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side).
    :param selected: String. Optional. The selected value or values.
    :param width: Tuple. Optional. Integer for the component width.
    :param height: Tuple. Optional. Integer for the component height.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    :param multiple: Boolean. Optional. To set if the component can handle multiple selections.
    :param options: Dictionary. The select options as defined https://developer.snapappointments.com/bootstrap-select/options/
    """
    width = Arguments.size(width, unit="%")
    height = Arguments.size(height, unit="%")
    records = records or []
    if not isinstance(records, list):
      records = [{'text': v, 'value': v, "selected": True} for v in records.split(",")]
    options = options or {}
    options['selected'] = selected
    if multiple:
      if not isinstance(multiple, dict):
        multiple = {"max": 2}
      if selected is not None:
        for rec in records:
          if rec["value"] in selected:
            rec["selected"] = True

      icon_details = Defaults_css.get_icon("check")
      options["iconBase"] = "iconBase"
      options["tickIcon"] = icon_details["icon"]
      html_select = html.HtmlSelect.Select(self.page, records, html_code, width, height, profile, multiple, options)
      html.Html.set_component_skin(html_select)
      return html_select

    if selected is not None:
      for rec in records:
        if rec["value"] == selected:
          rec["selected"] = True
    html_select = html.HtmlSelect.Select(self.page, records, html_code, width, height, profile, multiple, options)
    html.Html.set_component_skin(html_select)
    return html_select
Example #25
0
    def price(self,
              value,
              title,
              items,
              url=None,
              align="center",
              width=(250, 'px'),
              currency="£",
              options=None,
              profile=None):
        """
    Description:
    ------------

    Usage::

      page.ui.vignets.price(10, "This is the price", [])

    Attributes:
    ----------
    :param value:
    :param title:
    :param items:
    :param url:
    :param align:
    :param width:
    :param currency:
    :param options:
    :param profile:
    """
        container = self.context.rptObj.ui.div(align=align,
                                               width=width,
                                               options=options,
                                               profile=profile)
        container.style.css.border = "1px solid %s" % self.context.rptObj.theme.greys[
            3]
        container.style.css.margin = "auto"
        if not hasattr(title, 'options'):
            title = self.context.rptObj.ui.titles.title(title)
            title.style.css.display = "block"
            title.style.css.text_align = align
        container.add(title)
        if not hasattr(value, 'options'):
            value = self.context.rptObj.ui.texts.number(value,
                                                        options={
                                                            "type_number":
                                                            'money',
                                                            'symbol': currency
                                                        },
                                                        profile=profile)
            value.style.css.font_size = Defaults_css.font(30)
        container.add(value)
        if url is not None:
            button = self.context.rptObj.ui.button("Subscribe",
                                                   align="center",
                                                   profile=profile)
            button.style.css.background_color = self.context.rptObj.theme.success[
                1]
            button.style.css.color = 'white'
            button.style.css.margin_top = 10
            button.style.css.margin_bottom = 10
            container.add(button)
        if not hasattr(items, 'options'):
            items = self.context.rptObj.ui.lists.icons(items, profile=profile)
            items.style.css.margin = "auto 20%"
            items.style.css.text_align = "left"
        container.add(items)
        return container
Example #26
0
    def search_input(self,
                     text='',
                     placeholder='Search..',
                     color=None,
                     width=(100, '%'),
                     height=(None, "px"),
                     html_code=None,
                     tooltip=None,
                     extensible=False,
                     options=None,
                     profile=None):
        """
    Description:
    ------------
    Search bar.

    :tags:
    :categories:

    Usage::

      page.ui.inputs.search()

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlInput.Search`

    Related Pages:

      https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_anim_search

    Attributes:
    ----------
    :param text: String. Optional. The value to be displayed to the component.
    :param placeholder: String. Optional. The text display when empty.
    :param color: String. Optional. The font color in the component. Default inherit.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side).
    :param tooltip: String. Optional. A string with the value of the tooltip.
    :param extensible: Boolean. Optional. Flag to specify the input style.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    """
        width = Arguments.size(width, unit="px")
        height = Arguments.size(height, unit="px")
        icon_details = Defaults_css.get_icon("search")
        dflt_options = {
            "icon": icon_details["icon"],
            "icon_family": icon_details["icon_family"],
            'position': 'left',
            'select': True,
            "border": 1
        }
        if options is not None:
            dflt_options.update(options)
        html_s = html.HtmlInput.Search(self.page, text, placeholder, color,
                                       width, height, html_code, tooltip,
                                       extensible, dflt_options, profile)
        html.Html.set_component_skin(html_s)
        return html_s
Example #27
0
 def customize(self):
   self.css({'font-size': '%s%s' % (Defaults_css.font(4), Defaults_css.Font.unit),
             'font-family': Defaults_css.Font.family})
Example #28
0
    def download(self,
                 name: str,
                 icon: str = None,
                 path: str = None,
                 width: Union[tuple, int] = (25, 'px'),
                 height: Union[tuple, int] = (25, 'px'),
                 html_code: str = None,
                 options: dict = None,
                 profile: Union[dict, bool] = None):
        """
    Description:
    ------------

    Usage::

    Attributes:
    ----------
    :param name: String. Optional.
    :param icon: String. Optional. The component icon content from font-awesome references.
    :param path: String. Optional. String. The image file path.
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit.
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit.
    :param html_code: String. Optional. The id for this component.
    :param options: Dictionary. Optional. Specific Python options available for this component.
    :param profile: Boolean | Dictionary. Optional. A flag to set the component performance storage.
    """
        options = options or {}
        mapped_file = {
            "excel": Defaults_css.get_icon("excel"),
            'pdf': Defaults_css.get_icon("pdf"),
            'code': Defaults_css.get_icon("code"),
            'csv': Defaults_css.get_icon("csv"),
            'word': Defaults_css.get_icon("word")
        }
        extension = name.split(".")[-1]
        if extension in mapped_file:
            icon = mapped_file[extension]["icon"]
            options["icon_family"] = mapped_file[extension]["icon_family"]
        if icon is None:
            icon = Defaults_css.get_icon("upload")["icon"]
            options["icon_family"] = Defaults_css.get_icon(
                "upload")["icon_family"]
        file = self.page.ui.icons.awesome(icon,
                                          width=width,
                                          height=height,
                                          html_code=html_code,
                                          options=options,
                                          profile=profile)
        file.tooltip(r"Download file: %(path)s\%(name)s" % {
            "path": path,
            "name": name
        })
        if path is not None:
            file.click([
                '''
        var link = document.createElement("a");
        link.href = 'file://localhost/%(path)s';
        link.target="_blank";
        link.setAttribute('download', '%(name)s');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        ''' % {
                    "path": os.path.join(path, name),
                    "name": name
                }
            ])
        html.Html.set_component_skin(file)
        return file
Example #29
0
    def chips(self,
              items=None,
              category='group',
              placeholder="",
              width=(100, "%"),
              height=(60, "px"),
              htmlCode=None,
              helper=None,
              options=None,
              profile=None):
        """
    Description:
    ------------
    Add a chip (filter) html component

    Usage::

      chips = rptObj.ui.chips([])

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlEvent.Filters`

    Related Pages:

      https://www.w3schools.com/howto/howto_css_contact_chips.asp

    Templates:

        https://github.com/epykure/epyk-templates/blob/master/locals/components/chips.py
        https://github.com/epykure/epyk-templates/blob/master/locals/components/list.py

    Attributes:
    ----------
    :param items: List. Selected items
    :param category: String. The group of the items.
    :param placeholder: String. The input field placeholder
    :param width: Tuple. Optional. A tuple with the integer for the component width and its unit
    :param height: Tuple. Optional. A tuple with the integer for the component height and its unit
    :param htmlCode: String. Optional. An identifier for this component (on both Python and Javascript side)
    :param helper: String. Optional. A tooltip helper
    :param options: Dictionary. Optional. Specific Python options available for this component
    :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage
    """
        width = Arguments.size(width, unit="%")
        height = Arguments.size(height, unit="px")
        dflt_options = {
            "item_css": {
                "padding": '5px',
                'border':
                '1px solid %s' % self.context.rptObj.theme.success[0],
                'border-radius': '5px',
                'margin': '2px',
                "width": 'auto',
                'display': 'inline',
                'background': 'inherit'
            },
            'category': category,
            'visible': True,
            'value_css': {
                'font-size': Defaults.font(3),
                'font-weight': 'bold',
                'vertical-align': 'bottom'
            },
            'category_css': {
                'display': 'inline',
                'margin-right': '2px',
                'vertical-align': 'top',
                'font-size': Defaults.font(-3)
            },
            'icon_css': {
                'color': self.context.rptObj.theme.success[1],
                'margin-left': '5px',
                'cursor': 'pointer'
            }
        }
        if not hasattr(category, 'toStr') and category == 'group':
            dflt_options['visible'] = False
        if options is not None:
            dflt_options.update(options)
        html_f = html.HtmlEvent.Filters(self.context.rptObj, items or [],
                                        width, height, htmlCode, helper,
                                        dflt_options, profile)
        html_f.input.attr['placeholder'] = placeholder
        return html_f
Example #30
0
    def digits(self,
               text=None,
               color=None,
               align='center',
               width=None,
               height=None,
               htmlCode=None,
               tooltip=None,
               options=None,
               profile=None):
        """
    Description:
    ------------
    The <span> tag is used to group inline-elements in a document.

    The <span> tag provides no visual change by itself.

    The <span> tag provides a way to add a hook to a part of a text or a part of a document.

    Usage::

      rptObj.ui.texts.span("Test")

    Underlying HTML Objects:

      - :class:`epyk.core.html.HtmlText.Position`

    Related Pages:

      https://www.w3schools.com/tags/tag_span.asp

    Templates:

      https://github.com/epykure/epyk-templates/blob/master/locals/components/numbers.py

    Attributes:
    ----------
    :param text: Optional. The string value to be displayed in the component
    :param color: Optional. The color of the text
    :param align: Optional. The position of the icon in the line (left, right, center)
    :param width: Optional. A tuple with the integer for the component width and its unit
    :param height: Optional. A tuple with the integer for the component height and its unit
    :param htmlCode: Optional. An identifier for this component (on both Python and Javascript side)
    :param tooltip: Optional. A string with the value of the tooltip
    :param profile: Optional. A flag to set the component performance storage
    """
        if width is None:
            width = (defaults_html.TEXTS_SPAN_WIDTH, 'px')
        if height is None:
            height = (defaults_html.LINE_HEIGHT, 'px')
        html_label = html.HtmlText.Position(self.context.rptObj, text, color,
                                            align, width, height, htmlCode,
                                            tooltip, options, profile)
        html_label.position(3, {
            "font-size": defaults_css.font(5),
            "font-weight": "bold"
        })
        html_label.position(4, {
            "font-size": defaults_css.font(5),
            "font-weight": "bold"
        })
        html_label.digits(True)
        return html_label