mirror of
https://github.com/unraid/api.git
synced 2026-05-06 23:20:30 -05:00
277ac42046
## Summary Introduces a new Vue-based Docker container management interface replacing the legacy webgui table. ### Container Management - Start, stop, pause, resume, and remove containers via GraphQL mutations - Bulk actions for managing multiple containers at once - Container update detection with one-click updates - Real-time container statistics (CPU, memory, I/O) ### Organization & Navigation - Folder-based container organization with drag-and-drop support - Accessible reordering via keyboard controls - Customizable column visibility with persistent preferences - Column resizing and reordering - Filtering and search across container properties ### Auto-start Configuration - Dedicated autostart view with delay configuration - Drag-and-drop reordering of start/stop sequences ### Logs & Console - Integrated log viewer with filtering and download - Persistent console sessions with shell selection - Slideover panel for quick access ### Networking - Port conflict detection and alerts - Tailscale integration for container networking status - LAN IP and port information display ### Additional Features - Orphaned container detection and cleanup - Template mapping management - Critical notifications system - WebUI visit links with Tailscale support <sub>PR Summary by Claude Opus 4.5</sub>
122 lines
4.3 KiB
TypeScript
122 lines
4.3 KiB
TypeScript
import { Args, ResolveField, Resolver } from '@nestjs/graphql';
|
|
|
|
import { AuthAction, Resource } from '@unraid/shared/graphql.model.js';
|
|
import { PrefixedID } from '@unraid/shared/prefixed-id-scalar.js';
|
|
import { UsePermissions } from '@unraid/shared/use-permissions.directive.js';
|
|
|
|
import { UseFeatureFlag } from '@app/unraid-api/decorators/use-feature-flag.decorator.js';
|
|
import {
|
|
DockerAutostartEntryInput,
|
|
DockerContainer,
|
|
} from '@app/unraid-api/graph/resolvers/docker/docker.model.js';
|
|
import { DockerService } from '@app/unraid-api/graph/resolvers/docker/docker.service.js';
|
|
import { DockerMutations } from '@app/unraid-api/graph/resolvers/mutation/mutation.model.js';
|
|
|
|
/**
|
|
* Nested Resolvers for Mutations MUST use @ResolveField() instead of @Mutation()
|
|
*/
|
|
@Resolver(() => DockerMutations)
|
|
export class DockerMutationsResolver {
|
|
constructor(private readonly dockerService: DockerService) {}
|
|
|
|
@ResolveField(() => DockerContainer, { description: 'Start a container' })
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async start(@Args('id', { type: () => PrefixedID }) id: string) {
|
|
return this.dockerService.start(id);
|
|
}
|
|
|
|
@ResolveField(() => DockerContainer, { description: 'Stop a container' })
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async stop(@Args('id', { type: () => PrefixedID }) id: string) {
|
|
return this.dockerService.stop(id);
|
|
}
|
|
@ResolveField(() => DockerContainer, { description: 'Pause (Suspend) a container' })
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async pause(@Args('id', { type: () => PrefixedID }) id: string) {
|
|
return this.dockerService.pause(id);
|
|
}
|
|
@ResolveField(() => DockerContainer, { description: 'Unpause (Resume) a container' })
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async unpause(@Args('id', { type: () => PrefixedID }) id: string) {
|
|
return this.dockerService.unpause(id);
|
|
}
|
|
|
|
@ResolveField(() => Boolean, { description: 'Remove a container' })
|
|
@UsePermissions({
|
|
action: AuthAction.DELETE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async removeContainer(
|
|
@Args('id', { type: () => PrefixedID }) id: string,
|
|
@Args('withImage', { type: () => Boolean, nullable: true }) withImage?: boolean
|
|
) {
|
|
return this.dockerService.removeContainer(id, { withImage });
|
|
}
|
|
|
|
@ResolveField(() => Boolean, {
|
|
description: 'Update auto-start configuration for Docker containers',
|
|
})
|
|
@UseFeatureFlag('ENABLE_NEXT_DOCKER_RELEASE')
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async updateAutostartConfiguration(
|
|
@Args('entries', { type: () => [DockerAutostartEntryInput] })
|
|
entries: DockerAutostartEntryInput[],
|
|
@Args('persistUserPreferences', { type: () => Boolean, nullable: true })
|
|
persistUserPreferences?: boolean
|
|
) {
|
|
await this.dockerService.updateAutostartConfiguration(entries, {
|
|
persistUserPreferences,
|
|
});
|
|
return true;
|
|
}
|
|
|
|
@ResolveField(() => DockerContainer, { description: 'Update a container to the latest image' })
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async updateContainer(@Args('id', { type: () => PrefixedID }) id: string) {
|
|
return this.dockerService.updateContainer(id);
|
|
}
|
|
|
|
@ResolveField(() => [DockerContainer], {
|
|
description: 'Update multiple containers to the latest images',
|
|
})
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async updateContainers(
|
|
@Args('ids', { type: () => [PrefixedID] })
|
|
ids: string[]
|
|
) {
|
|
return this.dockerService.updateContainers(ids);
|
|
}
|
|
|
|
@ResolveField(() => [DockerContainer], {
|
|
description: 'Update all containers that have available updates',
|
|
})
|
|
@UsePermissions({
|
|
action: AuthAction.UPDATE_ANY,
|
|
resource: Resource.DOCKER,
|
|
})
|
|
public async updateAllContainers() {
|
|
return this.dockerService.updateAllContainers();
|
|
}
|
|
}
|