homarr-labs / homarr

Missing key for the property JS-0414
Bug risk
Major
1 occurrence in this check
Missing "key" prop for element in iterator
 55        const disksData = matchFileSystemAndSmart(healthInfo.fileSystem, healthInfo.smart);
 56
 57        return (
 58          <Box> 59            <Card m="2.5cqmin" p="2.5cqmin" withBorder> 60              <Flex justify="space-between" align="center" key={integrationId}> 61                <HoverCard> 62                  <HoverCard.Target> 63                    <Indicator 64                      inline 65                      processing 66                      color={healthInfo.rebootRequired ? "red" : healthInfo.availablePkgUpdates > 0 ? "blue" : "gray"} 67                      position="top-end" 68                      size={12} 69                      label={healthInfo.availablePkgUpdates > 0 ? healthInfo.availablePkgUpdates : undefined} 70                      disabled={!healthInfo.rebootRequired && healthInfo.availablePkgUpdates === 0} 71                    > 72                      <Avatar size="md" radius="sm"> 73                        <IconInfoSquare size={32} /> 74                      </Avatar> 75                    </Indicator> 76                  </HoverCard.Target> 77                  <HoverCard.Dropdown> 78                    <List center spacing="0.5cqmin"> 79                      <List.Item icon={<IconCpu2 size={16} />}> 80                        {t("widget.healthMonitoring.popover.model")}: {healthInfo.cpuModelName} 81                      </List.Item> 82                      <List.Item icon={<IconVersions size={16} />}> 83                        {t("widget.healthMonitoring.popover.version")}: {healthInfo.version} 84                      </List.Item> 85                      <List.Item icon={<IconClock size={16} />}> 86                        {t("widget.healthMonitoring.popover.uptime")}: {formatUptime(healthInfo.uptime)} 87                      </List.Item> 88                    </List> 89                  </HoverCard.Dropdown> 90                </HoverCard> 91                {options.cpu && ( 92                  <RingProgress 93                    roundCaps 94                    size={100} 95                    thickness={12} 96                    label={ 97                      <Center style={{ flexDirection: "column" }}> 98                        <Text size="3cqmin">{`${healthInfo.cpuUtilization.toFixed(2)}%`}</Text> 99                        <HoverCard>100                          <HoverCard.Target>101                            <IconCpu size={25} />102                          </HoverCard.Target>103                          <HoverCard.Dropdown>104                            <List center spacing="0.5cqmin" icon={<IconCpu2 size={16} />}>105                              <Text fw={700} td="underline">106                                {t("widget.healthMonitoring.popover.loadAverage")}107                              </Text>108                              <List.Item>109                                1 {t("widget.healthMonitoring.popover.minute")}: {healthInfo.loadAverage["1min"]}110                              </List.Item>111                              <List.Item>112                                5 {t("widget.healthMonitoring.popover.minutes")}: {healthInfo.loadAverage["5min"]}113                              </List.Item>114                              <List.Item>115                                15 {t("widget.healthMonitoring.popover.minutes")}: {healthInfo.loadAverage["15min"]}116                              </List.Item>117                            </List>118                          </HoverCard.Dropdown>119                        </HoverCard>120                      </Center>121                    }122                    sections={[123                      {124                        value: Number(healthInfo.cpuUtilization.toFixed(2)),125                        color: progressColor(Number(healthInfo.cpuUtilization.toFixed(2))),126                      },127                    ]}128                  />129                )}130                {healthInfo.cpuTemp && options.cpu && (131                  <RingProgress132                    roundCaps133                    size={100}134                    thickness={12}135                    label={136                      <Center style={{ flexDirection: "column" }}>137                        <Text size="3cqmin">138                          {options.fahrenheit139                            ? `${(healthInfo.cpuTemp * 1.8 + 32).toFixed(1)}°F`140                            : `${healthInfo.cpuTemp}°C`}141                        </Text>142                        <IconCpu size={25} />143                      </Center>144                    }145                    sections={[146                      {147                        value: healthInfo.cpuTemp,148                        color: progressColor(healthInfo.cpuTemp),149                      },150                    ]}151                  />152                )}153                {options.memory && (154                  <RingProgress155                    roundCaps156                    size={100}157                    thickness={12}158                    label={159                      <Center style={{ flexDirection: "column" }}>160                        <Text size="3cqmin">{memoryUsage.memUsed.GB}GiB</Text>161                        <HoverCard>162                          <HoverCard.Target>163                            <IconBrain size={25} />164                          </HoverCard.Target>165                          <HoverCard.Dropdown>166                            <List center spacing="0.5cqmin" icon={<IconBrain size={16} />}>167                              <List.Item>168                                {t("widget.healthMonitoring.popover.total")}: {memoryUsage.memTotal.GB}GiB169                              </List.Item>170                              <List.Item>171                                {t("widget.healthMonitoring.popover.available")}: {memoryUsage.memFree.GB}GiB (172                                {memoryUsage.memFree.percent}%)173                              </List.Item>174                            </List>175                          </HoverCard.Dropdown>176                        </HoverCard>177                      </Center>178                    }179                    sections={[180                      {181                        value: Number(memoryUsage.memUsed.percent),182                        color: progressColor(Number(memoryUsage.memUsed.percent)),183                        tooltip: `${memoryUsage.memUsed.percent}%`,184                      },185                    ]}186                  />187                )}188              </Flex>189            </Card>190            {options.fileSystem &&191              disksData.map((disk) => {192                return (193                  <Card key={disk.deviceName} m="2.5cqmin" p="2.5cqmin" withBorder>194                    <Flex justify="space-between" align="center" m="1.5cqmin">195                      <Group gap="1cqmin">196                        <IconServer size={18} />197                        {disk.deviceName}198                      </Group>199                      <Group gap="1cqmin">200                        <IconTemperature size={18} />{" "}201                        {options.fahrenheit ? `${(disk.temperature * 1.8 + 32).toFixed(1)}°F` : `${disk.temperature}°C`}202                      </Group>203                      <Group gap="1cqmin">204                        <IconFileReport size={18} />205                        {disk.overallStatus}206                      </Group>207                    </Flex>208                    <Progress.Root size={20}>209                      <Tooltip label={disk.used}>210                        <Progress.Section value={disk.percentage} color={progressColor(disk.percentage)}>211                          <Progress.Label>{t("widget.healthMonitoring.popover.used")}</Progress.Label>212                        </Progress.Section>213                      </Tooltip>214215                      <Tooltip216                        label={217                          Number(disk.available) / 1024 ** 4 >= 1218                            ? `${(Number(disk.available) / 1024 ** 4).toFixed(2)} TiB`219                            : `${(Number(disk.available) / 1024 ** 3).toFixed(2)} GiB`220                        }221                      >222                        <Progress.Section value={100 - disk.percentage} color="default">223                          <Progress.Label>{t("widget.healthMonitoring.popover.available")}</Progress.Label>224                        </Progress.Section>225                      </Tooltip>226                    </Progress.Root>227                  </Card>228                );229              })}230          </Box>231        );
232      })}
233    </Box>