Closed adaburrows closed 11 months ago
@adaburrows Am I correct in my understanding that the Assessment Widgets are not now bound to a dimension? Just a dimension kind of input/output?
If so, does this entail a revision of the work @weswalla did to create
pub struct DimensionAppletWidgetBinding {
pub dimension_eh: EntryHash,
// id of the AppletConfig stored in companion zome
pub applet_id: EntryHash,
// name of the component as exposed by the applet interface
pub component_name: String,
}
which does in fact bind the dimensions to the widgets?
Furthermore.. is the component_name
from above, and the widget_key
from your initial comment refer to the same thing? If not, what iswidget_key
?
Let me try and provide the context for this. When the applet is registered, we should be creating entries in this new API. It will replace/augment the in-memory widget registry that is in the SensemakerStore. Currently, when apps are registered they are only placing info about their components into memory and on reload, everything about them is gone (which is rather terrible).
This API will provide the list of all the components and provide a way to look them up from the applet matrix entries. It will also provide a way of displaying the components that are available in the widget tray configuration screen.
The mapping between dimensions and widgets is stored in the AssessmentWidgetConfiguration. So to display the whole tray, we need to fetch the AssessmentWidgetConfiguration and then fetch the associated applets from the matrix store and then fetch the components from the applet based on the widget_key
.
So the example of:
const feedApplet: NeighbourhoodApplet = {
//...
assessmentWidgets: {
"importance": { // widget_key
name: "Importance Ranker",
range: {
min: 0,
max: 10
},
component: ImportanceWidget,
kind: "input"
}
}
}
// Registration type in TS, should be analogous in Rust
type AssessmentWidgetRegistration = {
applet_eh: EntryHash, // Applet entry hash
widget_key: string, // the "importance" bit above
name: string, // The "Importance Ranker" bit form above
range_eh: EntryHash, // The EntryHash for the created Range object (should probably just be the range object when returned from the API)
kind: "input" | "output"
}
// API
registerWidget(widget_registration: AssessmentWidgetRegistration);
getRegisteredWidgets(): Record<EntryHashB64, AssessmentWidgetRegistration);
We should probably also just change the newly implemented API from:
#[derive(Debug, Clone, Serialize, Deserialize, SerializedBytes)]
#[serde(rename_all = "camelCase")]
pub struct DimensionStandaloneWidgetBinding {
pub dimension_eh: EntryHash,
// id of the widget CustomElement stored in companion zome
pub widget_eh: EntryHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, SerializedBytes)]
#[serde(rename_all = "camelCase")]
pub struct DimensionAppletWidgetBinding {
pub dimension_eh: EntryHash,
// id of the AppletConfig stored in companion zome
pub applet_id: EntryHash,
// name of the component as exposed by the applet interface
pub component_name: String,
}
to
#[derive(Debug, Clone, Serialize, Deserialize, SerializedBytes)]
#[serde(rename_all = "camelCase")]
pub struct DimensionWidgetBinding {
pub dimension_eh: EntryHash,
// Widget Registration object that has all data needed to load the component from the matrix
pub widget_registry_eh: EntryHash,
}
@adaburrows I have a question re: applet config widget registration:
Are we to do a staged applet registration so that we can create Range entries before registering widgets?
type AssessmentWidgetRegistration = {
applet_eh: EntryHash, // Applet entry hash
widget_key: string, // the "importance" bit above
name: string, // The "Importance Ranker" bit form above
range_eh: EntryHash, // The EntryHash for the created Range object (should probably just be the range object when returned from the API)
kind: "input" | "output"
}
necessarily requires range_eh
s, I am assuming at least some of them will be created from the same config.
Also I am not sure about the comment.. does that mean the return object has both range and range eh?
Like https://github.com/neighbour-hoods/sensemaker-lite/blob/74469cddd23967bd72850ded91fab91498eb8282/client/src/widgets/widget-registry.ts#L4-L14
Our current convention would require that:
export interface AssessmentWidgetRegistrationInput {
applet_eh: EntryHash, // Applet entry hash
widget_key: string, // keyof an AssessmentWidgetConfigDict
name: string,
range: Range,
kind: AssessmentWidgetKind
}
and therefore
export interface AssessmentWidgetRegistration {
applet_eh: EntryHash, // Applet entry hash
widget_key: string, // keyof an AssessmentWidgetConfigDict
name: string,
range_eh: EntryHash,
kind: AssessmentWidgetKind
}
The when everything is queried, we should return the same AssessmentWidgetRegistrationInput
s that we originally received so that the front end doesn't have to query the ranges separately.
However, if we can just store the ranges together in a nested object, that would also be acceptable, since those ranges have no use anywhere but the front end code.
@adaburrows So is the data flow like this?
Create -
SensemakerService: AssessmentWidgetRegistrationInput -> ZomeFn: creates and returns AssessmentWidgetRegistration (TryInto
, using hash_entry
on the provided Range, and if TryInto
fails then create_entry
on the range)
Get -
SensemakerService: EntryHash -> ZomeFn: returns AssessmentWidgetRegistrationInput (get
on the EntryHash for the AssessmentWidgetRegistration, then get
on the range_eh
that was stored in the AssessmentWidgetRegistration to give the actual range again)
And it would make sense to discuss the update flow also.. since if the update parameters are the same as I was expecting
export type AssessmentWidgetRegistrationUpdateInput = {
assessmentRegistrationEh: EntryHash,
assessmentRegistrationUpdate: AssessmentWidgetRegistrationInput
}
then the implementation above would mean an update to the range values becomes more complicated: an update to a range that doesn't exist yet would mean a range creation at the same time. Makes more sense to me that you would update with a range_eh
and not a full Range
We need an API to register the widgets provided by each applet, so that we can easily look up all the provided widgets and the ranges they support. Basically, we will take the components registered in the applet as below and put them into the API so we can know which applet provides which widget and what range it applies to.
The future applet interface will look like so:
We should have a AssessmentWidgetRegistration object that gets created upon applet registration from the above entries for each widget entry:
The important thing is that we return an array of all of the registered widgets for the config screen, regardless of whatapplet they came from and that we can look up the component from the matrix store based on the information stored in the AssessmentWidgetRegistration.