def render_CardsCounter_edit(self, h, comp, *args): """Render the title of the associated object""" text = var.Var(self.text) with h.div(class_='list-counter'): with h.div(class_='cardCounter'): with h.form(onsubmit='return false;'): action = h.input(type='submit').action(lambda: self.validate(text(), comp)).get('onclick') id_ = h.generate_id() h << h.input(id=id_, type='text', value=self.column.nb_max_cards or '', onblur=action).action(text) h << h.script( """YAHOO.util.Event.on(%s, 'keyup', function (e) { if (e.keyCode == 13) { e.preventDefault(); this.blur(); } var result = this.value.replace(/[^0-9]/g, '') if (this.value !=result) { this.value = result; } });""" % ajax.py2js(id_) ) h << h.script( "YAHOO.kansha.app.selectElement(%s);" % ajax.py2js(id_) ) if self.error is not None: with h.div(class_='nagare-error-message'): h << self.error return h.root
def render_CardsCounter_edit(self, h, comp, *args): """Render the title of the associated object""" text = var.Var(self.text) with h.form(class_='title-form'): id_ = h.generate_id() h << h.input(id=id_, type='text', value=self.column.nb_max_cards or '').action(text) h << h.script( """YAHOO.util.Event.on(%s, 'keyup', function (e) { var result =this.value.replace(/[^0-9]/g, '') if (this.value !=result) { this.value = result; } });""" % ajax.py2js(id_) ) h << h.button(_('Save'), class_='btn btn-primary btn-small').action( lambda: self.validate(text(), comp)) h << ' ' h << h.button(_('Cancel'), class_='btn btn-small').action(self.cancel, comp) if self.error is not None: with h.div(class_='nagare-error-message'): h << self.error h << h.script( "YAHOO.kansha.app.selectElement(%s);" "YAHOO.kansha.app.hideOverlay()" % ajax.py2js(id_) ) return h.root
def render_BoardDescription(self, h, comp, *args): """Render description component in edit mode""" text = var.Var(self.text) with h.form(class_='description-form'): txt_id, btn_id = h.generate_id(), h.generate_id() h << h.label(_(u'Description'), for_=txt_id) ta = h.textarea(text(), id_=txt_id).action(text) if not security.has_permissions('edit', self): ta(disabled='disabled') h << ta with h.div: if security.has_permissions('edit', self): h << h.button(_('Save'), class_='btn btn-primary btn-small', id=btn_id).action(remote.Action(lambda: self.change_text(text()))) h << ' ' h << h.button( _('Cancel'), class_='btn btn-small').action(remote.Action(lambda: self.change_text(None))) h.head.javascript( h.generate_id(), 'YAHOO.kansha.app.addCtrlEnterHandler(%s, %s)' % ( ajax.py2js(txt_id), ajax.py2js(btn_id) ) ) return h.root
def render(self, h, comp, *args): """Render the column""" # Add answer on delete overlay component self.actions_comp.on_answer( lambda data, comp=comp: self.actions(data, comp)) column_class = 'span-auto list' if self.is_archive: column_class += ' archive' with h.div( class_=column_class, id=self.id, ): with h.div(class_='list-header', id=self.id + '_header'): with h.div(class_='list-title', id=self.id + '_title'): h << comp.render(h.AsyncRenderer(), 'header') with h.div(class_='list-actions hidden'): if security.has_permissions('edit', self): h << self.actions_overlay h << comp.render(h.AsyncRenderer(), 'body') h << h.script( "YAHOO.kansha.app.saveLimit(%(list_id)s, %(limit)s);" % { 'list_id': ajax.py2js(self.id), 'limit': ajax.py2js(self.nb_max_cards or 0) }) return h.root
def render_comments_form(self, h, comp, *args): """Add a comment to the current card""" if security.has_permissions('comment', self): text = var.Var() with h.form: txt_id, buttons_id = h.generate_id(), h.generate_id() sub_id = h.generate_id() kw = { "id": txt_id, "placeholder": _("Add comment."), "onfocus": "YAHOO.kansha.app.show('%s', true);YAHOO.util.Dom.addClass(this, 'expanded'); " % buttons_id, } h << h.textarea(**kw).action(text) h.head.javascript( h.generate_id(), 'YAHOO.kansha.app.addCtrlEnterHandler(%s, %s)' % ( ajax.py2js(txt_id), ajax.py2js(sub_id) ) ) with h.div(id=buttons_id, class_="buttons hidden"): h << h.input(value=_("Save"), id=sub_id, type='submit', class_="btn btn-primary").action(lambda: comp.answer(text())) h << ' ' h << h.input(value=_("Cancel"), type='submit', class_="btn").action(lambda: comp.answer('')) return h.root
def py2js(value, h): due_date = ajax.py2js(value.due_date(), h) if due_date: return u'{title:%s, editable:true, allDay: true, start: %s}' % ( ajax.py2js(value.get_title(), h).decode('utf-8'), due_date) else: return None
def render_column_overlay(self, h, comp, *args): """Render the column menu""" with h.ul(class_='nav nav-list'): if not self.is_archive: with h.li: onclick = (u"if (confirm(%(message)s)){" u" YAHOO.kansha.app.hideOverlay();" u" %(callback)s" u"}" % { 'message': ajax.py2js( _(u'The list will be deleted. Are you sure?' )).decode('UTF-8'), 'callback': h.a.action(comp.answer, 'delete').get('onclick') }) h << h.a(_(u'Delete this list'), onclick=onclick) h << h.li(h.a(_('Set cards limit')).action(comp.answer, 'set_limit'), id=self.id + '_counter_option') else: with h.li: onclick = "if (confirm(%(message)s)){%(purge_func)s;}" % { 'message': ajax.py2js(_(u'All cards will be deleted. Are you sure?')). decode('UTF-8'), 'purge_func': h.a.action(comp.answer, 'purge').get('onclick') } h << h.a(_('Purge the cards'), onclick=onclick) return h.root
def render_Board_menu(self, h, comp, *args): with h.div(class_='nav-menu', onclick='YAHOO.kansha.app.toggleMainMenu(this)'): with h.ul(class_='actions large'): h << h.li( h.a(self.icons['preferences']).action(self.show_preferences)) if security.has_permissions('edit', self): h << h.li(h.a(self.icons['add_list']).action(self.add_list)) h << h.li( h.a(self.icons['edit_desc']).action(self.edit_description)) if security.has_permissions('manage', self): h << h.li( h.a(self.icons['save_template']).action( self.save_template, comp)) h << h.li(h.SyncRenderer().a(self.icons['export']).action( self.export)) h << h.li(h.a(self.icons['history']).action(self.show_actionlog)) if security.has_permissions('manage', self): h << h.li(h.SyncRenderer().a( self.icons['archive'], onclick=('return confirm(%s)' % ajax.py2js( _("This board will be archived. Are you sure?")). decode('UTF-8'))).action(self.archive, comp)) else: h << h.li(h.SyncRenderer().a( self.icons['leave'], onclick=("return confirm(%s)" % ajax.py2js( _("You won't be able to access this board anymore. Are you sure you want to leave it anyway?" )).decode('UTF-8'))).action(self.leave, comp)) h << h.span(_(u'Board'), class_="menu-title", id='board-nav-menu') h << self.modal return h.root
def render_AddMembers(self, h, comp, *args): value = var.Var('') submit_id = h.generate_id('form') hidden_id = h.generate_id('hidden') with h.form: h << h.input(type='text', id=self.text_id) h << h.input(type='hidden', id=hidden_id).action(value) h << self.autocomplete h << h.script( u"%(ac_id)s.itemSelectEvent.subscribe(function(sType, aArgs) {" u"var value = aArgs[2][0];" u"YAHOO.util.Dom.setAttribute(%(hidden_id)s, 'value', value);" u"YAHOO.util.Dom.get(%(submit_id)s).click();" u"});" % { 'ac_id': self.autocomplete().var, 'hidden_id': ajax.py2js(hidden_id), 'submit_id': ajax.py2js(submit_id) } ) h << h.script( "document.getElementById(%s).focus()" % ajax.py2js(self.text_id) ) h << h.button(id=submit_id, style='display:none').action(remote.Action(lambda: comp.answer([] if not value() else [value()]))) return h.root
def render_AddMembers(self, h, comp, *args): value = var.Var('') submit_id = h.generate_id('form') hidden_id = h.generate_id('hidden') with h.form: h << h.input(type='text', id=self.text_id) h << h.input(type='hidden', id=hidden_id).action(value) h << self.autocomplete h << h.script( u"%(ac_id)s.itemSelectEvent.subscribe(function(sType, aArgs) {" u"var value = aArgs[2][0];" u"YAHOO.util.Dom.setAttribute(%(hidden_id)s, 'value', value);" u"YAHOO.util.Dom.get(%(submit_id)s).click();" u"});" % { 'ac_id': self.autocomplete().var, 'hidden_id': ajax.py2js(hidden_id), 'submit_id': ajax.py2js(submit_id) }) h << h.script( "document.getElementById(%s).focus()" % ajax.py2js(self.text_id)) h << h.button(id=submit_id, style='display:none').action( remote.Action(lambda: comp.answer([] if not value() else [value()]))) return h.root
def render_Board_menu(self, h, comp, *args): with h.div(class_='navbar', id='boardNavbar'): with h.div(class_='navActions', id='boardActions'): h << h.a(self.icons['preferences']).action(lambda: self.popin.call( popin.Popin(component.Component(BoardConfig(self)), "edit"))) if security.has_permissions('edit', self): h << self.add_list_overlay h << self.edit_description_overlay h << h.a(self.icons['export']).action(self.export) h << h.a(self.icons['history']).action(lambda: self.popin.call( popin.Popin(component.Component(notifications.ActionLog(self)), 'history'))) if security.has_permissions('manage', self): h << h.a(self.icons['archive'], onclick=('return confirm(%s)' % ajax.py2js( _("This board will be archived. Are you sure?")). decode('UTF-8'))).action(self.archive_board) else: h << h.a( self.icons['leave'], onclick=("return confirm(%s)" % ajax.py2js( _("You won't be able to access this board anymore. Are you sure you want to leave it anyway?" )).decode('UTF-8'))).action(self.leave) kw = {'onclick': "YAHOO.kansha.app.toggleMenu('boardNavbar')"} with h.div(class_="tab collapse", **kw): h << h.a('Board', title='Board', id="boardTab") 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_card_delete(self, h, comp, model): if security.has_permissions('edit', self) and not self.archived: with h.form: close_func = ajax.js( 'function (){%s;}' % h.a.action(self.emit_event, comp, events.CardArchived).get('onclick') ) h << h.button( h.i(class_='icon-trashcan'), _('Delete'), class_='btn delete', onclick=( "if (confirm(%(confirm_msg)s)) {" " YAHOO.kansha.app.archiveCard(%(close_func)s);" " reload_columns();" "}" "return false" % { 'close_func': ajax.py2js(close_func), 'confirm_msg': ajax.py2js( _(u'This card will be deleted. Are you sure?') ).decode('UTF-8') } ) ) return h.root
def render_autocomplete(self, h, comp, *args): static_url = h.head.static_url def get_results(query): raise json_response(self._completion_results(query, static_url)) h << h.script( 'var %(var)s = YAHOO.kansha.autocomplete.init(%(field_id)s,' ' %(completion_url)s, %(delimiter)s, %(min_query_length)s, ' '%(max_results_displayed)s)' % { 'var': self.var, 'field_id': ajax.py2js(self.field_id), 'completion_url': ajax.py2js( h.add_sessionid_in_url( params=( '_a', '%s=' % h.register_callback(1, get_results, False) ) ) ), 'delimiter': ajax.py2js(self.delimiter), 'min_query_length': self.min_query_length, 'max_results_displayed': self.max_results_displayed, } ) 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_board_background_edit(self, h, comp, *args): """Render the background configuration panel""" h << h.div(_(u'Background image'), class_='panel-section') with h.div(class_='row-fluid'): with h.div(class_='span6'): def set_background(img): self.board.set_background_image(img) self._changed(True) v_file = var.Var() submit_id = h.generate_id("attach_submit") input_id = h.generate_id("attach_input") h << h.label((h.i(class_='icon-file icon-grey'), _("Choose an image")), class_='btn btn-small', 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(); } else { alert(%(error)s); } } YAHOO.util.Event.onDOMReady(function() { YAHOO.util.Event.on(%(input_id)s, 'change', valueChanged); });''' % { 'max_size': ajax.py2js(self.board.background_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') } ) h << h.input(id=input_id, style="position:absolute;left:-1000px;", type="file", name="file", multiple="multiple", maxlength="100",).action(v_file) h << h.input(style="position:absolute;left:-1000px;", id=submit_id, type="submit").action( lambda: set_background(v_file())) with h.div(class_='span5'): def reset_background(): self.board.set_background_image(None) self._changed(True) h << _('or') << ' ' h << h.a(_('Reset background')).action(reset_background) with h.div(class_='row-fluid'): with h.span(class_='span12 text-center'): h << component.Component(self.board, model='background_image') h << h.div(_(u'Board title color'), class_='panel-section') with h.div(class_='row-fluid'): with h.div(class_='span6'): h << comp.render(h, model='title-color-edit') with h.div(class_='span5'): def reset_color(): self.board.set_title_color(None) self._changed(True) h << _('or') << ' ' h << h.a(_('Reset to default color')).action(reset_color) return h.root
def render_CardsCounter_edit(self, h, comp, *args): """Render the title of the associated object""" text = var.Var(self.text) with h.div(class_='list-counter'): with h.div(class_='cardCounter'): with h.form(onsubmit='return false;'): action = h.input(type='submit').action( lambda: self.validate(text(), comp)).get('onclick') id_ = h.generate_id() h << h.input(id=id_, type='text', value=self.column.nb_max_cards or '', onblur=action).action(text) h << h.script( """YAHOO.util.Event.on(%s, 'keyup', function (e) { if (e.keyCode == 13) { e.preventDefault(); this.blur(); } var result = this.value.replace(/[^0-9]/g, '') if (this.value !=result) { this.value = result; } });""" % ajax.py2js(id_)) h << h.script( "YAHOO.kansha.app.selectElement(%s);" % ajax.py2js(id_)) if self.error is not None: with h.div(class_='nagare-error-message'): h << self.error return h.root
def render_gallery_cropper(self, h, comp, *args): h << h.p(_('Use the controls below to create the cover of your card.')) form_id = h.generate_id() img_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(self.crop_width()), ajax.py2js(self.crop_height()))) with h.div(class_='buttons'): h << h.button(_('Create cover'), class_='btn btn-primary').action( self.commit, comp) if self.asset.is_cover: h << ' ' h << h.button(_('Remove cover'), class_='btn delete').action( self.remove_cover, comp) h << ' ' h << h.button(_('Cancel'), class_='btn').action(self.cancel, comp) return h.root
def render_autocomplete(self, h, comp, *args): static_url = h.head.static_url def get_results(query): raise json_response(self._completion_results(query, static_url)) h << h.script( 'var %(var)s = YAHOO.kansha.autocomplete.init(%(field_id)s,' ' %(completion_url)s, %(delimiter)s, %(min_query_length)s, ' '%(max_results_displayed)s)' % { 'var': self.var, 'field_id': ajax.py2js(self.field_id), 'completion_url': ajax.py2js( h.add_sessionid_in_url( params=('_a', '%s=' % h.register_callback(1, get_results, False)))), 'delimiter': ajax.py2js(self.delimiter), 'min_query_length': self.min_query_length, 'max_results_displayed': self.max_results_displayed, }) 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_gallery_cropper(self, h, comp, *args): h << h.p(_('Use the controls below to create the cover of your card.')) form_id = h.generate_id() img_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(self.crop_width()), ajax.py2js(self.crop_height()) ) ) with h.div(class_='buttons'): h << h.button(_('Create cover'), class_='btn btn-primary').action(self.commit, comp) if self.asset.is_cover: h << ' ' h << h.button(_('Remove cover'), class_='btn delete').action(self.remove_cover, comp) h << ' ' h << h.button(_('Cancel'), class_='btn').action(self.cancel, comp) return h.root
def py2js(card, h): due_date = dict(card.extensions)['due_date']().due_date if not due_date: return None due_date = ajax.py2js(due_date, h) return u'{title:%s, editable:true, allDay: true, start: %s}' % (ajax.py2js( card.get_title(), h).decode('utf-8'), due_date)
def py2js(card, h): due_date = dict(card.extensions)['due_date']().due_date if not due_date: return None due_date = ajax.py2js(due_date, h) return u'{title:%s, editable:true, allDay: true, start: %s}' % ( ajax.py2js(card.get_title(), h).decode('utf-8'), due_date)
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_Board_menu(self, h, comp, *args): with h.div(class_='navbar', id='boardNavbar'): with h.div(class_='navActions', id='boardActions'): h << h.a(self.icons['preferences']).action( lambda: self.popin.call( popin.Popin( component.Component( BoardConfig(self) ), "edit" ) ) ) if security.has_permissions('edit', self): h << self.add_list_overlay h << self.edit_description_overlay h << h.a(self.icons['export']).action(self.export) h << h.a(self.icons['history']).action( lambda: self.popin.call( popin.Popin( component.Component( notifications.ActionLog(self) ), 'history' ) ) ) if security.has_permissions('manage', self): h << h.a( self.icons['archive'], onclick=( 'return confirm(%s)' % ajax.py2js( _("This board will be archived. Are you sure?") ).decode('UTF-8') ) ).action(self.archive_board) else: h << h.a( self.icons['leave'], onclick=( "return confirm(%s)" % ajax.py2js( _("You won't be able to access this board anymore. Are you sure you want to leave it anyway?") ).decode('UTF-8') ) ).action(self.leave) kw = {'onclick': "YAHOO.kansha.app.toggleMenu('boardNavbar')"} with h.div(class_="tab collapse", **kw): h << h.a('Board', title='Board', id="boardTab") return h.root
def render_CardsCounter(self, h, comp, *args): with h.div(class_='list-counter'): self.error = None with h.div(class_='cardCounter', id=self.id): h << {'style': 'cursor: default'} h << h.span(self.text) h << h.script( "YAHOO.kansha.app.saveLimit(%(list_id)s, %(limit)s);" "YAHOO.kansha.app.countCards(%(list_id)s);" % { 'list_id': ajax.py2js(self.column.id), 'limit': ajax.py2js(self.column.nb_max_cards or 0) }) return h.root
def render_card_actions(self, h, comp, *args): with h.div(class_='card-actions'): with h.form: with h.ul(): with h.li(class_="buttonAddChecklist"): h << self.checklists.render(h, 'button') with h.li(class_="buttonAddFile"): h << self.gallery.render(h, 'download') with h.li(class_="buttonVote"): h << self.votes.render(h.AsyncRenderer(), 'edit') with h.li(class_="buttonDueDate"): h << self.due_date.render(h.AsyncRenderer(), 'button') if self.board.weighting_cards: with h.li(class_="actionWeight"): h << self._weight.on_answer( lambda v: self._weight.call(model='edit_weight' if v else None)) with h.li(class_="buttonDeleteCard"): if security.has_permissions( 'edit', self) and not self.column.is_archive: close_func = ajax.js( 'function (){%s;}' % h.a.action(comp.answer, 'delete').get('onclick')) h << h.button( h.i(class_='icon-bin'), _('Delete'), class_='btn delete', onclick= ("if (confirm(%(confirm_msg)s)) {" " YAHOO.kansha.app.archiveCard(%(close_func)s, %(id)s, %(col_id)s, %(archive_col_id)s);" " reload_columns();" "}" "return false" % { 'close_func': ajax.py2js(close_func), 'id': ajax.py2js(self.id), 'col_id': ajax.py2js(self.column.id), 'archive_col_id': ajax.py2js( self.column.board.archive_column.id), 'confirm_msg': ajax.py2js( _(u'This card will be deleted. Are you sure?' )).decode('UTF-8') })) h << comp.render(h, 'members') 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_column_dropdown(self, h, comp, *args): """Render the column menu""" with h.div(class_="dropdown menu"): with h.ul: if not self.is_archive: with h.li: onclick = ( u"if (confirm(%(message)s)){" u" window.location='%(callback)s';" u"}" % { 'message': ajax.py2js( _(u'The list will be deleted. Are you sure?') ).decode('UTF-8'), 'callback': h.SyncRenderer().a.action( self.actions, 'delete', comp ).get('href') } ) h << h.a(_(u'Delete this list'), onclick=onclick) if self.cards: with h.li: onclick = ( u"if (confirm(%(message)s)){" u" window.location='%(callback)s';" u"}" % { 'message': ajax.py2js( _(u'All the cards will be archived. Are you sure?') ).decode('UTF-8'), 'callback': h.SyncRenderer().a.action( self.actions, 'empty', comp ).get('href') } ) h << h.a(_(u'Empty this list'), onclick=onclick) h << self.card_counter.render(h, 'menu-entry') elif self.cards: with h.li: onclick = "if (confirm(%(message)s)){window.location='%(purge_func)s';}" % { 'message': ajax.py2js( _(u'All cards will be deleted. Are you sure?') ).decode('UTF-8'), 'purge_func': h.SyncRenderer().a.action( self.actions, 'purge', comp ).get('href') } h << h.a(_('Purge the cards'), onclick=onclick) return h.root
def render_column_dropdown(self, h, comp, *args): """Render the column menu""" with h.div(class_="dropdown menu"): with h.ul: if not self.is_archive: with h.li: onclick = ( u"if (confirm(%(message)s)){" u" window.location='%(callback)s';" u"}" % { 'message': ajax.py2js( _(u'The list will be deleted. Are you sure?')). decode('UTF-8'), 'callback': h.SyncRenderer().a.action(self.actions, 'delete', comp).get('href') }) h << h.a(_(u'Delete this list'), onclick=onclick) if self.cards: with h.li: onclick = ( u"if (confirm(%(message)s)){" u" window.location='%(callback)s';" u"}" % { 'message': ajax.py2js( _(u'All the cards will be archived. Are you sure?' )).decode('UTF-8'), 'callback': h.SyncRenderer().a.action( self.actions, 'empty', comp).get('href') }) h << h.a(_(u'Empty this list'), onclick=onclick) h << self.card_counter.render(h, 'menu-entry') elif self.cards: with h.li: onclick = "if (confirm(%(message)s)){window.location='%(purge_func)s';}" % { 'message': ajax.py2js( _(u'All cards will be deleted. Are you sure?')). decode('UTF-8'), 'purge_func': h.SyncRenderer().a.action(self.actions, 'purge', comp).get('href') } h << h.a(_('Purge the cards'), onclick=onclick) return h.root
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_CardsCounter(self, h, comp, *args): with h.div(class_='list-counter'): self.error = None with h.div(class_='cardCounter', id=self.id): h << {'style': 'cursor: default'} h << h.span(self.text) h << h.script( "YAHOO.kansha.app.saveLimit(%(list_id)s, %(limit)s);" "YAHOO.kansha.app.countCards(%(list_id)s);" % { 'list_id': ajax.py2js(self.column.id), 'limit': ajax.py2js(self.column.nb_max_cards or 0) } ) return h.root
def render(self, h, *args): if h.request.environ['wsgi.multiprocess']: apps = [] else: apps = sorted([app.name for app in self.get_applications() if app.last_exception]) with h.div: h << h.div(h.a('Reload', href='#', onclick='return nagare_getAndEval("reload")'), style='text-align: center', class_='tab_info') with h.div(id='treeview'): with h.ul: # Display the packages sources h << component.Component(Directories(self.projects, self.allow_extensions)) # Display the exception labels for name in apps: with h.li('Application ', name): with h.ul: h << h.li('Exception', yuiConfig='{ "labelStyle" : "ygtvlabel exception", "uid" : "exception@%s" }' % name) h << h.div(id='exceptions', syle='display: none ') h << h.script(''' var treeview = setup_tree_view("treeview"); exceptions_tabs(%s); // Open the exceptions tabs ''' % ajax.py2js(apps, h)) return h.root
def render_comment(self, h, comp, model, *args): with h.div(class_='comment'): with h.div(class_='left'): h << self.author.render(h, model='avatar') with h.div(class_='right'): h << self.author.render(h, model='fullname') h << ' ' << _('wrote') << ' ' h << h.span(_(u'on'), ' ', format_datetime(self.creation_date), class_="date") if security.has_permissions('delete_comment', self): onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action(comp.answer, comp).get('onclick'), 'message': ajax.py2js( _(u'Your comment will be deleted. Are you sure?')). decode('UTF-8') }) h << h.a(h.i(class_='icon-cross'), title=_('Delete'), class_="comment-delete", onclick=onclick, href='') h << self.comment_label.render(h.AsyncRenderer()) return h.root
def render_userboards(self, h, comp, *args): h.head << h.head.title(self.app_title) with h.ul(class_="unstyled board-labels"): h << [b.on_answer(comp.answer).render(h, "item") for b in self.boards] with h.div: h << self.new_board.on_answer(comp.answer) if len(self.archived_boards): with h.div: h << h.h2(_('Archived Boards')) with h.ul(class_="unstyled board-labels"): h << [b.render(h, "archived_item") for b in self.archived_boards] h << h.a( _("Delete"), class_="btn btn-primary btn-small", onclick='return confirm(%s)' % ajax.py2js( _("These boards will be destroyed. Are you sure?") ).decode('UTF-8'), type='submit' ).action(self.purge_archived_boards) return h.root
def render_NewMember(self, h, comp, *args): """Render the title of the associated card""" with h.form: members_to_add = var.Var() def get_emails(): emails = [] for email in members_to_add().split(','): try: email = email.strip() email = validators.validate_email(email) emails.append(email) except ValueError: continue return emails h << h.input(type='text', id=self.text_id,).action(members_to_add) h << h.input(value=_("Add"), type="submit", class_="btn btn-primary btn-small" ).action(remote.Action(lambda: comp.answer(get_emails()))) h << self.autocomplete h << h.script( "document.getElementById(%s).focus()" % ajax.py2js(self.text_id) ) 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(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') ) ) return h.root
def render_comment(self, h, comp, model, *args): with h.div(class_='comment'): with h.div(class_='left'): h << self.author.render(h, model='avatar') with h.div(class_='right'): h << self.author.render(h, model='fullname') h << ' ' << _('wrote') << ' ' h << h.span( _(u'on'), ' ', format_datetime(self.creation_date), class_="date") if security.has_permissions('delete_comment', self): onclick = ( u"if (confirm(%(message)s)){%(action)s;}return false" % { 'action': h.a.action( comp.answer, comp ).get('onclick'), 'message': ajax.py2js( _(u'Your comment will be deleted. Are you sure?') ).decode('UTF-8') } ) h << h.a(h.i(class_='icon-cross'), title=_('Delete'), class_="comment-delete", onclick=onclick, href='') h << self.comment_label.render(h.AsyncRenderer()) return h.root
def render(self, h, *args): h.head.css( 'nagare_chat', ''' #msgs { list-style-type: none; border: 1px dashed #f3f2f1; padding: 5px; } #msgs li:nth-child(odd) { background-color: #f3f2f1; } .msg_type_j { color: red } .msg_type_p { color: blue } ''') # Inclusion of the translated ``append_msg`` function h.head << h.head.script(ajax.py2js(append_msg, h)) with h.div: # Automatic inclusion of the javascript Comet functions h << component.Component(comet.channels[self.channel_id]) # Asynchronous (Ajax) rendering of the user interaction form h << self.interaction.render(h.AsyncRenderer()) # This list will be filled by the received messages h << h.ul(id='msgs') return h.root
def render_overlay_menu(self, h, comp, *args): id_ = h.generate_id() card_cmp, card_id, card_model = h.get_async_root().component, h.get_async_root().id, h.get_async_root().model with h.div(id=id_): with h.ul: h << h.li( h.a( _("Open"), target="_blank", onclick=( "window.open(%s);" "YAHOO.kansha.app.hideOverlay()" % ajax.py2js(self.assets_manager.get_image_url(self.filename)) ), ) ) h << h.li(h.a(_("Delete")).action(lambda: comp.answer(("delete", self)))) if self.is_image(): if self.is_cover: h << h.li(h.a(_("Remove cover")).action(lambda: comp.answer(("remove_cover", self)))) else: # Open asset cropper card_cmp = h.get_async_root().component card_id = h.get_async_root().id card_model = h.get_async_root().model self.create_cropper_component(comp, card_cmp, card_id, card_model) h << h.li(self.overlay_cropper) return h.root
def render_NewMember(self, h, comp, *args): """Render the title of the associated card""" with h.form: members_to_add = var.Var() def get_emails(): emails = [] for email in members_to_add().split(','): try: email = email.strip() email = validator.validate_email(email) emails.append(email) except ValueError: continue return emails h << h.input(type='text', id=self.text_id,).action(members_to_add) mail_input = h.input(value=_("Add"), type="submit", class_="btn btn-primary" ).action(remote.Action(lambda: comp.answer(get_emails()))) # Sending mail synchronously can take a long time mail_input.set('onclick', 'YAHOO.kansha.app.showWaiter();' + mail_input.get('onclick')) h << mail_input h << self.autocomplete h << h.script( "document.getElementById(%s).focus()" % ajax.py2js(self.text_id) ) return h.root
def render_column_body(self, h, comp, *args): model = 'dnd' if security.has_permissions('edit', self) else "no_dnd" id_ = h.generate_id() with h.div(class_='list-body', id=id_): h << [card.on_answer(self.edit_card).render(h, model=model) for card in self.cards] h << h.script("YAHOO.kansha.dnd.initTargetCard(%s)" % ajax.py2js(id_)) kw = {} if not security.has_permissions('edit', self): kw['style'] = 'width: 0px' if not self.is_archive: with h.div(class_='list-footer', id=self.id + '_footer', **kw): if security.has_permissions('edit', self): h << h.div(self.new_card) h << h.script("YAHOO.kansha.app.countCards(%s)" % ajax.py2js(self.id)) return h.root
def render_asset_anonymous(self, h, comp, model, *args): return h.a( comp.render(h, model="thumb"), onclick="window.open(%s);YAHOO.kansha.app.hideOverlay()" % ajax.py2js(self.assets_manager.get_image_url(self.filename)), target="_blank", )
def render(self, h, *args): h.head.css('nagare_chat', ''' #msgs { list-style-type: none; border: 1px dashed #f3f2f1; padding: 5px; } #msgs li:nth-child(odd) { background-color: #f3f2f1; } .msg_type_j { color: red } .msg_type_p { color: blue } ''') # Inclusion of the translated ``append_msg`` function h.head << h.head.script(ajax.py2js(append_msg, h)) with h.div: # Automatic inclusion of the javascript Comet functions h << component.Component(comet.channels[self.channel_id]) # Asynchronous (Ajax) rendering of the user interaction form h << self.interaction.render(h.AsyncRenderer()) # This list will be filled by the received messages h << h.ul(id='msgs') 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_NewColumnEditor(self, h, comp, *args): """Render column creator""" h << h.h2(_(u'Add list')) with h.form: with h.div: id_ = h.generate_id() h << h.label(_('Name'), for_=id) h << h.input(id=id_, type='text', placeholder=_('List title')).error(self.title.error).action(self.title) with h.div: id_ = h.generate_id() h << h.label(_('Position'), for_=id_) with h.select(id=id_).error(self.index.error).action(self.index): for i in xrange(1, self.columns_count + 2): h << h.option(i, value=i - 1).selected(i) with h.div: id_ = h.generate_id() h << h.label(_('Number max of cards'), id_=id_) h << h.input(id=id_, type='text').error(self.nb_cards.error).action(self.nb_cards) h << h.script( """YAHOO.util.Event.on(%s, 'keyup', function (e) { var result =this.value.replace(/[^0-9]/g, '') if (this.value !=result) { this.value = result; } })""" % ajax.py2js(id_) ) with h.div(class_='buttons'): h << h.button(_('Add'), class_=('btn btn-primary')).action(self.commit, comp) h << ' ' h << h.a(_('Cancel'), class_='btn').action(self.cancel, comp) return h.root
def render_NewMember(self, h, comp, *args): """Render the title of the associated card""" with h.form: members_to_add = var.Var() def get_emails(): emails = [] for email in members_to_add().split(','): try: email = email.strip() email = validator.validate_email(email) emails.append(email) except ValueError: continue return emails h << h.input( type='text', id=self.text_id, ).action(members_to_add) h << h.input(value=_("Add"), type="submit", class_="btn btn-primary").action( remote.Action(lambda: comp.answer(get_emails()))) h << self.autocomplete h << h.script( "document.getElementById(%s).focus()" % ajax.py2js(self.text_id)) return h.root
def render_overlay_menu(self, h, comp, *args): id_ = h.generate_id() card_cmp, card_id, card_model = h.get_async_root( ).component, h.get_async_root().id, h.get_async_root().model with h.div(id=id_): with h.ul: h << h.li( h.a(_('Open'), target='_blank', onclick=("window.open(%s);" "YAHOO.kansha.app.hideOverlay()" % ajax.py2js( self.assets_manager.get_image_url( self.filename))))) h << h.li( h.a(_('Delete')).action(lambda: comp.answer(('delete', self)))) if self.is_image(): if self.is_cover: h << h.li( h.a(_('Remove cover')).action(lambda: comp.answer( ('remove_cover', self)))) else: # Open asset cropper card_cmp = h.get_async_root().component card_id = h.get_async_root().id card_model = h.get_async_root().model self.create_cropper_component(comp, card_cmp, card_id, card_model) h << h.li(self.overlay_cropper) return h.root
def render_CardsCounter_body(self, h, comp, model): with h.div(class_='no-drop'): h << h.i(class_='icon-blocked huge') << h.br h << _(u"This list already holds its maximum amount of cards") h << h.script( "YAHOO.kansha.app.countCards(%s)" % ajax.py2js(self.column.id)) return h.root
def render_column_dnd(self, h, comp, *args): """DnD wrapper for column""" h << comp.render(h, None) h << h.script("YAHOO.util.Event.onDOMReady(function() {" " YAHOO.kansha.dnd.initList(%(list_id)s);" "})" % {'list_id': ajax.py2js(self.id)}) 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_card_actions(self, h, comp, *args): with h.div(class_='card-actions'): with h.form: with h.ul(): with h.li(class_="buttonAddChecklist"): h << self.checklists.render(h, 'button') with h.li(class_="buttonAddFile"): h << self.gallery.render(h, 'download') with h.li(class_="buttonVote"): h << self.votes.render(h.AsyncRenderer(), 'edit') with h.li(class_="buttonDueDate"): h << self.due_date.render(h.AsyncRenderer(), 'button') if self.board.weighting_cards: with h.li(class_="actionWeight"): h << self._weight.on_answer(lambda v: self._weight.call(model='edit_weight' if v else None)) with h.li(class_="buttonDeleteCard"): if security.has_permissions('edit', self) and not self.column.is_archive: close_func = ajax.js( 'function (){%s;}' % h.a.action(comp.answer, 'delete').get('onclick') ) h << h.button( h.i(class_='icon-bin'), _('Delete'), class_='btn delete', onclick=( "if (confirm(%(confirm_msg)s)) {" " YAHOO.kansha.app.archiveCard(%(close_func)s, %(id)s, %(col_id)s, %(archive_col_id)s);" " reload_columns();" "}" "return false" % { 'close_func': ajax.py2js(close_func), 'id': ajax.py2js(self.id), 'col_id': ajax.py2js(self.column.id), 'archive_col_id': ajax.py2js( self.column.board.archive_column.id ), 'confirm_msg': ajax.py2js( _(u'This card will be deleted. Are you sure?') ).decode('UTF-8') } ) ) h << comp.render(h, 'members') 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 visible_cols = len(self.columns) - int(not self.show_archive) layout = '' if 2 < visible_cols < 6: layout = 'list-span-{}'.format(visible_cols) elif visible_cols < 3: layout = 'list-span-3' with h.div(id='lists'): if layout: h << {'class': layout} 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) return h.root
def create_column(self, comp): """Create the column. Create new column and call the model "closed" on component In: - ``comp`` -- component """ nb_cards = int(self.nb_cards()) if self.nb_cards() else '' id = self.board.create_column(self.index(), self.title(), nb_cards or None) col_id = 'list_' + str(id) return ("YAHOO.kansha.app.toggleMenu('boardNavbar');" "reload_columns();" "YAHOO.kansha.app.saveLimit(%s,%s)" % (ajax.py2js(col_id), ajax.py2js(nb_cards or 0)))
def render_CardsCounter(self, h, comp, *args): with h.div(class_='list-counter'): self.error = None visibility = ' hidden' if self.column.nb_max_cards: visibility = '' if self.check_add() else ' limitReached' with h.div(class_='cardCounter' + visibility, id=self.id): with h.a().action(comp.call, self, 'edit'): h << self.column.count_cards << '/' << ( self.column.nb_max_cards or 0) h << h.script( "YAHOO.kansha.app.saveLimit(%(list_id)s, %(limit)s);" "YAHOO.kansha.app.countCards(%(list_id)s);" % { 'list_id': ajax.py2js(self.column.id), 'limit': ajax.py2js(self.column.nb_max_cards or 0) }) return h.root
def render_card_new(self, h, comp, *args): h << comp.becomes(model=None) h << h.script( "card = YAHOO.util.Dom.get(%s);" "list = YAHOO.util.Dom.getAncestorByClassName(card, 'list-body');" "list.scrollTop = card.offsetTop - list.offsetTop;" % ajax.py2js(self.id)) return h.root
def render_card_dnd(self, h, comp, *args): """DnD wrapping of the card""" if self.data is not None: id_ = h.generate_id('dnd') with h.div(id=id_): h << comp.render(h.AsyncRenderer()) h << h.script('YAHOO.kansha.dnd.initCard(%s)' % ajax.py2js(id_)) return h.root