rune-lab 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -6
- package/dist/actions/portal.js +6 -1
- package/dist/components/Icon.svelte +13 -2
- package/dist/components/RuneProvider.svelte +81 -0
- package/dist/components/RuneProvider.svelte.d.ts +9 -0
- package/dist/composables/usePersistence.d.ts +2 -0
- package/dist/composables/usePersistence.js +5 -0
- package/dist/composables/useRuneLab.d.ts +17 -0
- package/dist/composables/useRuneLab.js +19 -0
- package/dist/config.d.ts +4 -85
- package/dist/config.js +6 -32
- package/dist/context.d.ts +12 -0
- package/dist/context.js +13 -0
- package/dist/devtools/API_Monitor.svelte +5 -2
- package/dist/devtools/Toaster.svelte +14 -12
- package/dist/devtools/createConfigStore.svelte.d.ts +11 -1
- package/dist/devtools/createConfigStore.svelte.js +13 -11
- package/dist/features/command-palette/CommandPalette.svelte +12 -4
- package/dist/features/config/components/AppSettingSelector.svelte +85 -3
- package/dist/features/config/components/AppSettingSelector.svelte.d.ts +2 -0
- package/dist/features/config/components/CurrencySelector.svelte +27 -9
- package/dist/features/config/components/CurrencySelector.svelte.d.ts +3 -1
- package/dist/features/config/components/LanguageSelector.svelte +21 -6
- package/dist/features/config/components/LanguageSelector.svelte.d.ts +3 -1
- package/dist/features/config/components/ThemeSelector.svelte +23 -8
- package/dist/features/config/components/ThemeSelector.svelte.d.ts +3 -1
- package/dist/features/detail-panels/DashboardPanel.svelte +34 -17
- package/dist/features/detail-panels/ShortcutsPanel.svelte +185 -88
- package/dist/features/detail-panels/ShowcasePanel.svelte +20 -6
- package/dist/features/layout/smart/ConnectedNavigationPanel.svelte +30 -0
- package/dist/features/layout/smart/ConnectedNavigationPanel.svelte.d.ts +10 -0
- package/dist/features/layout/smart/ConnectedWorkspaceStrip.svelte +23 -0
- package/dist/features/layout/smart/ConnectedWorkspaceStrip.svelte.d.ts +9 -0
- package/dist/features/shortcuts/ShortcutPalette.svelte +14 -6
- package/dist/index.d.ts +14 -2
- package/dist/index.js +19 -8
- package/dist/layout/NavigationPanel.svelte +97 -121
- package/dist/layout/NavigationPanel.svelte.d.ts +5 -1
- package/dist/layout/WorkspaceLayout.svelte +109 -30
- package/dist/layout/WorkspaceLayout.svelte.d.ts +2 -2
- package/dist/layout/WorkspaceStrip.svelte +17 -12
- package/dist/layout/WorkspaceStrip.svelte.d.ts +3 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/index.js +1 -1
- package/dist/paraglide/runtime.d.ts +43 -2
- package/dist/paraglide/runtime.js +143 -23
- package/dist/paraglide/server.js +37 -14
- package/dist/persistence/drivers.d.ts +10 -0
- package/dist/persistence/drivers.js +71 -0
- package/dist/persistence/types.d.ts +17 -0
- package/dist/persistence/types.js +2 -0
- package/dist/showcase/AppStateInspector.svelte +26 -11
- package/dist/showcase/Showcase.svelte +4 -1
- package/dist/state/api.svelte.d.ts +3 -3
- package/dist/state/api.svelte.js +9 -2
- package/dist/state/app.svelte.d.ts +3 -3
- package/dist/state/app.svelte.js +14 -4
- package/dist/state/commands.svelte.d.ts +21 -4
- package/dist/state/commands.svelte.js +22 -94
- package/dist/state/currency.svelte.d.ts +4 -1
- package/dist/state/currency.svelte.js +16 -8
- package/dist/state/index.d.ts +9 -9
- package/dist/state/index.js +10 -9
- package/dist/state/language.svelte.d.ts +4 -1
- package/dist/state/language.svelte.js +27 -8
- package/dist/state/layout.svelte.d.ts +10 -3
- package/dist/state/layout.svelte.js +56 -14
- package/dist/state/shortcuts.svelte.d.ts +56 -6
- package/dist/state/shortcuts.svelte.js +21 -69
- package/dist/state/theme.svelte.d.ts +4 -1
- package/dist/state/theme.svelte.js +16 -8
- package/dist/state/toast.svelte.d.ts +3 -3
- package/dist/state/toast.svelte.js +9 -2
- package/package.json +9 -9
- package/dist/features/command-palette/commands.svelte.d.ts +0 -8
- package/dist/features/command-palette/commands.svelte.js +0 -5
- package/dist/features/config/stores/api.svelte.d.ts +0 -13
- package/dist/features/config/stores/api.svelte.js +0 -5
- package/dist/features/config/stores/app.svelte.d.ts +0 -13
- package/dist/features/config/stores/app.svelte.js +0 -5
- package/dist/features/config/stores/currency.svelte.d.ts +0 -8
- package/dist/features/config/stores/currency.svelte.js +0 -5
- package/dist/features/config/stores/language.svelte.d.ts +0 -8
- package/dist/features/config/stores/language.svelte.js +0 -5
- package/dist/features/config/stores/theme.svelte.d.ts +0 -8
- package/dist/features/config/stores/theme.svelte.js +0 -5
- package/dist/features/config/stores/toast.svelte.d.ts +0 -9
- package/dist/features/config/stores/toast.svelte.js +0 -5
|
@@ -1,16 +1,98 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { type Snippet } from "svelte";
|
|
3
3
|
|
|
4
|
-
let {
|
|
4
|
+
let {
|
|
5
|
+
options,
|
|
6
|
+
value,
|
|
7
|
+
item,
|
|
8
|
+
triggerLabel,
|
|
9
|
+
tooltip,
|
|
10
|
+
direction = "bottom",
|
|
11
|
+
responsive = true,
|
|
12
|
+
} = $props<{
|
|
5
13
|
options: any[];
|
|
6
14
|
value: any;
|
|
7
15
|
item: Snippet<[any]>;
|
|
8
16
|
triggerLabel: Snippet<[any]>;
|
|
9
17
|
tooltip?: string;
|
|
18
|
+
direction?: "top" | "bottom" | "left" | "right" | "end";
|
|
19
|
+
responsive?: boolean;
|
|
10
20
|
}>();
|
|
21
|
+
|
|
22
|
+
let modal = $state<HTMLDialogElement>();
|
|
23
|
+
|
|
24
|
+
// Use derived to compute the class, though simple reactive assignment works too
|
|
25
|
+
const directionClass = $derived(
|
|
26
|
+
(() => {
|
|
27
|
+
switch (direction) {
|
|
28
|
+
case "top":
|
|
29
|
+
return "dropdown-top";
|
|
30
|
+
case "left":
|
|
31
|
+
return "dropdown-left";
|
|
32
|
+
case "right":
|
|
33
|
+
return "dropdown-right";
|
|
34
|
+
case "end":
|
|
35
|
+
return "dropdown-end"; // same as right in LTR, but specifically for alignment
|
|
36
|
+
default:
|
|
37
|
+
return "dropdown-bottom";
|
|
38
|
+
}
|
|
39
|
+
})(),
|
|
40
|
+
);
|
|
11
41
|
</script>
|
|
12
42
|
|
|
13
|
-
|
|
43
|
+
<!-- Mobile Modal Implementation -->
|
|
44
|
+
{#if responsive}
|
|
45
|
+
<div class="md:hidden inline-block">
|
|
46
|
+
<button
|
|
47
|
+
type="button"
|
|
48
|
+
class="btn btn-ghost btn-sm m-1 h-auto min-h-[2rem] px-2"
|
|
49
|
+
onclick={() => modal?.showModal()}
|
|
50
|
+
>
|
|
51
|
+
<span class="flex items-center gap-2">
|
|
52
|
+
{@render triggerLabel(value)}
|
|
53
|
+
</span>
|
|
54
|
+
</button>
|
|
55
|
+
|
|
56
|
+
<dialog bind:this={modal} class="modal modal-bottom sm:modal-middle">
|
|
57
|
+
<div class="modal-box p-0 overflow-hidden">
|
|
58
|
+
<div
|
|
59
|
+
class="p-4 bg-base-200 border-b border-base-300 flex justify-between items-center"
|
|
60
|
+
>
|
|
61
|
+
<h3 class="font-bold text-lg">Select Option</h3>
|
|
62
|
+
<form method="dialog">
|
|
63
|
+
<button class="btn btn-sm btn-circle btn-ghost"
|
|
64
|
+
>✕</button
|
|
65
|
+
>
|
|
66
|
+
</form>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="max-h-[60vh] overflow-y-auto p-2">
|
|
69
|
+
<ul class="menu bg-base-100 w-full p-0">
|
|
70
|
+
{#each options as option}
|
|
71
|
+
<li class="border-b border-base-100 last:border-0">
|
|
72
|
+
<button
|
|
73
|
+
class="w-full text-left py-3"
|
|
74
|
+
onclick={() => modal?.close()}
|
|
75
|
+
>
|
|
76
|
+
{@render item(option)}
|
|
77
|
+
</button>
|
|
78
|
+
</li>
|
|
79
|
+
{/each}
|
|
80
|
+
</ul>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
<form method="dialog" class="modal-backdrop">
|
|
84
|
+
<button>close</button>
|
|
85
|
+
</form>
|
|
86
|
+
</dialog>
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
89
|
+
|
|
90
|
+
<!-- Desktop Dropdown Implementation -->
|
|
91
|
+
<div
|
|
92
|
+
class="dropdown {directionClass} {responsive
|
|
93
|
+
? 'hidden md:inline-block'
|
|
94
|
+
: 'inline-block'}"
|
|
95
|
+
>
|
|
14
96
|
<div
|
|
15
97
|
tabindex="0"
|
|
16
98
|
role="button"
|
|
@@ -25,7 +107,7 @@
|
|
|
25
107
|
</div>
|
|
26
108
|
|
|
27
109
|
<ul
|
|
28
|
-
class="
|
|
110
|
+
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-xl border border-base-200 max-h-96 overflow-y-auto"
|
|
29
111
|
>
|
|
30
112
|
{#each options as option}
|
|
31
113
|
<li>
|
|
@@ -5,6 +5,8 @@ type $$ComponentProps = {
|
|
|
5
5
|
item: Snippet<[any]>;
|
|
6
6
|
triggerLabel: Snippet<[any]>;
|
|
7
7
|
tooltip?: string;
|
|
8
|
+
direction?: "top" | "bottom" | "left" | "right" | "end";
|
|
9
|
+
responsive?: boolean;
|
|
8
10
|
};
|
|
9
11
|
declare const AppSettingSelector: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
12
|
type AppSettingSelector = ReturnType<typeof AppSettingSelector>;
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import AppSettingSelector from "./AppSettingSelector.svelte";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getCurrencyStore,
|
|
5
|
+
type Currency,
|
|
6
|
+
} from "../../../state/currency.svelte";
|
|
7
|
+
|
|
8
|
+
const currencyStore = getCurrencyStore();
|
|
9
|
+
|
|
4
10
|
import * as m from "../../../paraglide/messages.js";
|
|
5
11
|
import { createMessageResolver } from "../../../devtools/message-resolver";
|
|
6
12
|
|
|
7
|
-
let {
|
|
13
|
+
let {
|
|
14
|
+
codes = [],
|
|
15
|
+
current = $bindable(String(currencyStore.current)),
|
|
16
|
+
onchange,
|
|
17
|
+
}: {
|
|
18
|
+
codes?: string[];
|
|
19
|
+
current?: string;
|
|
20
|
+
onchange?: (value: string) => void;
|
|
21
|
+
} = $props();
|
|
8
22
|
|
|
9
23
|
const getLabel = createMessageResolver<Currency>(m as any, {
|
|
10
|
-
keyExtractor: (c) => c.code,
|
|
24
|
+
keyExtractor: (c) => String(c.code),
|
|
11
25
|
});
|
|
12
26
|
|
|
13
27
|
let active = $derived(
|
|
@@ -15,14 +29,14 @@
|
|
|
15
29
|
);
|
|
16
30
|
|
|
17
31
|
let available = $derived(
|
|
18
|
-
codes.length > 0
|
|
19
|
-
? currencyStore.available.filter(c => codes.includes(c.code))
|
|
20
|
-
: currencyStore.available
|
|
32
|
+
codes.length > 0
|
|
33
|
+
? currencyStore.available.filter((c) => codes.includes(c.code))
|
|
34
|
+
: currencyStore.available,
|
|
21
35
|
);
|
|
22
36
|
</script>
|
|
23
37
|
|
|
24
|
-
<AppSettingSelector
|
|
25
|
-
value={active}
|
|
38
|
+
<AppSettingSelector
|
|
39
|
+
value={active}
|
|
26
40
|
options={available}
|
|
27
41
|
tooltip={getLabel(active)}
|
|
28
42
|
>
|
|
@@ -33,7 +47,11 @@
|
|
|
33
47
|
{#snippet item(c)}
|
|
34
48
|
<button
|
|
35
49
|
class="flex items-center gap-3 w-full"
|
|
36
|
-
onclick={() =>
|
|
50
|
+
onclick={() => {
|
|
51
|
+
currencyStore.set(c.code);
|
|
52
|
+
current = c.code;
|
|
53
|
+
onchange?.(c.code);
|
|
54
|
+
}}
|
|
37
55
|
>
|
|
38
56
|
<span class="badge badge-sm badge-ghost w-8">{c.symbol}</span>
|
|
39
57
|
<span>{getLabel(c)}</span>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
type $$ComponentProps = {
|
|
2
2
|
codes?: string[];
|
|
3
|
+
current?: string;
|
|
4
|
+
onchange?: (value: string) => void;
|
|
3
5
|
};
|
|
4
|
-
declare const CurrencySelector: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
declare const CurrencySelector: import("svelte").Component<$$ComponentProps, {}, "current">;
|
|
5
7
|
type CurrencySelector = ReturnType<typeof CurrencySelector>;
|
|
6
8
|
export default CurrencySelector;
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import AppSettingSelector from "./AppSettingSelector.svelte";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getLanguageStore,
|
|
5
|
+
type Language,
|
|
6
|
+
} from "../../../state/language.svelte";
|
|
7
|
+
|
|
8
|
+
const languageStore = getLanguageStore();
|
|
9
|
+
|
|
4
10
|
import { setLocale, locales } from "../../../paraglide/runtime";
|
|
5
11
|
import * as m from "../../../paraglide/messages.js";
|
|
6
12
|
import { createMessageResolver } from "../../../devtools/message-resolver";
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
let {
|
|
15
|
+
languages: allowedLocales = locales,
|
|
16
|
+
current = $bindable(languageStore.current),
|
|
17
|
+
onchange,
|
|
18
|
+
}: {
|
|
19
|
+
languages?: ReadonlyArray<string>;
|
|
20
|
+
current?: string;
|
|
21
|
+
onchange?: (value: string) => void;
|
|
22
|
+
} = $props();
|
|
10
23
|
|
|
11
24
|
const getLabel = createMessageResolver<Language>(m as any, {
|
|
12
25
|
keyExtractor: (l) => l.code,
|
|
@@ -23,8 +36,8 @@
|
|
|
23
36
|
);
|
|
24
37
|
</script>
|
|
25
38
|
|
|
26
|
-
<AppSettingSelector
|
|
27
|
-
value={active}
|
|
39
|
+
<AppSettingSelector
|
|
40
|
+
value={active}
|
|
28
41
|
options={available}
|
|
29
42
|
tooltip={getLabel(active)}
|
|
30
43
|
>
|
|
@@ -37,7 +50,9 @@
|
|
|
37
50
|
class="flex items-center gap-3 w-full"
|
|
38
51
|
onclick={() => {
|
|
39
52
|
languageStore.set(l.code);
|
|
40
|
-
setLocale(l.code);
|
|
53
|
+
setLocale(l.code as any);
|
|
54
|
+
current = l.code;
|
|
55
|
+
onchange?.(l.code);
|
|
41
56
|
}}
|
|
42
57
|
>
|
|
43
58
|
<span class="text-lg">{l.flag}</span>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
type $$ComponentProps = {
|
|
2
2
|
languages?: ReadonlyArray<string>;
|
|
3
|
+
current?: string;
|
|
4
|
+
onchange?: (value: string) => void;
|
|
3
5
|
};
|
|
4
|
-
declare const LanguageSelector: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
declare const LanguageSelector: import("svelte").Component<$$ComponentProps, {}, "current">;
|
|
5
7
|
type LanguageSelector = ReturnType<typeof LanguageSelector>;
|
|
6
8
|
export default LanguageSelector;
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import AppSettingSelector from "./AppSettingSelector.svelte";
|
|
3
|
-
import {
|
|
3
|
+
import { getThemeStore, type Theme } from "../../../state/theme.svelte";
|
|
4
|
+
|
|
5
|
+
const themeStore = getThemeStore();
|
|
6
|
+
|
|
4
7
|
import * as m from "../../../paraglide/messages.js";
|
|
5
8
|
import { createMessageResolver } from "../../../devtools/message-resolver";
|
|
6
9
|
|
|
7
|
-
let {
|
|
10
|
+
let {
|
|
11
|
+
themes = [],
|
|
12
|
+
current = $bindable(themeStore.current),
|
|
13
|
+
onchange,
|
|
14
|
+
}: {
|
|
15
|
+
themes?: string[];
|
|
16
|
+
current?: string;
|
|
17
|
+
onchange?: (value: string) => void;
|
|
18
|
+
} = $props();
|
|
8
19
|
|
|
9
20
|
const getThemeLabel = createMessageResolver<Theme>(m as any, {
|
|
10
21
|
keyExtractor: (t) => t.name,
|
|
@@ -16,14 +27,14 @@
|
|
|
16
27
|
|
|
17
28
|
let available = $derived(
|
|
18
29
|
themes.length > 0
|
|
19
|
-
? themeStore.available.filter(t => themes.includes(t.name))
|
|
20
|
-
: themeStore.available
|
|
30
|
+
? themeStore.available.filter((t) => themes.includes(t.name))
|
|
31
|
+
: themeStore.available,
|
|
21
32
|
);
|
|
22
33
|
</script>
|
|
23
34
|
|
|
24
|
-
<AppSettingSelector
|
|
25
|
-
value={activeTheme}
|
|
26
|
-
options={available}
|
|
35
|
+
<AppSettingSelector
|
|
36
|
+
value={activeTheme}
|
|
37
|
+
options={available}
|
|
27
38
|
tooltip={getThemeLabel(activeTheme)}
|
|
28
39
|
>
|
|
29
40
|
{#snippet triggerLabel(t)}
|
|
@@ -33,7 +44,11 @@
|
|
|
33
44
|
{#snippet item(t)}
|
|
34
45
|
<button
|
|
35
46
|
class="flex items-center gap-3 w-full"
|
|
36
|
-
onclick={() =>
|
|
47
|
+
onclick={() => {
|
|
48
|
+
themeStore.set(t.name);
|
|
49
|
+
current = t.name;
|
|
50
|
+
onchange?.(t.name);
|
|
51
|
+
}}
|
|
37
52
|
>
|
|
38
53
|
<input
|
|
39
54
|
type="radio"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
type $$ComponentProps = {
|
|
2
2
|
themes?: string[];
|
|
3
|
+
current?: string;
|
|
4
|
+
onchange?: (value: string) => void;
|
|
3
5
|
};
|
|
4
|
-
declare const ThemeSelector: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
declare const ThemeSelector: import("svelte").Component<$$ComponentProps, {}, "current">;
|
|
5
7
|
type ThemeSelector = ReturnType<typeof ThemeSelector>;
|
|
6
8
|
export default ThemeSelector;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
2
|
+
import { getToastStore } from "../../state/toast.svelte";
|
|
3
|
+
|
|
4
|
+
import { getApiStore } from "../../state/api.svelte";
|
|
5
|
+
import { getThemeStore } from "../../state/theme.svelte";
|
|
6
|
+
import { getShortcutStore } from "../../state/shortcuts.svelte";
|
|
7
|
+
// import { getCommandStore } from "../../state/commands.svelte";
|
|
8
|
+
import { getAppStore } from "../../state/app.svelte";
|
|
9
|
+
import { getLanguageStore } from "../../state/language.svelte";
|
|
10
|
+
import { getCurrencyStore } from "../../state/currency.svelte";
|
|
11
|
+
|
|
12
|
+
const appStore = getAppStore();
|
|
13
|
+
const apiStore = getApiStore();
|
|
14
|
+
const themeStore = getThemeStore();
|
|
15
|
+
const shortcutStore = getShortcutStore();
|
|
16
|
+
const toastStore = getToastStore();
|
|
17
|
+
const languageStore = getLanguageStore();
|
|
18
|
+
// const currencyStore = getCurrencyStore();
|
|
11
19
|
|
|
12
20
|
let beat = $state(false);
|
|
13
21
|
let logs = $state<{ time: string; what: string }[]>([]);
|
|
@@ -24,7 +32,7 @@
|
|
|
24
32
|
);
|
|
25
33
|
|
|
26
34
|
$effect(() => {
|
|
27
|
-
stateHash;
|
|
35
|
+
stateHash; // Subscribe
|
|
28
36
|
beat = true;
|
|
29
37
|
const timer = setTimeout(() => (beat = false), 300);
|
|
30
38
|
|
|
@@ -44,7 +52,9 @@
|
|
|
44
52
|
// Section 3: Quick-fire actions
|
|
45
53
|
function cycleTheme() {
|
|
46
54
|
const themes = themeStore.available;
|
|
47
|
-
const currentIndex = themes.findIndex(
|
|
55
|
+
const currentIndex = themes.findIndex(
|
|
56
|
+
(t) => t.name === themeStore.current,
|
|
57
|
+
);
|
|
48
58
|
const nextIndex = (currentIndex + 1) % themes.length;
|
|
49
59
|
themeStore.set(themes[nextIndex].name);
|
|
50
60
|
}
|
|
@@ -92,8 +102,7 @@
|
|
|
92
102
|
</tr>
|
|
93
103
|
<tr>
|
|
94
104
|
<td class="opacity-50">Shortcuts</td>
|
|
95
|
-
<td class="font-mono"
|
|
96
|
-
>{shortcutStore.entries.length}</td
|
|
105
|
+
<td class="font-mono">{shortcutStore.entries.length}</td
|
|
97
106
|
>
|
|
98
107
|
</tr>
|
|
99
108
|
</tbody>
|
|
@@ -137,16 +146,24 @@
|
|
|
137
146
|
{#each logs as log, i}
|
|
138
147
|
<li>
|
|
139
148
|
{#if i !== 0}<hr class="bg-base-content/10" />{/if}
|
|
140
|
-
<div
|
|
149
|
+
<div
|
|
150
|
+
class="timeline-start font-mono text-[10px] opacity-40"
|
|
151
|
+
>
|
|
141
152
|
{log.time}
|
|
142
153
|
</div>
|
|
143
154
|
<div class="timeline-middle">
|
|
144
|
-
<div
|
|
155
|
+
<div
|
|
156
|
+
class="w-1.5 h-1.5 rounded-full bg-primary/50"
|
|
157
|
+
></div>
|
|
145
158
|
</div>
|
|
146
|
-
<div
|
|
159
|
+
<div
|
|
160
|
+
class="timeline-end text-[10px] truncate max-w-[160px]"
|
|
161
|
+
>
|
|
147
162
|
{log.what}
|
|
148
163
|
</div>
|
|
149
|
-
{#if i !== logs.length - 1}<hr
|
|
164
|
+
{#if i !== logs.length - 1}<hr
|
|
165
|
+
class="bg-base-content/10"
|
|
166
|
+
/>{/if}
|
|
150
167
|
</li>
|
|
151
168
|
{/each}
|
|
152
169
|
</ul>
|