mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-04-26 23:49:59 -07:00
Add card based manifest entries for mobile
This commit is contained in:
55
bin/web/src/lib/components/ManifestCard.svelte
Normal file
55
bin/web/src/lib/components/ManifestCard.svelte
Normal file
@@ -0,0 +1,55 @@
|
||||
<script lang="ts">
|
||||
import { ManifestEntry } from "$lib/manifest.svelte";
|
||||
import DownloadLink from '$lib/components/DownloadLink.svelte';
|
||||
import DeleteButton from "$lib/components/DeleteButton.svelte";
|
||||
import AnalysisStatus from "./AnalysisStatus.svelte";
|
||||
import AnalysisView from "./AnalysisView.svelte";
|
||||
import RecordingControls from "./RecordingControls.svelte";
|
||||
let { entry, current, i, server_is_recording }: {
|
||||
entry: ManifestEntry;
|
||||
current: boolean;
|
||||
i: number;
|
||||
server_is_recording: boolean;
|
||||
} = $props();
|
||||
|
||||
// passing `undefined` as the locale uses the browser default
|
||||
const date_formatter = new Intl.DateTimeFormat(undefined, {
|
||||
timeStyle: "long",
|
||||
dateStyle: "short",
|
||||
});
|
||||
let status_row_color = $derived.by(() => {
|
||||
const num_warnings = entry.get_num_warnings();
|
||||
if (num_warnings !== undefined && num_warnings > 0) {
|
||||
return "bg-red-100";
|
||||
}
|
||||
return current ? "bg-green-100" : "bg-gray-100"
|
||||
});
|
||||
let analysis_visible = $state(false);
|
||||
function toggle_analysis_visibility() {
|
||||
analysis_visible = !analysis_visible;
|
||||
}
|
||||
</script>
|
||||
<div class="{status_row_color} drop-shadow p-4 flex flex-col">
|
||||
<span class="">Name: {entry.name}</span>
|
||||
<span class="">Started: {date_formatter.format(entry.start_time)}</span>
|
||||
<span class="">Last Message: {date_formatter.format(entry.last_message_time)}</span>
|
||||
<span class="">Size: {entry.qmdl_size_bytes} bytes</span>
|
||||
<span class=""><AnalysisStatus onclick={toggle_analysis_visibility} entry={entry} /></span>
|
||||
<div class="flex flex-row justify-between">
|
||||
<span class=""><DownloadLink url={entry.get_pcap_url()} text="pcap" /></span>
|
||||
<span class=""><DownloadLink url={entry.get_qmdl_url()} text="qmdl" /></span>
|
||||
{#if current}
|
||||
<RecordingControls {server_is_recording} />
|
||||
{:else}
|
||||
<DeleteButton
|
||||
prompt={`Are you sure you want to delete entry ${entry.name}?`}
|
||||
url={entry.get_delete_url()}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="border-b {analysis_visible ? '' : 'hidden'}">
|
||||
<div class="border-t border-dashed p-2" colspan="8">
|
||||
<AnalysisView {entry} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,13 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { Manifest, ManifestEntry } from "$lib/manifest.svelte";
|
||||
import TableRow from "./ManifestTableRow.svelte";
|
||||
import Card from "./ManifestCard.svelte"
|
||||
interface Props {
|
||||
entries: ManifestEntry[];
|
||||
current_entry: ManifestEntry | undefined;
|
||||
server_is_recording: boolean;
|
||||
}
|
||||
let { entries, current_entry }: Props = $props();
|
||||
let { entries, current_entry, server_is_recording }: Props = $props();
|
||||
</script>
|
||||
<table class="table-auto text-left">
|
||||
|
||||
<!--For larger screens we use a table-->
|
||||
<table class="hidden table-auto text-left lg:table">
|
||||
<thead>
|
||||
<tr class="bg-gray-100 drop-shadow">
|
||||
<th class='p-2' scope="col">Name</th>
|
||||
@@ -28,4 +32,13 @@
|
||||
<TableRow {entry} current={false} {i} />
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
<!--For smaller screens we use cards-->
|
||||
<div class="lg:hidden flex flex-col gap-2">
|
||||
{#if current_entry !== undefined}
|
||||
<Card entry={current_entry} current={true} i={0} server_is_recording={server_is_recording}/>
|
||||
{/if}
|
||||
{#each entries as entry, i}
|
||||
<Card {entry} current={false} {i} />
|
||||
{/each}
|
||||
</div>
|
||||
@@ -7,7 +7,8 @@
|
||||
let { entry, current, i }: {
|
||||
entry: ManifestEntry;
|
||||
current: boolean;
|
||||
i: number
|
||||
i: number;
|
||||
server_is_recording: boolean;
|
||||
} = $props();
|
||||
|
||||
// passing `undefined` as the locale uses the browser default
|
||||
@@ -30,7 +31,7 @@
|
||||
</script>
|
||||
|
||||
<tr class="{status_row_color} drop-shadow">
|
||||
<th class="font-bold p-2" scope='row'>{entry.name}</th>
|
||||
<td class="p-2">{entry.name}</td>
|
||||
<td class="p-2">{date_formatter.format(entry.start_time)}</td>
|
||||
<td class="p-2">{date_formatter.format(entry.last_message_time)}</td>
|
||||
<td class="p-2">{entry.qmdl_size_bytes}</td>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
{#if loaded}
|
||||
<SystemStatsTable stats={system_stats!} />
|
||||
<ControlBar server_is_recording={recording} />
|
||||
<ManifestTable entries={entries} current_entry={current_entry} />
|
||||
<ManifestTable entries={entries} current_entry={current_entry} server_is_recording={recording} />
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user