Edgewall Software

LudvigStrigeus: FlexibleProgressBar_r1518.2.diff

File FlexibleProgressBar_r1518.2.diff, 11.3 KB (added by ludde, 7 years ago)

More flexible progress bars

  • trac/Milestone.py

     
    5757        tickets.append(ticket) 
    5858    return tickets 
    5959 
    60  
    61 def get_query_links(env, milestone, grouped_by='component', group=None): 
    62     q = {} 
    63     if not group: 
    64         q['all_tickets'] = env.href.query(milestone=milestone) 
    65         q['active_tickets'] = env.href.query(milestone=milestone, 
    66                                              status=('new', 'assigned', 'reopened')) 
    67         q['closed_tickets'] = env.href.query(milestone=milestone, status='closed') 
    68     else: 
    69         q['all_tickets'] = env.href.query(milestone=milestone, grouped_by=group) 
    70         q['active_tickets'] = env.href.query(milestone=milestone, 
    71                                              grouped_by=group, 
    72                                              status=('new', 'assigned', 'reopened')) 
    73         q['closed_tickets'] = env.href.query(milestone=milestone, grouped_by=group, 
    74                                              status='closed') 
    75     return q 
    76  
    77  
    78 def calc_ticket_stats(tickets): 
     60def get_tickets_progressbar(tickets, env, milestone, grouped_by='component', group=None): 
    7961    total_cnt = len(tickets) 
    80     active = [ticket for ticket in tickets if ticket['status'] != 'closed'] 
    81     active_cnt = len(active) 
    82     closed_cnt = total_cnt - active_cnt 
     62    closed_cnt = len([ticket for ticket in tickets if ticket['status'] in ('verified', 'closed')]) 
     63    active_cnt = total_cnt - closed_cnt 
    8364 
    84     percent_active, percent_closed = 0, 0 
     65    # Determine percentages 
     66    active_pct, closed_pct = 0, 0 
    8567    if total_cnt > 0: 
    86         percent_active = round(float(active_cnt) / float(total_cnt) * 100) 
    87         percent_closed = round(float(closed_cnt) / float(total_cnt) * 100) 
    88         if percent_active + percent_closed > 100: 
    89             percent_closed -= 1 
     68        closed_pct = round(float(closed_cnt) / float(total_cnt) * 100) 
     69        active_pct = 100 - closed_pct 
    9070 
     71    # Additional URL constraint?     
     72    extra = group and { grouped_by: group } or {} 
     73 
     74    # Determine URLs 
     75    closed_url = env.href.query( 
     76        milestone=milestone, status=('closed',), **extra) 
     77    active_url = env.href.query( 
     78        milestone=milestone, status=('new', 'assigned', 'reopened'), **extra) 
     79    all_url = env.href.query(milestone=milestone, **extra) 
     80 
     81    # Construct result     
     82    bar = [ 
     83        {'name': 'closed',  'capsname': 'Closed', 'pct': closed_pct, 
     84         'cnt': closed_cnt, 'url': closed_url}, 
     85        {'name': 'active',  'capsname': 'Active', 'pct': active_pct, 
     86         'cnt': active_cnt, 'url': active_url} 
     87        ] 
    9188    return { 
    9289        'total_tickets': total_cnt, 
    93         'active_tickets': active_cnt, 
    94         'percent_active': percent_active, 
    95         'closed_tickets': closed_cnt, 
    96         'percent_closed': percent_closed 
     90        'bar': bar, 
     91        'all_tickets_url' : all_url,         
     92        'text_pct': '%d%%' % closed_pct,      # Shown like: 25% 
     93        'text_frac': '%d/%d' % (closed_cnt, total_cnt) # Shown like: 1/4 
    9794    } 
    9895 
    99  
    10096class Milestone(Module): 
    10197 
    10298    def save_milestone(self, req, id): 
     
    333329        req.hdf['milestone.stats.grouped_by'] = by 
    334330 
    335331        tickets = get_tickets_for_milestone(self.env, self.db, id, by) 
    336         stats = calc_ticket_stats(tickets) 
     332        stats = get_tickets_progressbar(tickets, self.env, milestone['name']) 
    337333        req.hdf['milestone.stats'] = stats 
    338         queries = get_query_links(self.env, milestone['name']) 
    339         req.hdf['milestone.queries'] = queries 
    340334 
    341335        groups = self.get_groups(by) 
    342336        group_no = 0 
     
    353347                if percent_total > max_percent_total: 
    354348                    max_percent_total = percent_total 
    355349            req.hdf['%s.percent_total' % prefix] = percent_total * 100 
    356             stats = calc_ticket_stats(group_tickets) 
     350            stats = get_tickets_progressbar(group_tickets, self.env, milestone['name'], by, group) 
    357351            req.hdf[prefix] = stats 
    358             queries = get_query_links(self.env, milestone['name'], by, group) 
    359             req.hdf['%s.queries' % prefix] = queries 
    360352            group_no += 1 
    361353        req.hdf['milestone.stats.max_percent_total'] = max_percent_total * 100 
  • trac/Roadmap.py

     
    9292            tickets = Milestone.get_tickets_for_milestone(self.env, self.db, 
    9393                                                          milestone['name'], 
    9494                                                          'owner') 
    95             stats = Milestone.calc_ticket_stats(tickets) 
     95            stats = Milestone.get_tickets_progressbar(tickets, self.env, milestone['name']) 
    9696            req.hdf['roadmap.milestones.%s.stats' % milestone_no] = stats 
    97             queries = Milestone.get_query_links(self.env, milestone['name']) 
    98             req.hdf['roadmap.milestones.%s.queries' % milestone_no] = queries 
    9997            milestone['tickets'] = tickets # for the iCalendar view 
    10098            milestone_no += 1 
    10199 
     
    116114            status = ticket['status'] 
    117115            if status == 'new' or status == 'reopened' and not ticket['owner']: 
    118116                return 'NEEDS-ACTION' 
    119             elif status == 'assigned' or status == 'reopened': 
     117            elif status != 'closed': 
    120118                return 'IN-PROCESS' 
    121119            elif status == 'closed': 
    122120                if ticket['resolution'] == 'fixed': return 'COMPLETED' 
  • templates/roadmap.cs

     
    3939    with:stats = milestone.stats ?><?cs 
    4040     if:#stats.total_tickets > #0 ?> 
    4141      <div class="progress"> 
    42        <a class="closed" href="<?cs 
    43          var:milestone.queries.closed_tickets ?>" style="width: <?cs 
    44          var:#stats.percent_closed ?>%" title="<?cs 
    45          var:#stats.closed_tickets ?> of <?cs 
     42       <?cs each:bar = stats.bar ?> 
     43       <a class="<?cs var:bar.name ?>" href="<?cs 
     44         var:bar.url ?>" style="width: <?cs 
     45         var:#bar.pct ?>%" title="<?cs 
     46         var:#bar.cnt ?> of <?cs 
    4647         var:#stats.total_tickets ?> ticket<?cs 
    47          if:#stats.total_tickets != #1 ?>s<?cs /if ?> closed"></a> 
    48        <a class="open" href="<?cs 
    49          var:milestone.queries.active_tickets ?>" style="width: <?cs 
    50          var:#stats.percent_active ?>%" title="<?cs 
    51          var:#stats.active_tickets ?> of <?cs 
    52          var:#stats.total_tickets ?> ticket<?cs 
    53          if:#stats.total_tickets != #1 ?>s<?cs /if ?> active"></a> 
     48         if:#stats.total_tickets != #1 ?>s<?cs /if ?> <?cs var:bar.name ?>"></a> 
     49       <?cs /each ?> 
    5450      </div> 
    55       <p class="percent"><?cs var:#stats.percent_closed ?>%</p> 
     51      <p class="percent"><?cs var:stats.text_pct ?></p> 
    5652      <dl> 
    57        <dt>Active tickets:</dt> 
    58        <dd><a href="<?cs var:milestone.queries.active_tickets ?>"><?cs 
    59          var:stats.active_tickets ?></a></dd> 
    60        <dt>Closed tickets:</dt> 
    61        <dd><a href="<?cs var:milestone.queries.closed_tickets ?>"><?cs 
    62          var:stats.closed_tickets ?></a></dd> 
     53       <?cs each:bar = stats.bar ?> 
     54       <dt><?cs var:bar.capsname ?> tickets:</dt> 
     55       <dd><a href="<?cs var:bar.url ?>"><?cs var:bar.cnt ?></a></dd> 
     56       <?cs /each ?> 
    6357      </dl><?cs 
    6458     /if ?><?cs 
    6559    /with ?> 
  • templates/milestone.cs

     
    9494   <select name="target" id="target"> 
    9595    <option value="">None</option><?cs 
    9696     each:other = milestones ?><?cs if:other != milestone.name ?> 
    97       <option><?cs var:other ?></option><?cs  
     97      <option><?cs var:other ?></option><?cs 
    9898     /if ?><?cs /each ?> 
    9999   </select> 
    100100   <div class="buttons"> 
     
    121121   with:stats = milestone.stats ?><?cs 
    122122    if:#stats.total_tickets > #0 ?> 
    123123     <div class="progress"> 
    124       <a class="closed" href="<?cs 
    125         var:milestone.queries.closed_tickets ?>" style="width: <?cs 
    126         var:#stats.percent_closed ?>%" title="<?cs 
    127         var:#stats.closed_tickets ?> of <?cs 
    128         var:#stats.total_tickets ?> ticket<?cs 
    129         if:#stats.total_tickets != #1 ?>s<?cs /if ?> closed"></a> 
    130       <a class="open" href="<?cs 
    131         var:milestone.queries.active_tickets ?>" style="width: <?cs 
    132         var:#stats.percent_active ?>%" title="<?cs 
    133         var:#stats.active_tickets ?> of <?cs 
    134         var:#stats.total_tickets ?> ticket<?cs 
    135         if:#stats.total_tickets != #1 ?>s<?cs /if ?> active"></a> 
     124       <?cs each:bar = stats.bar ?> 
     125       <a class="<?cs var:bar.name ?>" href="<?cs 
     126         var:bar.url ?>" style="width: <?cs 
     127         var:#bar.pct ?>%" title="<?cs 
     128         var:#bar.cnt ?> of <?cs 
     129         var:#stats.total_tickets ?> ticket<?cs 
     130         if:#stats.total_tickets != #1 ?>s<?cs /if ?> <?cs var:bar.name ?>"></a> 
     131       <?cs /each ?> 
    136132     </div> 
    137      <p class="percent"><?cs var:#stats.percent_closed ?>%</p> 
     133     <p class="percent"><?cs var:stats.text_pct ?></p> 
    138134     <dl> 
    139       <dt>Active tickets:</dt> 
    140       <dd><a href="<?cs var:milestone.queries.active_tickets ?>"><?cs 
    141         var:stats.active_tickets ?></a></dd> 
    142       <dt>Closed tickets:</dt> 
    143       <dd><a href="<?cs var:milestone.queries.closed_tickets ?>"><?cs 
    144         var:stats.closed_tickets ?></a></dd> 
     135       <?cs each:bar = stats.bar ?> 
     136       <dt><?cs var:bar.capsname ?> tickets:</dt> 
     137       <dd><a href="<?cs var:bar.url ?>"><?cs var:bar.cnt ?></a></dd> 
     138       <?cs /each ?> 
    145139     </dl><?cs 
    146140    /if ?><?cs 
    147141   /with ?> 
     
    165159     each:group = milestone.stats.groups ?> 
    166160      <tr> 
    167161       <th scope="row"><a href="<?cs 
    168          var:group.queries.all_tickets ?>"><?cs var:group.name ?></a></th> 
     162         var:group.all_tickets_url ?>"><?cs var:group.name ?></a></th> 
    169163       <td nowrap=nowrap><?cs if:#group.total_tickets ?> 
    170164        <div class="progress" style="width: <?cs 
    171165          var:#group.percent_total * #80 / #milestone.stats.max_percent_total ?>%"> 
    172          <a class="closed" href="<?cs 
    173            var:group.queries.closed_tickets ?>" style="width: <?cs 
    174            var:#group.percent_closed ?>%" title="<?cs 
    175           var:group.closed_tickets ?> of <?cs 
    176           var:group.total_tickets ?> ticket<?cs 
    177           if:group.total_tickets != #1 ?>s<?cs /if ?> closed"></a> 
    178          <a class="open" href="<?cs 
    179            var:group.queries.active_tickets ?>" style="width: <?cs 
    180            var:#group.percent_active - 1 ?>%" title="<?cs 
    181           var:group.active_tickets ?> of <?cs 
    182           var:group.total_tickets ?> ticket<?cs 
    183           if:group.total_tickets != 1 ?>s<?cs /if ?> active"></a> 
     166                                 <?cs each:bar = group.bar ?> 
     167                                 <a class="<?cs var:bar.name ?>" href="<?cs 
     168                                         var:bar.url ?>" style="width: <?cs 
     169                                         var:#bar.pct ?>%" title="<?cs 
     170                                         var:#bar.cnt ?> of <?cs 
     171                                         var:#group.total_tickets ?> ticket<?cs 
     172                                         if:#group.total_tickets != #1 ?>s<?cs /if ?> <?cs var:bar.name ?>"></a> 
     173                                 <?cs /each ?> 
    184174        </div> 
    185         <p class="percent"><?cs var:group.closed_tickets ?>/<?cs 
    186          var:group.total_tickets ?></p> 
     175        <p class="percent"><?cs var:group.text_frac ?></p> 
    187176       <?cs /if ?></td> 
    188177      </tr><?cs 
    189178     /each ?>