Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6de6f09
table > select & status badge
pujitm Sep 17, 2025
a2f85fc
fix context menu trigger area and dropdown styles
pujitm Sep 18, 2025
92262d4
implement 'move to folder'
pujitm Sep 18, 2025
8a0fde7
implement 'start / stop' bulk & row actions
pujitm Sep 18, 2025
d301edd
implement pause / resume
pujitm Sep 19, 2025
2877810
implement column visibility customization
pujitm Sep 19, 2025
9136e41
fix(organizer): over-eager addition of untracked containers to root f…
pujitm Sep 22, 2025
a993fad
scaffold docker form service
pujitm Sep 22, 2025
2e938ce
docker container management prototype
pujitm Sep 22, 2025
8d46d86
use compacted table as sidebar tree
pujitm Sep 24, 2025
4e07bb9
add drag and drop for re-ordering containers & folders
pujitm Sep 24, 2025
6fb9b70
right click to reame & delete folders
pujitm Sep 24, 2025
930a7f4
add bottom padding to container to make it easier to drag items to bo…
pujitm Sep 24, 2025
c1f7294
click overview row to open details
pujitm Sep 25, 2025
7aca685
track active container in query param
pujitm Sep 25, 2025
6b9b4a8
refactor: extract composables
pujitm Oct 13, 2025
fc13447
refactor: simplify organizer operations
pujitm Oct 13, 2025
5bee590
refactor!: rm intermediate tree resolution of organizers
pujitm Oct 13, 2025
8fb7b73
fix: rm extra Root layer in table
pujitm Oct 13, 2025
903b51b
map containers to their template files
pujitm Oct 14, 2025
ed8810a
feat: icon support
pujitm Oct 14, 2025
811fbfe
fix: rm usage of 'dark' class; use css vars instead
pujitm Oct 14, 2025
31f7a6c
fix: container state badge
pujitm Oct 14, 2025
c9c053d
chore: fix formatting
pujitm Oct 14, 2025
821d2dc
fix: search filtering
pujitm Oct 14, 2025
5e2263e
fix: context menu
pujitm Oct 14, 2025
4a1ce15
feat: filtering & bulk actions in compact mode
pujitm Oct 15, 2025
e02920a
feat: critical notifications
pujitm Oct 15, 2025
1cb3a74
feat: notifyIfUnique service method
pujitm Oct 15, 2025
77df006
tmp: critical notifications system
pujitm Oct 20, 2025
31fd727
fix: nuxt ui portal styling
pujitm Oct 23, 2025
b4526b6
fix: notifications type check
pujitm Oct 23, 2025
79f874a
fix api tests
pujitm Oct 27, 2025
234c2e2
fix: css
pujitm Oct 27, 2025
8d63e53
Revert "fix: css"
pujitm Oct 28, 2025
dcef442
add docker constants
pujitm Oct 28, 2025
62fea59
flatten css scopes
pujitm Oct 28, 2025
c13d395
feat: file modification for replacing docker overview table
pujitm Oct 28, 2025
f16b586
feat: navigate to container update page
pujitm Oct 28, 2025
8aa0178
feat: implement manage settings action
pujitm Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PATHS_LOGS_FILE=./dev/log/graphql-api.log
PATHS_CONNECT_STATUS_FILE_PATH=./dev/connectStatus.json # Connect plugin status file
PATHS_OIDC_JSON=./dev/configs/oidc.local.json
PATHS_LOCAL_SESSION_FILE=./dev/local-session
PATHS_DOCKER_TEMPLATES=./dev/docker-templates
ENVIRONMENT="development"
NODE_ENV="development"
PORT="3001"
Expand Down
3 changes: 3 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,6 @@ dev/configs/oidc.local.json

# local api keys
dev/keys/*

# dev docker templates
dev/docker-templates
178 changes: 104 additions & 74 deletions api/generated-schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,12 @@ type DockerMutations {

"""Stop a container"""
stop(id: PrefixedID!): DockerContainer!

"""Pause (Suspend) a container"""
pause(id: PrefixedID!): DockerContainer!

"""Unpause (Resume) a container"""
unpause(id: PrefixedID!): DockerContainer!
}

type VmMutations {
Expand Down Expand Up @@ -1102,12 +1108,14 @@ type DockerContainer implements Node {
networkSettings: JSON
mounts: [JSON!]
autoStart: Boolean!
templatePath: String
isUpdateAvailable: Boolean
isRebuildReady: Boolean
}

enum ContainerState {
RUNNING
PAUSED
EXITED
}

Expand All @@ -1133,45 +1141,110 @@ type Docker implements Node {
id: PrefixedID!
containers(skipCache: Boolean! = false): [DockerContainer!]!
networks(skipCache: Boolean! = false): [DockerNetwork!]!
organizer: ResolvedOrganizerV1!
organizer(skipCache: Boolean! = false): ResolvedOrganizerV1!
containerUpdateStatuses: [ExplicitStatusItem!]!
}

type ResolvedOrganizerView {
id: String!
name: String!
root: ResolvedOrganizerEntry!
prefs: JSON
type DockerContainerOverviewForm {
id: ID!
dataSchema: JSON!
uiSchema: JSON!
data: JSON!
}

union ResolvedOrganizerEntry = ResolvedOrganizerFolder | OrganizerContainerResource | OrganizerResource
type NotificationCounts {
info: Int!
warning: Int!
alert: Int!
total: Int!
}

type ResolvedOrganizerFolder {
id: String!
type: String!
name: String!
children: [ResolvedOrganizerEntry!]!
type NotificationOverview {
unread: NotificationCounts!
archive: NotificationCounts!
}

type OrganizerContainerResource {
id: String!
type: String!
name: String!
meta: DockerContainer
type Notification implements Node {
id: PrefixedID!

"""Also known as 'event'"""
title: String!
subject: String!
description: String!
importance: NotificationImportance!
link: String
type: NotificationType!

"""ISO Timestamp for when the notification occurred"""
timestamp: String
formattedTimestamp: String
}

enum NotificationImportance {
ALERT
INFO
WARNING
}

enum NotificationType {
UNREAD
ARCHIVE
}

type Notifications implements Node {
id: PrefixedID!

"""A cached overview of the notifications in the system & their severity."""
overview: NotificationOverview!
list(filter: NotificationFilter!): [Notification!]!

"""
Deduplicated list of unread warning and alert notifications, sorted latest first.
"""
warningsAndAlerts: [Notification!]!
}

input NotificationFilter {
importance: NotificationImportance
type: NotificationType!
offset: Int!
limit: Int!
}

type OrganizerResource {
type DockerTemplateSyncResult {
scanned: Int!
matched: Int!
skipped: Int!
errors: [String!]!
}

type ResolvedOrganizerView {
id: String!
type: String!
name: String!
meta: JSON
rootId: String!
flatEntries: [FlatOrganizerEntry!]!
prefs: JSON
}

type ResolvedOrganizerV1 {
version: Float!
views: [ResolvedOrganizerView!]!
}

type FlatOrganizerEntry {
id: String!
type: String!
name: String!
parentId: String
depth: Float!
position: Float!
path: [String!]!
hasChildren: Boolean!
childrenIds: [String!]!
meta: DockerContainer
icon: String
}

type FlashBackupStatus {
"""Status message indicating the outcome of the backup initiation."""
status: String!
Expand Down Expand Up @@ -1753,60 +1826,6 @@ type Metrics implements Node {
memory: MemoryUtilization
}

type NotificationCounts {
info: Int!
warning: Int!
alert: Int!
total: Int!
}

type NotificationOverview {
unread: NotificationCounts!
archive: NotificationCounts!
}

type Notification implements Node {
id: PrefixedID!

"""Also known as 'event'"""
title: String!
subject: String!
description: String!
importance: NotificationImportance!
link: String
type: NotificationType!

"""ISO Timestamp for when the notification occurred"""
timestamp: String
formattedTimestamp: String
}

enum NotificationImportance {
ALERT
INFO
WARNING
}

enum NotificationType {
UNREAD
ARCHIVE
}

type Notifications implements Node {
id: PrefixedID!

"""A cached overview of the notifications in the system & their severity."""
overview: NotificationOverview!
list(filter: NotificationFilter!): [Notification!]!
}

input NotificationFilter {
importance: NotificationImportance
type: NotificationType!
offset: Int!
limit: Int!
}

type Owner {
username: String!
url: String!
Expand Down Expand Up @@ -2369,6 +2388,7 @@ type Query {
publicPartnerInfo: PublicPartnerInfo
publicTheme: Theme!
docker: Docker!
dockerContainerOverviewForm(skipCache: Boolean! = false): DockerContainerOverviewForm!
disks: [Disk!]!
disk(id: PrefixedID!): Disk!
rclone: RCloneBackupSettings!
Expand Down Expand Up @@ -2416,6 +2436,11 @@ type Mutation {
"""Marks a notification as archived."""
archiveNotification(id: PrefixedID!): Notification!
archiveNotifications(ids: [PrefixedID!]!): NotificationOverview!

"""
Creates a notification if an equivalent unread notification does not already exist.
"""
notifyIfUnique(input: NotificationData!): Notification
archiveAll(importance: NotificationImportance): NotificationOverview!

"""Marks a notification as unread."""
Expand All @@ -2435,6 +2460,10 @@ type Mutation {
setDockerFolderChildren(folderId: String, childrenIds: [String!]!): ResolvedOrganizerV1!
deleteDockerEntries(entryIds: [String!]!): ResolvedOrganizerV1!
moveDockerEntriesToFolder(sourceEntryIds: [String!]!, destinationFolderId: String!): ResolvedOrganizerV1!
moveDockerItemsToPosition(sourceEntryIds: [String!]!, destinationFolderId: String!, position: Float!): ResolvedOrganizerV1!
renameDockerFolder(folderId: String!, newName: String!): ResolvedOrganizerV1!
createDockerFolderWithItems(name: String!, parentId: String, sourceEntryIds: [String!], position: Float): ResolvedOrganizerV1!
syncDockerTemplatePaths: DockerTemplateSyncResult!
refreshDockerDigests: Boolean!

"""Initiates a flash drive backup using a configured remote."""
Expand Down Expand Up @@ -2636,6 +2665,7 @@ input AccessUrlInput {
type Subscription {
notificationAdded: Notification!
notificationsOverview: NotificationOverview!
notificationsWarningsAndAlerts: [Notification!]!
ownerSubscription: Owner!
serversSubscription: Server!
parityHistorySubscription: ParityCheck!
Expand Down
1 change: 1 addition & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"escape-html": "1.0.3",
"execa": "9.6.0",
"exit-hook": "4.0.0",
"fast-xml-parser": "^5.3.0",
"fastify": "5.5.0",
"filenamify": "7.0.0",
"fs-extra": "11.3.1",
Expand Down
2 changes: 1 addition & 1 deletion api/src/core/utils/misc/catch-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AppError } from '@app/core/errors/app-error.js';
import { getters } from '@app/store/index.js';

interface DockerError extends NodeJS.ErrnoException {
address: string;
address?: string;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions api/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,10 @@ export const PATHS_CONFIG_MODULES =
export const PATHS_LOCAL_SESSION_FILE =
process.env.PATHS_LOCAL_SESSION_FILE ?? '/var/run/unraid-api/local-session';

export const PATHS_DOCKER_TEMPLATES = process.env.PATHS_DOCKER_TEMPLATES?.split(',') ?? [
'/boot/config/plugins/dockerMan/templates-user',
'/boot/config/plugins/dockerMan/templates',
];

/** feature flag for the upcoming docker release */
export const ENABLE_NEXT_DOCKER_RELEASE = process.env.ENABLE_NEXT_DOCKER_RELEASE === 'true';
Loading
Loading