@@ -5,31 +5,38 @@ DataUtil.serverTimezoneOffset = 0;
55
66const resolvers = {
77 Query : {
8- // Main query used by the grid (supports paging, sorting, filtering, searching)
8+ /* Main query used by the grid (supports paging, sorting, filtering, searching. */
99 getProducts : ( parent , { datamanager } , context , info ) => {
1010 console . log ( 'getProducts called with:' , datamanager ) ;
1111
1212 let orders = [ ...productDetails ] ;
1313 const query = new Query ( ) ;
14- // 1. Filtering
14+ /*------------------------ 1. Filtering-----------------------------------*/
1515 const performFiltering = ( filterString ) => {
1616 const parsed = JSON . parse ( filterString ) ;
1717
18- // Some filter UIs send an array of predicates; commonly you want the first group
19- // Adjust this if your payload is different
18+ /**
19+ * The parsed filter can be an array or a single object.
20+ * We normalize it here so we always work on the first element.
21+ */
2022 const predicateCollection = Array . isArray ( parsed ) ? parsed [ 0 ] : parsed ;
2123
22- // Guard
24+ /* If no valid predicate structure exists, return the original query unchanged. */
2325 if ( ! predicateCollection || ! Array . isArray ( predicateCollection . predicates ) || predicateCollection . predicates . length === 0 ) {
2426 return query ; // nothing to apply
2527 }
2628
29+ /* Determines whether multiple predicates should be combined using AND / OR. */
2730 const condition = ( predicateCollection . condition || 'and' ) . toLowerCase ( ) ; // 'and' | 'or'
2831 const ignoreCase = predicateCollection . ignoreCase !== undefined ? ! ! predicateCollection . ignoreCase : true ;
2932
30- // Build a combined Predicate chain
33+ /*This variable will accumulate the full predicate chain*/
3134 let combined = null ;
3235
36+ /**
37+ * Loop through each predicate and convert it into Syncfusion Predicate objects.
38+ * Supports nested (complex) filter groups through recursive processing.
39+ */
3340 predicateCollection . predicates . forEach ( p => {
3441 // If the format nests predicateCollections, handle recursively
3542 if ( p . isComplex && Array . isArray ( p . predicates ) ) {
@@ -50,20 +57,34 @@ const resolvers = {
5057 : pred ;
5158 } ) ;
5259
53- // Clear previous where clauses if needed (optional depending on your lifecycle)
54- // query.queries = query.queries.filter(q => q.fn !== 'where');
55-
60+ /* Apply the final combined predicate to the Syncfusion Query object. */
5661 if ( combined ) {
5762 query . where ( combined ) ;
5863 }
5964
6065 return query ;
6166 } ;
62- // Helper for nested predicates
67+
68+ /**
69+ * Builds a nested Predicate structure from complex filter conditions.
70+ * This function is called recursively to handle multi-level filter logic.
71+ * (e.g., AND/OR combinations inside other AND/OR blocks).
72+ *
73+ * @param block - A complex filter object containing nested predicates.
74+ * @param ignoreCase - Whether string comparisons should ignore case.
75+ * @returns A merged Predicate representing the entire nested filter block.
76+ */
6377 function buildNestedPredicate ( block , ignoreCase ) {
78+ /* Determine whether this block uses "and" or "or" to merge its child predicates.*/
6479 const condition = ( block . condition || 'and' ) . toLowerCase ( ) ;
80+
81+ /* Will store the final combined Predicate after processing all nested items. */
6582 let mergedPredicate = null ;
6683
84+ /**
85+ * Loop through each predicate entry within the current block.
86+ * Each entry can be a simple predicate or another nested (complex) block.
87+ */
6788 block . predicates . forEach ( p => {
6889 let node ;
6990 if ( p . isComplex && Array . isArray ( p . predicates ) ) {
@@ -81,20 +102,21 @@ const resolvers = {
81102 return mergedPredicate ;
82103 }
83104
84- // 2. Searching (uncomment when you want to support grid search)
105+ /*----------- 2. Searching------------------------------------*/
85106 const performSearching = ( searchParam ) => {
86107 const { fields, key } = JSON . parse ( searchParam ) [ 0 ] ;
87108 query . search ( key , fields ) ;
88109 }
89- // 3. Sorting
110+
111+ /*-----------------3. Sorting-----------------------------------*/
90112 const performSorting = ( sorted ) => {
91113 for ( let i = 0 ; i < sorted . length ; i ++ ) {
92114 const { name, direction } = sorted [ i ] ;
93115 query . sortBy ( name , direction ) ;
94116 }
95117 }
96118
97- // Apply all operations
119+ /* Apply all operations */
98120 if ( datamanager . where ) {
99121 performFiltering ( datamanager . where ) ;
100122 }
@@ -105,13 +127,13 @@ const resolvers = {
105127 performSorting ( datamanager . sorted ) ;
106128 }
107129
108- // Execute filtering/sorting/search first
130+ /* Execute filtering/sorting/search first. */
109131 const filteredData = new DataManager ( orders ) . executeLocal ( query ) ;
110132
111- // Total count after filtering
133+ /* Total count after filtering */
112134 const count = filteredData . length ;
113135
114- // 4. Paging
136+ /*-------------------- 4. Paging----------------------------------*/
115137 let result = filteredData ;
116138
117139 if ( datamanager . take !== undefined ) {
@@ -128,6 +150,7 @@ const resolvers = {
128150 } ;
129151 } ,
130152
153+ /* Query to get a single product by ID. */
131154 getProductById : ( parent , { datamanager } ) => {
132155 console . log ( 'getProductById called with datamanager:' , datamanager ) ;
133156
@@ -150,18 +173,51 @@ const resolvers = {
150173 } ,
151174
152175 Mutation : {
176+ /**
177+ * Create a new product.
178+ *
179+ * @param _parent - Unused, kept for GraphQL resolver signature consistency.
180+ * @param args - Arguments containing the `value` payload for the new product.
181+ * @returns The newly created product object.
182+ */
153183 createProduct : ( parent , { value } , context , info ) => {
154184 productDetails . push ( value ) ;
155185 return value ;
156186 } ,
187+
188+ /**
189+ * Update an existing product by key.
190+ * @param args - Arguments containing `key`, optional `keyColumn`, and `value` (partial update).
191+ * @returns The updated product object.
192+ *
193+ * Behavior:
194+ * - Defaults `keyColumn` to "productId" if not provided.
195+ * - Finds the product using the provided key + keyColumn.
196+ * - Performs a shallow merge (Object.assign) to update fields.
197+ *
198+ * Caution:
199+ * - `Object.assign` mutates the found object. If immutability is required,
200+ * consider replacing the item in the array with a new object instead.
201+ */
202+
157203 updateProduct : ( parent , { key, keyColumn, value } , context , info ) => {
158204 const product = productDetails . find ( p => p . productId === key ) ;
159205 if ( ! product ) throw new Error ( "Product not found" ) ;
160206
161207 Object . assign ( product , value ) ;
162208 return product ;
163209 } ,
164-
210+
211+ /**
212+ * Delete an existing product by key.
213+ * @param args - Arguments containing `key` and optional `keyColumn`.
214+ * @returns The deleted product object (commonly useful for confirmations/audits).
215+ *
216+ * Behavior:
217+ * - Finds the index of the matching product.
218+ * - Removes it from the in-memory array using `splice`.
219+ * - Returns the removed entity.
220+ */
165221 deleteProduct : ( parent , { key, keyColumn = 'productId' } , context , info ) => {
166222 const idx = productDetails . findIndex ( p => String ( p [ keyColumn ] ) === String ( key ) ) ;
167223 if ( idx === - 1 ) throw new Error ( 'Product not found' ) ;
0 commit comments