Open metasoarous opened 8 years ago
Moving over discussion from #5 on scoping entities.
The vague working draft idea I have now is to build entities that have scoping data (organization of that data to be determined), as well as some scoping parameters. Things like :dat.view.scope/type
, :dat.view.scope/attribute
, :dat.view.scope/cardinality
, etc, so that in a given component you specify any scoping parameters which might apply (the attribute, it's cardinality, the entity type, etc). The two big questions are:
or
specifications or and
specifications?There is some work in the dat.view.representations
ns regarding context resolution, but it goes in a slightly different direction. Hopefully there's something nice in the space between.
First thoughts. What about having some meta scope keyword that acts as a scope-channel
. A scope-channel
can be specified to run as or
or and
. A scope-channel
can be marked as dependency a la plumbing or ss-component.
Interesting... Can you elaborate?
What if the entity just pointed to a scope query directly? Then or/and could be taken care of via datalog.
I'm not sure how you would point to the query directly.
My idea in query form:
[:find (pull ?chan) (pull ?scope-entity)
:in $ ?data-entity
:where
[?scope :scope/type ?type]
[?scope :scope/attr ?attr]
[?scope :scope/chan ?chan]
;;[?chan :scope.chan/index ?chan-order]
;;[?chan :scope.chan/require ?parent-chans]
;;[?chan :scope.chan/merge-style ?chan-style]
[?scope :scope/entity ?scope-entity]
[?data-entity :e.type/type ?type]
...]
(let [scopes (sortedmap (GROUPBY ?chan query) #(if (child? %1 %2) -1 (if (child? %2 %1) 1 0)))]
;; TODO: merge scope-entity based on ?chan-style using ?chan-order if needed (which is the order they are specified in) for each ?chan
;; TODO: merge ?chan based on hierarchy and ?chan-style of default-chan
)
I think I might see the disconnect. I'm talking about the merging strategy after a set of scope-entities have been selected and I think you're talking about how a singular scope-entity is selected from varied ands and ors performed on the schema?
How about this pattern? 1) The base representation function creates a bunch of re-frame subscriptions. 2) Control middleware adds re-frame handlers using subscriptions and possibly adding some state. 3) Layout middleware decides where everything goes and makes choices based on layout oriented controls. Passes context.
(defn contextualize [app parent-context parent-data data]
(let [context (assoc :parent-eid (:db/id data))]
(reduce #(control control-info %) [representation-fn app [(representation-query app data) context] data] (controls-query app data))
))
(defn toggle! [data]
(swap! data #(not %)))
(defn control [[_ {:keys [starts-collapsed?]}] representation-fn]
::collapsable
(fn [app [represent-id context] data]
(let [collapsed? (atom starts-collapsed?)]
(assoc-in data [:controls :collapse] {:collapser #(toggle! collapsed?) :collapsed? @collapsed?}))
[representation-fn app [represent-id context] data]))
(defn control [[_ {:keys [parent-eid]}] representation-fn]
::edit-field
(fn [app [represent-id context] data]
(let [subscription [representation-fn app [represent-id context] data]
editor
(case (:type data)
:db.type/string (fn [db] [:db/add db (:parent-eid context) (:value subscription)])
...)]
(assoc-in subscription [:controls :edit] editor))))
(defn layout [[_ {:keys [editable? collapsable?]}] representation-fn]
::collection-layout
(fn [app context data]
(let [subscription [representation-fn app context data]]
[:div {:class (:name subscription)}
(when collapsable?
(re-com/button
:label "<"
:on-click (get-in subscription [:controls :collapse :collapser])))
(when (get-in subscription [:controls :collapse :collapsed?])
[:ul
(for [item (:items subscription)]
(let [item (contextualize app context data item)]
[:li
(layout (layout-query app item) item)
(when editable?
(re-com/button
:label "-"
:on-click (get-in item [:controls :delete])))])
)]
(when editable?
(re-com/button
:label "+"
:on-click (get-in subscription [:controls :add]))))
])))
Feels like there could be a lot of potential patterns for how one component sets up context for children components. We should think about these possible patterns and how we can standardize around a sort of meta-pattern here to keep things sane. Is this something that can be dispatched as well?