@shko.online/lookupobjects-mock
Version:
Mocking Dataverse Lookup Objects to simplify writing soties for PCF components
187 lines • 8.97 kB
JavaScript
import React, { useCallback, useMemo, useRef, useState } from 'react';
import './LookupCss.css';
import SingleEntityFilter from './SingleEntityFilter';
import MultiEntityFilter from './MultiEntityFilter';
import Header from './Header';
import Footer from './Footer';
import SelectedRecord from './SelectedRecord';
import SearchLookup from './SearchLookup';
function LookupComponent({
unmount,
resolve,
lookupOptions,
db
}) {
const {
allowMultiSelect,
entityTypes
} = lookupOptions;
const [results, setResults] = useState(null);
const [selected, setSelected] = useState(null);
const selectedIds = useMemo(() => (selected === null || selected === void 0 ? void 0 : selected.map(i => i.id)) || [], [selected]);
const inpuRef = useRef();
const onCloseClick = useCallback(() => {
console.log('unmount?');
unmount();
resolve([]);
}, [resolve, unmount]);
const searchRecords = useCallback(search => {
const result = [];
entityTypes.forEach(value => {
const metadata = db.getTableMetadata(value);
const select = `SELECT ${metadata.PrimaryIdAttribute}, ${metadata.PrimaryNameAttribute}
FROM ${metadata.LogicalName}
${search ? `WHERE ${metadata.PrimaryNameAttribute || 'name'} LIKE '%${search}%'` : ''}`;
const res = db.db.exec(select).map(v => ({
entityType: value,
id: v[metadata.PrimaryIdAttribute],
name: v[metadata.PrimaryNameAttribute]
}));
result.push(...res);
});
console.log('Result', result);
setResults(result.filter(i => !selectedIds.includes(i.id)));
}, [db, entityTypes, selectedIds]);
const searchByEntityRecords = useCallback(entity => {
var _inpuRef$current;
const search = inpuRef === null || inpuRef === void 0 || (_inpuRef$current = inpuRef.current) === null || _inpuRef$current === void 0 ? void 0 : _inpuRef$current.value;
const result = [];
console.log(entity);
lookupOptions.entityTypes.forEach(value => {
if (entity && value !== entity) {
return;
}
const metadata = db.getTableMetadata(value);
const select = `SELECT ${metadata.PrimaryIdAttribute}, ${metadata.PrimaryNameAttribute}
FROM ${metadata.LogicalName}
${search ? `WHERE ${metadata.PrimaryNameAttribute || 'name'} LIKE '%${search}%'` : ''}`;
const res = db.db.exec(select).map(v => ({
entityType: value,
id: v[metadata.PrimaryIdAttribute],
name: v[metadata.PrimaryNameAttribute]
}));
result.push(...res);
});
console.log('Result', result);
setResults(result.filter(i => !(selectedIds !== null && selectedIds !== void 0 && selectedIds.includes(i.id))));
}, [db, lookupOptions.entityTypes, selectedIds]);
const OnSearchClick = useCallback(() => {
const search = inpuRef.current.value;
searchRecords(search);
}, [searchRecords]);
const onSelect = useCallback(lookup => {
if (allowMultiSelect) {
setSelected(prev => {
return prev ? [...prev, lookup] : [lookup];
});
setResults(prev => {
return prev.filter(i => i.id !== lookup.id);
});
} else {
setSelected([lookup]);
setResults(null);
}
}, [allowMultiSelect]);
const onUnSelect = useCallback(lookup => {
var _inpuRef$current2;
setSelected(prev => {
const state = prev.filter(item => item.id !== lookup.id);
return state.length === 0 ? null : state;
});
if (allowMultiSelect) setResults(prev => [...prev, lookup]);
if (inpuRef !== null && inpuRef !== void 0 && (_inpuRef$current2 = inpuRef.current) !== null && _inpuRef$current2 !== void 0 && _inpuRef$current2.value) inpuRef.current.value = '';
}, [allowMultiSelect]);
const onAddClick = useCallback(() => {
resolve(selected);
setSelected(null);
unmount();
}, [resolve, selected, unmount]);
const lookForRecords = useMemo(() => {
if (lookupOptions.entityTypes.length > 1) {
return 'Look for records';
}
const metadata = db.getTableMetadata(lookupOptions.entityTypes[0]);
return 'Look for ' + ((metadata === null || metadata === void 0 ? void 0 : metadata.DisplayCollectionName) || (metadata === null || metadata === void 0 ? void 0 : metadata.DisplayName) || (metadata === null || metadata === void 0 ? void 0 : metadata.LogicalName));
}, [db, lookupOptions.entityTypes]);
const entityTypesFilter = useMemo(() => {
const metadata = db.getTableMetadata(lookupOptions.entityTypes[0]);
// return 'Look for ' + (metadata.DisplayCollectionName || metadata.DisplayName || metadata.LogicalName);
return lookupOptions.entityTypes.length === 1 ? /*#__PURE__*/React.createElement(SingleEntityFilter, {
entity: (metadata === null || metadata === void 0 ? void 0 : metadata.DisplayName) || (metadata === null || metadata === void 0 ? void 0 : metadata.LogicalName)
}) : /*#__PURE__*/React.createElement(MultiEntityFilter, {
db: db,
entityTypes: lookupOptions.entityTypes,
results: results,
searchByEntityRecords: searchByEntityRecords
});
}, [db, lookupOptions.entityTypes, results, searchByEntityRecords]);
return /*#__PURE__*/React.createElement("div", {
className: "so.fixed so.top-0 so.bottom-0 so.right-0 so.left-0 so.z-50 so.w-full so.bg-opacity-30 so.bg-black so.flex so.justify-end"
}, /*#__PURE__*/React.createElement("div", {
className: "so.flex so.flex-col so.h-full so.box-border so.bg-white so.border-solid so.border-2 so.border-transparent so.overflow-auto so.flex-nowrap so.w-[400px] so.content-start so.outline-none so.text-neutral-800 so.font-sans so.font-normal so.antialiased so.visible"
}, /*#__PURE__*/React.createElement("section", {
className: "so.flex so.flex-col so.flex-1"
}, /*#__PURE__*/React.createElement(Header, {
onCloseClick: onCloseClick
}), /*#__PURE__*/React.createElement("div", {
className: "so.flex so.overflow-visible so.mb-6 so.mx-2 so.mt-4 so.justify-between so.h-full so.flex-col",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
className: "so.flex so.w-full",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
className: "so.max-w-full so.flex-1 so.flex",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
className: "so.flex so.flex-col so.w-full so.border so.border-zinc-100 so.border-solid",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
className: "so.flex so.w-full",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
className: "so.rounded so.w-full so.bg-gray-100",
role: "presentation"
}, /*#__PURE__*/React.createElement("div", {
"aria-atomic": "true",
role: "status"
}), selected === null && /*#__PURE__*/React.createElement(SearchLookup, {
inputRef: inpuRef,
lookForRecords: lookForRecords,
onSearchClick: OnSearchClick,
searchRecords: searchRecords
}), selected != null && /*#__PURE__*/React.createElement(SelectedRecord, {
allowMultiSelect: allowMultiSelect,
inputRef: inpuRef,
onSearchClick: OnSearchClick,
onUnSelect: onUnSelect,
searchRecords: searchRecords,
selected: selected
}))), /*#__PURE__*/React.createElement("div", {
className: "so.w-full so.flex so.flex-1 so.flex-col",
role: "presentation"
}, results === null && /*#__PURE__*/React.createElement("span", {
className: "so.p-2 so.text-sm so.leading-8 so.cursor-default so.text-neutral-800"
}, "Type to search or press Enter to browse"), (results === null || results === void 0 ? void 0 : results.length) === 0 && /*#__PURE__*/React.createElement("span", {
className: "so.p-2 so.text-sm so.leading-8 so.cursor-default so.text-neutral-800"
}, "No records found. Create a new record."), (results === null || results === void 0 ? void 0 : results.length) > 0 && entityTypesFilter, (results === null || results === void 0 ? void 0 : results.length) > 0 && /*#__PURE__*/React.createElement("ul", {
className: "so.flex-1 so.flex-col so.scroll-auto"
}, results.map(r => /*#__PURE__*/React.createElement("li", {
className: "so.flex",
key: r.id
}, /*#__PURE__*/React.createElement("button", {
className: "so.flex so.flex-1 so.gap-x-1 so.min-h-12 so.items-center so.overflow-hidden so.rounded hover:so.bg-gray-200",
key: r.id,
onClick: () => onSelect(r)
}, /*#__PURE__*/React.createElement("div", {
className: "so.justify-start so.flex so.text-sm so.items-center so.px-1"
}, /*#__PURE__*/React.createElement("img", {
className: "so.h-6 so.w-6",
src: "./favicon.ico"
})), /*#__PURE__*/React.createElement("div", {
className: "so.flex-1 so.truncate so.text-start"
}, r.name)))))))))), /*#__PURE__*/React.createElement(Footer, {
onAddClick: onAddClick,
onCloseClick: onCloseClick
}))));
}
export default LookupComponent;