implement 'move to folder'

This commit is contained in:
Pujit Mehrotra
2025-09-18 15:10:47 -04:00
parent 0681a4e34c
commit 0a99f9c202
7 changed files with 490 additions and 31 deletions

7
web/components.d.ts vendored
View File

@@ -105,7 +105,6 @@ declare module 'vue' {
SsoButtons: typeof import('./src/components/sso/SsoButtons.vue')['default']
SsoProviderButton: typeof import('./src/components/sso/SsoProviderButton.vue')['default']
Status: typeof import('./src/components/UpdateOs/Status.vue')['default']
TableRenderer: typeof import('./src/components/JsonForms/TableRenderer.vue')['default']
'TestThemeSwitcher.standalone': typeof import('./src/components/TestThemeSwitcher.standalone.vue')['default']
'TestUpdateModal.standalone': typeof import('./src/components/UpdateOs/TestUpdateModal.standalone.vue')['default']
'ThemeSwitcher.standalone': typeof import('./src/components/ThemeSwitcher.standalone.vue')['default']
@@ -116,12 +115,11 @@ declare module 'vue' {
UCard: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default']
UCheckbox: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default']
UContextMenu: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/ContextMenu.vue')['default']
UDrawer: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Drawer.vue')['default']
UDropdownMenu: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/DropdownMenu.vue')['default']
UFormField: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default']
UIcon: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default']
UInput: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default']
UNavigationMenu: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/NavigationMenu.vue')['default']
UModal: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default']
UnraidToaster: typeof import('./src/components/UnraidToaster.vue')['default']
Update: typeof import('./src/components/UpdateOs/Update.vue')['default']
UpdateExpiration: typeof import('./src/components/Registration/UpdateExpiration.vue')['default']
@@ -129,11 +127,10 @@ declare module 'vue' {
UpdateIneligible: typeof import('./src/components/UpdateOs/UpdateIneligible.vue')['default']
'UpdateOs.standalone': typeof import('./src/components/UpdateOs.standalone.vue')['default']
UptimeExpire: typeof import('./src/components/UserProfile/UptimeExpire.vue')['default']
URadioGroup: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/RadioGroup.vue')['default']
USelectMenu: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/SelectMenu.vue')['default']
'UserProfile.standalone': typeof import('./src/components/UserProfile.standalone.vue')['default']
USwitch: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Switch.vue')['default']
UTable: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Table.vue')['default']
UTabs: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.0.0-alpha.0_@babel+parser@7.28.4_@netlify+blobs@9.1.2_change-case@5.4.4_db0@_655bac6707ae017754653173419b3890/node_modules/@nuxt/ui/dist/runtime/components/Tabs.vue')['default']
'WanIpCheck.standalone': typeof import('./src/components/WanIpCheck.standalone.vue')['default']
'WelcomeModal.standalone': typeof import('./src/components/Activation/WelcomeModal.standalone.vue')['default']
}

View File

@@ -2,9 +2,12 @@
import { computed, h, ref, resolveComponent } from 'vue';
import { useMutation } from '@vue/apollo-composable';
import { Button } from '@unraid/ui';
// removed unused Button import
import { GET_DOCKER_CONTAINERS } from '@/components/Docker/docker-containers.query';
import { CREATE_DOCKER_FOLDER } from '@/components/Docker/docker-create-folder.mutation';
import { DELETE_DOCKER_ENTRIES } from '@/components/Docker/docker-delete-entries.mutation';
import { MOVE_DOCKER_ENTRIES_TO_FOLDER } from '@/components/Docker/docker-move-entries.mutation';
import { SET_DOCKER_FOLDER_CHILDREN } from '@/components/Docker/docker-set-folder-children.mutation';
import { ContainerState } from '@/composables/gql/graphql';
import type {
@@ -31,6 +34,7 @@ const UBadge = resolveComponent('UBadge');
const UInput = resolveComponent('UInput');
const UDropdownMenu = resolveComponent('UDropdownMenu');
const UContextMenu = resolveComponent('UContextMenu');
const UModal = resolveComponent('UModal');
function formatPorts(container?: DockerContainer | null): string {
if (!container) return '';
@@ -266,7 +270,7 @@ const columns = computed<TableColumn<TreeRow>[]>(() => {
items,
size: 'md',
ui: {
content: 'overflow-x-hidden z-10',
content: 'overflow-x-hidden z-50',
item: 'bg-transparent hover:bg-transparent focus:bg-transparent border-0 ring-0 outline-none shadow-none data-[state=checked]:bg-transparent',
},
},
@@ -305,37 +309,220 @@ const emit = defineEmits<{
}>();
const { mutate: createFolderMutation, loading: creating } = useMutation(CREATE_DOCKER_FOLDER);
const { mutate: moveEntriesMutation, loading: moving } = useMutation(MOVE_DOCKER_ENTRIES_TO_FOLDER);
const { mutate: deleteEntriesMutation, loading: deleting } = useMutation(DELETE_DOCKER_ENTRIES);
const { mutate: setFolderChildrenMutation } = useMutation(SET_DOCKER_FOLDER_CHILDREN);
async function handleCreateFolder() {
const name = window.prompt('New folder name');
if (!name) return;
const childrenIds = treeData.value
.flatMap(function collect(row): TreeRow[] {
if (row.type === 'container') return [row];
return (row.children || []).flatMap(collect);
})
.filter((r) => rowSelection.value[r.id])
.map((r) => r.id);
if (childrenIds.length === 0) return;
await createFolderMutation(
{ name, childrenIds },
const moveOpen = ref(false);
const selectedFolderId = ref<string>('');
const pendingMoveSourceIds = ref<string[]>([]);
const expandedFolders = ref<Set<string>>(new Set());
const renamingFolderId = ref<string>('');
const renameValue = ref<string>('');
const newTreeFolderName = ref<string>('');
const rootFolderId = computed<string>(() => props.organizerRoot?.id || '');
type FolderNode = { id: string; name: string; children: FolderNode[] };
function buildFolderOnlyTree(entry?: ResolvedOrganizerFolder | null): FolderNode | null {
if (!entry) return null;
const folders: FolderNode[] = [];
for (const child of entry.children || []) {
if ((child as ResolvedOrganizerEntry).__typename === 'ResolvedOrganizerFolder') {
const sub = buildFolderOnlyTree(child as ResolvedOrganizerFolder);
if (sub) folders.push(sub);
}
}
return { id: entry.id, name: entry.name, children: folders };
}
const folderTree = computed<FolderNode | null>(() => buildFolderOnlyTree(props.organizerRoot));
type FlatFolderRow = { id: string; name: string; depth: number; hasChildren: boolean };
function flattenVisibleFolders(
node: FolderNode | null,
depth = 0,
out: FlatFolderRow[] = []
): FlatFolderRow[] {
if (!node) return out;
out.push({ id: node.id, name: node.name, depth, hasChildren: node.children.length > 0 });
if (expandedFolders.value.has(node.id)) {
for (const child of node.children) flattenVisibleFolders(child, depth + 1, out);
}
return out;
}
const visibleFolders = computed<FlatFolderRow[]>(() => flattenVisibleFolders(folderTree.value));
const parentById = computed<Record<string, string>>(() => {
const map: Record<string, string> = {};
function walk(node?: ResolvedOrganizerFolder | null, parentId?: string) {
if (!node) return;
if (parentId) map[node.id] = parentId;
for (const child of node.children || []) {
if ((child as ResolvedOrganizerEntry).__typename === 'ResolvedOrganizerFolder') {
walk(child as ResolvedOrganizerFolder, node.id);
}
}
}
walk(props.organizerRoot, undefined);
return map;
});
const folderChildrenIds = computed<Record<string, string[]>>(() => {
const map: Record<string, string[]> = {};
function walk(node?: ResolvedOrganizerFolder | null) {
if (!node) return;
map[node.id] = (node.children || []).map((c) => {
const entry = c as ResolvedOrganizerEntry;
return (entry as { id: string }).id;
});
for (const child of node.children || []) {
if ((child as ResolvedOrganizerEntry).__typename === 'ResolvedOrganizerFolder') {
walk(child as ResolvedOrganizerFolder);
}
}
}
walk(props.organizerRoot);
return map;
});
function getSelectedEntryIds(): string[] {
return Object.entries(rowSelection.value)
.filter(([, selected]) => !!selected)
.map(([id]) => id);
}
function openMoveModal(ids?: string[]) {
const sources = ids ?? getSelectedEntryIds();
console.log('sources', sources);
if (sources.length === 0) return;
pendingMoveSourceIds.value = sources;
selectedFolderId.value = rootFolderId.value || '';
expandedFolders.value = new Set([rootFolderId.value]);
renamingFolderId.value = '';
renameValue.value = '';
newTreeFolderName.value = '';
moveOpen.value = true;
}
async function confirmMove(close: () => void) {
const ids = pendingMoveSourceIds.value;
if (ids.length === 0) return;
if (!selectedFolderId.value) return;
await moveEntriesMutation(
{ destinationFolderId: selectedFolderId.value, sourceEntryIds: ids },
{
refetchQueries: [{ query: GET_DOCKER_CONTAINERS, variables: { skipCache: true } }],
awaitRefetchQueries: true,
}
);
rowSelection.value = {};
emit('created-folder');
showToast('Moved to folder');
close();
}
async function handleCreateFolderInTree() {
const name = newTreeFolderName.value.trim();
if (!name) return;
await createFolderMutation(
{
name,
parentId: selectedFolderId.value || rootFolderId.value,
childrenIds: pendingMoveSourceIds.value,
},
{
refetchQueries: [{ query: GET_DOCKER_CONTAINERS, variables: { skipCache: true } }],
awaitRefetchQueries: true,
}
);
emit('created-folder');
showToast('Folder created');
newTreeFolderName.value = '';
expandedFolders.value.add(selectedFolderId.value || rootFolderId.value);
}
function startRenameFolder(id: string, currentName: string) {
if (!id || id === rootFolderId.value) return;
renamingFolderId.value = id;
renameValue.value = currentName;
}
async function commitRenameFolder(id: string) {
const newName = renameValue.value.trim();
if (!id || !newName || newName === id) {
renamingFolderId.value = '';
renameValue.value = '';
return;
}
const parentId = parentById.value[id] || rootFolderId.value;
const children = folderChildrenIds.value[id] || [];
// 1) Create new folder with same children under same parent
await createFolderMutation(
{ name: newName, parentId, childrenIds: children },
{ awaitRefetchQueries: true }
);
// 2) Clear old folder children to avoid cascading deletion of descendants
await setFolderChildrenMutation({ folderId: id, childrenIds: [] }, { awaitRefetchQueries: true });
// 3) Delete the now-empty old folder
await deleteEntriesMutation(
{ entryIds: [id] },
{
refetchQueries: [{ query: GET_DOCKER_CONTAINERS, variables: { skipCache: true } }],
awaitRefetchQueries: true,
}
);
renamingFolderId.value = '';
renameValue.value = '';
selectedFolderId.value = newName;
showToast('Folder renamed');
}
async function handleDeleteFolder() {
const id = selectedFolderId.value;
if (!id || id === rootFolderId.value) return;
if (!confirm('Delete this folder? Contents will move to root.')) return;
await deleteEntriesMutation(
{ entryIds: [id] },
{
refetchQueries: [{ query: GET_DOCKER_CONTAINERS, variables: { skipCache: true } }],
awaitRefetchQueries: true,
}
);
selectedFolderId.value = rootFolderId.value;
showToast('Folder deleted');
}
function toggleExpandFolder(id: string) {
const set = new Set(expandedFolders.value);
if (set.has(id)) set.delete(id);
else set.add(id);
expandedFolders.value = set;
}
// removed unused handleCreateFolder; creation handled in modal
function getSelectedContainerIds(): string[] {
return treeData.value
.flatMap(function collect(row): TreeRow[] {
if (row.type === 'container') return [row];
return (row.children || []).flatMap(collect);
})
.filter((r) => rowSelection.value[r.id])
.map((r) => r.id);
const collected = new Set<string>();
function collectContainers(row: TreeRow, includeAll: boolean): void {
const isSelected = !!rowSelection.value[row.id];
const shouldInclude = includeAll || isSelected;
if (row.type === 'container') {
if (shouldInclude) collected.add(row.id);
return;
}
// folder
const children = row.children || [];
const propagate = shouldInclude; // selecting a folder selects all descendants
for (const child of children) collectContainers(child as TreeRow, propagate);
}
for (const root of treeData.value) collectContainers(root, false);
return Array.from(collected);
}
declare global {
@@ -377,7 +564,7 @@ const bulkItems = computed<DropdownMenuItems>(() => [
label: 'Move to folder',
icon: 'i-lucide-folder',
as: 'button',
onSelect: () => handleBulkAction('Move to folder'),
onSelect: () => openMoveModal(),
},
{
label: 'Start / Stop',
@@ -401,7 +588,7 @@ function getRowActionItems(row: TreeRow): DropdownMenuItems {
label: 'Move to folder',
icon: 'i-lucide-folder',
as: 'button',
onSelect: () => handleRowAction(row, 'Move to folder'),
onSelect: () => openMoveModal([row.id]),
},
{
label: 'Start / Stop',
@@ -436,7 +623,7 @@ function getRowActionItems(row: TreeRow): DropdownMenuItems {
:items="bulkItems"
size="md"
:ui="{
content: 'overflow-x-hidden z-10',
content: 'overflow-x-hidden z-40',
item: 'bg-transparent hover:bg-transparent focus:bg-transparent border-0 ring-0 outline-none shadow-none data-[state=checked]:bg-transparent',
}"
>
@@ -467,5 +654,107 @@ function getRowActionItems(row: TreeRow): DropdownMenuItems {
<div v-if="!loading && treeData.length === 0" class="py-8 text-center text-gray-500">
No containers found
</div>
<UModal
v-model:open="moveOpen"
title="Move to folder"
:ui="{ footer: 'justify-end', overlay: 'z-50', content: 'z-50' }"
>
<template #body>
<div class="space-y-3">
<div class="flex items-center gap-2">
<UInput v-model="newTreeFolderName" placeholder="New folder name" class="flex-1" />
<UButton
size="sm"
color="neutral"
variant="outline"
:disabled="!newTreeFolderName.trim()"
@click="handleCreateFolderInTree"
>Create</UButton
>
<UButton
size="sm"
color="neutral"
variant="outline"
:disabled="!selectedFolderId || selectedFolderId === rootFolderId"
@click="handleDeleteFolder"
>Delete</UButton
>
</div>
<div class="border-default rounded border">
<div
v-for="row in visibleFolders"
:key="row.id"
:data-id="row.id"
class="flex items-center gap-2 px-2 py-1 hover:bg-gray-50 dark:hover:bg-gray-800"
>
<UButton
v-if="row.hasChildren"
color="neutral"
size="xs"
variant="ghost"
icon="i-lucide-chevron-right"
:class="expandedFolders.has(row.id) ? 'rotate-90' : ''"
square
@click="toggleExpandFolder(row.id)"
/>
<span v-else class="inline-block w-5" />
<input type="radio" :value="row.id" v-model="selectedFolderId" class="accent-primary" />
<div
:style="{ paddingLeft: `calc(${row.depth} * 0.75rem)` }"
class="flex min-w-0 flex-1 items-center gap-2"
>
<span class="i-lucide-folder text-gray-500" />
<template v-if="renamingFolderId === row.id">
<input
v-model="renameValue"
class="border-default bg-default flex-1 rounded border px-2 py-1"
@keydown.enter.prevent="commitRenameFolder(row.id)"
@keydown.esc.prevent="
renamingFolderId = '';
renameValue = '';
"
@blur="commitRenameFolder(row.id)"
autofocus
/>
</template>
<template v-else>
<span class="truncate">{{ row.name }}</span>
</template>
</div>
<UDropdownMenu
:items="[
[
{
label: 'Rename',
icon: 'i-lucide-pencil',
as: 'button',
onSelect: () => startRenameFolder(row.id, row.name),
},
],
]"
:ui="{ content: 'z-50' }"
>
<UButton color="neutral" variant="ghost" icon="i-lucide-more-vertical" square />
</UDropdownMenu>
</div>
</div>
</div>
</template>
<template #footer="{ close }">
<UButton color="neutral" variant="outline" @click="close">Cancel</UButton>
<UButton
:loading="moving || creating || deleting"
:disabled="!selectedFolderId"
@click="confirmMove(close)"
>
Confirm
</UButton>
</template>
</UModal>
</div>
</template>

View File

@@ -0,0 +1,34 @@
import { gql } from '@apollo/client';
export const DELETE_DOCKER_ENTRIES = gql`
mutation DeleteDockerEntries($entryIds: [String!]!) {
deleteDockerEntries(entryIds: $entryIds) {
version
views {
id
name
root {
__typename
... on ResolvedOrganizerFolder {
id
name
type
children {
__typename
... on ResolvedOrganizerFolder {
id
name
type
}
... on OrganizerContainerResource {
id
name
type
}
}
}
}
}
}
}
`;

View File

@@ -0,0 +1,37 @@
import { gql } from '@apollo/client';
export const MOVE_DOCKER_ENTRIES_TO_FOLDER = gql`
mutation MoveDockerEntriesToFolder($destinationFolderId: String!, $sourceEntryIds: [String!]!) {
moveDockerEntriesToFolder(
destinationFolderId: $destinationFolderId
sourceEntryIds: $sourceEntryIds
) {
version
views {
id
name
root {
__typename
... on ResolvedOrganizerFolder {
id
name
type
children {
__typename
... on ResolvedOrganizerFolder {
id
name
type
}
... on OrganizerContainerResource {
id
name
type
}
}
}
}
}
}
}
`;

View File

@@ -0,0 +1,34 @@
import { gql } from '@apollo/client';
export const SET_DOCKER_FOLDER_CHILDREN = gql`
mutation SetDockerFolderChildren($folderId: String, $childrenIds: [String!]!) {
setDockerFolderChildren(folderId: $folderId, childrenIds: $childrenIds) {
version
views {
id
name
root {
__typename
... on ResolvedOrganizerFolder {
id
name
type
children {
__typename
... on ResolvedOrganizerFolder {
id
name
type
}
... on OrganizerContainerResource {
id
name
type
}
}
}
}
}
}
}
`;

View File

@@ -30,7 +30,10 @@ type Documents = {
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": typeof types.UpdateConnectSettingsDocument,
"\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 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 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,
@@ -78,7 +81,10 @@ const documents: Documents = {
"\n mutation UpdateConnectSettings($input: JSON!) {\n updateSettings(input: $input) {\n restartRequired\n values\n }\n }\n": types.UpdateConnectSettingsDocument,
"\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 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 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,
@@ -188,10 +194,22 @@ export function graphql(source: "\n query GetDockerContainers($skipCache: Boole
* 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 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 documents)["\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"];
/**
* 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 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 documents)["\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"];
/**
* 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 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 documents)["\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"];
/**
* 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 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 documents)["\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"];
/**
* 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