[{"id":"f322fea7-4ca5-4b5d-86c1-001912c850b2","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"f7bf5f33-288c-4893-b444-055be654e93a","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"4244ec5a-a6a9-42fc-9651-072233db3cf0","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"53155f14-d53e-4d53-a087-0a32d9b088e8","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"d5b83782-724a-4dcd-a518-0ae69944e387","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"7c54099b-4e27-4e88-91eb-0c637639e54d","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"20765fbe-aa2d-45e9-b63f-0efcc5225c16","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"17f5bd45-99ce-43d5-b68e-0f5049943703","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"8c11df37-0484-40c2-a9b4-103ead6c8314","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"1c4f2565-d1d8-4ad5-89d3-1980a756bab0","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"cccfd524-1150-4583-98f4-1c78277fb19b","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"18b5ea90-6de5-4399-90d1-2238cfb3382e","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"dac211bb-2f29-4663-8bb3-2359b67c5dc3","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"0d811d5c-d17f-4262-96ef-272da4fee248","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"83e0bc87-eb53-4a6c-a354-28ec6433cc9f","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"f3aca57e-9e1e-4242-a235-31898017ee25","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"af280636-785f-4b45-8c31-3433882a446a","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"6308caea-fbe5-4424-b9af-34c24356e951","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"6433ad22-3173-436a-8ff9-355a17142bc5","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"49c3c113-8550-43de-a6c8-35829e88e5e6","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"18eede08-b743-418d-94db-37c2af1dbc30","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"decb7443-11fe-4aa0-8b93-3c200275616a","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"6d98d12d-125b-4741-b4a5-3db1a0f2e301","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"5b251a9f-5a3b-4a44-8408-3fdcf02f3d90","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"e9c38f09-cfd3-4a78-b2cf-412e3c1b5945","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"1e5d6f9f-050e-4b0c-a881-41dd5951c7e5","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"9922f417-b683-48c6-bad6-439c91ebf668","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c907e410-0d04-4906-ac6f-452336e8d44f","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"e36475b1-32f5-4b0b-a33b-47e34aa1a708","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"37f2c3b0-6b80-4da3-9d06-481bb204a2b1","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"5f15dcdb-9002-46de-9423-4d87ce9e8cb9","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c126327a-cafc-49a4-8d18-4daaa1e9b2b0","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"6f091bb9-87ea-4ff0-9b1b-4f280c1d96c1","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"4ef5fa73-b193-400b-942e-51646095e0f5","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"6eed225d-831a-4ad0-ace7-52c306719b0e","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"3a5cd23f-8c36-47a0-ba1f-565c13d9dc41","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"3e527c36-c9a3-4850-bd83-578097ae97f4","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"2a064357-436f-48b6-9d47-57fafa83ca83","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"f28d747e-a0a9-4967-9940-581cdf4e6a07","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"28d36d47-c582-4210-a848-5ba48491bb80","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"bd4ffbde-fb59-44f0-8166-5de0e2f8dcb3","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"538ebc70-b737-4e61-a1a5-5f33e41367f6","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"7fc447a7-c879-424d-832b-603f956c3cb3","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"2e3972d0-8608-4a5c-920d-66734b85033c","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c916ab18-d86f-45ce-b2ac-6aa47581a625","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"40a13a36-7246-4f8b-8ccc-6b5d494fc344","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"13811256-dbe9-48a8-88b9-6ec49b2467ac","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"4d4adcc8-433a-4969-9daa-732be28b5d0d","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c3f78991-8a84-451e-8704-7414c1318b9e","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"664d4485-f5e8-49e4-9766-748abe7aeac2","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"3a548f28-610d-42d6-8602-7d982025750f","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"754efafe-744e-452e-9e46-833c9b36c763","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"59774e97-ff52-425e-8b41-8657dcb115ef","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"d5f1de25-5097-46ca-8e8c-881e41679af8","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"71cfa296-3ff8-4259-acc9-8d89d0268c3f","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"de1c695a-c31f-4884-8215-8eeb468cb36d","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"81fc1b9e-a9e4-41f6-be4f-9043eaa82970","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"8d952ce2-b977-4976-b8cb-91999367d807","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"e742bb05-9f35-412d-bac5-91f0094a7c44","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"bbbef556-1bcd-4fe9-8bd2-93593b315e0b","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"d3e0049c-437f-4361-b452-97464367f2ca","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"7d2857c8-1f21-4806-ae86-9a33ebef97c5","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"b26b60af-f0f9-4dc7-baba-9cb816e469df","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"7ccb20b2-7e36-4fe8-9c24-9fecc761cc4e","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"b3c7e8d4-8fd1-4c1f-891d-a01f59233ac7","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"9f59a948-51e5-4973-a1f2-a2317e6558b0","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"fd091a7c-6bb2-40d3-b471-a26eec95cf9e","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"d5b1f409-61c4-4e5b-838d-a61f619ad369","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c610be2b-7242-4f96-a82d-ace5c6780110","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"ef28807f-c72f-4a28-8f05-b5b918225c63","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"473587ec-9bbe-400e-b1ba-be46ff5490c6","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"b2cc3c1a-3f57-47ac-838c-c60760ca2057","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c5cc96ac-e1f4-442d-8a20-c91d613dfc8e","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"fcb88fc4-f83c-4c6c-8ef2-c9f726913d66","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"5a29931c-50d2-4535-ace2-cd9e0f04d9b8","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"c6a516da-4175-4615-8c69-cde1f1c97471","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"79ba78c3-596e-4c91-84e2-cf209029f9a7","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"7c93af39-5091-4a6d-ba35-d63aee420f6d","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"97dbcd20-2993-40b6-bd9d-d957fd36c682","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"7f0db861-bec6-4083-a3a1-dc63dc748d4d","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"b34be8fb-7180-4d6f-9a82-dca69d533948","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"5e710667-f653-4604-ab4e-e0e5f77b2001","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"a2c07f8c-4eb2-452a-b592-e7e868907e46","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"1652b4e6-63f5-4307-9a32-eae723728651","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"4c1940f2-b444-4821-b372-eba9877a246c","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"b4108347-e0ee-4c23-a269-ecf370879fef","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"4c3f9ce0-b19f-4784-985a-edd29b21e713","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"689fe533-2f18-436e-82ff-eefe1b908783","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"08e3a5db-2265-42d4-bd30-efc17de0d028","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"1b402080-435c-43f2-a191-f21385bb8dc7","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"e138f0f4-c8c7-49d7-8ea0-f65f8845d8e0","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]},{"id":"9bab41b8-5227-4c3b-8d40-f9ebae939eeb","tags":[{"name":"Upd","color":"Blue","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"2f377cfe-f512-431a-895b-f89af32041ce"}]},{"id":"2872e81a-93c5-4540-bd3b-fe8f172cddf8","tags":[{"name":"New","color":"Red","productId":"c15646e4-63d8-4965-8d62-7549a2986e99","links":null,"id":"c3c0ef13-c7a9-4649-9fcb-23b3abec175d"}]}]
        
(Showing Draft Content)

TableSheet Views

A tablesheet view is the centerpiece of a tablesheet and is formed by the fields of fetched data sources. It is used to enrich data columns and give them more capabilities.




As displayed in the above flowchart image, a tablesheet view can be presented in the following ways:

  • Table columns: Default columns that are generated from fields directly, which means they only have a field name property and are used to display the default view.

  • View columns: Rich columns that you can customize with styles, formats, and more properties. They are rendered into TableSheet view by using many useful attributes such as caption, style, width, and headerStyle.

You can customize a tablesheet view by setting various IColumn attributes such as header style, header fit, conditional formatting, data validation, and column styles such as cell types and dropdowns.

Column Display Value

You can display a customized value in a tablesheet column in place of the existing column data using the formatter with the formula in the style variable of the column. The formula can display the properties from the full row using the '@' operator in the bracket which displays the entire row data. 

There are two ways to display customized values in a column of tablesheet:

  • Formula in formatter

    =[@contactTitle] & ":" & [@employee.FirstName] & " " & [@employee.LastName]

  • Template formula in formatter

    {{[@contactTitle]}} : {{=[@employee.FirstName] & " " & [@employee.LastName]}}

column-display-value.png


The following code sample displays the formula in formatter to display customized column values: 

//add relationship between sales table and customer table
dataManager.addRelationship(salesTable, "customerKey", "myCustomer", customerTable, "customerKey", "mySales");

//add custom view
customerTable.fetch().then(function () {

var myView = salesTable.addView("myView", [
       { value: "saleKey", width: 100, caption: "Sale Key" },
       { value: "salesPerson", width: 150, caption: "Sales Person" },
       { value: "myCustomer", width: 350, caption: "Customer Information", style: { formatter: '=[@myCustomer.primaryContact] & " " & [@myCustomer.postalCode]' } },
       { value: "address", width: 350, caption: "Address" },
       { value: "stockItem", width: 350, caption: "Stock Item" },
       { value: "quantity", width: 100, caption: "Quantity" }
          ]);

Column Header Style

You can customize a column header's style by defining HeaderStyleOptions in the view headerStyle attribute. The HeaderStyleOptions contain options such as background color, theme font, word wrap, and so on.




The following code sample shows how to set column header style in a tablesheet view.

// define a style for column headers and assign it while adding the view using addView() method
var headerStyle = {
    font: "italic bold 13pt Calibri",
    borderTop: {
        color: "red",
        style: "thick"
    },
    borderLeft: {
        color: "red",
        style: "thin"
    },
    borderRight: {
        color: "red",
        style: "thin"
    },
    borderBottom: {
        color: "red",
        style: "thin"
    }
};


//bind a view to the tablesheet
customerTable.fetch().then(function () {
    var view = customerTable.addView("myView", [
        { value: "customerKey", width: 130, headerStyle: headerStyle, caption: "Customer Key" },// set the style of column header using headerStyle property
        { value: "customer", width: 200, headerStyle: headerStyle, caption: "Customer" }, 
        { value: "billToCustomer", width: 200, headerStyle: headerStyle, caption: "Bill To Customer" },
        { value: "category", width: 120, headerStyle: headerStyle, caption: "Category" },
        { value: "buyingGroup", width: 180, headerStyle: headerStyle, caption: "Buying Group" },
        { value: "primaryContact", width: 170, headerStyle: headerStyle, caption: "Primary Contact" },
        { value: "postalCode", width: 120, headerStyle: headerStyle, caption: "Postal Code" },
        { value: "validFrom", width: 150, headerStyle: headerStyle, caption: "Valid From" },
        { value: "validTo", width: 180, headerStyle: headerStyle, caption: "Valid To" }

    ]);
    //the View has all default columns of the Table
    sheet.setDataView(view);
});

Column Header Fit Mode

You can set the column header fit mode for the specified column in a tablesheet view to change the header layout to display the header and viewport data suitably.

It is useful when the content length of column data is short but the length of column header caption is too long, or when some columns have relations.

The view option attribute headerFit can be used to set the three types of header fit mode as described below.

  • Normal: The column header text direction is horizontal and from left to right. It is the default header fit mode.



  • Vertical: The column header text direction is vertical and from top to bottom.



  • Stack: The column headers are stacked on top of each other when the column is not wide enough for the column header text.




    The stack header fit mode is displayed alongside the vertical mode in a cross-fit way when the columns are adjacent to each other.



You can also set the stack row height in a tablesheet view by using the defaultStackRowHeight option. It calculates the average row height by default when the value is null (default). If a valid number is given as a value, it calculates the height from top to bottom.

The following code sample shows how to set the desired column header fit mode and adjust the row height in a tablesheet view.

//bind a view to the tablesheet
myTable.fetch().then(function () {
    var view = myTable.addView("myView", [
        { value: "saleKey", caption: "Sale Key", headerFit: "stack", headerStyle: headerStyle },// set headerFit to stack
        { value: "cityKey", caption: "City Key", headerFit: "stack", headerStyle: headerStyle },
        { value: "stockItemKey", width: 50, caption: "Stock Item Key", headerFit: "stack", headerStyle: headerStyle },
        { value: "invoiceDateKey", width: 120, caption: "Invoice Date Key", headerFit: "vertical", headerStyle: headerStyle },
        { value: "deliveryDateKey", width: 120, caption: "Delivery Date Key", headerFit: "vertical", headerStyle: headerStyle },
        { value: "salesPerson", width: 150, caption: "Sales Person", headerFit: "vertical", headerStyle: headerStyle },
        { value: "address", caption: "Address", width: 300, headerFit: "normal", headerStyle: headerStyle }

    ]);
    sheet.setDataView(view);
    sheet.options.defaultStackRowHeight = 30;
    sheet.setDefaultRowHeight(220, 1);
});

Note: If the row height is unable to display the entire caption, the specific column row stack will be cut off. The setDefaultRowHeight method can be used to adjust this.

Cell Types and Dropdowns

You can set different cell types and dropdowns in a tablesheet view to show how information is displayed and help in selecting the data easily and quickly.


Cell Types and Dropdowns in SpreadJS TableSheet


The following cell types and dropdowns are supported in the tablesheet:

  • Cell types - Checkbox, combobox, hyperlink, radio button list, checkbox list, range template

  • Dropdown - Color picker, date picker, time picker, month picker, list, slider, calculator, workflow list, multi-column

The following code sample shows how to add cell types and dropdowns in a tablesheet view.

// Code for RadioButtonList
var radioButtonListStyle = new GC.Spread.Sheets.Style();
var cellTypeRadioButtonList = new GC.Spread.Sheets.CellTypes.RadioButtonList();
cellTypeRadioButtonList.items([
    { text: "Tailspin Toys (Head Office)", value: "Tailspin Toys (Head Office)" },
    { text: "Wingtip Toys (Head Office)", value: "Wingtip Toys (Head Office)" },
]);
radioButtonListStyle.cellType = cellTypeRadioButtonList;

// Code for ButtonList
var buttonListStyle = new GC.Spread.Sheets.Style();
var buttonListCellType = new GC.Spread.Sheets.CellTypes.ButtonList();
buttonListCellType.items([
    { text: "Tailspin Toys", value: "Tailspin Toys" },
    { text: "Wingtip Toys", value: "Wingtip Toys" },
]);
buttonListStyle.cellType = buttonListCellType;

// Code for Date DropDown
var dateStyle = {};
dateStyle.cellButtons = [
    {
        imageType: "dropdown",
        command: "openDateTimePicker",
        useButtonStyle: true,
    }
];
dateStyle.dropDowns = [
    {
        type: "dateTimePicker",
        option: {
            showTime: true
        }
    }
];

//bind a view to the tablesheet
customerTable.fetch().then(function () {
    var view = customerTable.addView("myView", [
        { value: "customerKey", width: 120, caption: "Customer Key" },
        { value: "billToCustomer", width: 400, caption: "Bill To Customer", style: radioButtonListStyle },
        { value: "buyingGroup", width: 250, caption: "Buying Group", style: buttonListStyle },
        { value: "primaryContact", width: 170, caption: "Primary Contact" },
        { value: "validFrom", width: 190, caption: "Valid From", style: dateStyle }
    ]);
    //the View has all default columns of the Table
    sheet.setDataView(view);
});

Column Caption Multiple Headers

You can set a column caption in a tablesheet view where multiple columns can be grouped under a common header. It helps you represent the available information in an organized way by grouping the columns into a common category.

The "caption" property of the columnInfos parameter present in the addView method accepts a string array to set multiple rows of a column header in a tablesheet. The columns, with common values in the headers, are merged automatically in the row direction and column direction.

In the following example, customer information like Customer Key, Customer Name, Bill To Customer, and Primary Contact are presented under a common caption “Customer Information” that retains the existing headers for each column. Similarly, product validity dates can be displayed under one column header caption.




The following code sample shows how to set the same caption to the multiple columns in a tablesheet view.

//bind a view to the tablesheet
myTable.fetch().then(function () {
   var view = myTable.addView("myView", [
       { value: "customerKey", width: 130, caption: ["Customer Information", "Customer Key"] }, // Set string array to caption
       { value: "customer", width: 200, caption: ["Customer Information", "Customer"] },
       { value: "billToCustomer", width: 200, caption: ["Customer Information", "Bill To Customer"] },
       { value: "primaryContact", width: 170, caption: ["Customer Information", "Primary Contact"] },
       { value: "validFrom", width: 150, caption: ["Validity", "Valid From"], style: { formatter: "MM/dd/yyyy"} },
       { value: "validTo", width: 180, caption: ["Validity", "Valid To"], style: { formatter: "MM/dd/yyyy"} }
   ]);
   sheet.setDataView(view);
});

To know how to apply multiple header column captions using the SpreadJS Designer, refer to TableSheet Design Mode.

Free Header Area

You can add a header area to a tablesheet view where you can describe the tablesheet and present aggregated data using formulas and sparklines. The free header area is assigned above the main tablesheet view and can consist of a single row or multiple rows as shown in the image below.




The applyFreeHeaderArea method is used to configure the free layout area for the column header. This method accepts a worksheet JSON which can be created using the toJSON method. Before generating the worksheet JSON, set the keepUnknownFormulas option to true if you want to keep formulas that contain sheet names.

The following code sample shows how to create a template worksheet and apply the free header area in a tablesheet view.

//bind a view to the tablesheet
myTable.fetch().then(function () {
   var view = myTable.addView("myView", [

       { value: "stockItem", width: 300, caption: "Stock Item", headerStyle: headerStyle },
       { value: "unitPrice", width: 120, caption: "Unit Price", headerStyle: headerStyle },
       { value: "taxRate", width: 120, caption: "Tax Rate", headerStyle: headerStyle },
       { value: "recommendedRetailPrice", width: 190, caption: "Recommended Retail Price", style: currencyFormatter, headerStyle: headerStyle, conditionalFormats: [dataBarRule1] },
       { value: "=([@unitPrice] * [@taxRate])/100 + [@unitPrice]", caption: "Actual Retail Price", style: currencyFormatter, width: 190, headerStyle: headerStyle, conditionalFormats: [dataBarRule2] }, // calculated column

   ]);

   // create template sheet for free header area json
   var templateSheet = new GC.Spread.Sheets.Worksheet();
   templateSheet.options.keepUnknownFormulas = true;
   var currencyFormatterStyle = new GC.Spread.Sheets.Style();
   currencyFormatterStyle.formatter = formatter;
   currencyFormatterStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.left;
   templateSheet.setRowCount(6);
   var freeHeaderAreaStyle = new GC.Spread.Sheets.Style();
   freeHeaderAreaStyle.backColor = Colors.white;

   templateSheet.setValue(0, 0, "Retail Price Analysis");
   templateSheet.getCell(0, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 30px \"Calibri\"");
   templateSheet.addSpan(0, 0, 1, 5);
   var titleStyle = new GC.Spread.Sheets.Style();
   titleStyle.backColor = Colors.lightGreen;
   titleStyle.foreColor = Colors.black;
   templateSheet.setStyle(0, -1, titleStyle);
   templateSheet.setRowHeight(0, 80);

   templateSheet.getCell(1, 0)
       .value("Whether a Stock Item's Actual Retail Price is either under or over Recommended Retail Price is automatically calculated.")
       .font("italic 12px \"Calibri\"")
       .foreColor("rgb(120,120,120)")
       .textIndent(2);
   templateSheet.setStyle(1, -1, titleStyle);
   templateSheet.addSpan(1, 0, 1, 5);

   var headerDescriptionStyle = new GC.Spread.Sheets.Style();
   headerDescriptionStyle.backColor = Colors.lightGreen;
   headerDescriptionStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.middleGreen, GC.Spread.Sheets.LineStyle.thick);
   templateSheet.setStyle(2, -1, headerDescriptionStyle);
   templateSheet.addSpan(2, 0, 1, 5);
   templateSheet.setRowHeight(2, 16);

   templateSheet.setValue(3, 0, "Total Recommended Retail Price");
   templateSheet.getCell(3, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.darkGreen);
   templateSheet.addSpan(3, 0, 1, 2);
   templateSheet.setFormula(3, 2, '=SUM(TableSheet1[Recommended Retail Price])');
   templateSheet.getCell(3, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.darkGreen).formatter(formatter);
   templateSheet.setFormula(3, 3, '=HBARSPARKLINE(ROUND(C4/MAX(C4,C5),2),"' + Colors.darkGreen + '",false)');
   templateSheet.addSpan(3, 3, 1, 2);
   templateSheet.setStyle(3, -1, freeHeaderAreaStyle);

   templateSheet.setValue(4, 0, "Total Actual Retail Price");
   templateSheet.getCell(4, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.brown);
   templateSheet.addSpan(4, 0, 1, 2);
   templateSheet.setFormula(4, 2, '=SUM(TableSheet1[Actual Retail Price])');
   templateSheet.getCell(4, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.brown).formatter(formatter);
   var contentBorderStyle = new GC.Spread.Sheets.Style();
   contentBorderStyle.backColor = Colors.white;
   contentBorderStyle.borderBottom = new GC.Spread.Sheets.LineBorder(Colors.brown, GC.Spread.Sheets.LineStyle.thick);
   templateSheet.setStyle(4, -1, contentBorderStyle);
   templateSheet.setFormula(4, 3, '=HBARSPARKLINE(ROUND(C5/MAX(C4,C5),2),"' + Colors.brown + '",false)');
   templateSheet.addSpan(4, 3, 1, 2);

   templateSheet.setFormula(5, 0, '=IF(C4>C5,"Budget is under Total Recommended Retail Price by","Budget is over Total Recommended Retail Price")');
   templateSheet.getCell(5, 0).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").foreColor(Colors.black);
   templateSheet.addSpan(5, 0, 1, 2);
   templateSheet.setFormula(5, 2, '=C4-C5');
   templateSheet.getCell(5, 2).hAlign(GC.Spread.Sheets.HorizontalAlign.left).font("bold 14px \"Calibri\"").formatter(formatter).foreColor(Colors.black);
   templateSheet.setStyle(5, -1, freeHeaderAreaStyle);
   templateSheet.addSpan(5, 2, 1, 3);

   let template = templateSheet.toJSON();
   sheet.applyFreeHeaderArea(template);
   sheet.setDataView(view);
});

The free header supports the formula text box when editing or creating formulas in the cell. This enables you to perform selection operations on tablesheet columns, column ranges, multiple columns, and cross sheet columns.




To know how to apply the free header area using the SpreadJS Designer, refer to TableSheet Design Mode.

Trigger Formula

You can store independent data in a column but still allows you to use a formula to calculate column data using the Trigger formula in a TableSheet. It is useful to recalculate your data based on selected conditions or clean data when a new value is entered or set an appropriate default value for a column.

SpreadJS provides a new interface GC.Data.ITriggerFormulaOptions which includes properties such as when, formula, and fields to configure the triggers.

Name

Description

Usage

when

(Required)

Indicates when to trigger.

  • onNew: apply the formula to the data created.

  • onNewAndUpdate: apply the formula to the data created or updated.

formula

(Required)

Indicates the applied formula.

The evaluated result of the formula is set in the row data.

fields

(Required)

Indicates which fields could affect the formula to trigger.

“Any Field” indicates that all field “field1, field2, field3“ indicates the related fields which are separated by the comma.

If the when is onNew, no need to specify the fields, otherwise it’s required.

The following code sample implements the trigger formula.

schema: {
        type: "csv",
        columns: {
            SKU: {
                dataType: "string",
                trigger: {
                    when: "onNewAndUpdate",
                    formula: "=UPPER(TRIM([@SKU]))", // Format the input SKU text
                    fields: "SKU" // If the SKU field be inputted, trigger the formula to format the input text
                }
            },
            OrderDate: {
                dataType: "date",
                trigger: {
                    when: "onNew", // When an order added, records the order created date
                    formula: "=TODAY()"
               }
            },
            lastUpdatedTime: {
                dataType: "date",
                trigger: {
                    when: "onNewAndUpdate",
                    formula: "=NOW()",
                    fields: "*" // When any field be updated or the order be added, records the order updated time
                }
            },
            lastUpdateUser: {
                dataType: "string",
                trigger: {
                    when: "onNewAndUpdate",
                    formula: "=ACTIVEUSER()", // The user could determine how to getting the current updated user by them self
                    fields: "*" // When any field be updated or the order be added, records the updated user
                }
            },
            OrderPhone: {
                dataType: "string",
                trigger: {
                    when: "onNewAndUpdate",
                    formula: "=IF(ISBLANK([@OrderPhone]),[@customer.Phone],[@OrderPhone])",
                    fields: "CustomerId,OrderPhone"// Provide the customer phone when the order phone is blank
                }
            },
            Amount: {
                dataType: "number",
                trigger: {
                    when: "onNewAndUpdate",
                    formula: "=LET(amount, [@UnitPrice] * [@Quantity], IF([@Quantity] > 30, amount * 0.8, amount))",
                    fields: "UnitPrice,Quantity"  // When the UnitPrice or Quantity fields updated or the order be added, Amount field will get a calculated result automatically
                }
            },
            CustomerId: {
                lookup: {
                    name: 'customer', columns: [
                        { value: "Id", width: 60 },
                        { value: "CompanyName", width: 200 },
                        { value: "ContactName", width: 140 },
                        { value: "ContactTitle", width: 140 }
                    ]
                }
            },
            Quantity: { dataType: "number" },
            UnitPrice: { dataType: "number" },
        }
    }
});

Trigger formulas have certain policies, such as:

  • When new row data is added, the trigger with onNew and onNewAndUpdating is evaluated, similar to updating.

  • When multiple fields in a row's data are updated, the formula will be triggered to alter the values of watched fields. Otherwise, it’s not triggered.

  • If the trigger of the field watches the field itself, the trigger formula is evaluated with the new value, and the result is treated as the updated value of the field.

  • The evaluated value from the trigger formula is treated as the updated value of the field, and the updated value will be applied in the evaluation of the trigger formula which refers to the field directly.