def render_comment_actions(self, h, comp, *args): # delete if security.has_permissions('delete_comment', self) and not self.show_delete_form(): h << h.a(h.i(class_='icon-close'), class_="delete", title=_(u'Delete this comment')).action(lambda: self.show_delete_form(True)) # moderation if not self.comment.moderated and security.has_permissions('moderate_comment', self): h << h.a(h.i(class_='icon-remark'), class_="moderate", title=_(u'Moderate this comment')).action(self.moderate) if self.comment.moderated and security.has_permissions('unmoderate_comment', self): h << h.a(h.i(class_='icon-remark'), class_="unmoderate", title=_(u'Cancel moderation')).action(self.cancel_moderation) # vote if security.has_permissions('vote_comment', self): if self.has_vote(): label = _(u"I don't find this comment relevant anymore") h << h.a(h.i(class_='icon-thumb-down'), title=label).action(self.remove_vote) else: label = _(u"I find this comment relevant") h << h.a(h.i(class_='icon-thumb-up'), title=label).action(self.add_vote) return h.root
def load_user_boards(self, user=None): if user is None: user = security.get_user() self.my_boards.clear() self.guest_boards.clear() self.archived_boards.clear() last_modifications = {} for board_id, in Board.get_all_board_ids(): # Comma is important board_obj = self._services(Board, board_id, self.app_title, self.app_banner, self.theme, self.card_extensions, self.search_engine, load_children=False) if security.has_permissions('manage', board_obj) or security.has_permissions('edit', board_obj): board_comp = component.Component(board_obj) if board_obj.archived: self.archived_boards[board_id] = board_comp else: last_activity = board_obj.get_last_activity() if last_activity is not None: last_modifications[board_id] = (last_activity, board_comp) if security.has_permissions('manage', board_obj): self.my_boards[board_id] = board_comp elif security.has_permissions('edit', board_obj): self.guest_boards[board_id] = board_comp last_5 = sorted(last_modifications.values(), reverse=True)[:5] self.last_modified_boards = OrderedDict((comp().id, comp) for _modified, comp in last_5) public, private = Board.get_templates_for(user.username, user.source) self.templates = {'public': [(b.id, b.template_title) for b in public], 'private': [(b.id, b.template_title) for b in private]}
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_Board(self, h, comp, *args): """Main board renderer""" security.check_permissions('view', self) h.head.css_url('css/themes/board.css') h.head.css_url('css/themes/%s/board.css' % self.theme) h.head.javascript_url('js/jquery-searchinput/jquery.searchinput.js') h.head.javascript_url('js/debounce.js') h.head.css_url('js/jquery-searchinput/styles/jquery.searchinput.min.css') h.head.javascript('searchinput', '''jQuery(document).ready(function ($) { $('#search').searchInput(); });''') title = '%s - %s' % (self.get_title(), self.app_title) h.head << h.head.title(title) if security.has_permissions('edit', self): h << comp.render(h, "menu") h << self.modal with h.div(class_='board'): if self.background_image_url: h << {'class': 'board ' + self.background_image_position, 'style': 'background-image:url(%s)' % self.background_image_url} with h.div(class_='header'): with h.div(class_='board-title', style='color: %s' % self.title_color): h << self.title.render(h.AsyncRenderer(), 0 if security.has_permissions('edit', self) else 'readonly') h << comp.render(h, 'switch') with h.div(class_='bbody'): h << comp.render(h.AsyncRenderer(), self.model) return h.root
def render_Board(self, h, comp, *args): """Main board renderer""" security.check_permissions('view', self) self.refresh_on_version_mismatch() self.card_filter.reload_search() h.head.css_url('css/themes/board.css?v=2c') h.head.css_url('css/themes/%s/board.css?v=2c' % self.theme) title = '%s - %s' % (self.get_title(), self.app_title) h.head << h.head.title(title) if security.has_permissions('edit', self): h << comp.render(h.AsyncRenderer(), "menu") with h.div(class_='board'): if self.background_image_url: h << { 'class': 'board ' + self.background_image_position, 'style': 'background-image:url(%s)' % self.background_image_url } with h.div(class_='header'): with h.div(class_='board-title', style='color: %s' % self.title_color): h << self.title.render( h.AsyncRenderer(), 0 if security.has_permissions( 'edit', self) else 'readonly') h << comp.render(h, 'switch') with h.div(class_='bbody'): h << comp.render(h.AsyncRenderer(), self.model) return h.root
def render_idea_wf_comment_table_row(self, h, comp, *args): with h.td(class_='date'): h << format_datetime(self.data.submission_date, format='short') with h.td(class_='change'): h << _(self.data.from_state.label) h << h.div(u" ⬇ ") h << _(self.data.to_state.label) with h.td(class_='author'): # FIXME: we should use a specific "di" view to render the author name author = self.data.created_by di = self.data.idea_wf.assignated_di if author is not di or security.has_permissions('view_di', self): h << author.fullname else: h << _(u'Expert') with h.td(class_='comment'): if security.has_permissions('edit_comment', self): h << self.content_editor.render(h.AsyncRenderer()) else: h << self.data.content 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_Board_item(self, h, comp, *args): def answer(): comp.answer(self.data.id) url = self.data.url with h.li: h << h.SyncRenderer().a(h.i( ' ', class_=VISIBILITY_ICONS[self.data.visibility]), self.data.title, href=url, class_="boardItemLabel", title=self.data.description) with h.div(class_='actions'): h << self.comp_members.render(h, 'members') if security.has_permissions('manage', self): h << h.a(h.i(class_='ico-btn icon-box-add'), class_='archive', title=_(u'Archive "%s"') % self.data.title).action( self.archive, comp) elif security.has_permissions('leave', self): onclick = 'return confirm("%s")' % _( "You won't be able to access this board anymore. Are you sure you want to leave it anyway?" ) h << h.SyncRenderer().a( h.i(class_='ico-btn icon-exit'), class_='leave', title=_(u'Leave "%s"') % self.data.title, onclick=onclick).action(self.leave, comp) else: # place holder for alignment and for future feature 'request membership' h << h.a(h.i(class_='ico-btn icon-user-check'), style='visibility:hidden') 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_Board_item(self, h, comp, *args): def answer(): comp.answer(self.data.id) url = self.data.url with h.li: h << h.SyncRenderer().a( h.i(' ', class_=VISIBILITY_ICONS[self.data.visibility]), self.data.title, href=url, class_="boardItemLabel", title=self.data.description) with h.div(class_='actions'): h << self.comp_members.render(h, 'members') if security.has_permissions('manage', self): h << h.a( h.i(class_='ico-btn icon-box-add'), class_='archive', title=_(u'Archive "%s"') % self.data.title ).action(self.archive, comp) elif security.has_permissions('leave', self): onclick = 'return confirm("%s")' % _("You won't be able to access this board anymore. Are you sure you want to leave it anyway?") h << h.SyncRenderer().a( h.i(class_='ico-btn icon-exit'), class_='leave', title=_(u'Leave "%s"') % self.data.title, onclick=onclick ).action(self.leave, comp) else: # place holder for alignment and for future feature 'request membership' h << h.a(h.i(class_='ico-btn icon-user-check'), style='visibility:hidden') return h.root
def show_frontdesk(self): if security.has_permissions('show_administration_menu', self): self.show_administration_menu() elif security.has_permissions('show_di_basket', self): self.show_di_ideas_basket() elif security.has_permissions('show_fi_basket', self): self.show_fi_ideas_basket() else: self.show_home()
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_profile_box_header(self, h, comp, *args): user_comp = component.Component(User(self, self.user)) with h.section(class_='profile'): with h.div(class_='user'): # user info # avatar image h << user_comp.render(h, model='avatar_photo') h << h.div(self.user.fullname, class_='name') h << h.small(self.user.status_level_label, class_='title') if security.has_permissions('edit_avatar', self): h << component.Component(self.avatar_editor) with h.div(class_='user-info'): h << h.h1(self.user.fullname) l1 = '-'.join([elt for elt in [self.user.corporation_label, self.user.site_label] if elt]) l2 = '-'.join([elt for elt in [self.user.direction_label, self.user.service_label] if elt]) l3 = self.user.position if l1 or l2 or l3: with h.ul: if l1: h << h.li(l1) if l2: h << h.li(l2) if l3: h << h.li(l3) h << h.h2(_('Contact')) h << h.a(self.user.email, href="mailto:" + self.user.email) h << h.br h << (self.user.work_phone or '') h << h.br h << (self.user.mobile_phone or '') h << h.br h << h.br # FI user_fi = self.user.fi if security.has_permissions('edit_fi', self): h << component.Component(self.fi_editor).render(h) elif user_fi: h << _(u'Facilitator: ') h << h.a(user_fi.fullname, href=self.profile_url(user_fi.uid)).action(lambda uid=user_fi.uid: self.view_profile(uid)) else: with h.p: h << h.a(_(u'No facilitator associated')) h << comp.render(h, model='tabs') return h.root
def _create_tabs(self): can_edit = security.has_permissions('edit_user', self) can_view_tracked_ideas = security.has_permissions('view_tracked_ideas', self) menu_items = ( ('profile', True), ('settings', can_edit), ('tracked_ideas', can_view_tracked_ideas), ('ideas', True), ('points', True), # ('rank', True), ) return [name for name, enabled in menu_items if enabled]
def render(self, h, comp, *args): """Render the title of the associated object Used by column title and card title on popin """ with h.div(class_='title'): kw = {} if not security.has_permissions('edit', self): kw['style'] = 'cursor: default' a = h.a(self.text, **kw) if security.has_permissions('edit', self): a.action(comp.answer) h << a 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_ColumnTitle(self, h, comp, *args): """Render the title of the associated object Used by column title and card title on popin """ with h.div(class_="title"): kw = {} if not security.has_permissions("edit", self): kw["style"] = "cursor: default" a = h.a(self.text, title=self.text, **kw) if security.has_permissions("edit", self): a.action(comp.answer) h << a h << h.script("YAHOO.kansha.app.showCardsLimitEdit(%s)" % self.parent.id) 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_Checklists(self, h, comp, model): h.head.javascript_url('checklists/js/checklists.js') self.load_children() can_edit = security.has_permissions('checklist', self.card) with h.div(id_='clists'): if can_edit: # 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_): not_alone = len(self.checklists) > 1 for index, clist in enumerate(self.checklists): if can_edit: h << clist.on_answer( lambda v, index=index: self.delete_checklist(index) ).render(h, 'not-alone' if not_alone else None) else: h << clist.render(h, 'read-only') return h.root
def render_CardLabels(self, h, comp, *args): """Add or remove labels to card""" if security.has_permissions('edit', self.card): h << comp.render(h.AsyncRenderer(), model="list-edit") else: h << comp.render(h, model="list") return h.root
def render_portal_navigation_top(self, h, comp, *args): # FIXME: use a TabContainer instead with h.div(class_="nav-box"): with h.ul: with h.li(class_='current' if self.selected_tab == 'home' else ''): h << h.a(_(u'Home'), title=_(u"Go to the home page"), href='home').action(self.show_home) # challenges with h.li(class_='current' if self.selected_tab == 'challenge' else ''): h << h.a(_(u'Challenge'), title=_(u"View, comment and vote for challenge ideas"), href='challenges').action(self.show_challenge_ideas) # ideas with h.li(class_='current' if self.selected_tab == 'ideas' else ''): h << h.a(_(u'Ideas'), title=_(u"View, comment and vote for ideas"), href='ideas').action(self.show_ideas) # admininistration menu if security.has_permissions('show_administration_menu', self): with h.li(class_='current' if self.selected_tab == 'administration' else ''): h << h.a(_(u'Administration'), href='administration').action(self.show_administration_menu) # Help with h.li(class_='current' if self.selected_tab == 'help' else ''): h << h.a(_(u'Help'), href="help") 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_profile_editor(self, h, comp, *args): with h.form(class_='profile-editor'): # expert's business area if self.user.di_business_area and security.has_permissions('view_di_business_area', self): with h.h3: h << _(u"Expert's Business Area") with h.p: h << self.user.di_business_area if self.user.is_developer(): h << h.h3(_(u'My speciality')) h << h.input(type='text', class_='text wide', value=self.specialty()).action(self.specialty).error(self.specialty.error) h << h.h3(_(u'Mobile phone')) h << h.input(type='text', class_='text wide', value=self.mobile_phone()).action(self.mobile_phone).error(self.mobile_phone.error) h << h.h3(_(u'Office phone')) h << h.input(type='text', class_='text wide', value=self.work_phone()).action(self.work_phone).error(self.work_phone.error) h << h.h3(_(u'Who am I?')) h << h.textarea(self.description(), class_='wide', rows=5, cols=30).action(self.description).error(self.description.error) h << h.h3(_(u'Skills')) h << h.textarea(self.competencies(), class_='wide', rows=5, cols=30).action(self.competencies).error(self.competencies.error) h << h.div(_(u'List your skills, knowledge, learning, know-how, … then submit your profile'), class_='legend') h << h.h3(_(u'Expertises')) h << h.textarea(self.expertises(), class_='wide', rows=5, cols=30).action(self.expertises).error(self.expertises.error) h << h.div(_(u'Tell us about your expertises, … then submit your profile'), class_='legend') h << h.h3(_(u'Hobbies')) h << h.textarea(self.hobbies(), class_='wide', rows=5, cols=30).action(self.hobbies).error(self.hobbies.error) h << h.div(_(u'Describe your hobbies, passions outside the company, … then submit your profile'), class_='legend') with h.div(class_='buttons'): h << h.input(type='submit', value=_(u'Submit the profile')).action(self.commit) return h.root
def render_download(self, h, comp, *args): if security.has_permissions('edit', self): 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'), _("Add file")), 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(); 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': self.assets_manager.max_size, 'input_id': input_id, 'submit_id': submit_id, 'error': _(u'Max file size exceeded')}) 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: self.add_assets(v_file())) return h.root
def render_Board_item(self, h, comp, *args): def answer(): comp.answer(self.data.id) url = self.data.url with h.li: h << h.SyncRenderer().a(self.data.title, href=url, class_="boardItemLabel", title=self.data.description) with h.div(class_='actions'): h << self.comp_members.render(h, 'members') if security.has_permissions('manage', self): h << h.a(h.i(class_='ico-btn icon-box-add'), class_='archive', title=_(u'Archive this board')).action( self.archive, comp) else: onclick = 'return confirm("%s")' % _( "You won't be able to access this board anymore. Are you sure you want to leave it anyway?" ) h << h.SyncRenderer().a(h.i(class_='ico-btn icon-exit'), class_='leave', title=_(u'Leave this board'), onclick=onclick).action( self.leave, comp) 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_card_actions(self, h, comp, *args): with h.div(class_='span2 cardactions'): 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') with h.li(class_="buttonDeleteCard"): if security.has_permissions('edit', self) and not self.column.is_archive: action = h.a.action(lambda: comp.answer('delete')).get('onclick') close_func = 'function (){%s;}' % (action) h << h.button(h.i(class_='icon-remove icon-grey'), _('Delete'), class_='btn btn-small', onclick=("if (confirm(\"%(confirm_msg)s\"))" " { YAHOO.kansha.app.archiveCard(%(close_func)s, '%(id)s', '%(col_id)s', '%(archive_col_id)s'); }return false;" % dict(close_func=close_func, id=self.id, col_id=self.column.id, archive_col_id=self.column.board.archive_column.id, confirm_msg=_(u'This card will be deleted. Are you sure ?')))) 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)) h << comp.render(h, 'members') return h.root
def render_Board(self, h, comp, *args): """Main board renderer""" h.head.javascript_url('js/jquery-searchinput/jquery.searchinput.js') h.head.javascript_url('js/debounce.js') h.head.css_url('js/jquery-searchinput/styles/jquery.searchinput.min.css') h.head.javascript('searchinput', "jQuery(document).ready(function ($) {$('#search').searchInput();});") h << self.title.render(h, 'tabname') security.check_permissions('view', self) if security.has_permissions('edit', self): h << comp.render(h, "menu") # TODO: Remove this popin h << self.popin.render(h.AsyncRenderer()) background_image_url = self.background_image_url background_image_position = self.background_image_position if background_image_url: styles = {'repeat': 'background:url(%s) repeat' % background_image_url, 'cover': 'background:url(%s) no-repeat; background-size:cover' % background_image_url} style = styles[background_image_position] else: style = '' with h.div(class_='board', style=style): with h.div(class_='header'): h << self.title.render(h.AsyncRenderer()) h << comp.render(h, 'switch') with h.div(class_='bbody'): h << comp.render(h.AsyncRenderer(), self.model) return h.root
def render_BoardMember_overlay(self, h, comp, *args): if security.has_permissions('manage', self.board): return self.user.on_answer(self.dispatch).render(h, model='overlay-%s' % self.role) else: member = self.user.render(h, "avatar") member.attrib.update({'class': 'miniavatar unselectable'}) return member
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_Board_item(self, h, comp, *args): def answer(): comp.answer(self.data.id) url = self.data.url with h.li(class_="row-fluid"): with h.a(self.data.title, href=url, class_="boardItemLabel").action(answer): if self.data.description: h << {'data-tooltip': self.data.description} h << {'onmouseover': """YAHOO.kansha.app.highlight(this, 'members', false); YAHOO.kansha.app.highlight(this, 'archive', false); YAHOO.kansha.app.highlight(this, 'leave', false);""", 'onmouseout': """YAHOO.kansha.app.highlight(this, 'members', true); YAHOO.kansha.app.highlight(this, 'archive', true); YAHOO.kansha.app.highlight(this, 'leave', true);"""} h << self.comp_members.render(h.AsyncRenderer(), 'members') if security.has_permissions('manage', self): h << h.a(class_='archive', title=_(u'Archive this board')).action(self.archive_board) else: h << h.a(class_='leave', title=_(u'Leave this board'), onclick='return confirm("%s")' % _("You won't be able to access this board anymore. Are you sure you want to leave it anyway?") ).action(self.leave) return h.root
def render(self, h, comp, *args): """Add or remove labels to card""" if security.has_permissions('edit', self.card): h << self.overlay else: h << comp.render(h, model="list") 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_ColumnTitle(self, h, comp, *args): """Render the title of the associated object Used by column title and card title on popin """ with h.div(class_='title'): kw = {} if not security.has_permissions('edit', self): kw['style'] = 'cursor: default' a = h.a(self.text, title=self.text, **kw) if security.has_permissions('edit', self): a.action(comp.answer) h << a h << h.script( 'YAHOO.kansha.app.showCardsLimitEdit(%s)' % ajax.py2js(self.parent.id)) return h.root
def has_permission_edit_idea_in_editor(self, user, perm, subject): idea_comp = subject.idea if idea_comp is None: return True return security.has_permissions('edit_idea', idea_comp)
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 render_column_header(self, h, comp, *args): with h.div(class_='title'): h << self.title.render( h.AsyncRenderer(), 0 if security.has_permissions('edit', self) else 'readonly') h << self.card_counter 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_profile_box_profile_view(self, h, comp, *args): user = self.user # expert's business area if user.di_business_area and security.has_permissions('view_di_business_area', self): with h.h2: h << _(u"Expert's Business Area") with h.p: h << user.di_business_area or '' with h.div(class_='group'): h << h.h2(_(u'Who am I?')) if user.description: with h.p: h << '"%s"' % user.description with h.div(class_='group'): with h.table: with h.tbody: with h.tr: with h.td: h << h.h2(_(u'Skills')) if user.competencies: h << text_to_html_elements(h, user.competencies) with h.td: h << h.h2(_(u'Expertises')) if user.expertises: h << text_to_html_elements(h, user.expertises) with h.td: h << h.h2(_(u'Hobbies')) if user.hobbies: h << text_to_html_elements(h, user.hobbies) return h.root
def get_all_comments(self): if security.has_permissions('view_moderated_comments', self): comments = [c for c in self.i.comments if not c.deleted] else: comments = [c for c in self.i.comments if not c.moderated and not c.deleted] return reversed(comments)
def render_CardLabels(self, h, comp, *args): """Add or remove labels to card""" if security.has_permissions('edit', self.card): h << self.overlay else: h << comp.render(h, model="list") return h.root
def render_profile_box_profile_view(self, h, comp, *args): user = self.user # expert's business area if user.di_business_area and security.has_permissions( 'view_di_business_area', self): with h.h2: h << _(u"Expert's Business Area") with h.p: h << user.di_business_area or '' with h.div(class_='group'): h << h.h2(_(u'Who am I?')) if user.description: with h.p: h << '"%s"' % user.description with h.div(class_='group'): with h.table: with h.tbody: with h.tr: with h.td: h << h.h2(_(u'Skills')) if user.competencies: h << text_to_html_elements(h, user.competencies) with h.td: h << h.h2(_(u'Expertises')) if user.expertises: h << text_to_html_elements(h, user.expertises) with h.td: h << h.h2(_(u'Hobbies')) if user.hobbies: h << text_to_html_elements(h, user.hobbies) return h.root
def render_card_edit(self, h, comp, *args): """Render card in edition mode""" # Test for delete card if self.data is None: return h.root parent_title = self.emit_event(comp, events.ParentTitleNeeded) or '' with h.div(class_='card-edit-form'): with h.div(class_='header'): with h.div(class_='title'): h << self.title.render( h.AsyncRenderer(), 0 if security.has_permissions( 'edit', self) else 'readonly') h << h.span('(%s)' % parent_title, class_='reminder') with h.div(class_='grid-2'): with h.div(class_='card-edition'): for name, extension in self.extensions: h << h.div(extension.render(h.AsyncRenderer()), class_=name) with h.div(class_='card-actions'): h << comp.render(h, 'delete-action') h << [ extension.render(h.AsyncRenderer(), 'action') for __, extension in self.extensions ] 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_BoardMember(self, h, comp, *args): application_url = h.request.application_url if security.has_permissions('manage', self.board): return self.user.on_answer( lambda action: self.dispatch(action, application_url)).render( h, model='%s' % self.role) else: return h.div(self.user.render(h), class_='member')
def ui_create_card(self, comp, title): if not security.has_permissions('edit', self): return card = self.create_card(title) if card: self.index_cards([card]) self.emit_event(comp, events.SearchIndexUpdated) self.card_filter.reset()
def get_all_comments(self): if security.has_permissions('view_moderated_comments', self): comments = [c for c in self.i.comments if not c.deleted] else: comments = [ c for c in self.i.comments if not c.moderated and not c.deleted ] return reversed(comments)
def render(self, h, comp, *args): """Render description component. If text is empty, display a text area otherwise it's a simple text """ id_ = h.generate_id() kw = {'class': 'description', 'id': id_} if security.has_permissions('edit', self.card): kw['onclick'] = h.a.action(comp.becomes, model='edit').get('onclick') with h.div(**kw): if self.text: h << h.parse_htmlstring(self.text, fragment=True) elif security.has_permissions('edit', self.card): h << h.textarea(placeholder=_("Add description.")) h << h.script("YAHOO.kansha.app.urlify($('#' + %s))" % ajax.py2js(id_)) 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_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_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_Votes_edit(self, h, comp, *args): '''Add vote form''' if security.has_permissions('vote', self): if self.has_voted(): msg = _('Unvote (%s)') % self.count_votes() else: msg = _('Vote (%s)') % self.count_votes() h << h.a(h.i(class_='icon-heart'), msg, class_='btn').action(self.toggle) return h.root
def _handle_signal_view_idea_edit_user(self, sender, signal, *args, **kwds): # self.idea_submit.becomes(None) self.content.becomes(self, model='one_col') if security.has_permissions('view_unpublished_ideas', sender.user): p = IdeaPager(self, lambda: get_all_user_ideas(sender.uid), 9) else: p = IdeaPager(self, lambda: get_published_user_ideas(sender.uid), 9) p.goto(kwds.get('idea_id'))