using System.Linq.Expressions; using System.Reflection; namespace HopFrame.Core.Config; public class PropertyConfig(PropertyInfo info, TableConfig table, int nthProperty) { public PropertyInfo Info { get; } = info; public TableConfig Table { get; } = table; public string Name { get; set; } = info.Name; public bool List { get; set; } = true; public bool Sortable { get; set; } = true; public bool Searchable { get; set; } = true; public PropertyInfo? DisplayedProperty { get; set; } public Func>? Formatter { get; set; } public Func>? EnumerableFormatter { get; set; } public Func>? Parser { get; set; } public Func>>? Validator { get; set; } public bool Editable { get; set; } = true; public bool Creatable { get; set; } = true; public bool DisplayValue { get; set; } = true; public bool TextArea { get; set; } public int TextAreaRows { get; set; } = 16; public bool IsRelation { get; internal set; } public bool IsRequired { get; internal set; } public bool IsEnumerable { get; internal set; } public bool IsListingProperty { get; set; } public int Order { get; set; } = nthProperty; public int DisplayLength { get; set; } = 32; } /// /// A helper class for editing the /// public class PropertyConfigurator(PropertyConfig config) { /// /// The Internal property configuration that's modified by the helper functions /// public PropertyConfig InnerConfig { get; } = config; /// /// Sets the title displayed in the table header and edit dialog /// public PropertyConfigurator SetDisplayName(string displayName) { InnerConfig.Name = displayName; return this; } /// /// Determines if the property should appear in the table, if not the property is also set to be not searchable /// /// public PropertyConfigurator List(bool list) { InnerConfig.List = list; InnerConfig.Searchable = !list; return this; } /// /// Determines if the table can be sorted by the property /// public PropertyConfigurator IsSortable(bool sortable) { InnerConfig.Sortable = sortable; return this; } /// /// Determines if the property get taken into account for search results /// public PropertyConfigurator IsSearchable(bool searchable) { InnerConfig.Searchable = searchable; return this; } /// /// Determines if the value that should be displayed instead of the string representation of the type /// public PropertyConfigurator SetDisplayedProperty(Expression> propertyExpression) { InnerConfig.DisplayedProperty = TableConfigurator.GetPropertyInfo(propertyExpression); return this; } /// /// Determines the value that's displayed in the admin ui /// /// public PropertyConfigurator Format(Func formatter) { InnerConfig.Formatter = (obj, provider) => Task.FromResult(formatter.Invoke((TProp)obj, provider)); return this; } /// public PropertyConfigurator Format(Func> formatter) { InnerConfig.Formatter = (obj, provider) => formatter.Invoke((TProp)obj, provider); return this; } /// /// Determines the value that's displayed for each entry in the list /// public PropertyConfigurator FormatEach(Func formatter) { InnerConfig.EnumerableFormatter = (obj, provider) => Task.FromResult(formatter.Invoke((TInnerProp)obj, provider)); return this; } /// public PropertyConfigurator FormatEach(Func> formatter) { InnerConfig.EnumerableFormatter = (obj, provider) => formatter.Invoke((TInnerProp)obj, provider); return this; } /// /// Determines the function used for parsing the value provided in the editor dialog to the actual property value /// public PropertyConfigurator SetParser(Func parser) { InnerConfig.Parser = (str, provider) => Task.FromResult(parser.Invoke(str, provider)!); return this; } /// public PropertyConfigurator SetParser(Func> parser) { InnerConfig.Parser = async (str, provider) => (await parser.Invoke(str, provider))!; return this; } /// /// Determines if the value can be edited in the admin ui. If true, the value can still be initially set, but not modified /// /// public PropertyConfigurator SetEditable(bool editable) { InnerConfig.Editable = editable; return this; } /// /// Determines if the initial value can be edited in the admin ui. If true the value will not be visible in the create dialog /// /// public PropertyConfigurator SetCreatable(bool creatable) { InnerConfig.Creatable = creatable; return this; } /// /// Determines if the value should be displayed in the admin ui (useful for secrets like passwords etc.) /// public PropertyConfigurator DisplayValue(bool display) { InnerConfig.DisplayValue = display; return this; } /// /// Determines if the admin ui should use a text area for modifying the value /// /// public PropertyConfigurator IsTextArea(bool textField) { InnerConfig.TextArea = textField; return this; } /// /// Determines the initial size of the text area field /// /// public PropertyConfigurator SetTextAreaRows(int rows) { InnerConfig.TextAreaRows = rows; return this; } /// /// Determines the validator used for the property value before saving /// public PropertyConfigurator SetValidator(Func> validator) { InnerConfig.Validator = (obj, provider) => Task.FromResult(validator.Invoke((TProp?)obj, provider)); return this; } /// /// Determines the validator used for the property value before saving /// public PropertyConfigurator SetValidator(Func>> validator) { InnerConfig.Validator = (obj, provider) => validator.Invoke((TProp?)obj, provider); return this; } /// /// Determines the order index for the property in the admin ui /// /// public PropertyConfigurator SetOrderIndex(int index) { InnerConfig.Order = index; return this; } /// /// Sets the maximum character length displayed in the admin ui (not in the editor dialog) /// /// The maximum length of characters to be displayed public PropertyConfigurator SetDisplayLength(int maxLength) { InnerConfig.DisplayLength = maxLength; return this; } }