Skip to content

Commit 82a04c5

Browse files
author
mdatelle
committed
refactor: use new new button variants in updated components
1 parent 6e98e3b commit 82a04c5

File tree

9 files changed

+92
-64
lines changed

9 files changed

+92
-64
lines changed

web/components/Activation/Steps.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const steps: readonly Step[] = [
8585
<StepperTrigger>
8686
<div class="flex items-center justify-center">
8787
<Button
88-
:variant="state === 'completed' ? 'primary' : state === 'active' ? 'primary' : 'outline'"
88+
:variant="state === 'completed' ? 'primary' : state === 'active' ? 'primary' : 'secondary'"
8989
size="md"
9090
:class="`z-10 rounded-full ${
9191
state !== 'inactive'

web/components/Auth.ce.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const { authAction, stateData } = storeToRefs(serverStore);
2020
</span>
2121
<span v-if="authAction">
2222
<Button
23-
variant="brand"
23+
variant="primary"
2424
:disabled="authAction?.disabled"
2525
:icon="authAction.icon"
2626
size="md"

web/components/ConnectSettings/ConnectSettings.ce.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ const onChange = ({ data }: { data: Record<string, unknown> }) => {
120120
</div>
121121
<div class="col-start-2 ml-10 space-y-4">
122122
<Button
123-
variant="outline-brand"
123+
variant="secondary"
124124
padding="lean"
125125
size="md"
126126
class="leading-normal"

web/components/DownloadApiLogs.ce.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const downloadUrl = computed(() => {
2828
<span class="flex flex-col gap-y-16px">
2929
<div class="flex">
3030
<Button
31-
variant="brand"
31+
variant="primary"
3232
class="grow-0 shrink-0"
3333
download
3434
:external="true"

web/components/Logs/SingleLogViewer.vue

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
<script setup lang="ts">
22
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
3-
import { useQuery, useApolloClient } from '@vue/apollo-composable';
3+
import { useApolloClient, useQuery } from '@vue/apollo-composable';
44
import { vInfiniteScroll } from '@vueuse/components';
5-
import { ArrowPathIcon, ArrowDownTrayIcon } from '@heroicons/vue/24/outline';
6-
import { Button, Tooltip, TooltipProvider, TooltipTrigger, TooltipContent } from '@unraid/ui';
7-
import DOMPurify from 'isomorphic-dompurify';
5+
6+
import { ArrowDownTrayIcon, ArrowPathIcon } from '@heroicons/vue/24/outline';
7+
import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@unraid/ui';
88
import hljs from 'highlight.js/lib/core';
9+
import DOMPurify from 'isomorphic-dompurify';
10+
911
import 'highlight.js/styles/github-dark.css'; // You can choose a different style
10-
import { useThemeStore } from '~/store/theme';
1112
12-
// Register the languages you want to support
13-
import plaintext from 'highlight.js/lib/languages/plaintext';
13+
import apache from 'highlight.js/lib/languages/apache';
1414
import bash from 'highlight.js/lib/languages/bash';
1515
import ini from 'highlight.js/lib/languages/ini';
16-
import xml from 'highlight.js/lib/languages/xml';
16+
import javascript from 'highlight.js/lib/languages/javascript';
1717
import json from 'highlight.js/lib/languages/json';
18-
import yaml from 'highlight.js/lib/languages/yaml';
1918
import nginx from 'highlight.js/lib/languages/nginx';
20-
import apache from 'highlight.js/lib/languages/apache';
21-
import javascript from 'highlight.js/lib/languages/javascript';
2219
import php from 'highlight.js/lib/languages/php';
20+
// Register the languages you want to support
21+
import plaintext from 'highlight.js/lib/languages/plaintext';
22+
import xml from 'highlight.js/lib/languages/xml';
23+
import yaml from 'highlight.js/lib/languages/yaml';
2324
2425
import type { LogFileContentQuery, LogFileContentQueryVariables } from '~/composables/gql/graphql';
26+
27+
import { useThemeStore } from '~/store/theme';
2528
import { GET_LOG_FILE_CONTENT } from './log.query';
2629
import { LOG_FILE_SUBSCRIPTION } from './log.subscription';
2730
@@ -61,7 +64,7 @@ const state = reactive({
6164
canLoadMore: false,
6265
initialLoadComplete: false,
6366
isDownloading: false,
64-
isSubscriptionActive: false
67+
isSubscriptionActive: false,
6568
});
6669
6770
// Get Apollo client for direct queries
@@ -117,15 +120,15 @@ onMounted(() => {
117120
118121
// Set subscription as active when we receive data
119122
state.isSubscriptionActive = true;
120-
123+
121124
const existingContent = prev.logFile?.content || '';
122125
const newContent = subscriptionData.data.logFile.content;
123-
126+
124127
// Update the local state with the new content
125128
if (newContent && state.loadedContentChunks.length > 0) {
126129
const lastChunk = state.loadedContentChunks[state.loadedContentChunks.length - 1];
127130
lastChunk.content += newContent;
128-
131+
129132
// Force scroll to bottom if auto-scroll is enabled
130133
if (props.autoScroll) {
131134
nextTick(() => forceScrollToBottom());
@@ -142,7 +145,7 @@ onMounted(() => {
142145
};
143146
},
144147
});
145-
148+
146149
// Set subscription as active
147150
state.isSubscriptionActive = true;
148151
}
@@ -158,18 +161,18 @@ watch(
158161
logContentResult,
159162
(newResult) => {
160163
if (!newResult?.logFile) return;
161-
164+
162165
const { content, startLine } = newResult.logFile;
163166
const effectiveStartLine = startLine || 1;
164167
165168
if (state.isLoadingMore) {
166169
state.loadedContentChunks.unshift({ content, startLine: effectiveStartLine });
167170
state.isLoadingMore = false;
168171
169-
nextTick(() => state.canLoadMore = true);
172+
nextTick(() => (state.canLoadMore = true));
170173
} else {
171174
state.loadedContentChunks = [{ content, startLine: effectiveStartLine }];
172-
175+
173176
nextTick(() => {
174177
forceScrollToBottom();
175178
state.initialLoadComplete = true;
@@ -190,29 +193,29 @@ const highlightLog = (content: string): string => {
190193
try {
191194
// Determine which language to use for highlighting
192195
const language = props.highlightLanguage || defaultLanguage;
193-
196+
194197
// Apply syntax highlighting
195198
let highlighted = hljs.highlight(content, { language }).value;
196-
199+
197200
// Apply additional custom highlighting for common log patterns
198-
201+
199202
// Highlight timestamps (various formats)
200203
highlighted = highlighted.replace(
201204
/\b(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\b/g,
202205
'<span class="hljs-timestamp">$1</span>'
203206
);
204-
207+
205208
// Highlight IP addresses
206209
highlighted = highlighted.replace(
207210
/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/g,
208211
'<span class="hljs-ip">$1</span>'
209212
);
210-
213+
211214
// Split the content into lines
212215
let lines = highlighted.split('\n');
213-
216+
214217
// Process each line to add error, warning, and success highlighting
215-
lines = lines.map(line => {
218+
lines = lines.map((line) => {
216219
if (/(error|exception|fail|failed|failure)/i.test(line)) {
217220
// Highlight error keywords
218221
line = line.replace(
@@ -223,10 +226,7 @@ const highlightLog = (content: string): string => {
223226
return `<span class="hljs-error">${line}</span>`;
224227
} else if (/(warning|warn)/i.test(line)) {
225228
// Highlight warning keywords
226-
line = line.replace(
227-
/\b(warning|warn)\b/gi,
228-
'<span class="hljs-warning-keyword">$1</span>'
229-
);
229+
line = line.replace(/\b(warning|warn)\b/gi, '<span class="hljs-warning-keyword">$1</span>');
230230
// Wrap the entire line
231231
return `<span class="hljs-warning">${line}</span>`;
232232
} else if (/(success|successful|completed|done)/i.test(line)) {
@@ -240,10 +240,10 @@ const highlightLog = (content: string): string => {
240240
}
241241
return line;
242242
});
243-
243+
244244
// Join the lines back together
245245
highlighted = lines.join('\n');
246-
246+
247247
// Sanitize the highlighted HTML
248248
return DOMPurify.sanitize(highlighted);
249249
} catch (error) {
@@ -255,7 +255,7 @@ const highlightLog = (content: string): string => {
255255
256256
// Computed properties
257257
const logContent = computed(() => {
258-
const rawContent = state.loadedContentChunks.map(chunk => chunk.content).join('');
258+
const rawContent = state.loadedContentChunks.map((chunk) => chunk.content).join('');
259259
return highlightLog(rawContent);
260260
});
261261
@@ -294,13 +294,13 @@ const loadMoreContent = async () => {
294294
// Download log file
295295
const downloadLogFile = async () => {
296296
if (!props.logFilePath || state.isDownloading) return;
297-
297+
298298
try {
299299
state.isDownloading = true;
300-
300+
301301
// Get the filename from the path
302302
const fileName = props.logFilePath.split('/').pop() || 'log.txt';
303-
303+
304304
// Query for the entire log file content
305305
const result = await client.query({
306306
query: GET_LOG_FILE_CONTENT,
@@ -310,24 +310,24 @@ const downloadLogFile = async () => {
310310
},
311311
fetchPolicy: 'network-only',
312312
});
313-
313+
314314
if (!result.data?.logFile?.content) {
315315
throw new Error('Failed to fetch log content');
316316
}
317-
317+
318318
// Create a blob with the content
319319
const blob = new Blob([result.data.logFile.content], { type: 'text/plain' });
320-
320+
321321
// Create a download link
322322
const url = URL.createObjectURL(blob);
323323
const link = document.createElement('a');
324324
link.href = url;
325325
link.download = fileName;
326-
326+
327327
// Trigger the download
328328
document.body.appendChild(link);
329329
link.click();
330-
330+
331331
// Clean up
332332
document.body.removeChild(link);
333333
URL.revokeObjectURL(url);
@@ -348,7 +348,7 @@ const refreshLogContent = () => {
348348
state.initialLoadComplete = false;
349349
state.isLoadingMore = false;
350350
refetchLogContent();
351-
351+
352352
nextTick(() => {
353353
forceScrollToBottom();
354354
});
@@ -360,13 +360,18 @@ defineExpose({ refreshLogContent });
360360

361361
<template>
362362
<div class="flex flex-col h-full max-h-full overflow-hidden">
363-
<div class="flex justify-between px-4 py-2 bg-muted text-xs text-muted-foreground shrink-0 items-center">
363+
<div
364+
class="flex justify-between px-4 py-2 bg-muted text-xs text-muted-foreground shrink-0 items-center"
365+
>
364366
<div class="flex items-center gap-2">
365367
<span>Total lines: {{ totalLines }}</span>
366368
<TooltipProvider v-if="state.isSubscriptionActive">
367369
<Tooltip :delay-duration="300">
368370
<TooltipTrigger as-child>
369-
<div class="w-2 h-2 rounded-full bg-green-500 animate-pulse cursor-help" aria-hidden="true"></div>
371+
<div
372+
class="w-2 h-2 rounded-full bg-green-500 animate-pulse cursor-help"
373+
aria-hidden="true"
374+
></div>
370375
</TooltipTrigger>
371376
<TooltipContent>
372377
<p>Watching log file</p>
@@ -376,42 +381,62 @@ defineExpose({ refreshLogContent });
376381
</div>
377382
<span>{{ state.isAtTop ? 'Showing all available lines' : 'Scroll up to load more' }}</span>
378383
<div class="flex gap-2">
379-
<Button variant="outline" :disabled="loadingLogContent || state.isDownloading" @click="downloadLogFile">
380-
<ArrowDownTrayIcon class="h-3 w-3 mr-1" :class="{ 'animate-pulse': state.isDownloading }" aria-hidden="true" />
384+
<Button
385+
variant="secondary"
386+
:disabled="loadingLogContent || state.isDownloading"
387+
@click="downloadLogFile"
388+
>
389+
<ArrowDownTrayIcon
390+
class="h-3 w-3 mr-1"
391+
:class="{ 'animate-pulse': state.isDownloading }"
392+
aria-hidden="true"
393+
/>
381394
<span class="text-sm">{{ state.isDownloading ? 'Downloading...' : 'Download' }}</span>
382395
</Button>
383-
<Button variant="outline" :disabled="loadingLogContent" @click="refreshLogContent">
396+
<Button variant="secondary" :disabled="loadingLogContent" @click="refreshLogContent">
384397
<ArrowPathIcon class="h-3 w-3 mr-1" aria-hidden="true" />
385398
<span class="text-sm">Refresh</span>
386399
</Button>
387400
</div>
388401
</div>
389402

390-
<div v-if="loadingLogContent && !state.isLoadingMore" class="flex items-center justify-center flex-1 p-4 text-muted-foreground">
403+
<div
404+
v-if="loadingLogContent && !state.isLoadingMore"
405+
class="flex items-center justify-center flex-1 p-4 text-muted-foreground"
406+
>
391407
Loading log content...
392408
</div>
393409

394-
<div v-else-if="logContentError" class="flex items-center justify-center flex-1 p-4 text-destructive">
410+
<div
411+
v-else-if="logContentError"
412+
class="flex items-center justify-center flex-1 p-4 text-destructive"
413+
>
395414
Error loading log content: {{ logContentError.message }}
396415
</div>
397416

398417
<div
399418
v-else
400419
ref="scrollViewportRef"
401-
v-infinite-scroll="[loadMoreContent, { direction: 'top', distance: 200, canLoadMore: () => shouldLoadMore }]"
420+
v-infinite-scroll="[
421+
loadMoreContent,
422+
{ direction: 'top', distance: 200, canLoadMore: () => shouldLoadMore },
423+
]"
402424
class="flex-1 overflow-y-auto"
403425
:class="{ 'theme-dark': isDarkMode, 'theme-light': !isDarkMode }"
404426
>
405427
<!-- Loading indicator for loading more content -->
406-
<div v-if="state.isLoadingMore" class="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm border-b border-border rounded-md mx-2 mt-2">
428+
<div
429+
v-if="state.isLoadingMore"
430+
class="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm border-b border-border rounded-md mx-2 mt-2"
431+
>
407432
<div class="flex items-center justify-center p-2 text-xs text-primary-foreground">
408433
<ArrowPathIcon class="h-3 w-3 mr-2 animate-spin" aria-hidden="true" />
409434
Loading more lines...
410435
</div>
411436
</div>
412-
413-
<pre
414-
class="font-mono whitespace-pre-wrap p-4 m-0 text-xs leading-6 hljs"
437+
438+
<pre
439+
class="font-mono whitespace-pre-wrap p-4 m-0 text-xs leading-6 hljs"
415440
:class="{ 'theme-dark': isDarkMode, 'theme-light': !isDarkMode }"
416441
v-html="logContent"
417442
></pre>

web/components/Notifications/Item.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
2-
import { Markdown } from '@/helpers/markdown';
2+
import { useMutation } from '@vue/apollo-composable';
3+
34
import {
45
ArchiveBoxIcon,
56
CheckBadgeIcon,
@@ -9,8 +10,10 @@ import {
910
TrashIcon,
1011
} from '@heroicons/vue/24/solid';
1112
import { Button } from '@unraid/ui';
12-
import { useMutation } from '@vue/apollo-composable';
13+
import { Markdown } from '@/helpers/markdown';
14+
1315
import type { NotificationFragmentFragment } from '~/composables/gql/graphql';
16+
1417
import { NotificationType } from '~/composables/gql/graphql';
1518
import {
1619
archiveNotification as archiveMutation,
@@ -117,7 +120,7 @@ const reformattedTimestamp = computed<string>(() => {
117120

118121
<div class="flex justify-end items-baseline gap-4">
119122
<a v-if="link" :href="link">
120-
<Button type="button" variant="outline">
123+
<Button type="button" variant="secondary">
121124
<LinkIcon class="size-4 mr-2" />
122125
<span class="text-sm">View</span>
123126
</Button>

web/components/Registration.ce.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ const items = computed((): RegistrationItemProps[] => {
288288
/>
289289
<span v-if="authAction" class="grow-0">
290290
<Button
291-
variant="brand"
291+
variant="primary"
292292
:disabled="authAction?.disabled"
293293
:icon="authAction.icon"
294294
:title="authAction.title ? t(authAction.title) : undefined"

0 commit comments

Comments
 (0)