msupply-foundation / open-msupply

Open mSupply represents our most recent advancement in the Logistics Management Information System (LMIS), expanding on more than two decades of development inherited from the well-established legacy of the original mSupply.
https://msupply.foundation/open-msupply/
Other
23 stars 14 forks source link

Open-mSupply Global Prefs #5644

Open jmbrunskill opened 22 hours ago

jmbrunskill commented 22 hours ago

Is your feature request related to a problem? Please describe πŸ‘€

Global prefs are a useful feature to allow system admins to control how the system operates nationally (store prefs do a similar thing at a store level)

Side Note: Before adding a global prefes, we should consider what makes a good global vs store pref, and/or if a plugin might be more appropriate for each use cases.

We need the ability to easily create and manage store prefs for Open mSupply Specific stores. We also need to consider how, or if it interacts with mSupply Global Prefs (do they both existing in open-mSupply?)

Describe the solution you'd like 🎁

From @andreievg ...

I played around a little bit with the translation structure, considering that global preference is stored in a table with key = preference type and value = json. In the use case of the requisition line column visibility some columns might be added via plugin, so they won't be strictly typed, but other should be I think, structure below should allow for it.


#[derive(Serialize, Deserialize, Debug)]
enum TypedColumnName {
    PreviousStockOnHand,
    PositiveAdjustment,
}
#[derive(Serialize, Deserialize, Debug)]
struct TypedColumn {
    column_name: TypedColumnName,
    is_visible: bool,
}
#[derive(Serialize, Deserialize, Debug)]
struct CustomColumn {
    column_name: String,
    is_visible: bool,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum RequisitionColumnVisibility {
    TypedColumn(TypedColumn),
    CustomColumn(CustomColumn),
}

fn main() {
    let value = r#"[{
        "column_name": "PreviousStockOnHand", "is_visible": true },
         {"column_name": "PositiveAdjustment", "is_visible": false },
         {"column_name": "SomeCustomColumn", "is_visible": true }
    ]"#;

    println!(
        "{:#?}",
        serde_json::from_str::<Vec<RequisitionColumnVisibility>>(value)
    );

    println!(
        "{}",
        serde_json::to_string_pretty(&vec![RequisitionColumnVisibility::TypedColumn(
            TypedColumn {
                column_name: TypedColumnName::PositiveAdjustment,
                is_visible: true
            }
        )])
        .unwrap()
    );
}

Above can go all the way through to graphql and typescript layer i think.

I would also imagine that we access each preference type separately, and have a seperate method for each serialisation and mapping, although I played around with some generic preference types, not sure how they would work across all of the layers:


table! {
    glob_pref (id) {
        id -> Text,
        value -> Text,
    }
}

trait GlobalPref: Default + DeserializeOwned {
    fn key() -> &'static str;

    fn load(connection: &StorageConnection) -> Result<Self, RepositoryError> {
        use glob_pref::dsl;

        let text_pref: Option<String> = dsl::glob_pref
            .filter(dsl::id.eq(Self::key()))
            .select(dsl::value)
            .first(connection.lock().connection())
            .optional()?;

        let Some(text_pref) = text_pref else {
            return Ok(Default::default());
        };

        let parsed = serde_json::from_str(&text_pref).unwrap();

        Ok(parsed)
    }
}

#[derive(Default, Deserialize)]
struct CustomTranslation(serde_json::Value);

impl GlobalPref for CustomTranslation {
    fn key() -> &'static str {
        "custom_translations"
    }
}

#[derive(Default, Deserialize)]
struct CustomTranslation(serde_json::Value);

Describe alternatives you've considered πŸ’­

Additional context πŸ’Œ

Moneyworks Jobcode 🧰

OMS:DDSP

jmbrunskill commented 22 hours ago

Needed for https://github.com/msupply-foundation/open-msupply/issues/5138#issuecomment-2461246641 and https://github.com/msupply-foundation/open-msupply/issues/5061