[{"data":1,"prerenderedAt":6778},["ShallowReactive",2],{"blog-\u002Fblog\u002F2025\u002F06\u002Fbuilding-andon-task-manager-dashboard-with-ff":3,"featureCatalog":5851,"changelog-titles":6243,"blog-all-for-related":6777},{"id":4,"title":5,"authors":6,"body":8,"cta":5830,"date":5831,"description":5832,"extension":5833,"features":5830,"image":5834,"lastUpdated":5830,"meta":5835,"navigation":2193,"path":5843,"release":5830,"seo":5844,"sitemap":5845,"stem":5846,"subtitle":5847,"tags":5848,"tldr":5830,"video":5830,"__hash__":5850},"blog\u002Fblog\u002F2025\u002F06\u002Fbuilding-andon-task-manager-dashboard-with-ff.md","Part 2: Building an Andon Task Manager with FlowFuse",[7],"sumit-shinde",{"type":9,"value":10,"toc":5809},"minimark",[11,21,36,41,44,75,84,93,98,101,166,169,172,292,303,310,313,316,2046,2056,2063,2066,2069,2102,3045,3050,3053,3061,3070,3079,3082,3085,3088,3091,3102,3107,3110,3159,3168,3175,3179,3182,3185,3199,3204,3391,3394,3417,3422,3479,3482,3491,3499,3513,3522,3526,3529,3787,3796,3832,3841,3845,3848,3970,3979,3982,3985,4003,4516,4579,4585,4606,4615,4624,4627,4641,4837,4846,4850,4991,5011,5023,5026,5033,5130,5139,5142,5145,5276,5586,5637,5646,5653,5689,5705,5716,5741,5759,5775,5784,5787,5796,5800,5803,5806],[12,13,14,15,20],"p",{},"In ",[16,17,19],"a",{"href":18},"\u002Fblog\u002F2025\u002F05\u002Fbuilding-andon-task-manager-with-ff\u002F","Part 1",", we introduced the concept of an Andon Task Manager, designed to streamline issue reporting and resolution on the factory floor, and outlined the system’s key features, user roles, and dashboard layout.",[12,22,23,24,30,31,35],{},"In this part 2, we move from planning to implementation. The focus now shifts to building the actual system using ",[16,25,29],{"href":26,"rel":27},"https:\u002F\u002Fdashboard.flowfuse.com",[28],"nofollow","FlowFuse Dashboard"," (Node-RED Dashboard 2.0), hosted on the FlowFuse platform. We will begin by developing the ",[32,33,34],"strong",{},"Lines view"," for regular users, along with a line selection menu. The Department View and Admin interface will follow in a later part of the series.",[37,38,40],"h2",{"id":39},"getting-started","Getting Started",[12,42,43],{},"To simplify the development process, the implementation is divided into the following key sections:",[45,46,47,51,54,57,60,63,66,69,72],"ul",{},[48,49,50],"li",{},"Initialize SQLite Database",[48,52,53],{},"Seed Demo Data: Departments & Lines",[48,55,56],{},"Build Line Selection Menu",[48,58,59],{},"Enable URL-Based Dashboard Access",[48,61,62],{},"Create Live Request Fetch Flow (Per Line)",[48,64,65],{},"Render Request Data in a Table",[48,67,68],{},"Setting Up Visual Alerts and Timestamp Formatting",[48,70,71],{},"Highlight Requests with CSS & Add Buttons to Update Request Status",[48,73,74],{},"Create New Request Submission Flow",[12,76,77,78,83],{},"Before proceeding, a basic understanding of Node-RED is recommended. If you are new to Node-RED, consider going through this ",[16,79,82],{"href":80,"rel":81},"https:\u002F\u002Fnode-red-academy.learnworlds.com\u002Fcourse\u002Fnode-red-getting-started",[28],"free Node-RED Fundamentals Course"," to get started.",[85,86,87],"blockquote",{},[12,88,89,92],{},[32,90,91],{},"Tip:"," Organize your flows into clearly defined groups. For reference, images of each flow are provided. Please use the exact names given to each flow, this will help ensure consistency and make it easier to navigate back to specific flows when referenced later.",[94,95,97],"h3",{"id":96},"prerequisites","Prerequisites",[12,99,100],{},"Before you begin building the Andon Task Manager with FlowFuse, make sure you have the following:",[45,102,103,120,126,137,146,157],{},[48,104,105,108,109,114,115,119],{},[32,106,107],{},"Running FlowFuse Instance:"," Make sure you have a FlowFuse instance set up and running. If you don't have an account, check out the ",[16,110,113],{"href":111,"rel":112},"https:\u002F\u002Fapp.flowfuse.com\u002Faccount\u002Fcreate",[28],"free trial"," and ",[16,116,118],{"href":117},"\u002Fdocs\u002Fuser\u002Fintroduction\u002F#creating-a-node-red-instance","learn"," how to create an instance.",[48,121,122,125],{},[32,123,124],{},"@flowfuse\u002Fnode-red-dashboard:"," Ensure you have FlowFuse Dashboard (also known as Node-RED Dashboard 2.0 in the community) installed.",[48,127,128,131,132,136],{},[32,129,130],{},"SQLite Contrib Node:"," Install ",[133,134,135],"code",{},"node-red-contrib-sqlite"," to handle local data storage.",[48,138,139,131,142,145],{},[32,140,141],{},"FlowFuse Multi-user Andon:",[133,143,144],{},"@flowfuse\u002Fnode-red-dashboard-2-user-addon"," to enable multi-user support.",[48,147,148,151,152,156],{},[32,149,150],{},"Enable FlowFuse User Authentication:"," ",[16,153,155],{"href":154},"\u002Fblog\u002F2024\u002F04\u002Fdisplaying-logged-in-users-on-dashboard\u002F#enabling-flowfuse-user-authentication","Enable FlowFuse User Authentication"," on your FlowFuse instance.",[48,158,159,131,162,165],{},[32,160,161],{},"Moment Contrib Node:",[133,163,164],{},"node-red-contrib-moment"," for date and time formatting.",[94,167,50],{"id":168},"initialize-sqlite-database",[12,170,171],{},"The first step is to set up a database to store requests and their updates.",[173,174,175,182,192,203,279,285],"ol",{},[48,176,177,178,181],{},"Drag an ",[32,179,180],{},"Inject"," node onto the canvas and configure it to trigger on Deploy, after a delay of 0.1 seconds.",[48,183,177,184,187,188,191],{},[32,185,186],{},"SQLite"," node onto the canvas. Double-click and click the ",[32,189,190],{},"+"," icon to add a new database configuration.",[48,193,194,195,198,199,202],{},"Give the database a name and set the mode to ",[32,196,197],{},"Read-Write-Create",". Click ",[32,200,201],{},"Add"," to save.",[48,204,205,206,209,210,213,214],{},"Set ",[32,207,208],{},"SQL Query"," to ",[32,211,212],{},"Fixed statement"," and enter:",[215,216,221],"pre",{"className":217,"code":218,"language":219,"meta":220,"style":220},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CREATE TABLE IF NOT EXISTS requests (\n  rowid INTEGER PRIMARY KEY,\n  line TEXT NOT NULL,\n  support TEXT NOT NULL,\n  requested TEXT NOT NULL,\n  acknowledged TEXT,\n  resolved TEXT,\n  notes TEXT\n);\n","sql","",[133,222,223,231,237,243,249,255,261,267,273],{"__ignoreMap":220},[224,225,228],"span",{"class":226,"line":227},"line",1,[224,229,230],{},"CREATE TABLE IF NOT EXISTS requests (\n",[224,232,234],{"class":226,"line":233},2,[224,235,236],{},"  rowid INTEGER PRIMARY KEY,\n",[224,238,240],{"class":226,"line":239},3,[224,241,242],{},"  line TEXT NOT NULL,\n",[224,244,246],{"class":226,"line":245},4,[224,247,248],{},"  support TEXT NOT NULL,\n",[224,250,252],{"class":226,"line":251},5,[224,253,254],{},"  requested TEXT NOT NULL,\n",[224,256,258],{"class":226,"line":257},6,[224,259,260],{},"  acknowledged TEXT,\n",[224,262,264],{"class":226,"line":263},7,[224,265,266],{},"  resolved TEXT,\n",[224,268,270],{"class":226,"line":269},8,[224,271,272],{},"  notes TEXT\n",[224,274,276],{"class":226,"line":275},9,[224,277,278],{},");\n",[48,280,281,282,284],{},"Connect the ",[32,283,180],{}," node to the SQLite node.",[48,286,287,288,291],{},"Click ",[32,289,290],{},"Deploy",".",[12,293,294,299],{},[295,296],"img",{"alt":297,"dataZoomable":220,"src":298},"Node-RED flow showing an Inject node connected to an SQLite node to create a requests table in the database.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fsqlite-create-flow.png",[300,301,302],"em",{},"Flow to initialize the SQLite database and create the requests table.",[12,304,305,306,309],{},"Once deployed, this will create the SQLite database and ",[133,307,308],{},"requests"," table if it does not already exist.",[94,311,53],{"id":312},"seed-demo-data-departments-lines",[12,314,315],{},"As discussed in the planning section, only the admin role will have the ability to add new departments and lines. Since the admin feature is not yet available, we will populate demo data using a predefined flow to allow ourself to test the application while the standard user interface is being developed.",[317,318,320],"render-flow",{":height":319},"300",[215,321,325],{"className":322,"code":323,"language":324,"meta":220,"style":220},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[{\"id\":\"d5dd9bfc599374d4\",\"type\":\"tab\",\"label\":\"Populate with demo support areas and lines\",\"disabled\":false,\"info\":\"\",\"env\":[]},{\"id\":\"6471824e24f18939\",\"type\":\"group\",\"z\":\"d5dd9bfc599374d4\",\"name\":\"Add demo production line and department\",\"style\":{\"label\":true},\"nodes\":[\"34c733b480e41a13\",\"4e46ae25d198fd1b\",\"882e29d2dcc9326c\",\"399bd159f46c7427\",\"5001c1cdf6661f88\"],\"x\":34,\"y\":39,\"w\":1302,\"h\":122},{\"id\":\"34c733b480e41a13\",\"type\":\"inject\",\"z\":\"d5dd9bfc599374d4\",\"g\":\"6471824e24f18939\",\"name\":\"Add production lines and department for testing\",\"props\":[],\"repeat\":\"\",\"crontab\":\"\",\"once\":true,\"onceDelay\":0.1,\"topic\":\"\",\"x\":260,\"y\":100,\"wires\":[[\"4e46ae25d198fd1b\",\"399bd159f46c7427\"]]},{\"id\":\"4e46ae25d198fd1b\",\"type\":\"switch\",\"z\":\"d5dd9bfc599374d4\",\"g\":\"6471824e24f18939\",\"name\":\"Is lines undefined?\",\"property\":\"#:(persistent)::lines\",\"propertyType\":\"global\",\"rules\":[{\"t\":\"istype\",\"v\":\"undefined\",\"vt\":\"undefined\"}],\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":770,\"y\":80,\"wires\":[[\"882e29d2dcc9326c\"]]},{\"id\":\"882e29d2dcc9326c\",\"type\":\"change\",\"z\":\"d5dd9bfc599374d4\",\"g\":\"6471824e24f18939\",\"name\":\"Store lines to context store\",\"rules\":[{\"t\":\"set\",\"p\":\"#:(persistent)::lines\",\"pt\":\"global\",\"to\":\"[{\\\"value\\\":\\\"T1\\\",\\\"label\\\":\\\"T1\\\"},{\\\"value\\\":\\\"T2\\\",\\\"label\\\":\\\"T2\\\"}]\",\"tot\":\"json\"}],\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1140,\"y\":80,\"wires\":[[]]},{\"id\":\"399bd159f46c7427\",\"type\":\"switch\",\"z\":\"d5dd9bfc599374d4\",\"g\":\"6471824e24f18939\",\"name\":\"Is departments undefined?\",\"property\":\"#:(persistent)::departments\",\"propertyType\":\"global\",\"rules\":[{\"t\":\"istype\",\"v\":\"undefined\",\"vt\":\"undefined\"}],\"checkall\":\"true\",\"repair\":false,\"outputs\":1,\"x\":800,\"y\":120,\"wires\":[[\"5001c1cdf6661f88\"]]},{\"id\":\"5001c1cdf6661f88\",\"type\":\"change\",\"z\":\"d5dd9bfc599374d4\",\"g\":\"6471824e24f18939\",\"name\":\"Store departments to context store\",\"rules\":[{\"t\":\"set\",\"p\":\"#:(persistent)::departments\",\"pt\":\"global\",\"to\":\"[{\\\"value\\\":\\\"Maintenance\\\",\\\"label\\\":\\\"Maintenance\\\"},{\\\"value\\\":\\\"Stores\\\",\\\"label\\\":\\\"Stores\\\"},{\\\"value\\\":\\\"Quality\\\",\\\"label\\\":\\\"Quality\\\"}]\",\"tot\":\"json\"}],\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":1170,\"y\":120,\"wires\":[[]]}]\n","json",[133,326,327],{"__ignoreMap":220},[224,328,329,333,336,340,342,345,347,351,353,356,358,361,363,365,367,370,372,374,376,379,381,383,385,388,390,392,394,397,399,402,404,407,409,411,414,416,418,421,423,426,428,430,432,434,436,439,441,443,445,447,449,451,453,456,458,460,462,465,467,469,471,473,475,477,479,482,484,486,488,491,493,495,497,500,502,505,507,510,512,515,517,520,522,525,527,530,532,534,536,539,541,543,545,548,550,552,554,557,559,561,563,566,568,571,573,576,578,580,584,586,588,591,593,595,598,600,602,605,607,609,612,614,616,619,621,623,626,629,631,633,635,637,639,641,643,645,647,649,651,653,655,658,660,662,664,666,668,670,672,674,676,678,680,683,685,687,689,691,693,695,697,699,701,703,705,708,710,712,714,717,719,722,724,727,729,731,733,735,737,740,742,744,746,748,750,753,755,758,760,763,765,767,770,772,774,777,779,781,783,785,787,789,791,793,796,798,800,802,804,806,809,811,813,816,818,821,823,825,827,829,831,833,835,838,840,842,844,846,848,850,852,854,856,858,860,862,864,867,869,871,873,875,877,879,881,883,885,887,889,891,893,895,897,899,901,903,905,907,909,911,913,916,918,920,922,925,927,929,931,934,936,938,940,943,945,947,949,952,954,956,958,961,963,966,968,971,973,975,977,980,982,984,986,989,991,993,995,998,1000,1002,1004,1007,1009,1011,1013,1015,1017,1020,1022,1025,1027,1029,1031,1034,1036,1038,1040,1043,1045,1047,1049,1052,1054,1056,1059,1061,1063,1065,1067,1069,1072,1074,1076,1078,1080,1082,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1132,1134,1136,1138,1140,1142,1144,1146,1148,1150,1152,1154,1156,1158,1160,1162,1164,1166,1168,1170,1172,1174,1176,1178,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201,1203,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228,1231,1233,1235,1237,1239,1241,1243,1245,1248,1250,1252,1254,1256,1260,1263,1265,1267,1269,1272,1274,1276,1278,1280,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1305,1307,1309,1311,1313,1315,1317,1319,1321,1323,1326,1328,1330,1332,1335,1337,1339,1341,1343,1345,1347,1349,1352,1354,1356,1358,1360,1362,1364,1366,1368,1370,1372,1374,1377,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1402,1404,1406,1408,1410,1412,1414,1417,1419,1421,1423,1425,1427,1429,1431,1433,1435,1437,1440,1442,1444,1446,1448,1450,1452,1454,1456,1458,1460,1462,1464,1466,1468,1470,1472,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506,1508,1510,1512,1514,1517,1519,1521,1523,1525,1527,1529,1531,1534,1536,1538,1540,1542,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574,1576,1578,1580,1582,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620,1622,1624,1626,1628,1630,1632,1634,1636,1638,1640,1642,1644,1646,1648,1650,1652,1654,1657,1659,1661,1663,1665,1667,1670,1672,1674,1676,1678,1680,1682,1684,1686,1688,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708,1710,1712,1714,1716,1718,1720,1722,1724,1726,1728,1730,1732,1734,1736,1738,1740,1742,1744,1746,1748,1750,1752,1754,1756,1758,1760,1762,1765,1767,1769,1771,1773,1775,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1850,1852,1854,1856,1858,1860,1862,1864,1866,1868,1870,1872,1874,1876,1878,1880,1883,1885,1887,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913,1916,1918,1920,1922,1924,1926,1928,1930,1932,1934,1936,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1962,1964,1966,1968,1970,1972,1974,1976,1978,1980,1982,1984,1986,1988,1990,1992,1994,1996,1998,2000,2002,2004,2006,2008,2010,2012,2014,2016,2018,2020,2023,2025,2027,2029,2031,2033,2035,2037,2039,2041,2043],{"class":226,"line":227},[224,330,332],{"class":331},"sMK4o","[{",[224,334,335],{"class":331},"\"",[224,337,339],{"class":338},"spNyl","id",[224,341,335],{"class":331},[224,343,344],{"class":331},":",[224,346,335],{"class":331},[224,348,350],{"class":349},"sfazB","d5dd9bfc599374d4",[224,352,335],{"class":331},[224,354,355],{"class":331},",",[224,357,335],{"class":331},[224,359,360],{"class":338},"type",[224,362,335],{"class":331},[224,364,344],{"class":331},[224,366,335],{"class":331},[224,368,369],{"class":349},"tab",[224,371,335],{"class":331},[224,373,355],{"class":331},[224,375,335],{"class":331},[224,377,378],{"class":338},"label",[224,380,335],{"class":331},[224,382,344],{"class":331},[224,384,335],{"class":331},[224,386,387],{"class":349},"Populate with demo support areas and lines",[224,389,335],{"class":331},[224,391,355],{"class":331},[224,393,335],{"class":331},[224,395,396],{"class":338},"disabled",[224,398,335],{"class":331},[224,400,401],{"class":331},":false,",[224,403,335],{"class":331},[224,405,406],{"class":338},"info",[224,408,335],{"class":331},[224,410,344],{"class":331},[224,412,413],{"class":331},"\"\"",[224,415,355],{"class":331},[224,417,335],{"class":331},[224,419,420],{"class":338},"env",[224,422,335],{"class":331},[224,424,425],{"class":331},":[]},{",[224,427,335],{"class":331},[224,429,339],{"class":338},[224,431,335],{"class":331},[224,433,344],{"class":331},[224,435,335],{"class":331},[224,437,438],{"class":349},"6471824e24f18939",[224,440,335],{"class":331},[224,442,355],{"class":331},[224,444,335],{"class":331},[224,446,360],{"class":338},[224,448,335],{"class":331},[224,450,344],{"class":331},[224,452,335],{"class":331},[224,454,455],{"class":349},"group",[224,457,335],{"class":331},[224,459,355],{"class":331},[224,461,335],{"class":331},[224,463,464],{"class":338},"z",[224,466,335],{"class":331},[224,468,344],{"class":331},[224,470,335],{"class":331},[224,472,350],{"class":349},[224,474,335],{"class":331},[224,476,355],{"class":331},[224,478,335],{"class":331},[224,480,481],{"class":338},"name",[224,483,335],{"class":331},[224,485,344],{"class":331},[224,487,335],{"class":331},[224,489,490],{"class":349},"Add demo production line and department",[224,492,335],{"class":331},[224,494,355],{"class":331},[224,496,335],{"class":331},[224,498,499],{"class":338},"style",[224,501,335],{"class":331},[224,503,504],{"class":331},":{",[224,506,335],{"class":331},[224,508,378],{"class":509},"sBMFI",[224,511,335],{"class":331},[224,513,514],{"class":331},":true},",[224,516,335],{"class":331},[224,518,519],{"class":338},"nodes",[224,521,335],{"class":331},[224,523,524],{"class":331},":[",[224,526,335],{"class":331},[224,528,529],{"class":349},"34c733b480e41a13",[224,531,335],{"class":331},[224,533,355],{"class":331},[224,535,335],{"class":331},[224,537,538],{"class":349},"4e46ae25d198fd1b",[224,540,335],{"class":331},[224,542,355],{"class":331},[224,544,335],{"class":331},[224,546,547],{"class":349},"882e29d2dcc9326c",[224,549,335],{"class":331},[224,551,355],{"class":331},[224,553,335],{"class":331},[224,555,556],{"class":349},"399bd159f46c7427",[224,558,335],{"class":331},[224,560,355],{"class":331},[224,562,335],{"class":331},[224,564,565],{"class":349},"5001c1cdf6661f88",[224,567,335],{"class":331},[224,569,570],{"class":331},"],",[224,572,335],{"class":331},[224,574,575],{"class":338},"x",[224,577,335],{"class":331},[224,579,344],{"class":331},[224,581,583],{"class":582},"sbssI","34",[224,585,355],{"class":331},[224,587,335],{"class":331},[224,589,590],{"class":338},"y",[224,592,335],{"class":331},[224,594,344],{"class":331},[224,596,597],{"class":582},"39",[224,599,355],{"class":331},[224,601,335],{"class":331},[224,603,604],{"class":338},"w",[224,606,335],{"class":331},[224,608,344],{"class":331},[224,610,611],{"class":582},"1302",[224,613,355],{"class":331},[224,615,335],{"class":331},[224,617,618],{"class":338},"h",[224,620,335],{"class":331},[224,622,344],{"class":331},[224,624,625],{"class":582},"122",[224,627,628],{"class":331},"},{",[224,630,335],{"class":331},[224,632,339],{"class":338},[224,634,335],{"class":331},[224,636,344],{"class":331},[224,638,335],{"class":331},[224,640,529],{"class":349},[224,642,335],{"class":331},[224,644,355],{"class":331},[224,646,335],{"class":331},[224,648,360],{"class":338},[224,650,335],{"class":331},[224,652,344],{"class":331},[224,654,335],{"class":331},[224,656,657],{"class":349},"inject",[224,659,335],{"class":331},[224,661,355],{"class":331},[224,663,335],{"class":331},[224,665,464],{"class":338},[224,667,335],{"class":331},[224,669,344],{"class":331},[224,671,335],{"class":331},[224,673,350],{"class":349},[224,675,335],{"class":331},[224,677,355],{"class":331},[224,679,335],{"class":331},[224,681,682],{"class":338},"g",[224,684,335],{"class":331},[224,686,344],{"class":331},[224,688,335],{"class":331},[224,690,438],{"class":349},[224,692,335],{"class":331},[224,694,355],{"class":331},[224,696,335],{"class":331},[224,698,481],{"class":338},[224,700,335],{"class":331},[224,702,344],{"class":331},[224,704,335],{"class":331},[224,706,707],{"class":349},"Add production lines and department for testing",[224,709,335],{"class":331},[224,711,355],{"class":331},[224,713,335],{"class":331},[224,715,716],{"class":338},"props",[224,718,335],{"class":331},[224,720,721],{"class":331},":[],",[224,723,335],{"class":331},[224,725,726],{"class":338},"repeat",[224,728,335],{"class":331},[224,730,344],{"class":331},[224,732,413],{"class":331},[224,734,355],{"class":331},[224,736,335],{"class":331},[224,738,739],{"class":338},"crontab",[224,741,335],{"class":331},[224,743,344],{"class":331},[224,745,413],{"class":331},[224,747,355],{"class":331},[224,749,335],{"class":331},[224,751,752],{"class":338},"once",[224,754,335],{"class":331},[224,756,757],{"class":331},":true,",[224,759,335],{"class":331},[224,761,762],{"class":338},"onceDelay",[224,764,335],{"class":331},[224,766,344],{"class":331},[224,768,769],{"class":582},"0.1",[224,771,355],{"class":331},[224,773,335],{"class":331},[224,775,776],{"class":338},"topic",[224,778,335],{"class":331},[224,780,344],{"class":331},[224,782,413],{"class":331},[224,784,355],{"class":331},[224,786,335],{"class":331},[224,788,575],{"class":338},[224,790,335],{"class":331},[224,792,344],{"class":331},[224,794,795],{"class":582},"260",[224,797,355],{"class":331},[224,799,335],{"class":331},[224,801,590],{"class":338},[224,803,335],{"class":331},[224,805,344],{"class":331},[224,807,808],{"class":582},"100",[224,810,355],{"class":331},[224,812,335],{"class":331},[224,814,815],{"class":338},"wires",[224,817,335],{"class":331},[224,819,820],{"class":331},":[[",[224,822,335],{"class":331},[224,824,538],{"class":349},[224,826,335],{"class":331},[224,828,355],{"class":331},[224,830,335],{"class":331},[224,832,556],{"class":349},[224,834,335],{"class":331},[224,836,837],{"class":331},"]]},{",[224,839,335],{"class":331},[224,841,339],{"class":338},[224,843,335],{"class":331},[224,845,344],{"class":331},[224,847,335],{"class":331},[224,849,538],{"class":349},[224,851,335],{"class":331},[224,853,355],{"class":331},[224,855,335],{"class":331},[224,857,360],{"class":338},[224,859,335],{"class":331},[224,861,344],{"class":331},[224,863,335],{"class":331},[224,865,866],{"class":349},"switch",[224,868,335],{"class":331},[224,870,355],{"class":331},[224,872,335],{"class":331},[224,874,464],{"class":338},[224,876,335],{"class":331},[224,878,344],{"class":331},[224,880,335],{"class":331},[224,882,350],{"class":349},[224,884,335],{"class":331},[224,886,355],{"class":331},[224,888,335],{"class":331},[224,890,682],{"class":338},[224,892,335],{"class":331},[224,894,344],{"class":331},[224,896,335],{"class":331},[224,898,438],{"class":349},[224,900,335],{"class":331},[224,902,355],{"class":331},[224,904,335],{"class":331},[224,906,481],{"class":338},[224,908,335],{"class":331},[224,910,344],{"class":331},[224,912,335],{"class":331},[224,914,915],{"class":349},"Is lines undefined?",[224,917,335],{"class":331},[224,919,355],{"class":331},[224,921,335],{"class":331},[224,923,924],{"class":338},"property",[224,926,335],{"class":331},[224,928,344],{"class":331},[224,930,335],{"class":331},[224,932,933],{"class":349},"#:(persistent)::lines",[224,935,335],{"class":331},[224,937,355],{"class":331},[224,939,335],{"class":331},[224,941,942],{"class":338},"propertyType",[224,944,335],{"class":331},[224,946,344],{"class":331},[224,948,335],{"class":331},[224,950,951],{"class":349},"global",[224,953,335],{"class":331},[224,955,355],{"class":331},[224,957,335],{"class":331},[224,959,960],{"class":338},"rules",[224,962,335],{"class":331},[224,964,965],{"class":331},":[{",[224,967,335],{"class":331},[224,969,970],{"class":509},"t",[224,972,335],{"class":331},[224,974,344],{"class":331},[224,976,335],{"class":331},[224,978,979],{"class":349},"istype",[224,981,335],{"class":331},[224,983,355],{"class":331},[224,985,335],{"class":331},[224,987,988],{"class":509},"v",[224,990,335],{"class":331},[224,992,344],{"class":331},[224,994,335],{"class":331},[224,996,997],{"class":349},"undefined",[224,999,335],{"class":331},[224,1001,355],{"class":331},[224,1003,335],{"class":331},[224,1005,1006],{"class":509},"vt",[224,1008,335],{"class":331},[224,1010,344],{"class":331},[224,1012,335],{"class":331},[224,1014,997],{"class":349},[224,1016,335],{"class":331},[224,1018,1019],{"class":331},"}],",[224,1021,335],{"class":331},[224,1023,1024],{"class":338},"checkall",[224,1026,335],{"class":331},[224,1028,344],{"class":331},[224,1030,335],{"class":331},[224,1032,1033],{"class":349},"true",[224,1035,335],{"class":331},[224,1037,355],{"class":331},[224,1039,335],{"class":331},[224,1041,1042],{"class":338},"repair",[224,1044,335],{"class":331},[224,1046,401],{"class":331},[224,1048,335],{"class":331},[224,1050,1051],{"class":338},"outputs",[224,1053,335],{"class":331},[224,1055,344],{"class":331},[224,1057,1058],{"class":582},"1",[224,1060,355],{"class":331},[224,1062,335],{"class":331},[224,1064,575],{"class":338},[224,1066,335],{"class":331},[224,1068,344],{"class":331},[224,1070,1071],{"class":582},"770",[224,1073,355],{"class":331},[224,1075,335],{"class":331},[224,1077,590],{"class":338},[224,1079,335],{"class":331},[224,1081,344],{"class":331},[224,1083,1084],{"class":582},"80",[224,1086,355],{"class":331},[224,1088,335],{"class":331},[224,1090,815],{"class":338},[224,1092,335],{"class":331},[224,1094,820],{"class":331},[224,1096,335],{"class":331},[224,1098,547],{"class":349},[224,1100,335],{"class":331},[224,1102,837],{"class":331},[224,1104,335],{"class":331},[224,1106,339],{"class":338},[224,1108,335],{"class":331},[224,1110,344],{"class":331},[224,1112,335],{"class":331},[224,1114,547],{"class":349},[224,1116,335],{"class":331},[224,1118,355],{"class":331},[224,1120,335],{"class":331},[224,1122,360],{"class":338},[224,1124,335],{"class":331},[224,1126,344],{"class":331},[224,1128,335],{"class":331},[224,1130,1131],{"class":349},"change",[224,1133,335],{"class":331},[224,1135,355],{"class":331},[224,1137,335],{"class":331},[224,1139,464],{"class":338},[224,1141,335],{"class":331},[224,1143,344],{"class":331},[224,1145,335],{"class":331},[224,1147,350],{"class":349},[224,1149,335],{"class":331},[224,1151,355],{"class":331},[224,1153,335],{"class":331},[224,1155,682],{"class":338},[224,1157,335],{"class":331},[224,1159,344],{"class":331},[224,1161,335],{"class":331},[224,1163,438],{"class":349},[224,1165,335],{"class":331},[224,1167,355],{"class":331},[224,1169,335],{"class":331},[224,1171,481],{"class":338},[224,1173,335],{"class":331},[224,1175,344],{"class":331},[224,1177,335],{"class":331},[224,1179,1180],{"class":349},"Store lines to context store",[224,1182,335],{"class":331},[224,1184,355],{"class":331},[224,1186,335],{"class":331},[224,1188,960],{"class":338},[224,1190,335],{"class":331},[224,1192,965],{"class":331},[224,1194,335],{"class":331},[224,1196,970],{"class":509},[224,1198,335],{"class":331},[224,1200,344],{"class":331},[224,1202,335],{"class":331},[224,1204,1205],{"class":349},"set",[224,1207,335],{"class":331},[224,1209,355],{"class":331},[224,1211,335],{"class":331},[224,1213,12],{"class":509},[224,1215,335],{"class":331},[224,1217,344],{"class":331},[224,1219,335],{"class":331},[224,1221,933],{"class":349},[224,1223,335],{"class":331},[224,1225,355],{"class":331},[224,1227,335],{"class":331},[224,1229,1230],{"class":509},"pt",[224,1232,335],{"class":331},[224,1234,344],{"class":331},[224,1236,335],{"class":331},[224,1238,951],{"class":349},[224,1240,335],{"class":331},[224,1242,355],{"class":331},[224,1244,335],{"class":331},[224,1246,1247],{"class":509},"to",[224,1249,335],{"class":331},[224,1251,344],{"class":331},[224,1253,335],{"class":331},[224,1255,332],{"class":349},[224,1257,1259],{"class":1258},"sTEyZ","\\\"",[224,1261,1262],{"class":349},"value",[224,1264,1259],{"class":1258},[224,1266,344],{"class":349},[224,1268,1259],{"class":1258},[224,1270,1271],{"class":349},"T1",[224,1273,1259],{"class":1258},[224,1275,355],{"class":349},[224,1277,1259],{"class":1258},[224,1279,378],{"class":349},[224,1281,1259],{"class":1258},[224,1283,344],{"class":349},[224,1285,1259],{"class":1258},[224,1287,1271],{"class":349},[224,1289,1259],{"class":1258},[224,1291,628],{"class":349},[224,1293,1259],{"class":1258},[224,1295,1262],{"class":349},[224,1297,1259],{"class":1258},[224,1299,344],{"class":349},[224,1301,1259],{"class":1258},[224,1303,1304],{"class":349},"T2",[224,1306,1259],{"class":1258},[224,1308,355],{"class":349},[224,1310,1259],{"class":1258},[224,1312,378],{"class":349},[224,1314,1259],{"class":1258},[224,1316,344],{"class":349},[224,1318,1259],{"class":1258},[224,1320,1304],{"class":349},[224,1322,1259],{"class":1258},[224,1324,1325],{"class":349},"}]",[224,1327,335],{"class":331},[224,1329,355],{"class":331},[224,1331,335],{"class":331},[224,1333,1334],{"class":509},"tot",[224,1336,335],{"class":331},[224,1338,344],{"class":331},[224,1340,335],{"class":331},[224,1342,324],{"class":349},[224,1344,335],{"class":331},[224,1346,1019],{"class":331},[224,1348,335],{"class":331},[224,1350,1351],{"class":338},"action",[224,1353,335],{"class":331},[224,1355,344],{"class":331},[224,1357,413],{"class":331},[224,1359,355],{"class":331},[224,1361,335],{"class":331},[224,1363,924],{"class":338},[224,1365,335],{"class":331},[224,1367,344],{"class":331},[224,1369,413],{"class":331},[224,1371,355],{"class":331},[224,1373,335],{"class":331},[224,1375,1376],{"class":338},"from",[224,1378,335],{"class":331},[224,1380,344],{"class":331},[224,1382,413],{"class":331},[224,1384,355],{"class":331},[224,1386,335],{"class":331},[224,1388,1247],{"class":338},[224,1390,335],{"class":331},[224,1392,344],{"class":331},[224,1394,413],{"class":331},[224,1396,355],{"class":331},[224,1398,335],{"class":331},[224,1400,1401],{"class":338},"reg",[224,1403,335],{"class":331},[224,1405,401],{"class":331},[224,1407,335],{"class":331},[224,1409,575],{"class":338},[224,1411,335],{"class":331},[224,1413,344],{"class":331},[224,1415,1416],{"class":582},"1140",[224,1418,355],{"class":331},[224,1420,335],{"class":331},[224,1422,590],{"class":338},[224,1424,335],{"class":331},[224,1426,344],{"class":331},[224,1428,1084],{"class":582},[224,1430,355],{"class":331},[224,1432,335],{"class":331},[224,1434,815],{"class":338},[224,1436,335],{"class":331},[224,1438,1439],{"class":331},":[[]]},{",[224,1441,335],{"class":331},[224,1443,339],{"class":338},[224,1445,335],{"class":331},[224,1447,344],{"class":331},[224,1449,335],{"class":331},[224,1451,556],{"class":349},[224,1453,335],{"class":331},[224,1455,355],{"class":331},[224,1457,335],{"class":331},[224,1459,360],{"class":338},[224,1461,335],{"class":331},[224,1463,344],{"class":331},[224,1465,335],{"class":331},[224,1467,866],{"class":349},[224,1469,335],{"class":331},[224,1471,355],{"class":331},[224,1473,335],{"class":331},[224,1475,464],{"class":338},[224,1477,335],{"class":331},[224,1479,344],{"class":331},[224,1481,335],{"class":331},[224,1483,350],{"class":349},[224,1485,335],{"class":331},[224,1487,355],{"class":331},[224,1489,335],{"class":331},[224,1491,682],{"class":338},[224,1493,335],{"class":331},[224,1495,344],{"class":331},[224,1497,335],{"class":331},[224,1499,438],{"class":349},[224,1501,335],{"class":331},[224,1503,355],{"class":331},[224,1505,335],{"class":331},[224,1507,481],{"class":338},[224,1509,335],{"class":331},[224,1511,344],{"class":331},[224,1513,335],{"class":331},[224,1515,1516],{"class":349},"Is departments undefined?",[224,1518,335],{"class":331},[224,1520,355],{"class":331},[224,1522,335],{"class":331},[224,1524,924],{"class":338},[224,1526,335],{"class":331},[224,1528,344],{"class":331},[224,1530,335],{"class":331},[224,1532,1533],{"class":349},"#:(persistent)::departments",[224,1535,335],{"class":331},[224,1537,355],{"class":331},[224,1539,335],{"class":331},[224,1541,942],{"class":338},[224,1543,335],{"class":331},[224,1545,344],{"class":331},[224,1547,335],{"class":331},[224,1549,951],{"class":349},[224,1551,335],{"class":331},[224,1553,355],{"class":331},[224,1555,335],{"class":331},[224,1557,960],{"class":338},[224,1559,335],{"class":331},[224,1561,965],{"class":331},[224,1563,335],{"class":331},[224,1565,970],{"class":509},[224,1567,335],{"class":331},[224,1569,344],{"class":331},[224,1571,335],{"class":331},[224,1573,979],{"class":349},[224,1575,335],{"class":331},[224,1577,355],{"class":331},[224,1579,335],{"class":331},[224,1581,988],{"class":509},[224,1583,335],{"class":331},[224,1585,344],{"class":331},[224,1587,335],{"class":331},[224,1589,997],{"class":349},[224,1591,335],{"class":331},[224,1593,355],{"class":331},[224,1595,335],{"class":331},[224,1597,1006],{"class":509},[224,1599,335],{"class":331},[224,1601,344],{"class":331},[224,1603,335],{"class":331},[224,1605,997],{"class":349},[224,1607,335],{"class":331},[224,1609,1019],{"class":331},[224,1611,335],{"class":331},[224,1613,1024],{"class":338},[224,1615,335],{"class":331},[224,1617,344],{"class":331},[224,1619,335],{"class":331},[224,1621,1033],{"class":349},[224,1623,335],{"class":331},[224,1625,355],{"class":331},[224,1627,335],{"class":331},[224,1629,1042],{"class":338},[224,1631,335],{"class":331},[224,1633,401],{"class":331},[224,1635,335],{"class":331},[224,1637,1051],{"class":338},[224,1639,335],{"class":331},[224,1641,344],{"class":331},[224,1643,1058],{"class":582},[224,1645,355],{"class":331},[224,1647,335],{"class":331},[224,1649,575],{"class":338},[224,1651,335],{"class":331},[224,1653,344],{"class":331},[224,1655,1656],{"class":582},"800",[224,1658,355],{"class":331},[224,1660,335],{"class":331},[224,1662,590],{"class":338},[224,1664,335],{"class":331},[224,1666,344],{"class":331},[224,1668,1669],{"class":582},"120",[224,1671,355],{"class":331},[224,1673,335],{"class":331},[224,1675,815],{"class":338},[224,1677,335],{"class":331},[224,1679,820],{"class":331},[224,1681,335],{"class":331},[224,1683,565],{"class":349},[224,1685,335],{"class":331},[224,1687,837],{"class":331},[224,1689,335],{"class":331},[224,1691,339],{"class":338},[224,1693,335],{"class":331},[224,1695,344],{"class":331},[224,1697,335],{"class":331},[224,1699,565],{"class":349},[224,1701,335],{"class":331},[224,1703,355],{"class":331},[224,1705,335],{"class":331},[224,1707,360],{"class":338},[224,1709,335],{"class":331},[224,1711,344],{"class":331},[224,1713,335],{"class":331},[224,1715,1131],{"class":349},[224,1717,335],{"class":331},[224,1719,355],{"class":331},[224,1721,335],{"class":331},[224,1723,464],{"class":338},[224,1725,335],{"class":331},[224,1727,344],{"class":331},[224,1729,335],{"class":331},[224,1731,350],{"class":349},[224,1733,335],{"class":331},[224,1735,355],{"class":331},[224,1737,335],{"class":331},[224,1739,682],{"class":338},[224,1741,335],{"class":331},[224,1743,344],{"class":331},[224,1745,335],{"class":331},[224,1747,438],{"class":349},[224,1749,335],{"class":331},[224,1751,355],{"class":331},[224,1753,335],{"class":331},[224,1755,481],{"class":338},[224,1757,335],{"class":331},[224,1759,344],{"class":331},[224,1761,335],{"class":331},[224,1763,1764],{"class":349},"Store departments to context store",[224,1766,335],{"class":331},[224,1768,355],{"class":331},[224,1770,335],{"class":331},[224,1772,960],{"class":338},[224,1774,335],{"class":331},[224,1776,965],{"class":331},[224,1778,335],{"class":331},[224,1780,970],{"class":509},[224,1782,335],{"class":331},[224,1784,344],{"class":331},[224,1786,335],{"class":331},[224,1788,1205],{"class":349},[224,1790,335],{"class":331},[224,1792,355],{"class":331},[224,1794,335],{"class":331},[224,1796,12],{"class":509},[224,1798,335],{"class":331},[224,1800,344],{"class":331},[224,1802,335],{"class":331},[224,1804,1533],{"class":349},[224,1806,335],{"class":331},[224,1808,355],{"class":331},[224,1810,335],{"class":331},[224,1812,1230],{"class":509},[224,1814,335],{"class":331},[224,1816,344],{"class":331},[224,1818,335],{"class":331},[224,1820,951],{"class":349},[224,1822,335],{"class":331},[224,1824,355],{"class":331},[224,1826,335],{"class":331},[224,1828,1247],{"class":509},[224,1830,335],{"class":331},[224,1832,344],{"class":331},[224,1834,335],{"class":331},[224,1836,332],{"class":349},[224,1838,1259],{"class":1258},[224,1840,1262],{"class":349},[224,1842,1259],{"class":1258},[224,1844,344],{"class":349},[224,1846,1259],{"class":1258},[224,1848,1849],{"class":349},"Maintenance",[224,1851,1259],{"class":1258},[224,1853,355],{"class":349},[224,1855,1259],{"class":1258},[224,1857,378],{"class":349},[224,1859,1259],{"class":1258},[224,1861,344],{"class":349},[224,1863,1259],{"class":1258},[224,1865,1849],{"class":349},[224,1867,1259],{"class":1258},[224,1869,628],{"class":349},[224,1871,1259],{"class":1258},[224,1873,1262],{"class":349},[224,1875,1259],{"class":1258},[224,1877,344],{"class":349},[224,1879,1259],{"class":1258},[224,1881,1882],{"class":349},"Stores",[224,1884,1259],{"class":1258},[224,1886,355],{"class":349},[224,1888,1259],{"class":1258},[224,1890,378],{"class":349},[224,1892,1259],{"class":1258},[224,1894,344],{"class":349},[224,1896,1259],{"class":1258},[224,1898,1882],{"class":349},[224,1900,1259],{"class":1258},[224,1902,628],{"class":349},[224,1904,1259],{"class":1258},[224,1906,1262],{"class":349},[224,1908,1259],{"class":1258},[224,1910,344],{"class":349},[224,1912,1259],{"class":1258},[224,1914,1915],{"class":349},"Quality",[224,1917,1259],{"class":1258},[224,1919,355],{"class":349},[224,1921,1259],{"class":1258},[224,1923,378],{"class":349},[224,1925,1259],{"class":1258},[224,1927,344],{"class":349},[224,1929,1259],{"class":1258},[224,1931,1915],{"class":349},[224,1933,1259],{"class":1258},[224,1935,1325],{"class":349},[224,1937,335],{"class":331},[224,1939,355],{"class":331},[224,1941,335],{"class":331},[224,1943,1334],{"class":509},[224,1945,335],{"class":331},[224,1947,344],{"class":331},[224,1949,335],{"class":331},[224,1951,324],{"class":349},[224,1953,335],{"class":331},[224,1955,1019],{"class":331},[224,1957,335],{"class":331},[224,1959,1351],{"class":338},[224,1961,335],{"class":331},[224,1963,344],{"class":331},[224,1965,413],{"class":331},[224,1967,355],{"class":331},[224,1969,335],{"class":331},[224,1971,924],{"class":338},[224,1973,335],{"class":331},[224,1975,344],{"class":331},[224,1977,413],{"class":331},[224,1979,355],{"class":331},[224,1981,335],{"class":331},[224,1983,1376],{"class":338},[224,1985,335],{"class":331},[224,1987,344],{"class":331},[224,1989,413],{"class":331},[224,1991,355],{"class":331},[224,1993,335],{"class":331},[224,1995,1247],{"class":338},[224,1997,335],{"class":331},[224,1999,344],{"class":331},[224,2001,413],{"class":331},[224,2003,355],{"class":331},[224,2005,335],{"class":331},[224,2007,1401],{"class":338},[224,2009,335],{"class":331},[224,2011,401],{"class":331},[224,2013,335],{"class":331},[224,2015,575],{"class":338},[224,2017,335],{"class":331},[224,2019,344],{"class":331},[224,2021,2022],{"class":582},"1170",[224,2024,355],{"class":331},[224,2026,335],{"class":331},[224,2028,590],{"class":338},[224,2030,335],{"class":331},[224,2032,344],{"class":331},[224,2034,1669],{"class":582},[224,2036,355],{"class":331},[224,2038,335],{"class":331},[224,2040,815],{"class":338},[224,2042,335],{"class":331},[224,2044,2045],{"class":331},":[[]]}]\n",[173,2047,2048,2051],{},[48,2049,2050],{},"Import the provided demo flow.",[48,2052,2053,2055],{},[32,2054,290],{}," the flow.",[12,2057,2058,2059,2062],{},"This will store demo lines and departments in the global context as ",[133,2060,2061],{},"global.lines"," if not already present.",[94,2064,56],{"id":2065},"build-line-selection-menu",[12,2067,2068],{},"Now, let us create a new page and menu item for Production Lines. This page will list all currently available production lines, making it easier to navigate through them.",[173,2070,2071,2078,2093,2099],{},[48,2072,2073,2074,2077],{},"Drag a ",[32,2075,2076],{},"ui-event"," node onto the canvas to detect page navigation.",[48,2079,2073,2080,2082,2083],{},[32,2081,1131],{}," node and configure it to:\n",[45,2084,2085],{},[48,2086,205,2087,209,2090],{},[133,2088,2089],{},"msg.payload.lines",[133,2091,2092],{},"global.get(\"lines\")",[48,2094,2073,2095,2098],{},[32,2096,2097],{},"ui-template"," node onto the canvas. Create a new page with name “Line Menu” and a group.",[48,2100,2101],{},"Paste the following into the template:",[215,2103,2107],{"className":2104,"code":2105,"language":2106,"meta":220,"style":220},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003Cv-container>\n    \u003Cv-row>\n      \u003Cv-col>\n        \u003Ch3>Production Lines\u003C\u002Fh3>\n      \u003C\u002Fv-col>\n    \u003C\u002Fv-row>\n\n    \u003Cv-row class=\"scrollable-row\" no-gutters>\n      \u003Cv-col v-for=\"(btn, index) in lines\" :key=\"index\" cols=\"auto\">\n        \u003Cv-btn :href=\"`\u002Fdashboard\u002Flines?line=${btn.value}`\" class=\"custom-btn\" rounded>\n          {{ btn.label }}\n        \u003C\u002Fv-btn>\n      \u003C\u002Fv-col>\n    \u003C\u002Fv-row>\n\n    \u003Cv-alert v-if=\"selectedLine\" type=\"success\" class=\"mt-3\">\n      Selected Line: {{ selectedLine }}\n    \u003C\u002Fv-alert>\n  \u003C\u002Fv-container>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n  data() {\n    return {\n      selectedLine: '',\n      lines: []\n    };\n  },\n  methods: {\n    updateButtonContent(data) {\n      this.lines = (data.lines || []).sort((a, b) => a.label.localeCompare(b.label));\n    }\n  },\n  mounted() {\n    this.lines = [];\n    this.$socket.on('msg-input:' + this.id, (msg) => {\n      this.updateButtonContent(msg.payload);\n    });\n  }\n};\n\u003C\u002Fscript>\n\n\u003Cstyle scoped>\n.scrollable-row {\n  display: flex;\n  overflow-x: auto;\n  padding: 10px 0;\n  flex-wrap: wrap;\n}\n.scrollable-row .v-col {\n  flex-shrink: 0;\n  margin-bottom: 10px;\n}\n.scrollable-row {\n  min-height: 60px;\n}\n.custom-btn {\n  background-color: rgb(32, 44, 52) !important;\n  color: white !important;\n  margin-right: 12px;\n  padding: 8px 16px;\n}\n.custom-btn:hover {\n  background-color: rgb(54, 70, 86) !important;\n}\n\u003C\u002Fstyle>\n","html",[133,2108,2109,2121,2131,2141,2151,2171,2180,2189,2195,2219,2264,2300,2306,2316,2325,2334,2339,2384,2390,2399,2409,2418,2423,2433,2446,2457,2465,2479,2490,2496,2502,2512,2530,2606,2612,2617,2627,2642,2686,2707,2717,2723,2729,2738,2743,2755,2764,2778,2791,2807,2820,2826,2840,2852,2864,2869,2878,2891,2896,2905,2938,2954,2967,2982,2987,3001,3031,3036],{"__ignoreMap":220},[224,2110,2111,2114,2118],{"class":226,"line":227},[224,2112,2113],{"class":331},"\u003C",[224,2115,2117],{"class":2116},"swJcz","template",[224,2119,2120],{"class":331},">\n",[224,2122,2123,2126,2129],{"class":226,"line":233},[224,2124,2125],{"class":331},"  \u003C",[224,2127,2128],{"class":2116},"v-container",[224,2130,2120],{"class":331},[224,2132,2133,2136,2139],{"class":226,"line":239},[224,2134,2135],{"class":331},"    \u003C",[224,2137,2138],{"class":2116},"v-row",[224,2140,2120],{"class":331},[224,2142,2143,2146,2149],{"class":226,"line":245},[224,2144,2145],{"class":331},"      \u003C",[224,2147,2148],{"class":2116},"v-col",[224,2150,2120],{"class":331},[224,2152,2153,2156,2158,2161,2164,2167,2169],{"class":226,"line":251},[224,2154,2155],{"class":331},"        \u003C",[224,2157,94],{"class":2116},[224,2159,2160],{"class":331},">",[224,2162,2163],{"class":1258},"Production Lines",[224,2165,2166],{"class":331},"\u003C\u002F",[224,2168,94],{"class":2116},[224,2170,2120],{"class":331},[224,2172,2173,2176,2178],{"class":226,"line":257},[224,2174,2175],{"class":331},"      \u003C\u002F",[224,2177,2148],{"class":2116},[224,2179,2120],{"class":331},[224,2181,2182,2185,2187],{"class":226,"line":263},[224,2183,2184],{"class":331},"    \u003C\u002F",[224,2186,2138],{"class":2116},[224,2188,2120],{"class":331},[224,2190,2191],{"class":226,"line":269},[224,2192,2194],{"emptyLinePlaceholder":2193},true,"\n",[224,2196,2197,2199,2201,2204,2207,2209,2212,2214,2217],{"class":226,"line":275},[224,2198,2135],{"class":331},[224,2200,2138],{"class":2116},[224,2202,2203],{"class":338}," class",[224,2205,2206],{"class":331},"=",[224,2208,335],{"class":331},[224,2210,2211],{"class":349},"scrollable-row",[224,2213,335],{"class":331},[224,2215,2216],{"class":338}," no-gutters",[224,2218,2120],{"class":331},[224,2220,2222,2224,2226,2229,2231,2233,2236,2238,2241,2243,2245,2248,2250,2253,2255,2257,2260,2262],{"class":226,"line":2221},10,[224,2223,2145],{"class":331},[224,2225,2148],{"class":2116},[224,2227,2228],{"class":338}," v-for",[224,2230,2206],{"class":331},[224,2232,335],{"class":331},[224,2234,2235],{"class":349},"(btn, index) in lines",[224,2237,335],{"class":331},[224,2239,2240],{"class":338}," :key",[224,2242,2206],{"class":331},[224,2244,335],{"class":331},[224,2246,2247],{"class":349},"index",[224,2249,335],{"class":331},[224,2251,2252],{"class":338}," cols",[224,2254,2206],{"class":331},[224,2256,335],{"class":331},[224,2258,2259],{"class":349},"auto",[224,2261,335],{"class":331},[224,2263,2120],{"class":331},[224,2265,2267,2269,2272,2275,2277,2279,2282,2284,2286,2288,2290,2293,2295,2298],{"class":226,"line":2266},11,[224,2268,2155],{"class":331},[224,2270,2271],{"class":2116},"v-btn",[224,2273,2274],{"class":338}," :href",[224,2276,2206],{"class":331},[224,2278,335],{"class":331},[224,2280,2281],{"class":349},"`\u002Fdashboard\u002Flines?line=${btn.value}`",[224,2283,335],{"class":331},[224,2285,2203],{"class":338},[224,2287,2206],{"class":331},[224,2289,335],{"class":331},[224,2291,2292],{"class":349},"custom-btn",[224,2294,335],{"class":331},[224,2296,2297],{"class":338}," rounded",[224,2299,2120],{"class":331},[224,2301,2303],{"class":226,"line":2302},12,[224,2304,2305],{"class":1258},"          {{ btn.label }}\n",[224,2307,2309,2312,2314],{"class":226,"line":2308},13,[224,2310,2311],{"class":331},"        \u003C\u002F",[224,2313,2271],{"class":2116},[224,2315,2120],{"class":331},[224,2317,2319,2321,2323],{"class":226,"line":2318},14,[224,2320,2175],{"class":331},[224,2322,2148],{"class":2116},[224,2324,2120],{"class":331},[224,2326,2328,2330,2332],{"class":226,"line":2327},15,[224,2329,2184],{"class":331},[224,2331,2138],{"class":2116},[224,2333,2120],{"class":331},[224,2335,2337],{"class":226,"line":2336},16,[224,2338,2194],{"emptyLinePlaceholder":2193},[224,2340,2342,2344,2347,2350,2352,2354,2357,2359,2362,2364,2366,2369,2371,2373,2375,2377,2380,2382],{"class":226,"line":2341},17,[224,2343,2135],{"class":331},[224,2345,2346],{"class":2116},"v-alert",[224,2348,2349],{"class":338}," v-if",[224,2351,2206],{"class":331},[224,2353,335],{"class":331},[224,2355,2356],{"class":349},"selectedLine",[224,2358,335],{"class":331},[224,2360,2361],{"class":338}," type",[224,2363,2206],{"class":331},[224,2365,335],{"class":331},[224,2367,2368],{"class":349},"success",[224,2370,335],{"class":331},[224,2372,2203],{"class":338},[224,2374,2206],{"class":331},[224,2376,335],{"class":331},[224,2378,2379],{"class":349},"mt-3",[224,2381,335],{"class":331},[224,2383,2120],{"class":331},[224,2385,2387],{"class":226,"line":2386},18,[224,2388,2389],{"class":1258},"      Selected Line: {{ selectedLine }}\n",[224,2391,2393,2395,2397],{"class":226,"line":2392},19,[224,2394,2184],{"class":331},[224,2396,2346],{"class":2116},[224,2398,2120],{"class":331},[224,2400,2402,2405,2407],{"class":226,"line":2401},20,[224,2403,2404],{"class":331},"  \u003C\u002F",[224,2406,2128],{"class":2116},[224,2408,2120],{"class":331},[224,2410,2412,2414,2416],{"class":226,"line":2411},21,[224,2413,2166],{"class":331},[224,2415,2117],{"class":2116},[224,2417,2120],{"class":331},[224,2419,2421],{"class":226,"line":2420},22,[224,2422,2194],{"emptyLinePlaceholder":2193},[224,2424,2426,2428,2431],{"class":226,"line":2425},23,[224,2427,2113],{"class":331},[224,2429,2430],{"class":2116},"script",[224,2432,2120],{"class":331},[224,2434,2436,2440,2443],{"class":226,"line":2435},24,[224,2437,2439],{"class":2438},"s7zQu","export",[224,2441,2442],{"class":2438}," default",[224,2444,2445],{"class":331}," {\n",[224,2447,2449,2452,2455],{"class":226,"line":2448},25,[224,2450,2451],{"class":2116},"  data",[224,2453,2454],{"class":331},"()",[224,2456,2445],{"class":331},[224,2458,2460,2463],{"class":226,"line":2459},26,[224,2461,2462],{"class":2438},"    return",[224,2464,2445],{"class":331},[224,2466,2468,2471,2473,2476],{"class":226,"line":2467},27,[224,2469,2470],{"class":2116},"      selectedLine",[224,2472,344],{"class":331},[224,2474,2475],{"class":331}," ''",[224,2477,2478],{"class":331},",\n",[224,2480,2482,2485,2487],{"class":226,"line":2481},28,[224,2483,2484],{"class":2116},"      lines",[224,2486,344],{"class":331},[224,2488,2489],{"class":2116}," []\n",[224,2491,2493],{"class":226,"line":2492},29,[224,2494,2495],{"class":331},"    };\n",[224,2497,2499],{"class":226,"line":2498},30,[224,2500,2501],{"class":331},"  },\n",[224,2503,2505,2508,2510],{"class":226,"line":2504},31,[224,2506,2507],{"class":2116},"  methods",[224,2509,344],{"class":331},[224,2511,2445],{"class":331},[224,2513,2515,2518,2521,2525,2528],{"class":226,"line":2514},32,[224,2516,2517],{"class":2116},"    updateButtonContent",[224,2519,2520],{"class":331},"(",[224,2522,2524],{"class":2523},"sHdIc","data",[224,2526,2527],{"class":331},")",[224,2529,2445],{"class":331},[224,2531,2533,2536,2539,2542,2545,2547,2549,2551,2554,2557,2559,2563,2565,2567,2569,2571,2574,2576,2579,2582,2584,2586,2588,2591,2593,2596,2598,2600,2603],{"class":226,"line":2532},33,[224,2534,2535],{"class":331},"      this.",[224,2537,2538],{"class":1258},"lines",[224,2540,2541],{"class":331}," =",[224,2543,2544],{"class":2116}," (",[224,2546,2524],{"class":1258},[224,2548,291],{"class":331},[224,2550,2538],{"class":1258},[224,2552,2553],{"class":331}," ||",[224,2555,2556],{"class":2116}," [])",[224,2558,291],{"class":331},[224,2560,2562],{"class":2561},"s2Zo4","sort",[224,2564,2520],{"class":2116},[224,2566,2520],{"class":331},[224,2568,16],{"class":2523},[224,2570,355],{"class":331},[224,2572,2573],{"class":2523}," b",[224,2575,2527],{"class":331},[224,2577,2578],{"class":338}," =>",[224,2580,2581],{"class":1258}," a",[224,2583,291],{"class":331},[224,2585,378],{"class":1258},[224,2587,291],{"class":331},[224,2589,2590],{"class":2561},"localeCompare",[224,2592,2520],{"class":2116},[224,2594,2595],{"class":1258},"b",[224,2597,291],{"class":331},[224,2599,378],{"class":1258},[224,2601,2602],{"class":2116},"))",[224,2604,2605],{"class":331},";\n",[224,2607,2609],{"class":226,"line":2608},34,[224,2610,2611],{"class":331},"    }\n",[224,2613,2615],{"class":226,"line":2614},35,[224,2616,2501],{"class":331},[224,2618,2620,2623,2625],{"class":226,"line":2619},36,[224,2621,2622],{"class":2116},"  mounted",[224,2624,2454],{"class":331},[224,2626,2445],{"class":331},[224,2628,2630,2633,2635,2637,2640],{"class":226,"line":2629},37,[224,2631,2632],{"class":331},"    this.",[224,2634,2538],{"class":1258},[224,2636,2541],{"class":331},[224,2638,2639],{"class":2116}," []",[224,2641,2605],{"class":331},[224,2643,2645,2647,2650,2652,2655,2657,2660,2663,2665,2668,2671,2673,2675,2677,2680,2682,2684],{"class":226,"line":2644},38,[224,2646,2632],{"class":331},[224,2648,2649],{"class":1258},"$socket",[224,2651,291],{"class":331},[224,2653,2654],{"class":2561},"on",[224,2656,2520],{"class":2116},[224,2658,2659],{"class":331},"'",[224,2661,2662],{"class":349},"msg-input:",[224,2664,2659],{"class":331},[224,2666,2667],{"class":331}," +",[224,2669,2670],{"class":331}," this.",[224,2672,339],{"class":1258},[224,2674,355],{"class":331},[224,2676,2544],{"class":331},[224,2678,2679],{"class":2523},"msg",[224,2681,2527],{"class":331},[224,2683,2578],{"class":338},[224,2685,2445],{"class":331},[224,2687,2689,2691,2694,2696,2698,2700,2703,2705],{"class":226,"line":2688},39,[224,2690,2535],{"class":331},[224,2692,2693],{"class":2561},"updateButtonContent",[224,2695,2520],{"class":2116},[224,2697,2679],{"class":1258},[224,2699,291],{"class":331},[224,2701,2702],{"class":1258},"payload",[224,2704,2527],{"class":2116},[224,2706,2605],{"class":331},[224,2708,2710,2713,2715],{"class":226,"line":2709},40,[224,2711,2712],{"class":331},"    }",[224,2714,2527],{"class":2116},[224,2716,2605],{"class":331},[224,2718,2720],{"class":226,"line":2719},41,[224,2721,2722],{"class":331},"  }\n",[224,2724,2726],{"class":226,"line":2725},42,[224,2727,2728],{"class":331},"};\n",[224,2730,2732,2734,2736],{"class":226,"line":2731},43,[224,2733,2166],{"class":331},[224,2735,2430],{"class":2116},[224,2737,2120],{"class":331},[224,2739,2741],{"class":226,"line":2740},44,[224,2742,2194],{"emptyLinePlaceholder":2193},[224,2744,2746,2748,2750,2753],{"class":226,"line":2745},45,[224,2747,2113],{"class":331},[224,2749,499],{"class":2116},[224,2751,2752],{"class":338}," scoped",[224,2754,2120],{"class":331},[224,2756,2758,2760,2762],{"class":226,"line":2757},46,[224,2759,291],{"class":331},[224,2761,2211],{"class":509},[224,2763,2445],{"class":331},[224,2765,2767,2771,2773,2776],{"class":226,"line":2766},47,[224,2768,2770],{"class":2769},"sqsOY","  display",[224,2772,344],{"class":331},[224,2774,2775],{"class":1258}," flex",[224,2777,2605],{"class":331},[224,2779,2781,2784,2786,2789],{"class":226,"line":2780},48,[224,2782,2783],{"class":2769},"  overflow-x",[224,2785,344],{"class":331},[224,2787,2788],{"class":1258}," auto",[224,2790,2605],{"class":331},[224,2792,2794,2797,2799,2802,2805],{"class":226,"line":2793},49,[224,2795,2796],{"class":2769},"  padding",[224,2798,344],{"class":331},[224,2800,2801],{"class":582}," 10px",[224,2803,2804],{"class":582}," 0",[224,2806,2605],{"class":331},[224,2808,2810,2813,2815,2818],{"class":226,"line":2809},50,[224,2811,2812],{"class":2769},"  flex-wrap",[224,2814,344],{"class":331},[224,2816,2817],{"class":1258}," wrap",[224,2819,2605],{"class":331},[224,2821,2823],{"class":226,"line":2822},51,[224,2824,2825],{"class":331},"}\n",[224,2827,2829,2831,2833,2836,2838],{"class":226,"line":2828},52,[224,2830,291],{"class":331},[224,2832,2211],{"class":509},[224,2834,2835],{"class":331}," .",[224,2837,2148],{"class":509},[224,2839,2445],{"class":331},[224,2841,2843,2846,2848,2850],{"class":226,"line":2842},53,[224,2844,2845],{"class":2769},"  flex-shrink",[224,2847,344],{"class":331},[224,2849,2804],{"class":582},[224,2851,2605],{"class":331},[224,2853,2855,2858,2860,2862],{"class":226,"line":2854},54,[224,2856,2857],{"class":2769},"  margin-bottom",[224,2859,344],{"class":331},[224,2861,2801],{"class":582},[224,2863,2605],{"class":331},[224,2865,2867],{"class":226,"line":2866},55,[224,2868,2825],{"class":331},[224,2870,2872,2874,2876],{"class":226,"line":2871},56,[224,2873,291],{"class":331},[224,2875,2211],{"class":509},[224,2877,2445],{"class":331},[224,2879,2881,2884,2886,2889],{"class":226,"line":2880},57,[224,2882,2883],{"class":2769},"  min-height",[224,2885,344],{"class":331},[224,2887,2888],{"class":582}," 60px",[224,2890,2605],{"class":331},[224,2892,2894],{"class":226,"line":2893},58,[224,2895,2825],{"class":331},[224,2897,2899,2901,2903],{"class":226,"line":2898},59,[224,2900,291],{"class":331},[224,2902,2292],{"class":509},[224,2904,2445],{"class":331},[224,2906,2908,2911,2913,2916,2918,2921,2923,2926,2928,2931,2933,2936],{"class":226,"line":2907},60,[224,2909,2910],{"class":2769},"  background-color",[224,2912,344],{"class":331},[224,2914,2915],{"class":2561}," rgb",[224,2917,2520],{"class":331},[224,2919,2920],{"class":582},"32",[224,2922,355],{"class":331},[224,2924,2925],{"class":582}," 44",[224,2927,355],{"class":331},[224,2929,2930],{"class":582}," 52",[224,2932,2527],{"class":331},[224,2934,2935],{"class":582}," !important",[224,2937,2605],{"class":331},[224,2939,2941,2944,2946,2949,2952],{"class":226,"line":2940},61,[224,2942,2943],{"class":2769},"  color",[224,2945,344],{"class":331},[224,2947,2948],{"class":1258}," white ",[224,2950,2951],{"class":582},"!important",[224,2953,2605],{"class":331},[224,2955,2957,2960,2962,2965],{"class":226,"line":2956},62,[224,2958,2959],{"class":2769},"  margin-right",[224,2961,344],{"class":331},[224,2963,2964],{"class":582}," 12px",[224,2966,2605],{"class":331},[224,2968,2970,2972,2974,2977,2980],{"class":226,"line":2969},63,[224,2971,2796],{"class":2769},[224,2973,344],{"class":331},[224,2975,2976],{"class":582}," 8px",[224,2978,2979],{"class":582}," 16px",[224,2981,2605],{"class":331},[224,2983,2985],{"class":226,"line":2984},64,[224,2986,2825],{"class":331},[224,2988,2990,2992,2994,2996,2999],{"class":226,"line":2989},65,[224,2991,291],{"class":331},[224,2993,2292],{"class":509},[224,2995,344],{"class":331},[224,2997,2998],{"class":338},"hover",[224,3000,2445],{"class":331},[224,3002,3004,3006,3008,3010,3012,3015,3017,3020,3022,3025,3027,3029],{"class":226,"line":3003},66,[224,3005,2910],{"class":2769},[224,3007,344],{"class":331},[224,3009,2915],{"class":2561},[224,3011,2520],{"class":331},[224,3013,3014],{"class":582},"54",[224,3016,355],{"class":331},[224,3018,3019],{"class":582}," 70",[224,3021,355],{"class":331},[224,3023,3024],{"class":582}," 86",[224,3026,2527],{"class":331},[224,3028,2935],{"class":582},[224,3030,2605],{"class":331},[224,3032,3034],{"class":226,"line":3033},67,[224,3035,2825],{"class":331},[224,3037,3039,3041,3043],{"class":226,"line":3038},68,[224,3040,2166],{"class":331},[224,3042,499],{"class":2116},[224,3044,2120],{"class":331},[173,3046,3047],{"start":251},[48,3048,3049],{},"Deploy the flow.",[12,3051,3052],{},"Once deployed, the dashboard will show buttons for each production line. Clicking a line redirects the user to a page with following url:",[215,3054,3059],{"className":3055,"code":3057,"language":3058},[3056],"language-text","https:\u002F\u002F\u003Cyour-instance-name>\u002Fdashboard\u002Flines?line=T1\n","text",[133,3060,3057],{"__ignoreMap":220},[12,3062,3063,3067],{},[295,3064],{"alt":3065,"dataZoomable":220,"src":3066},"Node-RED editor showing the flow setup for generating a menu of production lines using ui-event, change, and ui-template nodes.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fmenu-for-lines-flow.png",[300,3068,3069],{},"Node-RED flow to create a dynamic menu for production lines on the dashboard.",[12,3071,3072,3076],{},[295,3073],{"alt":3074,"dataZoomable":220,"src":3075},"FlowFuse Dashboard displaying styled buttons for each production line, enabling quick navigation to specific line pages.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fmenu-for-lines.png",[300,3077,3078],{},"Dashboard view showing production line buttons generated from the flow.",[12,3080,3081],{},"The \"line\" URL parameter will be used in the next section to store the user's selected production line.",[94,3083,59],{"id":3084},"enable-url-based-dashboard-access",[12,3086,3087],{},"In this section, we’ll build a flow that allows users to directly access the dashboard using a URL with a line parameter (e.g., ?line=T1). The flow will validate this parameter and store the selected line for each user session. If the parameter is missing or invalid, the user will be redirected to a Not Found page.",[12,3089,3090],{},"To achieve this, we need to:",[45,3092,3093,3096,3099],{},[48,3094,3095],{},"Configure the dashboard to expose client-specific metadata.",[48,3097,3098],{},"Create a flow that validates the line parameter from the URL.",[48,3100,3101],{},"Store the user’s selected line using session-aware context data.",[3103,3104,3106],"h4",{"id":3105},"configuring-dashboard-widgets-to-include-client-information","Configuring Dashboard Widgets to Include Client Information",[12,3108,3109],{},"To ensure client data is available in your flows, follow these steps:",[173,3111,3112,3119,3126,3132,3154],{},[48,3113,3114,3115,3118],{},"Open the ",[32,3116,3117],{},"Dashboard 2.0"," sidebar.",[48,3120,3121,3122,3125],{},"Switch to the ",[32,3123,3124],{},"Client Data"," tab.",[48,3127,3128,3129,291],{},"Enable the option ",[32,3130,3131],{},"“Include client data”",[48,3133,3134,3135],{},"Tick the checkbox in front of:\n",[45,3136,3137,3140,3142,3145,3148,3151],{},[48,3138,3139],{},"ui-control",[48,3141,2097],{},[48,3143,3144],{},"ui-button",[48,3146,3147],{},"ui-text-input",[48,3149,3150],{},"ui-dropdown",[48,3152,3153],{},"ui-notification",[48,3155,3156,3158],{},[32,3157,290],{}," the updated configuration.",[12,3160,3161,3165],{},[295,3162],{"alt":3163,"dataZoomable":220,"src":3164},"Enabling client data in the Dashboard 2.0 settings to include metadata from specific widgets.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fclient-data-configuration.png",[300,3166,3167],{},"Dashboard 2.0 settings to include client metadata from selected widgets like buttons and templates.",[12,3169,3170,3171,3174],{},"With this setting enabled, the selected widgets will include client-related metadata in their output messages under the ",[133,3172,3173],{},"msg._client"," property. This metadata is essential for building session-aware features in the Dashboard.",[3103,3176,3178],{"id":3177},"building-a-dashboard-flow-for-url-access-line-validation-and-user-selection","Building a Dashboard Flow for URL Access, Line Validation, and User Selection",[12,3180,3181],{},"In this section, we'll build a Node-RED flow that handles dashboard access via direct URLs, validates the line parameter, and stores the selected line per user session using client metadata. This ensures that each user's line selection is tracked independently and that invalid or missing parameters are handled gracefully.",[12,3183,3184],{},"The flow performs the following key tasks:",[45,3186,3187,3190,3193,3196],{},[48,3188,3189],{},"Detects when a user accesses the dashboard using a URL containing a line parameter.",[48,3191,3192],{},"Validates the parameter against a list of predefined production lines.",[48,3194,3195],{},"Stores the selected line using session-aware (client-specific) data.",[48,3197,3198],{},"Redirects the user appropriately based on the validity of the parameter.",[12,3200,3201],{},[32,3202,3203],{},"Steps to Build the Flow:",[173,3205,3206,3212,3229,3249,3254],{},[48,3207,2073,3208,3211],{},[32,3209,3210],{},"ui-event node"," onto the canvas and configure it with the correct UI base path.",[48,3213,2073,3214,3217,3218,3221,3222],{},[32,3215,3216],{},"switch node"," and name it \"Is it a pageview event?\" and configure it with the property ",[133,3219,3220],{},"msg.topic"," and add the following condition:",[45,3223,3224],{},[48,3225,3226],{},[133,3227,3228],{},"== $pageview",[48,3230,3231,3232,3234,3235,3238,3239],{},"Drag another ",[32,3233,3216],{}," and name it \"Has line key?\" and configure it with the property ",[133,3236,3237],{},"msg.payload.page.params.line",", with two conditions:",[45,3240,3241,3246],{},[48,3242,3243,3244],{},"has key ",[133,3245,226],{},[48,3247,3248],{},"is empty",[48,3250,281,3251,3253],{},[32,3252,3210],{}," to the first switch node (labeled Is it a pageview event?). Then, connect the first output of this switch node to the second switch node (labeled Has line key?). This checks whether the page was accessed via URL and if a line parameter is present.",[48,3255,2073,3256,3259,3260],{},[133,3257,3258],{},"function"," node and name it \"Extract Labels from Lines\" and paste the following code:",[215,3261,3265],{"className":3262,"code":3263,"language":3264,"meta":220,"style":220},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","let lines = global.get('lines', 'persistent') || [];\nlet labels = [\n   ...lines.map(obj => obj.label),\n];\nmsg.payload.labels = labels;\nreturn msg;\n","javascript",[133,3266,3267,3313,3325,3354,3361,3381],{"__ignoreMap":220},[224,3268,3269,3272,3275,3277,3280,3282,3285,3287,3289,3291,3293,3295,3298,3301,3303,3306,3309,3311],{"class":226,"line":227},[224,3270,3271],{"class":338},"let",[224,3273,3274],{"class":1258}," lines ",[224,3276,2206],{"class":331},[224,3278,3279],{"class":1258}," global",[224,3281,291],{"class":331},[224,3283,3284],{"class":2561},"get",[224,3286,2520],{"class":1258},[224,3288,2659],{"class":331},[224,3290,2538],{"class":349},[224,3292,2659],{"class":331},[224,3294,355],{"class":331},[224,3296,3297],{"class":331}," '",[224,3299,3300],{"class":349},"persistent",[224,3302,2659],{"class":331},[224,3304,3305],{"class":1258},") ",[224,3307,3308],{"class":331},"||",[224,3310,2639],{"class":1258},[224,3312,2605],{"class":331},[224,3314,3315,3317,3320,3322],{"class":226,"line":233},[224,3316,3271],{"class":338},[224,3318,3319],{"class":1258}," labels ",[224,3321,2206],{"class":331},[224,3323,3324],{"class":1258}," [\n",[224,3326,3327,3330,3332,3334,3337,3339,3342,3344,3347,3349,3352],{"class":226,"line":239},[224,3328,3329],{"class":331},"   ...",[224,3331,2538],{"class":1258},[224,3333,291],{"class":331},[224,3335,3336],{"class":2561},"map",[224,3338,2520],{"class":1258},[224,3340,3341],{"class":2523},"obj",[224,3343,2578],{"class":338},[224,3345,3346],{"class":1258}," obj",[224,3348,291],{"class":331},[224,3350,3351],{"class":1258},"label)",[224,3353,2478],{"class":331},[224,3355,3356,3359],{"class":226,"line":245},[224,3357,3358],{"class":1258},"]",[224,3360,2605],{"class":331},[224,3362,3363,3365,3367,3369,3371,3374,3376,3379],{"class":226,"line":251},[224,3364,2679],{"class":1258},[224,3366,291],{"class":331},[224,3368,2702],{"class":1258},[224,3370,291],{"class":331},[224,3372,3373],{"class":1258},"labels ",[224,3375,2206],{"class":331},[224,3377,3378],{"class":1258}," labels",[224,3380,2605],{"class":331},[224,3382,3383,3386,3389],{"class":226,"line":257},[224,3384,3385],{"class":2438},"return",[224,3387,3388],{"class":1258}," msg",[224,3390,2605],{"class":331},[12,3392,3393],{},"This retrieves the list of available lines from the persistent global context, extracts their labels, and creates an array for easier verification of whether the user selected line is present.",[173,3395,3396,3412],{"start":257},[48,3397,2073,3398,3401,3402],{},[32,3399,3400],{},"change node"," and name it \"Store line selection\":\n",[45,3403,3404],{},[48,3405,205,3406,209,3409,291],{},[133,3407,3408],{},"global.store[msg._client.socketId].line",[133,3410,3411],{},"msg.payload",[48,3413,3231,3414,3416],{},[32,3415,3216],{}," and name it \"Is the currently accessed page 'Lines'?\":",[45,3418,3419],{},[48,3420,3421],{},"is equal to \"Lines\"",[173,3423,3424,3436,3452,3470],{"start":269},[48,3425,281,3426,3429,3430,3432,3433,3435],{},[32,3427,3428],{},"function node"," (Extract Labels from Lines) and the ",[32,3431,3400],{}," (Store line selection) to the first output of the ",[32,3434,3216],{}," (Has line key?).",[48,3437,3231,3438,3440,3441,3444,3445],{},[133,3439,866],{}," node and name it \"Is line valid?\" and set the property to ",[133,3442,3443],{},"msg.payload.labels"," and add following conditions:\n",[45,3446,3447],{},[48,3448,3449,3450],{},"contains ",[133,3451,3408],{},[48,3453,3454,3455,3457,3458,3460,3461],{},"For the first output of the ",[133,3456,866],{}," node (Is the currently accessed page 'Lines'?), drag a ",[32,3459,1131],{}," node and name it \"Redirect the user to the All Lines menu\" and Configure it to:\n",[45,3462,3463],{},[48,3464,205,3465,209,3467],{},[133,3466,3411],{},[133,3468,3469],{},"\"All Lines\"",[48,3471,2073,3472,3475,3476,3478],{},[32,3473,3474],{},"ui-control node"," onto the canvas and connect it to the ",[32,3477,3400],{}," (Redirect the user to the All Lines menu). This node will handle the redirection or display feedback on the dashboard.",[12,3480,3481],{},"This checks whether the selected line is valid by comparing it with the list of known line labels.",[173,3483,3484],{"start":2302},[48,3485,3486,3487,3490],{},"For the second output of the switch node (Is line valid?), drag a switch node and give it name \"Is the currently accessed page 'Lines'?\" and Set property to ",[133,3488,3489],{},"msg.payload.page.name"," and add following condition to check against:",[45,3492,3493,3496],{},[48,3494,3495],{},"== \"Lines\"",[48,3497,3498],{},"Otherwise",[173,3500,3501,3507,3510],{"start":2308},[48,3502,3503,3504,3506],{},"For the first output of the switch node ((Is the currently accessed page 'Lines'?), drag a change node and configure it to:\n- Set ",[133,3505,3411],{}," to \"Incorrect Link\"",[48,3508,3509],{},"Drag a ui-control node onto the canvas and configure it with the correct UI base path and connect it the change node (Redirect to Not found page).",[48,3511,3512],{},"Deploy the changes.",[12,3514,3515,3519],{},[295,3516],{"alt":3517,"dataZoomable":220,"src":3518},"Flow for handling dashboard navigation, validating URL parameters, and assigning selected production lines to individual client sessions.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Faccessing-production-lines.png",[300,3520,3521],{},"Flow for managing URL-based access, validating line parameters, and storing client-specific selections on the OEE dashboard.",[94,3523,3525],{"id":3524},"create-live-request-flow-per-line","Create Live Request Flow (Per Line)",[12,3527,3528],{},"Let’s build the flow to retrieve the data now based on the user selection.",[173,3530,3531,3537,3540,3547,3692,3698,3718,3723,3728,3740,3746,3749],{},[48,3532,2073,3533,3536],{},[133,3534,3535],{},"Template"," widget onto the canvas.",[48,3538,3539],{},"Double-click the Template widget to open its configuration.",[48,3541,3542,3543,3546],{},"Set the scope to ",[133,3544,3545],{},"ui"," and select the appropriate UI Base.",[48,3548,3549,3550],{},"Paste the following script into the content field. This script triggers every second and sends a message that includes the current user's client data:",[215,3551,3553],{"className":2104,"code":3552,"language":2106,"meta":220,"style":220},"\u003Cscript>\n  export default {\n    mounted() {\n      \u002F\u002F Set an interval to update the message every second\n      this.intervalId = setInterval(() => {\n        this.send('Component has loaded');\n      }, 1000);\n    },\n    beforeUnmount() {\n      \u002F\u002F Clear the interval when the component is about to be destroyed\n      clearInterval(this.intervalId);\n    },\n  };\n\u003C\u002Fscript>\n",[133,3554,3555,3563,3572,3581,3587,3607,3628,3640,3645,3654,3659,3675,3679,3684],{"__ignoreMap":220},[224,3556,3557,3559,3561],{"class":226,"line":227},[224,3558,2113],{"class":331},[224,3560,2430],{"class":2116},[224,3562,2120],{"class":331},[224,3564,3565,3568,3570],{"class":226,"line":233},[224,3566,3567],{"class":2438},"  export",[224,3569,2442],{"class":2438},[224,3571,2445],{"class":331},[224,3573,3574,3577,3579],{"class":226,"line":239},[224,3575,3576],{"class":2116},"    mounted",[224,3578,2454],{"class":331},[224,3580,2445],{"class":331},[224,3582,3583],{"class":226,"line":245},[224,3584,3586],{"class":3585},"sHwdD","      \u002F\u002F Set an interval to update the message every second\n",[224,3588,3589,3591,3594,3596,3599,3601,3603,3605],{"class":226,"line":251},[224,3590,2535],{"class":331},[224,3592,3593],{"class":1258},"intervalId",[224,3595,2541],{"class":331},[224,3597,3598],{"class":2561}," setInterval",[224,3600,2520],{"class":2116},[224,3602,2454],{"class":331},[224,3604,2578],{"class":338},[224,3606,2445],{"class":331},[224,3608,3609,3612,3615,3617,3619,3622,3624,3626],{"class":226,"line":257},[224,3610,3611],{"class":331},"        this.",[224,3613,3614],{"class":2561},"send",[224,3616,2520],{"class":2116},[224,3618,2659],{"class":331},[224,3620,3621],{"class":349},"Component has loaded",[224,3623,2659],{"class":331},[224,3625,2527],{"class":2116},[224,3627,2605],{"class":331},[224,3629,3630,3633,3636,3638],{"class":226,"line":263},[224,3631,3632],{"class":331},"      },",[224,3634,3635],{"class":582}," 1000",[224,3637,2527],{"class":2116},[224,3639,2605],{"class":331},[224,3641,3642],{"class":226,"line":269},[224,3643,3644],{"class":331},"    },\n",[224,3646,3647,3650,3652],{"class":226,"line":275},[224,3648,3649],{"class":2116},"    beforeUnmount",[224,3651,2454],{"class":331},[224,3653,2445],{"class":331},[224,3655,3656],{"class":226,"line":2221},[224,3657,3658],{"class":3585},"      \u002F\u002F Clear the interval when the component is about to be destroyed\n",[224,3660,3661,3664,3666,3669,3671,3673],{"class":226,"line":2266},[224,3662,3663],{"class":2561},"      clearInterval",[224,3665,2520],{"class":2116},[224,3667,3668],{"class":331},"this.",[224,3670,3593],{"class":1258},[224,3672,2527],{"class":2116},[224,3674,2605],{"class":331},[224,3676,3677],{"class":226,"line":2302},[224,3678,3644],{"class":331},[224,3680,3681],{"class":226,"line":2308},[224,3682,3683],{"class":331},"  };\n",[224,3685,3686,3688,3690],{"class":226,"line":2318},[224,3687,2166],{"class":331},[224,3689,2430],{"class":2116},[224,3691,2120],{"class":331},[48,3693,2073,3694,3697],{},[133,3695,3696],{},"Change"," node and name it \"Set params\".",[48,3699,3700,3701],{},"Configure the Change node with the following rules:",[45,3702,3703,3710],{},[48,3704,205,3705,209,3708],{},[133,3706,3707],{},"msg.params.$line",[133,3709,3408],{},[48,3711,205,3712,209,3715],{},[133,3713,3714],{},"msg.query",[133,3716,3717],{},"\"line\"",[48,3719,2073,3720,3722],{},[133,3721,3535],{}," node onto the canvas.",[48,3724,3725,3726,291],{},"Double-click the Template node and set the property to ",[133,3727,3220],{},[48,3729,3730,3731],{},"Paste the following SQL query into the content field:",[215,3732,3734],{"className":217,"code":3733,"language":219,"meta":220,"style":220},"SELECT * FROM requests WHERE \"{{query}}\" = \"{{line}}\" AND resolved IS NULL\n",[133,3735,3736],{"__ignoreMap":220},[224,3737,3738],{"class":226,"line":227},[224,3739,3733],{},[48,3741,2073,3742,3745],{},[133,3743,3744],{},"Markdown"," widget and name it \"Show currently selected line\".",[48,3747,3748],{},"Create a new group in the UI for the Markdown widget to render into.",[48,3750,3751,3752],{},"Enter the following content into the Markdown widget:",[215,3753,3755],{"className":2104,"code":3754,"language":2106,"meta":220,"style":220},"\u003Ch1 style=\"text-align: center;\">Line: {{ msg?.line }}\u003C\u002Fh1>\n",[133,3756,3757],{"__ignoreMap":220},[224,3758,3759,3761,3764,3767,3769,3771,3774,3776,3778,3781,3783,3785],{"class":226,"line":227},[224,3760,2113],{"class":331},[224,3762,3763],{"class":2116},"h1",[224,3765,3766],{"class":338}," style",[224,3768,2206],{"class":331},[224,3770,335],{"class":331},[224,3772,3773],{"class":349},"text-align: center;",[224,3775,335],{"class":331},[224,3777,2160],{"class":331},[224,3779,3780],{"class":1258},"Line: {{ msg?.line }}",[224,3782,2166],{"class":331},[224,3784,3763],{"class":2116},[224,3786,2120],{"class":331},[12,3788,3789,3793],{},[295,3790],{"alt":3791,"dataZoomable":220,"src":3792},"Dashboard view showing the title of the selected production line centered at the top.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Flines-page-with-tittle-of-selected-line.png",[300,3794,3795],{},"The dashboard displays the selected production line name, retrieved from the client context, rendered using a Markdown widget.",[173,3797,3798,3802,3805,3808,3822,3830],{"start":2308},[48,3799,2073,3800,3722],{},[133,3801,186],{},[48,3803,3804],{},"Select the appropriate database configuration.",[48,3806,3807],{},"Set the node to use the SQL query via \"Prepared Statement\".",[48,3809,281,3810,3812,3813,3815,3816,3818,3819,3821],{},[133,3811,3535],{}," widget to ",[133,3814,3696],{}," node and ",[133,3817,3535],{}," node to ",[133,3820,186],{}," node.",[48,3823,2073,3824,3827,3828,3821],{},[133,3825,3826],{},"link-out"," node onto the canvas and connect it to the ",[133,3829,186],{},[48,3831,3512],{},[12,3833,3834,3838],{},[295,3835],{"alt":3836,"dataZoomable":220,"src":3837},"Node-RED flow to fetch live requests for a selected production line using client context and SQLite query.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fretrive-data.png",[300,3839,3840],{},"Flow that triggers periodic queries for open requests specific to the user’s selected line using the client session and a SQLite database.",[94,3842,3844],{"id":3843},"preparing-data-rendering-it-in-a-table","Preparing Data Rendering it in a Table",[12,3846,3847],{},"Once the data is retrieved, it needs to be validated, formatted, and routed appropriately for display. In this section, a flow will be built to check whether any unresolved requests exist for the selected production line. If there are no requests, a message will be shown to the user. Otherwise, the data will be processed and rendered in a table format using Dashboard widgets.",[173,3849,3850,3859,3884,3898,3904,3918,3924,3930,3939,3947,3953,3961,3968],{},[48,3851,2073,3852,3855,3856,291],{},[32,3853,3854],{},"link-in node"," onto the canvas and connect it to the last ",[32,3857,3858],{},"link-out node",[48,3860,3861,3862,3864,3865,3867,3868],{},"Add a ",[32,3863,3216],{}," to check whether the ",[133,3866,3411],{}," is empty, name it \"Is Payload empty?\".",[45,3869,3870],{},[48,3871,3872,3873],{},"Configure the switch with the following conditions:\n",[45,3874,3875,3880],{},[48,3876,3877],{},[133,3878,3879],{},"msg.payload is empty",[48,3881,3882],{},[133,3883,3498],{},[48,3885,2073,3886,3888,3889],{},[32,3887,3400],{},", name it \"Show 'no outstanding request' message\" and configure it to set a message when the payload is empty:",[45,3890,3891],{},[48,3892,205,3893,209,3895],{},[133,3894,3411],{},[133,3896,3897],{},"\"There are no outstanding requests\"",[48,3899,3900,3901,3903],{},"Connect this ",[32,3902,3400],{}," to the first output of the switch node (\"Is Payload empty?\").",[48,3905,3231,3906,3908,3909],{},[32,3907,3400],{},", name it \"Remove 'no outstanding request' message\" and configure it as follows:",[45,3910,3911],{},[48,3912,205,3913,3915,3916],{},[133,3914,3411],{}," to an empty string ",[133,3917,413],{},[48,3919,3920,3921,3923],{},"Connect this second ",[32,3922,3400],{}," to the second output of the switch node (\"Is Payload empty?\").",[48,3925,2073,3926,3929],{},[32,3927,3928],{},"text widget",", name it \"Text Widget for Message\", onto the canvas, double-click it, and add a new group in the \"Lines\" page to render the message.",[48,3931,281,3932,3934,3935,3938],{},[32,3933,3928],{}," (\"Text Widget for Message\") to both ",[32,3936,3937],{},"change nodes"," that are setting the text message (\"Show 'no outstanding request' message\" and \"Remove 'no outstanding request' message\").",[48,3940,3231,3941,3943,3944,3946],{},[32,3942,3858],{}," onto the canvas and connect it to the second output of the switch node (\"Is Payload empty?\") that checks whether ",[133,3945,3411],{}," is empty.",[48,3948,3231,3949,3952],{},[32,3950,3951],{},"link-in"," onto the canvas.",[48,3954,2073,3955,3958,3959,291],{},[32,3956,3957],{},"split node",", name it \"Split Node\", onto the canvas and connect it to the ",[32,3960,3854],{},[48,3962,2073,3963,3965,3966,291],{},[32,3964,3858],{}," and connect it to the ",[32,3967,3957],{},[48,3969,3512],{},[12,3971,3972,3976],{},[295,3973],{"alt":3974,"dataZoomable":220,"src":3975},"Flow that checks if unresolved requests exist, sends an appropriate message when none are found, or prepares the data for tabular rendering","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fpreparing-data.png",[300,3977,3978],{},"Flow that checks if unresolved requests exist, sends an appropriate message when none are found, or prepares the data for tabular rendering.",[94,3980,68],{"id":3981},"setting-up-visual-alerts-and-timestamp-formatting",[12,3983,3984],{},"To enhance the visibility of production line requests, this section focuses on setting up visual alerts based on the age of each request and formatting timestamps in a user-friendly way. The created timestamp is always shown using relative time (e.g., \"5 minutes ago\"). For acknowledged and resolved, relative formatting is applied only when those timestamps are available. This improves readability and makes it easier to identify requests that are pending action.",[173,3986,3987,3998],{},[48,3988,2073,3989,3991,3992,3994,3995,3997],{},[32,3990,3854],{}," and a ",[32,3993,3428],{}," onto the canvas. Name the ",[32,3996,3428],{}," as \"Highlight Old Requests\" and open it.",[48,3999,4000,4001,344],{},"Paste the following JavaScript code into the ",[32,4002,3428],{},[215,4004,4006],{"className":3262,"code":4005,"language":3264,"meta":220,"style":220},"const requested = msg.payload.requested;\nconst now = Date.now();\n\nconst requestedTime = new Date(requested).getTime();\nconst difference = now - requestedTime;\n\nconst oldRequestThreshold = global.get('oldRequestThreshold');\nconst veryOldRequestThreshold = global.get('veryOldRequestThreshold');\nconst alertActivationThreshold = global.get('alertActivationThreshold');\n\nif (difference > (veryOldRequestThreshold * 60 * 1000)) {\n   msg.payload.class = 'older';\n   if (difference > (alertActivationThreshold * 60 * 1000)) {\n       msg.payload.alert = true;\n   }\n   return msg;\n}\nelse if (difference > (oldRequestThreshold * 60 * 1000)) {\n   msg.payload.class = 'old';\n   if (difference > (alertActivationThreshold * 60 * 1000)) {\n       msg.payload.alert = true;\n   }\n   return msg;\n}\nelse {\n   if (difference > (alertActivationThreshold * 60 * 1000)) {\n       msg.payload.alert = true;\n   }\n   msg.payload.class = 'normal';\n   return msg;\n}\n",[133,4007,4008,4031,4052,4056,4082,4101,4105,4133,4161,4189,4193,4223,4248,4277,4299,4304,4313,4317,4344,4367,4393,4411,4415,4423,4427,4433,4459,4477,4481,4504,4512],{"__ignoreMap":220},[224,4009,4010,4013,4016,4018,4020,4022,4024,4026,4029],{"class":226,"line":227},[224,4011,4012],{"class":338},"const",[224,4014,4015],{"class":1258}," requested ",[224,4017,2206],{"class":331},[224,4019,3388],{"class":1258},[224,4021,291],{"class":331},[224,4023,2702],{"class":1258},[224,4025,291],{"class":331},[224,4027,4028],{"class":1258},"requested",[224,4030,2605],{"class":331},[224,4032,4033,4035,4038,4040,4043,4045,4048,4050],{"class":226,"line":233},[224,4034,4012],{"class":338},[224,4036,4037],{"class":1258}," now ",[224,4039,2206],{"class":331},[224,4041,4042],{"class":1258}," Date",[224,4044,291],{"class":331},[224,4046,4047],{"class":2561},"now",[224,4049,2454],{"class":1258},[224,4051,2605],{"class":331},[224,4053,4054],{"class":226,"line":239},[224,4055,2194],{"emptyLinePlaceholder":2193},[224,4057,4058,4060,4063,4065,4068,4070,4073,4075,4078,4080],{"class":226,"line":245},[224,4059,4012],{"class":338},[224,4061,4062],{"class":1258}," requestedTime ",[224,4064,2206],{"class":331},[224,4066,4067],{"class":331}," new",[224,4069,4042],{"class":2561},[224,4071,4072],{"class":1258},"(requested)",[224,4074,291],{"class":331},[224,4076,4077],{"class":2561},"getTime",[224,4079,2454],{"class":1258},[224,4081,2605],{"class":331},[224,4083,4084,4086,4089,4091,4093,4096,4099],{"class":226,"line":251},[224,4085,4012],{"class":338},[224,4087,4088],{"class":1258}," difference ",[224,4090,2206],{"class":331},[224,4092,4037],{"class":1258},[224,4094,4095],{"class":331},"-",[224,4097,4098],{"class":1258}," requestedTime",[224,4100,2605],{"class":331},[224,4102,4103],{"class":226,"line":257},[224,4104,2194],{"emptyLinePlaceholder":2193},[224,4106,4107,4109,4112,4114,4116,4118,4120,4122,4124,4127,4129,4131],{"class":226,"line":263},[224,4108,4012],{"class":338},[224,4110,4111],{"class":1258}," oldRequestThreshold ",[224,4113,2206],{"class":331},[224,4115,3279],{"class":1258},[224,4117,291],{"class":331},[224,4119,3284],{"class":2561},[224,4121,2520],{"class":1258},[224,4123,2659],{"class":331},[224,4125,4126],{"class":349},"oldRequestThreshold",[224,4128,2659],{"class":331},[224,4130,2527],{"class":1258},[224,4132,2605],{"class":331},[224,4134,4135,4137,4140,4142,4144,4146,4148,4150,4152,4155,4157,4159],{"class":226,"line":269},[224,4136,4012],{"class":338},[224,4138,4139],{"class":1258}," veryOldRequestThreshold ",[224,4141,2206],{"class":331},[224,4143,3279],{"class":1258},[224,4145,291],{"class":331},[224,4147,3284],{"class":2561},[224,4149,2520],{"class":1258},[224,4151,2659],{"class":331},[224,4153,4154],{"class":349},"veryOldRequestThreshold",[224,4156,2659],{"class":331},[224,4158,2527],{"class":1258},[224,4160,2605],{"class":331},[224,4162,4163,4165,4168,4170,4172,4174,4176,4178,4180,4183,4185,4187],{"class":226,"line":275},[224,4164,4012],{"class":338},[224,4166,4167],{"class":1258}," alertActivationThreshold ",[224,4169,2206],{"class":331},[224,4171,3279],{"class":1258},[224,4173,291],{"class":331},[224,4175,3284],{"class":2561},[224,4177,2520],{"class":1258},[224,4179,2659],{"class":331},[224,4181,4182],{"class":349},"alertActivationThreshold",[224,4184,2659],{"class":331},[224,4186,2527],{"class":1258},[224,4188,2605],{"class":331},[224,4190,4191],{"class":226,"line":2221},[224,4192,2194],{"emptyLinePlaceholder":2193},[224,4194,4195,4198,4201,4203,4206,4209,4212,4215,4217,4220],{"class":226,"line":2266},[224,4196,4197],{"class":2438},"if",[224,4199,4200],{"class":1258}," (difference ",[224,4202,2160],{"class":331},[224,4204,4205],{"class":1258}," (veryOldRequestThreshold ",[224,4207,4208],{"class":331},"*",[224,4210,4211],{"class":582}," 60",[224,4213,4214],{"class":331}," *",[224,4216,3635],{"class":582},[224,4218,4219],{"class":1258},")) ",[224,4221,4222],{"class":331},"{\n",[224,4224,4225,4228,4230,4232,4234,4237,4239,4241,4244,4246],{"class":226,"line":2302},[224,4226,4227],{"class":1258},"   msg",[224,4229,291],{"class":331},[224,4231,2702],{"class":1258},[224,4233,291],{"class":331},[224,4235,4236],{"class":1258},"class",[224,4238,2541],{"class":331},[224,4240,3297],{"class":331},[224,4242,4243],{"class":349},"older",[224,4245,2659],{"class":331},[224,4247,2605],{"class":331},[224,4249,4250,4253,4255,4258,4261,4263,4265,4267,4269,4271,4273,4275],{"class":226,"line":2308},[224,4251,4252],{"class":2438},"   if",[224,4254,2544],{"class":2116},[224,4256,4257],{"class":1258},"difference",[224,4259,4260],{"class":331}," >",[224,4262,2544],{"class":2116},[224,4264,4182],{"class":1258},[224,4266,4214],{"class":331},[224,4268,4211],{"class":582},[224,4270,4214],{"class":331},[224,4272,3635],{"class":582},[224,4274,4219],{"class":2116},[224,4276,4222],{"class":331},[224,4278,4279,4282,4284,4286,4288,4291,4293,4297],{"class":226,"line":2318},[224,4280,4281],{"class":1258},"       msg",[224,4283,291],{"class":331},[224,4285,2702],{"class":1258},[224,4287,291],{"class":331},[224,4289,4290],{"class":1258},"alert",[224,4292,2541],{"class":331},[224,4294,4296],{"class":4295},"sfNiH"," true",[224,4298,2605],{"class":331},[224,4300,4301],{"class":226,"line":2327},[224,4302,4303],{"class":331},"   }\n",[224,4305,4306,4309,4311],{"class":226,"line":2336},[224,4307,4308],{"class":2438},"   return",[224,4310,3388],{"class":1258},[224,4312,2605],{"class":331},[224,4314,4315],{"class":226,"line":2341},[224,4316,2825],{"class":331},[224,4318,4319,4322,4325,4327,4329,4332,4334,4336,4338,4340,4342],{"class":226,"line":2386},[224,4320,4321],{"class":2438},"else",[224,4323,4324],{"class":2438}," if",[224,4326,4200],{"class":1258},[224,4328,2160],{"class":331},[224,4330,4331],{"class":1258}," (oldRequestThreshold ",[224,4333,4208],{"class":331},[224,4335,4211],{"class":582},[224,4337,4214],{"class":331},[224,4339,3635],{"class":582},[224,4341,4219],{"class":1258},[224,4343,4222],{"class":331},[224,4345,4346,4348,4350,4352,4354,4356,4358,4360,4363,4365],{"class":226,"line":2392},[224,4347,4227],{"class":1258},[224,4349,291],{"class":331},[224,4351,2702],{"class":1258},[224,4353,291],{"class":331},[224,4355,4236],{"class":1258},[224,4357,2541],{"class":331},[224,4359,3297],{"class":331},[224,4361,4362],{"class":349},"old",[224,4364,2659],{"class":331},[224,4366,2605],{"class":331},[224,4368,4369,4371,4373,4375,4377,4379,4381,4383,4385,4387,4389,4391],{"class":226,"line":2401},[224,4370,4252],{"class":2438},[224,4372,2544],{"class":2116},[224,4374,4257],{"class":1258},[224,4376,4260],{"class":331},[224,4378,2544],{"class":2116},[224,4380,4182],{"class":1258},[224,4382,4214],{"class":331},[224,4384,4211],{"class":582},[224,4386,4214],{"class":331},[224,4388,3635],{"class":582},[224,4390,4219],{"class":2116},[224,4392,4222],{"class":331},[224,4394,4395,4397,4399,4401,4403,4405,4407,4409],{"class":226,"line":2411},[224,4396,4281],{"class":1258},[224,4398,291],{"class":331},[224,4400,2702],{"class":1258},[224,4402,291],{"class":331},[224,4404,4290],{"class":1258},[224,4406,2541],{"class":331},[224,4408,4296],{"class":4295},[224,4410,2605],{"class":331},[224,4412,4413],{"class":226,"line":2420},[224,4414,4303],{"class":331},[224,4416,4417,4419,4421],{"class":226,"line":2425},[224,4418,4308],{"class":2438},[224,4420,3388],{"class":1258},[224,4422,2605],{"class":331},[224,4424,4425],{"class":226,"line":2435},[224,4426,2825],{"class":331},[224,4428,4429,4431],{"class":226,"line":2448},[224,4430,4321],{"class":2438},[224,4432,2445],{"class":331},[224,4434,4435,4437,4439,4441,4443,4445,4447,4449,4451,4453,4455,4457],{"class":226,"line":2459},[224,4436,4252],{"class":2438},[224,4438,2544],{"class":2116},[224,4440,4257],{"class":1258},[224,4442,4260],{"class":331},[224,4444,2544],{"class":2116},[224,4446,4182],{"class":1258},[224,4448,4214],{"class":331},[224,4450,4211],{"class":582},[224,4452,4214],{"class":331},[224,4454,3635],{"class":582},[224,4456,4219],{"class":2116},[224,4458,4222],{"class":331},[224,4460,4461,4463,4465,4467,4469,4471,4473,4475],{"class":226,"line":2467},[224,4462,4281],{"class":1258},[224,4464,291],{"class":331},[224,4466,2702],{"class":1258},[224,4468,291],{"class":331},[224,4470,4290],{"class":1258},[224,4472,2541],{"class":331},[224,4474,4296],{"class":4295},[224,4476,2605],{"class":331},[224,4478,4479],{"class":226,"line":2481},[224,4480,4303],{"class":331},[224,4482,4483,4485,4487,4489,4491,4493,4495,4497,4500,4502],{"class":226,"line":2492},[224,4484,4227],{"class":1258},[224,4486,291],{"class":331},[224,4488,2702],{"class":1258},[224,4490,291],{"class":331},[224,4492,4236],{"class":1258},[224,4494,2541],{"class":331},[224,4496,3297],{"class":331},[224,4498,4499],{"class":349},"normal",[224,4501,2659],{"class":331},[224,4503,2605],{"class":331},[224,4505,4506,4508,4510],{"class":226,"line":2498},[224,4507,4308],{"class":2438},[224,4509,3388],{"class":1258},[224,4511,2605],{"class":331},[224,4513,4514],{"class":226,"line":2504},[224,4515,2825],{"class":331},[173,4517,4518,4521,4535,4538,4541,4555,4558,4569,4572],{"start":239},[48,4519,4520],{},"Connect the link-in node to the function node.",[48,4522,4523,4524],{},"Drag a date time formatter node onto the canvas. Name it \"Format Requested Time\" and double-click it to configure.\n",[45,4525,4526,4529],{},[48,4527,4528],{},"Set outputFrom to fromNow.",[48,4530,4531,4532,291],{},"Set both input and output to ",[133,4533,4534],{},"msg.payload.requested",[48,4536,4537],{},"Connect the function node to the date time formatter node.",[48,4539,4540],{},"Drag a link-out node and connect it to the function node.",[48,4542,4543,4544,4547,4548],{},"Drag a switch node onto the canvas. Name it \"Check if Acknowledged is null\". Set the property to ",[133,4545,4546],{},"msg.payload.acknowledged",", and add the following conditions:\n",[45,4549,4550,4553],{},[48,4551,4552],{},"is null",[48,4554,3498],{},[48,4556,4557],{},"Connect the function node to the switch node.",[48,4559,4560,4561],{},"Drag a second date time formatter node onto the canvas. Name it \"Format Acknowledged Time\".\n",[45,4562,4563,4565],{},[48,4564,4528],{},[48,4566,4531,4567,291],{},[133,4568,4546],{},[48,4570,4571],{},"Connect the second date time formatter node to the second output of the switch node (\"Check if Acknowledged is null\").",[48,4573,4574,4575,4578],{},"Drag another switch node onto the canvas. Name it \"Check if Resolved is null\". set the property to ",[133,4576,4577],{},"msg.payload.resolved",". Add the following conditions:",[45,4580,4581,4583],{},[48,4582,4552],{},[48,4584,3498],{},[173,4586,4587,4590,4595,4598,4601,4604],{"start":2302},[48,4588,4589],{},"Connect this switch node (\"Check if Resolved is null\") to the output of the second date time formatter (\"Format Acknowledged Time\") node and to the first output of the first switch node (\"Check if Acknowledged is null\").",[48,4591,4592,4593,291],{},"Drag a third date time formatter node onto the canvas. Name it \"Format Resolved Time\" and set outputFrom to fromNow. Set both input and output to ",[133,4594,4577],{},[48,4596,4597],{},"Connect this third date time formatter node to the second output of the second switch node (\"Check if Resolved is null\") .",[48,4599,4600],{},"Drag a link-out node and connect it to the third date time formatter node.",[48,4602,4603],{},"Drag another link-out node and connect it to the first output of the second switch node. Name it \"Link to First Switch Output\".",[48,4605,3512],{},[12,4607,4608,4612],{},[295,4609],{"alt":4610,"dataZoomable":220,"src":4611},"Dashboard view displaying a highlighted request entry with visual emphasis based on request age.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fhighlighted-requst.png",[300,4613,4614],{},"Dashboard showing a request visually highlighted based on how long ago it was made, with applied styling and alert classification.",[12,4616,4617,4621],{},[295,4618],{"alt":4619,"dataZoomable":220,"src":4620},"Node-RED flow that includes nodes for assigning visual alert classes and formatting timestamps using relative time.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fvisual-alert-and-timestamp-formatting.png",[300,4622,4623],{},"Flow for setting visual alert classes and formatting timestamps like \"5 minutes ago\" to enhance clarity and urgency of displayed requests.",[37,4625,71],{"id":4626},"highlight-requests-with-css-add-buttons-to-update-request-status",[12,4628,4629,4630,114,4633,4636,4637,4640],{},"We have the data prepared, the class property added to each request message, and the timestamp formatted for better readability. In this section, we will add ",[32,4631,4632],{},"'Resolve'",[32,4634,4635],{},"'Acknowledge'"," buttons for each request to update its status and apply CSS classes based on the ",[133,4638,4639],{},"status"," property for visual highlighting.",[173,4642,4643,4650,4662,4731,4745,4757,4807,4827,4835],{},[48,4644,2073,4645,4647,4648,3821],{},[32,4646,3951],{}," node onto the canvas and connect it to the last ",[32,4649,3826],{},[48,4651,4652,4653,4578,4655],{},"Drag a switch node, name it \"Is acknowledged null?\", and set the property to ",[133,4654,4546],{},[45,4656,4657,4659],{},[48,4658,4552],{},[48,4660,4661],{},"otherwise",[48,4663,2073,4664,4667,4668,4671,4672,4674,4675],{},[32,4665,4666],{},"template node",", name it ",[32,4669,4670],{},"\"Build ack link\"",", set the property to ",[133,4673,4546],{},", and add the following Mustache:",[215,4676,4678],{"className":2104,"code":4677,"language":2106,"meta":220,"style":220},"\u003Ca href=\"\u002Fdashboard\u002Flines?line={{line}}&action=ack&request={{payload.rowid}}\" style=\"color: #000000\" class=\"{{payload.class}}\">ACKNOWLEDGE\u003C\u002Fa>\n",[133,4679,4680],{"__ignoreMap":220},[224,4681,4682,4684,4686,4689,4691,4693,4696,4698,4700,4702,4704,4707,4709,4711,4713,4715,4718,4720,4722,4725,4727,4729],{"class":226,"line":227},[224,4683,2113],{"class":331},[224,4685,16],{"class":2116},[224,4687,4688],{"class":338}," href",[224,4690,2206],{"class":331},[224,4692,335],{"class":331},[224,4694,4695],{"class":349},"\u002Fdashboard\u002Flines?line={{line}}&action=ack&request={{payload.rowid}}",[224,4697,335],{"class":331},[224,4699,3766],{"class":338},[224,4701,2206],{"class":331},[224,4703,335],{"class":331},[224,4705,4706],{"class":349},"color: #000000",[224,4708,335],{"class":331},[224,4710,2203],{"class":338},[224,4712,2206],{"class":331},[224,4714,335],{"class":331},[224,4716,4717],{"class":349},"{{payload.class}}",[224,4719,335],{"class":331},[224,4721,2160],{"class":331},[224,4723,4724],{"class":1258},"ACKNOWLEDGE",[224,4726,2166],{"class":331},[224,4728,16],{"class":2116},[224,4730,2120],{"class":331},[48,4732,281,4733,4735,4736,4738,4739,4742,4743,3821],{},[32,4734,3951],{}," node to the ",[32,4737,866],{}," node. Connect the ",[32,4740,4741],{},"first output"," of the switch node (\"Is acknowledged null?\") to the input of the ",[32,4744,2117],{},[48,4746,4747,4748,4750,4751],{},"Drag another switch node, name it \"Is resolved null?\", set the property to ",[133,4749,4577],{},", and add the following conditions:",[45,4752,4753,4755],{},[48,4754,4552],{},[48,4756,4661],{},[48,4758,2073,4759,4761,4762,4674,4764],{},[32,4760,4666],{},", give it name \"Build res link\",  set the property to ",[133,4763,4577],{},[215,4765,4767],{"className":2104,"code":4766,"language":2106,"meta":220,"style":220},"\u003Ca href=\"\u002Fdashboard\u002Flines?line={{line}}&action=res&request={{payload.rowid}}\" style=\"color: #000000\">RESOLVE\u003C\u002Fa>\n",[133,4768,4769],{"__ignoreMap":220},[224,4770,4771,4773,4775,4777,4779,4781,4784,4786,4788,4790,4792,4794,4796,4798,4801,4803,4805],{"class":226,"line":227},[224,4772,2113],{"class":331},[224,4774,16],{"class":2116},[224,4776,4688],{"class":338},[224,4778,2206],{"class":331},[224,4780,335],{"class":331},[224,4782,4783],{"class":349},"\u002Fdashboard\u002Flines?line={{line}}&action=res&request={{payload.rowid}}",[224,4785,335],{"class":331},[224,4787,3766],{"class":338},[224,4789,2206],{"class":331},[224,4791,335],{"class":331},[224,4793,4706],{"class":349},[224,4795,335],{"class":331},[224,4797,2160],{"class":331},[224,4799,4800],{"class":1258},"RESOLVE",[224,4802,2166],{"class":331},[224,4804,16],{"class":2116},[224,4806,2120],{"class":331},[48,4808,4809,4810,4813,4814,4817,4818,4820,4821,4824,4825,3821],{},"Connect the input of this second switch node (\"Is resolved null?\") to the ",[32,4811,4812],{},"second output"," of the previous switch node (",[133,4815,4816],{},"acknowledged"," switch), then connect the ",[32,4819,4741],{}," of the ",[133,4822,4823],{},"resolved"," switch node to the input of the second ",[32,4826,2117],{},[48,4828,2073,4829,4831,4832,4834],{},[32,4830,3826],{}," node and connect both outputs of the ",[133,4833,4823],{}," switch node to this link-out.",[48,4836,3512],{},[12,4838,4839,4843],{},[295,4840],{"alt":4841,"dataZoomable":220,"src":4842},"Adding 'Acknowledged' and 'Resolved' buttons for each request in the table","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fadd-request-update-button.png",[300,4844,4845],{},"Adding action buttons to update the status of each request directly from the dashboard table.",[94,4847,4849],{"id":4848},"adding-a-mechanism-to-update-the-status-of-a-request-in-the-database","Adding a Mechanism to Update the Status of a Request in the Database",[173,4851,4852,4859,4882,4891,4910,4913,4945,4973],{},[48,4853,4854,4855,4858],{},"Drag ",[32,4856,4857],{},"ui event widget"," onto the canvas and configure it with the correct ui base.",[48,4860,4854,4861,4863,4864],{},[32,4862,3400],{}," onto the canvas and add the following element:",[45,4865,4866,4874],{},[48,4867,205,4868,209,4871],{},[133,4869,4870],{},"msg.params",[133,4872,4873],{},"{}",[48,4875,205,4876,209,4879],{},[133,4877,4878],{},"msg.params.$request",[133,4880,4881],{},"msg.payload.query.request",[48,4883,4854,4884,4887,4888,291],{},[32,4885,4886],{},"Date\u002FTime Formatter node"," onto the canvas and set input format to \"timestamp: milliseconds since epoch\" and output to ",[133,4889,4890],{},"msg.now",[48,4892,4854,4893,4895,4896,4899,4900],{},[32,4894,3216],{}," onto the canvas, set property to ",[133,4897,4898],{},"msg.query.action",", and add the following conditions to check against:",[45,4901,4902,4905,4908],{},[48,4903,4904],{},"== ack",[48,4906,4907],{},"== res",[48,4909,4661],{},[48,4911,4912],{},"Drag two SQLite nodes onto the canvas, select the correct database configuration for both, and set the query type to 'Prepared Statement'.",[48,4914,4915,4916,4919,4920],{},"For the ",[32,4917,4918],{},"first",", set the following sql query:",[215,4921,4923],{"className":217,"code":4922,"language":219,"meta":220,"style":220},"UPDATE requests \nSET acknowledged = $now\nWHERE rowid = $request \nAND acknowledged IS NULL\n",[133,4924,4925,4930,4935,4940],{"__ignoreMap":220},[224,4926,4927],{"class":226,"line":227},[224,4928,4929],{},"UPDATE requests \n",[224,4931,4932],{"class":226,"line":233},[224,4933,4934],{},"SET acknowledged = $now\n",[224,4936,4937],{"class":226,"line":239},[224,4938,4939],{},"WHERE rowid = $request \n",[224,4941,4942],{"class":226,"line":245},[224,4943,4944],{},"AND acknowledged IS NULL\n",[48,4946,4915,4947,4919,4950],{},[32,4948,4949],{},"second",[215,4951,4953],{"className":217,"code":4952,"language":219,"meta":220,"style":220},"UPDATE requests \nSET resolved = $now\nWHERE rowid = $request \nAND resolved IS NULL \n",[133,4954,4955,4959,4964,4968],{"__ignoreMap":220},[224,4956,4957],{"class":226,"line":227},[224,4958,4929],{},[224,4960,4961],{"class":226,"line":233},[224,4962,4963],{},"SET resolved = $now\n",[224,4965,4966],{"class":226,"line":239},[224,4967,4939],{},[224,4969,4970],{"class":226,"line":245},[224,4971,4972],{},"AND resolved IS NULL\n",[48,4974,281,4975,209,4977,4979,4980,209,4982,4979,4985,209,4988,4990],{},[32,4976,4857],{},[32,4978,3400],{},", ",[32,4981,3400],{},[32,4983,4984],{},"date\u002Ftime formatter node",[32,4986,4987],{},"date\u002Ftime formatter",[32,4989,3216],{},", and:",[45,4992,4993,5002],{},[48,4994,4995,4998,4999],{},[32,4996,4997],{},"switch node first output"," to first ",[32,5000,5001],{},"first sqlite node",[48,5003,5004,5007,5008],{},[32,5005,5006],{},"switch node second output"," to second ",[32,5009,5010],{},"second sqlite node",[12,5012,5013,5017,5020],{},[295,5014],{"alt":5015,"dataZoomable":220,"src":5016},"Flow for the mechanism to update request status","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fupdate-request-status.png",[5018,5019],"br",{},[300,5021,5022],{},"Flow that handles the update of request status based on user actions (Acknowledged or Resolved).",[94,5024,65],{"id":5025},"render-request-data-in-a-table",[12,5027,5028,5029,5032],{},"Now, let's display the prepared data in a table. To do this, we'll use a ",[32,5030,5031],{},"ui_table"," widget. However, before displaying, we need to convert the data back into an array, as we are currently spilling array data retrieved from the database into a single message.",[173,5034,5035,5042,5053,5060,5066,5071,5081,5095,5102,5128],{},[48,5036,2073,5037,3827,5039,3821],{},[32,5038,3951],{},[32,5040,5041],{},"last link-out",[48,5043,2073,5044,3827,5047,5049,5050,291],{},[32,5045,5046],{},"join",[32,5048,3951],{}," node. Double-click on the join node and set the mode to ",[32,5051,5052],{},"automatic",[48,5054,3231,5055,5057,5058,3821],{},[32,5056,3826],{}," node and connect it to the ",[32,5059,5046],{},[48,5061,2073,5062,5057,5064,3821],{},[32,5063,3951],{},[32,5065,5041],{},[48,5067,2073,5068,5070],{},[32,5069,5031],{}," widget onto the canvas and double-click to configure.",[48,5072,5073,5074,5077,5078,5080],{},"Create a ",[32,5075,5076],{},"new group"," on the ",[300,5079,2538],{}," page.",[48,5082,205,5083,209,5086,114,5089,209,5092,291],{},[32,5084,5085],{},"Action",[133,5087,5088],{},"replace",[32,5090,5091],{},"Interaction",[133,5093,5094],{},"none",[48,5096,5097,5098,5101],{},"Untick the ",[32,5099,5100],{},"Auto Calculate Columns"," option.",[48,5103,5104,5105],{},"Add the following column elements:",[45,5106,5107,5110,5113,5116,5119,5122,5125],{},[48,5108,5109],{},"Key: rowid, Label: Request, Align: Left, Type: Text",[48,5111,5112],{},"Key: line, Label: Line, Align: Left, Type: Text",[48,5114,5115],{},"Key: support, Label: Support, Align: Left, Type: Text",[48,5117,5118],{},"Key: requested, Label: Requested, Align: Left, Type: HTML",[48,5120,5121],{},"Key: acknowledged, Label: Acknowledged, Align: Left, Type: HTML",[48,5123,5124],{},"Key: resolved, Label: Resolved, Align: Left, Type: HTML",[48,5126,5127],{},"Key: notes, Label: Notes, Align: Left, Type: Text",[48,5129,3512],{},[12,5131,5132,5136],{},[295,5133],{"alt":5134,"dataZoomable":220,"src":5135},"Render Data on table\"","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Frender-data-in-table.png",[300,5137,5138],{},"Render Data on table.",[37,5140,74],{"id":5141},"create-new-request-submission-flow",[12,5143,5144],{},"To create a flow that allows users to submit a request, follow these steps to set up the necessary UI elements, store the request details, validate input, and store the data in a database.",[173,5146,5147,5153,5168,5176,5187,5193,5208,5211,5220,5265,5271],{},[48,5148,5149,5150,5152],{},"Drag the ",[32,5151,2076],{}," widget onto the canvas and configure it with the correct UI settings.",[48,5154,2073,5155,5157,5158],{},[32,5156,3400],{}," to retrieve the department list and name it \"Show Dropdown Options\". Add the following:",[45,5159,5160],{},[48,5161,205,5162,209,5165,291],{},[133,5163,5164],{},"msg.ui_update.options",[133,5166,5167],{},"global.departments",[48,5169,5170,5171,5173,5174,3821],{},"Create a new group for the dropdown widget on the lines page. Connect the ",[32,5172,3400],{}," to the input of the dropdown widget, then link it to the ",[32,5175,2076],{},[48,5177,3231,5178,5180,5181,209,5183,5186],{},[32,5179,3400],{}," and set ",[133,5182,3411],{},[133,5184,5185],{},"msg.store[msg._client.socketId].support",". Name it \"Store support (department) to context store\".",[48,5188,2073,5189,5192],{},[32,5190,5191],{},"text input widget"," for the notes field. Create a group for it in the lines page.",[48,5194,5195,5196,5198,5199],{},"Add another ",[32,5197,3400],{}," to store the notes in the global context and name it \"Store notes to context store\":",[45,5200,5201],{},[48,5202,205,5203,209,5205,291],{},[133,5204,3411],{},[133,5206,5207],{},"msg.store[msg._client.socketId].notes",[48,5209,5210],{},"Connect the change node (\"Store support (department) to context store\") to the input of the dropdown widget and connect the change node (\"Store notes to context store\") to the text input widget.",[48,5212,5149,5213,5216,5217,5219],{},[32,5214,5215],{},"button widget",", label it \"Request Support,\" and connect it to the ",[32,5218,3400],{}," that updates the UI with the department list.",[48,5221,3861,5222,5224,5225],{},[32,5223,3400],{}," to store the request details in the global context and name it \"Retrieve entered support request data\":",[45,5226,5227,5234,5242,5249,5257],{},[48,5228,205,5229,209,5232,291],{},[133,5230,5231],{},"msg.request",[133,5233,4873],{},[48,5235,205,5236,5239,5240,291],{},[133,5237,5238],{},"msg.request.support"," to the value ",[133,5241,5185],{},[48,5243,205,5244,5239,5247,291],{},[133,5245,5246],{},"msg.request.notes",[133,5248,5207],{},[48,5250,205,5251,5239,5254,291],{},[133,5252,5253],{},"msg.request.line",[133,5255,5256],{},"msg.store[msg._client.socketId].line",[48,5258,205,5259,5239,5262,291],{},[133,5260,5261],{},"msg.request.reference",[133,5263,5264],{},"msg.store[msg._client.socketId].reference",[48,5266,5267,5268,5270],{},"Drag the switch node onto the canvas and set property to ",[133,5269,5231],{}," and add condtion to check \"is not null\".",[48,5272,2073,5273,5275],{},[32,5274,3428],{}," and add the following code. Name it \"Does department and notes are not empty?\":",[215,5277,5279],{"className":3262,"code":5278,"language":3264,"meta":220,"style":220},"let request = msg.request;\nif (typeof request !== \"object\" || request === null) {\n   msg.payload = \"Request must be an object.\";\n   return [null, null, msg];\n} else if (!request.hasOwnProperty(\"support\")) {\n   msg.payload = \"Please select the appropriate department for the request.\";\n   return [null, msg, null];\n} else if (!request.hasOwnProperty(\"notes\") || typeof request.notes !== \"string\" || request.notes.trim() === \"\") {\n   msg.payload = \"Please add notes to provide more context on the request.\";\n   return [null, null, msg];\n} else {\n   return [msg, null, null];\n}\n",[133,5280,5281,5299,5335,5354,5373,5408,5427,5445,5521,5540,5556,5564,5582],{"__ignoreMap":220},[224,5282,5283,5285,5288,5290,5292,5294,5297],{"class":226,"line":227},[224,5284,3271],{"class":338},[224,5286,5287],{"class":1258}," request ",[224,5289,2206],{"class":331},[224,5291,3388],{"class":1258},[224,5293,291],{"class":331},[224,5295,5296],{"class":1258},"request",[224,5298,2605],{"class":331},[224,5300,5301,5303,5305,5308,5310,5313,5316,5319,5321,5323,5325,5328,5331,5333],{"class":226,"line":233},[224,5302,4197],{"class":2438},[224,5304,2544],{"class":1258},[224,5306,5307],{"class":331},"typeof",[224,5309,5287],{"class":1258},[224,5311,5312],{"class":331},"!==",[224,5314,5315],{"class":331}," \"",[224,5317,5318],{"class":349},"object",[224,5320,335],{"class":331},[224,5322,2553],{"class":331},[224,5324,5287],{"class":1258},[224,5326,5327],{"class":331},"===",[224,5329,5330],{"class":331}," null",[224,5332,3305],{"class":1258},[224,5334,4222],{"class":331},[224,5336,5337,5339,5341,5343,5345,5347,5350,5352],{"class":226,"line":239},[224,5338,4227],{"class":1258},[224,5340,291],{"class":331},[224,5342,2702],{"class":1258},[224,5344,2541],{"class":331},[224,5346,5315],{"class":331},[224,5348,5349],{"class":349},"Request must be an object.",[224,5351,335],{"class":331},[224,5353,2605],{"class":331},[224,5355,5356,5358,5361,5364,5367,5369,5371],{"class":226,"line":245},[224,5357,4308],{"class":2438},[224,5359,5360],{"class":2116}," [",[224,5362,5363],{"class":331},"null,",[224,5365,5366],{"class":331}," null,",[224,5368,3388],{"class":1258},[224,5370,3358],{"class":2116},[224,5372,2605],{"class":331},[224,5374,5375,5378,5381,5383,5385,5388,5390,5392,5395,5397,5399,5402,5404,5406],{"class":226,"line":251},[224,5376,5377],{"class":331},"}",[224,5379,5380],{"class":2438}," else",[224,5382,4324],{"class":2438},[224,5384,2544],{"class":1258},[224,5386,5387],{"class":331},"!",[224,5389,5296],{"class":1258},[224,5391,291],{"class":331},[224,5393,5394],{"class":2561},"hasOwnProperty",[224,5396,2520],{"class":1258},[224,5398,335],{"class":331},[224,5400,5401],{"class":349},"support",[224,5403,335],{"class":331},[224,5405,4219],{"class":1258},[224,5407,4222],{"class":331},[224,5409,5410,5412,5414,5416,5418,5420,5423,5425],{"class":226,"line":257},[224,5411,4227],{"class":1258},[224,5413,291],{"class":331},[224,5415,2702],{"class":1258},[224,5417,2541],{"class":331},[224,5419,5315],{"class":331},[224,5421,5422],{"class":349},"Please select the appropriate department for the request.",[224,5424,335],{"class":331},[224,5426,2605],{"class":331},[224,5428,5429,5431,5433,5435,5437,5439,5441,5443],{"class":226,"line":263},[224,5430,4308],{"class":2438},[224,5432,5360],{"class":2116},[224,5434,5363],{"class":331},[224,5436,3388],{"class":1258},[224,5438,355],{"class":331},[224,5440,5330],{"class":331},[224,5442,3358],{"class":2116},[224,5444,2605],{"class":331},[224,5446,5447,5449,5451,5453,5455,5457,5459,5461,5463,5465,5467,5470,5472,5474,5476,5479,5482,5484,5487,5489,5491,5494,5496,5498,5500,5502,5504,5506,5509,5512,5514,5517,5519],{"class":226,"line":269},[224,5448,5377],{"class":331},[224,5450,5380],{"class":2438},[224,5452,4324],{"class":2438},[224,5454,2544],{"class":1258},[224,5456,5387],{"class":331},[224,5458,5296],{"class":1258},[224,5460,291],{"class":331},[224,5462,5394],{"class":2561},[224,5464,2520],{"class":1258},[224,5466,335],{"class":331},[224,5468,5469],{"class":349},"notes",[224,5471,335],{"class":331},[224,5473,3305],{"class":1258},[224,5475,3308],{"class":331},[224,5477,5478],{"class":331}," typeof",[224,5480,5481],{"class":1258}," request",[224,5483,291],{"class":331},[224,5485,5486],{"class":1258},"notes ",[224,5488,5312],{"class":331},[224,5490,5315],{"class":331},[224,5492,5493],{"class":349},"string",[224,5495,335],{"class":331},[224,5497,2553],{"class":331},[224,5499,5481],{"class":1258},[224,5501,291],{"class":331},[224,5503,5469],{"class":1258},[224,5505,291],{"class":331},[224,5507,5508],{"class":2561},"trim",[224,5510,5511],{"class":1258},"() ",[224,5513,5327],{"class":331},[224,5515,5516],{"class":331}," \"\"",[224,5518,3305],{"class":1258},[224,5520,4222],{"class":331},[224,5522,5523,5525,5527,5529,5531,5533,5536,5538],{"class":226,"line":275},[224,5524,4227],{"class":1258},[224,5526,291],{"class":331},[224,5528,2702],{"class":1258},[224,5530,2541],{"class":331},[224,5532,5315],{"class":331},[224,5534,5535],{"class":349},"Please add notes to provide more context on the request.",[224,5537,335],{"class":331},[224,5539,2605],{"class":331},[224,5541,5542,5544,5546,5548,5550,5552,5554],{"class":226,"line":2221},[224,5543,4308],{"class":2438},[224,5545,5360],{"class":2116},[224,5547,5363],{"class":331},[224,5549,5366],{"class":331},[224,5551,3388],{"class":1258},[224,5553,3358],{"class":2116},[224,5555,2605],{"class":331},[224,5557,5558,5560,5562],{"class":226,"line":2266},[224,5559,5377],{"class":331},[224,5561,5380],{"class":2438},[224,5563,2445],{"class":331},[224,5565,5566,5568,5570,5572,5574,5576,5578,5580],{"class":226,"line":2302},[224,5567,4308],{"class":2438},[224,5569,5360],{"class":2116},[224,5571,2679],{"class":1258},[224,5573,355],{"class":331},[224,5575,5366],{"class":331},[224,5577,5330],{"class":331},[224,5579,3358],{"class":2116},[224,5581,2605],{"class":331},[224,5583,5584],{"class":226,"line":2308},[224,5585,2825],{"class":331},[173,5587,5588,5598,5605,5610,5616,5621,5626,5629],{"start":2302},[48,5589,5590,5591,5594,5595,291],{},"Connect the change node to switch node and switch node to function node. Connect the function node's first output to a ",[32,5592,5593],{},"Date\u002FTime Formatter"," node. Set the input to 'Timestamp (milliseconds since epoch)' and the output to ",[133,5596,5597],{},"msg.request.time",[48,5599,2073,5600,5180,5602,5604],{},[32,5601,3400],{},[133,5603,3411],{}," to \"Are you sure you want to submit a request?\". Name it \"Set Confirmation message\".",[48,5606,5607,5608,3821],{},"Connect the change node (\"Set Confirmation message\") to the ",[32,5609,5593],{},[48,5611,2073,5612,5615],{},[32,5613,5614],{},"ui-notification widget",", configure it with the correct UI, and set the position to center, checked the checkbox for both allow mnaual dismisal and all amnual confirmation, change close to \"Cancel\".",[48,5617,5607,5618,5620],{},[32,5619,3153],{}," widget.",[48,5622,3231,5623,5625],{},[32,5624,5614],{},", configure it with the correct UI, and set the position to center.",[48,5627,5628],{},"connect it to the second output of the function node.",[48,5630,3861,5631,5633,5634,5636],{},[32,5632,3216],{}," and set the property to ",[133,5635,3411],{}," with the condition:",[45,5638,5639],{},[48,5640,5641,5642,5645],{},"== ",[133,5643,5644],{},"confirm_clicked","\nName it \"Is confirm clicked?\"",[173,5647,5648],{"start":2401},[48,5649,2073,5650,5652],{},[32,5651,3400],{}," and add the following elements and give it name \"Set Params\":",[45,5654,5655,5661,5668,5675,5682],{},[48,5656,205,5657,209,5659,291],{},[133,5658,4870],{},[133,5660,4873],{},[48,5662,205,5663,5239,5665,291],{},[133,5664,3707],{},[133,5666,5667],{},"msg.request.linet",[48,5669,205,5670,5239,5673,291],{},[133,5671,5672],{},"msg.params.$support",[133,5674,5238],{},[48,5676,205,5677,5239,5680,291],{},[133,5678,5679],{},"msg.params.$time",[133,5681,5597],{},[48,5683,205,5684,5239,5687,291],{},[133,5685,5686],{},"msg.params.$notes",[133,5688,5246],{},[173,5690,5691,5694,5700],{"start":2411},[48,5692,5693],{},"Connect the change node (\"Set Params\") to the switch node (\"Is confirm clicked?\").",[48,5695,2073,5696,5699],{},[32,5697,5698],{},"sqlite node",", select the correct database configuration, and choose SQL Query via \"Prepared Statement\" and connect that sqlite node to the input change node (\"Set Params\")",[48,5701,2073,5702,5704],{},[32,5703,3400],{}," and set the following, give it name \"Clear entered request data\":",[45,5706,5707,5712],{},[48,5708,5709,5710,291],{},"Delete ",[133,5711,5185],{},[48,5713,5709,5714,291],{},[133,5715,5207],{},[173,5717,5718,5725,5730,5735],{"start":2435},[48,5719,281,5720,5722,5723,291],{},[32,5721,3400],{},"* (\"Clear entered request data\") to the ",[32,5724,5698],{},[48,5726,2073,5727,5729],{},[32,5728,3858],{}," and connect it to the last change node.",[48,5731,2073,5732,5734],{},[32,5733,3854],{}," and connect it to the last link-out node.",[48,5736,5737,5738,5740],{},"Drag two ",[32,5739,3937],{}," and configure them as follows:",[45,5742,5743,5752],{},[48,5744,5745,5746,5748,5749,291],{},"First change node: Set ",[133,5747,3411],{}," to an empty array ",[133,5750,5751],{},"[]",[48,5753,5754,5755,3915,5757,291],{},"Second change node: Set ",[133,5756,3411],{},[133,5758,413],{},[173,5760,5761,5764,5773],{"start":2481},[48,5762,5763],{},"Connect the change nodes to the link-in node to complete the flow.",[48,5765,5766,5767,5770,5771,291],{},"Connect the first change node to the ",[32,5768,5769],{},"ui dropdown widget"," and the second to the ",[32,5772,5191],{},[48,5774,3512],{},[12,5776,5777,5781],{},[295,5778],{"alt":5779,"dataZoomable":220,"src":5780},"Node-RED flow showing the logic for validating and storing user-submitted support requests.","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fsubmit-request-flow.png",[300,5782,5783],{},"Node-RED flow to handle request submission, including form validation, timestamp formatting, and SQL database insertion.",[12,5785,5786],{},"We have now successfully built one part of the Andon task dashboard. You can open the line view in the dashboard and check whether you can submit a request, mark it as acknowledged, and resolve it.",[12,5788,5789,5793],{},[295,5790],{"alt":5791,"dataZoomable":220,"src":5792},"UI form with dropdown, text input, and a submit button labeled \"Request Support.\"","\u002Fblog\u002F2025\u002F06\u002Fimages\u002Fsubmit-form.png",[300,5794,5795],{},"Dashboard UI where users select a department, enter notes, and submit a support request for the production line.",[37,5797,5799],{"id":5798},"up-next","Up Next",[12,5801,5802],{},"Up until now, the focus has been on building the core functionality of the Andon Task Manager dashboard, including the Lines page. Design and layout have not been the priority. In the next part, you will learn how to enhance the visual design, improve usability, and create a dedicated page and menu for departments.",[12,5804,5805],{},"Later, we will guide you through building the Admin page for the Andon Task Manager dashboard, enabling request management, department configuration, and overall system control.",[499,5807,5808],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":220,"searchDepth":245,"depth":245,"links":5810},[5811,5824,5828,5829],{"id":39,"depth":233,"text":40,"children":5812},[5813,5814,5815,5816,5817,5821,5822,5823],{"id":96,"depth":239,"text":97},{"id":168,"depth":239,"text":50},{"id":312,"depth":239,"text":53},{"id":2065,"depth":239,"text":56},{"id":3084,"depth":239,"text":59,"children":5818},[5819,5820],{"id":3105,"depth":245,"text":3106},{"id":3177,"depth":245,"text":3178},{"id":3524,"depth":239,"text":3525},{"id":3843,"depth":239,"text":3844},{"id":3981,"depth":239,"text":68},{"id":4626,"depth":233,"text":71,"children":5825},[5826,5827],{"id":4848,"depth":239,"text":4849},{"id":5025,"depth":239,"text":65},{"id":5141,"depth":233,"text":74},{"id":5798,"depth":233,"text":5799},null,"2025-06-26","Learn how to build an Andon Task Manager with FlowFuse in this step-by-step guide. Create real-time issue reporting and task tracking systems using Node-RED and FlowFuse Dashboard.","md","\u002Fblog\u002F2025\u002F06\u002Fimages\u002FBuilding-an-Andon-Task-Manager-with-FlowFuse-2.png",{"keywords":5836,"excerpt":5837},"free andon task dashboard, andon task manager dashboard free, building andon task manager, node-red andon task manager, flowfuse andon task manager",{"type":9,"value":5838},[5839],[12,5840,14,5841,20],{},[16,5842,19],{"href":18},"\u002Fblog\u002F2025\u002F06\u002Fbuilding-andon-task-manager-dashboard-with-ff",{"title":5,"description":5832},{"loc":5843},"blog\u002F2025\u002F06\u002Fbuilding-andon-task-manager-dashboard-with-ff","Step-by-step guide to building a real-time issue reporting and task tracking system using FlowFuse.",[5849],"flowfuse","HqxYRX92NsxPj1zTepAFk3lsUsqfAl4VjaLprbyRG90",{"id":5852,"extension":5853,"meta":5854,"sections":5855,"stem":6241,"__hash__":6242},"featureCatalog\u002Ffeature-catalog.yml","yml",{},[5856,5907,6008,6068,6145,6224],{"id":5857,"title":5858,"features":5859},"ai-automation","AI & Automation",[5860,5870,5880,5890,5896,5902],{"id":5861,"title":5862,"description":5863,"docsLink":5864,"changelog":5865,"tiers":5869},"flowfuse-expert-ai","FlowFuse Expert AI","Build industrial apps with agents, and query the state of the factory with an agent. Adapt your current hardware and machines so agentic work can be done against them, without ripping and replacing what's already on the plant floor.","\u002Fdocs\u002Fuser\u002Fexpert\u002F",[5866],{"url":5867,"release":5868},"\u002Fchangelog\u002F2026\u002F02\u002Fff-expert-update-banner\u002F","2.28",{"edge":2193,"hub":2193,"fleet":2193},{"id":5871,"title":5872,"description":5873,"docsLink":5874,"changelog":5875,"subfeature":2193,"showOnPricing":5878,"tiers":5879},"flowfuse-expert-support-mode","Support Mode","Chat-based assistance for FlowFuse and Node-RED, including Node-RED instance management through natural language.","\u002Fdocs\u002Fuser\u002Fexpert\u002Fchat\u002F#support-mode",[5876],{"url":5877,"release":5868},"\u002Fchangelog\u002F2026\u002F02\u002Fff-expert-debug-log-context\u002F",false,{"edge":2193,"hub":2193,"fleet":2193},{"id":5881,"title":5882,"description":5883,"docsLink":5884,"changelog":5885,"subfeature":2193,"showOnPricing":5878,"tiers":5889},"flowfuse-expert-application-building","Application Building","Describe what you want to build and FlowFuse Expert assembles it on your workspace, adding tabs, wiring nodes, and configuring properties.","\u002Fdocs\u002Fuser\u002Fexpert\u002Fchat\u002F",[5886],{"url":5887,"release":5888},"\u002Fchangelog\u002F2026\u002F05\u002Fexpert-application-building\u002F","2.30",{"edge":2193,"hub":2193,"fleet":2193},{"id":5891,"title":5892,"description":5893,"docsLink":5894,"subfeature":2193,"beta":2193,"showOnPricing":5878,"tiers":5895},"flowfuse-expert-insights-mode","Insights Mode","Connects FlowFuse Expert to MCP servers in your Node-RED instances, enabling real-time data queries and actions through a single chat interface.","\u002Fdocs\u002Fuser\u002Fexpert\u002Fchat\u002F#insights-mode",{"edge":2193,"hub":2193,"fleet":2193},{"id":5897,"title":5898,"description":5899,"docsLink":5900,"tiers":5901},"mcp-servers","Agentic Operations","Expose your Node-RED flows as tools an AI agent can call directly, so agents can query the state of the factory or trigger actions without custom integration work.","\u002Fnode-red\u002Fflowfuse\u002Fmcp\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5903,"title":5904,"description":5905,"tiers":5906},"onnx-integration","ONNX Integration","Run trained machine learning models directly in your flows, including on edge hardware, without sending data out to an external inference service.",{"edge":2193,"hub":2193,"fleet":2193},{"id":5908,"title":5909,"features":5910},"build","Build",[5911,5917,5923,5933,5939,5945,5949,5955,5961,5969,5975,5979,5983,5992,6000],{"id":5912,"title":5913,"description":5914,"docsLink":5915,"tiers":5916},"edge-development","Edge Development","Develop and test Node-RED flows directly on edge devices with a remote editor proxy.","\u002Fdocs\u002Fdevice-agent\u002Fquickstart\u002F",{"edge":2193,"hub":5878,"fleet":2193},{"id":5918,"title":5919,"description":5920,"docsLink":5921,"tiers":5922},"private-npm-registry","Custom Node-RED Nodes","Create and manage your own private npm registry for Node-RED nodes, so you can share custom nodes across your team and devices without publishing them publicly.","\u002Fdocs\u002Fuser\u002Fcustom-npm-packages\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5924,"title":5925,"description":5926,"docsLink":5927,"changelog":5928,"tiers":5932},"flowfuse-tables","FlowFuse Tables","A managed PostgreSQL database for every application, so you can store and query structured data without standing up and maintaining your own database.","\u002Fdocs\u002Fuser\u002Fff-tables\u002F",[5929],{"url":5930,"release":5931},"\u002Fchangelog\u002F2026\u002F07\u002Fexpert-tables-automation\u002F","2.33",{"edge":2193,"hub":2193,"fleet":2193},{"id":5934,"title":5935,"description":5936,"docsLink":5937,"tiers":5938},"persistent-files","File Storage","Store and retrieve files from your Node-RED flows, with automatic replication and backup across your devices and hosted instances.","\u002Fdocs\u002Finstall\u002Ffile-storage\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5940,"title":5941,"description":5942,"docsLink":5943,"showOnPricing":5878,"tiers":5944},"persistent-context","Persistent Context","In-memory values defined in a Node-RED flow persist across project restarts and upgrades.","\u002Fdocs\u002Fuser\u002Fpersistent-context\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5946,"title":5947,"showOnPricing":5878,"tiers":5948},"static-assets","Static Assets",{"edge":2193,"hub":2193,"fleet":2193},{"id":5950,"title":5951,"description":5952,"docsLink":5953,"tiers":5954},"team-library","Team Library","Set up standard nodes and flows that can be shared with all team members across your organisation.","\u002Fdocs\u002Fuser\u002Fshared-library\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5956,"title":5957,"description":5958,"docsLink":5959,"tiers":5960},"personalised-multi-user-dashboards","Personalised Multi-User Dashboards","Build applications that provide unique data to each logged-in user using personalised multi-user dashboards.","https:\u002F\u002Fdashboard.flowfuse.com\u002Fuser\u002Fmulti-tenancy.html",{"edge":2193,"hub":2193,"fleet":2193},{"id":5962,"title":5963,"description":5964,"changelog":5965,"subfeature":2193,"showOnPricing":5878,"tiers":5968},"dashboards-view","Dashboards View","Browse and open every dashboard across your team from a dedicated Dashboards view, at both team and application level, without leaving FlowFuse.",[5966],{"url":5967,"release":5931},"\u002Fchangelog\u002F2026\u002F07\u002Fteam-and-application-dashboards\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":5970,"title":5971,"description":5972,"docsLink":5973,"tiers":5974},"blueprints-converge","Blueprints","Ready-made starting points for your apps, from cross-team Converge templates to OT and IT specific blueprints.","\u002Fdocs\u002Fuser\u002Fconcepts\u002F#blueprint",{"edge":2193,"hub":2193,"fleet":2193},{"id":5976,"title":5977,"subfeature":2193,"showOnPricing":5878,"tiers":5978},"blueprints-ot-apps","Blueprints - OT APPS",{"edge":2193,"hub":5878,"fleet":2193},{"id":5980,"title":5981,"subfeature":2193,"showOnPricing":5878,"tiers":5982},"blueprints-it-apps","Blueprints - IT APPS",{"edge":5878,"hub":2193,"fleet":5878},{"id":5984,"title":5985,"description":5986,"changelog":5987,"showOnPricing":5878,"tiers":5991},"immersive-editor-snapshots","Snapshot Details in Immersive Editor","View and manage snapshot details directly inside the immersive editor without leaving your editing session.",[5988],{"url":5989,"release":5990},"\u002Fchangelog\u002F2026\u002F03\u002Fsnapshot-detail-modal-immersive-editor\u002F","2.29",{"edge":2193,"hub":2193,"fleet":2193},{"id":5993,"title":5994,"description":5995,"changelog":5996,"showOnPricing":5878,"tiers":5999},"immersive-editor-drawer","Customisable Immersive Editor Drawer","Pin, move, resize, or full-screen the immersive editor drawer. Your preferences are remembered between sessions.",[5997],{"url":5998,"release":5888},"\u002Fchangelog\u002F2026\u002F04\u002Fimmersive-editor-drawer\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6001,"title":6002,"description":6003,"changelog":6004,"showOnPricing":5878,"tiers":6007},"embedded-editor-tab-title","Embedded Editor Browser Tab Title","The browser tab title updates to reflect the active Node-RED canvas tab when working in the embedded editor.",[6005],{"url":6006,"release":5990},"\u002Fchangelog\u002F2026\u002F03\u002Fembedded-editor-tab-title\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6009,"title":290,"features":6010},"deploy",[6011,6016,6025,6031,6037,6043,6049,6055,6060],{"id":6012,"title":6013,"description":6014,"docsLink":117,"tiers":6015},"hosted-instances","Cloud Instances","Run Node-RED instances managed and hosted by FlowFuse.",{"edge":2193,"hub":2193,"fleet":2193},{"id":6017,"title":6018,"description":6019,"docsLink":6020,"changelog":6021,"tiers":6024},"edge-devices","Edge Instances","Deploy and mange your Node-RED instances on edge PLCs and gateways, with full visibility and control from the cloud.","\u002Fdocs\u002Fdevice-agent\u002Fintroduction\u002F",[6022],{"url":6023,"release":5868},"\u002Fchangelog\u002F2026\u002F02\u002Fdevice-agent-nodejs-options\u002F",{"edge":2193,"hub":5878,"fleet":2193},{"id":6026,"title":6027,"description":6028,"docsLink":6029,"tiers":6030},"custom-hostnames","Custom Hostnames","Access your Node-RED application via your own domain name.","\u002Fdocs\u002Fuser\u002Fcustom-hostnames\u002F",{"edge":5878,"hub":2193,"fleet":5878},{"id":6032,"title":6033,"description":6034,"docsLink":6035,"tiers":6036},"mqtt-broker","MQTT Broker","Manage and create MQTT clients to transport data for efficient messaging and communication within your applications.","\u002Fdocs\u002Fuser\u002Fteambroker\u002F",{"edge":2193,"hub":5878,"fleet":2193},{"id":6038,"title":6039,"description":6040,"docsLink":6041,"showOnPricing":5878,"tiers":6042},"project-nodes","Project Nodes aka seamless project comms","FlowFuse Project Nodes enable the passing of data and messages between your Node-RED projects.","\u002Fdocs\u002Fuser\u002Fprojectnodes\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6044,"title":6045,"description":6046,"docsLink":6047,"tiers":6048},"devops-pipelines","DevOps Pipelines","Set up different environments for development, testing, and production Node-RED instances to support a full software delivery lifecycle.","\u002Fdocs\u002Fuser\u002Fdevops-pipelines\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6050,"title":6051,"description":6052,"docsLink":6053,"tiers":6054},"git-integration","Git Integration","Back up your flows to a remote Git repository through a DevOps Pipeline. Supports GitHub and Azure DevOps repositories.","\u002Fdocs\u002Fuser\u002Fdevops-pipelines\u002F#git-repository-stage",{"edge":5878,"hub":2193,"fleet":5878},{"id":6056,"title":6057,"description":6058,"docsLink":6053,"subfeature":2193,"showOnPricing":5878,"tiers":6059},"git-integration-github","GitHub","Push and pull snapshots to GitHub repositories through DevOps Pipeline Git Stages.",{"edge":5878,"hub":2193,"fleet":5878},{"id":6061,"title":6062,"description":6063,"docsLink":6053,"changelog":6064,"subfeature":2193,"showOnPricing":5878,"tiers":6067},"git-integration-azure","Azure DevOps","Push and pull snapshots to Azure DevOps repositories through DevOps Pipeline Git Stages.",[6065],{"url":6066,"release":5990},"\u002Fchangelog\u002F2026\u002F03\u002Fazure-dev-ops-gitops\u002F",{"edge":5878,"hub":2193,"fleet":5878},{"id":6069,"title":6070,"features":6071},"operate-maintain","Operate & Maintain",[6072,6078,6084,6089,6097,6101,6105,6110,6116,6122,6127,6133,6137,6141],{"id":6073,"title":6074,"description":6075,"docsLink":6076,"tiers":6077},"snapshots","Snapshots & Version History","Automatic snapshots on remote devices and hosted instances, plus a full version history timeline so you can roll back to any prior state.","\u002Fdocs\u002Fuser\u002Fsnapshots\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6079,"title":6080,"description":6081,"docsLink":6082,"subfeature":2193,"showOnPricing":5878,"tiers":6083},"auto-snapshot-remote","Auto Snapshot (Remote)","Automatically capture a snapshot every time a remote instance is deployed, so you always have a recoverable history of what was running on each device.","\u002Fdocs\u002Fuser\u002Fsnapshots\u002F#auto-snapshots",{"edge":2193,"hub":2193,"fleet":2193},{"id":6085,"title":6086,"description":6087,"docsLink":6082,"subfeature":2193,"showOnPricing":5878,"tiers":6088},"auto-snapshot-hosted","Auto Snapshot (Hosted)","Automatically capture a snapshot every time a hosted instance is deployed, so you always have a recoverable history of what was running.",{"edge":2193,"hub":2193,"fleet":2193},{"id":6090,"title":6091,"description":6092,"changelog":6093,"subfeature":2193,"showOnPricing":5878,"tiers":6096},"snapshot-comparison","Snapshot Comparison","Compare two snapshots side-by-side with a navigable diff view. Step through every changed, added, or deleted node and see property and code diffs.",[6094],{"url":6095,"release":5990},"\u002Fchangelog\u002F2026\u002F04\u002Fsnapshot-diff-viewer\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6098,"title":6099,"subfeature":2193,"showOnPricing":5878,"tiers":6100},"version-history-timeline","Version History Timeline",{"edge":2193,"hub":2193,"fleet":2193},{"id":6102,"title":6103,"tiers":6104},"unlimited-workflow-executions","Unlimited Workflow Executions",{"edge":2193,"hub":2193,"fleet":2193},{"id":6106,"title":6107,"description":6108,"tiers":6109},"device-fleet-updates","Device Fleet Updates","Connect to edge devices to quickly assess and update logic. Debug one device and roll out improvements to your fleet in minutes, securely without requiring full device access for your whole organisation.",{"edge":2193,"hub":5878,"fleet":2193},{"id":6111,"title":6112,"description":6113,"docsLink":6114,"tiers":6115},"device-group-management","Device Group Management","Logically group devices assigned to an application and integrate device groups into your DevOps Pipeline for coordinated fleet updates.","\u002Fdocs\u002Fuser\u002Fdevice-groups\u002F",{"edge":2193,"hub":5878,"fleet":2193},{"id":6117,"title":6118,"description":6119,"docsLink":6120,"tiers":6121},"high-availability","High Availability","Leverage horizontal scaling for reliable and scalable processing of your data through Node-RED.","\u002Fdocs\u002Fuser\u002Fhigh-availability\u002F",{"edge":5878,"hub":2193,"fleet":5878},{"id":6123,"title":6124,"description":6125,"tiers":6126},"performance-monitoring","Performance Monitoring & Alerts","Track CPU, memory, and event loop performance across your instances and devices, with email alerts when something needs your attention.",{"edge":2193,"hub":2193,"fleet":2193},{"id":6128,"title":6129,"description":6130,"docsLink":6131,"subfeature":2193,"showOnPricing":5878,"tiers":6132},"instance-monitoring","Instance Monitoring","Enable alerts to be sent via email when your Node-RED instances encounter issues.","\u002Fdocs\u002Fuser\u002Finstance-settings\u002F#alerts",{"edge":2193,"hub":2193,"fleet":2193},{"id":6134,"title":6135,"subfeature":2193,"showOnPricing":5878,"tiers":6136},"email-alerts","Email Alerts",{"edge":2193,"hub":2193,"fleet":2193},{"id":6138,"title":6139,"showOnPricing":5878,"tiers":6140},"api-debug-length-limit","API\u002FDebug Length Limit",{"edge":2193,"hub":2193,"fleet":2193},{"id":6142,"title":6143,"tiers":6144},"protected-instances","Protected Instances",{"edge":5878,"hub":2193,"fleet":5878},{"id":6146,"title":6147,"features":6148},"govern-secure","Govern and Secure",[6149,6158,6164,6170,6175,6181,6187,6193,6201,6207,6213,6219],{"id":6150,"title":6151,"description":6152,"docsLink":6153,"changelog":6154,"tiers":6157},"single-sign-on","Single Sign-On (SSO)","Configure FlowFuse to work with your own SSO provider, allowing users to access FlowFuse with a single set of login credentials.","\u002Fdocs\u002Fadmin\u002Fsso\u002F",[6155],{"url":6156,"release":5931},"\u002Fchangelog\u002F2026\u002F07\u002Fapplication-sso-groups\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6159,"title":6160,"description":6161,"docsLink":6162,"tiers":6163},"two-factor-authentication","Two-Factor Authentication","Two-factor authentication adds an extra layer of security to your FlowFuse account.","\u002Fdocs\u002Fuser\u002Fuser-settings\u002F#two-factor-authentication",{"edge":2193,"hub":2193,"fleet":2193},{"id":6165,"title":6166,"description":6167,"docsLink":6168,"tiers":6169},"certified-nodes-it","Certified Nodes - IT","IT certified node bundle includes: Redis, MQTT, HTTP Request, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server","\u002Fblog\u002F2025\u002F07\u002Fcertified-nodes-v2\u002F",{"edge":5878,"hub":2193,"fleet":2193},{"id":6171,"title":6172,"description":6173,"tiers":6174},"certified-nodes-ot","Certified OT Connections - OPC-UA, Modbus, etc.","OT certified node bundle includes: OPC-UA, Modbus TCP & RTU, RTSP, EtherNet\u002FIP, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server",{"edge":2193,"hub":5878,"fleet":5878},{"id":6176,"title":6177,"description":6178,"docsLink":6179,"tiers":6180},"audit-log","Audit Log","Keep track of everything going on in your Node-RED instances and FlowFuse. Audit Logs provide details on what actions have taken place, when they happened, and who did them.","\u002Fdocs\u002Fuser\u002Flogs\u002F#audit-log",{"edge":2193,"hub":2193,"fleet":2193},{"id":6182,"title":6183,"description":6184,"docsLink":6185,"tiers":6186},"role-based-access-control","Role-Based Access Control","Control who can do what at both the team and application level, from viewers to admins.","\u002Fdocs\u002Fuser\u002Frole-based-access-control\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6188,"title":6189,"description":6190,"docsLink":6191,"subfeature":2193,"showOnPricing":5878,"tiers":6192},"application-level-rbac","Application-Level RBAC","Fine-grained access control per application, allowing team members to have different permission levels across different applications without requiring separate teams.","\u002Fdocs\u002Fuser\u002Frole-based-access-control\u002F#application-level-rbac",{"edge":2193,"hub":2193,"fleet":2193},{"id":6194,"title":6195,"description":6196,"changelog":6197,"subfeature":2193,"showOnPricing":5878,"tiers":6200},"scoped-personal-access-tokens","Scoped Personal Access Tokens","Restrict a Personal Access Token to specific teams, limit it to read-only operations, or control whether it carries admin privileges.",[6198],{"url":6199,"release":5931},"\u002Fchangelog\u002F2026\u002F07\u002Fscoped-pats\u002F",{"edge":2193,"hub":2193,"fleet":2193},{"id":6202,"title":6203,"description":6204,"docsLink":6205,"showOnPricing":5878,"tiers":6206},"team-members","Team Members","Invite multiple team members to collaborate on the same Node-RED flows.","\u002Fdocs\u002Fuser\u002Fteam\u002F#teams",{"edge":2193,"hub":2193,"fleet":2193},{"id":6208,"title":6209,"description":6210,"docsLink":6211,"showOnPricing":5878,"tiers":6212},"endpoint-security","Endpoint Security","Secure HTTP endpoints for hosted Node-RED instances using FlowFuse credentials.","\u002Fdocs\u002Fuser\u002Finstance-settings\u002F#security",{"edge":2193,"hub":2193,"fleet":2193},{"id":6214,"title":6215,"description":6216,"docsLink":6217,"tiers":6218},"baa-for-hipaa","BAA for HIPAA","FlowFuse can sign a Business Associate Agreement to ensure proper safeguarding of protected health information handled on your behalf.","\u002Fhandbook\u002Fsales\u002Fsubscription-agreement-1.5\u002F",{"edge":5878,"hub":2193,"fleet":5878},{"id":6220,"title":6221,"description":6222,"tiers":6223},"sbom","Software Bill of Materials","A complete list of all software components used in your Node-RED instances and hosted applications, including version numbers and license information.",{"edge":5878,"hub":2193,"fleet":5878},{"id":5401,"title":6225,"features":6226},"Support",[6227,6232,6236],{"id":6228,"title":6229,"docsLink":6230,"tiers":6231},"installation-support","Installation Support","\u002Fdocs\u002Finstall\u002Fintroduction\u002F#do-you-need-help-installation-service",{"edge":2193,"hub":2193,"fleet":2193},{"id":6233,"title":6234,"showOnPricing":5878,"tiers":6235},"live-chat-support","Live Chat Support",{"edge":2193,"hub":2193,"fleet":2193},{"id":6237,"title":6238,"docsLink":6239,"tiers":6240},"enterprise-support","Enterprise Support","\u002Fdocs\u002Fpremium-support\u002F",{"edge":2193,"hub":2193,"fleet":2193},"feature-catalog","0AnkhTIPCECCwP9NmbTWP5HvRYx4FTSao4lG93-HaWM",[6244,6247,6250,6253,6256,6259,6261,6264,6267,6270,6273,6275,6278,6281,6284,6287,6290,6293,6296,6299,6302,6305,6308,6311,6314,6317,6320,6323,6326,6329,6332,6335,6338,6341,6344,6347,6350,6353,6356,6359,6362,6365,6368,6371,6374,6377,6380,6383,6386,6388,6391,6394,6397,6400,6403,6406,6409,6411,6414,6417,6420,6423,6426,6428,6431,6434,6437,6440,6443,6446,6449,6452,6455,6458,6460,6463,6466,6469,6472,6475,6478,6481,6484,6487,6490,6493,6496,6499,6502,6504,6507,6510,6513,6516,6519,6522,6525,6528,6531,6534,6537,6540,6543,6546,6549,6552,6555,6558,6560,6563,6566,6569,6572,6575,6578,6581,6583,6586,6589,6592,6595,6598,6601,6604,6607,6610,6613,6616,6619,6622,6625,6628,6631,6634,6637,6640,6643,6646,6649,6652,6655,6658,6661,6664,6667,6670,6673,6676,6679,6682,6685,6688,6691,6694,6697,6700,6703,6706,6709,6712,6715,6718,6721,6724,6727,6730,6733,6735,6738,6741,6744,6747,6750,6753,6756,6759,6762,6765,6768,6771,6774],{"path":6245,"title":6246},"\u002Fchangelog\u002F2023\u002F09\u002Fcustom-node-support","Custom Node Support",{"path":6248,"title":6249},"\u002Fchangelog\u002F2023\u002F09\u002Fdevops-actions","DevOps Pipeline with action selection",{"path":6251,"title":6252},"\u002Fchangelog\u002F2023\u002F09\u002Fintroduction-enterprise-tier","Introducing the Enterprise Tier",{"path":6254,"title":6255},"\u002Fchangelog\u002F2023\u002F09\u002Fpipeline-api","API Endpoint for DevOps Pipeline",{"path":6257,"title":6258},"\u002Fchangelog\u002F2023\u002F09\u002Fsnapshots-devices","Usability improvements to Device Management",{"path":6260,"title":5971},"\u002Fchangelog\u002F2023\u002F10\u002Fblueprints",{"path":6262,"title":6263},"\u002Fchangelog\u002F2023\u002F10\u002Fcertified-nodes","Certified Nodes",{"path":6265,"title":6266},"\u002Fchangelog\u002F2023\u002F10\u002Fdevice-snapshot-selection","Enhanced Snapshot Selection",{"path":6268,"title":6269},"\u002Fchangelog\u002F2023\u002F10\u002Fpath-bug-fix","Device Agent path bug fix",{"path":6271,"title":6272},"\u002Fchangelog\u002F2023\u002F10\u002Fresource-alerts","Resource Monitoring in Audit Log",{"path":6274,"title":6160},"\u002Fchangelog\u002F2023\u002F11\u002F2fa",{"path":6276,"title":6277},"\u002Fchangelog\u002F2023\u002F11\u002Fdefault-editor","Device Editor enabled by default",{"path":6279,"title":6280},"\u002Fchangelog\u002F2023\u002F11\u002Fdevices-in-pipelines","Devices in DevOps Pipelines",{"path":6282,"title":6283},"\u002Fchangelog\u002F2023\u002F11\u002Fproject-nodes-devices","Project Nodes for Devices",{"path":6285,"title":6286},"\u002Fchangelog\u002F2023\u002F12\u002Fbilling","No Credit Card required for billing",{"path":6288,"title":6289},"\u002Fchangelog\u002F2023\u002F12\u002Fblueprint-selection","Blueprint Selection Update",{"path":6291,"title":6292},"\u002Fchangelog\u002F2023\u002F12\u002Fdevice-groups","Device Groups",{"path":6294,"title":6295},"\u002Fchangelog\u002F2023\u002F12\u002Femail-alerting-node-red-crash","Email Alerts for Audit Log Events",{"path":6297,"title":6298},"\u002Fchangelog\u002F2023\u002F12\u002Fnode-red-updated","Node-RED 3.1.3 now available",{"path":6300,"title":6301},"\u002Fchangelog\u002F2024\u002F01\u002Fdevice-audit-log","Introducing the Device Auditlog Feature",{"path":6303,"title":6304},"\u002Fchangelog\u002F2024\u002F01\u002Fdevice-groups-snapshot","Device Groups - Automatic snapshot assignment",{"path":6306,"title":6307},"\u002Fchangelog\u002F2024\u002F01\u002Ffleet-mode","Renaming \"Default Device Mode\" to \"Fleet Mode\"",{"path":6309,"title":6310},"\u002Fchangelog\u002F2024\u002F01\u002Fhelm-v2","Helm Chart v2.0",{"path":6312,"title":6313},"\u002Fchangelog\u002F2024\u002F01\u002Fnew-blueprints","New Blueprints added",{"path":6315,"title":6316},"\u002Fchangelog\u002F2024\u002F01\u002Fsecurity-updates","Security Updates",{"path":6318,"title":6319},"\u002Fchangelog\u002F2024\u002F01\u002Fsso-team-membership","Managing Team Membership via SSO",{"path":6321,"title":6322},"\u002Fchangelog\u002F2024\u002F01\u002Fstreamlined-device-assignment","Streamlined Device assignment",{"path":6324,"title":6325},"\u002Fchangelog\u002F2024\u002F02\u002Fdevice-auto-snapshot","Device Auto Snapshots",{"path":6327,"title":6328},"\u002Fchangelog\u002F2024\u002F02\u002Fdevice-instance-audit-logs","Device Instance Audit Logging",{"path":6330,"title":6331},"\u002Fchangelog\u002F2024\u002F02\u002Fdevice-onboarding-improvements","Device Onboarding Improvements",{"path":6333,"title":6334},"\u002Fchangelog\u002F2024\u002F02\u002Fdevice-pricing-change","Pricing change for Devices",{"path":6336,"title":6337},"\u002Fchangelog\u002F2024\u002F02\u002Finstance-auto-snapshots","Instance Auto Snapshots",{"path":6339,"title":6340},"\u002Fchangelog\u002F2024\u002F02\u002Fpostgresql-upgrade","PostgreSQL Version update",{"path":6342,"title":6343},"\u002Fchangelog\u002F2024\u002F03\u002Fbearer-token-authentication","Bearer Token Authentication for Node-RED Instances",{"path":6345,"title":6346},"\u002Fchangelog\u002F2024\u002F03\u002Finstance-protection-mode","Instance Protection Mode",{"path":6348,"title":6349},"\u002Fchangelog\u002F2024\u002F03\u002Flimits-debug-payload","Configure HTTP Payload and Debug Message size",{"path":6351,"title":6352},"\u002Fchangelog\u002F2024\u002F03\u002Frestart-devices-remotly","Remote Device Restart",{"path":6354,"title":6355},"\u002Fchangelog\u002F2024\u002F04\u002Fcustom-nodes-on-devices","Custom Nodes Support on Devices",{"path":6357,"title":6358},"\u002Fchangelog\u002F2024\u002F04\u002Fdevice-auto-snapshot","Direct Dashboard Access",{"path":6360,"title":6361},"\u002Fchangelog\u002F2024\u002F04\u002Fimproving-device-groups","Improving Device Groups",{"path":6363,"title":6364},"\u002Fchangelog\u002F2024\u002F04\u002Fpricing-change","Pricing change Enterprise & Teams Tier",{"path":6366,"title":6367},"\u002Fchangelog\u002F2024\u002F04\u002Ftougher-rate-limiting","Tougher Rate Limiting on Public Routes",{"path":6369,"title":6370},"\u002Fchangelog\u002F2024\u002F05\u002Finstance-healthcheck","Customizing instance health-check settings",{"path":6372,"title":6373},"\u002Fchangelog\u002F2024\u002F05\u002Flibrary-blueprints","Blueprints added to Library",{"path":6375,"title":6376},"\u002Fchangelog\u002F2024\u002F05\u002Flibrary-flowviewer","Team Library - Flow Viewer",{"path":6378,"title":6379},"\u002Fchangelog\u002F2024\u002F05\u002Fmanaging-node-red-version-on-devices","Managing Node-RED versions on Devices",{"path":6381,"title":6382},"\u002Fchangelog\u002F2024\u002F05\u002Fsnapshot-improvements","Snapshot Improvements",{"path":6384,"title":6385},"\u002Fchangelog\u002F2024\u002F05\u002Fsnapshot-improvements-pt3","Snapshot Upload",{"path":6387,"title":6385},"\u002Fchangelog\u002F2024\u002F05\u002Fsnapshot-upload",{"path":6389,"title":6390},"\u002Fchangelog\u002F2024\u002F06\u002Fdevice-agent-proxy-support","Running the Device Agent behind an HTTP proxy",{"path":6392,"title":6393},"\u002Fchangelog\u002F2024\u002F06\u002Flibrary-blueprints","Custom hostnames for your instances",{"path":6395,"title":6396},"\u002Fchangelog\u002F2024\u002F06\u002Fmultiline-env-vars","Multi-line Environment Variables",{"path":6398,"title":6399},"\u002Fchangelog\u002F2024\u002F06\u002Fsnapshot-flow-compare","Compare Snapshots flows",{"path":6401,"title":6402},"\u002Fchangelog\u002F2024\u002F07\u002Fapplications-search","Applications Search",{"path":6404,"title":6405},"\u002Fchangelog\u002F2024\u002F07\u002Fdevice-group-clear-snapshot","Device Groups Snapshots",{"path":6407,"title":6408},"\u002Fchangelog\u002F2024\u002F07\u002Fdevice-management-bulk-delete","Managing devices",{"path":6410,"title":6408},"\u002Fchangelog\u002F2024\u002F07\u002Fdevice-management-bulk-move",{"path":6412,"title":6413},"\u002Fchangelog\u002F2024\u002F07\u002Fedit-snapshots","Edit Snapshots",{"path":6415,"title":6416},"\u002Fchangelog\u002F2024\u002F07\u002Fflowfuse-assistant","The FlowFuse Expert",{"path":6418,"title":6419},"\u002Fchangelog\u002F2024\u002F07\u002Fflowfuse-assistant-json","FlowFuse Expert Writes JSON",{"path":6421,"title":6422},"\u002Fchangelog\u002F2024\u002F07\u002Fimmersive-editor","Immersive Editor Experience",{"path":6424,"title":6425},"\u002Fchangelog\u002F2024\u002F07\u002Fnotifications-inbox","Notifications Inbox",{"path":6427,"title":6425},"\u002Fchangelog\u002F2024\u002F07\u002Fnotifications-update",{"path":6429,"title":6430},"\u002Fchangelog\u002F2024\u002F07\u002Fpersistent-storage","Persistent Storage on FlowFuse Cloud",{"path":6432,"title":6433},"\u002Fchangelog\u002F2024\u002F07\u002Fsso","Single Sign On Updates",{"path":6435,"title":6436},"\u002Fchangelog\u002F2024\u002F08\u002Fbill-of-materials","Bill of Materials",{"path":6438,"title":6439},"\u002Fchangelog\u002F2024\u002F08\u002Fenterprise-license-update","Enforcing Enterprise Restrictions",{"path":6441,"title":6442},"\u002Fchangelog\u002F2024\u002F08\u002Fldap-sso-groups","LDAP Single Sign On Updates",{"path":6444,"title":6445},"\u002Fchangelog\u002F2024\u002F08\u002Fstatic-file-service-navigation-visibility","Static File Service Navigation and Visibility",{"path":6447,"title":6448},"\u002Fchangelog\u002F2024\u002F10\u002Fdevice-group-env-vars","Environment Variables for your Device Groups",{"path":6450,"title":6451},"\u002Fchangelog\u002F2024\u002F10\u002Fmqtt-service","MQTT Broker Service",{"path":6453,"title":6454},"\u002Fchangelog\u002F2024\u002F10\u002Fnotifications-bulk-actions","Managing Notifications",{"path":6456,"title":6457},"\u002Fchangelog\u002F2024\u002F10\u002Fsnapshot-download-upload-options","Snapshot Upload and Download Improvements",{"path":6459,"title":6099},"\u002Fchangelog\u002F2024\u002F10\u002Fversion-history-timeline",{"path":6461,"title":6462},"\u002Fchangelog\u002F2024\u002F11\u002Faudit-log-hierarchy","Audit logs show hierarchical events",{"path":6464,"title":6465},"\u002Fchangelog\u002F2024\u002F11\u002Fdevice-agent-release","Device Agent 3.0 released",{"path":6467,"title":6468},"\u002Fchangelog\u002F2024\u002F11\u002Fmqtt-topic-hierarchy","MQTT Topic Hierarchy view",{"path":6470,"title":6471},"\u002Fchangelog\u002F2024\u002F11\u002Fteam-search","Team-wide search",{"path":6473,"title":6474},"\u002Fchangelog\u002F2024\u002F12\u002Fdashboad-iframe","Allow Dashboards to be embedded in iFrames",{"path":6476,"title":6477},"\u002Fchangelog\u002F2024\u002F12\u002Fdevice-editor-cache","Device Editor Access Speed Up",{"path":6479,"title":6480},"\u002Fchangelog\u002F2024\u002F12\u002Fteam-bom-timeline","Team BOM and Pipeline Views",{"path":6482,"title":6483},"\u002Fchangelog\u002F2025\u002F01\u002Ffree-tier-onboarding","New Onboarding Tour for Free Tier Users",{"path":6485,"title":6486},"\u002Fchangelog\u002F2025\u002F01\u002Fhidden-env-vars","Hidden Environment Variables",{"path":6488,"title":6489},"\u002Fchangelog\u002F2025\u002F01\u002Fimproved-diagnostics","Improved Diagnostics",{"path":6491,"title":6492},"\u002Fchangelog\u002F2025\u002F01\u002Fteam-level-groups","Team level view of Groups",{"path":6494,"title":6495},"\u002Fchangelog\u002F2025\u002F02\u002Fadditional-device-version-history-events","New Remote Instances Version History Events",{"path":6497,"title":6498},"\u002Fchangelog\u002F2025\u002F02\u002Fbroker-error-feedback","Improved Broker Connection Feedback",{"path":6500,"title":6501},"\u002Fchangelog\u002F2025\u002F02\u002Fdevice-agent-updates","FlowFuse User Authentication on Remote Instances",{"path":6503,"title":6099},"\u002Fchangelog\u002F2025\u002F02\u002Fdevice-version-history-timeline",{"path":6505,"title":6506},"\u002Fchangelog\u002F2025\u002F02\u002Fexternal-brokers","External MQTT Brokers",{"path":6508,"title":6509},"\u002Fchangelog\u002F2025\u002F02\u002Fmqtt-schema-suggestions","MQTT Smart Schema Suggestions",{"path":6511,"title":6512},"\u002Fchangelog\u002F2025\u002F02\u002Fresend-and-extend-team-invitation-expiration","Re-send Team Invitations",{"path":6514,"title":6515},"\u002Fchangelog\u002F2025\u002F02\u002Fschema-docs","Personalized Schema Documentation",{"path":6517,"title":6518},"\u002Fchangelog\u002F2025\u002F02\u002Ftopic-hierarchy-search","Search & Filter for Topic Hierarchy List",{"path":6520,"title":6521},"\u002Fchangelog\u002F2025\u002F03\u002Fcontainer-tags","Changes to tags for flowfuse\u002Fnode-red",{"path":6523,"title":6524},"\u002Fchangelog\u002F2025\u002F03\u002Fdevice-groups","Multiple Device Groups in a pipeline",{"path":6526,"title":6527},"\u002Fchangelog\u002F2025\u002F03\u002Fdevice-local-login","Local Login for Remote Instances",{"path":6529,"title":6530},"\u002Fchangelog\u002F2025\u002F03\u002Ffree-tier","Free Tier now more accessible to all",{"path":6532,"title":6533},"\u002Fchangelog\u002F2025\u002F03\u002Fresource-notifications","Resource Alerts",{"path":6535,"title":6536},"\u002Fchangelog\u002F2025\u002F03\u002Fsnapshot-filter","Filtering Snapshots",{"path":6538,"title":6539},"\u002Fchangelog\u002F2025\u002F03\u002Fteam-npm-registry","NPM Package Hosting",{"path":6541,"title":6542},"\u002Fchangelog\u002F2025\u002F03\u002Ftopic-deletion","MQTT Topic Management",{"path":6544,"title":6545},"\u002Fchangelog\u002F2025\u002F04\u002Fdevice-provisioning","Remote Instance Provisioning",{"path":6547,"title":6548},"\u002Fchangelog\u002F2025\u002F04\u002Fgit-integration","Git Integration with Pipelines",{"path":6550,"title":6551},"\u002Fchangelog\u002F2025\u002F04\u002Finstance-log-browsing","Better Node-RED log handling",{"path":6553,"title":6554},"\u002Fchangelog\u002F2025\u002F05\u002Fimport-node-red-flows","Import Node-RED Flows During Remote Instance Setup",{"path":6556,"title":6557},"\u002Fchangelog\u002F2025\u002F06\u002Fflowfuse-assistant","FlowFuse Expert just got smarter",{"path":6559,"title":6557},"\u002Fchangelog\u002F2025\u002F06\u002Fflowfuse-assistant-2",{"path":6561,"title":6562},"\u002Fchangelog\u002F2025\u002F06\u002Fgit-integration","Pulling snapshots from Git with Pipelines",{"path":6564,"title":6565},"\u002Fchangelog\u002F2025\u002F06\u002Finstance-performance-memory","Memory Metrics in Instance Performance View",{"path":6567,"title":6568},"\u002Fchangelog\u002F2025\u002F06\u002Fnew-home-page","Introducing the New Home Page Experience",{"path":6570,"title":6571},"\u002Fchangelog\u002F2025\u002F06\u002Fteam-performance","Team Performance Feature",{"path":6573,"title":6574},"\u002Fchangelog\u002F2025\u002F06\u002Fteam-performance-view","Instance Performance View",{"path":6576,"title":6577},"\u002Fchangelog\u002F2025\u002F06\u002Fui-refresh","Navigation UI Refresh",{"path":6579,"title":6580},"\u002Fchangelog\u002F2025\u002F07\u002Fbrowse-node-red-flows","Browse for Node-RED Flows During Remote Instance Setup",{"path":6582,"title":5925},"\u002Fchangelog\u002F2025\u002F07\u002Fflowfuse-tables",{"path":6584,"title":6585},"\u002Fchangelog\u002F2025\u002F07\u002Fimport-blueprints","Import blueprints directly into your existing instances",{"path":6587,"title":6588},"\u002Fchangelog\u002F2025\u002F07\u002Fsimplified-applications-overview","Simplified Applications Page with Summary Tiles",{"path":6590,"title":6591},"\u002Fchangelog\u002F2025\u002F07\u002Fsmart-suggestions","Smart Suggestions",{"path":6593,"title":6594},"\u002Fchangelog\u002F2025\u002F07\u002Fteam-to-pro-plan-rename","Team Plan Renamed to Pro Plan",{"path":6596,"title":6597},"\u002Fchangelog\u002F2025\u002F08\u002Fai-generated-snapshot-descriptions-hosted","Generate snapshot descriptions with AI",{"path":6599,"title":6600},"\u002Fchangelog\u002F2025\u002F08\u002Fai-generated-snapshot-descriptions-remote","AI Snapshot Descriptions Now Work with Remote Instances",{"path":6602,"title":6603},"\u002Fchangelog\u002F2025\u002F08\u002Fdevice-performance","FlowFuse Remote Instance Performance Data",{"path":6605,"title":6606},"\u002Fchangelog\u002F2025\u002F08\u002Fdirect-sso","Direct SSO Login",{"path":6608,"title":6609},"\u002Fchangelog\u002F2025\u002F08\u002Fflowfuse-assistant","FlowFuse Expert documents your flows",{"path":6611,"title":6612},"\u002Fchangelog\u002F2025\u002F08\u002Fflowfuse-mqtt","FlowFuse MQTT",{"path":6614,"title":6615},"\u002Fchangelog\u002F2025\u002F08\u002Fhttp-cors","Configure HTTP CORS",{"path":6617,"title":6618},"\u002Fchangelog\u002F2025\u002F08\u002Fsubflow-export","Export SubFlow as Node-RED module",{"path":6620,"title":6621},"\u002Fchangelog\u002F2025\u002F08\u002Ftables-assistant","FlowFuse Tables with a little help from the Assistant",{"path":6623,"title":6624},"\u002Fchangelog\u002F2025\u002F09\u002Fexpose-saml-groups-to-dashboard","Allow SSO groups to be shared with the Node-RED Dashboard",{"path":6626,"title":6627},"\u002Fchangelog\u002F2025\u002F09\u002Finline-assist","FlowFuse Expert can help you write code",{"path":6629,"title":6630},"\u002Fchangelog\u002F2025\u002F09\u002Fretiring-flowforge-device-agent","No more @flowforge\u002Fflowforge-device-agent releases",{"path":6632,"title":6633},"\u002Fchangelog\u002F2025\u002F09\u002Frevised-instance-snapshot-ui","Streamlined Snapshot Management",{"path":6635,"title":6636},"\u002Fchangelog\u002F2025\u002F09\u002Fteam-broker-async-api","Capture Async API data from FlowFuse Team Broker",{"path":6638,"title":6639},"\u002Fchangelog\u002F2025\u002F10\u002Fapplication-level-rbac","Application-level access control for Enterprise teams",{"path":6641,"title":6642},"\u002Fchangelog\u002F2025\u002F10\u002Fbulk-device-group-assignment","Easier Access to Bulk Device Group Management",{"path":6644,"title":6645},"\u002Fchangelog\u002F2025\u002F10\u002Fduplicate-instances-across-applications","Duplicate Instances Across Different Applications",{"path":6647,"title":6648},"\u002Fchangelog\u002F2025\u002F10\u002Fimport-flows-on-instance-creation","Import flows during instance creation",{"path":6650,"title":6651},"\u002Fchangelog\u002F2025\u002F10\u002Fmcp-nodes","FlowFuse MCP Server Nodes",{"path":6653,"title":6654},"\u002Fchangelog\u002F2025\u002F10\u002Fonnx-nodes","FlowFuse AI Nodes",{"path":6656,"title":6657},"\u002Fchangelog\u002F2025\u002F10\u002Fsettings-page-device-group-management","Device Group Management from Settings Page",{"path":6659,"title":6660},"\u002Fchangelog\u002F2025\u002F11\u002Fff-expert-update","FlowFuse Expert Update",{"path":6662,"title":6663},"\u002Fchangelog\u002F2025\u002F11\u002Fminimum-nodejs-version","Node.js v20 Minimum Version Requirement",{"path":6665,"title":6666},"\u002Fchangelog\u002F2025\u002F11\u002Fsso-session","SSO control over Session life",{"path":6668,"title":6669},"\u002Fchangelog\u002F2025\u002F12\u002Fff-expert-mcp-insights","FlowFuse Expert: Now with MCP-Powered Insights",{"path":6671,"title":6672},"\u002Fchangelog\u002F2025\u002F12\u002Fscheduled-maintenance","Scheduled Maintenance Mode",{"path":6674,"title":6675},"\u002Fchangelog\u002F2026\u002F01\u002Fdevice-agent-containers","Device Agent Docker Containers updated",{"path":6677,"title":6678},"\u002Fchangelog\u002F2026\u002F01\u002Fff-expert-manage-palette","FlowFuse Expert: Enhanced Palette Integration",{"path":6680,"title":6681},"\u002Fchangelog\u002F2026\u002F01\u002Fff-expert-nr-actions","FlowFuse Expert: Integration with Node-RED",{"path":6683,"title":6684},"\u002Fchangelog\u002F2026\u002F01\u002Fff-expert-palette-queries","FlowFuse Expert: Palette Queries",{"path":6686,"title":6687},"\u002Fchangelog\u002F2026\u002F01\u002Fff-expert-select-flows","FlowFuse Expert: Ask about your flows",{"path":6689,"title":6690},"\u002Fchangelog\u002F2026\u002F01\u002Fmcp-rbacs","FlowFuse Expert: MCP-Powered Insights with RBACs",{"path":6692,"title":6693},"\u002Fchangelog\u002F2026\u002F01\u002Fmcp-security","FlowFuse Expert: MCP-Powered Insights",{"path":6695,"title":6696},"\u002Fchangelog\u002F2026\u002F02\u002Fdevice-agent-nodejs-options","Set Node.js Options for Remote Instances",{"path":6698,"title":6699},"\u002Fchangelog\u002F2026\u002F02\u002Fff-expert-debug-log-context","FlowFuse Expert: Helping you make sense of your debug log",{"path":6701,"title":6702},"\u002Fchangelog\u002F2026\u002F02\u002Fff-expert-update-banner","FlowFuse Expert: Never Miss an Update",{"path":6704,"title":6705},"\u002Fchangelog\u002F2026\u002F02\u002Fha-instance-rolling-restart","HA Hosted Instance Rolling Restart",{"path":6707,"title":6708},"\u002Fchangelog\u002F2026\u002F02\u002Fremote-instances-immersive-editor","Immersive Mode for Remote Instances",{"path":6710,"title":6711},"\u002Fchangelog\u002F2026\u002F02\u002Frestoring-snapshots-to-remote-instances","Restoring snapshots to developer-mode Remote Instances",{"path":6713,"title":6714},"\u002Fchangelog\u002F2026\u002F03\u002Fazure-dev-ops-gitops","Azure DevOps Pipeline support",{"path":6716,"title":6717},"\u002Fchangelog\u002F2026\u002F03\u002Fdeveloper-mode-in-immersive-editor","Developer Mode Now Accessible from the Immersive Editor",{"path":6719,"title":6720},"\u002Fchangelog\u002F2026\u002F03\u002Fembedded-editor-tab-title","Embedded Editor Now Shows Active Tab",{"path":6722,"title":6723},"\u002Fchangelog\u002F2026\u002F03\u002Fmarch-scheduled-maintenance","Updated: Upcoming Scheduled Server Maintenance on March 28th, 2026",{"path":6725,"title":6726},"\u002Fchangelog\u002F2026\u002F03\u002Fsnapshot-detail-modal-immersive-editor","View Snapshot Details in the Immersive Editor",{"path":6728,"title":6729},"\u002Fchangelog\u002F2026\u002F04\u002Fexpert-action-links","FlowFuse expert action links",{"path":6731,"title":6732},"\u002Fchangelog\u002F2026\u002F04\u002Fhosted-instance-url-env-var","Hosted Instances know their own URL",{"path":6734,"title":5994},"\u002Fchangelog\u002F2026\u002F04\u002Fimmersive-editor-drawer",{"path":6736,"title":6737},"\u002Fchangelog\u002F2026\u002F04\u002Fsnapshot-diff-viewer","Richer snapshot comparison view",{"path":6739,"title":6740},"\u002Fchangelog\u002F2026\u002F05\u002Fai-opt-out","AI Feature Opt-Out for Teams",{"path":6742,"title":6743},"\u002Fchangelog\u002F2026\u002F05\u002Fexpert-application-building","FlowFuse Expert Builds Your Application",{"path":6745,"title":6746},"\u002Fchangelog\u002F2026\u002F05\u002Fsingle-sso-provider","Single SSO provider for all users",{"path":6748,"title":6749},"\u002Fchangelog\u002F2026\u002F06\u002Fdark-mode","Dark Mode",{"path":6751,"title":6752},"\u002Fchangelog\u002F2026\u002F06\u002Fdevice-agent-v4-released","Device Agent v4 released",{"path":6754,"title":6755},"\u002Fchangelog\u002F2026\u002F06\u002Fgeneric-git-server-support","Connect Pipelines to Any Git Server",{"path":6757,"title":6758},"\u002Fchangelog\u002F2026\u002F06\u002Fjuly-scheduled-maintenance","Updated: Upcoming Scheduled Server Maintenance on July 11th, 2026",{"path":6760,"title":6761},"\u002Fchangelog\u002F2026\u002F07\u002Fapplication-sso-groups","Application Roles from SSO Groups",{"path":6763,"title":6764},"\u002Fchangelog\u002F2026\u002F07\u002Fdevice-agent-onboarding","Getting started with FlowFuse straight from the terminal",{"path":6766,"title":6767},"\u002Fchangelog\u002F2026\u002F07\u002Fexpert-enhancements","FlowFuse Expert Enhancements",{"path":6769,"title":6770},"\u002Fchangelog\u002F2026\u002F07\u002Fexpert-tables-automation","FlowFuse Expert Can Now Work With Your Tables",{"path":6772,"title":6773},"\u002Fchangelog\u002F2026\u002F07\u002Fscoped-pats","Team Scoped Personal Access Tokens",{"path":6775,"title":6776},"\u002Fchangelog\u002F2026\u002F07\u002Fteam-and-application-dashboards","A Dedicated Home for Your Dashboards",[],1786105892104]