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