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

PolyLookup/91-cache-not-invalidated #92

Merged
merged 2 commits into from
Jan 13, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll": "explicit"
},
"editor.formatOnSave": true
}
12 changes: 3 additions & 9 deletions PolyLookupComponent/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
"browser": true,
"es2021": true
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"plugin:react/recommended",
"prettier"
],
"extends": ["plugin:@typescript-eslint/recommended", "plugin:react/recommended"],
"globals": {
"ComponentFramework": true
},
Expand All @@ -17,11 +12,10 @@
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@microsoft/power-apps", "@typescript-eslint", "prettier"],
"plugins": ["@microsoft/power-apps", "@typescript-eslint"],
"rules": {
"no-unused-vars": "off",
"no-explicit-any": "off",
"prettier/prettier": "warn"
"no-explicit-any": "off"
},
"settings": {
"react": {
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.2.1" display-name-key="PolyLookup v1.2.1" description-key="Multi-select lookup supporting different type of many-to-many relationships" control-type="virtual" >
<control namespace="DCEPCF" constructor="PolyLookup" version="1.2.2" display-name-key="PolyLookup v1.2.2" description-key="Multi-select lookup supporting different type of many-to-many relationships" control-type="virtual" >
<!--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
29 changes: 11 additions & 18 deletions PolyLookupComponent/PolyLookup/components/PolyLookupControl.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React, { useCallback } from "react";
import {
IBasePickerStyles,
IBasePickerSuggestionsProps,
Expand All @@ -9,6 +8,8 @@ import {
ValidationState,
} from "@fluentui/react";
import { QueryClient, QueryClientProvider, useMutation } from "@tanstack/react-query";
import Handlebars from "handlebars";
import React, { useCallback } from "react";
import {
associateRecord,
createRecord,
Expand All @@ -18,11 +19,9 @@ import {
retrieveMultipleFetch,
useMetadata,
useSelectedItems,
useSuggestions,
} from "../services/DataverseService";
import { SuggestionInfo } from "./SuggestionInfo";
import { IMetadata } from "../types/metadata";
import Handlebars from "handlebars";
import { SuggestionInfo } from "./SuggestionInfo";

const queryClient = new QueryClient();
const parser = new DOMParser();
Expand Down Expand Up @@ -143,21 +142,13 @@ const Body = ({

const fetchXmlTemplate = Handlebars.compile(associatedFetchXml ?? "");

// get top 50 suggestions from associated table
const { data: suggestions, isLoading: isLoadingSuggestions } = useSuggestions(
relationshipName,
associatedTableSetName,
fetchXmlTemplate,
pageSize
);

// get selected items
const {
data: selectedItems,
isInitialLoading: isLoadingSelectedItems,
isSuccess: isLoadingSelectedItemsSuccess,
refetch: selectedItemsRefetch,
} = useSelectedItems(currentTable, currentRecordId, metadata, formType);
} = useSelectedItems(metadata, currentRecordId, formType);

if (isLoadingSelectedItemsSuccess && onChange) {
onChange(
Expand All @@ -179,7 +170,6 @@ const Body = ({
if (!lookupView && metadata?.associatedView.querytype === 64) {
shouldDefaultSearch = true;
} else {
const currentRecord = getCurrentRecord();
if (
!fetchXml.includes("{{PolyLookupSearch}}") &&
!fetchXml.includes("{{ PolyLookupSearch}}") &&
Expand All @@ -189,6 +179,8 @@ const Body = ({
shouldDefaultSearch = true;
}

const currentRecord = getCurrentRecord();

fetchXml = fetchXmlTemplate({
...currentRecord,
PolyLookupSearch: searchText,
Expand Down Expand Up @@ -286,9 +278,10 @@ const Body = ({

const showAllSuggestions = useCallback(
async (selectedTags?: ITag[]): Promise<ITag[]> => {
return getSuggestionTags(suggestions, metadata);
const results = await filterQuery.mutateAsync({ searchText: "", pageSizeParam: pageSize });
return getSuggestionTags(results, metadata);
},
[suggestions, metadata?.associatedEntity.PrimaryIdAttribute]
[metadata?.associatedEntity.PrimaryIdAttribute]
);

const onPickerChange = useCallback(
Expand Down Expand Up @@ -419,7 +412,7 @@ const Body = ({
return ValidationState.invalid;
};

const isDataLoading = (isLoadingMetadata || isLoadingSuggestions || isLoadingSelectedItems) && !shouldDisable();
const isDataLoading = (isLoadingMetadata || isLoadingSelectedItems) && !shouldDisable();

return (
<TagPicker
Expand Down Expand Up @@ -499,7 +492,7 @@ function getSuggestionTags(
key: i[metadata?.associatedEntity.PrimaryIdAttribute ?? ""] ?? "",
name: i[metadata?.associatedEntity.PrimaryNameAttribute ?? ""] ?? "",
data: i,
} as ITagWithData)
}) as ITagWithData
) ?? []
);
}
Expand Down
41 changes: 12 additions & 29 deletions PolyLookupComponent/PolyLookup/services/DataverseService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import {
IEntityDefinition,
Expand All @@ -8,7 +9,6 @@ import {
IViewDefinition,
IViewLayout,
} from "../types/metadata";
import { useQuery } from "@tanstack/react-query";

const nToNColumns = [
"SchemaName",
Expand Down Expand Up @@ -51,41 +51,19 @@ export function useMetadata(
lookupView: string | undefined
) {
return useQuery({
queryKey: [
`${relationshipName}_${lookupView}_metadata`,
{ currentTable, relationshipName, relationship2Name, lookupView },
],
queryKey: ["metadata", currentTable, relationshipName, relationship2Name, lookupView],
queryFn: () => getMetadata(currentTable, relationshipName, relationship2Name, lookupView),
enabled: !!currentTable && !!relationshipName,
});
}

export function useSuggestions(
relationshipName: string,
associatedTableSetName: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fetchXmlTemplate: HandlebarsTemplateDelegate<any>,
pageSize: number | undefined
) {
return useQuery({
queryKey: [`${relationshipName}_suggestionItems`, { associatedTableSetName, pageSize }],
queryFn: () => {
const currentRecord = getCurrentRecord();
const fetchXml = fetchXmlTemplate(currentRecord);
return retrieveMultipleFetch(associatedTableSetName, fetchXml, 1, pageSize);
},
enabled: !!relationshipName && !!associatedTableSetName,
});
}

export function useSelectedItems(
currentTable: string,
currentRecordId: string,
metadata: IMetadata | undefined,
currentRecordId: string,
formType: XrmEnum.FormType | undefined
) {
return useQuery({
queryKey: [`${metadata?.relationship1.SchemaName}_selectedItems`, { currentTable, currentRecordId }],
queryKey: ["selectedItems", metadata, currentRecordId, formType],
queryFn: () =>
retrieveAssociatedRecords(
currentRecordId,
Expand Down Expand Up @@ -485,10 +463,15 @@ export function deleteRecord(entitySetName: string | undefined, recordId: string
});
}

export function getCurrentRecord(): ComponentFramework.WebApi.Entity {
export function getCurrentRecord(attributes?: string[]): ComponentFramework.WebApi.Entity {
let entityAttributes = Xrm.Page.data.entity.attributes.get();

if (attributes?.length) {
entityAttributes = entityAttributes.filter((a) => attributes.includes(a.getName()));
}

return Object.fromEntries(
/* global Xrm */
Xrm.Page.data.entity.attributes.get().map((attribute) => {
entityAttributes.map((attribute) => {
const attributeType = attribute.getAttributeType();
if (attributeType === "lookup") {
const lookupVal = (attribute as Xrm.Attributes.LookupAttribute).getValue()?.at(0);
Expand Down
25 changes: 20 additions & 5 deletions PolyLookupComponent/PolyLookup/types/handlebars.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
declare module "handlebars/lib/handlebars" {
// Re-export the types from the existing handlebars module
import Handlebars = require("handlebars");
export default Handlebars;
}
import Handlebars from "handlebars";

export const getHBVars = (value: string) => {
const ast = Handlebars.parse(value);
const keys = [];

for (const i in ast.body) {
if (ast.body[i].type === "MustacheStatement") {
const statement = ast.body[i] as hbs.AST.MustacheStatement;
if (statement.path.type === "PathExpression") {
const varName = (statement.path as hbs.AST.PathExpression).original;
const attr = varName.split(".").at(0);
if (attr) {
keys.push(attr);
}
}
}
}
return Array.from(new Set<string>(keys));
};
50 changes: 35 additions & 15 deletions PolyLookupComponent/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion PolyLookupComponent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"eslint": "^8.24.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.1",
"eslint-plugin-react": "^7.31.8",
"pcf-scripts": "^1",
"pcf-start": "^1",
"prettier": "2.8.7",
"prettier": "3.0.3",
"react": "^16.8",
"typescript": "^4.8.4"
}
Expand Down
Loading