Skip to content

Commit 4793404

Browse files
committed
feat: add new set of properties
1 parent 5b7684b commit 4793404

File tree

8 files changed

+355
-12
lines changed

8 files changed

+355
-12
lines changed

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/DatagridDropdownFilter.editorConfig.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { hidePropertyIn, Problem, Properties } from "@mendix/pluggable-widgets-tools";
1+
import { hidePropertiesIn, hidePropertyIn, Problem, Properties } from "@mendix/pluggable-widgets-tools";
22
import { chevronDownIcon, chevronDownIconDark } from "@mendix/widget-plugin-filtering/preview/editor-preview-icons";
33
import {
44
ContainerProps,
@@ -13,8 +13,10 @@ export function getProperties(values: DatagridDropdownFilterPreviewProps, defaul
1313
const showSelectedItemsStyle = values.filterable && values.multiSelect;
1414
const showSelectionMethod = showSelectedItemsStyle && values.selectedItemsStyle === "boxes";
1515

16-
if (values.auto) {
17-
hidePropertyIn(defaultProperties, values, "filterOptions");
16+
if (values.baseType === "attr") {
17+
defaultProperties = attrGroupProperties(values, defaultProperties);
18+
} else {
19+
hidePropertiesIn(defaultProperties, values, ["attr", "attrChoice", "filterOptions", "auto"]);
1820
}
1921

2022
if (values.filterable) {
@@ -33,6 +35,21 @@ export function getProperties(values: DatagridDropdownFilterPreviewProps, defaul
3335
return defaultProperties;
3436
}
3537

38+
function attrGroupProperties(values: DatagridDropdownFilterPreviewProps, defaultProperties: Properties): Properties {
39+
hidePropertiesIn(defaultProperties, values, ["ref", "refOptions", "fetchOptionsLazy"]);
40+
41+
if (values.attrChoice === "auto") {
42+
hidePropertyIn(defaultProperties, {} as { linkedDs: unknown }, "linkedDs");
43+
hidePropertyIn(defaultProperties, values, "attr");
44+
}
45+
46+
if (values.auto) {
47+
hidePropertyIn(defaultProperties, values, "filterOptions");
48+
}
49+
50+
return defaultProperties;
51+
}
52+
3653
export const getPreview = (values: DatagridDropdownFilterPreviewProps, isDarkMode: boolean): StructurePreviewProps => {
3754
const palette = structurePreviewPalette[isDarkMode ? "dark" : "light"];
3855
return {

packages/pluggableWidgets/datagrid-dropdown-filter-web/src/DatagridDropdownFilter.xml

+58-6
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,41 @@
77
<helpUrl>https://docs.mendix.com/appstore/modules/data-grid-2#7-2-drop-down-filter</helpUrl>
88
<properties>
99
<propertyGroup caption="General">
10-
<propertyGroup caption="General">
10+
<propertyGroup caption="Data source">
11+
<property key="baseType" type="enumeration" defaultValue="attr">
12+
<caption>Filter by</caption>
13+
<description />
14+
<enumerationValues>
15+
<enumerationValue key="attr">Attribute</enumerationValue>
16+
<enumerationValue key="ref">Association</enumerationValue>
17+
</enumerationValues>
18+
</property>
19+
<property key="linkedDs" type="datasource" isLinked="true" isList="true">
20+
<caption>Datasource to Filter</caption>
21+
<description />
22+
</property>
23+
24+
<!-- start: Attr type -->
25+
<property key="attrChoice" type="enumeration" defaultValue="auto">
26+
<caption>Attribute config</caption>
27+
<description>"Auto" works only when the widget is placed in a Data grid column.</description>
28+
<enumerationValues>
29+
<enumerationValue key="auto">Auto</enumerationValue>
30+
<enumerationValue key="linked">Custom</enumerationValue>
31+
</enumerationValues>
32+
</property>
33+
<property key="attr" type="attribute" dataSource="linkedDs">
34+
<caption>Attribute</caption>
35+
<description />
36+
<attributeTypes>
37+
<attributeType name="Enum" />
38+
<attributeType name="Boolean" />
39+
</attributeTypes>
40+
</property>
1141
<property key="auto" type="boolean" defaultValue="true">
1242
<caption>Automatic options</caption>
1343
<description>Show options based on the references or the enumeration values and captions.</description>
1444
</property>
15-
<property key="defaultValue" type="expression" required="false">
16-
<caption>Default value</caption>
17-
<description>Empty option caption will be shown by default or if configured default value matches none of the options</description>
18-
<returnType type="String" />
19-
</property>
2045
<property key="filterOptions" type="object" isList="true" required="false">
2146
<caption>Options</caption>
2247
<description />
@@ -34,6 +59,33 @@
3459
</property>
3560
</properties>
3661
</property>
62+
<!-- end: Attr type -->
63+
64+
<!-- start: Ref type -->
65+
<property key="ref" type="association" selectableObjects="refOptions" required="false" dataSource="linkedDs">
66+
<caption>Entity</caption>
67+
<description>Set the entity to enable filtering over association.</description>
68+
<associationTypes>
69+
<associationType name="Reference" />
70+
<associationType name="ReferenceSet" />
71+
</associationTypes>
72+
</property>
73+
<property key="refOptions" type="datasource" isList="true" required="false">
74+
<caption>Selectable objects</caption>
75+
<description>The options to show in the Drop-down filter widget.</description>
76+
</property>
77+
<property key="fetchOptionsLazy" type="boolean" defaultValue="false">
78+
<caption>Use lazy load</caption>
79+
<description>Lazy loading enables faster parent loading, but with personalization enabled, value restoration will be limited.</description>
80+
</property>
81+
<!-- end: Ref type -->
82+
</propertyGroup>
83+
<propertyGroup caption="General">
84+
<property key="defaultValue" type="expression" required="false">
85+
<caption>Default value</caption>
86+
<description>Empty option caption will be shown by default or if configured default value matches none of the options</description>
87+
<returnType type="String" />
88+
</property>
3789
<property key="filterable" type="boolean" defaultValue="false">
3890
<caption>Filterable</caption>
3991
<description />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { createElement } from "react";
2+
import { AttributeMetaData } from "mendix";
3+
import { useFilterAPI } from "@mendix/widget-plugin-filtering/context";
4+
import { APIError } from "@mendix/widget-plugin-filtering/errors";
5+
import { error, value, Result } from "@mendix/widget-plugin-filtering/result-meta";
6+
import { PickerFilterStore } from "@mendix/widget-plugin-filtering/typings/PickerFilterStore";
7+
import { Alert } from "@mendix/widget-plugin-component-kit/Alert";
8+
import { useConst } from "@mendix/widget-plugin-mobx-kit/react/useConst";
9+
import { useSetup } from "@mendix/widget-plugin-mobx-kit/react/useSetup";
10+
import { ISetupable } from "@mendix/widget-plugin-mobx-kit/setupable";
11+
import { DropdownStoreProvider } from "@mendix/widget-plugin-filtering";
12+
13+
interface RequiredProps {
14+
attributes: Array<{
15+
attribute: AttributeMetaData<string>;
16+
}>;
17+
name: string;
18+
}
19+
20+
interface StoreProvider extends ISetupable {
21+
store: PickerFilterStore;
22+
}
23+
24+
type Component<P extends object> = (props: P) => React.ReactElement;
25+
26+
export function withDropdownLinkedAttributes<P extends RequiredProps>(
27+
component: Component<P & InjectableFilterAPI>
28+
): Component<P> {
29+
const StoreInjector = withInjectedStore(component);
30+
31+
return function FilterAPIProvider(props) {
32+
const api = useStoreProvider(props);
33+
34+
if (api.hasError) {
35+
return <Alert bootstrapStyle="danger">{api.error.message}</Alert>;
36+
}
37+
38+
return <StoreInjector {...props} {...api.value} />;
39+
};
40+
}
41+
42+
function withInjectedStore<P extends object>(
43+
Component: Component<P & InjectableFilterAPI>
44+
): Component<P & { provider: StoreProvider; channel: string }> {
45+
return function StoreInjector(props) {
46+
const provider = useSetup(() => props.provider);
47+
return <Component {...props} filterStore={provider.store} parentChannelName={props.channel} />;
48+
};
49+
}
50+
51+
interface InjectableFilterAPI {
52+
filterStore: PickerFilterStore;
53+
parentChannelName?: string;
54+
}
55+
56+
function useStoreProvider(props: RequiredProps): Result<{ provider: StoreProvider; channel: string }, APIError> {
57+
const filterAPI = useFilterAPI();
58+
return useConst(() => {
59+
if (filterAPI.hasError) {
60+
return error(filterAPI.error);
61+
}
62+
63+
return value({
64+
provider: new DropdownStoreProvider(filterAPI.value, {
65+
attributes: props.attributes.map(obj => obj.attribute),
66+
dataKey: props.name
67+
}),
68+
channel: filterAPI.value.parentChannelName
69+
});
70+
});
71+
}

packages/pluggableWidgets/datagrid-dropdown-filter-web/typings/DatagridDropdownFilterProps.d.ts

+19-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
* @author Mendix Widgets Framework Team
55
*/
66
import { CSSProperties } from "react";
7-
import { ActionValue, DynamicValue, EditableValue } from "mendix";
7+
import { ActionValue, DynamicValue, EditableValue, ListValue, ListAttributeValue, ListReferenceValue, ListReferenceSetValue } from "mendix";
8+
9+
export type BaseTypeEnum = "attr" | "ref";
10+
11+
export type AttrChoiceEnum = "auto" | "linked";
812

913
export interface FilterOptionsType {
1014
caption: DynamicValue<string>;
@@ -25,9 +29,15 @@ export interface DatagridDropdownFilterContainerProps {
2529
class: string;
2630
style?: CSSProperties;
2731
tabIndex?: number;
32+
baseType: BaseTypeEnum;
33+
attrChoice: AttrChoiceEnum;
34+
attr: ListAttributeValue<string | boolean>;
2835
auto: boolean;
29-
defaultValue?: DynamicValue<string>;
3036
filterOptions: FilterOptionsType[];
37+
ref?: ListReferenceValue | ListReferenceSetValue;
38+
refOptions?: ListValue;
39+
fetchOptionsLazy: boolean;
40+
defaultValue?: DynamicValue<string>;
3141
filterable: boolean;
3242
multiSelect: boolean;
3343
emptyOptionCaption?: DynamicValue<string>;
@@ -50,9 +60,15 @@ export interface DatagridDropdownFilterPreviewProps {
5060
readOnly: boolean;
5161
renderMode: "design" | "xray" | "structure";
5262
translate: (text: string) => string;
63+
baseType: BaseTypeEnum;
64+
attrChoice: AttrChoiceEnum;
65+
attr: string;
5366
auto: boolean;
54-
defaultValue: string;
5567
filterOptions: FilterOptionsPreviewType[];
68+
ref: string;
69+
refOptions: {} | { caption: string } | { type: string } | null;
70+
fetchOptionsLazy: boolean;
71+
defaultValue: string;
5672
filterable: boolean;
5773
multiSelect: boolean;
5874
emptyOptionCaption: string;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ListAttributeValue } from "mendix";
2+
import { FilterAPI } from "../context";
3+
import { StaticSelectFilterStore } from "../stores/picker/StaticSelectFilterStore";
4+
import { PickerFilterStore } from "../typings/PickerFilterStore";
5+
import { BaseStoreProvider } from "./BaseStoreProvider";
6+
import { FilterSpec } from "./typings";
7+
8+
export class DropdownStoreProvider extends BaseStoreProvider<StaticSelectFilterStore> {
9+
protected _store: StaticSelectFilterStore;
10+
protected filterAPI: FilterAPI;
11+
readonly dataKey: string;
12+
13+
constructor(filterAPI: FilterAPI, spec: FilterSpec<string>) {
14+
super();
15+
this.filterAPI = filterAPI;
16+
this.dataKey = spec.dataKey;
17+
18+
// Convert AttributeMetaData to ListAttributeValue
19+
const attributes = spec.attributes.map(attr => {
20+
const defaultFormatter = {
21+
format: (value: any) => String(value),
22+
parse: (value: string) => ({ valid: true, value })
23+
};
24+
25+
return {
26+
...attr,
27+
isList: false,
28+
get: (obj: any) => obj[attr.id],
29+
formatter: defaultFormatter
30+
} as ListAttributeValue;
31+
});
32+
33+
this._store = new StaticSelectFilterStore(
34+
attributes,
35+
this.findInitFilter(filterAPI.sharedInitFilter, this.dataKey)
36+
);
37+
}
38+
39+
get store(): PickerFilterStore {
40+
return this._store;
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export * from "./BaseStoreProvider";
2+
export * from "./DateStoreProvider";
3+
export * from "./DropdownStoreProvider";
4+
export * from "./NumberStoreProvider";
5+
export * from "./StringStoreProvider";
6+
export * from "./typings";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./custom-filter-api/DropdownStoreProvider";

0 commit comments

Comments
 (0)