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

keplergl / kepler.gl / 25969480752

16 May 2026 06:25PM UTC coverage: 57.665% (+0.01%) from 57.652%
25969480752

Pull #3441

github

web-flow
Merge 06aa82672 into 259667648
Pull Request #3441: chore: Convert class components to functional components

7181 of 14909 branches covered (48.17%)

Branch coverage included in aggregate %.

49 of 110 new or added lines in 6 files covered. (44.55%)

1 existing line in 1 file now uncovered.

14568 of 22807 relevant lines covered (63.88%)

77.69 hits per line

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

6.35
/src/components/src/modals/export-data-modal.tsx
1
// SPDX-License-Identifier: MIT
2
// Copyright contributors to the kepler.gl project
3

4
import React, {useEffect} from 'react';
5
import {injectIntl, IntlShape} from 'react-intl';
6

7
import {DatasetType, EXPORT_DATA_TYPE_OPTIONS} from '@kepler.gl/constants';
8
import {FormattedMessage} from '@kepler.gl/localization';
9
import {Datasets} from '@kepler.gl/table';
10

11
import {FileType} from '../common/icons';
12
import {
13
  StyledExportSection,
14
  StyledFilteredOption,
15
  StyledModalContent,
16
  StyledType,
17
  CheckMark
18
} from '../common/styled-components';
19
import {StyledWarning} from './export-map-modal/components';
20

21
const getDataRowCount = (
7✔
22
  datasets: Datasets,
23
  selectedDataset: string | undefined,
24
  filtered: boolean,
25
  intl: IntlShape
26
) => {
27
  if (selectedDataset === undefined) {
×
28
    return;
×
29
  }
30
  const selectedData = datasets[selectedDataset];
×
31
  if (!selectedData) {
×
32
    return intl.formatMessage(
×
33
      {id: 'modal.exportData.fileCount'},
34
      {fileCount: Object.keys(datasets).length}
35
    );
36
  }
37
  const {dataContainer, filteredIdxCPU} = selectedData;
×
38

39
  if (filtered && !filteredIdxCPU) {
×
40
    return '-';
×
41
  }
42

43
  const rowCount = filtered ? filteredIdxCPU?.length : dataContainer.numRows();
×
44

45
  return intl.formatMessage(
×
46
    {id: 'modal.exportData.rowCount'},
47
    {rowCount: rowCount?.toLocaleString()}
48
  );
49
};
50

51
export interface ExportDataModalProps {
52
  datasets: Datasets;
53
  selectedDataset?: string;
54
  dataType: string;
55
  filtered: boolean;
56
  // callbacks
57
  applyCPUFilter: (filter: string | string[]) => void;
58
  onChangeExportSelectedDataset: (dataset: string) => void;
59
  onChangeExportDataType: (type: string) => void;
60
  onChangeExportFiltered: (isFiltered: boolean) => void;
61
  intl: IntlShape;
62
  supportedDataTypes: {
63
    id: string;
64
    label: string;
65
    available: boolean;
66
  }[];
67
}
68

69
const ExportDataModalFactory = () => {
7✔
70
  const ExportDataModal = ({
14✔
71
    supportedDataTypes = EXPORT_DATA_TYPE_OPTIONS,
×
72
    datasets,
73
    selectedDataset,
74
    dataType,
75
    filtered,
76
    onChangeExportDataType,
77
    onChangeExportFiltered,
78
    applyCPUFilter,
79
    onChangeExportSelectedDataset,
80
    intl
81
  }: ExportDataModalProps) => {
NEW
82
    useEffect(() => {
×
NEW
83
      const toCPUFilter = selectedDataset || Object.keys(datasets);
×
NEW
84
      applyCPUFilter(toCPUFilter);
×
85
      // eslint-disable-next-line react-hooks/exhaustive-deps
86
    }, []);
87

NEW
88
    const onSelectDataset: React.ChangeEventHandler<HTMLSelectElement> = ({target: {value}}) => {
×
NEW
89
      applyCPUFilter(value);
×
NEW
90
      onChangeExportSelectedDataset(value);
×
91
    };
92

NEW
93
    const exportAllDatasets = selectedDataset ? !datasets[selectedDataset] : true;
×
NEW
94
    const showTiledDatasetWarning = Object.keys(datasets).some(datasetId => {
×
UNCOV
95
      return (
×
96
        (datasets[datasetId].type === DatasetType.VECTOR_TILE ||
×
97
          datasets[datasetId].type === DatasetType.RASTER_TILE ||
98
          datasets[datasetId].type === DatasetType.WMS_TILE ||
99
          datasets[datasetId].type === DatasetType.TILE_3D) &&
100
        (selectedDataset === datasetId || exportAllDatasets)
101
      );
102
    });
103

NEW
104
    return (
×
105
      <StyledModalContent className="export-data-modal">
106
        <div>
107
          <StyledExportSection>
108
            <div className="description">
109
              <div className="title">
110
                <FormattedMessage id={'modal.exportData.datasetTitle'} />
111
              </div>
112
              <div className="subtitle">
113
                <FormattedMessage id={'modal.exportData.datasetSubtitle'} />
114
              </div>
115
            </div>
116
            <div className="selection">
117
              <select value={selectedDataset} onChange={onSelectDataset}>
118
                {[intl.formatMessage({id: 'modal.exportData.allDatasets'})]
119
                  .concat(Object.keys(datasets))
120
                  .map(d => (
NEW
121
                    <option key={d} value={d}>
×
122
                      {(datasets[d] && datasets[d].label) || d}
×
123
                    </option>
124
                  ))}
125
              </select>
126
            </div>
127
          </StyledExportSection>
128
          <StyledExportSection>
129
            <div className="description">
130
              <div className="title">
131
                <FormattedMessage id={'modal.exportData.dataTypeTitle'} />
132
              </div>
133
              <div className="subtitle">
134
                <FormattedMessage id={'modal.exportData.dataTypeSubtitle'} />
135
              </div>
136
            </div>
137
            <div className="selection">
138
              {supportedDataTypes.map(op => (
NEW
139
                <StyledType
×
140
                  key={op.id}
141
                  selected={dataType === op.id}
NEW
142
                  onClick={() => op.available && onChangeExportDataType(op.id)}
×
143
                >
144
                  <FileType ext={op.label} height="80px" fontSize="11px" />
145
                  {dataType === op.id && <CheckMark />}
×
146
                </StyledType>
147
              ))}
148
            </div>
149
          </StyledExportSection>
150
          <StyledExportSection>
151
            <div className="description">
152
              <div className="title">
153
                <FormattedMessage id={'modal.exportData.dataTypeTitle'} />
154
              </div>
155
              <div className="subtitle">
156
                <FormattedMessage id={'modal.exportData.filterDataSubtitle'} />
157
              </div>
158
            </div>
159
            <div className="selection">
160
              <StyledFilteredOption
161
                className="unfiltered-option"
162
                selected={!filtered}
NEW
163
                onClick={() => onChangeExportFiltered(false)}
×
164
              >
165
                <div className="filter-option-title">
166
                  <FormattedMessage id={'modal.exportData.unfilteredData'} />
167
                </div>
168
                <div className="filter-option-subtitle">
169
                  {getDataRowCount(datasets, selectedDataset, false, intl)}
170
                </div>
171
                {!filtered && <CheckMark />}
×
172
              </StyledFilteredOption>
173
              <StyledFilteredOption
174
                className="filtered-option"
175
                selected={filtered}
NEW
176
                onClick={() => onChangeExportFiltered(true)}
×
177
              >
178
                <div className="filter-option-title">
179
                  <FormattedMessage id={'modal.exportData.filteredData'} />
180
                </div>
181
                <div className="filter-option-subtitle">
182
                  {getDataRowCount(datasets, selectedDataset, true, intl)}
183
                </div>
184
                {filtered && <CheckMark />}
×
185
              </StyledFilteredOption>
186
            </div>
187
          </StyledExportSection>
188
          {showTiledDatasetWarning ? (
×
189
            <div className="title">
190
              <StyledWarning>
191
                <FormattedMessage id={'modal.exportData.tiledDatasetWarning'} />
192
              </StyledWarning>
193
            </div>
194
          ) : null}
195
        </div>
196
      </StyledModalContent>
197
    );
198
  };
199

200
  return injectIntl(ExportDataModal);
14✔
201
};
202

203
export default ExportDataModalFactory;
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