Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Added delay configuration for getLookupLabelEx and typing in dropdowns 2023.2 #2317

Merged
merged 3 commits into from Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/Origam.Server/Common/PortalResult.cs
Expand Up @@ -145,5 +145,7 @@ public int MaxRequestLength

public string InitialScreenId { get; set; }
public int RowStatesDebouncingDelayMilliseconds { get; set; }
public int DropDownTypingDebouncingDelayMilliseconds { get; set; }
public int GetLookupLabelExDebouncingDelayMilliseconds { get; set; }
}
}
2 changes: 2 additions & 0 deletions backend/Origam.Server/Configuration/HtmlClientConfig.cs
Expand Up @@ -4,5 +4,7 @@ public class HtmlClientConfig
{
public bool ShowToolTipsForMemoFieldsOnly { get; set; }
public int RowStatesDebouncingDelayMilliseconds { get; set; }
public int DropDownTypingDebouncingDelayMilliseconds { get; set; } = 300;
public int GetLookupLabelExDebouncingDelayMilliseconds { get; set; } = 667;
}
}
2 changes: 2 additions & 0 deletions backend/Origam.Server/Controller/UIServiceController.cs
Expand Up @@ -1218,6 +1218,8 @@ private void AddConfigData(PortalResult result)
result.CustomAssetsRoute = customAssetsConfig.RouteToCustomAssetsFolder;
result.ShowToolTipsForMemoFieldsOnly = htmlClientConfig.ShowToolTipsForMemoFieldsOnly;
result.RowStatesDebouncingDelayMilliseconds = htmlClientConfig.RowStatesDebouncingDelayMilliseconds;
result.DropDownTypingDebouncingDelayMilliseconds = htmlClientConfig.DropDownTypingDebouncingDelayMilliseconds;
result.GetLookupLabelExDebouncingDelayMilliseconds = htmlClientConfig.GetLookupLabelExDebouncingDelayMilliseconds;
result.FilteringConfig = clientFilteringConfig;
}
}
Expand Down
4 changes: 3 additions & 1 deletion backend/Origam.Server/TemplateFiles/_appsettings.json
Expand Up @@ -143,7 +143,9 @@
},
"HtmlClientConfig":{
"ShowToolTipsForMemoFieldsOnly" : "false",
"RowStatesDebouncingDelayMilliseconds": 0
"RowStatesDebouncingDelayMilliseconds": 0,
"DropDownTypingDebouncingDelayMilliseconds": 300,
"GetLookupLabelExDebouncingDelayMilliseconds": 667
},
"Logging": {
"LogLevel": {
Expand Down
Expand Up @@ -49,6 +49,7 @@ import { resolveCellAlignment } from "gui/Workbench/ScreenArea/TableView/Resolve
import S from "./TableViewEditor.module.scss";
import { makeOnAddNewRecordClick } from "gui/connections/NewRecordScreen";
import { getKeyBuffer } from "model/selectors/getKeyBuffer";
import { getWorkbenchLifecycle } from "model/selectors/getWorkbenchLifecycle";

@inject(({tablePanelView}) => {
const row = getSelectedRow(tablePanelView)!;
Expand Down Expand Up @@ -109,6 +110,7 @@ export class TableViewEditor extends React.Component<{

const isFirstColumn = getTablePanelView(dataView)?.firstColumn === this.props.property;
const gridFocusManager = getGridFocusManager(this.props.property);
const portalSettings = getWorkbenchLifecycle(this.props.property).portalSettings;
switch (this.props.property!.column) {
case "Number":
return (
Expand Down Expand Up @@ -224,6 +226,7 @@ export class TableViewEditor extends React.Component<{
subscribeToFocusManager={(editor) =>
gridFocusManager.activeEditor = editor
}
typingDelayMillis={portalSettings?.dropDownTypingDebouncingDelayMilliseconds}
/>
);
case "Checklist":
Expand Down
Expand Up @@ -57,6 +57,7 @@ import { FormScreenEnvelope } from "model/entities/FormScreen";
import { EventHandler } from "@origam/utils";
import { hexToRgb } from "utils/colorUtils";
import { KeyBuffer } from "model/entities/WorkbenchLifecycle/KeyBuffer";
import { getWorkbench } from "model/selectors/getWorkbench";

export enum IRefreshOnReturnType {
None = "None",
Expand Down Expand Up @@ -565,11 +566,14 @@ export class WorkbenchLifecycle implements IWorkbenchLifecycle {
helpUrl: portalInfo.helpUrl,
showToolTipsForMemoFieldsOnly: portalInfo.showToolTipsForMemoFieldsOnly,
rowStatesDebouncingDelayMilliseconds: portalInfo.rowStatesDebouncingDelayMilliseconds,
dropDownTypingDebouncingDelayMilliseconds: portalInfo.dropDownTypingDebouncingDelayMilliseconds,
filterConfig: {
caseSensitive: portalInfo.filteringConfig.caseSensitive,
accentSensitive: portalInfo.filteringConfig.accentSensitive
}
};
getWorkbench(this).lookupMultiEngine.lookupLoaderMulti.getLookupLabelExDebouncingDelayMillis =
portalInfo.getLookupLabelExDebouncingDelayMilliseconds
const menuUI = findMenu(portalInfo.menu);
assignIIds(menuUI);
getFavorites(this).setXml(portalInfo.favorites);
Expand Down
Expand Up @@ -25,5 +25,6 @@ export interface IPortalSettings {
helpUrl: string;
showToolTipsForMemoFieldsOnly: boolean;
rowStatesDebouncingDelayMilliseconds: number;
dropDownTypingDebouncingDelayMilliseconds: number;
filterConfig: IFilterConfig;
}
Expand Up @@ -105,6 +105,7 @@ export function XmlBuildDropdownEditor(props: {
onAddNewRecordClick?: () => void;
subscribeToFocusManager?: (obj: IFocusable) => void;
onKeyDown?(event: any): void;
typingDelayMillis?: number;
}) {
const mobxContext = useContext(MobXProviderContext);
const {dataViewRowCursor, dataViewApi, dataViewData} = mobxContext.dataView;
Expand Down Expand Up @@ -147,7 +148,8 @@ export function XmlBuildDropdownEditor(props: {
autoSort: props.autoSort,
onTextOverflowChanged: props.onTextOverflowChanged,
newRecordScreen: props.newRecordScreen,
onAddNewRecordClick: props.onAddNewRecordClick
onAddNewRecordClick: props.onAddNewRecordClick,
typingDelayMillis: props.typingDelayMillis
});

const dropdownEditorSetup = DropdownEditorSetupFromXml(
Expand Down
Expand Up @@ -65,6 +65,7 @@ export interface IBehaviorData {
onTextOverflowChanged?: (toolTip: string | null | undefined) => void,
newRecordScreen?: NewRecordScreen,
onAddNewRecordClick?: () => void;
typingDelayMillis?: number;
}

export class DropdownEditorBehavior implements IDropdownEditorBehavior {
Expand All @@ -85,6 +86,7 @@ export class DropdownEditorBehavior implements IDropdownEditorBehavior {
private onTextOverflowChanged?: (toolTip: string | null | undefined) => void;
private newRecordScreen?: NewRecordScreen;
public onAddNewRecordClick?: () => void;
private readonly handleInputChangeDeb: _.DebouncedFunc<() => void>;

get hasNewScreenButton() {
return !!this.newRecordScreen;
Expand All @@ -104,13 +106,14 @@ export class DropdownEditorBehavior implements IDropdownEditorBehavior {
this.onDoubleClick = args.onDoubleClick;
this.onClick = args.onClick;
this.onBlur = args.onBlur;
this.onMount = args.onMount,
this.onMount = args.onMount;
this.subscribeToFocusManager = args.subscribeToFocusManager;
this.onKeyDown = args.onKeyDown;
this.autoSort = args.autoSort;
this.onTextOverflowChanged = args.onTextOverflowChanged;
this.newRecordScreen = args.newRecordScreen
this.onAddNewRecordClick = args.onAddNewRecordClick
this.newRecordScreen = args.newRecordScreen;
this.onAddNewRecordClick = args.onAddNewRecordClick;
this.handleInputChangeDeb = _.debounce(this.handleInputChangeImm, args.typingDelayMillis ?? 300);
}

@observable isDropped = false;
Expand Down Expand Up @@ -346,8 +349,6 @@ export class DropdownEditorBehavior implements IDropdownEditorBehavior {
this.dataTable.setFilterPhrase("");
}

handleInputChangeDeb = _.debounce(this.handleInputChangeImm, 300);

@action.bound
handleInputChange(event: any) {
if (this.userEnteredValue || event.target.value){
Expand Down
8 changes: 4 additions & 4 deletions frontend-html/src/modules/Lookup/LookupLoaderIndividual.ts
Expand Up @@ -39,12 +39,12 @@ export class LookupLoaderIndividual {

resultListeners = new PubSub<ILookupIndividualResultListenerArgs>();

setInterrest(key: any) {
this.loader.setInterrest(this.lookupId, key);
setInterest(key: any) {
this.loader.setInterest(this.lookupId, key);
}

resetInterrest(key: any) {
this.loader.resetInterrest(this.lookupId, key);
resetInterest(key: any) {
this.loader.resetInterest(this.lookupId, key);
}

async loadList(labelIds: Set<any>) {
Expand Down
38 changes: 21 additions & 17 deletions frontend-html/src/modules/Lookup/LookupLoaderMulti.ts
Expand Up @@ -32,8 +32,12 @@ export class LookupLoaderMulti {
this.triggerLoadDeb = clock.debounce(this.triggerLoadImm, 667);
}

set getLookupLabelExDebouncingDelayMillis(value: number) {
this.triggerLoadDeb = this.clock.debounce(this.triggerLoadImm, value);
}

// lookupId -> lookupKey -> something 🦄
interrests = new Map<string, Map<any, any>>();
interests = new Map<string, Map<any, any>>();
loading = new Map<string, Map<any, any>>();
loadingAtom = createAtom(
"LookupLoading",
Expand All @@ -55,17 +59,17 @@ export class LookupLoaderMulti {
do {
this.isLoading = true;
/*console.log("Will load:");
for (let [l1k, l1v] of this.interrests.entries()) {
for (let [l1k, l1v] of this.interests.entries()) {
console.log(` ${l1k}:`);
for (let [l2k, l2v] of l1v.entries()) {
console.log(` ${l2k}`);
}
}*/

for (let [k, v] of this.interrests.entries()) {
for (let [k, v] of this.interests.entries()) {
this.loading.set(k, v);
}
this.interrests.clear();
this.interests.clear();
this.loadingAtom.reportChanged();

const result = await this.api.getLookupLabels(this.loading);
Expand All @@ -84,7 +88,7 @@ export class LookupLoaderMulti {
this.loadingAtom.reportChanged();

this.resultListeners.trigger({labels: result});
} while (this.interrests.size > 0);
} while (this.interests.size > 0);
} finally {
this.isLoading = false;
}
Expand All @@ -93,29 +97,29 @@ export class LookupLoaderMulti {
triggerLoadDeb = () => {
};

setInterrest(lookupId: string, key: any) {
setInterest(lookupId: string, key: any) {
// Maybe it is loading right now.
if (this.loading.has(lookupId) && this.loading.get(lookupId)!.has(key)) return;

// Not yet loading, record that someon is interrested.
if (!this.interrests.has(lookupId)) {
this.interrests.set(lookupId, new Map());
// Not yet loading, record that someone is interested.
if (!this.interests.has(lookupId)) {
this.interests.set(lookupId, new Map());
}
const lookupInterrests = this.interrests.get(lookupId)!;
lookupInterrests.set(key, true);
const lookupInterests = this.interests.get(lookupId)!;
lookupInterests.set(key, true);

// Schedule actual loading.
this.triggerLoadDeb();
}

resetInterrest(lookupId: string, key: any) {
if (!this.interrests.has(lookupId)) {
resetInterest(lookupId: string, key: any) {
if (!this.interests.has(lookupId)) {
return;
}
const lookupInterrests = this.interrests.get(lookupId)!;
lookupInterrests.delete(key);
if (lookupInterrests.size === 0) {
this.interrests.delete(lookupId);
const lookupInterests = this.interests.get(lookupId)!;
lookupInterests.delete(key);
if (lookupInterests.size === 0) {
this.interests.delete(lookupId);
}
}

Expand Down
6 changes: 3 additions & 3 deletions frontend-html/src/modules/Lookup/LookupResolver.ts
Expand Up @@ -41,13 +41,13 @@ export class LookupResolver {
handleAtomObserved(key: any, atom: IAtom) {
this.atoms.set(key, atom);
if (!this.resolved.has(key)) {
this.loader.setInterrest(key);
this.loader.setInterest(key);
}
}

handleAtomUnobserved(key: any, atom: IAtom) {
this.atoms.delete(key);
this.loader.resetInterrest(key);
this.loader.resetInterest(key);
}

@action.bound
Expand All @@ -57,7 +57,7 @@ export class LookupResolver {
if (!this.atoms.has(k)) {
keysToDelete.push(k);
} else {
this.loader.setInterrest(k);
this.loader.setInterest(k);
}
}
for (let k of keysToDelete) {
Expand Down