Skip to content

Commit

Permalink
Merge pull request #236 from IMASau/feature/isa-619-cql-filters-shoul…
Browse files Browse the repository at this point in the history
…d-be-accessible-from-an-alt-view-of-a-layer

ISA-619: CQL filters should be accessible from an alt-view of a layer
  • Loading branch information
JoshGx2000 authored Dec 10, 2024
2 parents 1805238 + 2089812 commit 3dc1773
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 42 deletions.
36 changes: 20 additions & 16 deletions frontend/src/cljs/imas_seamap/map/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -580,17 +580,15 @@
(defn toggle-legend-display [{:keys [db]} [_ {:keys [id] :as layer}]]
(let [db (update-in db [:layer-state :legend-shown] #(if ((set %) layer) (disj % layer) (conj (set %) layer)))
has-legend? (get-in db [:map :legends id])
rich-layer (enhance-rich-layer (layer->rich-layer layer db) db)
has-cql-filter-values? (get-in rich-layer [:controls :values])]
rich-layer (enhance-rich-layer (layer->rich-layer layer db) db)]
{:db db
:dispatch-n [[:maybe-autosave]
;; Retrieve layer legend data for display if we don't already have it or aren't
;; already retrieving it
(when-not has-legend?
[:map.layer/get-legend layer])
;; Retrieve rich layer cql filter data if we don't already have it
(when (and rich-layer (not has-cql-filter-values?))
[:map.rich-layer/get-cql-filter-values rich-layer])]}))
[:map.rich-layer/get-cql-filter-values rich-layer]]}))

(defn zoom-to-layer
"Zoom to the layer's extent, adding it if it wasn't already."
Expand Down Expand Up @@ -764,16 +762,21 @@
[:map.rich-layer/get-cql-filter-values rich-layer]) ; then get them
[:maybe-autosave]]})

(defn rich-layer-get-cql-filter-values [{:keys [db]} [_ {:keys [id controls] :as rich-layer}]]
(if (seq controls)
{:http-xhrio
{:method :get
:uri (get-in db [:config :urls :cql-filter-values-url])
:params {:rich-layer-id id}
:response-format (ajax/json-response-format)
:on-success [:map.rich-layer/get-cql-filter-values-success rich-layer]
:on-failure [:ajax/default-err-handler]}}
{:dispatch [:map.rich-layer/get-cql-filter-values-success rich-layer {"values" {} "filter_combinations" []}]}))
(defn rich-layer-get-cql-filter-values [{:keys [db]} [_ {:keys [id] :as _rich-layer}]]
(let [; Check if the new displayed layer is a rich layer, and if it has cql filter values that need to be fetched
{:keys [displayed-layer]} (enhance-rich-layer (first-where #(= (:id %) id) (get-in db [:map :rich-layers :rich-layers])) db)
displayed-rich-layer (layer->rich-layer displayed-layer db)
has-cql-filter-values? (:values (first (get-in db [:map :rich-layers :async-datas (:id displayed-rich-layer) :controls])))]
(when-not has-cql-filter-values? ; If the displayed layer doesn't have cql filter values, fetch them
(if (seq (:controls displayed-rich-layer))
{:http-xhrio
{:method :get
:uri (get-in db [:config :urls :cql-filter-values-url])
:params {:rich-layer-id (:id displayed-rich-layer)}
:response-format (ajax/json-response-format)
:on-success [:map.rich-layer/get-cql-filter-values-success displayed-rich-layer]
:on-failure [:ajax/default-err-handler]}}
{:dispatch [:map.rich-layer/get-cql-filter-values-success displayed-rich-layer {"values" {} "filter_combinations" []}]}))))

(defn rich-layer-get-cql-filter-values-success [db [_ {:keys [id] :as _rich-layer} {:strs [values filter_combinations]}]]
(let [values (keywordize-keys values)]
Expand All @@ -794,7 +797,7 @@
db (assoc-in db [:map :rich-layers :states id :alternate-views-selected] (get-in alternate-views-selected [:layer :id]))
{:keys [timeline]
new-slider-label :slider-label}
(enhance-rich-layer rich-layer db)
(enhance-rich-layer (first-where #(= (:id %) id) (get-in db [:map :rich-layers :rich-layers])) db)

; Find a value on the new alternate view's timeline that matches the old
; selected value.
Expand All @@ -810,7 +813,8 @@
:dispatch-n
[(when
(and alternate-views-selected (not (get-in db [:map :legends (get-in alternate-views-selected [:layer :id])])))
[:map.layer/get-legend (:layer alternate-views-selected)])
[:map.layer/get-legend (:layer alternate-views-selected)])
[:map.rich-layer/get-cql-filter-values rich-layer]
[:maybe-autosave]]}))

(defn rich-layer-timeline-selected [{:keys [db]} [_ {:keys [id layer] :as _rich-layer} timeline-selected]]
Expand Down
67 changes: 41 additions & 26 deletions frontend/src/cljs/imas_seamap/map/utils.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -428,23 +428,23 @@
layer (first-where #(= (:id %) layer-id) layers)]
(assoc timeline :layer layer)))

(defn control->value [{:keys [cql-property controller-type default-value] :as _control} {:keys [id] :as _rich-layer} db]
(defn control->value [{:keys [cql-property controller-type default-value] :as _control} {:keys [id] :as _rich-layer} {alternate-view-rich-layer-id :id :as _alternate-view-rich-layer} db]
(let [value (get-in db [:map :rich-layers :states id :controls cql-property :value])
values (get-in db [:map :rich-layers :async-datas id :controls cql-property :values])]
values (get-in db [:map :rich-layers :async-datas (or alternate-view-rich-layer-id id) :controls cql-property :values])]
(or
value
default-value
(when (= controller-type "slider") (apply max values)))))

(defn control->value-map
"Returns a map of the control's cql-property to its value."
[{:keys [cql-property] :as control} rich-layer db]
(let [value (control->value control rich-layer db)]
[{:keys [cql-property] :as control} rich-layer alternate-view-rich-layer db]
(let [value (control->value control rich-layer alternate-view-rich-layer db)]
{cql-property value}))

(defn control-is-default-value? [{:keys [cql-property controller-type default-value] :as control} {:keys [id] :as rich-layer} db]
(let [value (control->value control rich-layer db)
values (get-in db [:map :rich-layers :async-datas id :controls cql-property :values])]
(defn control-is-default-value? [{:keys [cql-property controller-type default-value] :as control} {:keys [id] :as rich-layer} {alternate-view-rich-layer-id :id :as alternate-view-rich-layer} db]
(let [value (control->value control rich-layer alternate-view-rich-layer db)
values (get-in db [:map :rich-layers :async-datas (or alternate-view-rich-layer-id id) :controls cql-property :values])]
(boolean
(or
(= value default-value)
Expand All @@ -467,28 +467,31 @@
(filterv #(= (get % cql-property) value) filter-combinations))
filter-combinations))

(defn- ->control [{:keys [cql-property] :as control} {:keys [id controls] :as rich-layer} db]
(let [values (get-in db [:map :rich-layers :async-datas id :controls cql-property :values])
value (control->value control rich-layer db)
(defn- ->control [{:keys [cql-property] :as control} rich-layer {alternate-view-rich-layer-id :id :as alternate-view-rich-layer} db]
(let [values (get-in db [:map :rich-layers :async-datas alternate-view-rich-layer-id :controls cql-property :values])
value (control->value control rich-layer alternate-view-rich-layer db)
other-controls
(->>
controls
(or (:controls alternate-view-rich-layer) (:controls rich-layer))
(remove #(= cql-property (:cql-property %)))
(map #(assoc % :value (control->value % rich-layer db))))
filter-combinations (get-in db [:map :rich-layers :async-datas id :filter-combinations])
(map #(assoc % :value (control->value % rich-layer alternate-view-rich-layer db))))
filter-combinations (get-in db [:map :rich-layers :async-datas alternate-view-rich-layer-id :filter-combinations])
valid-filter-combinations (reduce #(remove-incompatible-combinations %1 %2) filter-combinations other-controls)
valid-values (set (map #(get % cql-property) valid-filter-combinations))]
valid-values (set (map #(get % cql-property) valid-filter-combinations))
values
(mapv
(fn [value]
(hash-map
:value (or value "None") ; nil is substituted with "None" for the dropdown
:valid? (boolean (some #(= % value) valid-values))))
values)

values (if (and value (not (first-where #(= (:value %) value) values))) (conj values {:value value :valid? false}) values)]
(assoc
control
:values
(mapv
(fn [value]
(hash-map
:value (or value "None") ; nil is substituted with "None" for the dropdown
:valid? (boolean (some #(= % value) valid-values))))
values)
:values values
:value value
:is-default-value? (control-is-default-value? control rich-layer db)
:is-default-value? (control-is-default-value? control rich-layer alternate-view-rich-layer db)
:cql-filter (control->cql-filter control value))))

(defn rich-layer->controls-value-map
Expand All @@ -498,9 +501,9 @@
* `db: :seamap/app-state`: Seamap app state
Example: `rich-layer` -> `{\"cql-property1\" 100 \"cql-property2\" 200}`"
[rich-layer db]
[rich-layer alternate-view-rich-layer db]
(s/assert :map.rich-layers/rich-layer rich-layer)
(apply merge (map #(control->value-map % rich-layer db) (:controls rich-layer))))
(apply merge (map #(control->value-map % rich-layer alternate-view-rich-layer db) (:controls rich-layer))))

(defn enhance-rich-layer
"Takes a rich-layer and enhances the info with other layer data."
Expand All @@ -523,7 +526,8 @@
timeline-selected (first-where #(= (get-in % [:layer :id]) timeline-selected-id) timeline)
slider-label (or (:slider-label alternate-view-rich-layer) slider-label)

controls (mapv #(->control % rich-layer db) controls)
controls (mapv #(->control % rich-layer alternate-view-rich-layer db) (if alternate-view-rich-layer (:controls alternate-view-rich-layer) controls))

cql-filter (->>
controls
(map :cql-filter)
Expand Down Expand Up @@ -590,7 +594,18 @@
layers)
displayed-layers
(map #(rich-layer->displayed-layer % db) active-layers)
displayed-rich-layer-filters (mapv #(rich-layer->controls-value-map (layer->rich-layer % db) db) displayed-layers)

displayed-rich-layer-filters
(mapv
(fn [displayed-layer]
(let [rich-layer (layer->rich-layer displayed-layer db)

alternate-view-rich-layer-id (get-in db [:map :rich-layers :layer-lookup (:alternate-views-selected rich-layer)])
alternate-view-rich-layer-id (when-not (= alternate-view-rich-layer-id id) alternate-view-rich-layer-id)
alternate-view-rich-layer (first-where #(= (:id %) alternate-view-rich-layer-id) (get-in db [:map :rich-layers :rich-layers]))]
(rich-layer->controls-value-map rich-layer alternate-view-rich-layer db)))
displayed-layers)

active-layers-metadata (map (fn [layer] (:metadata (first-where #(= (:layer %) (:id layer)) (:layers dynamic-pill)))) active-layers)] ; get the metadata for the active layers, forming a list of the same arity
(->
dynamic-pill
Expand Down

0 comments on commit 3dc1773

Please sign in to comment.