Upstream pterodactyl/panel state of the touched files before 152f40cc18

This commit is contained in:
upstream committed 2026-10-14 18:16:57 +02:00
commit 56e5db2059
11 files changed
+34637

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,73 @@
import { useCallback, useEffect, useRef } from 'react';
import { toast } from 'sonner';
import { useCurrentServerUuid } from '@/api/server/queries';
import { useUploadFiles } from '@/api/server/files/queries';
import { useFileUploadActions, useServerDirectory } from '@/state/server';
const UPLOADED_DISPLAY_MS = 500;
/** Uploads into the current directory; rejects when any file failed, after its error toast. */
export default function useFileUploader(): (files: readonly File[]) => Promise<void> {
const removals = useRef(new Map<string, ReturnType<typeof setTimeout>>());
const { mutateAsync } = useUploadFiles();
const uuid = useCurrentServerUuid()!;
const directory = useServerDirectory();
const { removeFileUpload, pushFileUpload, setUploadProgress } = useFileUploadActions();
useEffect(() => {
const pending = removals.current;
return () => {
for (const [id, timeout] of pending) {
clearTimeout(timeout);
removeFileUpload(id);
}
pending.clear();
};
}, [removeFileUpload]);
return useCallback(
async (files) => {
if (files.some((file) => !file.type && (!file.size || file.size === 4096))) {
toast.error('Folder uploads are not supported.');
throw new Error('Folder uploads are not supported.');
}
const { failed } = await mutateAsync({
uuid,
directory,
files: [...files],
callbacks: {
onFileQueued: (id, file, abort) => {
pushFileUpload({ id, data: { name: file.name, abort, loaded: 0, total: file.size } });
},
onFileProgress: (id, progress) => setUploadProgress({ id, loaded: progress.loaded }),
onFileSettled: (id, outcome) => {
if (outcome !== 'uploaded') {
removeFileUpload(id);
return;
}
const timeout = setTimeout(() => {
removals.current.delete(id);
removeFileUpload(id);
}, UPLOADED_DISPLAY_MS);
removals.current.set(id, timeout);
},
},
});
if (failed.length > 0) {
throw new Error(
failed.length === 1
? `Unable to upload ${failed[0].name}.`
: `Unable to upload ${failed.length} files.`
);
}
},
[mutateAsync, uuid, directory, removeFileUpload, pushFileUpload, setUploadProgress]
);
}
+73
View File
@@ -0,0 +1,73 @@
import type { Server } from '@/api/server/types';
import type { ServerCardModel } from './dashboard';
import { statMetric } from './server/state';
export interface TestServerOptions {
identifier?: string;
uuid?: string;
name?: string;
owner?: boolean;
permissions?: string[];
status?: Server['attributes']['status'];
eggFeatures?: string[];
eggTags?: string[];
}
/** A server payload for fixtures and tests. */
export function createTestServer(options: TestServerOptions = {}): Server {
const identifier = options.identifier ?? 'test-server';
const owner = options.owner ?? true;
return {
object: 'server',
attributes: {
identifier,
uuid: options.uuid ?? '11111111-1111-4111-8111-111111111111',
__deprecated_uuid_short: identifier,
server_identifier: identifier,
internal_id: 1,
server_owner: owner,
name: options.name ?? 'Test server',
node: 'Test node',
is_node_under_maintenance: false,
sftp_details: { ip: '127.0.0.1', port: 2022 },
description: null,
limits: { memory: 1024, swap: 0, disk: 1024, io: 500, cpu: 100, threads: null, oom_disabled: true },
invocation: 'run',
docker_image: 'test/image',
egg_features: options.eggFeatures ?? [],
egg_tags: options.eggTags ?? [],
feature_limits: { databases: 1, allocations: 1, backups: 1 },
status: options.status ?? null,
is_suspended: options.status === 'suspended',
is_installing: options.status === 'installing',
is_transferring: false,
skip_scripts: false,
},
meta: { is_server_owner: owner, user_permissions: options.permissions ?? [] },
};
}
const noop = () => {};
/** A running server's card, with every permission; `options` replace its fields. */
export function createTestServerCard(options: Partial<ServerCardModel> = {}): ServerCardModel {
return {
identifier: 'test-server',
uuid: '11111111-1111-4111-8111-111111111111',
name: 'Test server',
description: null,
address: '127.0.0.1:25565',
state: {
kind: 'ready',
power: 'running',
cpu: statMetric(12, 100),
memory: statMetric(256 * 1024 * 1024, 1024 * 1024 * 1024),
disk: statMetric(512 * 1024 * 1024, 2048 * 1024 * 1024),
},
permissions: { start: true, stop: true, restart: true, console: true },
actions: { start: noop, stop: noop, restart: noop },
sending: false,
...options,
};
}