FossilRepo
Fix ticket body, clickable stats, sort orders, markdown rendering - Ticket body: fall back to ticketchng.icomment when comment is empty (newer Fossil stores descriptions in change records) - Ticket body rendered as markdown/HTML via _render_fossil_content - Contributor stats are now clickable links to respective sections - Wiki pages sorted by most recently updated (not alphabetical) - Forum already sorted by newest (fmtime DESC)
Commit
11cb22eea564355189f5901e22cc8d4c9bf9d1f86239e27dc0a1914cc58c58b4
Parent
88b98207cac95f8…
4 files changed
+18
-3
+3
+2
-2
+9
-9
+18
-3
| --- fossil/reader.py | ||
| +++ fossil/reader.py | ||
| @@ -615,16 +615,31 @@ | ||
| 615 | 615 | return entries |
| 616 | 616 | |
| 617 | 617 | def get_ticket_detail(self, uuid: str) -> TicketEntry | None: |
| 618 | 618 | try: |
| 619 | 619 | row = self.conn.execute( |
| 620 | - "SELECT tkt_uuid, title, status, type, tkt_ctime, subsystem, priority, severity, resolution, comment " | |
| 620 | + "SELECT tkt_id, tkt_uuid, title, status, type, tkt_ctime, subsystem, priority, severity, resolution, comment " | |
| 621 | 621 | "FROM ticket WHERE tkt_uuid LIKE ?", |
| 622 | 622 | (uuid + "%",), |
| 623 | 623 | ).fetchone() |
| 624 | 624 | if not row: |
| 625 | 625 | return None |
| 626 | + | |
| 627 | + body = row["comment"] or "" | |
| 628 | + | |
| 629 | + # If comment is empty, try ticketchng.icomment (newer Fossil stores descriptions there) | |
| 630 | + if not body: | |
| 631 | + try: | |
| 632 | + chng = self.conn.execute( | |
| 633 | + "SELECT icomment, login FROM ticketchng WHERE tkt_id=? ORDER BY tkt_mtime ASC LIMIT 1", | |
| 634 | + (row["tkt_id"],), | |
| 635 | + ).fetchone() | |
| 636 | + if chng and chng["icomment"]: | |
| 637 | + body = chng["icomment"] | |
| 638 | + except sqlite3.OperationalError: | |
| 639 | + pass | |
| 640 | + | |
| 626 | 641 | return TicketEntry( |
| 627 | 642 | uuid=row["tkt_uuid"], |
| 628 | 643 | title=row["title"] or "", |
| 629 | 644 | status=row["status"] or "", |
| 630 | 645 | type=row["type"] or "", |
| @@ -632,11 +647,11 @@ | ||
| 632 | 647 | owner="", |
| 633 | 648 | subsystem=row["subsystem"] or "", |
| 634 | 649 | priority=row["priority"] or "", |
| 635 | 650 | severity=row["severity"] or "", |
| 636 | 651 | resolution=row["resolution"] or "", |
| 637 | - body=row["comment"] or "", | |
| 652 | + body=body, | |
| 638 | 653 | ) |
| 639 | 654 | except sqlite3.OperationalError: |
| 640 | 655 | return None |
| 641 | 656 | |
| 642 | 657 | # --- Wiki --- |
| @@ -651,11 +666,11 @@ | ||
| 651 | 666 | JOIN tagxref ON tag.tagid = tagxref.tagid |
| 652 | 667 | JOIN event ON tagxref.rid = event.objid |
| 653 | 668 | WHERE tag.tagname LIKE 'wiki-%' AND event.type = 'w' |
| 654 | 669 | GROUP BY tag.tagname |
| 655 | 670 | HAVING event.mtime = MAX(event.mtime) |
| 656 | - ORDER BY name | |
| 671 | + ORDER BY event.mtime DESC | |
| 657 | 672 | """ |
| 658 | 673 | ).fetchall() |
| 659 | 674 | for row in rows: |
| 660 | 675 | pages.append( |
| 661 | 676 | WikiPage( |
| 662 | 677 |
| --- fossil/reader.py | |
| +++ fossil/reader.py | |
| @@ -615,16 +615,31 @@ | |
| 615 | return entries |
| 616 | |
| 617 | def get_ticket_detail(self, uuid: str) -> TicketEntry | None: |
| 618 | try: |
| 619 | row = self.conn.execute( |
| 620 | "SELECT tkt_uuid, title, status, type, tkt_ctime, subsystem, priority, severity, resolution, comment " |
| 621 | "FROM ticket WHERE tkt_uuid LIKE ?", |
| 622 | (uuid + "%",), |
| 623 | ).fetchone() |
| 624 | if not row: |
| 625 | return None |
| 626 | return TicketEntry( |
| 627 | uuid=row["tkt_uuid"], |
| 628 | title=row["title"] or "", |
| 629 | status=row["status"] or "", |
| 630 | type=row["type"] or "", |
| @@ -632,11 +647,11 @@ | |
| 632 | owner="", |
| 633 | subsystem=row["subsystem"] or "", |
| 634 | priority=row["priority"] or "", |
| 635 | severity=row["severity"] or "", |
| 636 | resolution=row["resolution"] or "", |
| 637 | body=row["comment"] or "", |
| 638 | ) |
| 639 | except sqlite3.OperationalError: |
| 640 | return None |
| 641 | |
| 642 | # --- Wiki --- |
| @@ -651,11 +666,11 @@ | |
| 651 | JOIN tagxref ON tag.tagid = tagxref.tagid |
| 652 | JOIN event ON tagxref.rid = event.objid |
| 653 | WHERE tag.tagname LIKE 'wiki-%' AND event.type = 'w' |
| 654 | GROUP BY tag.tagname |
| 655 | HAVING event.mtime = MAX(event.mtime) |
| 656 | ORDER BY name |
| 657 | """ |
| 658 | ).fetchall() |
| 659 | for row in rows: |
| 660 | pages.append( |
| 661 | WikiPage( |
| 662 |
| --- fossil/reader.py | |
| +++ fossil/reader.py | |
| @@ -615,16 +615,31 @@ | |
| 615 | return entries |
| 616 | |
| 617 | def get_ticket_detail(self, uuid: str) -> TicketEntry | None: |
| 618 | try: |
| 619 | row = self.conn.execute( |
| 620 | "SELECT tkt_id, tkt_uuid, title, status, type, tkt_ctime, subsystem, priority, severity, resolution, comment " |
| 621 | "FROM ticket WHERE tkt_uuid LIKE ?", |
| 622 | (uuid + "%",), |
| 623 | ).fetchone() |
| 624 | if not row: |
| 625 | return None |
| 626 | |
| 627 | body = row["comment"] or "" |
| 628 | |
| 629 | # If comment is empty, try ticketchng.icomment (newer Fossil stores descriptions there) |
| 630 | if not body: |
| 631 | try: |
| 632 | chng = self.conn.execute( |
| 633 | "SELECT icomment, login FROM ticketchng WHERE tkt_id=? ORDER BY tkt_mtime ASC LIMIT 1", |
| 634 | (row["tkt_id"],), |
| 635 | ).fetchone() |
| 636 | if chng and chng["icomment"]: |
| 637 | body = chng["icomment"] |
| 638 | except sqlite3.OperationalError: |
| 639 | pass |
| 640 | |
| 641 | return TicketEntry( |
| 642 | uuid=row["tkt_uuid"], |
| 643 | title=row["title"] or "", |
| 644 | status=row["status"] or "", |
| 645 | type=row["type"] or "", |
| @@ -632,11 +647,11 @@ | |
| 647 | owner="", |
| 648 | subsystem=row["subsystem"] or "", |
| 649 | priority=row["priority"] or "", |
| 650 | severity=row["severity"] or "", |
| 651 | resolution=row["resolution"] or "", |
| 652 | body=body, |
| 653 | ) |
| 654 | except sqlite3.OperationalError: |
| 655 | return None |
| 656 | |
| 657 | # --- Wiki --- |
| @@ -651,11 +666,11 @@ | |
| 666 | JOIN tagxref ON tag.tagid = tagxref.tagid |
| 667 | JOIN event ON tagxref.rid = event.objid |
| 668 | WHERE tag.tagname LIKE 'wiki-%' AND event.type = 'w' |
| 669 | GROUP BY tag.tagname |
| 670 | HAVING event.mtime = MAX(event.mtime) |
| 671 | ORDER BY event.mtime DESC |
| 672 | """ |
| 673 | ).fetchall() |
| 674 | for row in rows: |
| 675 | pages.append( |
| 676 | WikiPage( |
| 677 |
+3
| --- fossil/views.py | ||
| +++ fossil/views.py | ||
| @@ -442,17 +442,20 @@ | ||
| 442 | 442 | ticket = reader.get_ticket_detail(ticket_uuid) |
| 443 | 443 | |
| 444 | 444 | if not ticket: |
| 445 | 445 | raise Http404("Ticket not found") |
| 446 | 446 | |
| 447 | + body_html = mark_safe(_render_fossil_content(ticket.body, project_slug=slug)) if ticket.body else "" | |
| 448 | + | |
| 447 | 449 | return render( |
| 448 | 450 | request, |
| 449 | 451 | "fossil/ticket_detail.html", |
| 450 | 452 | { |
| 451 | 453 | "project": project, |
| 452 | 454 | "fossil_repo": fossil_repo, |
| 453 | 455 | "ticket": ticket, |
| 456 | + "body_html": body_html, | |
| 454 | 457 | "active_tab": "tickets", |
| 455 | 458 | }, |
| 456 | 459 | ) |
| 457 | 460 | |
| 458 | 461 | |
| 459 | 462 |
| --- fossil/views.py | |
| +++ fossil/views.py | |
| @@ -442,17 +442,20 @@ | |
| 442 | ticket = reader.get_ticket_detail(ticket_uuid) |
| 443 | |
| 444 | if not ticket: |
| 445 | raise Http404("Ticket not found") |
| 446 | |
| 447 | return render( |
| 448 | request, |
| 449 | "fossil/ticket_detail.html", |
| 450 | { |
| 451 | "project": project, |
| 452 | "fossil_repo": fossil_repo, |
| 453 | "ticket": ticket, |
| 454 | "active_tab": "tickets", |
| 455 | }, |
| 456 | ) |
| 457 | |
| 458 | |
| 459 |
| --- fossil/views.py | |
| +++ fossil/views.py | |
| @@ -442,17 +442,20 @@ | |
| 442 | ticket = reader.get_ticket_detail(ticket_uuid) |
| 443 | |
| 444 | if not ticket: |
| 445 | raise Http404("Ticket not found") |
| 446 | |
| 447 | body_html = mark_safe(_render_fossil_content(ticket.body, project_slug=slug)) if ticket.body else "" |
| 448 | |
| 449 | return render( |
| 450 | request, |
| 451 | "fossil/ticket_detail.html", |
| 452 | { |
| 453 | "project": project, |
| 454 | "fossil_repo": fossil_repo, |
| 455 | "ticket": ticket, |
| 456 | "body_html": body_html, |
| 457 | "active_tab": "tickets", |
| 458 | }, |
| 459 | ) |
| 460 | |
| 461 | |
| 462 |
| --- templates/fossil/ticket_detail.html | ||
| +++ templates/fossil/ticket_detail.html | ||
| @@ -56,14 +56,14 @@ | ||
| 56 | 56 | </div> |
| 57 | 57 | </dl> |
| 58 | 58 | </div> |
| 59 | 59 | |
| 60 | 60 | <!-- Body/description --> |
| 61 | - {% if ticket.body %} | |
| 61 | + {% if body_html %} | |
| 62 | 62 | <div class="px-6 py-5"> |
| 63 | 63 | <div class="prose prose-invert prose-gray prose-sm max-w-none"> |
| 64 | - {{ ticket.body|linebreaksbr }} | |
| 64 | + {{ body_html }} | |
| 65 | 65 | </div> |
| 66 | 66 | </div> |
| 67 | 67 | {% endif %} |
| 68 | 68 | </div> |
| 69 | 69 | {% endblock %} |
| 70 | 70 |
| --- templates/fossil/ticket_detail.html | |
| +++ templates/fossil/ticket_detail.html | |
| @@ -56,14 +56,14 @@ | |
| 56 | </div> |
| 57 | </dl> |
| 58 | </div> |
| 59 | |
| 60 | <!-- Body/description --> |
| 61 | {% if ticket.body %} |
| 62 | <div class="px-6 py-5"> |
| 63 | <div class="prose prose-invert prose-gray prose-sm max-w-none"> |
| 64 | {{ ticket.body|linebreaksbr }} |
| 65 | </div> |
| 66 | </div> |
| 67 | {% endif %} |
| 68 | </div> |
| 69 | {% endblock %} |
| 70 |
| --- templates/fossil/ticket_detail.html | |
| +++ templates/fossil/ticket_detail.html | |
| @@ -56,14 +56,14 @@ | |
| 56 | </div> |
| 57 | </dl> |
| 58 | </div> |
| 59 | |
| 60 | <!-- Body/description --> |
| 61 | {% if body_html %} |
| 62 | <div class="px-6 py-5"> |
| 63 | <div class="prose prose-invert prose-gray prose-sm max-w-none"> |
| 64 | {{ body_html }} |
| 65 | </div> |
| 66 | </div> |
| 67 | {% endif %} |
| 68 | </div> |
| 69 | {% endblock %} |
| 70 |
| --- templates/fossil/user_activity.html | ||
| +++ templates/fossil/user_activity.html | ||
| @@ -40,39 +40,39 @@ | ||
| 40 | 40 | |
| 41 | 41 | <!-- Sidebar stats --> |
| 42 | 42 | <div> |
| 43 | 43 | <div class="rounded-lg bg-gray-800 border border-gray-700 p-4"> |
| 44 | 44 | <h3 class="text-sm font-medium text-gray-300 mb-3">Contributions</h3> |
| 45 | - <div class="space-y-2"> | |
| 46 | - <div class="flex items-center justify-between"> | |
| 45 | + <div class="space-y-1"> | |
| 46 | + <a href="{% url 'fossil:timeline' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> | |
| 47 | 47 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 48 | 48 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> |
| 49 | 49 | Checkins |
| 50 | 50 | </span> |
| 51 | 51 | <span class="text-sm font-medium text-gray-200">{{ activity.checkin_count }}</span> |
| 52 | - </div> | |
| 53 | - <div class="flex items-center justify-between"> | |
| 52 | + </a> | |
| 53 | + <a href="{% url 'fossil:tickets' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> | |
| 54 | 54 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 55 | 55 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z" /></svg> |
| 56 | 56 | Ticket changes |
| 57 | 57 | </span> |
| 58 | 58 | <span class="text-sm font-medium text-gray-200">{{ activity.ticket_count }}</span> |
| 59 | - </div> | |
| 60 | - <div class="flex items-center justify-between"> | |
| 59 | + </a> | |
| 60 | + <a href="{% url 'fossil:wiki' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> | |
| 61 | 61 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 62 | 62 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /></svg> |
| 63 | 63 | Wiki edits |
| 64 | 64 | </span> |
| 65 | 65 | <span class="text-sm font-medium text-gray-200">{{ activity.wiki_count }}</span> |
| 66 | - </div> | |
| 67 | - <div class="flex items-center justify-between"> | |
| 66 | + </a> | |
| 67 | + <a href="{% url 'fossil:forum' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> | |
| 68 | 68 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 69 | 69 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" /></svg> |
| 70 | 70 | Forum posts |
| 71 | 71 | </span> |
| 72 | 72 | <span class="text-sm font-medium text-gray-200">{{ activity.forum_count }}</span> |
| 73 | - </div> | |
| 73 | + </a> | |
| 74 | 74 | </div> |
| 75 | 75 | </div> |
| 76 | 76 | </div> |
| 77 | 77 | </div> |
| 78 | 78 | {% endblock %} |
| 79 | 79 |
| --- templates/fossil/user_activity.html | |
| +++ templates/fossil/user_activity.html | |
| @@ -40,39 +40,39 @@ | |
| 40 | |
| 41 | <!-- Sidebar stats --> |
| 42 | <div> |
| 43 | <div class="rounded-lg bg-gray-800 border border-gray-700 p-4"> |
| 44 | <h3 class="text-sm font-medium text-gray-300 mb-3">Contributions</h3> |
| 45 | <div class="space-y-2"> |
| 46 | <div class="flex items-center justify-between"> |
| 47 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 48 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> |
| 49 | Checkins |
| 50 | </span> |
| 51 | <span class="text-sm font-medium text-gray-200">{{ activity.checkin_count }}</span> |
| 52 | </div> |
| 53 | <div class="flex items-center justify-between"> |
| 54 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 55 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z" /></svg> |
| 56 | Ticket changes |
| 57 | </span> |
| 58 | <span class="text-sm font-medium text-gray-200">{{ activity.ticket_count }}</span> |
| 59 | </div> |
| 60 | <div class="flex items-center justify-between"> |
| 61 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 62 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /></svg> |
| 63 | Wiki edits |
| 64 | </span> |
| 65 | <span class="text-sm font-medium text-gray-200">{{ activity.wiki_count }}</span> |
| 66 | </div> |
| 67 | <div class="flex items-center justify-between"> |
| 68 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 69 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" /></svg> |
| 70 | Forum posts |
| 71 | </span> |
| 72 | <span class="text-sm font-medium text-gray-200">{{ activity.forum_count }}</span> |
| 73 | </div> |
| 74 | </div> |
| 75 | </div> |
| 76 | </div> |
| 77 | </div> |
| 78 | {% endblock %} |
| 79 |
| --- templates/fossil/user_activity.html | |
| +++ templates/fossil/user_activity.html | |
| @@ -40,39 +40,39 @@ | |
| 40 | |
| 41 | <!-- Sidebar stats --> |
| 42 | <div> |
| 43 | <div class="rounded-lg bg-gray-800 border border-gray-700 p-4"> |
| 44 | <h3 class="text-sm font-medium text-gray-300 mb-3">Contributions</h3> |
| 45 | <div class="space-y-1"> |
| 46 | <a href="{% url 'fossil:timeline' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> |
| 47 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 48 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg> |
| 49 | Checkins |
| 50 | </span> |
| 51 | <span class="text-sm font-medium text-gray-200">{{ activity.checkin_count }}</span> |
| 52 | </a> |
| 53 | <a href="{% url 'fossil:tickets' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> |
| 54 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 55 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z" /></svg> |
| 56 | Ticket changes |
| 57 | </span> |
| 58 | <span class="text-sm font-medium text-gray-200">{{ activity.ticket_count }}</span> |
| 59 | </a> |
| 60 | <a href="{% url 'fossil:wiki' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> |
| 61 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 62 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /></svg> |
| 63 | Wiki edits |
| 64 | </span> |
| 65 | <span class="text-sm font-medium text-gray-200">{{ activity.wiki_count }}</span> |
| 66 | </a> |
| 67 | <a href="{% url 'fossil:forum' slug=project.slug %}" class="flex items-center justify-between rounded-md px-2 py-1.5 hover:bg-gray-700/50"> |
| 68 | <span class="flex items-center gap-2 text-sm text-gray-400"> |
| 69 | <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" /></svg> |
| 70 | Forum posts |
| 71 | </span> |
| 72 | <span class="text-sm font-medium text-gray-200">{{ activity.forum_count }}</span> |
| 73 | </a> |
| 74 | </div> |
| 75 | </div> |
| 76 | </div> |
| 77 | </div> |
| 78 | {% endblock %} |
| 79 |