()
| 79 | Container used for setting up a new chart |
| 80 | */ |
| 81 | function AddChart() { |
| 82 | const [newChart, setNewChart] = useState(defaultChart); |
| 83 | const [editingTitle, setEditingTitle] = useState(false); |
| 84 | const [chartName, setChartName] = useState(""); |
| 85 | const [toastOpen, setToastOpen] = useState(false); |
| 86 | const [saveRequired, setSaveRequired] = useState(true); |
| 87 | const [loading, setLoading] = useState(false); |
| 88 | const [conditions, setConditions] = useState([]); |
| 89 | const [useCache, setUseCache] = useState(true); |
| 90 | const [creatingDatasetId, setCreatingDatasetId] = useState(null); |
| 91 | const [creatingNewDataset, setCreatingNewDataset] = useState(false); |
| 92 | |
| 93 | const charts = useSelector(selectCharts); |
| 94 | const datasets = useSelector(selectDatasetsNoDrafts); |
| 95 | const datasetLoading = useSelector((state) => state.dataset.loading); |
| 96 | const team = useSelector(selectTeam); |
| 97 | const user = useSelector(selectUser); |
| 98 | |
| 99 | const params = useParams(); |
| 100 | const navigate = useNavigate(); |
| 101 | const dispatch = useDispatch(); |
| 102 | const projectId = parseInt(params.projectId, 10); |
| 103 | |
| 104 | const currentUserRole = team?.TeamRoles?.find((teamRole) => teamRole.user_id === user?.id); |
| 105 | const isProjectScopedEditor = ["projectAdmin", "projectEditor"].includes(currentUserRole?.role) |
| 106 | && currentUserRole?.projects?.includes(projectId); |
| 107 | const missingChartDatasets = _.uniqBy( |
| 108 | (newChart.ChartDatasetConfigs || []).filter((cdc) => ( |
| 109 | cdc?.dataset_id && !datasets.some((dataset) => dataset.id === parseInt(cdc.dataset_id, 10)) |
| 110 | )), |
| 111 | "dataset_id" |
| 112 | ); |
| 113 | // Do not key this on local state that flips with datasetLoading — that remounted ChartDatasets |
| 114 | // (two branches) and reset its fetch ref, re-dispatching getDatasets in a loop. |
| 115 | const showMissingDatasetAlert = isProjectScopedEditor |
| 116 | && !datasetLoading |
| 117 | && missingChartDatasets.length > 0; |
| 118 | const missingSeriesLabels = missingChartDatasets |
| 119 | .map((cdc) => cdc.legend) |
| 120 | .filter(Boolean); |
| 121 | const missingDatasetDescription = "This chart uses datasets " |
| 122 | + "that your project role cannot access because " |
| 123 | + "they are not tagged with this dashboard. " |
| 124 | + "Ask a team owner or team admin to tag the dataset with this dashboard, then reload the editor." |
| 125 | + `${missingSeriesLabels.length > 0 |
| 126 | ? ` Affected series: ${missingSeriesLabels.slice(0, 3).join(", ")}${missingSeriesLabels.length > 3 ? ", ..." : ""}.` |
| 127 | : ""}`; |
| 128 | |
| 129 | useEffect(() => { |
| 130 | dispatch(clearAlerts()); |
| 131 | |
| 132 | if (params.chartId) { |
| 133 | // also fetch the chart's datasets and alerts |
| 134 | dispatch(getChartAlerts({ |
| 135 | project_id: params.projectId, |
| 136 | chart_id: params.chartId |
| 137 | })); |
| 138 | } |
nothing calls this directly
no test coverage detected