Upstream pterodactyl/panel state of the touched files before 152f40cc18
This commit is contained in:
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]
|
||||
);
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user