Skip to content

Commit

Permalink
refactor and enhancements (#199)
Browse files Browse the repository at this point in the history
* Bump cookie and socket.io in /PolyLookupComponent (#178)

Bumps [cookie](https://github.com/jshttp/cookie) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together.

Updates `cookie` from 0.4.2 to 0.7.2
- [Release notes](https://github.com/jshttp/cookie/releases)
- [Commits](jshttp/cookie@v0.4.2...v0.7.2)

Updates `socket.io` from 4.7.5 to 4.8.0
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/compare/[email protected]@4.8.0)

---
updated-dependencies:
- dependency-name: cookie
  dependency-type: indirect
- dependency-name: socket.io
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* split query hooks

* enhance use query hooks

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
khoait and dependabot[bot] authored Nov 30, 2024
1 parent 199fff8 commit 8f906d0
Show file tree
Hide file tree
Showing 26 changed files with 506 additions and 428 deletions.
2 changes: 1 addition & 1 deletion LookdownComponent/Lookdown/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="DCEPCF" constructor="Lookdown" version="1.3.2" display-name-key="Lookdown v1.3.2" description-key="Display a lookup control as a dropdown" control-type="virtual" >
<control namespace="DCEPCF" constructor="Lookdown" version="1.3.3" display-name-key="Lookdown v1.3.3" description-key="Display a lookup control as a dropdown" control-type="virtual" >
<external-service-usage enabled="false">
<!--UNCOMMENT TO ADD EXTERNAL DOMAINS
<domain></domain>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import {
} from "@fluentui/react";
import { useQueryClient } from "@tanstack/react-query";
import React, { useCallback, useEffect } from "react";
import { useEntityOptions, useLanguagePack, useMetadata } from "../services/DataverseService";
import { getClassicDropdownOptions } from "../services/DropdownHelper";
import { getCustomFilterString, getHandlebarsVariables } from "../services/TemplateService";
import { EntityOption, LookdownControlProps, OpenRecordMode } from "../types/typings";
import { useAttributeOnChange } from "../hooks/useAttributeOnChange";
import { useEntityOptions } from "../hooks/queries/useEntityOptions";
import { useLanguagePack } from "../hooks/queries/useLanguagePack";
import { useMetadata } from "../hooks/queries/useMetadata";

const DEFAULT_BORDER_STYLES: IStyle = {
borderColor: "#666",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import {
import { AddRegular, MoreVerticalRegular, OpenRegular, SearchRegular } from "@fluentui/react-icons";
import { useQueryClient } from "@tanstack/react-query";
import React, { useCallback, useEffect, useState } from "react";
import { useEntityOptions, useLanguagePack, useMetadata } from "../services/DataverseService";
import { getCustomFilterString, getHandlebarsVariables } from "../services/TemplateService";
import { EntityOption, LookdownControlProps, OpenRecordMode } from "../types/typings";
import { useAttributeOnChange } from "../hooks/useAttributeOnChange";
import { useEntityOptions } from "../hooks/queries/useEntityOptions";
import { useLanguagePack } from "../hooks/queries/useLanguagePack";
import { useMetadata } from "../hooks/queries/useMetadata";

const useStyle = makeStyles({
root: {
Expand Down
65 changes: 65 additions & 0 deletions LookdownComponent/Lookdown/hooks/queries/useEntityOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useQuery } from "@tanstack/react-query";
import { getHandlebarsVariables, getFetchTemplateString } from "../../services/TemplateService";
import { IMetadata } from "../../types/metadata";
import { ShowIconOptions, IconSizes } from "../../types/typings";
import { getEntityRecords } from "../../services/DataverseService";

export function useEntityOptions(
metadata: IMetadata | undefined,
customFilter?: string | null,
groupBy?: string | null,
optionTemplate?: string | null,
selectedItemTemplate?: string | null,
iconOptions?: ShowIconOptions,
iconSize?: IconSizes
) {
const entitySetName = metadata?.lookupEntity.EntitySetName ?? "";
const lookupViewFetchXml = metadata?.lookupView.fetchxml ?? "";

const entityIcon =
metadata?.lookupEntity.IconVectorName ??
(iconSize === IconSizes.Large
? metadata?.lookupEntity.IconMediumName ?? metadata?.lookupEntity.IconSmallName
: metadata?.lookupEntity.IconSmallName);

const recordImageUrlTemplate = metadata?.lookupEntity.RecordImageUrlTemplate;

let iconTemplate = "";
if (iconOptions === ShowIconOptions.RecordImage) {
iconTemplate = recordImageUrlTemplate ?? "";
} else if (iconOptions === ShowIconOptions.EntityIcon) {
iconTemplate = entityIcon ?? "";
}

return useQuery({
queryKey: [
"entityRecords",
entitySetName,
lookupViewFetchXml,
customFilter,
groupBy,
optionTemplate,
selectedItemTemplate,
],
queryFn: () => {
const templateColumns: string[] = [];
if (optionTemplate || selectedItemTemplate) {
templateColumns.push(...getHandlebarsVariables(optionTemplate ?? "" + " " + selectedItemTemplate ?? ""));
}
const populatedFetchXml = getFetchTemplateString(lookupViewFetchXml ?? "", customFilter, templateColumns);
return getEntityRecords(
entitySetName,
metadata?.lookupEntity.PrimaryIdAttribute ?? "",
metadata?.lookupEntity.PrimaryNameAttribute ?? "",
populatedFetchXml,
groupBy,
optionTemplate,
selectedItemTemplate,
iconOptions,
iconTemplate,
iconSize
);
},
enabled: !!entitySetName && !!lookupViewFetchXml,
});
}
11 changes: 11 additions & 0 deletions LookdownComponent/Lookdown/hooks/queries/useLanguagePack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import { getLanguagePack } from "../../services/DataverseService";
import { LanguagePack } from "../../types/languagePack";

export function useLanguagePack(webResourcePath: string | undefined, defaultLanguagePack: LanguagePack) {
return useQuery({
queryKey: ["languagePack", webResourcePath],
queryFn: () => getLanguagePack(webResourcePath, defaultLanguagePack),
enabled: !!webResourcePath,
});
}
10 changes: 10 additions & 0 deletions LookdownComponent/Lookdown/hooks/queries/useMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useQuery } from "@tanstack/react-query";
import { getMetadata } from "../../services/DataverseService";

export function useMetadata(lookupTable: string, lookupViewId: string) {
return useQuery({
queryKey: ["metadata", lookupTable, lookupViewId],
queryFn: () => getMetadata(lookupTable, lookupViewId),
enabled: !!lookupTable && !!lookupViewId,
});
}
80 changes: 2 additions & 78 deletions LookdownComponent/Lookdown/services/DataverseService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,82 +33,6 @@ const DEFAULT_HEADERS = {
'odata.include-annotations="OData.Community.Display.V1.FormattedValue,Microsoft.Dynamics.CRM.associatednavigationproperty,Microsoft.Dynamics.CRM.lookuplogicalname"',
};

export function useMetadata(lookupTable: string, lookupViewId: string) {
return useQuery({
queryKey: ["metadata", lookupTable, lookupViewId],
queryFn: () => getMetadata(lookupTable, lookupViewId),
enabled: !!lookupTable && !!lookupViewId,
});
}

export function useEntityOptions(
metadata: IMetadata | undefined,
customFilter?: string | null,
groupBy?: string | null,
optionTemplate?: string | null,
selectedItemTemplate?: string | null,
iconOptions?: ShowIconOptions,
iconSize?: IconSizes
) {
const entitySetName = metadata?.lookupEntity.EntitySetName ?? "";
const lookupViewFetchXml = metadata?.lookupView.fetchxml ?? "";

const entityIcon =
metadata?.lookupEntity.IconVectorName ??
(iconSize === IconSizes.Large
? metadata?.lookupEntity.IconMediumName ?? metadata?.lookupEntity.IconSmallName
: metadata?.lookupEntity.IconSmallName);

const recordImageUrlTemplate = metadata?.lookupEntity.RecordImageUrlTemplate;

let iconTemplate = "";
if (iconOptions === ShowIconOptions.RecordImage) {
iconTemplate = recordImageUrlTemplate ?? "";
} else if (iconOptions === ShowIconOptions.EntityIcon) {
iconTemplate = entityIcon ?? "";
}

return useQuery({
queryKey: [
"entityRecords",
entitySetName,
lookupViewFetchXml,
customFilter,
groupBy,
optionTemplate,
selectedItemTemplate,
],
queryFn: () => {
const templateColumns: string[] = [];
if (optionTemplate || selectedItemTemplate) {
templateColumns.push(...getHandlebarsVariables(optionTemplate ?? "" + " " + selectedItemTemplate ?? ""));
}
const populatedFetchXml = getFetchTemplateString(lookupViewFetchXml ?? "", customFilter, templateColumns);
return getEntityRecords(
entitySetName,
metadata?.lookupEntity.PrimaryIdAttribute ?? "",
metadata?.lookupEntity.PrimaryNameAttribute ?? "",
populatedFetchXml,
groupBy,
optionTemplate,
selectedItemTemplate,
iconOptions,
iconTemplate,
iconSize
);
},
enabled: !!entitySetName && !!lookupViewFetchXml,
});
}

export function useLanguagePack(webResourcePath: string | undefined, defaultLanguagePack: LanguagePack) {
return useQuery({
queryKey: ["languagePack", webResourcePath],
queryFn: () => getLanguagePack(webResourcePath, defaultLanguagePack),
enabled: !!webResourcePath,
});
}

export function getLanguagePack(
webResourceUrl: string | undefined,
defaultLanguagePack: LanguagePack
Expand Down Expand Up @@ -140,7 +64,7 @@ export function getLanguagePack(
.catch(() => languagePack);
}

async function getMetadata(lookupTable: string, lookupViewId: string): Promise<IMetadata> {
export async function getMetadata(lookupTable: string, lookupViewId: string): Promise<IMetadata> {
const [lookupEntity, lookupView] = await Promise.all([
getEntityDefinition(lookupTable),
getViewDefinition(lookupTable, lookupViewId),
Expand Down Expand Up @@ -235,7 +159,7 @@ export async function getLookupViewDefinition(entityName: string) {
return view;
}

async function getEntityRecords(
export async function getEntityRecords(
entitySetName: string,
primaryIdAttribute: string,
primaryNameAttribute: string,
Expand Down
2 changes: 1 addition & 1 deletion PolyLookupComponent/PolyLookup/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="DCEPCF" constructor="PolyLookup" version="1.6.4" display-name-key="PolyLookup v1.6.4" description-key="Multi-select lookup supporting different type of many-to-many relationships" control-type="standard" >
<control namespace="DCEPCF" constructor="PolyLookup" version="1.6.5" display-name-key="PolyLookup v1.6.5" description-key="Multi-select lookup supporting different type of many-to-many relationships" control-type="standard" >
<!--external-service-usage node declares whether this 3rd party PCF control is using external service or not, if yes, this control will be considered as premium and please also add the external domain it is using.
If it is not using any external service, please set the enabled="false" and DO NOT add any domain below. The "enabled" will be false by default.
Example1:
Expand Down
92 changes: 92 additions & 0 deletions PolyLookupComponent/PolyLookup/components/OptionList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { TagPickerOption, Avatar, Divider, Text, tokens, makeStyles } from "@fluentui/react-components";
import React from "react";
import { LanguagePack } from "../types/languagePack";
import { EntityOption, ShowIconOptions, ShowOptionDetailsEnum } from "../types/typings";
import { SuggestionInfo } from "./SuggestionInfo";

const useStyles = makeStyles({
optionListFooter: {
padding: tokens.spacingVerticalS,
},
listBox: {
maxHeight: "50vh",
overflowX: "hidden",
overflowY: "auto",
padding: tokens.spacingVerticalXS,
},
transparentBackground: {
backgroundColor: tokens.colorTransparentBackground,
},
});

export interface OptionListProps {
options: EntityOption[];
columns: string[];
languagePack: LanguagePack;
isLoading?: boolean;
hasMoreRecords?: boolean;
showIcon?: ShowIconOptions;
entityIconUrl?: string;
showOptionDetails?: ShowOptionDetailsEnum;
}

export function OptionList({
options,
columns,
languagePack,
isLoading,
hasMoreRecords,
showIcon,
entityIconUrl,
showOptionDetails,
}: OptionListProps) {
const { optionListFooter, listBox, transparentBackground } = useStyles();

if (!options?.length) {
return (
<div className={optionListFooter}>
<Text>{isLoading ? languagePack.LoadingMessage : languagePack.EmptyListDefaultMessage}</Text>
</div>
);
}

return (
<div>
<div className={listBox}>
{options?.map((option) => (
<TagPickerOption
media={
showIcon ? (
<Avatar
className={transparentBackground}
size={showIcon === ShowIconOptions.EntityIcon ? 16 : 28}
shape="square"
name={showIcon === ShowIconOptions.EntityIcon ? "" : option.optionText}
image={{
className: transparentBackground,
src: showIcon === ShowIconOptions.EntityIcon ? entityIconUrl : option.iconSrc,
}}
color={showIcon === ShowIconOptions.EntityIcon ? "neutral" : "colorful"}
aria-hidden
/>
) : undefined
}
key={option.id}
value={option.id}
text={option.optionText}
>
<SuggestionInfo
data={option}
columns={columns}
showOptionDetails={showOptionDetails ?? ShowOptionDetailsEnum.Collapsed}
/>
</TagPickerOption>
))}
</div>
<Divider />
<div className={optionListFooter}>
<Text>{hasMoreRecords ? languagePack.SuggestionListFullMessage : languagePack.NoMoreRecordsMessage}</Text>
</div>
</div>
);
}
Loading

0 comments on commit 8f906d0

Please sign in to comment.