@ram_28/kf-ai-sdk 1.0.33 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/hooks/useTable/types.d.ts +2 -2
- package/dist/components/hooks/useTable/types.d.ts.map +1 -1
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +19 -19
- package/docs/api.md +4 -0
- package/docs/useAuth.md +5 -2
- package/docs/useFilter.md +186 -77
- package/docs/useForm.md +14 -9
- package/docs/useTable.md +9 -6
- package/package.json +1 -1
- package/sdk/components/hooks/useTable/types.ts +2 -2
- package/sdk/components/hooks/useTable/useTable.llm.txt +8 -7
- package/sdk/components/hooks/useTable/useTable.ts +5 -5
|
@@ -37,8 +37,8 @@ export interface UseTableReturnType<T> {
|
|
|
37
37
|
error: Error | null;
|
|
38
38
|
search: {
|
|
39
39
|
query: string;
|
|
40
|
-
field:
|
|
41
|
-
set: (field: keyof T
|
|
40
|
+
field: keyof T | null;
|
|
41
|
+
set: (field: keyof T, query: string) => void;
|
|
42
42
|
clear: () => void;
|
|
43
43
|
};
|
|
44
44
|
sort: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../sdk/components/hooks/useTable/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG9F,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAM9E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,oBAAoB;IACpB,YAAY,CAAC,EAAE;QACb,mDAAmD;QACnD,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,6CAA6C;QAC7C,UAAU,CAAC,EAAE,mBAAmB,CAAC;QACjC,6CAA6C;QAC7C,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;KAClC,CAAC;IACF,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,uBAAuB;IACvB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IAEnC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IAGnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IAGpB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAGpB,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../sdk/components/hooks/useTable/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG9F,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAM9E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,oBAAoB;IACpB,YAAY,CAAC,EAAE;QACb,mDAAmD;QACnD,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,6CAA6C;QAC7C,UAAU,CAAC,EAAE,mBAAmB,CAAC;QACjC,6CAA6C;QAC7C,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;KAClC,CAAC;IACF,qBAAqB;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,uBAAuB;IACvB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IAEnC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IAGnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IAGpB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAGpB,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACtB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7C,KAAK,EAAE,MAAM,IAAI,CAAC;KACnB,CAAC;IAGF,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACtB,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;QACjC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;QACjC,KAAK,EAAE,MAAM,IAAI,CAAC;QAClB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC;KAC1D,CAAC;IAGF,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAG/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;QACnB,aAAa,EAAE,OAAO,CAAC;QACvB,QAAQ,EAAE,MAAM,IAAI,CAAC;QACrB,YAAY,EAAE,MAAM,IAAI,CAAC;QACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACjC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KACrC,CAAC;IAGF,OAAO,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;CAC7C"}
|
package/dist/table.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react"),x=require("@tanstack/react-query"),D=require("./client-DxjRcEtN.cjs"),y=require("./error-handling-CAoD0Kwb.cjs"),re=require("./useFilter-DzpP_ag0.cjs");function oe(o){var k,z,M,P,Q,O,R,w;const[a,h]=r.useState({query:"",debouncedQuery:"",field:null}),c=r.useRef(null),H=300,j=()=>{var t,n;const e=(t=o.initialState)==null?void 0:t.sort;if(e&&e.length>0){const A=e[0],L=Object.keys(A)[0],te=(n=A[L])==null?void 0:n.toLowerCase();return{field:L,direction:te}}return{field:null,direction:null}},[s,p]=r.useState(j),[i,u]=r.useState({pageNo:((z=(k=o.initialState)==null?void 0:k.pagination)==null?void 0:z.pageNo)||1,pageSize:((P=(M=o.initialState)==null?void 0:M.pagination)==null?void 0:P.pageSize)||10}),C=re.useFilter({conditions:(O=(Q=o.initialState)==null?void 0:Q.filter)==null?void 0:O.conditions,operator:((w=(R=o.initialState)==null?void 0:R.filter)==null?void 0:w.operator)||"And"}),l=r.useMemo(()=>{const e={};let t=C.payload;if(a.debouncedQuery&&a.field){const n={LHSField:a.field,Operator:"Contains",RHSValue:a.debouncedQuery,RHSType:"Constant"};t?t.Operator==="And"?t={...t,Condition:[...t.Condition||[],n]}:t={Operator:"And",Condition:[t,n]}:t={Operator:"And",Condition:[n]}}return t&&(e.Filter=t),e},[a.debouncedQuery,a.field,C.payload]),N=r.useMemo(()=>{const e={...l};return s.field&&s.direction&&(e.Sort=[{[String(s.field)]:s.direction==="asc"?"ASC":"DESC"}]),e.Page=i.pageNo,e.PageSize=i.pageSize,e},[l,s,i]),{data:d,isLoading:G,isFetching:I,error:T,refetch:E}=x.useQuery({queryKey:["table",o.source,N],queryFn:async()=>{try{const e=await D.api(o.source).list(N);return o.onSuccess&&o.onSuccess(e.Data),e}catch(e){throw o.onError&&o.onError(y.toError(e)),e}},staleTime:0,gcTime:0}),{data:g,isLoading:K,isFetching:_,error:q,refetch:F}=x.useQuery({queryKey:["table-count",o.source,l],queryFn:async()=>{try{return await D.api(o.source).count(l)}catch(e){throw o.onError&&o.onError(y.toError(e)),e}},staleTime:0,gcTime:0}),B=r.useMemo(()=>(d==null?void 0:d.Data)||[],[d]),f=r.useMemo(()=>(g==null?void 0:g.Count)||0,[g]),S=r.useMemo(()=>Math.ceil(f/i.pageSize),[f,i.pageSize]),U=r.useCallback(e=>{p(t=>{if(t.field===e){if(t.direction==="asc")return{field:e,direction:"desc"};if(t.direction==="desc")return{field:null,direction:null}}return{field:e,direction:"asc"}})},[]),V=r.useCallback(()=>{p({field:null,direction:null})},[]),J=r.useCallback((e,t)=>{p({field:e,direction:t})},[]),W=r.useCallback((e,t)=>{if(t.length>255){console.warn("Search query exceeds maximum length of 255 characters");return}h(n=>({...n,query:t,field:
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react"),x=require("@tanstack/react-query"),D=require("./client-DxjRcEtN.cjs"),y=require("./error-handling-CAoD0Kwb.cjs"),re=require("./useFilter-DzpP_ag0.cjs");function oe(o){var k,z,M,P,Q,O,R,w;const[a,h]=r.useState({query:"",debouncedQuery:"",field:null}),c=r.useRef(null),H=300,j=()=>{var t,n;const e=(t=o.initialState)==null?void 0:t.sort;if(e&&e.length>0){const A=e[0],L=Object.keys(A)[0],te=(n=A[L])==null?void 0:n.toLowerCase();return{field:L,direction:te}}return{field:null,direction:null}},[s,p]=r.useState(j),[i,u]=r.useState({pageNo:((z=(k=o.initialState)==null?void 0:k.pagination)==null?void 0:z.pageNo)||1,pageSize:((P=(M=o.initialState)==null?void 0:M.pagination)==null?void 0:P.pageSize)||10}),C=re.useFilter({conditions:(O=(Q=o.initialState)==null?void 0:Q.filter)==null?void 0:O.conditions,operator:((w=(R=o.initialState)==null?void 0:R.filter)==null?void 0:w.operator)||"And"}),l=r.useMemo(()=>{const e={};let t=C.payload;if(a.debouncedQuery&&a.field){const n={LHSField:a.field,Operator:"Contains",RHSValue:a.debouncedQuery,RHSType:"Constant"};t?t.Operator==="And"?t={...t,Condition:[...t.Condition||[],n]}:t={Operator:"And",Condition:[t,n]}:t={Operator:"And",Condition:[n]}}return t&&(e.Filter=t),e},[a.debouncedQuery,a.field,C.payload]),N=r.useMemo(()=>{const e={...l};return s.field&&s.direction&&(e.Sort=[{[String(s.field)]:s.direction==="asc"?"ASC":"DESC"}]),e.Page=i.pageNo,e.PageSize=i.pageSize,e},[l,s,i]),{data:d,isLoading:G,isFetching:I,error:T,refetch:E}=x.useQuery({queryKey:["table",o.source,N],queryFn:async()=>{try{const e=await D.api(o.source).list(N);return o.onSuccess&&o.onSuccess(e.Data),e}catch(e){throw o.onError&&o.onError(y.toError(e)),e}},staleTime:0,gcTime:0}),{data:g,isLoading:K,isFetching:_,error:q,refetch:F}=x.useQuery({queryKey:["table-count",o.source,l],queryFn:async()=>{try{return await D.api(o.source).count(l)}catch(e){throw o.onError&&o.onError(y.toError(e)),e}},staleTime:0,gcTime:0}),B=r.useMemo(()=>(d==null?void 0:d.Data)||[],[d]),f=r.useMemo(()=>(g==null?void 0:g.Count)||0,[g]),S=r.useMemo(()=>Math.ceil(f/i.pageSize),[f,i.pageSize]),U=r.useCallback(e=>{p(t=>{if(t.field===e){if(t.direction==="asc")return{field:e,direction:"desc"};if(t.direction==="desc")return{field:null,direction:null}}return{field:e,direction:"asc"}})},[]),V=r.useCallback(()=>{p({field:null,direction:null})},[]),J=r.useCallback((e,t)=>{p({field:e,direction:t})},[]),W=r.useCallback((e,t)=>{if(t.length>255){console.warn("Search query exceeds maximum length of 255 characters");return}h(n=>({...n,query:t,field:e})),c.current&&clearTimeout(c.current),c.current=setTimeout(()=>{h(n=>({...n,debouncedQuery:t})),u(n=>({...n,pageNo:1}))},H)},[]),X=r.useCallback(()=>{c.current&&clearTimeout(c.current),h({query:"",debouncedQuery:"",field:null}),u(e=>({...e,pageNo:1}))},[]);r.useEffect(()=>()=>{c.current&&clearTimeout(c.current)},[]);const b=i.pageNo<S,m=i.pageNo>1,Y=r.useCallback(()=>{b&&u(e=>({...e,pageNo:e.pageNo+1}))},[b]),Z=r.useCallback(()=>{m&&u(e=>({...e,pageNo:e.pageNo-1}))},[m]),$=r.useCallback(e=>{const t=Math.max(1,Math.min(e,S));u(n=>({...n,pageNo:t}))},[S]),v=r.useCallback(e=>{u(t=>({...t,pageSize:e,pageNo:1}))},[]),ee=r.useCallback(async()=>{const[e]=await Promise.all([E(),F()]);return e.data||{Data:[]}},[E,F]);return{rows:B,totalItems:f,isLoading:G||K,isFetching:I||_,error:T?y.toError(T):q?y.toError(q):null,search:{query:a.query,field:a.field,set:W,clear:X},sort:{field:s.field,direction:s.direction,toggle:U,clear:V,set:J},filter:C,pagination:{pageNo:i.pageNo,pageSize:i.pageSize,totalPages:S,totalItems:f,canGoNext:b,canGoPrevious:m,goToNext:Y,goToPrevious:Z,goToPage:$,setPageSize:v},refetch:ee}}exports.useTable=oe;
|
package/dist/table.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState as T, useRef as
|
|
1
|
+
import { useState as T, useRef as ne, useMemo as l, useCallback as n, useEffect as ie } from "react";
|
|
2
2
|
import { useQuery as k } from "@tanstack/react-query";
|
|
3
3
|
import { a as G } from "./client-BIkaIr2y.js";
|
|
4
4
|
import { t as h } from "./error-handling-CrhTtD88.js";
|
|
@@ -9,7 +9,7 @@ function ge(r) {
|
|
|
9
9
|
query: "",
|
|
10
10
|
debouncedQuery: "",
|
|
11
11
|
field: null
|
|
12
|
-
}), c =
|
|
12
|
+
}), c = ne(null), I = 300, K = () => {
|
|
13
13
|
var t, o;
|
|
14
14
|
const e = (t = r.initialState) == null ? void 0 : t.sort;
|
|
15
15
|
if (e && e.length > 0) {
|
|
@@ -17,7 +17,7 @@ function ge(r) {
|
|
|
17
17
|
return { field: H, direction: oe };
|
|
18
18
|
}
|
|
19
19
|
return { field: null, direction: null };
|
|
20
|
-
}, [s, y] = T(K), [
|
|
20
|
+
}, [s, y] = T(K), [i, u] = T({
|
|
21
21
|
pageNo: ((A = (w = r.initialState) == null ? void 0 : w.pagination) == null ? void 0 : A.pageNo) || 1,
|
|
22
22
|
pageSize: ((Q = (O = r.initialState) == null ? void 0 : O.pagination) == null ? void 0 : Q.pageSize) || 10
|
|
23
23
|
}), N = ae({
|
|
@@ -51,8 +51,8 @@ function ge(r) {
|
|
|
51
51
|
{
|
|
52
52
|
[String(s.field)]: s.direction === "asc" ? "ASC" : "DESC"
|
|
53
53
|
}
|
|
54
|
-
]), e.Page =
|
|
55
|
-
}, [d, s,
|
|
54
|
+
]), e.Page = i.pageNo, e.PageSize = i.pageSize, e;
|
|
55
|
+
}, [d, s, i]), {
|
|
56
56
|
data: g,
|
|
57
57
|
isLoading: _,
|
|
58
58
|
isFetching: j,
|
|
@@ -87,7 +87,7 @@ function ge(r) {
|
|
|
87
87
|
},
|
|
88
88
|
staleTime: 0,
|
|
89
89
|
gcTime: 0
|
|
90
|
-
}), V = l(() => (g == null ? void 0 : g.Data) || [], [g]), S = l(() => (f == null ? void 0 : f.Count) || 0, [f]), p = l(() => Math.ceil(S /
|
|
90
|
+
}), V = l(() => (g == null ? void 0 : g.Data) || [], [g]), S = l(() => (f == null ? void 0 : f.Count) || 0, [f]), p = l(() => Math.ceil(S / i.pageSize), [S, i.pageSize]), J = n((e) => {
|
|
91
91
|
y((t) => {
|
|
92
92
|
if (t.field === e) {
|
|
93
93
|
if (t.direction === "asc")
|
|
@@ -97,44 +97,44 @@ function ge(r) {
|
|
|
97
97
|
}
|
|
98
98
|
return { field: e, direction: "asc" };
|
|
99
99
|
});
|
|
100
|
-
}, []), W =
|
|
100
|
+
}, []), W = n(() => {
|
|
101
101
|
y({ field: null, direction: null });
|
|
102
|
-
}, []), X =
|
|
102
|
+
}, []), X = n(
|
|
103
103
|
(e, t) => {
|
|
104
104
|
y({ field: e, direction: t });
|
|
105
105
|
},
|
|
106
106
|
[]
|
|
107
|
-
), Y =
|
|
107
|
+
), Y = n((e, t) => {
|
|
108
108
|
if (t.length > 255) {
|
|
109
109
|
console.warn("Search query exceeds maximum length of 255 characters");
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
-
m((o) => ({ ...o, query: t, field:
|
|
112
|
+
m((o) => ({ ...o, query: t, field: e })), c.current && clearTimeout(c.current), c.current = setTimeout(() => {
|
|
113
113
|
m((o) => ({ ...o, debouncedQuery: t })), u((o) => ({ ...o, pageNo: 1 }));
|
|
114
114
|
}, I);
|
|
115
|
-
}, []), Z =
|
|
115
|
+
}, []), Z = n(() => {
|
|
116
116
|
c.current && clearTimeout(c.current), m({ query: "", debouncedQuery: "", field: null }), u((e) => ({ ...e, pageNo: 1 }));
|
|
117
117
|
}, []);
|
|
118
|
-
|
|
118
|
+
ie(() => () => {
|
|
119
119
|
c.current && clearTimeout(c.current);
|
|
120
120
|
}, []);
|
|
121
|
-
const C =
|
|
121
|
+
const C = i.pageNo < p, b = i.pageNo > 1, $ = n(() => {
|
|
122
122
|
C && u((e) => ({ ...e, pageNo: e.pageNo + 1 }));
|
|
123
|
-
}, [C]), v =
|
|
123
|
+
}, [C]), v = n(() => {
|
|
124
124
|
b && u((e) => ({ ...e, pageNo: e.pageNo - 1 }));
|
|
125
|
-
}, [b]), ee =
|
|
125
|
+
}, [b]), ee = n(
|
|
126
126
|
(e) => {
|
|
127
127
|
const t = Math.max(1, Math.min(e, p));
|
|
128
128
|
u((o) => ({ ...o, pageNo: t }));
|
|
129
129
|
},
|
|
130
130
|
[p]
|
|
131
|
-
), te =
|
|
131
|
+
), te = n((e) => {
|
|
132
132
|
u((t) => ({
|
|
133
133
|
...t,
|
|
134
134
|
pageSize: e,
|
|
135
135
|
pageNo: 1
|
|
136
136
|
}));
|
|
137
|
-
}, []), re =
|
|
137
|
+
}, []), re = n(async () => {
|
|
138
138
|
const [e] = await Promise.all([z(), q()]);
|
|
139
139
|
return e.data || { Data: [] };
|
|
140
140
|
}, [z, q]);
|
|
@@ -166,8 +166,8 @@ function ge(r) {
|
|
|
166
166
|
filter: N,
|
|
167
167
|
// Pagination (Flat Access)
|
|
168
168
|
pagination: {
|
|
169
|
-
pageNo:
|
|
170
|
-
pageSize:
|
|
169
|
+
pageNo: i.pageNo,
|
|
170
|
+
pageSize: i.pageSize,
|
|
171
171
|
totalPages: p,
|
|
172
172
|
totalItems: S,
|
|
173
173
|
canGoNext: C,
|
package/docs/api.md
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# API
|
|
2
2
|
|
|
3
|
+
This Api SDK provides the interface for making any api call to server.
|
|
4
|
+
|
|
3
5
|
Direct API methods for CRUD operations, drafts, metrics, and metadata.
|
|
4
6
|
|
|
7
|
+
You SHOULD only use this Api for making any api call to post and read data.
|
|
8
|
+
|
|
5
9
|
## Setup
|
|
6
10
|
|
|
7
11
|
```typescript
|
package/docs/useAuth.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Auth SDK API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This Auth SDK API provides necessary React-hooks and Components to build the
|
|
4
|
+
authentication and state management with session handling.
|
|
5
|
+
|
|
6
|
+
Here is the example how to use this API:
|
|
4
7
|
|
|
5
8
|
## Imports
|
|
6
9
|
|
package/docs/useFilter.md
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Filter SDK API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This Filter SDK API provides necessary React-hooks and Components to build the
|
|
4
|
+
Filter for using it when making api calls and building form component.
|
|
5
|
+
|
|
6
|
+
Here is the example of Build and manage filter conditions with support for nested groups and complex logic.
|
|
7
|
+
|
|
8
|
+
You SHOULD only use this API to building Table, Form, any other api call with that requires Filter.
|
|
4
9
|
|
|
5
10
|
## Imports
|
|
6
11
|
|
|
7
12
|
```typescript
|
|
8
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
useFilter,
|
|
15
|
+
isCondition,
|
|
16
|
+
isConditionGroup,
|
|
17
|
+
} from "@ram_28/kf-ai-sdk/filter";
|
|
9
18
|
import type {
|
|
10
19
|
UseFilterOptionsType,
|
|
11
20
|
UseFilterReturnType,
|
|
@@ -22,14 +31,22 @@ import type {
|
|
|
22
31
|
```typescript
|
|
23
32
|
// Condition operators
|
|
24
33
|
type ConditionOperatorType =
|
|
25
|
-
| "EQ"
|
|
26
|
-
| "
|
|
27
|
-
| "
|
|
28
|
-
| "
|
|
29
|
-
| "
|
|
30
|
-
| "
|
|
31
|
-
| "
|
|
32
|
-
| "
|
|
34
|
+
| "EQ"
|
|
35
|
+
| "NE" // Equal, Not Equal
|
|
36
|
+
| "GT"
|
|
37
|
+
| "GTE" // Greater Than, Greater Than or Equal
|
|
38
|
+
| "LT"
|
|
39
|
+
| "LTE" // Less Than, Less Than or Equal
|
|
40
|
+
| "Between"
|
|
41
|
+
| "NotBetween"
|
|
42
|
+
| "IN"
|
|
43
|
+
| "NIN" // In List, Not In List
|
|
44
|
+
| "Empty"
|
|
45
|
+
| "NotEmpty"
|
|
46
|
+
| "Contains"
|
|
47
|
+
| "NotContains"
|
|
48
|
+
| "MinLength"
|
|
49
|
+
| "MaxLength";
|
|
33
50
|
|
|
34
51
|
// Group operators
|
|
35
52
|
type ConditionGroupOperatorType = "And" | "Or" | "Not";
|
|
@@ -96,22 +113,36 @@ interface UseFilterReturnType<T = any> {
|
|
|
96
113
|
// ============================================================
|
|
97
114
|
|
|
98
115
|
// Add a condition, optionally to a parent group. Returns the new condition's ID
|
|
99
|
-
addCondition: (
|
|
116
|
+
addCondition: (
|
|
117
|
+
condition: Omit<ConditionType<T>, "id">,
|
|
118
|
+
parentId?: string,
|
|
119
|
+
) => string;
|
|
100
120
|
|
|
101
121
|
// Add a condition group, optionally to a parent group. Returns the new group's ID
|
|
102
|
-
addConditionGroup: (
|
|
122
|
+
addConditionGroup: (
|
|
123
|
+
operator: ConditionGroupOperatorType,
|
|
124
|
+
parentId?: string,
|
|
125
|
+
) => string;
|
|
103
126
|
|
|
104
127
|
// Update a condition's properties (Operator, LHSField, RHSValue)
|
|
105
|
-
updateCondition: (
|
|
128
|
+
updateCondition: (
|
|
129
|
+
id: string,
|
|
130
|
+
updates: Partial<Omit<ConditionType<T>, "id">>,
|
|
131
|
+
) => void;
|
|
106
132
|
|
|
107
133
|
// Change a group's operator (And, Or, Not)
|
|
108
|
-
updateGroupOperator: (
|
|
134
|
+
updateGroupOperator: (
|
|
135
|
+
id: string,
|
|
136
|
+
operator: ConditionGroupOperatorType,
|
|
137
|
+
) => void;
|
|
109
138
|
|
|
110
139
|
// Remove a condition or group by ID
|
|
111
140
|
removeCondition: (id: string) => void;
|
|
112
141
|
|
|
113
142
|
// Get a condition or group by ID
|
|
114
|
-
getCondition: (
|
|
143
|
+
getCondition: (
|
|
144
|
+
id: string,
|
|
145
|
+
) => ConditionType<T> | ConditionGroupType<T> | undefined;
|
|
115
146
|
|
|
116
147
|
// Remove all conditions and groups
|
|
117
148
|
clearAllConditions: () => void;
|
|
@@ -123,15 +154,15 @@ interface UseFilterReturnType<T = any> {
|
|
|
123
154
|
|
|
124
155
|
## Operator Applicability
|
|
125
156
|
|
|
126
|
-
| Operator
|
|
127
|
-
|
|
128
|
-
| EQ, NE
|
|
129
|
-
| GT, GTE, LT, LTE
|
|
130
|
-
| Between, NotBetween
|
|
131
|
-
| IN, NIN
|
|
132
|
-
| Empty, NotEmpty
|
|
133
|
-
| Contains, NotContains | string only
|
|
134
|
-
| MinLength, MaxLength
|
|
157
|
+
| Operator | Applicable Field Types |
|
|
158
|
+
| --------------------- | ---------------------- |
|
|
159
|
+
| EQ, NE | All types |
|
|
160
|
+
| GT, GTE, LT, LTE | number, date, currency |
|
|
161
|
+
| Between, NotBetween | number, date, currency |
|
|
162
|
+
| IN, NIN | All types |
|
|
163
|
+
| Empty, NotEmpty | All types |
|
|
164
|
+
| Contains, NotContains | string only |
|
|
165
|
+
| MinLength, MaxLength | string only |
|
|
135
166
|
|
|
136
167
|
## Basic Example
|
|
137
168
|
|
|
@@ -154,7 +185,10 @@ function SimpleFilter() {
|
|
|
154
185
|
return (
|
|
155
186
|
<div>
|
|
156
187
|
<button onClick={addCategoryFilter}>Filter by Electronics</button>
|
|
157
|
-
<button
|
|
188
|
+
<button
|
|
189
|
+
onClick={filter.clearAllConditions}
|
|
190
|
+
disabled={!filter.hasConditions}
|
|
191
|
+
>
|
|
158
192
|
Clear
|
|
159
193
|
</button>
|
|
160
194
|
<p>Active filters: {filter.items.length}</p>
|
|
@@ -186,7 +220,7 @@ function TypeSafeFilter() {
|
|
|
186
220
|
const addCategoryFilter = () => {
|
|
187
221
|
filter.addCondition({
|
|
188
222
|
Operator: "EQ",
|
|
189
|
-
LHSField: "Category",
|
|
223
|
+
LHSField: "Category", // TypeScript validates this field exists
|
|
190
224
|
RHSValue: "Electronics",
|
|
191
225
|
});
|
|
192
226
|
};
|
|
@@ -194,7 +228,7 @@ function TypeSafeFilter() {
|
|
|
194
228
|
const addInvalidFilter = () => {
|
|
195
229
|
filter.addCondition({
|
|
196
230
|
Operator: "EQ",
|
|
197
|
-
LHSField: "InvalidField",
|
|
231
|
+
LHSField: "InvalidField", // TypeScript error: not a key of BuyerProduct
|
|
198
232
|
RHSValue: "test",
|
|
199
233
|
});
|
|
200
234
|
};
|
|
@@ -210,6 +244,7 @@ function TypeSafeFilter() {
|
|
|
210
244
|
### UseFilterOptionsType for Initial State
|
|
211
245
|
|
|
212
246
|
`UseFilterOptionsType<T>` is used for:
|
|
247
|
+
|
|
213
248
|
- Initializing `useFilter` directly
|
|
214
249
|
- Setting `initialState.filter` in `useTable`
|
|
215
250
|
- Setting `initialState.filter` in `useKanban`
|
|
@@ -269,7 +304,9 @@ function EqualityFilters() {
|
|
|
269
304
|
return (
|
|
270
305
|
<div>
|
|
271
306
|
<button onClick={() => filterByStatus("Active")}>Active Only</button>
|
|
272
|
-
<button onClick={() => excludeStatus("Archived")}>
|
|
307
|
+
<button onClick={() => excludeStatus("Archived")}>
|
|
308
|
+
Exclude Archived
|
|
309
|
+
</button>
|
|
273
310
|
</div>
|
|
274
311
|
);
|
|
275
312
|
}
|
|
@@ -359,7 +396,9 @@ function RangeFilters() {
|
|
|
359
396
|
return (
|
|
360
397
|
<div>
|
|
361
398
|
<button onClick={() => filterPriceRange(50, 200)}>$50 - $200</button>
|
|
362
|
-
<button onClick={() => excludePriceRange(0, 10)}>
|
|
399
|
+
<button onClick={() => excludePriceRange(0, 10)}>
|
|
400
|
+
Exclude Under $10
|
|
401
|
+
</button>
|
|
363
402
|
</div>
|
|
364
403
|
);
|
|
365
404
|
}
|
|
@@ -517,9 +556,7 @@ function AndFilter() {
|
|
|
517
556
|
|
|
518
557
|
return (
|
|
519
558
|
<div>
|
|
520
|
-
<button onClick={applyFilters}>
|
|
521
|
-
Electronics under $500, In Stock
|
|
522
|
-
</button>
|
|
559
|
+
<button onClick={applyFilters}>Electronics under $500, In Stock</button>
|
|
523
560
|
<p>Root operator: {filter.operator}</p>
|
|
524
561
|
</div>
|
|
525
562
|
);
|
|
@@ -552,9 +589,7 @@ function OrFilter() {
|
|
|
552
589
|
});
|
|
553
590
|
};
|
|
554
591
|
|
|
555
|
-
return
|
|
556
|
-
<button onClick={applyFilters}>Urgent Tasks</button>
|
|
557
|
-
);
|
|
592
|
+
return <button onClick={applyFilters}>Urgent Tasks</button>;
|
|
558
593
|
}
|
|
559
594
|
```
|
|
560
595
|
|
|
@@ -583,24 +618,26 @@ function NestedFilter() {
|
|
|
583
618
|
const orGroupId = filter.addConditionGroup("Or");
|
|
584
619
|
|
|
585
620
|
// Add conditions to the OR group
|
|
586
|
-
filter.addCondition(
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
621
|
+
filter.addCondition(
|
|
622
|
+
{
|
|
623
|
+
Operator: "LT",
|
|
624
|
+
LHSField: "Price",
|
|
625
|
+
RHSValue: 100,
|
|
626
|
+
},
|
|
627
|
+
orGroupId,
|
|
628
|
+
);
|
|
629
|
+
|
|
630
|
+
filter.addCondition(
|
|
631
|
+
{
|
|
632
|
+
Operator: "EQ",
|
|
633
|
+
LHSField: "OnSale",
|
|
634
|
+
RHSValue: true,
|
|
635
|
+
},
|
|
636
|
+
orGroupId,
|
|
637
|
+
);
|
|
597
638
|
};
|
|
598
639
|
|
|
599
|
-
return
|
|
600
|
-
<button onClick={applyComplexFilter}>
|
|
601
|
-
Affordable Electronics
|
|
602
|
-
</button>
|
|
603
|
-
);
|
|
640
|
+
return <button onClick={applyComplexFilter}>Affordable Electronics</button>;
|
|
604
641
|
}
|
|
605
642
|
```
|
|
606
643
|
|
|
@@ -619,13 +656,25 @@ function DeepNestedFilter() {
|
|
|
619
656
|
|
|
620
657
|
// First AND group
|
|
621
658
|
const group1 = filter.addConditionGroup("And");
|
|
622
|
-
filter.addCondition(
|
|
623
|
-
|
|
659
|
+
filter.addCondition(
|
|
660
|
+
{ Operator: "EQ", LHSField: "Type", RHSValue: "A" },
|
|
661
|
+
group1,
|
|
662
|
+
);
|
|
663
|
+
filter.addCondition(
|
|
664
|
+
{ Operator: "GT", LHSField: "Value", RHSValue: 10 },
|
|
665
|
+
group1,
|
|
666
|
+
);
|
|
624
667
|
|
|
625
668
|
// Second AND group
|
|
626
669
|
const group2 = filter.addConditionGroup("And");
|
|
627
|
-
filter.addCondition(
|
|
628
|
-
|
|
670
|
+
filter.addCondition(
|
|
671
|
+
{ Operator: "EQ", LHSField: "Type", RHSValue: "B" },
|
|
672
|
+
group2,
|
|
673
|
+
);
|
|
674
|
+
filter.addCondition(
|
|
675
|
+
{ Operator: "LT", LHSField: "Value", RHSValue: 5 },
|
|
676
|
+
group2,
|
|
677
|
+
);
|
|
629
678
|
};
|
|
630
679
|
|
|
631
680
|
return <button onClick={buildFilter}>Apply Complex Filter</button>;
|
|
@@ -760,7 +809,11 @@ function EditableFilter() {
|
|
|
760
809
|
<button onClick={addFilter}>Add Price Filter</button>
|
|
761
810
|
{conditionId && (
|
|
762
811
|
<div>
|
|
763
|
-
<select
|
|
812
|
+
<select
|
|
813
|
+
onChange={(e) =>
|
|
814
|
+
updateOperator(e.target.value as ConditionOperatorType)
|
|
815
|
+
}
|
|
816
|
+
>
|
|
764
817
|
<option value="GT">Greater Than</option>
|
|
765
818
|
<option value="LT">Less Than</option>
|
|
766
819
|
<option value="EQ">Equals</option>
|
|
@@ -804,9 +857,7 @@ function ToggleableGroupOperator() {
|
|
|
804
857
|
return (
|
|
805
858
|
<div>
|
|
806
859
|
<button onClick={createGroup}>Create Group</button>
|
|
807
|
-
{groupId &&
|
|
808
|
-
<button onClick={toggleOperator}>Toggle AND/OR</button>
|
|
809
|
-
)}
|
|
860
|
+
{groupId && <button onClick={toggleOperator}>Toggle AND/OR</button>}
|
|
810
861
|
</div>
|
|
811
862
|
);
|
|
812
863
|
}
|
|
@@ -844,11 +895,15 @@ function FilterWithApi() {
|
|
|
844
895
|
|
|
845
896
|
return (
|
|
846
897
|
<div>
|
|
847
|
-
<button
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
898
|
+
<button
|
|
899
|
+
onClick={() =>
|
|
900
|
+
filter.addCondition({
|
|
901
|
+
Operator: "EQ",
|
|
902
|
+
LHSField: "Status",
|
|
903
|
+
RHSValue: "Active",
|
|
904
|
+
})
|
|
905
|
+
}
|
|
906
|
+
>
|
|
852
907
|
Add Filter
|
|
853
908
|
</button>
|
|
854
909
|
<button onClick={fetchFiltered}>Fetch Data</button>
|
|
@@ -919,7 +974,11 @@ Produces:
|
|
|
919
974
|
### Multiple Conditions (AND)
|
|
920
975
|
|
|
921
976
|
```tsx
|
|
922
|
-
filter.addCondition({
|
|
977
|
+
filter.addCondition({
|
|
978
|
+
Operator: "EQ",
|
|
979
|
+
LHSField: "Category",
|
|
980
|
+
RHSValue: "Electronics",
|
|
981
|
+
});
|
|
923
982
|
filter.addCondition({ Operator: "GT", LHSField: "Price", RHSValue: 100 });
|
|
924
983
|
filter.addCondition({ Operator: "LTE", LHSField: "Stock", RHSValue: 50 });
|
|
925
984
|
```
|
|
@@ -930,9 +989,24 @@ Produces:
|
|
|
930
989
|
{
|
|
931
990
|
"Operator": "And",
|
|
932
991
|
"Condition": [
|
|
933
|
-
{
|
|
934
|
-
|
|
935
|
-
|
|
992
|
+
{
|
|
993
|
+
"Operator": "EQ",
|
|
994
|
+
"LHSField": "Category",
|
|
995
|
+
"RHSValue": "Electronics",
|
|
996
|
+
"RHSType": "Constant"
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
"Operator": "GT",
|
|
1000
|
+
"LHSField": "Price",
|
|
1001
|
+
"RHSValue": 100,
|
|
1002
|
+
"RHSType": "Constant"
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
"Operator": "LTE",
|
|
1006
|
+
"LHSField": "Stock",
|
|
1007
|
+
"RHSValue": 50,
|
|
1008
|
+
"RHSType": "Constant"
|
|
1009
|
+
}
|
|
936
1010
|
]
|
|
937
1011
|
}
|
|
938
1012
|
```
|
|
@@ -942,10 +1016,20 @@ Produces:
|
|
|
942
1016
|
```tsx
|
|
943
1017
|
// Root: AND
|
|
944
1018
|
// Category = "Electronics" AND (Price < 100 OR OnSale = true)
|
|
945
|
-
filter.addCondition({
|
|
1019
|
+
filter.addCondition({
|
|
1020
|
+
Operator: "EQ",
|
|
1021
|
+
LHSField: "Category",
|
|
1022
|
+
RHSValue: "Electronics",
|
|
1023
|
+
});
|
|
946
1024
|
const orGroupId = filter.addConditionGroup("Or");
|
|
947
|
-
filter.addCondition(
|
|
948
|
-
|
|
1025
|
+
filter.addCondition(
|
|
1026
|
+
{ Operator: "LT", LHSField: "Price", RHSValue: 100 },
|
|
1027
|
+
orGroupId,
|
|
1028
|
+
);
|
|
1029
|
+
filter.addCondition(
|
|
1030
|
+
{ Operator: "EQ", LHSField: "OnSale", RHSValue: true },
|
|
1031
|
+
orGroupId,
|
|
1032
|
+
);
|
|
949
1033
|
```
|
|
950
1034
|
|
|
951
1035
|
Produces:
|
|
@@ -954,12 +1038,27 @@ Produces:
|
|
|
954
1038
|
{
|
|
955
1039
|
"Operator": "And",
|
|
956
1040
|
"Condition": [
|
|
957
|
-
{
|
|
1041
|
+
{
|
|
1042
|
+
"Operator": "EQ",
|
|
1043
|
+
"LHSField": "Category",
|
|
1044
|
+
"RHSValue": "Electronics",
|
|
1045
|
+
"RHSType": "Constant"
|
|
1046
|
+
},
|
|
958
1047
|
{
|
|
959
1048
|
"Operator": "Or",
|
|
960
1049
|
"Condition": [
|
|
961
|
-
{
|
|
962
|
-
|
|
1050
|
+
{
|
|
1051
|
+
"Operator": "LT",
|
|
1052
|
+
"LHSField": "Price",
|
|
1053
|
+
"RHSValue": 100,
|
|
1054
|
+
"RHSType": "Constant"
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
"Operator": "EQ",
|
|
1058
|
+
"LHSField": "OnSale",
|
|
1059
|
+
"RHSValue": true,
|
|
1060
|
+
"RHSType": "Constant"
|
|
1061
|
+
}
|
|
963
1062
|
]
|
|
964
1063
|
}
|
|
965
1064
|
]
|
|
@@ -982,7 +1081,12 @@ Produces:
|
|
|
982
1081
|
{
|
|
983
1082
|
"Operator": "And",
|
|
984
1083
|
"Condition": [
|
|
985
|
-
{
|
|
1084
|
+
{
|
|
1085
|
+
"Operator": "Between",
|
|
1086
|
+
"LHSField": "Price",
|
|
1087
|
+
"RHSValue": [50, 200],
|
|
1088
|
+
"RHSType": "Constant"
|
|
1089
|
+
}
|
|
986
1090
|
]
|
|
987
1091
|
}
|
|
988
1092
|
```
|
|
@@ -1003,7 +1107,12 @@ Produces:
|
|
|
1003
1107
|
{
|
|
1004
1108
|
"Operator": "And",
|
|
1005
1109
|
"Condition": [
|
|
1006
|
-
{
|
|
1110
|
+
{
|
|
1111
|
+
"Operator": "IN",
|
|
1112
|
+
"LHSField": "Category",
|
|
1113
|
+
"RHSValue": ["Electronics", "Computers", "Accessories"],
|
|
1114
|
+
"RHSType": "Constant"
|
|
1115
|
+
}
|
|
1007
1116
|
]
|
|
1008
1117
|
}
|
|
1009
1118
|
```
|
package/docs/useForm.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Form SDK API
|
|
2
2
|
|
|
3
|
-
Form
|
|
3
|
+
This Form SDK API proivdes the React-hooks and apis to build Form component when building the Pages.
|
|
4
|
+
Here is the example of building Form Component with Form state management with schema validation, computed fields.
|
|
5
|
+
|
|
6
|
+
You SHOULD only use this API to build Form component
|
|
4
7
|
|
|
5
8
|
## Imports
|
|
6
9
|
|
|
@@ -533,10 +536,7 @@ function ProductCategoryForm({ recordId }: { recordId: string }) {
|
|
|
533
536
|
<form onSubmit={form.handleSubmit()}>
|
|
534
537
|
<div>
|
|
535
538
|
<label>Category</label>
|
|
536
|
-
<select
|
|
537
|
-
{...form.register("Category")}
|
|
538
|
-
onFocus={handleDropdownOpen}
|
|
539
|
-
>
|
|
539
|
+
<select {...form.register("Category")} onFocus={handleDropdownOpen}>
|
|
540
540
|
<option value="">Select category</option>
|
|
541
541
|
{loadingOptions ? (
|
|
542
542
|
<option disabled>Loading...</option>
|
|
@@ -578,7 +578,8 @@ type SupplierOption = {
|
|
|
578
578
|
function ProductSupplierForm({ recordId }: { recordId: string }) {
|
|
579
579
|
const product = new Product(Roles.Buyer);
|
|
580
580
|
const [supplierOptions, setSupplierOptions] = useState<SupplierOption[]>([]);
|
|
581
|
-
const [selectedSupplier, setSelectedSupplier] =
|
|
581
|
+
const [selectedSupplier, setSelectedSupplier] =
|
|
582
|
+
useState<SupplierOption | null>(null);
|
|
582
583
|
const [isOpen, setIsOpen] = useState(false);
|
|
583
584
|
const [loadingOptions, setLoadingOptions] = useState(false);
|
|
584
585
|
|
|
@@ -607,7 +608,10 @@ function ProductSupplierForm({ recordId }: { recordId: string }) {
|
|
|
607
608
|
|
|
608
609
|
const handleSelect = (supplier: SupplierOption) => {
|
|
609
610
|
setSelectedSupplier(supplier);
|
|
610
|
-
form.setValue("SupplierInfo", {
|
|
611
|
+
form.setValue("SupplierInfo", {
|
|
612
|
+
_id: supplier._id,
|
|
613
|
+
SupplierName: supplier.SupplierName,
|
|
614
|
+
});
|
|
611
615
|
setIsOpen(false);
|
|
612
616
|
};
|
|
613
617
|
|
|
@@ -637,7 +641,8 @@ function ProductSupplierForm({ recordId }: { recordId: string }) {
|
|
|
637
641
|
>
|
|
638
642
|
<span className="supplier-name">{supplier.SupplierName}</span>
|
|
639
643
|
<span className="supplier-rating">
|
|
640
|
-
{"★".repeat(supplier.Rating)}
|
|
644
|
+
{"★".repeat(supplier.Rating)}
|
|
645
|
+
{"☆".repeat(5 - supplier.Rating)}
|
|
641
646
|
</span>
|
|
642
647
|
</div>
|
|
643
648
|
))
|
package/docs/useTable.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Table SDK API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This Table SDK API proivdes the React-hooks and apis to build Table and any List like component when building the Pages.
|
|
4
|
+
|
|
5
|
+
Here is the complete exmaple of building table with state management with data fetching, sorting, filtering, search, and pagination.
|
|
6
|
+
|
|
7
|
+
You SHOULD only use this API to build Table, List, Galllary, any other list like component.
|
|
4
8
|
|
|
5
9
|
## Imports
|
|
6
10
|
|
|
@@ -119,11 +123,11 @@ interface UseTableReturnType<T> {
|
|
|
119
123
|
query: string;
|
|
120
124
|
|
|
121
125
|
// Field being searched, null if no search active
|
|
122
|
-
field:
|
|
126
|
+
field: keyof T | null;
|
|
123
127
|
|
|
124
128
|
// Set search field and query (triggers API call, 300ms debounced)
|
|
125
129
|
// Internally creates a Contains filter condition
|
|
126
|
-
set: (field: keyof T
|
|
130
|
+
set: (field: keyof T, query: string) => void;
|
|
127
131
|
|
|
128
132
|
// Clear search and reset to empty string (triggers API call)
|
|
129
133
|
clear: () => void;
|
|
@@ -821,7 +825,7 @@ Search by field with filter-based implementation. The search internally creates
|
|
|
821
825
|
### API
|
|
822
826
|
|
|
823
827
|
- `search.query: string` - Current search query string
|
|
824
|
-
- `search.field:
|
|
828
|
+
- `search.field: keyof T | null` - Field being searched
|
|
825
829
|
- `search.set(field, query)` - Set search field and query (triggers API call, 300ms debounced)
|
|
826
830
|
- `search.clear()` - Clear search (triggers API call)
|
|
827
831
|
|
|
@@ -1078,4 +1082,3 @@ function ProductListPage() {
|
|
|
1078
1082
|
);
|
|
1079
1083
|
}
|
|
1080
1084
|
```
|
|
1081
|
-
|
package/package.json
CHANGED
|
@@ -57,8 +57,8 @@ export interface UseTableReturnType<T> {
|
|
|
57
57
|
// Search (Flat Access)
|
|
58
58
|
search: {
|
|
59
59
|
query: string;
|
|
60
|
-
field:
|
|
61
|
-
set: (field: keyof T
|
|
60
|
+
field: keyof T | null;
|
|
61
|
+
set: (field: keyof T, query: string) => void;
|
|
62
62
|
clear: () => void;
|
|
63
63
|
};
|
|
64
64
|
|
|
@@ -82,17 +82,18 @@ const table = useTable<ProductType>({
|
|
|
82
82
|
| Property | Type | Description |
|
|
83
83
|
|----------|------|-------------|
|
|
84
84
|
| `search.query` | `string` | Current search query |
|
|
85
|
-
| `search.
|
|
86
|
-
| `search.
|
|
85
|
+
| `search.field` | `keyof T \| null` | Field being searched |
|
|
86
|
+
| `search.set` | `(field: keyof T, query: string) => void` | Set search field and query (triggers API call, 300ms debounced) |
|
|
87
|
+
| `search.clear` | `() => void` | Clear search (triggers API call) |
|
|
87
88
|
|
|
88
89
|
#### Sorting
|
|
89
90
|
| Property | Type | Description |
|
|
90
91
|
|----------|------|-------------|
|
|
91
92
|
| `sort.field` | `keyof T \| null` | Current sort field |
|
|
92
93
|
| `sort.direction` | `"asc" \| "desc" \| null` | Current sort direction |
|
|
93
|
-
| `sort.toggle` | `(field: keyof T) => void` | Toggle sort (cycles: asc -> desc -> none) |
|
|
94
|
-
| `sort.clear` | `() => void` | Clear sorting |
|
|
95
|
-
| `sort.set` | `(field: keyof T, direction: "asc" \| "desc") => void` | Set specific sort |
|
|
94
|
+
| `sort.toggle` | `(field: keyof T) => void` | Toggle sort (triggers API call, cycles: asc -> desc -> none) |
|
|
95
|
+
| `sort.clear` | `() => void` | Clear sorting (triggers API call) |
|
|
96
|
+
| `sort.set` | `(field: keyof T, direction: "asc" \| "desc") => void` | Set specific sort (triggers API call) |
|
|
96
97
|
|
|
97
98
|
#### Filtering (Advanced)
|
|
98
99
|
| Property | Type | Description |
|
|
@@ -177,10 +178,10 @@ const table = useTable<SellerProduct>({
|
|
|
177
178
|
},
|
|
178
179
|
});
|
|
179
180
|
|
|
180
|
-
// Search
|
|
181
|
+
// Search by Title field
|
|
181
182
|
<Input
|
|
182
183
|
value={table.search.query}
|
|
183
|
-
onChange={(e) => table.search.
|
|
184
|
+
onChange={(e) => table.search.set("Title", e.target.value)}
|
|
184
185
|
/>
|
|
185
186
|
|
|
186
187
|
// Display rows
|
|
@@ -10,10 +10,10 @@ import type { UseTableOptionsType, UseTableReturnType } from "./types";
|
|
|
10
10
|
// INTERNAL STATE TYPES
|
|
11
11
|
// ============================================================
|
|
12
12
|
|
|
13
|
-
interface SearchState {
|
|
13
|
+
interface SearchState<T> {
|
|
14
14
|
query: string; // Immediate UI value
|
|
15
15
|
debouncedQuery: string; // Debounced value for API queries
|
|
16
|
-
field:
|
|
16
|
+
field: keyof T | null; // Field being searched
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
interface SortingState<T> {
|
|
@@ -37,7 +37,7 @@ export function useTable<T = any>(
|
|
|
37
37
|
// STATE MANAGEMENT
|
|
38
38
|
// ============================================================
|
|
39
39
|
|
|
40
|
-
const [search, setSearch] = useState<SearchState
|
|
40
|
+
const [search, setSearch] = useState<SearchState<T>>({
|
|
41
41
|
query: "",
|
|
42
42
|
debouncedQuery: "",
|
|
43
43
|
field: null,
|
|
@@ -242,7 +242,7 @@ export function useTable<T = any>(
|
|
|
242
242
|
// SEARCH OPERATIONS
|
|
243
243
|
// ============================================================
|
|
244
244
|
|
|
245
|
-
const setSearchFieldAndQuery = useCallback((field: keyof T
|
|
245
|
+
const setSearchFieldAndQuery = useCallback((field: keyof T, query: string) => {
|
|
246
246
|
// Validate search query length to prevent DoS
|
|
247
247
|
if (query.length > 255) {
|
|
248
248
|
console.warn("Search query exceeds maximum length of 255 characters");
|
|
@@ -250,7 +250,7 @@ export function useTable<T = any>(
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
// Update immediate value for UI
|
|
253
|
-
setSearch((prev) => ({ ...prev, query, field
|
|
253
|
+
setSearch((prev) => ({ ...prev, query, field }));
|
|
254
254
|
|
|
255
255
|
// Clear existing debounce timeout
|
|
256
256
|
if (searchDebounceRef.current) {
|