1<script lang="ts">
2  import { createEventDispatcher } from "svelte";
3  import {
4    type DatasetSelection,
5    type DatasetSelectionEvent,
6    type MetricSelection,
7    type MetricSelectionEvent,
8    type StatEvent,
9    type StatInfo,
10    type StatType,
11  } from "../types/events.js";
12  import { Session, type IndexedWrapper } from "../wrappers/session.js";
13
14  export let name: string;
15  export let datasetGroup: IndexedWrapper[];
16  export let suppressedMetrics: Set<string>;
17
18  // Dispatchers
19  let datasetDispatcher = createEventDispatcher<DatasetSelectionEvent>();
20  let metricsDispatcher = createEventDispatcher<MetricSelectionEvent>();
21  let statDispatcher = createEventDispatcher<StatEvent>();
22  // State
23  let selected: boolean = true;
24  let compute: boolean = false;
25  let sources: Set<string>;
26  let sampledMetrics: Set<string>;
27  let metrics: Set<string>;
28
29  // Events
30  let selection = function (event: Event) {
31    event.stopPropagation();
32    const target = event.target as HTMLInputElement;
33    selected = target.checked;
34    const selection: DatasetSelection = {
35      name: name,
36      enabled: selected,
37    };
38    datasetDispatcher("datasetSelections", [selection]);
39  };
40
41  let stat = function (type: StatType) {
42    return function (event: Event) {
43      event.stopPropagation();
44      const target = event.target as HTMLInputElement;
45      compute = target.checked;
46      const stat: StatInfo = {
47        name: name,
48        type: type,
49        enabled: compute,
50      };
51      statDispatcher("info", [stat]);
52    };
53  };
54
55  let metricSelection = function (metric: string) {
56    return function (event: Event) {
57      event.stopPropagation();
58      const target = event.target as HTMLInputElement;
59      const checked = target.checked;
60      const selection: MetricSelection = {
61        name: metric,
62        enabled: checked,
63      };
64      metricsDispatcher("metricSelections", [selection]);
65    };
66  };
67
68  $: {
69    sources = Session.sources(datasetGroup);
70    let labels = datasetGroup
71      .map((indexed) => indexed.value.metricLabels())
72      .flat();
73
74    let sampled = datasetGroup
75      .map((indexed) => indexed.value.sampledLabels())
76      .flat();
77
78    metrics = new Set<string>(labels);
79    sampledMetrics = new Set<string>(sampled);
80  }
81</script>
82
83<div class="dataset">
84  <hgroup>
85    <div class="section">
86      <span class="item">{name}</span>
87      <div class="item actions">
88        <fieldset>
89          <label for="switch">
90            Show
91            <input
92              type="checkbox"
93              role="switch"
94              checked={selected}
95              on:change={selection}
96            />
97          </label>
98        </fieldset>
99        {#if sources.size > 1}
100          <fieldset>
101            <label for="switch">
102              P
103              <input
104                type="checkbox"
105                role="switch"
106                checked={compute}
107                on:change={stat("p")}
108              />
109            </label>
110          </fieldset>
111        {/if}
112      </div>
113    </div>
114    <div class="details">
115      <div class="sources">
116        {#each sources as source (source)}
117          <div>�� <small>{source}</small></div>
118        {/each}
119      </div>
120      {#if metrics.size > 0}
121        <div class="metrics">
122          {#each metrics as metric (metric)}
123            <fieldset class="metric">
124              <label for={metric}>
125                <input
126                  type="checkbox"
127                  name={metric}
128                  id={metric}
129                  checked={!suppressedMetrics.has(metric)}
130                  on:change={metricSelection(metric)}
131                />
132                �� {metric}
133              </label>
134            </fieldset>
135          {/each}
136        </div>
137      {/if}
138      {#if sampledMetrics.size > 0}
139        <div class="sampled">
140          {#each sampledMetrics as metric (metric)}
141            <fieldset class="metric">
142              <label for={metric}>
143                <input
144                  type="checkbox"
145                  name={metric}
146                  id={metric}
147                  checked={!suppressedMetrics.has(metric)}
148                  on:change={metricSelection(metric)}
149                />
150                �� {metric}
151              </label>
152            </fieldset>
153          {/each}
154        </div>
155      {/if}
156    </div>
157  </hgroup>
158</div>
159
160<style>
161  .dataset {
162    margin: 0.5rem;
163    padding-top: 1rem;
164    padding-left: 1rem;
165    border: 1px solid #b3cee5;
166  }
167  .details {
168    padding-left: 1rem;
169  }
170
171  .details > div {
172    margin-top: 0.25rem;
173  }
174  .section {
175    display: flex;
176    flex-direction: row;
177    justify-content: space-between;
178  }
179
180  .section .item {
181    margin: 0px 10px;
182  }
183  .actions {
184    display: flex;
185    flex-direction: row;
186    justify-content: flex-end;
187  }
188  .actions fieldset {
189    margin-left: 5px;
190  }
191  .metric {
192    margin-bottom: 0;
193  }
194  .metric label {
195    font-size: 0.875em;
196  }
197</style>
198