docs(changeset): Extra api options, local data options
This commit is contained in:
		
							parent
							
								
									9506d123f3
								
							
						
					
					
						commit
						b49fadae83
					
				
							
								
								
									
										5
									
								
								.changeset/nasty-bottles-ask.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.changeset/nasty-bottles-ask.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | --- | ||||||
|  | '@warkypublic/oranguru': patch | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | Extra api options, local data options | ||||||
| @ -13,7 +13,7 @@ import { BottomBar } from './components/BottomBar'; | |||||||
| import { Computer } from './components/Computer'; | import { Computer } from './components/Computer'; | ||||||
| import { useGridlerStore } from './components/GridlerStore'; | import { useGridlerStore } from './components/GridlerStore'; | ||||||
| import { Pager } from './components/Pager'; | import { Pager } from './components/Pager'; | ||||||
| import { RightMenuIcon } from './components/RightMenuIcon'; | import { GridlerRightMenuIcon } from './components/RightMenuIcon'; | ||||||
| import { SortSprite } from './components/sprites/Sort'; | import { SortSprite } from './components/sprites/Sort'; | ||||||
| import { SortDownSprite } from './components/sprites/SortDown'; | import { SortDownSprite } from './components/sprites/SortDown'; | ||||||
| import { SortUpSprite } from './components/sprites/SortUp'; | import { SortUpSprite } from './components/sprites/SortUp'; | ||||||
| @ -237,11 +237,13 @@ export const GridlerDataGrid = () => { | |||||||
|             onVisibleRegionChanged={onVisibleRegionChanged} |             onVisibleRegionChanged={onVisibleRegionChanged} | ||||||
|             ref={refMerged as React.Ref<DataEditorRef>} |             ref={refMerged as React.Ref<DataEditorRef>} | ||||||
|             rightElement={ |             rightElement={ | ||||||
|               <Group> |               sections?.rightElementDisabled ? undefined : ( | ||||||
|                 {sections?.rightElementStart} |                 <Group> | ||||||
|                 <RightMenuIcon /> |                   {sections?.rightElementStart} | ||||||
|                 {sections?.rightElementEnd} |                   <GridlerRightMenuIcon /> | ||||||
|               </Group> |                   {sections?.rightElementEnd} | ||||||
|  |                 </Group> | ||||||
|  |               ) | ||||||
|             } |             } | ||||||
|             rowHeight={rowHeight ?? 22} |             rowHeight={rowHeight ?? 22} | ||||||
|             //rowMarkersCheckboxStyle='square'
 |             //rowMarkersCheckboxStyle='square'
 | ||||||
|  | |||||||
| @ -93,6 +93,7 @@ export interface GridlerProps extends PropsWithChildren { | |||||||
|     bottom?: React.ReactNode; |     bottom?: React.ReactNode; | ||||||
|     left?: React.ReactNode; |     left?: React.ReactNode; | ||||||
|     right?: React.ReactNode; |     right?: React.ReactNode; | ||||||
|  |     rightElementDisabled?: boolean; | ||||||
|     rightElementEnd?: React.ReactNode; |     rightElementEnd?: React.ReactNode; | ||||||
|     rightElementStart?: React.ReactNode; |     rightElementStart?: React.ReactNode; | ||||||
|     top?: React.ReactNode; |     top?: React.ReactNode; | ||||||
| @ -100,6 +101,7 @@ export interface GridlerProps extends PropsWithChildren { | |||||||
|   selectedRow?: number; |   selectedRow?: number; | ||||||
|   selectMode?: 'cell' | 'row'; |   selectMode?: 'cell' | 'row'; | ||||||
|   showMenu?: (id: string, options?: Partial<MantineBetterMenuInstance>) => void; |   showMenu?: (id: string, options?: Partial<MantineBetterMenuInstance>) => void; | ||||||
|  |   title?: string; | ||||||
|   tooltipBarProps?: React.HTMLAttributes<HTMLDivElement>; |   tooltipBarProps?: React.HTMLAttributes<HTMLDivElement>; | ||||||
|   total_rows?: number; |   total_rows?: number; | ||||||
|   uniqueid: string; |   uniqueid: string; | ||||||
| @ -426,13 +428,10 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat | |||||||
| 
 | 
 | ||||||
|       const items = |       const items = | ||||||
|         area === 'menu' |         area === 'menu' | ||||||
|           ? [ |           ? [{ leftSection: <IconGrid4x4 size={16} />, title: s.title ?? 'Grid' }] | ||||||
|               { |  | ||||||
|                 label: `Side menu`, |  | ||||||
|               }, |  | ||||||
|             ] |  | ||||||
|           : coldef |           : coldef | ||||||
|             ? [ |             ? [ | ||||||
|  |                 { leftSection: <IconGrid4x4 size={16} />, title: s.title ?? 'Grid' }, | ||||||
|                 { |                 { | ||||||
|                   items: [ |                   items: [ | ||||||
|                     { |                     { | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import { IconMenu2 } from '@tabler/icons-react'; | |||||||
| 
 | 
 | ||||||
| import { useGridlerStore } from './GridlerStore'; | import { useGridlerStore } from './GridlerStore'; | ||||||
| 
 | 
 | ||||||
| export function RightMenuIcon() { | export function GridlerRightMenuIcon() { | ||||||
|   const { loadingData, onContextClick } = useGridlerStore((s) => ({ |   const { loadingData, onContextClick } = useGridlerStore((s) => ({ | ||||||
|     loadingData: s.loadingData, |     loadingData: s.loadingData, | ||||||
|     onContextClick: s.onContextClick, |     onContextClick: s.onContextClick, | ||||||
|  | |||||||
| @ -3,10 +3,15 @@ import React, { useEffect } from 'react'; | |||||||
| 
 | 
 | ||||||
| import type { APIOptions } from '../../utils/types'; | import type { APIOptions } from '../../utils/types'; | ||||||
| 
 | 
 | ||||||
|  | import { GoAPIHeaders, type GoAPIOperation } from '../../utils/golang-restapi-v2'; | ||||||
| import { useGridlerStore } from '../GridlerStore'; | import { useGridlerStore } from '../GridlerStore'; | ||||||
| 
 | 
 | ||||||
| //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
 | export interface GlidlerAPIAdaptorForGoLangv2Props<T = unknown> extends APIOptions { | ||||||
| export const GlidlerAPIAdaptorForGoLangv2 = React.memo((props: APIOptions) => { |   initialData?: Array<T>; | ||||||
|  |   options?: Array<GoAPIOperation>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForGoLangv2Props<T>) { | ||||||
|   const [setStateFN, setState, getState, addError, mounted] = useGridlerStore((s) => [ |   const [setStateFN, setState, getState, addError, mounted] = useGridlerStore((s) => [ | ||||||
|     s.setStateFN, |     s.setStateFN, | ||||||
|     s.setState, |     s.setState, | ||||||
| @ -49,6 +54,13 @@ export const GlidlerAPIAdaptorForGoLangv2 = React.memo((props: APIOptions) => { | |||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (props.options && props.options.length > 0) { | ||||||
|  |           const optionHeaders = GoAPIHeaders(props.options); | ||||||
|  |           for (const oh in optionHeaders) { | ||||||
|  |             head.set(oh, optionHeaders[oh]); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         const currentRequestIndex = _active_requests?.findIndex((f) => f.page === index) ?? -1; |         const currentRequestIndex = _active_requests?.findIndex((f) => f.page === index) ?? -1; | ||||||
|         _active_requests?.forEach((r) => { |         _active_requests?.forEach((r) => { | ||||||
|           if ((r.page >= 0 && r.page < index - 2) || (index >= 0 && r.page > index + 2)) { |           if ((r.page >= 0 && r.page < index - 2) || (index >= 0 && r.page > index + 2)) { | ||||||
| @ -142,6 +154,9 @@ export const GlidlerAPIAdaptorForGoLangv2 = React.memo((props: APIOptions) => { | |||||||
|   }, [props.url, props.authtoken, mounted, setState]); |   }, [props.url, props.authtoken, mounted, setState]); | ||||||
| 
 | 
 | ||||||
|   return <></>; |   return <></>; | ||||||
| }); | } | ||||||
|  | 
 | ||||||
|  | //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
 | ||||||
|  | export const GlidlerAPIAdaptorForGoLangv2 = React.memo(_GlidlerAPIAdaptorForGoLangv2); | ||||||
| 
 | 
 | ||||||
| GlidlerAPIAdaptorForGoLangv2.displayName = 'Gridler-GlidlerAPIAdaptorForGoLangv2'; | GlidlerAPIAdaptorForGoLangv2.displayName = 'Gridler-GlidlerAPIAdaptorForGoLangv2'; | ||||||
|  | |||||||
| @ -45,9 +45,9 @@ export function GlidlerFormAdaptor(props: { | |||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       const items = [] as Array<MantineBetterMenuInstanceItem>; |       const items = [] as Array<MantineBetterMenuInstanceItem>; | ||||||
|       if (defaultItems && id === 'cell') { | 
 | ||||||
|         items.push(...(defaultItems as Array<MantineBetterMenuInstanceItem>)); |       items.push(...(defaultItems as Array<MantineBetterMenuInstanceItem>)); | ||||||
|       } | 
 | ||||||
|       const rows = getState('_gridSelection')?.rows.toArray() ?? []; |       const rows = getState('_gridSelection')?.rows.toArray() ?? []; | ||||||
|       const manyRows = rows.length > 1; |       const manyRows = rows.length > 1; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,15 +1,40 @@ | |||||||
| import React, { useEffect } from 'react'; | import React, { useEffect } from 'react'; | ||||||
| 
 | 
 | ||||||
| import { useGridlerStore } from '../GridlerStore'; | import type { GridlerColumns } from '../Column'; | ||||||
| 
 | 
 | ||||||
| export interface GlidlerLocalDataAdaptorProps { | import { type FilterOption, type SortOption, useGridlerStore } from '../GridlerStore'; | ||||||
|   data: Array<unknown>; | 
 | ||||||
|  | export interface GlidlerLocalDataAdaptorProps<T = unknown> { | ||||||
|  |   data: Array<T>; | ||||||
|  |   onColumnFilter?: ( | ||||||
|  |     colFilters: Array<FilterOption> | undefined, | ||||||
|  |     cols: GridlerColumns | undefined, | ||||||
|  |     data: Array<T> | ||||||
|  |   ) => Array<T>; | ||||||
|  |   onColumnSort?: ( | ||||||
|  |     colSort: Array<SortOption> | undefined, | ||||||
|  |     cols: GridlerColumns | undefined, | ||||||
|  |     data: Array<T> | ||||||
|  |   ) => Array<T>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
 | //The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
 | ||||||
| export const GlidlerLocalDataAdaptor = React.memo((props: GlidlerLocalDataAdaptorProps) => { | function _GlidlerLocalDataAdaptor<T = unknown>(props: GlidlerLocalDataAdaptorProps<T>) { | ||||||
|   const [setState, getState, mounted] = useGridlerStore((s) => [s.setState, s.getState, s.mounted]); |   const [setState, getState, mounted] = useGridlerStore((s) => [s.setState, s.getState, s.mounted]); | ||||||
| 
 | 
 | ||||||
|  |   const { colFilters, colSort, columns } = useGridlerStore((s) => ({ | ||||||
|  |     colFilters: s.colFilters, | ||||||
|  |     colOrder: s.colOrder, | ||||||
|  |     colSize: s.colSize, | ||||||
|  |     colSort: s.colSort, | ||||||
|  |     columns: s.columns, | ||||||
|  |   })); | ||||||
|  | 
 | ||||||
|  |   const refChanged = React.useRef({ | ||||||
|  |     colFilters: colFilters, | ||||||
|  |     colSort: colSort, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|   const useAPIQuery: (index: number) => Promise<any> = async (index: number) => { |   const useAPIQuery: (index: number) => Promise<any> = async (index: number) => { | ||||||
|     const pageSize = getState('pageSize'); |     const pageSize = getState('pageSize'); | ||||||
| 
 | 
 | ||||||
| @ -25,7 +50,26 @@ export const GlidlerLocalDataAdaptor = React.memo((props: GlidlerLocalDataAdapto | |||||||
|     setState('useAPIQuery', useAPIQuery); |     setState('useAPIQuery', useAPIQuery); | ||||||
|   }, [mounted, setState]); |   }, [mounted, setState]); | ||||||
| 
 | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     if (props.onColumnSort && colSort !== refChanged?.current?.colSort) { | ||||||
|  |       const sortedData = props.onColumnSort(colSort, columns, props.data as Array<T>); | ||||||
|  |       setState('total_rows', sortedData.length); | ||||||
|  |       setState('data', sortedData); | ||||||
|  |       refChanged.current.colSort = colSort; | ||||||
|  |     } | ||||||
|  |   }, [colSort, props.onColumnSort]); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     if (props.onColumnFilter && colFilters !== refChanged?.current?.colFilters) { | ||||||
|  |       const filteredData = props.onColumnFilter(colFilters, columns, props.data as Array<T>); | ||||||
|  |       setState('total_rows', filteredData.length); | ||||||
|  |       setState('data', filteredData); | ||||||
|  |       refChanged.current.colFilters = colFilters; | ||||||
|  |     } | ||||||
|  |   }, [colFilters, props.onColumnFilter]); | ||||||
|  | 
 | ||||||
|   return <></>; |   return <></>; | ||||||
| }); | } | ||||||
|  | export const GlidlerLocalDataAdaptor = React.memo(_GlidlerLocalDataAdaptor); | ||||||
| 
 | 
 | ||||||
| GlidlerLocalDataAdaptor.displayName = 'Gridler-GlidlerLocalDataAdaptor'; | GlidlerLocalDataAdaptor.displayName = 'Gridler-GlidlerLocalDataAdaptor'; | ||||||
|  | |||||||
| @ -3,4 +3,6 @@ export {GlidlerFormAdaptor } from './components/adaptors/GlidlerFormAdaptor' | |||||||
| export {GlidlerLocalDataAdaptor } from './components/adaptors/GlidlerLocalDataAdaptor' | export {GlidlerLocalDataAdaptor } from './components/adaptors/GlidlerLocalDataAdaptor' | ||||||
| export * from './components/Column' | export * from './components/Column' | ||||||
| export {useGridlerStore } from './components/GridlerStore' | export {useGridlerStore } from './components/GridlerStore' | ||||||
|  | export { GridlerRightMenuIcon } from './components/RightMenuIcon' | ||||||
| export {Gridler} from './Gridler' | export {Gridler} from './Gridler' | ||||||
|  | export  * from './utils' | ||||||
| @ -106,13 +106,18 @@ export const GridlerGoAPIExampleEventlog = () => { | |||||||
|           //console.log('GridlerGoAPIExampleEventlog onChange', v);
 |           //console.log('GridlerGoAPIExampleEventlog onChange', v);
 | ||||||
|           setValues(v); |           setValues(v); | ||||||
|         }} |         }} | ||||||
|         sections={sections} |         sections={{ ...sections, rightElementDisabled: false }} | ||||||
|         selectedRow={selectRow ? parseInt(selectRow, 10) : undefined} |         selectedRow={selectRow ? parseInt(selectRow, 10) : undefined} | ||||||
|         selectMode="row" |         selectMode="row" | ||||||
|  |         title="Go API Example" | ||||||
|         uniqueid="gridtest" |         uniqueid="gridtest" | ||||||
|         values={values} |         values={values} | ||||||
|       > |       > | ||||||
|         <GlidlerAPIAdaptorForGoLangv2 authtoken={apiKey} url={`${apiUrl}/public/process`} /> |         <GlidlerAPIAdaptorForGoLangv2 | ||||||
|  |           authtoken={apiKey} | ||||||
|  |           //options={[{ type: 'fieldfilter', name: 'process', value: 'test' }]}
 | ||||||
|  |           url={`${apiUrl}/public/process`} | ||||||
|  |         /> | ||||||
|         <Gridler.FormAdaptor |         <Gridler.FormAdaptor | ||||||
|           descriptionField={'process'} |           descriptionField={'process'} | ||||||
|           onRequestForm={(request, data) => { |           onRequestForm={(request, data) => { | ||||||
|  | |||||||
							
								
								
									
										270
									
								
								src/Gridler/utils/golang-restapi-v2/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/Gridler/utils/golang-restapi-v2/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,270 @@ | |||||||
|  | import {b64EncodeUnicode} from '@warkypublic/artemis-kit/base64' | ||||||
|  | const TOKEN_KEY = 'gridler_golang_restapi_v2_token' | ||||||
|  | 
 | ||||||
|  | export type APIOptionsType = { | ||||||
|  |     autocreate?: boolean | ||||||
|  |     autoref?: boolean | ||||||
|  |     baseurl?: string | ||||||
|  |     getAPIProvider?: () => { provider: string; providerKey: string } | ||||||
|  |     getAuthToken?: () => string | ||||||
|  |     operations?: Array<FetchAPIOperation> | ||||||
|  |     postfix?: string | ||||||
|  |     prefix?: string | ||||||
|  |     requestTimeoutSec?: number | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export interface APIResponse { | ||||||
|  |     errmsg: string | ||||||
|  |     payload?: any | ||||||
|  |     retval: number | ||||||
|  | } | ||||||
|  | export interface FetchAPIOperation { | ||||||
|  |     name?: string | ||||||
|  |     op?: string | ||||||
|  |     type: GoAPIHeaderTypes //x-fieldfilter
 | ||||||
|  |     value: string | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * @description Types for the Go Rest API headers | ||||||
|  |  * @typedef {String} GoAPIEnum | ||||||
|  | */ | ||||||
|  | export type GoAPIEnum = | ||||||
|  |   | 'advsql' | ||||||
|  |   | 'api-key' | ||||||
|  |   | 'api-range-from' | ||||||
|  |   | 'api-range-size' | ||||||
|  |   | 'api-range-total' | ||||||
|  |   | 'api-src' | ||||||
|  |   | 'api' | ||||||
|  |   | 'association_autocreate' | ||||||
|  |   | 'association_autoupdate' | ||||||
|  |   | 'association-update' | ||||||
|  |   | 'cql-sel' | ||||||
|  |   | 'cursor-backward'// For x cursor-backward header
 | ||||||
|  |   | 'cursor-forward' // For x cursor-forward header
 | ||||||
|  |   | 'custom-sql-join' | ||||||
|  |   | 'custom-sql-or' | ||||||
|  |   | 'custom-sql-w' | ||||||
|  |   | 'detailapi' | ||||||
|  |   | 'distinct' | ||||||
|  |   | 'expand' | ||||||
|  |   | 'fetch-rownumber' | ||||||
|  |   | 'fieldfilter' | ||||||
|  |   | 'fieldfilter' | ||||||
|  |   | 'files' //For x files header
 | ||||||
|  |   | 'func' | ||||||
|  |   | 'limit' | ||||||
|  |   | 'no-return' | ||||||
|  |   | 'not-select-fields' | ||||||
|  |   | 'offset' | ||||||
|  |   | 'parm' | ||||||
|  |   | 'pkrow' | ||||||
|  |   | 'preload' | ||||||
|  |   | 'searchand' | ||||||
|  |   | 'searchfilter' | ||||||
|  |   | 'searchfilter' | ||||||
|  |   | 'searchop' | ||||||
|  |   | 'searchop' | ||||||
|  |   | 'searchor' | ||||||
|  |   | 'select-fields' | ||||||
|  |   | 'simpleapi' | ||||||
|  |   | 'skipcache' | ||||||
|  |   | 'skipcount' | ||||||
|  |   | 'sort' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export type GoAPIHeaderKeys = `x-${GoAPIEnum}` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export type GoAPIHeaderTypes = GoAPIEnum & string | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export interface GoAPIOperation { | ||||||
|  |   name?: string | ||||||
|  |   op?: string | ||||||
|  |   type: GoAPIHeaderTypes //x-fieldfilter
 | ||||||
|  |   value: string | ||||||
|  | } | ||||||
|  | export interface MetaData { | ||||||
|  |     limit?: number | ||||||
|  |     offset?: number | ||||||
|  |     total?: number | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Builds an array of objects by encoding specific values and setting headers. | ||||||
|  |  * | ||||||
|  |  * @param {Array<FetchAPIOperation>} ops - The array of FetchAPIOperation objects to be built. | ||||||
|  |  * @param {Headers} [headers] - Optional headers to be set. | ||||||
|  |  * @return {Array<FetchAPIOperation>} - The built array of FetchAPIOperation objects. | ||||||
|  |  */ | ||||||
|  | const buildGoAPIOperation = ( | ||||||
|  |   ops: Array<FetchAPIOperation>, | ||||||
|  |   headers?: Headers | ||||||
|  | ): Array<FetchAPIOperation> => { | ||||||
|  |   const newops = [...ops.filter((i) => i !== undefined && i.type !== undefined)] | ||||||
|  | 
 | ||||||
|  |     | ||||||
|  |   for (let i = 0; i < newops.length; i++) { | ||||||
|  |     if (!newops[i].name || newops[i].name === '') { | ||||||
|  |       newops[i].name = '' | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'files' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'advsql' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (newops[i].type === 'custom-sql-or' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (newops[i].type === 'custom-sql-join' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'not-select-fields' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'custom-sql-w' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'select-fields' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  |     if (newops[i].type === 'cql-sel' && !newops[i].value.startsWith('__')) { | ||||||
|  |       newops[i].value = `__${b64EncodeUnicode(newops[i].value)}__` | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (headers) { | ||||||
|  |       if (!newops || newops.length === 0) { | ||||||
|  |         headers.set(`x-limit`, '10') | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (newops[i].type === 'association_autoupdate') { | ||||||
|  |         headers.set(`association_autoupdate`, newops[i].value ?? '1') | ||||||
|  |       } | ||||||
|  |       if (newops[i].type === 'association_autocreate') { | ||||||
|  |         headers.set(`association_autocreate`, newops[i].value ?? '1') | ||||||
|  |       } | ||||||
|  |       if ( | ||||||
|  |         newops[i].type === 'searchop' || | ||||||
|  |         newops[i].type === 'searchor' || | ||||||
|  |         newops[i].type === 'searchand' | ||||||
|  |       ) { | ||||||
|  |         headers.set( | ||||||
|  |           encodeURIComponent(`x-${newops[i].type}-${newops[i].op}-${newops[i].name}`), | ||||||
|  |           String(newops[i].value) | ||||||
|  |         ) | ||||||
|  |       } else { | ||||||
|  |         headers.set( | ||||||
|  |           encodeURIComponent( | ||||||
|  |             `x-${newops[i].type}${newops[i].name && newops[i].name !== '' ? '-' + newops[i].name : ''}` | ||||||
|  |           ), | ||||||
|  |           String(newops[i].value) | ||||||
|  |         ) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return newops | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Retrieves the headers from an array of FetchAPIOperation objects and returns them as an object. | ||||||
|  |  * | ||||||
|  |  * @param {Array<FetchAPIOperation>} ops - The array of FetchAPIOperation objects. | ||||||
|  |  * @return {{ [key: string]: string }} - The headers as an object with string keys and string values. | ||||||
|  |  */ | ||||||
|  | const GoAPIHeaders = ( | ||||||
|  |   ops: Array<FetchAPIOperation>, | ||||||
|  |   headers?: Headers | ||||||
|  | ): { [key: string]: string } => { | ||||||
|  |   const head = new Headers() | ||||||
|  |   const headerlist: Record<string,string> = {} | ||||||
|  | 
 | ||||||
|  |   const authToken = getAuthToken?.() | ||||||
|  |   if (authToken && authToken !== '') { | ||||||
|  |       | ||||||
|  |     head.set('Authorization', `Token ${authToken}`) | ||||||
|  |   } else { | ||||||
|  |     const token = getAuthToken() | ||||||
|  |     if (token) { | ||||||
|  |       head.set('Authorization', `Token ${token}`) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   if (headers) { | ||||||
|  |     headers.forEach((v, k) => { | ||||||
|  |       head.set(k, v) | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |   const distinctOperations: Array<FetchAPIOperation> = [] | ||||||
|  | 
 | ||||||
|  |   for (const value of ops?.filter((val) => !!val) ?? []) { | ||||||
|  |     const index = distinctOperations.findIndex( | ||||||
|  |       (searchValue) => searchValue.name === value.name && searchValue.type === value.type | ||||||
|  |     ) | ||||||
|  |     if (index === -1) { | ||||||
|  |       distinctOperations.push(value) | ||||||
|  |     } else { | ||||||
|  |       distinctOperations[index] = value | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   buildGoAPIOperation(distinctOperations, head) | ||||||
|  | 
 | ||||||
|  |   head?.forEach((v, k) => { | ||||||
|  |     headerlist[k] = v | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|  |   if (headers) { | ||||||
|  |     for (const key of Object.keys(headerlist)) { | ||||||
|  |       headers.set(key, headerlist[key]) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return headerlist | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const callbacks = { | ||||||
|  |     getAuthToken: () => { | ||||||
|  |     if (localStorage) { | ||||||
|  |         const token = localStorage.getItem(TOKEN_KEY) | ||||||
|  |         if (token) { | ||||||
|  |         return token | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Retrieves the authentication token from local storage. | ||||||
|  |  * | ||||||
|  |  * @return {string | undefined} The authentication token if found, otherwise undefined | ||||||
|  |  */ | ||||||
|  | const getAuthToken = () => callbacks?.getAuthToken?.() | ||||||
|  | 
 | ||||||
|  | const setAuthTokenCallback = (cb: ()=> string) => { | ||||||
|  |     callbacks.getAuthToken = cb | ||||||
|  |     return callbacks.getAuthToken | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Sets the authentication token in the local storage. | ||||||
|  |  * | ||||||
|  |  * @param {string} token - The authentication token to be set. | ||||||
|  |  */ | ||||||
|  | const setAuthToken = (token: string) => { | ||||||
|  |   if (localStorage) { | ||||||
|  |     localStorage.setItem(TOKEN_KEY, token) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export {buildGoAPIOperation,getAuthToken,GoAPIHeaders,setAuthToken,setAuthTokenCallback} | ||||||
| @ -1,81 +0,0 @@ | |||||||
| export type APIOptionsType = { |  | ||||||
|     autocreate?: boolean |  | ||||||
|     autoref?: boolean |  | ||||||
|     baseurl?: string |  | ||||||
|     getAPIProvider?: () => { provider: string; providerKey: string } |  | ||||||
|     getAuthToken?: () => string |  | ||||||
|     operations?: Array<FetchAPIOperation> |  | ||||||
|     postfix?: string |  | ||||||
|     prefix?: string |  | ||||||
|     requestTimeoutSec?: number |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export interface APIResponse { |  | ||||||
|     errmsg: string |  | ||||||
|     payload?: any |  | ||||||
|     retval: number |  | ||||||
| } |  | ||||||
| export interface FetchAPIOperation { |  | ||||||
|     name?: string |  | ||||||
|     op?: string |  | ||||||
|     type: FetchOpTypes //x-fieldfilter
 |  | ||||||
|     value: string |  | ||||||
| } |  | ||||||
| export type FetchOpTypes = GoAPIEnum & string |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * @description Types for the Go Rest API headers |  | ||||||
|  * @typedef {String} GoAPIEnum |  | ||||||
| */ |  | ||||||
| export type GoAPIEnum = 'advsql' |  | ||||||
|     | 'api-key' |  | ||||||
|     | 'api-range-from' |  | ||||||
|     | 'api-range-size' |  | ||||||
|     | 'api-range-total' |  | ||||||
|     | 'api-src' |  | ||||||
|     | 'api' |  | ||||||
|     | 'association_autocreate' |  | ||||||
|     | 'association_autoupdate' |  | ||||||
|     | 'association-update' |  | ||||||
|     | 'cql-sel' |  | ||||||
|     | 'custom-sql-join' |  | ||||||
|     | 'custom-sql-or' |  | ||||||
|     | 'custom-sql-w' |  | ||||||
|     | 'detailapi' |  | ||||||
|     | 'distinct' |  | ||||||
|     | 'expand' |  | ||||||
|     | 'fetch-rownumber' |  | ||||||
|     | 'fieldfilter' |  | ||||||
|     | 'fieldfilter' |  | ||||||
|     | 'func' |  | ||||||
|     | 'limit' |  | ||||||
|     | 'no-return' |  | ||||||
|     | 'not-select-fields' |  | ||||||
|     | 'offset' |  | ||||||
|     | 'parm' |  | ||||||
|     | 'pkrow' |  | ||||||
|     | 'preload' |  | ||||||
|     | 'searchfilter' |  | ||||||
|     | 'searchfilter' |  | ||||||
|     | 'searchop' |  | ||||||
|     | 'searchop' |  | ||||||
|     | 'select-fields' |  | ||||||
|     | 'simpleapi' |  | ||||||
|     | 'skipcache' |  | ||||||
|     | 'skipcount' |  | ||||||
|     | 'sort' |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export type GoAPIHeaderKeys = `x-${GoAPIEnum}` |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export type MetaCallback = (data: MetaData) => void |  | ||||||
| 
 |  | ||||||
| export interface MetaData { |  | ||||||
|     limit?: number |  | ||||||
|     offset?: number |  | ||||||
|     total?: number |  | ||||||
| } |  | ||||||
| @ -0,0 +1 @@ | |||||||
|  | export {type APIOptionsType,type FetchAPIOperation,GoAPIHeaders} from './golang-restapi-v2' | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user