Skip to content

Commit 608cb5b

Browse files
lipalath-msdanielluo-msft
authored andcommitted
display query based on type
1 parent bd92d0a commit 608cb5b

File tree

7 files changed

+88
-51
lines changed

7 files changed

+88
-51
lines changed

UI/web-app/src/components/HRQuerySource/HRQuerySource.base.tsx

Lines changed: 77 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
8181
let items: IFilterPart[] = children.map((child, index) => ({
8282
attribute: child.filter.split(' ')[0],
8383
equalityOperator: child.filter.split(' ')[1],
84-
value: child.filter.split(' ')[2],
84+
value: attributeValues[child.filter.split(' ')[0]] &&
85+
attributeValues[child.filter.split(' ')[0]].values &&
86+
attributeValues[child.filter.split(' ')[0]].values.length > 0 &&
87+
child.filter.split(' ')[2] && child.filter.split(' ')[2].startsWith("'") && child.filter.split(' ')[2].endsWith("'") ? child.filter.split(' ')[2].slice(1, -1) : child.filter.split(' ')[2],
8588
andOr: child.filter.split(' ')[3]
8689
}));
8790
setItems(items);
@@ -117,6 +120,18 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
117120
}
118121
}, [children]);
119122

123+
const checkType = (value: string, type: string | undefined): string => {
124+
switch (type) {
125+
case "nvarchar":
126+
if (value.startsWith("'") && value.endsWith("'")) {
127+
return value;
128+
} else {
129+
return `'${value}'`;
130+
}
131+
default:
132+
return value;
133+
}
134+
};
120135

121136
const getOptions = (attributes?: SqlMembershipAttribute[]): IComboBoxOption[] => {
122137
options = attributes?.map((attribute, index) => ({
@@ -374,7 +389,8 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
374389

375390
const handleAttributeChange = (event: React.FormEvent<IComboBox>, item?: IComboBoxOption, index?: number): void => {
376391
if (item) {
377-
dispatch(fetchAttributeValues({attribute: item.key as string }));
392+
const selectedAttribute = attributes?.find(attribute => attribute.name === item.key);
393+
dispatch(fetchAttributeValues({attribute: item.key as string, type: selectedAttribute?.type }));
378394
const updatedItems = items.map((it, idx) => {
379395
if (idx === index) {
380396
return { ...it, attribute: item.text };
@@ -464,79 +480,90 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
464480
}
465481
return it;
466482
});
467-
setItems(updatedItems);
468-
}
469483

470-
const regex = /(?<= And | Or )/;
471-
let segments = props.source.filter?.split(regex);
472-
if (item && (props.source.filter?.length === 0 || (segments?.length == children.length - 1))) {
473-
const a = item.key.toString();
474-
let filter: string;
475-
if (source.filter !== "") {
476-
filter = `${source.filter} ` + a;
477-
} else {
478-
filter = a;
479-
}
480-
setSource(prevSource => {
481-
const newSource = { ...prevSource, filter };
482-
onSourceChange(newSource, partId);
483-
return newSource;
484-
});
485-
}
486-
else if (segments && index !== undefined && segments[index] && item) {
487-
let words = segments[index].split(' ');
488-
if (words[0] === "") {
489-
words = segments[index].trim().split(' ');
484+
const selectedValue = item.key.toString();
485+
let selectedValueAfterConversion: string = "";
486+
487+
selectedValueAfterConversion = checkType(selectedValue, attributeValues[updatedItems[index ?? 0].attribute.toString()].type);
488+
setItems(updatedItems);
490489

490+
const regex = /(?<= And | Or )/;
491+
let segments = props.source.filter?.split(regex);
492+
if (item && (props.source.filter?.length === 0 || (segments?.length == children.length - 1))) {
493+
let filter: string;
494+
if (source.filter !== "") {
495+
filter = `${source.filter} ` + selectedValueAfterConversion || selectedValue;
496+
} else {
497+
filter = selectedValueAfterConversion || selectedValue;
498+
}
499+
setSource(prevSource => {
500+
const newSource = { ...prevSource, filter };
501+
onSourceChange(newSource, partId);
502+
return newSource;
503+
});
491504
}
492-
if (words.length > 0) {
493-
words[2] = item.key.toString();
505+
else if (segments && index !== undefined && segments[index] && item) {
506+
let words = segments[index].split(' ');
507+
if (words[0] === "") {
508+
words = segments[index].trim().split(' ');
509+
}
510+
if (words.length > 0) {
511+
words[2] = selectedValueAfterConversion || selectedValue;
512+
}
513+
segments[index] = words.join(' ');
514+
const updatedFilter = segments.join('');
515+
setSource(prevSource => {
516+
let filter = updatedFilter;
517+
const newSource = { ...prevSource, filter };
518+
onSourceChange(newSource, partId);
519+
return newSource;
520+
});
494521
}
495-
segments[index] = words.join(' ');
496-
const updatedFilter = segments.join('');
497-
setSource(prevSource => {
498-
let filter = updatedFilter;
499-
const newSource = { ...prevSource, filter };
500-
onSourceChange(newSource, partId);
501-
return newSource;
502-
});
503522
}
504523
};
505524

506525
const handleTAttributeValueChange = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string = '', index: number) => {
507-
const updatedItems = items.map((item, idx) => {
526+
const updatedItems = items.map((it, idx) => {
508527
if (idx === index) {
509-
return { ...item, value: newValue };
528+
return { ...it, value: newValue };
510529
}
511-
return item;
530+
return it;
512531
});
532+
533+
const selectedValue = newValue;
534+
let selectedValueAfterConversion: string = "";
535+
536+
selectedValueAfterConversion = checkType(selectedValue, attributeValues[items[index ?? 0].attribute].type);
513537
setItems(updatedItems);
514-
};
538+
}
515539

516540
const handleBlur = (event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>, index?: number) => {
517541
var newValue = event.target.value.trim();
542+
const selectedValue = newValue;
543+
let selectedValueAfterConversion: string = "";
544+
selectedValueAfterConversion = checkType(selectedValue, attributeValues[items[index ?? 0].attribute].type);
518545
const regex = /(?<= And | Or )/;
519546
let segments = props.source.filter?.split(regex);
520-
if (newValue !== "" && (props.source.filter?.length === 0 || (segments?.length == children.length - 1))) {
547+
if (selectedValueAfterConversion !== "" && (props.source.filter?.length === 0 || (segments?.length == children.length - 1))) {
521548
let filter: string;
522549
if (source.filter !== "") {
523-
filter = `${source.filter} ` + newValue;
550+
filter = `${source.filter} ` + selectedValueAfterConversion || selectedValue;
524551
} else {
525-
filter = newValue;
552+
filter = selectedValueAfterConversion || selectedValue;
526553
}
527554
setSource(prevSource => {
528555
const newSource = { ...prevSource, filter };
529556
onSourceChange(newSource, partId);
530557
return newSource;
531558
});
532559
}
533-
else if (segments && index !== undefined && segments[index] && newValue) {
560+
else if (segments && index !== undefined && segments[index] && selectedValueAfterConversion) {
534561
let words = segments[index].split(' ');
535562
if (words[0] === "") {
536563
words = segments[index].trim().split(' ');
537564
}
538565
if (words.length > 0) {
539-
words[2] = newValue;
566+
words[2] = selectedValueAfterConversion || selectedValue;
540567
}
541568
segments[index] = words.join(' ');
542569
const updatedFilter = segments.join('');
@@ -547,7 +574,7 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
547574
return newSource;
548575
});
549576
}
550-
}
577+
};
551578

552579
const handleOrAndOperatorChange = (event: React.FormEvent<HTMLDivElement>, item?: IDropdownOption, index?: number): void => {
553580
const regex = /(?<= And | Or )/;
@@ -762,7 +789,7 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
762789
}
763790
newSelectedIndices = selectedItems.map(item => newItems.indexOf(item));
764791
let newChildren: ChildType[] = newItems.map((item) => ({
765-
filter: `${item.attribute} ${item.equalityOperator} ${item.value} ${item.andOr}`,
792+
filter: `${item.attribute} ${item.equalityOperator} ${valueNeedsQuotes(item.value, item.attribute)} ${item.andOr}`,
766793
}));
767794
setChildren(newChildren);
768795
setItems(newItems);
@@ -780,7 +807,7 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
780807
return;
781808
}
782809
let newChildren: ChildType[] = newItems.map((item) => ({
783-
filter: `${item.attribute} ${item.equalityOperator} ${item.value} ${item.andOr}`,
810+
filter: `${item.attribute} ${item.equalityOperator} ${valueNeedsQuotes(item.value, item.attribute)} ${item.andOr}`,
784811
}));
785812
setChildren(newChildren);
786813
setItems(newItems);
@@ -799,6 +826,10 @@ export const HRQuerySourceBase: React.FunctionComponent<HRQuerySourceProps> = (p
799826
};
800827
};
801828

829+
const valueNeedsQuotes = (value: string, attribute: string) => {
830+
return attributeValues[attribute].values.length > 0 && attributeValues[attribute].type === "nvarchar" ? `'${value}'` : value;
831+
};
832+
802833
const [selection] = useState(() => new Selection({
803834
onSelectionChanged: () => {}
804835
}));

UI/web-app/src/models/GetAttributeValuesRequest.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
export interface GetAttributeValuesRequest {
55
attribute: string;
6+
type: string | undefined;
67
}

UI/web-app/src/models/GetAttributeValuesResponse.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ import { SqlMembershipAttributeValue } from "./SqlMembershipAttributeValue";
66
export interface GetAttributeValuesResponse {
77
values: SqlMembershipAttributeValue[];
88
attribute: string;
9+
type: string | undefined;
910
}

UI/web-app/src/models/SqlMembershipAttribute.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
export type SqlMembershipAttribute = {
55
name: string;
66
customLabel: string;
7+
type: string;
78
};
89

UI/web-app/src/models/SqlMembershipSource.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
export type SqlMembershipSource = {
55
name: string;
66
customLabel: string;
7+
type: string;
78
};
89

UI/web-app/src/store/sqlMembershipSources.api.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ export const fetchAttributeValues = createAsyncThunk<GetAttributeValuesResponse,
4141
const response = await gmmApi.sqlMembershipSources.fetchDefaultSqlMembershipSourceAttributeValues(request.attribute);
4242
const payload: GetAttributeValuesResponse = {
4343
values: response,
44-
attribute: request.attribute
44+
attribute: request.attribute,
45+
type: request.type
4546
};
4647
return payload;
4748
} catch (error) {
4849
const payload: GetAttributeValuesResponse = {
4950
values: [],
50-
attribute: request.attribute
51+
attribute: request.attribute,
52+
type: request.type
5153
};
5254
return payload;
5355
}

UI/web-app/src/store/sqlMembershipSources.slice.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ const sqlMembershipSourcesSlice = createSlice({
8282
});
8383
builder.addCase(fetchAttributeValues.fulfilled, (state, action) => {
8484
state.areAttributeValuesLoading = false;
85-
const { attribute, values} = action.payload;
85+
const { attribute, type, values} = action.payload;
8686
state.attributeValues[attribute] = {
8787
values: values,
88-
type: undefined
88+
type: type
8989
};
9090
});
9191
builder.addCase(fetchAttributeValues.rejected, (state, action) => {
@@ -122,7 +122,7 @@ const sqlMembershipSourcesSlice = createSlice({
122122
state.patchResponse = action.payload;
123123
state.patchError = action.error.message;
124124
});
125-
125+
126126
},
127127
});
128128

0 commit comments

Comments
 (0)