mirror of
https://github.com/unraid/api.git
synced 2026-01-24 01:18:39 -06:00
docker container management prototype
This commit is contained in:
2
web/components.d.ts
vendored
2
web/components.d.ts
vendored
@@ -45,9 +45,11 @@ declare module 'vue' {
|
||||
'DevModalTest.standalone': typeof import('./src/components/DevModalTest.standalone.vue')['default']
|
||||
DevSettings: typeof import('./src/components/DevSettings.vue')['default']
|
||||
'DevThemeSwitcher.standalone': typeof import('./src/components/DevThemeSwitcher.standalone.vue')['default']
|
||||
DockerContainerManagement: typeof import('./src/components/Docker/DockerContainerManagement.vue')['default']
|
||||
DockerContainerOverview: typeof import('./src/components/Docker/DockerContainerOverview.vue')['default']
|
||||
'DockerContainerOverview.standalone': typeof import('./src/components/Docker/DockerContainerOverview.standalone.vue')['default']
|
||||
DockerContainersTable: typeof import('./src/components/Docker/DockerContainersTable.vue')['default']
|
||||
DockerSidebarTree: typeof import('./src/components/Docker/DockerSidebarTree.vue')['default']
|
||||
Downgrade: typeof import('./src/components/UpdateOs/Downgrade.vue')['default']
|
||||
'DowngradeOs.standalone': typeof import('./src/components/DowngradeOs.standalone.vue')['default']
|
||||
'DownloadApiLogs.standalone': typeof import('./src/components/DownloadApiLogs.standalone.vue')['default']
|
||||
|
||||
231
web/src/components/Docker/DockerContainerManagement.vue
Normal file
231
web/src/components/Docker/DockerContainerManagement.vue
Normal file
@@ -0,0 +1,231 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useQuery } from '@vue/apollo-composable';
|
||||
|
||||
import { GET_DOCKER_CONTAINERS } from '@/components/Docker/docker-containers.query';
|
||||
import DockerSidebarTree from '@/components/Docker/DockerSidebarTree.vue';
|
||||
import DockerEdit from '@/components/Docker/Edit.vue';
|
||||
import DockerLogs from '@/components/Docker/Logs.vue';
|
||||
import DockerOverview from '@/components/Docker/Overview.vue';
|
||||
import DockerPreview from '@/components/Docker/Preview.vue';
|
||||
|
||||
import type {
|
||||
DockerContainer,
|
||||
OrganizerContainerResource,
|
||||
ResolvedOrganizerEntry,
|
||||
ResolvedOrganizerFolder,
|
||||
} from '@/composables/gql/graphql';
|
||||
|
||||
interface Props {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
const selectedIds = ref<string[]>([]);
|
||||
const activeId = ref<string | null>(null);
|
||||
const isSwitching = ref(false);
|
||||
|
||||
const { result, loading, error, refetch } = useQuery<{
|
||||
docker: {
|
||||
id: string;
|
||||
organizer: {
|
||||
views: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
root: ResolvedOrganizerEntry;
|
||||
}>;
|
||||
};
|
||||
containers: DockerContainer[];
|
||||
};
|
||||
}>(GET_DOCKER_CONTAINERS, {
|
||||
fetchPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const organizerRoot = computed(
|
||||
() => result.value?.docker?.organizer?.views?.[0]?.root as ResolvedOrganizerFolder | undefined
|
||||
);
|
||||
|
||||
function findContainerResourceById(
|
||||
entry: ResolvedOrganizerEntry | undefined,
|
||||
id: string
|
||||
): ResolvedOrganizerEntry | undefined {
|
||||
if (!entry) return undefined;
|
||||
if (entry.__typename === 'OrganizerContainerResource' && entry.id === id) return entry;
|
||||
if (entry.__typename === 'ResolvedOrganizerFolder') {
|
||||
for (const child of entry.children as ResolvedOrganizerEntry[]) {
|
||||
const found = findContainerResourceById(child, id);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function findFirstContainerId(entry?: ResolvedOrganizerEntry | null): string | null {
|
||||
if (!entry) return null;
|
||||
if (entry.__typename === 'OrganizerContainerResource') return entry.id;
|
||||
if (entry.__typename === 'ResolvedOrganizerFolder') {
|
||||
for (const child of entry.children) {
|
||||
const found = findFirstContainerId(child);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => organizerRoot.value,
|
||||
(root) => {
|
||||
if (!activeId.value) {
|
||||
activeId.value = findFirstContainerId(root);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
function handleSidebarClick(item: { id: string }) {
|
||||
if (activeId.value === item.id) return;
|
||||
isSwitching.value = true;
|
||||
activeId.value = item.id;
|
||||
// simulate fetch delay; real details queries will naturally set loading
|
||||
setTimeout(() => {
|
||||
isSwitching.value = false;
|
||||
}, 150);
|
||||
}
|
||||
|
||||
function handleSidebarSelect(item: { id: string; selected: boolean }) {
|
||||
const set = new Set(selectedIds.value);
|
||||
if (item.selected) set.add(item.id);
|
||||
else set.delete(item.id);
|
||||
selectedIds.value = Array.from(set);
|
||||
}
|
||||
|
||||
const activeContainer = computed<DockerContainer | undefined>(() => {
|
||||
if (!activeId.value) return undefined;
|
||||
const resource = findContainerResourceById(
|
||||
organizerRoot.value,
|
||||
activeId.value
|
||||
) as OrganizerContainerResource;
|
||||
return resource?.meta as DockerContainer | undefined;
|
||||
});
|
||||
|
||||
// Details data (mix of real and placeholder until specific queries exist)
|
||||
const detailsItem = computed(() => {
|
||||
const name = (activeContainer.value?.names?.[0] || '').replace(/^\//, '') || 'Unknown';
|
||||
return {
|
||||
id: activeContainer.value?.id || 'unknown',
|
||||
label: name,
|
||||
icon: 'i-lucide-box',
|
||||
};
|
||||
});
|
||||
|
||||
const details = computed(() => {
|
||||
const c = activeContainer.value;
|
||||
if (!c) return undefined;
|
||||
const network = c.hostConfig?.networkMode || 'bridge';
|
||||
const publicPort = c.ports?.find((p) => p.publicPort)?.publicPort;
|
||||
return {
|
||||
network,
|
||||
lanIpPort: publicPort ? `127.0.0.1:${publicPort}` : '—',
|
||||
containerIp: c.networkSettings?.IPAddress || '—',
|
||||
uptime: '—',
|
||||
containerPort: c.ports?.[0]?.privatePort?.toString?.() || '—',
|
||||
creationDate: new Date((c.created || 0) * 1000).toISOString(),
|
||||
containerId: c.id,
|
||||
maintainer: c.labels?.maintainer || '—',
|
||||
};
|
||||
});
|
||||
|
||||
const isDetailsLoading = computed(() => loading.value || isSwitching.value);
|
||||
const isDetailsDisabled = computed(() => props.disabled || isSwitching.value);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid gap-6 md:grid-cols-[280px_1fr]">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="font-medium">Containers</div>
|
||||
<UButton
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
icon="i-lucide-refresh-cw"
|
||||
:loading="loading"
|
||||
@click="
|
||||
() => {
|
||||
refetch({ skipCache: true });
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<USkeleton v-if="loading && !organizerRoot" class="h-6 w-full" :ui="{ rounded: 'rounded' }" />
|
||||
<DockerSidebarTree
|
||||
v-else
|
||||
:root="organizerRoot"
|
||||
:selected-ids="selectedIds"
|
||||
:active-id="activeId"
|
||||
:disabled="props.disabled || loading"
|
||||
@item:click="handleSidebarClick"
|
||||
@item:select="handleSidebarSelect"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
<div>
|
||||
<UCard class="mb-4">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="font-medium">Overview</div>
|
||||
<UBadge
|
||||
v-if="activeContainer?.state"
|
||||
:label="activeContainer.state"
|
||||
color="primary"
|
||||
variant="subtle"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<div class="relative">
|
||||
<div v-if="isDetailsLoading" class="pointer-events-none opacity-50">
|
||||
<DockerOverview :item="detailsItem" :details="details" />
|
||||
</div>
|
||||
<DockerOverview v-else :item="detailsItem" :details="details" />
|
||||
<div v-if="isDetailsLoading" class="absolute inset-0 grid place-items-center">
|
||||
<ULoader class="h-6 w-6" />
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<div class="3xl:grid-cols-2 grid gap-4">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="font-medium">Preview</div>
|
||||
</template>
|
||||
<div :class="{ 'pointer-events-none opacity-50': isDetailsDisabled }">
|
||||
<DockerPreview :item="detailsItem" :port="details?.containerPort || undefined" />
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="font-medium">Edit</div>
|
||||
</template>
|
||||
<div :class="{ 'pointer-events-none opacity-50': isDetailsDisabled }">
|
||||
<DockerEdit :item="detailsItem" />
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<UCard class="mt-4">
|
||||
<template #header>
|
||||
<div class="font-medium">Logs</div>
|
||||
</template>
|
||||
<div :class="{ 'pointer-events-none opacity-50': isDetailsDisabled }">
|
||||
<DockerLogs :item="detailsItem" />
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import DockerContainerManagement from '@/components/Docker/DockerContainerManagement.vue';
|
||||
import DockerContainerOverview from '@/components/Docker/DockerContainerOverview.vue';
|
||||
import DockerEdit from '@/components/Docker/Edit.vue';
|
||||
import DockerLogs from '@/components/Docker/Logs.vue';
|
||||
@@ -19,6 +20,7 @@ const details = {
|
||||
</script>
|
||||
<template>
|
||||
<div class="grid gap-8">
|
||||
<DockerContainerManagement />
|
||||
<DockerContainerOverview />
|
||||
<DockerOverview :item="item" :details="details" />
|
||||
<DockerPreview :item="item" />
|
||||
|
||||
270
web/src/components/Docker/DockerSidebarTree.vue
Normal file
270
web/src/components/Docker/DockerSidebarTree.vue
Normal file
@@ -0,0 +1,270 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { Box, ChevronRight, Cog, FolderOpen, FolderTree } from 'lucide-vue-next';
|
||||
|
||||
import type { ResolvedOrganizerEntry, ResolvedOrganizerFolder } from '@/composables/gql/graphql';
|
||||
|
||||
interface Emits {
|
||||
(e: 'item:click', item: { id: string; type: string; name: string }): void;
|
||||
(e: 'item:select', item: { id: string; type: string; name: string; selected: boolean }): void;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
root?: ResolvedOrganizerFolder;
|
||||
selectedIds?: string[];
|
||||
activeId?: string | null;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
selectedIds: () => [],
|
||||
activeId: null,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const isSelected = (id: string) => props.selectedIds?.includes(id);
|
||||
|
||||
function onClickEntry(entry: ResolvedOrganizerEntry) {
|
||||
if (props.disabled) return;
|
||||
if (entry.__typename === 'OrganizerContainerResource') {
|
||||
emit('item:click', { id: entry.id, type: entry.type, name: entry.name });
|
||||
}
|
||||
}
|
||||
|
||||
function isFolderEntry(entry: ResolvedOrganizerEntry): entry is ResolvedOrganizerFolder {
|
||||
return entry.__typename === 'ResolvedOrganizerFolder';
|
||||
}
|
||||
|
||||
function entryName(entry: ResolvedOrganizerEntry): string {
|
||||
if (isFolderEntry(entry)) return entry.name;
|
||||
if (entry.__typename === 'OrganizerContainerResource') return entry.name;
|
||||
return '';
|
||||
}
|
||||
|
||||
function onSelectEntry(entry: ResolvedOrganizerEntry, selected: boolean) {
|
||||
emit('item:select', { id: entry.id, type: entry.type, name: entryName(entry), selected });
|
||||
}
|
||||
|
||||
function onCheckboxChange(entry: ResolvedOrganizerEntry, value: boolean | 'indeterminate') {
|
||||
onSelectEntry(entry, value === true);
|
||||
}
|
||||
|
||||
const hasChildren = (entry: ResolvedOrganizerEntry) =>
|
||||
isFolderEntry(entry) && entry.children && entry.children.length > 0;
|
||||
|
||||
const entries = computed(() => props.root?.children ?? []);
|
||||
|
||||
const expandedIds = ref<Set<string>>(new Set());
|
||||
|
||||
const isExpanded = (id: string) => expandedIds.value.has(id);
|
||||
function toggleExpanded(id: string) {
|
||||
if (expandedIds.value.has(id)) {
|
||||
expandedIds.value.delete(id);
|
||||
} else {
|
||||
expandedIds.value.add(id);
|
||||
}
|
||||
expandedIds.value = new Set(expandedIds.value);
|
||||
}
|
||||
|
||||
function expand(id: string) {
|
||||
if (!expandedIds.value.has(id)) {
|
||||
expandedIds.value.add(id);
|
||||
expandedIds.value = new Set(expandedIds.value);
|
||||
}
|
||||
}
|
||||
|
||||
function flattenContainerEntries(entry: ResolvedOrganizerEntry): ResolvedOrganizerEntry[] {
|
||||
if (entry.__typename === 'OrganizerContainerResource') return [entry];
|
||||
if (isFolderEntry(entry)) {
|
||||
const children = entry.children ?? [];
|
||||
return children.flatMap((child) => flattenContainerEntries(child));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function folderSelectionState(folder: ResolvedOrganizerFolder): 'none' | 'partial' | 'all' {
|
||||
const containers = flattenContainerEntries(folder);
|
||||
if (containers.length === 0) return 'none';
|
||||
const selectedCount = containers.reduce((acc, e) => acc + (isSelected(e.id) ? 1 : 0), 0);
|
||||
if (selectedCount === 0) return 'none';
|
||||
if (selectedCount === containers.length) return 'all';
|
||||
return 'partial';
|
||||
}
|
||||
|
||||
function onFolderCheckboxChange(folder: ResolvedOrganizerFolder, value: boolean | 'indeterminate') {
|
||||
const containers = flattenContainerEntries(folder);
|
||||
const shouldSelectAll =
|
||||
value === true || (value === 'indeterminate' && folderSelectionState(folder) !== 'all');
|
||||
if (shouldSelectAll) expand(folder.id);
|
||||
for (const entry of containers) {
|
||||
const currentlySelected = isSelected(entry.id);
|
||||
if (shouldSelectAll && !currentlySelected) onSelectEntry(entry, true);
|
||||
if (!shouldSelectAll && currentlySelected) onSelectEntry(entry, false);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-2">
|
||||
<div v-if="!root" class="text-gray-500 dark:text-gray-400">No items</div>
|
||||
<ul v-else class="space-y-1">
|
||||
<li v-for="entry in entries" :key="entry.id">
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
v-if="isFolderEntry(entry)"
|
||||
class="inline-block h-4 w-4 transition-transform"
|
||||
:class="isExpanded(entry.id) ? 'rotate-90' : ''"
|
||||
:aria-expanded="isExpanded(entry.id) ? 'true' : 'false'"
|
||||
:disabled="disabled === true"
|
||||
@click="toggleExpanded(entry.id)"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</button>
|
||||
<span v-else class="inline-block h-4 w-4" />
|
||||
|
||||
<UCheckbox
|
||||
v-if="!isFolderEntry(entry)"
|
||||
:model-value="isSelected(entry.id)"
|
||||
:disabled="disabled === true"
|
||||
@click.stop
|
||||
@update:model-value="(v) => onCheckboxChange(entry, v)"
|
||||
/>
|
||||
<UCheckbox
|
||||
v-else
|
||||
:indeterminate="folderSelectionState(entry) === 'partial'"
|
||||
:model-value="folderSelectionState(entry) === 'all'"
|
||||
:disabled="disabled === true"
|
||||
@click.stop
|
||||
@update:model-value="(v) => onFolderCheckboxChange(entry, v)"
|
||||
/>
|
||||
|
||||
<button
|
||||
class="flex-1 flex-row justify-around truncate"
|
||||
:class="[
|
||||
isFolderEntry(entry)
|
||||
? 'cursor-pointer text-gray-700 dark:text-gray-200'
|
||||
: 'cursor-pointer',
|
||||
activeId === entry.id ? 'text-primary-600 dark:text-primary-400 font-medium' : '',
|
||||
]"
|
||||
:disabled="disabled === true"
|
||||
@click="isFolderEntry(entry) ? toggleExpanded(entry.id) : onClickEntry(entry)"
|
||||
>
|
||||
<FolderTree
|
||||
v-if="isFolderEntry(entry)"
|
||||
class="mr-1 inline-block h-4 w-4 align-middle text-amber-600 dark:text-amber-400"
|
||||
/>
|
||||
<Box
|
||||
v-else
|
||||
class="mr-1 inline-block h-4 w-4 align-middle text-blue-600 dark:text-blue-400"
|
||||
/>
|
||||
{{ entryName(entry) }}
|
||||
<FolderOpen
|
||||
v-if="isFolderEntry(entry)"
|
||||
class="ml-2 inline-block h-4 w-4 align-middle text-amber-600/80 dark:text-amber-400/80"
|
||||
/>
|
||||
<Cog
|
||||
v-else
|
||||
class="ml-2 inline-block h-4 w-4 align-middle text-blue-600/70 dark:text-blue-400/70"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul v-if="hasChildren(entry) && isExpanded(entry.id)" class="mt-1 ml-5 space-y-1">
|
||||
<li v-for="child in (entry as any).children" :key="child.id">
|
||||
<div class="flex items-center gap-2 text-sm md:text-[0.95rem]">
|
||||
<button
|
||||
v-if="isFolderEntry(child)"
|
||||
class="inline-block h-4 w-4 transition-transform"
|
||||
:class="isExpanded(child.id) ? 'rotate-90' : ''"
|
||||
:aria-expanded="isExpanded(child.id) ? 'true' : 'false'"
|
||||
:disabled="disabled === true"
|
||||
@click="toggleExpanded(child.id)"
|
||||
>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</button>
|
||||
<span v-else class="inline-block h-4 w-4" />
|
||||
|
||||
<UCheckbox
|
||||
v-if="!isFolderEntry(child)"
|
||||
:model-value="isSelected(child.id)"
|
||||
:disabled="disabled === true"
|
||||
@click.stop
|
||||
@update:model-value="(v) => onCheckboxChange(child, v)"
|
||||
/>
|
||||
<UCheckbox
|
||||
v-else
|
||||
:indeterminate="folderSelectionState(child) === 'partial'"
|
||||
:model-value="folderSelectionState(child) === 'all'"
|
||||
:disabled="disabled === true"
|
||||
@click.stop
|
||||
@update:model-value="(v) => onFolderCheckboxChange(child, v)"
|
||||
/>
|
||||
<button
|
||||
class="flex-1 truncate text-left"
|
||||
:class="[
|
||||
isFolderEntry(child)
|
||||
? 'cursor-pointer text-gray-700 dark:text-gray-200'
|
||||
: 'cursor-pointer',
|
||||
activeId === child.id ? 'text-primary-600 dark:text-primary-400 font-medium' : '',
|
||||
]"
|
||||
:disabled="disabled === true"
|
||||
@click="isFolderEntry(child) ? toggleExpanded(child.id) : onClickEntry(child)"
|
||||
>
|
||||
<FolderTree
|
||||
v-if="isFolderEntry(child)"
|
||||
class="mr-1 inline-block h-4 w-4 align-middle text-amber-600 dark:text-amber-400"
|
||||
/>
|
||||
<Box
|
||||
v-else
|
||||
class="mr-1 inline-block h-4 w-4 align-middle text-blue-600 dark:text-blue-400"
|
||||
/>
|
||||
{{ entryName(child) }}
|
||||
<FolderOpen
|
||||
v-if="isFolderEntry(child)"
|
||||
class="ml-2 inline-block h-4 w-4 align-middle text-amber-600/80 dark:text-amber-400/80"
|
||||
/>
|
||||
<Cog
|
||||
v-else
|
||||
class="ml-2 inline-block h-4 w-4 align-middle text-blue-600/70 dark:text-blue-400/70"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul v-if="hasChildren(child) && isExpanded(child.id)" class="mt-1 ml-5 space-y-1">
|
||||
<li v-for="grand in (child as any).children" :key="grand.id">
|
||||
<div class="flex items-center gap-2 text-sm md:text-[0.95rem]">
|
||||
<span class="inline-block h-4 w-4" />
|
||||
<UCheckbox
|
||||
:model-value="isSelected(grand.id)"
|
||||
:disabled="disabled === true"
|
||||
@click.stop
|
||||
@update:model-value="(v) => onCheckboxChange(grand, v)"
|
||||
/>
|
||||
<button
|
||||
class="flex-1 truncate text-left"
|
||||
:class="[
|
||||
activeId === grand.id ? 'text-primary-600 dark:text-primary-400 font-medium' : '',
|
||||
]"
|
||||
:disabled="disabled === true"
|
||||
@click="onClickEntry(grand)"
|
||||
>
|
||||
<Box
|
||||
class="mr-1 inline-block h-4 w-4 align-middle text-blue-600 dark:text-blue-400"
|
||||
/>
|
||||
{{ entryName(grand) }}
|
||||
<Cog
|
||||
class="ml-2 inline-block h-4 w-4 align-middle text-blue-600/70 dark:text-blue-400/70"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
28
web/src/components/Docker/docker-active-container.query.ts
Normal file
28
web/src/components/Docker/docker-active-container.query.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_DOCKER_ACTIVE_CONTAINER = gql`
|
||||
query GetDockerActiveContainer($id: PrefixedID!) {
|
||||
docker {
|
||||
id
|
||||
containers {
|
||||
id
|
||||
names
|
||||
image
|
||||
created
|
||||
state
|
||||
status
|
||||
autoStart
|
||||
ports {
|
||||
privatePort
|
||||
publicPort
|
||||
type
|
||||
}
|
||||
hostConfig {
|
||||
networkMode
|
||||
}
|
||||
networkSettings
|
||||
labels
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -28,14 +28,17 @@ type Documents = {
|
||||
"\n query GetPermissionsForRoles($roles: [Role!]!) {\n getPermissionsForRoles(roles: $roles) {\n resource\n actions\n }\n }\n": typeof types.GetPermissionsForRolesDocument,
|
||||
"\n query Unified {\n settings {\n unified {\n id\n dataSchema\n uiSchema\n values\n }\n }\n }\n": typeof types.UnifiedDocument,
|
||||
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": typeof types.UpdateConnectSettingsDocument,
|
||||
"\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports { privatePort publicPort type }\n hostConfig { networkMode }\n networkSettings\n labels\n }\n }\n }\n": typeof types.GetDockerActiveContainerDocument,
|
||||
"\n query GetDockerContainers($skipCache: Boolean = false) {\n docker {\n id\n organizer(skipCache: $skipCache) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n }\n }\n }\n": typeof types.GetDockerContainersDocument,
|
||||
"\n mutation CreateDockerFolder($name: String!, $parentId: String, $childrenIds: [String!]) {\n createDockerFolder(name: $name, parentId: $parentId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": typeof types.CreateDockerFolderDocument,
|
||||
"\n mutation DeleteDockerEntries($entryIds: [String!]!) {\n deleteDockerEntries(entryIds: $entryIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": typeof types.DeleteDockerEntriesDocument,
|
||||
"\n mutation MoveDockerEntriesToFolder($destinationFolderId: String!, $sourceEntryIds: [String!]!) {\n moveDockerEntriesToFolder(\n destinationFolderId: $destinationFolderId\n sourceEntryIds: $sourceEntryIds\n ) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": typeof types.MoveDockerEntriesToFolderDocument,
|
||||
"\n query GetDockerContainerOverviewForm($skipCache: Boolean = false) {\n dockerContainerOverviewForm(skipCache: $skipCache) {\n id\n dataSchema\n uiSchema\n data\n }\n }\n": typeof types.GetDockerContainerOverviewFormDocument,
|
||||
"\n mutation PauseDockerContainer($id: PrefixedID!) {\n docker {\n pause(id: $id) {\n id\n names\n state\n }\n }\n }\n": typeof types.PauseDockerContainerDocument,
|
||||
"\n mutation SetDockerFolderChildren($folderId: String, $childrenIds: [String!]!) {\n setDockerFolderChildren(folderId: $folderId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": typeof types.SetDockerFolderChildrenDocument,
|
||||
"\n mutation StartDockerContainer($id: PrefixedID!) {\n docker {\n start(id: $id) {\n id\n names\n state\n }\n }\n }\n": typeof types.StartDockerContainerDocument,
|
||||
"\n mutation StopDockerContainer($id: PrefixedID!) {\n docker {\n stop(id: $id) {\n id\n names\n state\n }\n }\n }\n": typeof types.StopDockerContainerDocument,
|
||||
"\n mutation UnpauseDockerContainer($id: PrefixedID!) {\n docker {\n unpause(id: $id) {\n id\n names\n state\n }\n }\n }\n": typeof types.UnpauseDockerContainerDocument,
|
||||
"\n query LogFiles {\n logFiles {\n name\n path\n size\n modifiedAt\n }\n }\n": typeof types.LogFilesDocument,
|
||||
"\n query LogFileContent($path: String!, $lines: Int, $startLine: Int) {\n logFile(path: $path, lines: $lines, startLine: $startLine) {\n path\n content\n totalLines\n startLine\n }\n }\n": typeof types.LogFileContentDocument,
|
||||
"\n subscription LogFileSubscription($path: String!) {\n logFile(path: $path) {\n path\n content\n totalLines\n }\n }\n": typeof types.LogFileSubscriptionDocument,
|
||||
@@ -81,14 +84,17 @@ const documents: Documents = {
|
||||
"\n query GetPermissionsForRoles($roles: [Role!]!) {\n getPermissionsForRoles(roles: $roles) {\n resource\n actions\n }\n }\n": types.GetPermissionsForRolesDocument,
|
||||
"\n query Unified {\n settings {\n unified {\n id\n dataSchema\n uiSchema\n values\n }\n }\n }\n": types.UnifiedDocument,
|
||||
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": types.UpdateConnectSettingsDocument,
|
||||
"\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports { privatePort publicPort type }\n hostConfig { networkMode }\n networkSettings\n labels\n }\n }\n }\n": types.GetDockerActiveContainerDocument,
|
||||
"\n query GetDockerContainers($skipCache: Boolean = false) {\n docker {\n id\n organizer(skipCache: $skipCache) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n meta {\n id\n names\n state\n status\n image\n ports {\n privatePort\n publicPort\n type\n }\n autoStart\n hostConfig {\n networkMode\n }\n created\n isUpdateAvailable\n isRebuildReady\n }\n }\n }\n }\n }\n }\n }\n": types.GetDockerContainersDocument,
|
||||
"\n mutation CreateDockerFolder($name: String!, $parentId: String, $childrenIds: [String!]) {\n createDockerFolder(name: $name, parentId: $parentId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": types.CreateDockerFolderDocument,
|
||||
"\n mutation DeleteDockerEntries($entryIds: [String!]!) {\n deleteDockerEntries(entryIds: $entryIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": types.DeleteDockerEntriesDocument,
|
||||
"\n mutation MoveDockerEntriesToFolder($destinationFolderId: String!, $sourceEntryIds: [String!]!) {\n moveDockerEntriesToFolder(\n destinationFolderId: $destinationFolderId\n sourceEntryIds: $sourceEntryIds\n ) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": types.MoveDockerEntriesToFolderDocument,
|
||||
"\n query GetDockerContainerOverviewForm($skipCache: Boolean = false) {\n dockerContainerOverviewForm(skipCache: $skipCache) {\n id\n dataSchema\n uiSchema\n data\n }\n }\n": types.GetDockerContainerOverviewFormDocument,
|
||||
"\n mutation PauseDockerContainer($id: PrefixedID!) {\n docker {\n pause(id: $id) {\n id\n names\n state\n }\n }\n }\n": types.PauseDockerContainerDocument,
|
||||
"\n mutation SetDockerFolderChildren($folderId: String, $childrenIds: [String!]!) {\n setDockerFolderChildren(folderId: $folderId, childrenIds: $childrenIds) {\n version\n views {\n id\n name\n root {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n children {\n __typename\n ... on ResolvedOrganizerFolder {\n id\n name\n type\n }\n ... on OrganizerContainerResource {\n id\n name\n type\n }\n }\n }\n }\n }\n }\n }\n": types.SetDockerFolderChildrenDocument,
|
||||
"\n mutation StartDockerContainer($id: PrefixedID!) {\n docker {\n start(id: $id) {\n id\n names\n state\n }\n }\n }\n": types.StartDockerContainerDocument,
|
||||
"\n mutation StopDockerContainer($id: PrefixedID!) {\n docker {\n stop(id: $id) {\n id\n names\n state\n }\n }\n }\n": types.StopDockerContainerDocument,
|
||||
"\n mutation UnpauseDockerContainer($id: PrefixedID!) {\n docker {\n unpause(id: $id) {\n id\n names\n state\n }\n }\n }\n": types.UnpauseDockerContainerDocument,
|
||||
"\n query LogFiles {\n logFiles {\n name\n path\n size\n modifiedAt\n }\n }\n": types.LogFilesDocument,
|
||||
"\n query LogFileContent($path: String!, $lines: Int, $startLine: Int) {\n logFile(path: $path, lines: $lines, startLine: $startLine) {\n path\n content\n totalLines\n startLine\n }\n }\n": types.LogFileContentDocument,
|
||||
"\n subscription LogFileSubscription($path: String!) {\n logFile(path: $path) {\n path\n content\n totalLines\n }\n }\n": types.LogFileSubscriptionDocument,
|
||||
@@ -190,6 +196,10 @@ export function graphql(source: "\n query Unified {\n settings {\n unif
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n"): (typeof documents)["\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports { privatePort publicPort type }\n hostConfig { networkMode }\n networkSettings\n labels\n }\n }\n }\n"): (typeof documents)["\n query GetDockerActiveContainer($id: PrefixedID!) {\n docker {\n id\n containers {\n id\n names\n image\n created\n state\n status\n autoStart\n ports { privatePort publicPort type }\n hostConfig { networkMode }\n networkSettings\n labels\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -210,6 +220,10 @@ export function graphql(source: "\n mutation MoveDockerEntriesToFolder($destina
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query GetDockerContainerOverviewForm($skipCache: Boolean = false) {\n dockerContainerOverviewForm(skipCache: $skipCache) {\n id\n dataSchema\n uiSchema\n data\n }\n }\n"): (typeof documents)["\n query GetDockerContainerOverviewForm($skipCache: Boolean = false) {\n dockerContainerOverviewForm(skipCache: $skipCache) {\n id\n dataSchema\n uiSchema\n data\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation PauseDockerContainer($id: PrefixedID!) {\n docker {\n pause(id: $id) {\n id\n names\n state\n }\n }\n }\n"): (typeof documents)["\n mutation PauseDockerContainer($id: PrefixedID!) {\n docker {\n pause(id: $id) {\n id\n names\n state\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -222,6 +236,10 @@ export function graphql(source: "\n mutation StartDockerContainer($id: Prefixed
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation StopDockerContainer($id: PrefixedID!) {\n docker {\n stop(id: $id) {\n id\n names\n state\n }\n }\n }\n"): (typeof documents)["\n mutation StopDockerContainer($id: PrefixedID!) {\n docker {\n stop(id: $id) {\n id\n names\n state\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n mutation UnpauseDockerContainer($id: PrefixedID!) {\n docker {\n unpause(id: $id) {\n id\n names\n state\n }\n }\n }\n"): (typeof documents)["\n mutation UnpauseDockerContainer($id: PrefixedID!) {\n docker {\n unpause(id: $id) {\n id\n names\n state\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user