mirror of
https://github.com/penpot/penpot.git
synced 2026-10-30 06:20:32 +00:00
✨ Show the export queued, then progress as a percentage
The widget could never say queued: the creation answers the row status (`pending`) and the widget only knew `queued`, so every export opened on the generic exporting wording. The widget now names a fresh job queued, and only the first milestone moves it to running — the worker sends that first breath right after the claim, before the session roundtrip. The figure is a percentage once the worker said how much there is, and nothing while it has not: a milestone without counters names the stage but no longer blanks the figures, and the queued and terminal states show no counter at all. AI-assisted-by: glm-5.3-flash
This commit is contained in:
parent
a63140d309
commit
74f8d563b4
@ -360,15 +360,19 @@
|
||||
;; registered a terminate callback for this job
|
||||
(jobs/mark-cancelled job-id))]
|
||||
(p/catch
|
||||
(p/let [session' (api/create-job-session job-id)
|
||||
(p/let [beats (start-beats! job-id stop-cmd!)
|
||||
beats! (:beat! beats)
|
||||
_ (reset! stop-watchdog! (with-watchdog! beats! (:last beats)))
|
||||
;; the first breath right after the claim, before the
|
||||
;; session roundtrip: the widget moves from queued to
|
||||
;; exporting on it, and a cancel that landed meanwhile
|
||||
;; raises here instead of after wasted work
|
||||
_ (check-beat! (beats! :preparing {} :force? true))
|
||||
session' (api/create-job-session job-id)
|
||||
_ (reset! session session')
|
||||
token (:session-token session')
|
||||
_ (l/info :hint "render session minted"
|
||||
:job-id (str job-id))
|
||||
beats (start-beats! job-id stop-cmd!)
|
||||
beats! (:beat! beats)
|
||||
_ (reset! stop-watchdog! (with-watchdog! beats! (:last beats)))
|
||||
_ (check-beat! (beats! :preparing {} :force? true))
|
||||
plan (make-plan job-id token params)
|
||||
resource (run-prepared! beats! cancelled plan)
|
||||
_ (@stop-watchdog!)
|
||||
|
||||
@ -256,9 +256,9 @@
|
||||
respond! (fake-fetch! (answer-with params sid stages))
|
||||
restore! (fake-render! "rendered!")]
|
||||
(p/let [_ (worker/process! (run-claim job-id))]
|
||||
(t/testing "the run went by claim, session, beats, settle"
|
||||
(t/is (= ["claim-job" "create-job-session"
|
||||
"report-job-progress" "report-job-progress" "report-job-progress"
|
||||
(t/testing "the run went by claim, first breath, session, beats, settle"
|
||||
(t/is (= ["claim-job" "report-job-progress" "create-job-session"
|
||||
"report-job-progress" "report-job-progress"
|
||||
"complete-job"]
|
||||
(steps-of))))
|
||||
(t/testing "the settle carried the real artifact, named and typed"
|
||||
|
||||
@ -154,7 +154,9 @@
|
||||
(defn- initialize-export-status
|
||||
"The state a just created job starts at: the widget shows it queued,
|
||||
with no figures yet — the counter comes with the first milestone the
|
||||
worker publishes, and counts itself down from the items meanwhile."
|
||||
worker publishes, and counts itself down from the items meanwhile.
|
||||
The creation answers the row status (`pending`): the widget names it
|
||||
queued, because nobody works on the job yet."
|
||||
[exports cmd {:keys [id status]}]
|
||||
(ptk/reify ::initialize-export-status
|
||||
ptk/UpdateEvent
|
||||
@ -169,7 +171,7 @@
|
||||
:last-update (ct/now)
|
||||
:cmd cmd
|
||||
:job-id id
|
||||
:status status}))))
|
||||
:status (if (= "pending" status) "queued" status)}))))
|
||||
|
||||
(defn- counter-of
|
||||
"The figures of one milestone: `objects` counts the shapes and
|
||||
@ -181,8 +183,11 @@
|
||||
|
||||
(defn- add-milestone
|
||||
"One beat of the job into the widget: what has landed and what is
|
||||
coming, named by the stage the run is in. A milestone that arrives
|
||||
once the widget settled from a cancel or an error is ignored."
|
||||
coming, named by the stage the run is in. The status moves to running
|
||||
on the first beat, figures or not. A milestone without figures (the
|
||||
first breath of the worker) names the stage but keeps the figures the
|
||||
widget already holds. A milestone that arrives once the widget
|
||||
settled from a cancel or an error is ignored."
|
||||
[payload]
|
||||
(let [figures (counter-of (:counters payload))]
|
||||
(ptk/reify ::add-milestone
|
||||
@ -190,13 +195,15 @@
|
||||
(update [_ state]
|
||||
(if-not (get-in state [:export :in-progress])
|
||||
state
|
||||
(update state :export assoc
|
||||
:status "running"
|
||||
:stage (:stage payload)
|
||||
:last-update (ct/now)
|
||||
:progress (:current figures)
|
||||
:total (or (:total figures)
|
||||
(get-in state [:export :total]))))))))
|
||||
(-> (update state :export assoc
|
||||
:status "running"
|
||||
:stage (:stage payload)
|
||||
:last-update (ct/now))
|
||||
(cond-> (some? figures)
|
||||
(update :export assoc
|
||||
:progress (:current figures)
|
||||
:total (or (:total figures)
|
||||
(get-in state [:export :total]))))))))))
|
||||
|
||||
(defn- add-outcome
|
||||
"The last row of the job as the end of the widget. A completed job
|
||||
|
||||
@ -246,11 +246,18 @@
|
||||
(not cancelling?))
|
||||
total (or (:total state) (count items))
|
||||
complete? (= progress total)
|
||||
;; The figure the detail names: a percentage when the worker
|
||||
;; said how much there is, nothing when it has not said yet
|
||||
;; (queued, or a milestone without counters).
|
||||
percent (when (and (number? progress)
|
||||
(number? total)
|
||||
(pos? total))
|
||||
(js/Math.round (* 100 (/ progress total))))
|
||||
circ (* 2 Math/PI 12)
|
||||
pct (if (zero? total) circ (- circ (* circ (/ progress total))))
|
||||
|
||||
pwidth
|
||||
(if error?
|
||||
(if (or error? (zero? total))
|
||||
280
|
||||
(/ (* progress 280) total))
|
||||
|
||||
@ -338,16 +345,22 @@
|
||||
[:button {:class (stl/css :retry-btn)
|
||||
:on-click cancel-export}
|
||||
(tr "workspace.options.cancel-export")]
|
||||
[:span {:class (stl/css :progress)}
|
||||
(dm/str progress " / " total)]]
|
||||
(when (some? percent)
|
||||
[:span {:class (stl/css :progress)}
|
||||
(dm/str percent "%")])]
|
||||
|
||||
;; A counter for work that is being abandoned says nothing useful.
|
||||
(or cancelling? cancelled?)
|
||||
;; A counter for work that is waiting, going away, or gone
|
||||
;; says nothing useful.
|
||||
(or queued? cancelling? cancelled?)
|
||||
nil
|
||||
|
||||
:else
|
||||
;; The running figure, once the worker said how much there is.
|
||||
(some? percent)
|
||||
[:span {:class (stl/css :progress)}
|
||||
(dm/str progress " / " total)])]
|
||||
(dm/str percent "%")]
|
||||
|
||||
:else
|
||||
nil)]
|
||||
|
||||
[:button {:class (stl/css :progress-close-button)
|
||||
:on-click toggle-detail-visibility}
|
||||
|
||||
@ -71,6 +71,28 @@
|
||||
(t/is (= (export-with-name (str (:object-id export)))
|
||||
(de/normalize-export (assoc export :name "")))))
|
||||
|
||||
(t/deftest initialize-export-status-shows-a-fresh-job-as-queued
|
||||
;; the creation answers the row status ("pending"): nobody works on
|
||||
;; the job yet, so the widget names it queued until the first
|
||||
;; milestone moves it to running
|
||||
(let [state (ptk/update (#'de/initialize-export-status
|
||||
[export] nil {:id (uuid/next) :status "pending"})
|
||||
{})]
|
||||
(t/is (= "queued" (get-in state [:export :status])))
|
||||
(t/is (true? (get-in state [:export :in-progress])))
|
||||
(t/is (= 0 (get-in state [:export :progress])))))
|
||||
|
||||
(t/deftest add-milestone-without-figures-keeps-the-figures
|
||||
;; the first breath of the worker (:preparing) carries no counters:
|
||||
;; it moves the widget to running without blanking the figures
|
||||
(let [before {:export {:in-progress true :status "queued"
|
||||
:progress 2 :total 5}}
|
||||
after (ptk/update (#'de/add-milestone {:stage :preparing :counters {}})
|
||||
before)]
|
||||
(t/is (= "running" (get-in after [:export :status])))
|
||||
(t/is (= 2 (get-in after [:export :progress])))
|
||||
(t/is (= 5 (get-in after [:export :total])))))
|
||||
|
||||
(t/deftest request-simple-export-runs-one-assets-job
|
||||
(t/async done
|
||||
(let [export (export-with-name "")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user