Skip to content

Commit fe96133

Browse files
committed
[wip] Add flows tab
1 parent b1e75e4 commit fe96133

3 files changed

Lines changed: 746 additions & 0 deletions

File tree

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
(ns day8.re-frame-10x.panels.flows.events
2+
(:require
3+
[re-frame.db]
4+
[re-frame.interop]
5+
[re-frame.core]
6+
[clojure.string :as string]
7+
[zprint.core :as zp]
8+
[day8.re-frame-10x.inlined-deps.re-frame.v1v3v0.re-frame.core :as rf]
9+
[day8.re-frame-10x.tools.coll :as tools.coll]
10+
[day8.re-frame-10x.fx.window :refer [popout-window]]
11+
[day8.re-frame-10x.fx.local-storage :as local-storage]
12+
[day8.re-frame-10x.tools.reader.edn :as reader.edn]))
13+
14+
(def paths-interceptors
15+
[(rf/path [:flows :paths])
16+
rf/trim-v
17+
(local-storage/save "flows-paths")])
18+
19+
;; The core idea with :flows/update-path and :flows/update-path-blur
20+
;; is that we need to separate the users text input (`path-str`) with the
21+
;; parsing of that string (`path`). We let the user type any string that
22+
;; they like, and check it for validity on each change. If it is valid
23+
;; then we update `path` and mark the pod as valid. If it isn't valid then
24+
;; we don't update `path` and mark the pod as invalid.
25+
;;
26+
;; On blur of the input, we reset path-str to the last valid path, if
27+
;; the pod isn't currently valid.
28+
29+
(rf/reg-event-db
30+
::create-path
31+
paths-interceptors
32+
(fn [paths [open-new-inspectors?]]
33+
(assoc paths
34+
(js/Date.now)
35+
{:diff? false
36+
:open? open-new-inspectors?
37+
:path nil
38+
:path-str ""
39+
:valid-path? true})))
40+
41+
(rf/reg-event-fx
42+
::create-path-and-skip-to
43+
paths-interceptors
44+
(fn [{:keys [db]} [skip-to-path open-new-inspectors?]]
45+
(let [path-id (js/Date.now)]
46+
{:db (assoc db
47+
path-id
48+
{:diff? false
49+
:open? open-new-inspectors?
50+
:path nil
51+
:path-str ""
52+
:valid-path? true})
53+
:dispatch [::update-path {:id path-id :path-str skip-to-path}]})))
54+
55+
(rf/reg-event-db
56+
::update-path
57+
paths-interceptors
58+
(fn [paths [{:keys [id path-str]}]]
59+
(let [path (reader.edn/read-string-maybe path-str)
60+
valid? (or (and (some? path) (sequential? path))
61+
(string/blank? path-str))]
62+
(-> paths
63+
(assoc-in [id :path-str] path-str)
64+
(assoc-in [id :valid-path?] valid?)
65+
(cond-> valid? (assoc-in [id :path] path))))))
66+
67+
(rf/reg-event-db
68+
::update-path-blur
69+
paths-interceptors
70+
(fn [paths [path-id]]
71+
(let [{:keys [valid-path? path]} (get paths path-id)]
72+
(if valid-path?
73+
paths
74+
(-> (assoc-in paths [path-id :path-str] (pr-str path))
75+
(assoc-in [path-id :valid-path?] true))))))
76+
77+
(rf/reg-event-db
78+
::set-path-visibility
79+
paths-interceptors
80+
(fn [paths [path-id open?]]
81+
(assoc-in paths [path-id :open?] open?)))
82+
83+
(rf/reg-event-db
84+
::set-diff-visibility
85+
paths-interceptors
86+
(fn [paths [path-id diff?]]
87+
(let [open? (if diff?
88+
true
89+
(get-in paths [path-id :open?]))]
90+
(-> paths
91+
(assoc-in [path-id :diff?] diff?)
92+
;; If we turn on diffing then we want to also expand the path
93+
(assoc-in [path-id :open?] open?)))))
94+
95+
(rf/reg-event-db
96+
::remove-path
97+
paths-interceptors
98+
(fn [paths [path-id]]
99+
(dissoc paths path-id)))
100+
101+
(rf/reg-event-db
102+
::paths
103+
paths-interceptors
104+
(fn [_ [paths]]
105+
paths))
106+
107+
;; [IJ] TODO: This doesn't appear to be used anywhere:
108+
(rf/reg-event-db
109+
::set-search-string
110+
[(rf/path [:flows :search-string]) rf/trim-v]
111+
(fn [_ [search-string]]
112+
search-string))
113+
114+
(rf/reg-event-db
115+
::set-json-ml-paths
116+
[(rf/path [:flows :json-ml-expansions]) rf/trim-v (local-storage/save "flows-json-ml-expansions")]
117+
(fn [_ [paths]]
118+
paths))
119+
120+
(rf/reg-event-db
121+
::toggle-expansion
122+
[(rf/path [:flows :json-ml-expansions]) rf/trim-v (local-storage/save "flows-json-ml-expansions")]
123+
(fn [paths [path]]
124+
(if (contains? paths path)
125+
(disj paths path)
126+
(conj paths path))))
127+
128+
(rf/reg-event-db
129+
::reagent-id
130+
[(rf/path [:flows :reagent-id])]
131+
(fn [_ _]
132+
(re-frame.interop/reagent-id re-frame.db/flows)))
133+
134+
(rf/reg-event-db
135+
::set-sort-form?
136+
paths-interceptors
137+
(fn [paths [path-id sort]]
138+
(-> paths
139+
(assoc-in [path-id :sort?] sort))))
140+
141+
(rf/reg-event-db
142+
::set-data-path-annotations?
143+
[(rf/path [:flows :data-path-annotations?]) rf/trim-v (local-storage/save "data-path-annotations?")]
144+
(fn [_ [data-path-annotations?]]
145+
data-path-annotations?))
146+
147+
(rf/reg-event-db
148+
::expand
149+
paths-interceptors
150+
(fn [paths [{:keys [id expand?]}]]
151+
(let [{was-expanded? :expand?} (get paths id)]
152+
(assoc-in paths [id :expand?] (if (some? expand?)
153+
expand?
154+
(not was-expanded?))))))
155+
156+
(rf/reg-event-db
157+
::start-edit
158+
paths-interceptors
159+
(fn [paths [id]]
160+
(assoc-in paths [id :editing?] true)))
161+
162+
(rf/reg-event-db
163+
::finish-edit
164+
paths-interceptors
165+
(fn [paths [id]]
166+
(assoc-in paths [id :editing?] false)))
167+
168+
(rf/reg-event-db
169+
::set-edit-str
170+
paths-interceptors
171+
(fn [paths [{:keys [id value refresh?]}]]
172+
(cond-> paths
173+
:do (update id assoc :edit-str (zp/zprint-str value {:parse-string? true}))
174+
refresh? (update-in [id :editor-key] inc))))
175+
176+
(rf/reg-sub
177+
::editor-key
178+
(fn [db [_ id]]
179+
(get-in db [:flows :paths id :editor-key])))
180+
181+
(re-frame.core/reg-event-db
182+
::edit
183+
(fn [db [_ path s]]
184+
(let [new-data (reader.edn/read-string-maybe s)]
185+
(if-not (seq path)
186+
new-data
187+
(assoc-in db path new-data)))))
188+
189+
(defn read-file [file callback]
190+
(let [file-reader (js/FileReader.)]
191+
(set! (.-onload ^js file-reader)
192+
#(callback (.-result (.-target %))))
193+
(.readAsText ^js file-reader file)))
194+
195+
(rf/reg-fx
196+
:read-file
197+
(fn [{:keys [file] [id m] :on-read}]
198+
(read-file file #(rf/dispatch [id (assoc m :value %)]))))
199+
200+
(rf/reg-event-fx
201+
::open-file
202+
(fn [_ [_ file on-read]]
203+
{:read-file {:file file
204+
:on-read on-read}}))
205+
206+
(rf/reg-fx
207+
::save-to-file
208+
(fn [filename contents]
209+
(let [blob (js/Blob. #js [contents] #js {:type "text/plain"})
210+
url (str (.createObjectURL js/URL blob))
211+
link (js/document.createElement "a")]
212+
(set! (.-href link) url)
213+
(set! (.-download link) filename)
214+
(.appendChild js/document.body link)
215+
(.click link)
216+
(.remove link))))
217+
218+
(rf/reg-event-fx
219+
::save-to-file
220+
(fn [_ [_ s]]
221+
{::save-to-file s}))
222+
223+
(rf/reg-cofx
224+
::window-bounds
225+
(fn [cofx]
226+
(let [rect (-> (or (some-> @popout-window .-document) js/document)
227+
(.getElementById "--re-frame-10x--")
228+
.-shadowRoot
229+
(.getElementById "re-frame-10x__ui-container")
230+
.getBoundingClientRect)]
231+
(into cofx {::window-bounds [(.-x rect) (.-y rect)]}))))
232+
233+
(rf/reg-event-fx
234+
::open-popup-menu
235+
[(rf/inject-cofx ::window-bounds)]
236+
(fn [{:keys [db] [wx wy] ::window-bounds}
237+
[_ {:keys [path data data-path] [mx my] :mouse-position}]]
238+
{:db (assoc db :popup-menu {:showing? true
239+
:position [(- mx wx) (- my wy)]
240+
:path path
241+
:data data
242+
:data-path data-path})}))
243+
244+
(rf/reg-event-db
245+
::close-popup-menu
246+
(fn [db _] (assoc db :popup-menu {:showing? false})))
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
(ns day8.re-frame-10x.panels.flows.subs
2+
(:require
3+
[day8.re-frame-10x.inlined-deps.re-frame.v1v3v0.re-frame.core :as rf]
4+
[day8.re-frame-10x.navigation.epochs.subs :as epochs]
5+
[day8.re-frame-10x.panels.settings.subs :as settings.subs]
6+
[day8.re-frame-10x.tools.coll :as tools.coll]))
7+
8+
(rf/reg-sub
9+
::root
10+
(fn [{:keys [flows]} _]
11+
flows))
12+
13+
(rf/reg-sub
14+
::current-epoch-flows-after
15+
:<- [::epochs/selected-event-trace]
16+
(fn [trace _]
17+
(get-in trace [:tags :flows-after])))
18+
19+
(rf/reg-sub
20+
::current-epoch-flows-before
21+
:<- [::epochs/selected-event-trace]
22+
(fn [trace _]
23+
(get-in trace [:tags :flows-before])))
24+
25+
(rf/reg-sub
26+
::paths
27+
:<- [::root]
28+
(fn [{:keys [paths]} _]
29+
(reverse
30+
(map #(assoc (val %) :id (key %))
31+
paths))))
32+
33+
(rf/reg-sub
34+
::path-data
35+
:<- [::root]
36+
:<- [::current-epoch-flows-after]
37+
(fn [[{:keys [paths]} db-after] [_ {:keys [id]}]]
38+
(tools.coll/get-in-with-lists-and-sets db-after (:path (get paths id)))))
39+
40+
(rf/reg-sub
41+
::small-data?
42+
(fn [[_ {:keys [id]}] _]
43+
[(rf/subscribe [::path-data {:id id}])
44+
(rf/subscribe [::settings.subs/expansion-limit])])
45+
(fn [[data limit] _]
46+
(tools.coll/nodes-fewer-than? data limit)))
47+
48+
;; [IJ] TODO: This doesn't appear to be used anywhere:
49+
(rf/reg-sub
50+
::search-string
51+
:<- [::root]
52+
(fn [{:keys [search-string]} _]
53+
search-string))
54+
55+
(rf/reg-sub
56+
::expansions
57+
:<- [::root]
58+
(fn [{:keys [json-ml-expansions]} _]
59+
json-ml-expansions))
60+
61+
(rf/reg-sub
62+
::node-expanded?
63+
:<- [::expansions]
64+
(fn [expansions [_ path]]
65+
(contains? expansions path)))
66+
67+
;; [IJ] TODO: This doesn't appear to be used anywhere:
68+
(rf/reg-sub
69+
::reagent-id
70+
:<- [::root]
71+
(fn [{:keys [reagent-id]} _]
72+
reagent-id))
73+
74+
(rf/reg-sub
75+
::data-path-annotations?
76+
:<- [::root]
77+
(fn [{:keys [data-path-annotations?]} _]
78+
data-path-annotations?))
79+
80+
(rf/reg-sub
81+
::expand-all?
82+
:<- [::root]
83+
(fn [{:keys [expand-all?]} [_ path-id]]
84+
(get expand-all? path-id)))
85+
86+
(rf/reg-sub ::popup-menu :-> :popup-menu)

0 commit comments

Comments
 (0)