Skip to content

Commit 3365675

Browse files
committed
Move static constants, pure functions, and config objects to <script module>
Also fix pre-existing prettier issue in vite.config.ts
1 parent 4e1679f commit 3365675

10 files changed

Lines changed: 181 additions & 144 deletions

File tree

src/lib/components/ControlModules/impl/ActionButtons.svelte

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
<script lang="ts">
2-
import { Loader, Volume2, Waves, Zap } from '@lucide/svelte';
1+
<script lang="ts" module>
2+
import { Volume2, Waves, Zap } from '@lucide/svelte';
33
import { buttonVariants } from '$lib/components/ui/button/button.svelte';
44
import { ControlType } from '$lib/signalr/models/ControlType';
5+
6+
const Buttons = [
7+
{ type: ControlType.Sound, Icon: Volume2 },
8+
{ type: ControlType.Vibrate, Icon: Waves },
9+
{ type: ControlType.Shock, Icon: Zap },
10+
];
11+
12+
const buttonClasses = buttonVariants({ variant: 'secondary', size: 'default' });
13+
</script>
14+
15+
<script lang="ts">
16+
import { Loader } from '@lucide/svelte';
517
import type { TimeoutHandle } from '$lib/types/WAPI';
618
import { cn } from '$lib/utils';
719
import { onDestroy } from 'svelte';
@@ -32,14 +44,6 @@
3244
ctrl(type);
3345
}
3446
35-
const Buttons = [
36-
{ type: ControlType.Sound, Icon: Volume2 },
37-
{ type: ControlType.Vibrate, Icon: Waves },
38-
{ type: ControlType.Shock, Icon: Zap },
39-
];
40-
41-
const buttonClasses = buttonVariants({ variant: 'secondary', size: 'default' });
42-
4347
onDestroy(() => clearTimeout(timeoutHandle));
4448
</script>
4549

src/lib/components/ControlModules/impl/CircleSlider.svelte

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
<script lang="ts">
2-
import { RadToDeg, clamp, getCircleX, getCircleY, invLerp, lerp } from '$lib/utils/math';
3-
import { onDestroy } from 'svelte';
4-
import { cubicOut } from 'svelte/easing';
5-
import { Tween } from 'svelte/motion';
1+
<script lang="ts" module>
2+
import { getCircleX, getCircleY } from '$lib/utils/math';
63
74
// Gauge constants
85
const viewHeight = 100;
@@ -16,6 +13,21 @@
1613
const arcStartX = centerX + getCircleX(radius, angleStart);
1714
const arcStartY = centerY + getCircleY(radius, angleStart);
1815
16+
function calcSvgPathData(angleEnd: number) {
17+
const arcEndX = centerX + getCircleX(radius, angleEnd);
18+
const arcEndY = centerY + getCircleY(radius, angleEnd);
19+
const largeArcFlag = angleEnd - angleStart < 180 ? 0 : 1;
20+
21+
return `M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${arcEndX} ${arcEndY}`;
22+
}
23+
</script>
24+
25+
<script lang="ts">
26+
import { RadToDeg, clamp, invLerp, lerp } from '$lib/utils/math';
27+
import { onDestroy } from 'svelte';
28+
import { cubicOut } from 'svelte/easing';
29+
import { Tween } from 'svelte/motion';
30+
1931
// Unique gauge IDs
2032
const id = $props.id();
2133
const inputId = id + '-input';
@@ -119,14 +131,6 @@
119131
120132
// Update visual progress
121133
let degrees = $derived(angleStart + invLerp(min, max, tween.current) * angleRange);
122-
123-
function calcSvgPathData(angleEnd: number) {
124-
const arcEndX = centerX + getCircleX(radius, angleEnd);
125-
const arcEndY = centerY + getCircleY(radius, angleEnd);
126-
const largeArcFlag = angleEnd - angleStart < 180 ? 0 : 1;
127-
128-
return `M ${arcStartX} ${arcStartY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${arcEndX} ${arcEndY}`;
129-
}
130134
</script>
131135

132136
<div class="relative size-[150px] select-none">

src/lib/components/auth/oauth-buttons.svelte

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
<script lang="ts">
2-
import { Button } from '$lib/components/ui/button/index.js';
3-
import { Field } from '$lib/components/ui/field/index.js';
4-
import { GetOAuthAuthorizeUrl } from '$lib/api/next/oauth';
1+
<script lang="ts" module>
52
import XLogo from '../svg/XLogo.svelte';
63
import DiscordLogo from '../svg/DiscordLogo.svelte';
74
import GoogleLogo from '../svg/GoogleLogo.svelte';
8-
import { LogIn } from '@lucide/svelte';
9-
import { backendMetadata } from '$lib/state/backend-metadata-state.svelte';
105
116
const providerDetails: Record<string, { icon: typeof XLogo; label: string }> = {
127
discord: { icon: DiscordLogo, label: 'Discord' },
138
twitter: { icon: XLogo, label: 'X (Twitter)' },
149
google: { icon: GoogleLogo, label: 'Google' },
1510
};
11+
</script>
12+
13+
<script lang="ts">
14+
import { Button } from '$lib/components/ui/button/index.js';
15+
import { Field } from '$lib/components/ui/field/index.js';
16+
import { GetOAuthAuthorizeUrl } from '$lib/api/next/oauth';
17+
import { LogIn } from '@lucide/svelte';
18+
import { backendMetadata } from '$lib/state/backend-metadata-state.svelte';
1619
1720
let { verb = 'Login' }: { verb?: string } = $props();
1821

src/routes/(app)/admin/+layout.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
<script lang="ts" module>
2+
import { RoleType } from '$lib/api/internal/v1';
3+
4+
const allowedRoles = [RoleType.Admin, RoleType.System];
5+
</script>
6+
17
<script lang="ts">
28
import { resolve } from '$app/paths';
3-
import { RoleType } from '$lib/api/internal/v1';
49
import { Button } from '$lib/components/ui/button';
510
import { userState } from '$lib/state/user-state.svelte';
611
import type { Snippet } from 'svelte';
@@ -11,7 +16,6 @@
1116
1217
let { children }: Props = $props();
1318
14-
const allowedRoles = [RoleType.Admin, RoleType.System];
1519
let isAdmin = $derived(
1620
userState.self ? userState.self.roles.some((role) => allowedRoles.includes(role)) : false
1721
);

src/routes/(app)/admin/users/+page.svelte

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
<script lang="ts">
2-
import type { SortingState } from '@tanstack/table-core';
1+
<script lang="ts" module>
32
import type { ColumnDef } from '@tanstack/table-core';
4-
import { adminApi } from '$lib/api';
5-
import type { AdminUsersView, AdminUsersViewPaginated } from '$lib/api/internal/v1';
3+
import type { AdminUsersView } from '$lib/api/internal/v1';
64
import { PasswordHashingAlgorithm, RoleType } from '$lib/api/internal/v1';
7-
import Container from '$lib/components/Container.svelte';
85
import {
96
CreateSortableColumnDef,
107
LocaleDateTimeRenderer,
@@ -14,13 +11,7 @@
1411
RenderOrangeCell,
1512
RenderRedCell,
1613
} from '$lib/components/Table/ColumnUtils';
17-
import DataTable from '$lib/components/Table/DataTableTemplate.svelte';
18-
import PaginationFooter from '$lib/components/Table/PaginationFooter.svelte';
19-
import { CardHeader, CardTitle } from '$lib/components/ui/card';
2014
import { renderComponent } from '$lib/components/ui/data-table';
21-
import { Input } from '$lib/components/ui/input';
22-
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
23-
import type { TimeoutHandle } from '$lib/types/WAPI';
2415
import DataTableActions from './data-table-actions.svelte';
2516
2617
const PasswordHashTypeRenderer = (passwordHashType: PasswordHashingAlgorithm) => {
@@ -54,26 +45,6 @@
5445
},
5546
];
5647
57-
let isFetching = $state(false);
58-
59-
let requestedPage = $state(1);
60-
let requestedPageSize = $state(100);
61-
62-
let page = $state(0);
63-
let perPage = $state(0);
64-
let total = $state(0);
65-
let data = $state<AdminUsersView[]>([]);
66-
67-
let nameSearch = $state('');
68-
let emailSearch = $state('');
69-
70-
let sorting = $state<SortingState>([]);
71-
72-
let filterQuery = $state<string>();
73-
let orderByQuery = $derived(
74-
sorting.length > 0 ? sorting[0].id + ' ' + (sorting[0].desc ? 'desc' : 'asc') : undefined
75-
);
76-
7748
function escapeQuotes(str: string) {
7849
if (/[ '"\\]/.test(str)) {
7950
const escaped = str.replace(/(['"\\])/g, '\\$1');
@@ -99,6 +70,39 @@
9970
const operator = hasWildcard ? 'ilike' : 'eq';
10071
return `${key} ${operator} ${escaped}`;
10172
}
73+
</script>
74+
75+
<script lang="ts">
76+
import type { SortingState } from '@tanstack/table-core';
77+
import { adminApi } from '$lib/api';
78+
import type { AdminUsersViewPaginated } from '$lib/api/internal/v1';
79+
import Container from '$lib/components/Container.svelte';
80+
import DataTable from '$lib/components/Table/DataTableTemplate.svelte';
81+
import PaginationFooter from '$lib/components/Table/PaginationFooter.svelte';
82+
import { CardHeader, CardTitle } from '$lib/components/ui/card';
83+
import { Input } from '$lib/components/ui/input';
84+
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
85+
import type { TimeoutHandle } from '$lib/types/WAPI';
86+
87+
let isFetching = $state(false);
88+
89+
let requestedPage = $state(1);
90+
let requestedPageSize = $state(100);
91+
92+
let page = $state(0);
93+
let perPage = $state(0);
94+
let total = $state(0);
95+
let data = $state<AdminUsersView[]>([]);
96+
97+
let nameSearch = $state('');
98+
let emailSearch = $state('');
99+
100+
let sorting = $state<SortingState>([]);
101+
102+
let filterQuery = $state<string>();
103+
let orderByQuery = $derived(
104+
sorting.length > 0 ? sorting[0].id + ' ' + (sorting[0].desc ? 'desc' : 'asc') : undefined
105+
);
102106
103107
function handleResponse(response: AdminUsersViewPaginated) {
104108
total = response.total;

src/routes/(app)/hubs/[hubId=guid]/update/+page.svelte

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,6 @@
1-
<script lang="ts">
2-
import { AlertTriangle, CheckCircle2, CircleX, DownloadCloud, RotateCcw } from '@lucide/svelte';
3-
import { page } from '$app/state';
4-
import { hubManagementV1Api } from '$lib/api';
5-
import { type OtaItem, OtaUpdateStatus } from '$lib/api/internal/v1';
6-
import Container from '$lib/components/Container.svelte';
7-
import FirmwareChannelSelector from '$lib/components/FirmwareChannelSelector.svelte';
8-
import { Badge } from '$lib/components/ui/badge';
9-
import Button from '$lib/components/ui/button/button.svelte';
10-
import * as Card from '$lib/components/ui/card';
11-
import * as Dialog from '$lib/components/ui/dialog';
12-
import { Progress } from '$lib/components/ui/progress';
13-
import * as Table from '$lib/components/ui/table';
14-
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
15-
import { getConnection } from '$lib/signalr/user.svelte';
1+
<script lang="ts" module>
2+
import { OtaUpdateStatus } from '$lib/api/internal/v1';
163
import { OtaUpdateProgressTask } from '$lib/signalr/models/OtaUpdateProgressTask';
17-
import { serializeOtaInstallMessage } from '$lib/signalr/serializers/OtaInstall';
18-
import { breadcrumbs } from '$lib/state/breadcrumbs-state.svelte';
19-
import {
20-
HubOnlineState,
21-
onlineHubs,
22-
ownHubs,
23-
refreshOwnHubs,
24-
} from '$lib/state/hubs-state.svelte';
25-
import { cn } from '$lib/utils';
26-
import { NumberToHexPadded } from '$lib/utils/convert';
27-
import { onMount } from 'svelte';
28-
import type { FirmwareChannel } from '$lib/api/firmwareCDN';
294
305
// Task weights for weighted total progress (7 tasks, sums to 100)
316
const TASK_WEIGHTS = [4, 2, 22, 2, 49, 1, 20];
@@ -76,6 +51,39 @@
7651
return 'just now';
7752
}
7853
54+
// Simulated reboot progress (last 20%) — hub goes offline so no more events
55+
const REBOOT_DURATION_MS = 10_000;
56+
const REBOOT_INTERVAL_MS = 100;
57+
</script>
58+
59+
<script lang="ts">
60+
import { AlertTriangle, CheckCircle2, CircleX, DownloadCloud, RotateCcw } from '@lucide/svelte';
61+
import { page } from '$app/state';
62+
import { hubManagementV1Api } from '$lib/api';
63+
import type { OtaItem } from '$lib/api/internal/v1';
64+
import Container from '$lib/components/Container.svelte';
65+
import FirmwareChannelSelector from '$lib/components/FirmwareChannelSelector.svelte';
66+
import { Badge } from '$lib/components/ui/badge';
67+
import Button from '$lib/components/ui/button/button.svelte';
68+
import * as Card from '$lib/components/ui/card';
69+
import * as Dialog from '$lib/components/ui/dialog';
70+
import { Progress } from '$lib/components/ui/progress';
71+
import * as Table from '$lib/components/ui/table';
72+
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
73+
import { getConnection } from '$lib/signalr/user.svelte';
74+
import { serializeOtaInstallMessage } from '$lib/signalr/serializers/OtaInstall';
75+
import { breadcrumbs } from '$lib/state/breadcrumbs-state.svelte';
76+
import {
77+
HubOnlineState,
78+
onlineHubs,
79+
ownHubs,
80+
refreshOwnHubs,
81+
} from '$lib/state/hubs-state.svelte';
82+
import { cn } from '$lib/utils';
83+
import { NumberToHexPadded } from '$lib/utils/convert';
84+
import { onMount } from 'svelte';
85+
import type { FirmwareChannel } from '$lib/api/firmwareCDN';
86+
7987
let hubLoaded = $state(false);
8088
let otaLogs = $state<OtaItem[]>([]);
8189
let version = $state<string | null>(null);
@@ -92,9 +100,6 @@
92100
93101
let isUpdating = $derived(hub?.otaInstall !== null && hub?.otaInstall !== undefined);
94102
95-
// Simulated reboot progress (last 20%) — hub goes offline so no more events
96-
const REBOOT_DURATION_MS = 10_000;
97-
const REBOOT_INTERVAL_MS = 100;
98103
let rebootProgress = $state(0);
99104
let rebootInterval: ReturnType<typeof setInterval> | null = null;
100105

src/routes/(app)/settings/api-tokens/dialog-token-create.svelte

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,7 @@
1-
<script lang="ts">
1+
<script lang="ts" module>
22
import type { ZonedDateTime } from '@internationalized/date';
3-
import { apiTokensApi } from '$lib/api';
4-
import { PermissionType, type TokenCreatedResponse } from '$lib/api/internal/v1';
5-
import DateTimePicker from '$lib/components/datetime-picker/date-time-picker.svelte';
6-
import TextInput from '$lib/components/input/TextInput.svelte';
7-
import Button from '$lib/components/ui/button/button.svelte';
8-
import * as Dialog from '$lib/components/ui/dialog';
9-
import * as Select from '$lib/components/ui/select';
10-
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
11-
import { GetValResColor, type ValidationResult } from '$lib/types/ValidationResult';
12-
import { elapsedToString } from '$lib/utils';
13-
14-
interface Props {
15-
open: boolean;
16-
onCreated: (token: TokenCreatedResponse) => void;
17-
}
18-
19-
let { open = $bindable(), onCreated }: Props = $props();
20-
21-
let name = $state<string>('');
22-
let expire = $state<'never' | `${number}days` | 'custom'>('never');
23-
let expireCustom = $state<ZonedDateTime | undefined>(undefined);
24-
let permissions = $state<PermissionType[]>([PermissionType.ShockersUse]);
25-
26-
function onOpenChange(o: boolean) {
27-
// Stupid hack because when this dialog closes its state is never cleared... ._.
28-
if (!o) {
29-
name = '';
30-
expire = 'never';
31-
expireCustom = undefined;
32-
permissions = [PermissionType.ShockersUse];
33-
}
34-
open = o;
35-
}
3+
import { PermissionType } from '$lib/api/internal/v1';
4+
import type { ValidationResult } from '$lib/types/ValidationResult';
365
376
type PermissionCategory = {
387
name: string;
@@ -78,6 +47,42 @@
7847
function capitalizeFirstLetter(string: string) {
7948
return string.charAt(0).toUpperCase() + string.slice(1);
8049
}
50+
</script>
51+
52+
<script lang="ts">
53+
import { apiTokensApi } from '$lib/api';
54+
import type { TokenCreatedResponse } from '$lib/api/internal/v1';
55+
import DateTimePicker from '$lib/components/datetime-picker/date-time-picker.svelte';
56+
import TextInput from '$lib/components/input/TextInput.svelte';
57+
import Button from '$lib/components/ui/button/button.svelte';
58+
import * as Dialog from '$lib/components/ui/dialog';
59+
import * as Select from '$lib/components/ui/select';
60+
import { handleApiError } from '$lib/errorhandling/apiErrorHandling';
61+
import { GetValResColor } from '$lib/types/ValidationResult';
62+
import { elapsedToString } from '$lib/utils';
63+
64+
interface Props {
65+
open: boolean;
66+
onCreated: (token: TokenCreatedResponse) => void;
67+
}
68+
69+
let { open = $bindable(), onCreated }: Props = $props();
70+
71+
let name = $state<string>('');
72+
let expire = $state<'never' | `${number}days` | 'custom'>('never');
73+
let expireCustom = $state<ZonedDateTime | undefined>(undefined);
74+
let permissions = $state<PermissionType[]>([PermissionType.ShockersUse]);
75+
76+
function onOpenChange(o: boolean) {
77+
// Stupid hack because when this dialog closes its state is never cleared... ._.
78+
if (!o) {
79+
name = '';
80+
expire = 'never';
81+
expireCustom = undefined;
82+
permissions = [PermissionType.ShockersUse];
83+
}
84+
open = o;
85+
}
8186
8287
let nameValidationResult = $derived(nameValidation(name));
8388
let expireValidationResult = $derived(expireValidation(expire, expireCustom));

0 commit comments

Comments
 (0)