def render_ActionLog_history(self, h, *_args): h << h.h2(_('Action log')) log = self.get_history() users = set(event.user for event in log) cards = set(event.card for event in log) with h.div(id='action-log'): with h.form: with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in sorted(users, key=lambda u: u.fullname): h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update( action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for card in sorted(cards, key=lambda c: c.title): h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history'): with h.table(class_='table table-striped table-hover'): with h.body: for event in self.get_history(): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(event.to_string()) return h.root
def render(self, h, comp, *args): """Label chooser contained in the overlay's body""" with h.ul(class_='unstyled inline-labels'): for _i, label in enumerate(self.get_available_labels(), 1): with h.li: cls = ['card-label-choose'] if label.id in self.labels: cls.append('active') # Update the list of labels action1 = ajax.Update( action=lambda label_id=label.id: self.activate(label_id)) # Refresh the list action2 = ajax.Update( render=lambda r: comp.render(r, model='list'), component_to_update='list' + self.comp_id) with h.a( title=label.color, class_=' '.join(cls), ).action(ajax.Updates(action1, action2)): h << h.span(class_="card-label", style='background-color: %s' % label.color) h << h.span(label.title) if label.id in self.labels: h << h.i(class_='icon-checkmark') return h.root
def render_Checklists(self, h, comp, model): h.head.javascript_url('checklists/js/checklists.js') with h.div(id_='clist' + self.comp_id): if security.has_permissions('checklist', self.card): # On drag and drop action = h.a.action( ajax.Update(action=self.reorder, with_request=True)).get('onclick').replace( 'return', '') action = action.replace( '")', '&data="+ YAHOO.lang.JSON.stringify(data))') h.head.javascript( h.generate_id(), '''function reorder_checklists(data) { %s; }''' % action) # On items drag and drop action = h.a.action( ajax.Update(action=self.reorder_items, with_request=True)).get('onclick').replace( 'return', '') action = action.replace( '")', '&data="+ YAHOO.lang.JSON.stringify(data))') h.head.javascript( h.generate_id(), '''function reorder_checklists_items(data) { %s; }''' % action) id_ = h.generate_id() with h.div(class_='checklists', id=id_): for index, clist in enumerate(self.checklists): h << clist.on_answer( lambda v, index=index: self.delete_checklist(index)) return h.root
def render_Board_item(self, h, comp, *args): reload_search = ajax.Update(component_to_update='show_results', render=lambda renderer: comp.render(renderer, 'search_results')) h << h.script(u'''$(window).on('reload_search', function() { %s; })''' % reload_search.generate_action(41, h)) with h.div(id='switch_zone'): if self.model == 'columns': search_cb = ajax.Update( action=self.search, component_to_update='show_results', render=lambda renderer: comp.render(renderer, 'search_results') ).generate_action(1, h).replace('this', 'elt') oninput = 'debounce(this, function(elt) { %s; }, 500)' % search_cb with h.div(id_='show_results'): h << comp.render(h, 'num_matches') if self.card_matches: if None in self.card_matches: klass = 'nomatches' else: klass = 'highlight' else: klass = '' h << h.input(type='text', id_='search', placeholder=_(u'search'), value=self.last_search, oninput=oninput, class_=klass) #h << h.a(h.i(class_='icon-search', title=_('search')), class_='btn unselected') h << h.SyncRenderer().a(h.i(class_='icon-calendar'), title=_('Calendar mode'), class_='btn unselected').action(self.switch_view) h << h.SyncRenderer().a(h.i(class_='icon-list'), title=_('Board mode'), class_='btn disabled') else: h << h.SyncRenderer().a(h.i(class_='icon-calendar'), title=_('Calendar mode'), class_='btn disabled') h << h.SyncRenderer().a(h.i(class_='icon-list'), title=_('Board mode'), class_='btn unselected').action(self.switch_view) return h.root
def render_Board_columns(self, h, comp, *args): """Render viewport containing the columns""" update_if_version_mismatch = lambda renderer: comp.render( renderer, 'columns') if self.increase_version() else '' with h.div(id='viewport-wrapper'): with h.div(class_='clearfix', id='viewport'): # On cards drag and drop action = ajax.Update(action=self.update_card_position, render=update_if_version_mismatch) action = '%s;_a;%s=' % (h.add_sessionid_in_url(sep=';'), action._generate_replace(1, h)) h.head.javascript( h.generate_id(), '''function _send_card_position(data) { nagare_getAndEval(%s + YAHOO.lang.JSON.stringify(data)); }''' % ajax.py2js(action)) # On columns drag and drop action = ajax.Update(action=self.update_column_position, render=update_if_version_mismatch) action = '%s;_a;%s=' % (h.add_sessionid_in_url(sep=';'), action._generate_replace(1, h)) h.head.javascript( h.generate_id(), '''function _send_column_position(data) { nagare_getAndEval(%s + YAHOO.lang.JSON.stringify(data)); }''' % ajax.py2js(action)) # Create the reload_columns function used when we need to reload # the columns from javascript reload_board = h.a.action(ajax.Update()).get('onclick').replace( 'return', "") h.head.javascript( h.generate_id(), """function reload_columns(){%s}""" % reload_board) increase_version = h.a.action( ajax.Update(render=update_if_version_mismatch)) h.head.javascript( h.generate_id(), """function increase_version() {%s}""" % increase_version.get('onclick')) # Render columns with h.div(id='lists'): h << h.div(' ', id='dnd-frame') for column in self.columns: if column().is_archive and not self.show_archive: continue model = 0 if not security.has_permissions( 'edit', self) else column.model or 'dnd' h << column.on_answer(self.handle_event, comp).render( h, model) # Call columns resize h << h.script( "YAHOO.kansha.app.columnsResize();YAHOO.kansha.app.refreshCardsCounters();$(window).trigger('reload_search');" ) return h.root
def render_Checklists(self, h, comp, model): if security.has_permissions('checklist', self.parent): # On drag and drop action = ajax.Update(action=self.reorder) action = '%s;_a;%s=' % (h.add_sessionid_in_url(sep=';'), action._generate_replace(1, h)) h.head.javascript( h.generate_id(), '''function reorder_checklists(data) { nagare_getAndEval(%s + YAHOO.lang.JSON.stringify(data)); }''' % ajax.py2js(action)) # On items drag and drop action = ajax.Update(action=self.reorder_items) action = '%s;_a;%s=' % (h.add_sessionid_in_url(sep=';'), action._generate_replace(1, h)) h.head.javascript( h.generate_id(), '''function reorder_checklists_items(data) { nagare_getAndEval(%s + YAHOO.lang.JSON.stringify(data)); }''' % ajax.py2js(action)) id_ = h.generate_id() with h.div(class_='checklists', id=id_): for index, clist in enumerate(self.checklists): h << clist.on_answer( lambda v, index=index: self.delete_checklist(index)) h << h.script("""$(function() { $("#" + %(id)s).sortable({ placeholder: "ui-state-highlight", axis: "y", handle: ".icon-list", cursor: "move", stop: function( event, ui ) { reorder_checklists($('.checklist').map(function() { return this.id }).get()) } }); $(".checklists .checklist .content ul").sortable({ placeholder: "ui-state-highlight", cursor: "move", connectWith: ".checklists .checklist .content ul", dropOnEmpty: true, update: function(event, ui) { var data = { target: ui.item.closest('.checklist').attr('id'), index: ui.item.index(), id: ui.item.attr('id') } reorder_checklists_items(data); } }).disableSelection(); })""" % {'id': ajax.py2js(id_)}) return h.root
def render_gallery_cropper(self, h, comp, *args): crop_width, crop_height = 425, 250 h << h.p(_('Use the controls below to create the cover of your card.')) form_id, img_id = h.generate_id(), h.generate_id() with h.form: for crop_name in 'crop_left', 'crop_top', 'crop_width', 'crop_height': h << h.input(type='hidden', id=form_id + '_' + crop_name).action( getattr(self, crop_name)) h << h.p(render_image(self.asset, h, comp, 'medium', id=img_id)) h << h.script( "YAHOO.util.Event.onContentReady(%s," "function(){YAHOO.kansha.app.initCrop(%s, %s, %s, %s)})" % (ajax.py2js(img_id), ajax.py2js(img_id), ajax.py2js(form_id), ajax.py2js(crop_width), ajax.py2js(crop_height))) with h.div(class_='buttons'): h << h.input( type='submit', value=_('Done'), class_='btn btn-primary').action( ajax.Update(render=lambda r: self.card_component.render( r, self.card_component_model), action=lambda: comp.answer( (int(self.crop_left() or 0), int(self.crop_top() or 0), int(self.crop_width() or crop_width), int(self.crop_height() or crop_height))), component_to_update=self.card_component_id)) return h.root
def render_num_matches(self, h, comp, *args): h.head.javascript_url('js/debounce.js') h.head.javascript_url('js/search.js?v=2c') search_cb = h.input.action( ajax.Update(action=self.search, component_to_update='show_results', render=lambda renderer: comp.render( renderer, 'search_results'))).get('onchange').replace( 'this', 'elt') oninput = 'debounce(this, function(elt) { %s; }, 500)' % search_cb h << h.div(id_='show_results') if self.card_matches: if None in self.card_matches: klass = 'nomatches' else: klass = 'highlight' else: klass = '' with h.div(id='search', class_=klass): h << h.input(type='text', placeholder=_(u'search'), value=self.last_search, oninput=oninput) with h.span(class_='icon'): h << h.i(class_='icon-search search_icon', style='display:none' if self.last_search else '') h << h.a(h.i(class_='icon-cancel-circle'), href='#', class_='search_close', style='' if self.last_search else 'display: none') h << comp.render(h, 'num_matches') return h.root
def render(self, h, comp, *args): """Render the card""" extensions = [ extension.on_answer(self.handle_event, comp) for name, extension in self.extensions ] card_id = h.generate_id() onclick = h.a.action(self.emit_event, comp, events.CardClicked, comp).get('onclick').replace('return', "") with h.div(id=self.id, class_='card'): with h.div(id=card_id, onclick=onclick): with h.div(class_='headers'): h << [ extension.render(h, 'header') for extension in extensions ] with h.div(class_='covers'): with h.div(class_='title'): h << self.title.render(h, 'readonly') h << [extension.render(h, 'cover') for extension in extensions] with h.div(class_='badges'): h << [extension.render(h, 'badge') for extension in extensions] h << h.script( "YAHOO.kansha.reload_cards[%s]=function() {%s}" "" % (ajax.py2js(self.id), h.a.action(ajax.Update()).get('onclick'))) if self.emit_event(comp, events.CardDisplayed) == 'reload_search': h << h.script('''$(window).trigger('reload_search');''') return h.root
def render_in_calendar(self, h, comp, *args): # TODO should be in due_date extension due_date = dict(self.extensions)['due_date']().due_date if due_date: due_date = ajax.py2js(due_date, h) parent_title = self.emit_event(comp, events.ParentTitleNeeded) or '' card = u'{title:%s, editable:true, allDay: true, start: %s, _id: %s}' % ( ajax.py2js(u'{} ({})'.format(self.data.title, parent_title), h).decode('utf-8'), due_date, ajax.py2js(self.id, h)) clicked_cb = h.a.action(lambda: self.emit_event( comp, events.CardClicked, comp)).get('onclick') dropped_cb = h.a.action( ajax.Update(action=self.card_dropped, render=lambda render: '', with_request=True)).get('onclick')[:-2] h << h.script(u"""YAHOO.kansha.app.add_event($('#calendar'), %(card)s, function() { %(clicked_cb)s}, function(start) { %(dropped_cb)s&start="+start);} )""" % { 'card': card, 'clicked_cb': clicked_cb, 'dropped_cb': dropped_cb }) return h.root
def render_PendingUser_pending(self, h, comp, *args): """Render for search result""" with h.div(class_='member'): h << comp.render(h, None) with h.span(class_="actions"): with h.form: h << h.input( value=_("Resend invitation"), type="submit", class_="btn btn-primary").action( ajax.Update(action=lambda: comp.answer('resend'))) h << h.input( value=_("Remove"), type="submit", class_="btn btn-primary delete").action( ajax.Update(action=(lambda: comp.answer('remove')))) return h.root
def render_Checklists_button(self, h, comp, model): if security.has_permissions('checklist', self.card): action = ajax.Update(render=lambda r: comp.render(r, model=None), component_to_update='clist' + self.comp_id, action=self.add_checklist) with h.a(class_='btn').action(action): h << h.i(class_='icon-list') h << _('Checklist') return h.root
def render(self, h, *args): h.head.css_url('counter.css') with h.div(class_='counter'): h << h.div(self.v, id='value') with h.span: h << h.a(u'\N{MINUS SIGN}', title='decrease').action( ajax.Update(self.generate_response, self.decrease, 'value')) with h.span: h << h.a('=', class_='disabled') with h.span: h << h.a(u'\N{PLUS SIGN}', title='increase').action( ajax.Update(self.generate_response, self.increase, 'value')) return h.root
def render_User_manager(self, h, comp, model): """Render for search result""" with h.div(class_='member'): h << comp.render(h, None) with h.span(class_="actions"): with h.form: h << h.input( value=_("Manager"), type="submit", class_=("btn btn-primary toggle" if model == 'manager' else "btn btn-primary")).action( ajax.Update( action=lambda: comp.answer('toggle_role'))) h << h.input( value=_("Remove"), type="submit", class_="btn btn-primary delete").action( ajax.Update(action=lambda: comp.answer('remove'))) return h.root
def render(self, h, comp, *args): """Render the overlay""" link_id = h.generate_id() overlay_id = h.generate_id() body_id = h.generate_id('BODY_') self.render_a(h, link_id) # TODO: find a cleaner solution if self.dynamic: # Load overlay body dynamically load = ajax.js( "YAHOO.util.Dom.get(%(body_id)s).innerHTML = '';" "%(load_body)s" % { 'body_id': ajax.py2js(body_id), 'load_body': h.a.action( ajax.Update(render=self.content, component_to_update=body_id) ).get('onclick').replace('return', '') } ) else: # The overlay body is already present in the DOM tree load = ajax.js('') js = ajax.js( "%(load)s;" "YAHOO.kansha.app.showOverlay(%(overlay_id)s, %(link_id)s, %(centered)s)" % { 'load': ajax.py2js(load), 'link_id': ajax.py2js(link_id), 'overlay_id': ajax.py2js(overlay_id), 'centered': ajax.py2js(self.centered, h) } ) h.head.javascript( h.generate_id(), "YAHOO.util.Event.addListener(%(link_id)s, 'click', " "function(){%(js)s;}" ")" % {'link_id': ajax.py2js(link_id), "js": ajax.py2js(js)} ) cls = [u'overlay'] if self.cls: cls.append(self.cls) with h.div(class_=u' '.join(cls), id=overlay_id, onclick="YAHOO.kansha.app.stopEvent()"): if not self.centered: h << h.span(class_='overlay_arrow') with h.div(class_='overlay-header'): with h.div(class_='overlay-title'): h << h.div(self.title or self.text(h)) h << h.div(' ' if self.dynamic else self.content(h), class_='overlay-body', id=body_id) return h.root
def render_SaveTemplateEditor_loading(self, h, comp, *args): id_ = h.generate_id() with h.div(class_='loading', id_=id_): h << h.img(src='img/ajax-loader.gif') h << _(u'Please wait while board is saved...') update = ajax.Update(action=self.save, render='saved', component_to_update=id_) h << h.script(h.AsyncRenderer().a.action(update).get('onclick').replace( 'return ', '')) return h.root
def render_filter_menu(self, h, comp, *args): with h.ul(id='menu_popin', class_=self.filter_type): # First item reset previous filter action_1 = ajax.Update(action=lambda: self.cb_('reset')) action_2 = ajax.Update(action=self.reset_pager, component_to_update='infinite-pager', render=self.create_pager_comp.render) action_3 = ajax.Update( action=lambda: None, component_to_update='pager-counter', render=lambda h: self.pager.render(h, model='count')) h << h.li( h.a(_(u'All')).action(ajax.Updates(action_2, action_1, action_3))) for filter_ in self.filters: action_1 = ajax.Update( action=lambda filter_=filter_: self.cb_(filter_)) action_2 = ajax.Update(action=self.reset_pager, component_to_update='infinite-pager', render=self.create_pager_comp.render) action_3 = ajax.Update( action=lambda: None, component_to_update='pager-counter', render=lambda h: self.pager.render(h, model='count')) h << h.li( h.a(filter_.title).action( ajax.Updates(action_2, action_1, action_3))) action = h.a.action(self.cb_) js = r"""manage_menu_click(function(){%s})""" % action.get('onclick') h << h.script(js) return h.root
def render_Label_edit_color_overlay(self, h, comp, *args): """Color chooser contained in the overlay body""" v = var.Var(self.data.color) i = h.generate_id() h << h.div(id=i, class_='label-color-picker clearfix') with h.form: h << h.input(type='hidden', value=v(), id='%s-hex-value' % i).action(v) h << h.button(_('Save'), class_='btn btn-primary').action( ajax.Update(action=lambda v=v: self.set_color(v()))) h << ' ' h << h.button(_('Cancel'), class_='btn').action(lambda: None) h << h.script("YAHOO.kansha.app.addColorPicker(%s)" % ajax.py2js(i)) return h.root
def async_action(self, renderer, action, with_request): """Register an asynchronous action In: - ``renderer`` -- the current renderer - ``action`` -- action - ``with_request`` -- will the request and response objects be passed to the action? """ if not isinstance(action, ajax.Update): action = ajax.Update(action=action, with_request=with_request) self.set(self._actions[2], action.generate_action(self._actions[0], renderer))
def render_download(self, h, comp, *args): if security.has_permissions('edit', self): submit_id = h.generate_id("attach_submit") input_id = h.generate_id("attach_input") h << h.label((h.i(class_='icon-file'), _("Add file")), class_='btn', for_=input_id) with h.form: h << h.script( u''' function valueChanged(e) { if (YAHOO.kansha.app.checkFileSize(this, %(max_size)s)) { YAHOO.util.Dom.get(%(submit_id)s).click(); YAHOO.kansha.app.showModal('oip'); } else { alert(%(error)s); } } YAHOO.util.Event.onDOMReady(function() { YAHOO.util.Event.on(%(input_id)s, 'change', valueChanged); });''' % { 'max_size': ajax.py2js(self.assets_manager.max_size), 'input_id': ajax.py2js(input_id), 'submit_id': ajax.py2js(submit_id), 'error': ajax.py2js(_(u'Max file size exceeded')).decode('UTF-8') }) submit_action = ajax.Update( render=lambda r: r.div( comp.render(r, model=None), r.script('YAHOO.kansha.app.closeModal()')), component_to_update='gal' + self.comp_id, ) h << h.input( id=input_id, class_='hidden', type="file", name="file", multiple="multiple", maxlength="100", ).action(self.add_assets) h << h.input(class_='hidden', id=submit_id, type="submit").action(submit_action) return h.root
def render_history(self, h, *_args): h << h.h2(_('Action log')) board = self.board.data with h.select(onchange=ajax.Update(action=self.user_id)): h << h.option(_('all users'), value='') for member in board.members: h << h.option(member.fullname, value=member.username).selected( self.user_id()) with h.select(onchange=ajax.Update(action=lambda x: self.card_id(int(x)))): h << h.option(_('all cards'), value=0) for col in board.columns: for card in col.cards: h << h.option(card.title, value=card.id).selected( self.card_id()) with h.div(class_='history'): with h.table(class_='table table-striped table-hover'): with h.body: for event in get_history(board, cardid=self.card_id(), username=self.user_id()): with h.tr: h << h.th(format_datetime(event.when, 'short')) h << h.td(render_event(event)) return h.root
def render_column_header(self, h, comp, *args): with h.div(class_='list-header', id=self.id + '_header'): h << h.a(class_='hidden', id=self.id + '_refresh').action( ajax.Update()) with h.div(class_='list-title'): with h.div(class_='title'): h << self.title.render( h.AsyncRenderer(), 0 if security.has_permissions( 'edit', self) and not self.is_archive else 'readonly') h << self.card_counter.render(h, 'header') with h.div(class_='list-actions with-dropdown'): if security.has_permissions('edit', self): h << h.a(h.i(class_='icon-dot-menu'), href='#', class_="toggle-dropdown", onclick="YAHOO.kansha.app.toggleMenu(this)") << ' ' h << comp.render(h, 'dropdown') return h.root
def render_userboards(self, h, comp, *args): h.head << h.head.title(self.app_title) h.head.css_url('css/themes/home.css') h.head.css_url('css/themes/%s/home.css' % self.theme) if self.last_modified_boards: h << h.h1(_(u'Last modified boards')) with h.ul(class_="board-labels"): h << [b.on_answer(comp.answer).render(h, "item") for b in self.last_modified_boards.itervalues()] h << h.h1(_(u'My boards')) with h.ul(class_="board-labels"): h << [b.on_answer(comp.answer).render(h, "item") for b in self.my_boards.itervalues()] if self.guest_boards: h << h.h1(_(u'Guest boards')) with h.ul(class_="board-labels"): h << [b.on_answer(comp.answer).render(h, "item") for b in self.guest_boards.itervalues()] with h.div: h << self.new_board.on_answer(lambda ret: self.reload_boards()) if len(self.archived_boards): h << h.h1(_('Archived boards')) with h.ul(class_="board-labels"): h << [b.render(h, "archived_item") for b in self.archived_boards.itervalues()] h << h.button( _("Delete"), class_="delete", onclick='return confirm(%s)' % ajax.py2js( _("These boards will be destroyed. Are you sure?") ).decode('UTF-8'), type='submit' ).action(self.purge_archived_boards) h << h.script('YAHOO.kansha.app.hideOverlay();' 'function reload_boards() { %s; }' % h.AsyncRenderer().a.action(ajax.Update(action=self.reload_boards, render=0)).get('onclick')) return h.root
def render(self, h, comp, *args): card = ajax.py2js(self, h) if card: clicked_cb = h.a.action(lambda: comp.answer(comp)).get('onclick') dropped_cb = h.a.action( ajax.Update(action=self.new_start_from_ajax, render=lambda render: '', with_request=True)).get('onclick')[:-2] h << h.script(u"""YAHOO.kansha.app.add_event($('#calendar'), %(card)s, function() { %(clicked_cb)s}, function(start) { %(dropped_cb)s&start="+start);} )""" % { 'card': card, 'clicked_cb': clicked_cb, 'dropped_cb': dropped_cb }) return h.root
def ViewsToJs(r): # On ajoute les rendus des composants tiers # au moment ou la requête est soumise # On supprime la mise à jour du composant lui même # au cas où son rendu ne serait pas nécessaire # (cas d'un composant mettantà jour son père) if not self._update_himself: renders.pop() for kd in self._le_l_knowndiv(): def le_render(r, kd): return kd.component.render(r) renders.append( ajax.Update(lambda r, kd=kd: le_render(r, kd), lambda: None, kd.id)._generate_render(r)) return ajax.ViewsToJs([render(r) for render in renders])
def render_Checklist(self, h, comp, model): with h.div(id='checklist_%s' % self.id, class_='checklist'): with h.div(class_='title'): h << h.i(class_='icon-list ' + (model or '')) if model == 'read-only': h << self.data.title else: h << self.title.render(h.AsyncRenderer()) onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action( ajax.Update(render='', action=comp.answer) ).get('onclick'), 'message': ajax.py2js( _(u'The checklist will be deleted. Are you sure?') ).decode('UTF-8') } ) h << h.a(h.i(class_='icon-cross'), class_='delete', onclick=onclick) with h.div(class_='content'): if self.items: h << comp.render(h, 'progress') with h.ul: not_alone = len(self.items) > 1 for index, item in enumerate(self.items): if model == 'read-only': h << h.li(item.render(h, 'read-only')) else: h << h.li( item.on_answer( lambda v, index=index: self.delete_index(index) ).render(h, model='not-alone' if not_alone else None), id='checklist_item_%s' % item().id, class_='checklist-item') if model != 'read-only': h << self.new_item return h.root
def render_ChecklistItem(self, h, comp, model): with h.a().action(self.set_done): help_msg = _(u'Click to toggle') h << {'title': help_msg} with h.i: check_class = 'icon-checkbox-' + ('checked' if self.done else 'unchecked') h << {'class': check_class} h << h.span(self.title.render(h.AsyncRenderer()), class_='title ' + ('done' if self.done else '')) onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action( ajax.Update(render='', action=lambda: comp.answer('delete')) ).get('onclick'), 'message': ajax.py2js( _(u'The checklist item will be deleted. Are you sure?') ).decode('UTF-8') } ) h << h.a(h.i(class_='icon-cross'), class_='delete-item', onclick=onclick) if model == 'not-alone': h << h.i(class_='icon-menu2 not-alone', title=_(u'Drag to re-order')) return h.root
def render(self, h, comp, *args): """Render the card""" card_id = h.generate_id() onclick = h.a.action(lambda: comp.answer(comp)).get('onclick').replace( 'return', "") if self.column.board.card_matches: c_class = 'card highlight' if self.id in self.column.board.card_matches else 'card hidden' else: c_class = 'card' with h.div(id=self.id, class_=c_class): h << { 'onmouseover': "YAHOO.kansha.app.highlight(this, 'badges', false);YAHOO.kansha.app.highlight(this, 'members', false);", 'onmouseout': "YAHOO.kansha.app.highlight(this, 'badges', true);YAHOO.kansha.app.highlight(this, 'members', true);" } with h.div(id=card_id, onclick=onclick): h << self.labels h << self.title.render(h, 'card-title') if self.has_cover(): h << h.p(component.Component(self.get_cover(), model='cover'), class_='cover') h << comp.render(h, 'badges') if security.has_permissions('edit', self): h << comp.render(h, 'members') else: h << comp.render(h, 'members_read_only') h << h.script( "YAHOO.kansha.reload_cards[%s]=function() {%s}" "" % (ajax.py2js(self.id), h.a.action(ajax.Update()).get('onclick'))) if self.must_reload_search: self.reload_search() h << h.script('''$(window).trigger('reload_search');''') return h.root
def render(self, h, comp, *args): """Render the card""" extensions = self.extensions card_id = h.generate_id() onclick = h.a.action(self.emit_event, comp, events.CardClicked, comp).get('onclick').replace('return', "") with h.div(id=self.id, class_='card ' + self.card_filter(self)): with h.div(id=card_id, onclick=onclick): with h.div(class_='headers'): h << [ extension.render(h, 'header') for _name, extension in extensions ] with h.div(class_='covers'): with h.div(class_='title'): h << self.title.render(h, 'readonly') h << [ extension.render(h, 'cover') for _name, extension in extensions ] with h.div(class_='badges'): h << [ extension.render(h, 'badge') for _name, extension in extensions ] if self.card_filter(self): h << component.Component(self.card_filter) h << h.script( "YAHOO.kansha.reload_cards[%s]=function() {%s}" "" % (ajax.py2js(self.id), h.a.action(ajax.Update()).get('onclick'))) return h.root
def render_userboards(self, h, comp, *args): template = var.Var(u'') h.head << h.head.title(self.app_title) h.head.css_url('css/themes/home.css?v=2c') h.head.css_url('css/themes/%s/home.css?v=2c' % self.theme) default_template_i18n = { 'Empty board': _(u'Empty board'), 'Basic Kanban': _(u'Basic Kanban') } with h.div(class_='new-board'): with h.form: h << h.SyncRenderer().button( _(u'Create'), type='submit', class_='btn btn-primary').action( lambda: self.create_board(template(), comp)) h << (u' ', _(u'a new'), u' ') if len(self.templates) > 1: with h.select.action(template): with h.optgroup(label=_(u'Shared templates')): h << [ h.option(default_template_i18n.get(tpl, tpl), value=id_) for id_, tpl in self.templates['public'] ] if self.templates['private']: with h.optgroup(label=_(u'My templates')): h << [ h.option(_(tpl), value=id_) for id_, tpl in self.templates['private'] ] else: id_, tpl = self.templates.items()[0] template(id_) h << tpl if self.last_modified_boards: h << h.h1(_(u'Last modified boards')) with h.ul(class_='board-labels'): h << [ b.on_answer(self.handle_event).render(h, 'item') for b in self.last_modified_boards ] h << h.h1(_(u'My boards')) if self.my_boards: with h.ul(class_='board-labels'): h << [ b.on_answer(self.handle_event).render(h, 'item') for b in self.my_boards ] else: h << h.p( _(u'test a board by choosing a template in the menu above, then click on the "Create" button.' )) if self.guest_boards: h << h.h1(_(u'Guest boards')) with h.ul(class_='board-labels'): h << [ b.on_answer(self.handle_event).render(h, 'item') for b in self.guest_boards ] if self.shared_boards: h << h.h1(_(u'Shared boards')) with h.ul(class_='board-labels'): h << [ b.on_answer(self.handle_event).render(h, 'item') for b in self.shared_boards ] if len(self.archived_boards): h << h.h1(_('Archived boards')) with h.ul(class_='board-labels'): h << [ b.on_answer(self.handle_event).render(h, 'archived_item') for b in self.archived_boards ] with h.form: h << h.SyncRenderer().button( _('Delete the archived board') if len(self.archived_boards) == 1 else _('Delete the archived boards'), class_='delete', onclick='return confirm(%s)' % ajax.py2js( _('Deleted boards cannot be restored. Are you sure?') ).decode('UTF-8'), type='submit').action(self.purge_archived_boards) h << h.script( 'YAHOO.kansha.app.hideOverlay();' 'function reload_boards() { %s; }' % h.AsyncRenderer().a.action( ajax.Update(action=self.load_user_boards, render=0)).get('onclick')) return h.root