UNPKG

@shko.online/lookupobjects-mock

Version:

Mocking Dataverse Lookup Objects to simplify writing soties for PCF components

187 lines 8.22 kB
/* eslint-disable sonarjs/no-nested-template-literals */ 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(_ref) { let { unmount, resolve, lookupOptions, db } = _ref; const { allowMultiSelect, entityTypes } = lookupOptions; const [results, setResults] = useState(null); const [selected, setSelected] = useState(null); const selectedIds = useMemo(() => 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 => { const search = 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?.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 => { 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?.current?.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?.DisplayCollectionName || metadata?.DisplayName || 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?.DisplayName || 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?.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?.length > 0 && entityTypesFilter, 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;