~pepe/neil

de783ced8276e23d68a9b540011f2a536c658cc8 — Josef Pospíšil a month ago 5b0912e
Refactor stat line
3 files changed, 188 insertions(+), 222 deletions(-)

M public/main.css
M templates/stats.temple
A templates/work-intervals/stat-line.temple
M public/main.css => public/main.css +16 -0
@@ 95,6 95,22 @@ footer {
  height: 20rem;
}

#stats table {
  margin-bottom: 3rem;
}

.stat-line td {
  width: 12.5%
}

.stat-line .task {
  width: 45%
}

.stat-line .project {
  width: 17.5%
}

@-webkit-keyframes sk-scaleout {
  0% { -webkit-transform: scale(0) }
  100% {

M templates/stats.temple => templates/stats.temple +161 -222
@@ 2,6 2,7 @@
  (use /neil/utils)
  (use bearimy)
  (use bearimy/utils)
  (import /templates/work-intervals/stat-line)
$}
{%
  (def {:worked-tasks wts


@@ 10,226 11,164 @@ $}
        :clients clients} args )
  (def td (today))
%}
<h1>Work statistics</h1>

<h2>Day</h2>
<h3>Today</h3>
<h4>{{ (format-interval (wis :today)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :today)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (> (w :start) (:epoch td))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h3>Yesterday</h3>
<h4>{{ (format-interval (wis :yesterday)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :yesterday)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (and
                                 (> (w :start) (yesterday))
                                 (< (w :end) (:epoch td)))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h2>Week</h2>
<h3>Current</h3>
<h4>{{ (format-interval (wis :week)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :week)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (> (w :start) (:epoch (:sooner (make-calendar td) (days (td :week-day)))))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h3>Last</h3>
<h4>{{ (format-interval (wis :last-week)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :last-week)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (and
                                 (> (w :start) (:epoch (last-week-start)))
                                 (< (w :end) (:epoch (current-week-start))))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h2>Month</h2>
<h3>Current</h3>
<h4>{{ (format-interval (wis :month)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :month)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (> (w :start) (:epoch (current-month-start)))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h3>Last</h3>
<h4>{{ (format-interval (wis :last-month)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :last-month)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (and
                                 (> (w :start) (:epoch (last-month-start)))
                                 (< (w :end) (:epoch (current-month-start))))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h2>Quarter</h2>
<h3>Current</h3>
<h4>{{ (format-interval (wis :quarter)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :quarter)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (> (w :start) (:epoch (current-quarter-start)))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h3>Last</h3>
<h4>{{ (format-interval (wis :last-quarter)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :last-quarter)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (and
                                 (> (w :start) (:epoch (last-quarter-start)))
                                 (< (w :end) (:epoch (current-quarter-start))))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>
<h2>Year</h2>
<h3>Current</h3>
<h4>{{ (format-interval (wis :year)) }}</h4>
<table>
<tbody>
  {% (loop [{:uuid i :name n :project pi
             :work-intervals wi :state st} :in (wts :year)
            :let [{:name pn :client pc} (projects pi)
                  {:name cn} (clients pc)]] %}
    <tr>
      <td>${{ cn }}</td>
      <td>@{{ pn }}</td>
      <td>#{{ (. i " " n) }}</td>
      <td>{{ st }}</td>
      <td>{{ (format-interval
               (reduce + 0
                 (seq [w :in wi
                         :when (> (w :start) (:epoch (current-year-start)))]
                   (- (or (w :end) (os/time)) (w :start))))) }}</td>
    </tr>

  {% ) %}
</tbody>
</table>

<vstack id="stats">
  <h1>Work statistics</h1>
  <h2>Day</h2>
  <h3>Today {{ (format-interval (wis :today)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :today)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (> (w :start) (:epoch td))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h3>Yesterday {{ (format-interval (wis :yesterday)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :yesterday)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (and
                                            (> (w :start) (:epoch (yesterday)))
                                            (< (w :end) (:epoch td)))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
         (stat-line/render :client-name cn :project-name pn
                           :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h2>Week</h2>
  <h3>Current {{ (format-interval (wis :week)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :week)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (> (w :start) (:epoch (:sooner (make-calendar td) (days (td :week-day)))))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h3>Last {{ (format-interval (wis :last-week)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :last-week)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (and
                                            (> (w :start) (:epoch (last-week-start)))
                                            (< (w :end) (:epoch (current-week-start))))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h2>Month</h2>
  <h3>Current {{ (format-interval (wis :month)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :month)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (> (w :start) (:epoch (current-month-start)))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h3>Last {{ (format-interval (wis :last-month)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :last-month)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (and
                                            (> (w :start) (:epoch (last-month-start)))
                                            (< (w :end) (:epoch (current-month-start))))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h2>Quarter</h2>
  <h3>Current {{ (format-interval (wis :quarter)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :quarter)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (> (w :start) (:epoch (current-quarter-start)))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h3>Last {{ (format-interval (wis :last-quarter)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :last-quarter)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (and
                                            (> (w :start) (:epoch (last-quarter-start)))
                                            (< (w :end) (:epoch (current-quarter-start))))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
  <h2>Year</h2>
  <h3>Current {{ (format-interval (wis :year)) }}</h3>
  <table>
  <tbody>
    {% (loop [{:uuid i :name n :project pi
               :work-intervals wi :state st} :in (wts :year)
              :let [{:name pn :client pc} (projects pi)
                    {:name cn} (clients pc)
                    dur (format-interval
                          (reduce + 0
                            (seq [w :in wi
                                    :when (> (w :start) (:epoch (current-year-start)))]
                              (- (or (w :end) (os/time)) (w :start)))))]]
          (stat-line/render :client-name cn :project-name pn
                            :uuid i :name n :state st :duration dur)) %}
  </tbody>
  </table>
</vstack>

A templates/work-intervals/stat-line.temple => templates/work-intervals/stat-line.temple +11 -0
@@ 0,0 1,11 @@
{$
  (use /neil/utils)
$}
<tr class="stat-line">
  <td>${{ (args :client-name) }}</td>
  <td class="project">@{{ (args :project-name) }}</td>
  <td class="task">#{{ (. (args :uuid) " " (args :name)) }}</td>
  <td>{{ (args :state) }}</td>
  <td>{{ (args :duration) }}</td>
</tr>