cerrado @ b71c6c0e5b8dd00d44e40ac0551902a23cbe19d5

feat: Add summary page
  1diff --git a/pkg/git/git.go b/pkg/git/git.go
  2index 428bfb164e78ca7e8055097fbe77a31b985e5da4..b725cd875a2615e043e4b15cad5b6bfc98860a85 100644
  3--- a/pkg/git/git.go
  4+++ b/pkg/git/git.go
  5@@ -77,7 +77,7 @@ 	}
  6 	return c, nil
  7 }
  8 
  9-func (g *GitRepository) Commits() ([]*object.Commit, error) {
 10+func (g *GitRepository) Commits(count int) ([]*object.Commit, error) {
 11 	err := g.validateRef()
 12 	if err != nil {
 13 		return nil, err
 14@@ -90,7 +90,7 @@ 	}
 15 
 16 	commits := []*object.Commit{}
 17 	// TODO: for now only load first 1000
 18-	for x := 0; x < 1000; x++ {
 19+	for x := 0; x < count; x++ {
 20 		c, err := ci.Next()
 21 		if err != nil && errors.Is(err, io.EOF) {
 22 			break
 23diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
 24index 48093629296b5531caef1fe0e4736576b205fca6..899f61ee30eab7f322c42d25636de59791763221 100644
 25--- a/pkg/handler/git/handler.go
 26+++ b/pkg/handler/git/handler.go
 27@@ -29,7 +29,7 @@ 	}
 28 
 29 	gitService interface {
 30 		ListRepositories() ([]*service.Repository, error)
 31-		ListCommits(name string, ref string) ([]*object.Commit, error)
 32+		ListCommits(name string, ref string, count int) ([]*object.Commit, error)
 33 		GetHead(name string) (*plumbing.Reference, error)
 34 		GetTree(name, ref, path string) (*object.Tree, error)
 35 		GetFileContent(name, ref, path string) (string, error)
 36@@ -91,10 +91,29 @@ 	if err != nil {
 37 		return err
 38 	}
 39 
 40+	tags, err := g.gitService.ListTags(name)
 41+	if err != nil {
 42+		return err
 43+	}
 44+
 45+	branches, err := g.gitService.ListBranches(name)
 46+	if err != nil {
 47+		return err
 48+	}
 49+
 50+	commits, err := g.gitService.ListCommits(name, "", 10)
 51+	if err != nil {
 52+		return err
 53+	}
 54+
 55 	gitList := &templates.GitItemPage{
 56-		Name:        name,
 57-		Ref:         ref.Name().Short(),
 58-		GitItemBase: &templates.GitItemSummaryPage{},
 59+		Name: name,
 60+		Ref:  ref.Name().Short(),
 61+		GitItemBase: &templates.GitItemSummaryPage{
 62+			Tags:     tags,
 63+			Branches: branches,
 64+			Commits:  commits,
 65+		},
 66 	}
 67 	templates.WritePageTemplate(w, gitList)
 68 	return nil
 69@@ -215,7 +234,7 @@ 	ext.SetHTML(w)
 70 	name := r.PathValue("name")
 71 	ref := r.PathValue("ref")
 72 
 73-	commits, err := g.gitService.ListCommits(name, ref)
 74+	commits, err := g.gitService.ListCommits(name, ref, 1000)
 75 	if err != nil {
 76 		return err
 77 	}
 78diff --git a/pkg/service/git.go b/pkg/service/git.go
 79index 071e10d640e86887901e442c608f898fa6058ffe..2165abef8acdfbe13d4831c7e6e0c2556678b004 100644
 80--- a/pkg/service/git.go
 81+++ b/pkg/service/git.go
 82@@ -74,7 +74,7 @@
 83 	return repos, nil
 84 }
 85 
 86-func (g *GitService) ListCommits(name, ref string) ([]*object.Commit, error) {
 87+func (g *GitService) ListCommits(name, ref string, count int) ([]*object.Commit, error) {
 88 	r := g.configRepo.GetByName(name)
 89 	if r == nil {
 90 		return nil, RepositoryNotFoundErr
 91@@ -89,7 +89,7 @@ 	err = repo.SetRef(ref)
 92 	if err != nil {
 93 		return nil, err
 94 	}
 95-	return repo.Commits()
 96+	return repo.Commits(count)
 97 }
 98 
 99 func (g *GitService) GetTree(name, ref, path string) (*object.Tree, error) {
100diff --git a/scss/main.scss b/scss/main.scss
101index af8a00210b514e60d9459176b42217b525a24b92..107a4c8231a96c66e05ffc6cc91dda311568a367 100644
102--- a/scss/main.scss
103+++ b/scss/main.scss
104@@ -114,35 +114,6 @@     display: grid;
105     overflow-x: auto;
106 }
107 
108-.logs {
109-  >div {
110-    background: #f8f9fa;
111-  }
112-
113-  >div {
114-    padding: 5px;
115-    margin: $spacer;
116-  }
117-
118-  @include media-breakpoint-down(md) {
119-    >div {
120-      margin: $spacer 0 $spacer 0;
121-    }
122-  }
123-
124-  pre {
125-    font-size: $base-font-size;
126-    margin: 0;
127-  }
128-}
129-
130-.logs>div>div:first-child {
131-  margin-bottom: 15px;
132-}
133-.logs>div>div:last-child {
134-  margin-top: 15px;
135-}
136-
137 #about {
138   padding: 0 $spacer $spacer $spacer;
139   > p:first-child {
140diff --git a/templates/gititemlog.qtpl b/templates/gititemlog.qtpl
141index 1af05ca2b19a2ef3bc21e3533ee7333425e21298..a28e7ad52cbd51c2cb6509b3f008116b61e7d8be 100644
142--- a/templates/gititemlog.qtpl
143+++ b/templates/gititemlog.qtpl
144@@ -9,9 +9,9 @@
145 {% func (g *GitItemLogPage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Log) %}{% endfunc %}
146 
147 {% func (g *GitItemLogPage) GitContent(name, ref string) %}
148-<div class="logs">
149+<div class="event-list">
150   {% for _, c := range g.Commits %}
151-  <div class="row">
152+  <div class="row event">
153       <div class="col-xxl-2">
154        {%s TimeFormat(c.Committer.When) %}
155       </div>
156diff --git a/templates/gititemlog.qtpl.go b/templates/gititemlog.qtpl.go
157index 185b1538470f819fe06465b82a2d762fc279962a..76c24329c241285809f56a6a9014e1e4274d47bb 100644
158--- a/templates/gititemlog.qtpl.go
159+++ b/templates/gititemlog.qtpl.go
160@@ -62,13 +62,13 @@ //line gititemlog.qtpl:11
161 func (g *GitItemLogPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
162 //line gititemlog.qtpl:11
163 	qw422016.N().S(`
164-<div class="logs">
165+<div class="event-list">
166   `)
167 //line gititemlog.qtpl:13
168 	for _, c := range g.Commits {
169 //line gititemlog.qtpl:13
170 		qw422016.N().S(`
171-  <div class="row">
172+  <div class="row event">
173       <div class="col-xxl-2">
174        `)
175 //line gititemlog.qtpl:16
176diff --git a/templates/gititemsummary.qtpl b/templates/gititemsummary.qtpl
177index 4cbf324c71e3d0d1d627e029553b682dd46feee5..9a3e2ee56526ef12d8b10e699d8ca98a3446cb88 100644
178--- a/templates/gititemsummary.qtpl
179+++ b/templates/gititemsummary.qtpl
180@@ -1,10 +1,72 @@
181+{% import "github.com/go-git/go-git/v5/plumbing" %}
182+{% import "github.com/go-git/go-git/v5/plumbing/object" %}
183+
184 {% code
185 type GitItemSummaryPage struct {
186+    Tags []*plumbing.Reference
187+    Branches []*plumbing.Reference
188+    Commits []*object.Commit
189 }
190 %}
191 
192 {% func (g *GitItemSummaryPage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Summary) %}{% endfunc %}
193 
194 {% func (g *GitItemSummaryPage) GitContent(name, ref string) %}
195-<h4>Summary</h4>
196+<div class="row">
197+  <div class="col-md-8">
198+    {% if len(g.Tags) > 0 %}
199+    <div class="event-list">
200+      {% for _, t := range g.Tags %}
201+      <div class="row event me-md-2">
202+          <div class="col-4">
203+           {%s t.Name().Short() %}
204+          </div>
205+          <div class="col-8">
206+            <div class="float-end">
207+              <a href="/{%s name %}/tree/{%s t.Name().Short() %}">tree</a>
208+              <a href="/{%s name %}/log/{%s t.Name().Short() %}">log</a>
209+            </div>
210+          </div>
211+      </div>
212+      {% endfor %}
213+    </div>
214+    {% else %}
215+        <p> No tags </p>
216+    {% endif %}
217+  </div>
218+  <div class="col-md-4">
219+    <div class="event-list">
220+      {% for _, b := range g.Branches %}
221+      <div class="row event">
222+          <div class="col-4">
223+           {%s b.Name().Short() %}
224+          </div>
225+          <div class="col-8">
226+            <div class="float-end">
227+              <a href="/{%s name %}/tree/{%s b.Name().Short() %}">tree</a>
228+              <a href="/{%s name %}/log/{%s b.Name().Short() %}">log</a>
229+            </div>
230+          </div>
231+      </div>
232+      {% endfor %}
233+    </div>
234+  </div>
235+</div>
236+<div class="row">
237+  <div class="event-list">
238+    {% for _, c := range g.Commits %}
239+    <div class="row event">
240+        <div class="col-xxl-2">
241+         {%s TimeFormat(c.Committer.When) %}
242+        </div>
243+        <div class="col-xxl-7 code-view">
244+         <pre>{%s c.Message %}</pre>
245+        </div>
246+        <div class="col-xxl-3">
247+         <small>{%s c.Committer.Name %} &lt;{%s c.Committer.Email %}&gt;</small>
248+        </div>
249+    </div>
250+    {% endfor %}
251+  </div>
252+</div>
253 {% endfunc %}
254diff --git a/templates/gititemsummary.qtpl.go b/templates/gititemsummary.qtpl.go
255index d8606a58c8b3d823a2ab6a293f0073fae603a7fa..cf1c07cac00b465234917bc9e5a92e2ec7eab62b 100644
256--- a/templates/gititemsummary.qtpl.go
257+++ b/templates/gititemsummary.qtpl.go
258@@ -5,86 +5,243 @@ //line gititemsummary.qtpl:1
259 package templates
260 
261 //line gititemsummary.qtpl:1
262+import "github.com/go-git/go-git/v5/plumbing"
263+
264+//line gititemsummary.qtpl:2
265+import "github.com/go-git/go-git/v5/plumbing/object"
266+
267+//line gititemsummary.qtpl:4
268 import (
269 	qtio422016 "io"
270 
271 	qt422016 "github.com/valyala/quicktemplate"
272 )
273 
274-//line gititemsummary.qtpl:1
275+//line gititemsummary.qtpl:4
276 var (
277 	_ = qtio422016.Copy
278 	_ = qt422016.AcquireByteBuffer
279 )
280 
281-//line gititemsummary.qtpl:2
282+//line gititemsummary.qtpl:5
283 type GitItemSummaryPage struct {
284+	Tags     []*plumbing.Reference
285+	Branches []*plumbing.Reference
286+	Commits  []*object.Commit
287 }
288 
289-//line gititemsummary.qtpl:6
290+//line gititemsummary.qtpl:12
291 func (g *GitItemSummaryPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
292-//line gititemsummary.qtpl:6
293+//line gititemsummary.qtpl:12
294 	StreamGitItemNav(qw422016, name, ref, Summary)
295-//line gititemsummary.qtpl:6
296+//line gititemsummary.qtpl:12
297 }
298 
299-//line gititemsummary.qtpl:6
300+//line gititemsummary.qtpl:12
301 func (g *GitItemSummaryPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
302-//line gititemsummary.qtpl:6
303+//line gititemsummary.qtpl:12
304 	qw422016 := qt422016.AcquireWriter(qq422016)
305-//line gititemsummary.qtpl:6
306+//line gititemsummary.qtpl:12
307 	g.StreamNav(qw422016, name, ref)
308-//line gititemsummary.qtpl:6
309+//line gititemsummary.qtpl:12
310 	qt422016.ReleaseWriter(qw422016)
311-//line gititemsummary.qtpl:6
312+//line gititemsummary.qtpl:12
313 }
314 
315-//line gititemsummary.qtpl:6
316+//line gititemsummary.qtpl:12
317 func (g *GitItemSummaryPage) Nav(name, ref string) string {
318-//line gititemsummary.qtpl:6
319+//line gititemsummary.qtpl:12
320 	qb422016 := qt422016.AcquireByteBuffer()
321-//line gititemsummary.qtpl:6
322+//line gititemsummary.qtpl:12
323 	g.WriteNav(qb422016, name, ref)
324-//line gititemsummary.qtpl:6
325+//line gititemsummary.qtpl:12
326 	qs422016 := string(qb422016.B)
327-//line gititemsummary.qtpl:6
328+//line gititemsummary.qtpl:12
329 	qt422016.ReleaseByteBuffer(qb422016)
330-//line gititemsummary.qtpl:6
331+//line gititemsummary.qtpl:12
332 	return qs422016
333-//line gititemsummary.qtpl:6
334+//line gititemsummary.qtpl:12
335 }
336 
337-//line gititemsummary.qtpl:8
338+//line gititemsummary.qtpl:14
339 func (g *GitItemSummaryPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
340-//line gititemsummary.qtpl:8
341+//line gititemsummary.qtpl:14
342+	qw422016.N().S(`
343+<div class="row">
344+  <div class="col-md-8">
345+    `)
346+//line gititemsummary.qtpl:17
347+	if len(g.Tags) > 0 {
348+//line gititemsummary.qtpl:17
349+		qw422016.N().S(`
350+    <div class="event-list">
351+      `)
352+//line gititemsummary.qtpl:19
353+		for _, t := range g.Tags {
354+//line gititemsummary.qtpl:19
355+			qw422016.N().S(`
356+      <div class="row event me-md-2">
357+          <div class="col-4">
358+           `)
359+//line gititemsummary.qtpl:22
360+			qw422016.E().S(t.Name().Short())
361+//line gititemsummary.qtpl:22
362+			qw422016.N().S(`
363+          </div>
364+          <div class="col-8">
365+            <div class="float-end">
366+              <a href="/`)
367+//line gititemsummary.qtpl:26
368+			qw422016.E().S(name)
369+//line gititemsummary.qtpl:26
370+			qw422016.N().S(`/tree/`)
371+//line gititemsummary.qtpl:26
372+			qw422016.E().S(t.Name().Short())
373+//line gititemsummary.qtpl:26
374+			qw422016.N().S(`">tree</a>
375+              <a href="/`)
376+//line gititemsummary.qtpl:27
377+			qw422016.E().S(name)
378+//line gititemsummary.qtpl:27
379+			qw422016.N().S(`/log/`)
380+//line gititemsummary.qtpl:27
381+			qw422016.E().S(t.Name().Short())
382+//line gititemsummary.qtpl:27
383+			qw422016.N().S(`">log</a>
384+            </div>
385+          </div>
386+      </div>
387+      `)
388+//line gititemsummary.qtpl:31
389+		}
390+//line gititemsummary.qtpl:31
391+		qw422016.N().S(`
392+    </div>
393+    `)
394+//line gititemsummary.qtpl:33
395+	} else {
396+//line gititemsummary.qtpl:33
397+		qw422016.N().S(`
398+        <p> No tags </p>
399+    `)
400+//line gititemsummary.qtpl:35
401+	}
402+//line gititemsummary.qtpl:35
403+	qw422016.N().S(`
404+  </div>
405+  <div class="col-md-4">
406+    <div class="event-list">
407+      `)
408+//line gititemsummary.qtpl:39
409+	for _, b := range g.Branches {
410+//line gititemsummary.qtpl:39
411+		qw422016.N().S(`
412+      <div class="row event">
413+          <div class="col-4">
414+           `)
415+//line gititemsummary.qtpl:42
416+		qw422016.E().S(b.Name().Short())
417+//line gititemsummary.qtpl:42
418+		qw422016.N().S(`
419+          </div>
420+          <div class="col-8">
421+            <div class="float-end">
422+              <a href="/`)
423+//line gititemsummary.qtpl:46
424+		qw422016.E().S(name)
425+//line gititemsummary.qtpl:46
426+		qw422016.N().S(`/tree/`)
427+//line gititemsummary.qtpl:46
428+		qw422016.E().S(b.Name().Short())
429+//line gititemsummary.qtpl:46
430+		qw422016.N().S(`">tree</a>
431+              <a href="/`)
432+//line gititemsummary.qtpl:47
433+		qw422016.E().S(name)
434+//line gititemsummary.qtpl:47
435+		qw422016.N().S(`/log/`)
436+//line gititemsummary.qtpl:47
437+		qw422016.E().S(b.Name().Short())
438+//line gititemsummary.qtpl:47
439+		qw422016.N().S(`">log</a>
440+            </div>
441+          </div>
442+      </div>
443+      `)
444+//line gititemsummary.qtpl:51
445+	}
446+//line gititemsummary.qtpl:51
447+	qw422016.N().S(`
448+    </div>
449+  </div>
450+</div>
451+<div class="row">
452+  <div class="event-list">
453+    `)
454+//line gititemsummary.qtpl:57
455+	for _, c := range g.Commits {
456+//line gititemsummary.qtpl:57
457+		qw422016.N().S(`
458+    <div class="row event">
459+        <div class="col-xxl-2">
460+         `)
461+//line gititemsummary.qtpl:60
462+		qw422016.E().S(TimeFormat(c.Committer.When))
463+//line gititemsummary.qtpl:60
464+		qw422016.N().S(`
465+        </div>
466+        <div class="col-xxl-7 code-view">
467+         <pre>`)
468+//line gititemsummary.qtpl:63
469+		qw422016.E().S(c.Message)
470+//line gititemsummary.qtpl:63
471+		qw422016.N().S(`</pre>
472+        </div>
473+        <div class="col-xxl-3">
474+         <small>`)
475+//line gititemsummary.qtpl:66
476+		qw422016.E().S(c.Committer.Name)
477+//line gititemsummary.qtpl:66
478+		qw422016.N().S(` &lt;`)
479+//line gititemsummary.qtpl:66
480+		qw422016.E().S(c.Committer.Email)
481+//line gititemsummary.qtpl:66
482+		qw422016.N().S(`&gt;</small>
483+        </div>
484+    </div>
485+    `)
486+//line gititemsummary.qtpl:69
487+	}
488+//line gititemsummary.qtpl:69
489 	qw422016.N().S(`
490-<h4>Summary</h4>
491+  </div>
492+</div>
493 `)
494-//line gititemsummary.qtpl:10
495+//line gititemsummary.qtpl:72
496 }
497 
498-//line gititemsummary.qtpl:10
499+//line gititemsummary.qtpl:72
500 func (g *GitItemSummaryPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) {
501-//line gititemsummary.qtpl:10
502+//line gititemsummary.qtpl:72
503 	qw422016 := qt422016.AcquireWriter(qq422016)
504-//line gititemsummary.qtpl:10
505+//line gititemsummary.qtpl:72
506 	g.StreamGitContent(qw422016, name, ref)
507-//line gititemsummary.qtpl:10
508+//line gititemsummary.qtpl:72
509 	qt422016.ReleaseWriter(qw422016)
510-//line gititemsummary.qtpl:10
511+//line gititemsummary.qtpl:72
512 }
513 
514-//line gititemsummary.qtpl:10
515+//line gititemsummary.qtpl:72
516 func (g *GitItemSummaryPage) GitContent(name, ref string) string {
517-//line gititemsummary.qtpl:10
518+//line gititemsummary.qtpl:72
519 	qb422016 := qt422016.AcquireByteBuffer()
520-//line gititemsummary.qtpl:10
521+//line gititemsummary.qtpl:72
522 	g.WriteGitContent(qb422016, name, ref)
523-//line gititemsummary.qtpl:10
524+//line gititemsummary.qtpl:72
525 	qs422016 := string(qb422016.B)
526-//line gititemsummary.qtpl:10
527+//line gititemsummary.qtpl:72
528 	qt422016.ReleaseByteBuffer(qb422016)
529-//line gititemsummary.qtpl:10
530+//line gititemsummary.qtpl:72
531 	return qs422016
532-//line gititemsummary.qtpl:10
533+//line gititemsummary.qtpl:72
534 }