| <script lang="ts"> | |
| import { createEventDispatcher } from "svelte"; | |
| import { | |
| type DatasetSelection, | |
| type DatasetSelectionEvent, | |
| type MetricSelection, | |
| type MetricSelectionEvent, | |
| type StatEvent, | |
| type StatInfo, | |
| type StatType, | |
| } from "../types/events.js"; | |
| import { Session, type IndexedWrapper } from "../wrappers/session.js"; | |
| export let name: string; | |
| export let datasetGroup: IndexedWrapper[]; | |
| export let suppressedMetrics: Set<string>; | |
| // Dispatchers | |
| let datasetDispatcher = createEventDispatcher<DatasetSelectionEvent>(); | |
| let metricsDispatcher = createEventDispatcher<MetricSelectionEvent>(); | |
| let statDispatcher = createEventDispatcher<StatEvent>(); | |
| // State | |
| let selected: boolean = true; | |
| let compute: boolean = false; | |
| let sources: Set<string>; | |
| let sampledMetrics: Set<string>; | |
| let metrics: Set<string>; | |
| // Events | |
| let selection = function (event: Event) { | |
| event.stopPropagation(); | |
| const target = event.target as HTMLInputElement; | |
| selected = target.checked; | |
| const selection: DatasetSelection = { | |
| name: name, | |
| enabled: selected, | |
| }; | |
| datasetDispatcher("datasetSelections", [selection]); | |
| }; | |
| let stat = function (type: StatType) { | |
| return function (event: Event) { | |
| event.stopPropagation(); | |
| const target = event.target as HTMLInputElement; | |
| compute = target.checked; | |
| const stat: StatInfo = { | |
| name: name, | |
| type: type, | |
| enabled: compute, | |
| }; | |
| statDispatcher("info", [stat]); | |
| }; | |
| }; | |
| let metricSelection = function (metric: string) { | |
| return function (event: Event) { | |
| event.stopPropagation(); | |
| const target = event.target as HTMLInputElement; | |
| const checked = target.checked; | |
| const selection: MetricSelection = { | |
| name: metric, | |
| enabled: checked, | |
| }; | |
| metricsDispatcher("metricSelections", [selection]); | |
| }; | |
| }; | |
| $: { | |
| sources = Session.sources(datasetGroup); | |
| let labels = datasetGroup | |
| .map((indexed) => indexed.value.metricLabels()) | |
| .flat(); | |
| let sampled = datasetGroup | |
| .map((indexed) => indexed.value.sampledLabels()) | |
| .flat(); | |
| metrics = new Set<string>(labels); | |
| sampledMetrics = new Set<string>(sampled); | |
| } | |
| </script> | |
| <div class="dataset"> | |
| <hgroup> | |
| <div class="section"> | |
| <span class="item">{name}</span> | |
| <div class="item actions"> | |
| <fieldset> | |
| <label for="switch"> | |
| Show | |
| <input | |
| type="checkbox" | |
| role="switch" | |
| checked={selected} | |
| on:change={selection} | |
| /> | |
| </label> | |
| </fieldset> | |
| {#if sources.size > 1} | |
| <fieldset> | |
| <label for="switch"> | |
| P | |
| <input | |
| type="checkbox" | |
| role="switch" | |
| checked={compute} | |
| on:change={stat("p")} | |
| /> | |
| </label> | |
| </fieldset> | |
| {/if} | |
| </div> | |
| </div> | |
| <div class="details"> | |
| <div class="sources"> | |
| {#each sources as source (source)} | |
| <div>📁 <small>{source}</small></div> | |
| {/each} | |
| </div> | |
| {#if metrics.size > 0} | |
| <div class="metrics"> | |
| {#each metrics as metric (metric)} | |
| <fieldset class="metric"> | |
| <label for={metric}> | |
| <input | |
| type="checkbox" | |
| name={metric} | |
| id={metric} | |
| checked={!suppressedMetrics.has(metric)} | |
| on:change={metricSelection(metric)} | |
| /> | |
| 📏 {metric} | |
| </label> | |
| </fieldset> | |
| {/each} | |
| </div> | |
| {/if} | |
| {#if sampledMetrics.size > 0} | |
| <div class="sampled"> | |
| {#each sampledMetrics as metric (metric)} | |
| <fieldset class="metric"> | |
| <label for={metric}> | |
| <input | |
| type="checkbox" | |
| name={metric} | |
| id={metric} | |
| checked={!suppressedMetrics.has(metric)} | |
| on:change={metricSelection(metric)} | |
| /> | |
| 📏 {metric} | |
| </label> | |
| </fieldset> | |
| {/each} | |
| </div> | |
| {/if} | |
| </div> | |
| </hgroup> | |
| </div> | |
| <style> | |
| .dataset { | |
| margin: 0.5rem; | |
| padding-top: 1rem; | |
| padding-left: 1rem; | |
| border: 1px solid #b3cee5; | |
| } | |
| .details { | |
| padding-left: 1rem; | |
| } | |
| .details > div { | |
| margin-top: 0.25rem; | |
| } | |
| .section { | |
| display: flex; | |
| flex-direction: row; | |
| justify-content: space-between; | |
| } | |
| .section .item { | |
| margin: 0px 10px; | |
| } | |
| .actions { | |
| display: flex; | |
| flex-direction: row; | |
| justify-content: flex-end; | |
| } | |
| .actions fieldset { | |
| margin-left: 5px; | |
| } | |
| .metric { | |
| margin-bottom: 0; | |
| } | |
| .metric label { | |
| font-size: 0.875em; | |
| } | |
| </style> |