Skip to content

Commit 3f0a535

Browse files
committed
Add persistence to API keys
1 parent d944baf commit 3f0a535

File tree

9 files changed

+96
-13
lines changed

9 files changed

+96
-13
lines changed

src/components/dialogs/ImportAPIDialog.svelte

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import NowCast from './dataSources/Nowcast.svelte';
2020
import CovidHosp from './dataSources/COVIDHosp.svelte';
2121
import CoviDcast from './dataSources/COVIDcast.svelte';
22-
import { navMode } from '../../store';
22+
import { navMode, storeApiKeys } from '../../store';
2323
import { NavMode } from '../chartUtils';
2424
2525
const dispatch = createEventDispatcher();
@@ -68,6 +68,14 @@
6868
<Dialog title="Load from Epidata API" on:close>
6969
<form class="uk-form-stacked" {id} on:submit={onSubmit}>
7070
<div>
71+
<div class="uk-form-controls uk-form-controls-text">
72+
<div class="uk-form-controls uk-form-controls-text api">
73+
<label
74+
><input class="uk-checkbox" type="checkbox" bind:checked={$storeApiKeys} />
75+
Save API keys & auth tokens</label
76+
>
77+
</div>
78+
</div>
7179
<div class="uk-form-label">Data Source</div>
7280
<div class="uk-form-controls uk-form-controls-text">
7381
<label
@@ -180,3 +188,9 @@
180188
{/if}
181189
</button>
182190
</Dialog>
191+
192+
<style>
193+
.api {
194+
float: right;
195+
}
196+
</style>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export default class ApiKeySelections {
2+
cdc = '';
3+
fluView = '';
4+
ght = '';
5+
quidel = '';
6+
sensors = '';
7+
twitter = '';
8+
}
9+
10+
export function getApiKeySelections() {
11+
try {
12+
if (localStorage.getItem('api')) {
13+
return JSON.parse(localStorage.getItem('api')!) as ApiKeySelections;
14+
}
15+
return new ApiKeySelections();
16+
} catch {
17+
localStorage.removeItem('api');
18+
return new ApiKeySelections();
19+
}
20+
}

src/components/dialogs/dataSources/CDC.svelte

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
import { cdcLocations as regions } from '../../../data/data';
44
import SelectField from '../inputs/SelectField.svelte';
55
import TextField from '../inputs/TextField.svelte';
6+
import { apiKeySelections } from '../../../store';
67
78
export let id: string;
89
910
let locations = regions[0].value;
10-
let auth = '';
11+
let auth = $apiKeySelections.cdc;
1112
1213
export function importDataSet() {
1314
return importCDC({ locations, auth });
1415
}
1516
</script>
1617

17-
<TextField id="{id}-auth" name="auth" label="Authorizaton Token" bind:value={auth} placeholder="authorization token" />
18+
<TextField
19+
id="{id}-auth"
20+
name="auth"
21+
label="Authorizaton Token"
22+
bind:value={$apiKeySelections.cdc}
23+
placeholder="authorization token"
24+
/>
1825
<SelectField id="{id}-r" label="Location" bind:value={locations} options={regions} />

src/components/dialogs/dataSources/FluView.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts">
22
import { importFluView } from '../../../api/EpiData';
33
import { fluViewRegions } from '../../../data/data';
4+
import { apiKeySelections } from '../../../store';
45
import SelectField from '../inputs/SelectField.svelte';
56
import SelectIssue from '../inputs/SelectIssue.svelte';
67
import TextField from '../inputs/TextField.svelte';
@@ -10,7 +11,7 @@
1011
1112
let regions = fluViewRegions[0].value;
1213
let issue = DEFAULT_ISSUE;
13-
let auth: string = '';
14+
let auth = $apiKeySelections.fluView;
1415
1516
export function importDataSet() {
1617
return importFluView({ regions, ...issue, auth });
@@ -23,7 +24,7 @@
2324
id="{id}-auth"
2425
name="auth"
2526
label="Auth Key"
26-
bind:value={auth}
27+
bind:value={$apiKeySelections.fluView}
2728
required={false}
2829
placeholder="authorization token"
2930
/>
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
<script lang="ts">
22
import { importGHT } from '../../../api/EpiData';
33
import { ghtLocations as regions } from '../../../data/data';
4+
import { apiKeySelections } from '../../../store';
45
import SelectField from '../inputs/SelectField.svelte';
56
import TextField from '../inputs/TextField.svelte';
67
78
export let id: string;
89
910
let locations = regions[0].value;
10-
let auth = '';
11+
let auth = $apiKeySelections.ght;
1112
let query = '';
1213
1314
export function importDataSet() {
1415
return importGHT({ auth, locations, query });
1516
}
1617
</script>
1718

18-
<TextField id="{id}-auth" name="auth" label="Authorizaton Token" bind:value={auth} placeholder="authorization token" />
19+
<TextField
20+
id="{id}-auth"
21+
name="auth"
22+
label="Authorizaton Token"
23+
bind:value={$apiKeySelections.ght}
24+
placeholder="authorization token"
25+
/>
1926
<SelectField id="{id}-r" label="Location" bind:value={locations} options={regions} />
2027
<TextField id="{id}-query" name="query" label="Search Query or Topic" bind:value={query} />
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
<script lang="ts">
22
import { importQuidel } from '../../../api/EpiData';
33
import { quidelLocations as regions } from '../../../data/data';
4+
import { apiKeySelections } from '../../../store';
45
import SelectField from '../inputs/SelectField.svelte';
56
import TextField from '../inputs/TextField.svelte';
67
78
export let id: string;
89
910
let locations = regions[0].value;
10-
let auth = '';
11+
let auth = $apiKeySelections.quidel;
1112
1213
export function importDataSet() {
1314
return importQuidel({ auth, locations });
1415
}
1516
</script>
1617

17-
<TextField id="{id}-auth" name="auth" label="Authorizaton Token" bind:value={auth} placeholder="authorization token" />
18+
<TextField
19+
id="{id}-auth"
20+
name="auth"
21+
label="Authorizaton Token"
22+
bind:value={$apiKeySelections.quidel}
23+
placeholder="authorization token"
24+
/>
1825
<SelectField id="{id}-r" label="Location" bind:value={locations} options={regions} />
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
<script lang="ts">
22
import { importSensors } from '../../../api/EpiData';
33
import { sensorLocations as regions, sensorNames } from '../../../data/data';
4+
import { apiKeySelections } from '../../../store';
45
import SelectField from '../inputs/SelectField.svelte';
56
import TextField from '../inputs/TextField.svelte';
67
78
export let id: string;
89
910
let locations = regions[0].value;
10-
let auth = '';
11+
let auth = $apiKeySelections.sensors;
1112
let names = sensorNames[0].value;
1213
1314
export function importDataSet() {
1415
return importSensors({ auth, names, locations });
1516
}
1617
</script>
1718

18-
<TextField id="{id}-auth" name="auth" label="Authorizaton Token" bind:value={auth} placeholder="authorization token" />
19+
<TextField
20+
id="{id}-auth"
21+
name="auth"
22+
label="Authorizaton Token"
23+
bind:value={$apiKeySelections.sensors}
24+
placeholder="authorization token"
25+
/>
1926
<SelectField id="{id}-s" label="Name" bind:value={names} options={sensorNames} name="sensor" />
2027
<SelectField id="{id}-r" label="Location" bind:value={locations} options={regions} />

src/components/dialogs/dataSources/Twitter.svelte

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
11
<script lang="ts">
22
import { importTwitter } from '../../../api/EpiData';
33
import { twitterLocations as regions } from '../../../data/data';
4+
import { apiKeySelections } from '../../../store';
45
import SelectField from '../inputs/SelectField.svelte';
56
import TextField from '../inputs/TextField.svelte';
67
78
export let id: string;
89
910
let locations = regions[0].value;
10-
let auth = '';
11+
let auth = $apiKeySelections.twitter;
1112
let resolution: 'daily' | 'weekly' = 'daily';
1213
1314
export function importDataSet() {
1415
return importTwitter({ auth, locations, resolution });
1516
}
1617
</script>
1718

18-
<TextField id="{id}-auth" name="auth" label="Authorizaton Token" bind:value={auth} placeholder="authorization token" />
19+
<TextField
20+
id="{id}-auth"
21+
name="auth"
22+
label="Authorizaton Token"
23+
bind:value={$apiKeySelections.twitter}
24+
placeholder="authorization token"
25+
/>
1926
<SelectField id="{id}-r" label="Location" bind:value={locations} options={regions} />
2027
<div>
2128
<div class="uk-form-label">Temporal Resolution</div>

src/store.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { get, writable } from 'svelte/store';
22
import { NavMode } from './components/chartUtils';
33
import DataSet, { DataGroup } from './data/DataSet';
44
import deriveLinkDefaults, { getDirectLinkImpl } from './deriveLinkDefaults';
5+
import ApiKeySelections, { getApiKeySelections } from './components/dialogs/apiKeySelections';
56

67
declare const __VERSION__: string;
78

@@ -17,6 +18,18 @@ export const isShowingPoints = writable(defaults.showPoints);
1718
export const initialViewport = writable(defaults.viewport);
1819
export const navMode = writable(NavMode.autofit);
1920

21+
export const storeApiKeys = writable(true);
22+
storeApiKeys.subscribe((val) => {
23+
if (!val) {
24+
// reset local storage if user decides not to store API keys
25+
localStorage.removeItem('api');
26+
}
27+
});
28+
export const apiKeySelections = writable(getApiKeySelections());
29+
apiKeySelections.subscribe((val) => {
30+
localStorage.setItem('api', JSON.stringify(val));
31+
});
32+
2033
export function addDataSet(dataset: DataSet | DataGroup): void {
2134
const root = get(datasetTree);
2235
root.datasets.push(dataset);

0 commit comments

Comments
 (0)