Skip to content

Commit

Permalink
fix: wc-2758 load combobox attribute database on initial load and rem…
Browse files Browse the repository at this point in the history
…ove default value
  • Loading branch information
gjulivan committed Jan 26, 2025
1 parent 4c3d6dd commit 3772324
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 106 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const DATABASE_SOURCE_CONFIG: Array<keyof ComboboxPreviewProps> = [
"optionsSourceDatabaseCustomContent",
"optionsSourceDatabaseCustomContentType",
"optionsSourceDatabaseDataSource",
"optionsSourceDatabaseDefaultValue",
"optionsSourceDatabaseValueAttribute",
"optionsSourceDatabaseItemSelection",
"databaseAttributeString",
Expand Down Expand Up @@ -122,15 +121,11 @@ export function getProperties(values: ComboboxPreviewProps, defaultProperties: P
if (values.optionsSourceDatabaseItemSelection === "Multi") {
hidePropertiesIn(defaultProperties, values, [
"optionsSourceDatabaseValueAttribute",
"databaseAttributeString",
"optionsSourceDatabaseDefaultValue"
"databaseAttributeString"
]);
}
if (values.databaseAttributeString.length === 0) {
hidePropertiesIn(defaultProperties, values, [
"optionsSourceDatabaseValueAttribute",
"optionsSourceDatabaseDefaultValue"
]);
hidePropertiesIn(defaultProperties, values, ["optionsSourceDatabaseValueAttribute"]);
}
} else if (values.source === "static") {
hidePropertiesIn(defaultProperties, values, [
Expand Down
5 changes: 0 additions & 5 deletions packages/pluggableWidgets/combobox-web/src/Combobox.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@
<attributeType name="Enum" />
</attributeTypes>
</property>
<property key="optionsSourceDatabaseDefaultValue" type="expression" required="false">
<caption>Default value</caption>
<description />
<returnType assignableTo="databaseAttributeString" />
</property>
<!-- END DATABASE / STRING -->
</propertyGroup>
<propertyGroup caption="Attribute">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ describe("Combo box (Association)", () => {
showFooter: false,
databaseAttributeString: new EditableValueBuilder<string | Big>().build(),
optionsSourceDatabaseCaptionType: "attribute",
optionsSourceDatabaseDefaultValue: dynamic("empty value"),
optionsSourceDatabaseCustomContentType: "yes",
staticDataSourceCustomContentType: "no",
staticAttribute: new EditableValueBuilder<string>().build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ describe("Combo box (Association)", () => {
showFooter: false,
databaseAttributeString: new EditableValueBuilder<string | Big>().build(),
optionsSourceDatabaseCaptionType: "attribute",
optionsSourceDatabaseDefaultValue: dynamic("empty value"),
optionsSourceDatabaseCustomContentType: "yes",
staticDataSourceCustomContentType: "no",
staticAttribute: new EditableValueBuilder<string>().build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ describe("Combo box (Static values)", () => {
showFooter: false,
databaseAttributeString: new EditableValueBuilder<string | Big>().build(),
optionsSourceDatabaseCaptionType: "attribute",
optionsSourceDatabaseDefaultValue: dynamic("empty value"),
optionsSourceDatabaseCustomContentType: "yes",
staticDataSourceCustomContentType: "no",
staticAttribute: new EditableValueBuilder<string>().withValue("value1").build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ export function SingleSelection({

const selectedItemCaption = useMemo(
() => selector.caption.render(selectedItem, "label"),
[selectedItem, selector.status, selector.caption.emptyCaption, selector.caption.value?.value]
[

Check warning on line 47 in packages/pluggableWidgets/combobox-web/src/components/SingleSelection/SingleSelection.tsx

View workflow job for this annotation

GitHub Actions / Run code quality check

React Hook useMemo has unnecessary dependencies: 'selector.caption.emptyCaption', 'selector.caption.value.value', 'selector.currentId', and 'selector.status'. Either exclude them or remove the dependency array
selectedItem,
selector.status,
selector.caption,
selector.caption.emptyCaption,
selector.currentId,
selector.caption.value?.value
]
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ export class BaseDatasourceOptionsProvider extends BaseOptionsProvider<ObjectIte
return (value?.id as string) ?? null;
}

// used for initial load of selected value in case options are lazy loaded
loadSelectedValue(attributeValue: string): void {
if (this.lazyLoading && this.ds && this.attributeId) {
const filterCondition = datasourceFilter("containsExact", attributeValue, this.attributeId);
this.ds?.setFilter(filterCondition);
this.ds.setLimit(1);
}
}

_updateProps(props: BaseProps): void {
this.attributeId = props.attributeId;
this.ds = props.ds;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,39 +1,66 @@
import { EditableValue, SelectionSingleValue } from "mendix";
import { ComboboxContainerProps } from "../../../typings/ComboboxProps";
import { EditableValue, ListAttributeValue, ObjectItem, SelectionSingleValue } from "mendix";
import {
ComboboxContainerProps,
LoadingTypeEnum,
OptionsSourceAssociationCustomContentTypeEnum
} from "../../../typings/ComboboxProps";
import { LazyLoadProvider } from "../LazyLoadProvider";
import { SingleSelector, Status } from "../types";
import { _valuesIsEqual } from "../utils";
import { BaseDatabaseSingleSelector } from "./BaseDatabaseSingleSelector";
import { DatabaseCaptionsProvider } from "./DatabaseCaptionsProvider";
import { DatabaseOptionsProvider } from "./DatabaseOptionsProvider";
import { DatabaseValuesProvider } from "./DatabaseValuesProvider";
import { extractDatabaseProps } from "./utils";

export class DatabaseSingleSelectionSelector<
T extends string | Big,
R extends EditableValue<T>
> extends BaseDatabaseSingleSelector<T> {
export class DatabaseSingleSelectionSelector<T extends string | Big, R extends EditableValue<T>>
implements SingleSelector
{
caption: DatabaseCaptionsProvider;
clearable = false;
currentId: string | null = null;
customContentType: OptionsSourceAssociationCustomContentTypeEnum = "no";
lazyLoading = false;
loadingType?: LoadingTypeEnum;
options: DatabaseOptionsProvider;
readOnly = false;
status: Status = "unavailable";
type = "single" as const;
protected _objectsMap: Map<string, ObjectItem> = new Map();
protected lazyLoader: LazyLoadProvider = new LazyLoadProvider();

validation?: string = undefined;
values: DatabaseValuesProvider;
protected _attr: R | undefined;
private selection?: SelectionSingleValue;

constructor() {
super();
this.caption = new DatabaseCaptionsProvider(this._objectsMap);
this.options = new DatabaseOptionsProvider(this.caption, this._objectsMap);
this.values = new DatabaseValuesProvider(this._objectsMap);
}

updateProps(props: ComboboxContainerProps): void {
super.updateProps(props);

const {
targetAttribute,
captionProvider,
captionType,
clearable,
customContent,
customContentType,
ds,
emptyOption,
emptyValue,
filterType,
lazyLoading,
loadingType,
valueSourceAttribute
} = extractDatabaseProps(props);

if (ds.status === "loading") {
return;
}
this._attr = targetAttribute as R;

this.lazyLoader.updateProps(ds);
this.lazyLoader.setLimit(
this.lazyLoader.getLimit(
ds.limit,
Expand All @@ -43,7 +70,6 @@ export class DatabaseSingleSelectionSelector<
)
);

this._attr = targetAttribute as R;
this.caption.updateProps({
emptyOptionText: emptyOption,
formattingAttributeOrExpression: captionProvider,
Expand All @@ -53,9 +79,15 @@ export class DatabaseSingleSelectionSelector<
caption: targetAttribute?.displayValue
});

this.options._updateProps({
ds,
filterType,
lazyLoading,
attributeId: captionType === "attribute" ? (captionProvider as ListAttributeValue<string>).id : undefined
});

this.values.updateProps({
valueAttribute: valueSourceAttribute,
emptyValue
valueAttribute: valueSourceAttribute
});

if (!ds || ds.status === "unavailable" || !emptyOption || emptyOption.status === "unavailable") {
Expand All @@ -64,30 +96,33 @@ export class DatabaseSingleSelectionSelector<
this.clearable = false;
return;
}

if (targetAttribute?.status === "available") {
if (this.lastSetValue === null || !_valuesIsEqual(this.lastSetValue, targetAttribute.value)) {
if (ds.status === "available") {
this.lastSetValue = this._attr.value;
if (!_valuesIsEqual(this.values.getEmptyValue(), targetAttribute.value)) {
const obj = this.options.getAll().find(option => {
return _valuesIsEqual(targetAttribute.value, this.values.get(option));
});
if (obj) {
this.currentId = obj;
} else {
this.currentId = null;
}
if (targetAttribute.value && !this.currentId) {
const allOptions = this.options.getAll();
if (allOptions.length > 0) {
const obj = this.options.getAll().find(option => {
return _valuesIsEqual(targetAttribute.value, this.values.get(option));
});
if (obj) {
this.currentId = obj;
}
} else {
this.options.loadSelectedValue(targetAttribute.value?.toString());
}
} else if (!targetAttribute.value && this.currentId) {
this.currentId = null;
}
}

this.readOnly = targetAttribute?.readOnly ?? false;
this.status = targetAttribute?.status ?? ds.status;
this.validation = targetAttribute?.validation;
this.selection = props.optionsSourceDatabaseItemSelection as SelectionSingleValue;

this.clearable = clearable;
this.customContentType = customContentType;
this.lazyLoading = lazyLoading;
this.loadingType = loadingType;

if (this.selection.selection === undefined) {
const objectId = this.options.getAll().find(option => {
return targetAttribute && _valuesIsEqual(targetAttribute?.value, this.values.get(option));
Expand All @@ -100,11 +135,10 @@ export class DatabaseSingleSelectionSelector<

setValue(objectId: string | null): void {
const value = this.values.get(objectId) as T;
this.lastSetValue = value;
this._attr?.setValue(value);
if (objectId !== (this.selection?.selection?.id ?? "")) {
this.selection?.setSelection(this.options._optionToValue(objectId));
}
super.setValue(objectId);
this.currentId = objectId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export class DatabaseValuesProvider implements ValuesProvider<string | Big> {
constructor(private optionsMap: Map<string, ObjectItem>) {}

updateProps(props: Props): void {
this.emptyValue = props.emptyValue;
this.attribute = props.valueAttribute;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type ExtractionReturnValue = {
customContentType: OptionsSourceAssociationCustomContentTypeEnum;
ds: ListValue;
emptyOption?: DynamicValue<string>;
emptyValue?: DynamicValue<string | Big>;
filterType: FilterTypeEnum;
lazyLoading: boolean;
loadingType: LoadingTypeEnum;
Expand All @@ -43,7 +42,6 @@ export function extractDatabaseProps(props: ComboboxContainerProps): ExtractionR
const captionAttribute = props.optionsSourceDatabaseCaptionAttribute;
const captionExpression = props.optionsSourceDatabaseCaptionExpression;
const emptyOption = props.emptyOptionText;
const emptyValue = props.optionsSourceDatabaseDefaultValue;
const clearable = props.clearable;
const customContent = props.optionsSourceDatabaseCustomContent;
const customContentType = props.optionsSourceDatabaseCustomContentType;
Expand Down Expand Up @@ -82,7 +80,6 @@ export function extractDatabaseProps(props: ComboboxContainerProps): ExtractionR
customContentType,
ds,
emptyOption,
emptyValue,
filterType,
lazyLoading,
loadingType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export interface ComboboxContainerProps {
optionsSourceDatabaseCaptionExpression?: ListExpressionValue<string>;
optionsSourceDatabaseValueAttribute?: ListAttributeValue<string | Big>;
databaseAttributeString?: EditableValue<string | Big>;
optionsSourceDatabaseDefaultValue?: DynamicValue<string | Big>;
attributeAssociation: ReferenceValue | ReferenceSetValue;
optionsSourceAssociationDataSource?: ListValue;
staticAttribute: EditableValue<string | Big | boolean | Date>;
Expand Down Expand Up @@ -112,7 +111,6 @@ export interface ComboboxPreviewProps {
optionsSourceDatabaseCaptionExpression: string;
optionsSourceDatabaseValueAttribute: string;
databaseAttributeString: string;
optionsSourceDatabaseDefaultValue: string;
attributeAssociation: string;
optionsSourceAssociationDataSource: {} | { caption: string } | { type: string } | null;
staticAttribute: string;
Expand Down

0 comments on commit 3772324

Please sign in to comment.