• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DLR-SC / ESID / 15257190808

26 May 2025 03:08PM UTC coverage: 51.267% (-0.9%) from 52.215%
15257190808

push

github

kunkoala
:wrench: enhance drag and drop functionalities

- Added `isDragging` prop to `DataCard`, `CardTooltip`, and `MainCard` components to manage drag state.
- Updated tooltip visibility logic to show when dragging or hovering.
- Adjusted cursor style during dragging for better user experience.

397 of 504 branches covered (78.77%)

Branch coverage included in aggregate %.

8 of 8 new or added lines in 3 files covered. (100.0%)

119 existing lines in 12 files now uncovered.

3771 of 7626 relevant lines covered (49.45%)

4.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.44
/src/components/ScenarioComponents/CardsComponents/DataCard.tsx
1
// SPDX-FileCopyrightText: 2024 German Aerospace Center (DLR)
2
// SPDX-License-Identifier: Apache-2.0
3

4
import Box from '@mui/material/Box';
1✔
5
import React, {Dispatch, useEffect, useMemo, useState} from 'react';
1✔
6
import MainCard from './MainCard/MainCard';
1✔
7
import FiltersContainer from './GroupFilter/FiltersContainer';
1✔
8
import {FilterValues} from 'types/card';
9
import {GroupFilter} from 'types/group';
10
import {Localization} from 'types/localization';
11
import {useSortable} from '@dnd-kit/sortable';
1✔
12
import {CSS} from '@dnd-kit/utilities';
1✔
13

14
interface DataCardProps {
15
  /** A unique identifier for the card.*/
16
  id: string;
17

18
  /** A dictionary of compartment values associated with the card.*/
19
  compartmentValues: Record<string, number | null> | null;
20

21
  /** A dictionary of start values used for calculating the rate. This determines whether the values have increased, decreased, or remained the same. */
22
  referenceValues: Record<string, number> | null;
23

24
  /** The title of the card.*/
25
  title: string;
26

27
  /** A boolean indicating whether the compartments are expanded.*/
28
  compartmentsExpanded: boolean;
29

30
  /** The compartment that is currently selected.*/
31
  selectedCompartmentId: string | null;
32

33
  /** A boolean indicating whether the scenario is selected.*/
34
  isSelected: boolean;
35

36
  /** The color of the card.*/
37
  color: string;
38

39
  /** if this scenario is active.*/
40
  isActive: boolean;
41

42
  /** A dictionary of filter values. This is an array of objects, each containing a title and a dictionary of numbers representing
43
   * the filtered information to be displayed, it's used a disctionary because each card has to have the same amount of filter. */
44
  filterValues?: Record<string, FilterValues[]> | null;
45

46
  /** A function to set the selected scenario.*/
47
  setSelected: Dispatch<{id: string; state: boolean}>;
48

49
  /** A function to set the active scenario.*/
50
  setActive: Dispatch<{id: string; state: boolean}>;
51

52
  hide: Dispatch<string>;
53

54
  /** The minimum number of compartment rows.*/
55
  minCompartmentsRows: number;
56

57
  /** The maximum number of compartment rows.*/
58
  maxCompartmentsRows: number;
59

60
  /** An object containing localization information (translation & number formattation).*/
61
  localization?: Localization;
62

63
  /** A dictionary of group filters.*/
64
  groupFilters: Record<string, GroupFilter> | undefined;
65

66
  /** Boolean to determine if the arrow is displayed */
67
  arrow?: boolean;
68
}
69

70
/**
71
 * This component renders a card for either the case data or the scenario cards. Each card contains a title, a list of
72
 * compartment values, and change rates relative to the simulation start. Additionally, the component includes a filter container.
73
 * The filter container renders a button and generates the necessary number of cards based on the presence of any filters.
74
 */
75
export default function DataCard({
22✔
76
  id,
22✔
77
  compartmentValues,
22✔
78
  referenceValues,
22✔
79
  title,
22✔
80
  compartmentsExpanded,
22✔
81
  selectedCompartmentId,
22✔
82
  filterValues,
22✔
83
  color,
22✔
84
  isActive,
22✔
85
  isSelected,
22✔
86
  minCompartmentsRows,
22✔
87
  maxCompartmentsRows,
22✔
88
  setSelected,
22✔
89
  setActive,
22✔
90
  hide,
22✔
91
  localization = {
22✔
92
    formatNumber: (value: number) => value.toString(),
22✔
93
    customLang: 'global',
22✔
94
    overrides: {},
22✔
95
  },
22✔
96
  groupFilters,
22✔
97
  arrow = true,
22✔
98
}: DataCardProps) {
22✔
99
  const [hover, setHover] = useState<boolean>(false);
22✔
100
  const [folded, setFolded] = useState<boolean>(false);
22✔
101
  const [visibility, setVisibility] = useState<boolean>(true);
22✔
102

103
  // drag and drop
104
  const {attributes, listeners, setNodeRef, setActivatorNodeRef, transform, isDragging, transition} = useSortable({
22✔
105
    id,
22✔
106
  });
22✔
107
  const style = {
22✔
108
    transform: CSS.Transform.toString(transform),
22✔
109
    transition,
22✔
110
  };
22✔
111

112
  const filteredTitles: string[] = useMemo(() => {
22✔
113
    if (isActive && filterValues?.[id.toString()]) {
13✔
114
      return filterValues[id.toString()].map((filterValue: FilterValues) => filterValue.filteredTitle);
4✔
115
    }
4✔
116
    return [];
9✔
117
  }, [isActive, filterValues, id]);
22✔
118

119
  const filteredValues = useMemo(() => {
22✔
120
    if (isActive && filterValues?.[id.toString()]) {
13✔
121
      return filterValues[id.toString()].map((filterValue: FilterValues) => filterValue.filteredValues);
4✔
122
    }
4✔
123
    return [];
9✔
124
  }, [isActive, filterValues, id]);
22✔
125

126
  /*
127
   * This useEffect hook updates the visibility of the component based on groupFilters and filteredTitles.
128
   * It checks if the first title in filteredTitles matches any filter name in groupFilters and if that filter is visible.
129
   * If at least one matching filter is visible, the component becomes visible; otherwise, it remains hidden.
130
   */
131
  useEffect(() => {
22✔
132
    function checkVisibility(): boolean {
13✔
133
      if (groupFilters) {
13✔
134
        return Object.values(groupFilters)
13✔
135
          .map((filter) => (filter.name == filteredTitles[0] ? filter.isVisible : false))
13✔
136
          .includes(true);
13✔
137
      }
13!
UNCOV
138
      return false;
×
139
    }
13✔
140
    setVisibility(checkVisibility);
13✔
141
  }, [filteredTitles, groupFilters]);
22✔
142

143
  return (
22✔
144
    <Box
22✔
145
      id={`data-card-${id}`}
22✔
146
      sx={{
22✔
147
        display: 'flex',
22✔
148
        flexDirection: 'row',
22✔
149
        alignItems: 'flex-start',
22✔
150
      }}
22✔
151
      ref={setNodeRef}
22✔
152
      style={style}
22✔
153
    >
154
      <MainCard
22✔
155
        id={id}
22✔
156
        label={title}
22✔
157
        hover={hover}
22✔
158
        color={color}
22✔
159
        referenceValues={referenceValues}
22✔
160
        compartmentValues={compartmentValues}
22✔
161
        setHover={setHover}
22✔
162
        compartmentsExpanded={compartmentsExpanded}
22✔
163
        selectedCompartmentId={selectedCompartmentId}
22✔
164
        isSelected={isSelected}
22✔
165
        isActive={isActive}
22✔
166
        setSelected={setSelected}
22✔
167
        setActive={setActive}
22✔
168
        hide={hide}
22✔
169
        minCompartmentsRows={minCompartmentsRows}
22✔
170
        maxCompartmentsRows={maxCompartmentsRows}
22✔
171
        localization={localization}
22✔
172
        arrow={arrow}
22✔
173
        dragListeners={listeners}
22✔
174
        dragAttributes={attributes}
22✔
175
        setActivatorNodeRef={setActivatorNodeRef}
22✔
176
        isDragging={isDragging}
22✔
177
      />
22✔
178
      {isActive && filterValues?.[id.toString()] && Object.keys(groupFilters || {}).length !== 0 && visibility && (
22✔
179
        <FiltersContainer
4✔
180
          id={id}
4✔
181
          color={color}
4✔
182
          filteredTitles={filteredTitles}
4✔
183
          folded={folded}
4✔
184
          setFolded={setFolded}
4✔
185
          compartmentsExpanded={compartmentsExpanded}
4✔
186
          selectedCompartmentId={selectedCompartmentId}
4✔
187
          filteredValues={filteredValues}
4✔
188
          minCompartmentsRows={minCompartmentsRows}
4✔
189
          maxCompartmentsRows={maxCompartmentsRows}
4✔
190
          localization={localization}
4✔
191
        />
4✔
192
      )}
193
    </Box>
22✔
194
  );
195
}
22✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc