Skip to content

Commit 5caa143

Browse files
authored
Merge pull request #167 from AnthonyGress/dev
Add 24 hour time support, allow custom theme color, allow network shares in disk monitor, add quality check
2 parents 7917875 + 2aadb85 commit 5caa143

39 files changed

+671
-230
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: quality-check
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
quality-check:
8+
permissions:
9+
contents: read
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout git repo
13+
uses: actions/checkout@v4
14+
15+
- name: Install Node and NPM
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version: 20
19+
20+
- name: Install dependencies
21+
run: |
22+
npm install
23+
24+
- name: Build - Backend
25+
run: |
26+
cd backend
27+
npm run build
28+
29+
- name: Build - Frontend
30+
run: |
31+
cd frontend
32+
npm run build
33+
34+
- name: Build - Docker
35+
run: |
36+
npm run docker:build
37+

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ dist-ssr
2323
*.sln
2424
*.sw?
2525
build
26-
backend/src/config/config.json
26+
backend/src/config/config*.json
2727
backend/src/config/users.json
2828
backend/src/config/backups
2929
backend/src/public/uploads

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ services:
4646
- /docker/lab-dash/uploads:/app/public/uploads
4747
- /var/run/docker.sock:/var/run/docker.sock
4848
restart: unless-stopped
49-
labels:
50-
- "com.centurylinklabs.watchtower.enable=true"
51-
5249
```
5350
5451
# Usage
@@ -103,5 +100,12 @@ npm run dev
103100
- `docker compose pull`
104101
- `docker compose up -d`
105102
103+
# Contributing
104+
Contributions to Lab Dash are welcome! Please follow these guidelines:
105+
106+
- **One feature per PR** - Keep pull requests focused on a single feature or fix
107+
- **Review AI-generated code** - If using AI tools, all code must be thoroughly reviewed and tested before submitting
108+
- **Maintain consistency** - New code must align with the app's existing style, theme, and overall user experience
109+
106110
# Disclaimer
107111
This code is provided for informational and educational purposes only. I am not associated with any of the services/applications mentioned in this project.

backend/src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export type Config = {
3838
isSetupComplete?: boolean;
3939
lastSeenVersion?: string;
4040
notes?: Note[];
41+
themeColor?: string;
4142
}
4243

4344
export type Note = {

docker-compose.yml

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
---
22
services:
33
lab-dash:
4-
container_name: lab-dash
5-
image: ghcr.io/anthonygress/lab-dash:latest
6-
privileged: true
7-
#network_mode: host # for monitoring network usage stats. run `sudo ufw allow 2022/tcp` on ubuntu to allow access through firewall
8-
ports:
9-
- 2022:2022
10-
environment:
11-
- SECRET=YOUR_SECRET_KEY # any random string for used for encryption.
12-
# You can run `openssl rand -base64 32` to generate a key
13-
volumes:
14-
- /sys:/sys:ro
15-
- /docker/lab-dash/config:/config
16-
- /docker/lab-dash/uploads:/app/public/uploads
17-
- /var/run/docker.sock:/var/run/docker.sock
18-
restart: unless-stopped
19-
labels:
20-
- "com.centurylinklabs.watchtower.enable=true"
4+
container_name: lab-dash
5+
image: ghcr.io/anthonygress/lab-dash:latest
6+
privileged: true
7+
#network_mode: host # for monitoring network usage stats. run `sudo ufw allow 2022/tcp` on ubuntu to allow access through firewall
8+
ports:
9+
- 2022:2022
10+
environment:
11+
- SECRET=YOUR_SECRET_KEY # any random string for used for encryption.
12+
# You can run `openssl rand -base64 32` to generate a key
13+
volumes:
14+
- /sys:/sys:ro
15+
- /docker/lab-dash/config:/config
16+
- /docker/lab-dash/uploads:/app/public/uploads
17+
- /var/run/docker.sock:/var/run/docker.sock
18+
restart: unless-stopped

frontend/src/components/dashboard/DashboardGrid.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,8 @@ export const DashboardGrid: React.FC = () => {
616616
const createDateTimeConfig = (config: any) => {
617617
return {
618618
location: config?.location || null,
619-
timezone: config?.timezone || undefined
619+
timezone: config?.timezone || undefined,
620+
use24Hour: config?.use24Hour || false
620621
};
621622
};
622623

frontend/src/components/dashboard/base-items/widgets/DateTimeWidget.tsx

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type DateTimeWidgetConfig = {
1212
longitude: number;
1313
} | null;
1414
timezone?: string;
15+
use24Hour?: boolean;
1516
};
1617

1718
type DateTimeWidgetProps = {
@@ -135,27 +136,63 @@ export const DateTimeWidget = ({ config }: DateTimeWidgetProps) => {
135136

136137
// Create formatter functions with the timezone
137138
const getFormattedTime = () => {
139+
const use24Hour = config?.use24Hour === true;
140+
138141
try {
139-
if (config?.timezone) {
140-
const options: Intl.DateTimeFormatOptions = {
141-
hour: 'numeric',
142-
minute: '2-digit',
143-
timeZone: config.timezone
144-
};
145-
return new Intl.DateTimeFormat([], options).format(dateTime);
142+
if (use24Hour) {
143+
// For 24-hour format, manually format to avoid locale issues
144+
let hours: number;
145+
let minutes: number;
146+
147+
if (config?.timezone) {
148+
// Get hours and minutes in the specified timezone
149+
const formatter = new Intl.DateTimeFormat('en-US', {
150+
hour: 'numeric',
151+
minute: 'numeric',
152+
hour12: false,
153+
timeZone: config.timezone
154+
});
155+
const parts = formatter.formatToParts(dateTime);
156+
hours = parseInt(parts.find(p => p.type === 'hour')?.value || '0');
157+
minutes = parseInt(parts.find(p => p.type === 'minute')?.value || '0');
158+
} else {
159+
hours = dateTime.getHours();
160+
minutes = dateTime.getMinutes();
161+
}
162+
163+
// Format as HH:MM
164+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
165+
} else {
166+
// For 12-hour format, use standard formatting
167+
if (config?.timezone) {
168+
const options: Intl.DateTimeFormatOptions = {
169+
hour: 'numeric',
170+
minute: '2-digit',
171+
timeZone: config.timezone,
172+
hour12: true
173+
};
174+
return new Intl.DateTimeFormat('en-US', options).format(dateTime);
175+
} else {
176+
return dateTime.toLocaleTimeString('en-US', {
177+
hour: 'numeric',
178+
minute: '2-digit',
179+
hour12: true
180+
});
181+
}
146182
}
147-
148-
// Fallback to local time if no timezone provided
149-
return dateTime.toLocaleTimeString([], {
150-
hour: 'numeric',
151-
minute: '2-digit'
152-
});
153183
} catch (error) {
154184
console.error('Error formatting time with timezone:', error);
155-
return dateTime.toLocaleTimeString([], {
156-
hour: 'numeric',
157-
minute: '2-digit'
158-
});
185+
if (use24Hour) {
186+
const hours = dateTime.getHours();
187+
const minutes = dateTime.getMinutes();
188+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
189+
} else {
190+
return dateTime.toLocaleTimeString('en-US', {
191+
hour: 'numeric',
192+
minute: '2-digit',
193+
hour12: true
194+
});
195+
}
159196
}
160197
};
161198

frontend/src/components/dashboard/base-items/widgets/DiskMonitorWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ export const DiskMonitorWidget = ({ config, editMode }: DiskMonitorWidgetProps)
281281
left: 0,
282282
width: `${displayUsagePercent}%`,
283283
height: '100%',
284-
backgroundColor: theme.palette.primary.main,
284+
backgroundColor: 'primary.main',
285285
cursor: 'pointer'
286286
}}
287287
/>

frontend/src/components/dashboard/base-items/widgets/DownloadClientWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ const DownloadItem: React.FC<DownloadItemProps> = ({ torrent, clientName, isAdmi
426426
'& .MuiLinearProgress-bar': {
427427
backgroundColor:
428428
torrent.state === 'downloading' ? 'primary.main' :
429-
torrent.state.includes('seed') || torrent.state.includes('upload') ? theme.palette.primary.main :
429+
torrent.state.includes('seed') || torrent.state.includes('upload') ? 'primary.main' :
430430
torrent.progress === 1 ? 'success.main' : 'warning.main'
431431
}
432432
}}

frontend/src/components/dashboard/base-items/widgets/NotesWidget/MarkdownPreview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export const MarkdownPreview: React.FC<MarkdownPreviewProps> = ({ content, fontS
6767
fontStyle: 'italic'
6868
},
6969
'& a': {
70-
color: theme.palette.primary.main,
70+
color: 'primary.main',
7171
textDecoration: 'underline'
7272
},
7373
'& strong': {

0 commit comments

Comments
 (0)