mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-12-18 20:04:17 +01:00
Fix more any types after updating to newer V2
This commit is contained in:
parent
a1a1394cad
commit
9be1d1aa5a
@ -4,7 +4,7 @@ import { TextInput, NumberInput, Switch, Button, Stack, Paper, Text, Loader, Gro
|
||||
import { alert } from '@app/components/toast';
|
||||
import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal';
|
||||
import { useRestartServer } from '@app/components/shared/config/useRestartServer';
|
||||
import { useAdminSettings } from '@app/hooks/useAdminSettings';
|
||||
import { useAdminSettings, type SettingsRecord } from '@app/hooks/useAdminSettings';
|
||||
import PendingBadge from '@app/components/shared/config/PendingBadge';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
|
||||
@ -73,7 +73,7 @@ export default function AdminMailSection() {
|
||||
saveTransformer: (settings) => {
|
||||
const { frontendUrl, ...mailSettings } = settings;
|
||||
|
||||
const deltaSettings: Record<string, any> = {
|
||||
const deltaSettings: SettingsRecord = {
|
||||
'system.frontendUrl': frontendUrl
|
||||
};
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import { useRestartServer } from '@app/components/shared/config/useRestartServer
|
||||
import { useAdminSettings, type SettingsRecord } from '@app/hooks/useAdminSettings';
|
||||
import PendingBadge from '@app/components/shared/config/PendingBadge';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
import type { SettingsWithPending } from '@app/utils/settingsPendingHelper';
|
||||
|
||||
interface SecuritySettingsData extends Record<string, unknown> {
|
||||
enableLogin?: boolean;
|
||||
@ -83,7 +82,7 @@ export default function AdminSecuritySection() {
|
||||
systemPending: JSON.parse(JSON.stringify(systemPending || {}))
|
||||
});
|
||||
|
||||
const combined: SecurityResponse = {
|
||||
const combined = {
|
||||
...securityActive
|
||||
};
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
Table,
|
||||
} from '@mantine/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import auditService, { AuditEvent } from '@app/services/auditService';
|
||||
import auditService, { AuditEvent, type AuditFilters } from '@app/services/auditService';
|
||||
import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex';
|
||||
import { useAuditFilters } from '@app/hooks/useAuditFilters';
|
||||
import AuditFiltersForm from '@app/components/shared/config/configSections/audit/AuditFiltersForm';
|
||||
@ -55,7 +55,7 @@ const AuditEventsTable: React.FC = () => {
|
||||
}, [filters, currentPage]);
|
||||
|
||||
// Wrap filter handlers to reset pagination
|
||||
const handleFilterChangeWithReset = (key: keyof typeof filters, value: any) => {
|
||||
const handleFilterChangeWithReset = <K extends keyof AuditFilters>(key: K, value: AuditFilters[K]) => {
|
||||
handleFilterChange(key, value);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import React from 'react';
|
||||
import { Group, Select, Button } from '@mantine/core';
|
||||
import { DateInput } from '@mantine/dates';
|
||||
import type { DateValue } from '@mantine/dates';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AuditFilters } from '@app/services/auditService';
|
||||
import { Z_INDEX_OVER_CONFIG_MODAL } from '@app/styles/zIndex';
|
||||
|
||||
type FilterChangeHandler = <K extends keyof AuditFilters>(key: K, value: AuditFilters[K]) => void;
|
||||
|
||||
interface AuditFiltersFormProps {
|
||||
filters: AuditFilters;
|
||||
eventTypes: string[];
|
||||
users: string[];
|
||||
onFilterChange: (key: keyof AuditFilters, value: any) => void;
|
||||
onFilterChange: FilterChangeHandler;
|
||||
onClearFilters: () => void;
|
||||
}
|
||||
|
||||
@ -49,8 +52,8 @@ const AuditFiltersForm: React.FC<AuditFiltersFormProps> = ({
|
||||
<DateInput
|
||||
placeholder={t('audit.events.startDate', 'Start date')}
|
||||
value={filters.startDate ? new Date(filters.startDate) : null}
|
||||
onChange={(value: string | null) =>
|
||||
onFilterChange('startDate', value ?? undefined)
|
||||
onChange={(value: DateValue) =>
|
||||
onFilterChange('startDate', value instanceof Date ? value.toISOString() : undefined)
|
||||
}
|
||||
clearable
|
||||
style={{ flex: 1, minWidth: 150 }}
|
||||
@ -59,8 +62,8 @@ const AuditFiltersForm: React.FC<AuditFiltersFormProps> = ({
|
||||
<DateInput
|
||||
placeholder={t('audit.events.endDate', 'End date')}
|
||||
value={filters.endDate ? new Date(filters.endDate) : null}
|
||||
onChange={(value: string | null) =>
|
||||
onFilterChange('endDate', value ?? undefined)
|
||||
onChange={(value: DateValue) =>
|
||||
onFilterChange('endDate', value instanceof Date ? value.toISOString() : undefined)
|
||||
}
|
||||
clearable
|
||||
style={{ flex: 1, minWidth: 150 }}
|
||||
|
||||
@ -71,10 +71,13 @@ export const AppConfigProvider: React.FC<{ children: ReactNode }> = ({ children
|
||||
console.debug('[AppConfig] Config fetched successfully:', data);
|
||||
setConfig(data);
|
||||
setFetchCount(prev => prev + 1);
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
// On 401 (not authenticated), use default config with login enabled
|
||||
// This allows the app to work even without authentication
|
||||
if (err.response?.status === 401) {
|
||||
const responseStatus = typeof err === 'object' && err !== null && 'response' in err
|
||||
? (err as { response?: { status?: number } }).response?.status
|
||||
: undefined;
|
||||
if (responseStatus === 401) {
|
||||
console.debug('[AppConfig] 401 error - using default config (login enabled)');
|
||||
setConfig({ enableLogin: true });
|
||||
setLoading(false);
|
||||
|
||||
@ -485,7 +485,7 @@ export function useTranslatedToolCatalog(): TranslatedToolCatalog {
|
||||
categoryId: ToolCategoryId.STANDARD_TOOLS,
|
||||
subcategoryId: SubcategoryId.EXTRACTION,
|
||||
synonyms: getSynonyms(t, "extractPages"),
|
||||
automationSettings: ExtractPagesSettings,
|
||||
automationSettings: toAutomationSettings(ExtractPagesSettings),
|
||||
operationConfig: extractPagesOperationConfig,
|
||||
endpoints: ["rearrange-pages"],
|
||||
},
|
||||
|
||||
@ -117,7 +117,7 @@ export function useAdminSettings<T extends object>(
|
||||
const { sectionData: originalSectionData } = saveTransformer(originalSettings);
|
||||
|
||||
// Save section data (with delta applied) - compare transformed vs transformed
|
||||
const sectionDelta = computeDelta(originalSectionData, sectionData);
|
||||
const sectionDelta = computeDelta(originalSectionData as SettingsRecord, sectionData as SettingsRecord);
|
||||
if (Object.keys(sectionDelta).length > 0) {
|
||||
await apiClient.put(`/api/v1/admin/settings/section/${sectionName}`, sectionDelta);
|
||||
}
|
||||
@ -133,7 +133,7 @@ export function useAdminSettings<T extends object>(
|
||||
});
|
||||
|
||||
// Compare current vs original deltaSettings (both have same backend paths)
|
||||
const changedDeltaSettings: Record<string, any> = {};
|
||||
const changedDeltaSettings: SettingsRecord = {};
|
||||
for (const [key, value] of Object.entries(deltaSettings)) {
|
||||
const originalValue = originalDeltaSettings?.[key];
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ export function useAuditFilters(initialFilters: Partial<AuditFilters> = {}) {
|
||||
fetchMetadata();
|
||||
}, []);
|
||||
|
||||
const handleFilterChange = (key: keyof AuditFilters, value: any) => {
|
||||
const handleFilterChange = <K extends keyof AuditFilters>(key: K, value: AuditFilters[K]) => {
|
||||
setFilters((prev) => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
|
||||
@ -137,9 +137,12 @@ export function useMultipleEndpointsEnabled(endpoints: string[]): {
|
||||
|
||||
setEndpointStatus(fullStatus);
|
||||
globalFetchedSets.add(endpointsKey);
|
||||
} catch (err: any) {
|
||||
} catch (err: unknown) {
|
||||
// On 401 (auth error), use optimistic fallback instead of disabling
|
||||
if (err.response?.status === 401) {
|
||||
const responseStatus = typeof err === 'object' && err !== null && 'response' in err
|
||||
? (err as { response?: { status?: number } }).response?.status
|
||||
: undefined;
|
||||
if (responseStatus === 401) {
|
||||
console.warn('[useEndpointConfig] 401 error - using optimistic fallback');
|
||||
const optimisticStatus = endpoints.reduce((acc, endpoint) => {
|
||||
acc[endpoint] = true;
|
||||
|
||||
@ -13,7 +13,7 @@ export interface AuditEvent {
|
||||
eventType: string;
|
||||
username: string;
|
||||
ipAddress: string;
|
||||
details: Record<string, any>;
|
||||
details: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface AuditEventsResponse {
|
||||
@ -44,12 +44,18 @@ export interface AuditFilters {
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
interface AuditStatusApiResponse {
|
||||
auditEnabled: boolean;
|
||||
auditLevel: string;
|
||||
retentionDays: number;
|
||||
}
|
||||
|
||||
const auditService = {
|
||||
/**
|
||||
* Get audit system status
|
||||
*/
|
||||
async getSystemStatus(): Promise<AuditSystemStatus> {
|
||||
const response = await apiClient.get<any>('/api/v1/proprietary/ui-data/audit-dashboard');
|
||||
const response = await apiClient.get<AuditStatusApiResponse>('/api/v1/proprietary/ui-data/audit-dashboard');
|
||||
const data = response.data;
|
||||
|
||||
// Map V1 response to expected format
|
||||
|
||||
@ -25,7 +25,7 @@ const usageAnalyticsService = {
|
||||
limit?: number,
|
||||
dataType: 'all' | 'api' | 'ui' = 'all'
|
||||
): Promise<EndpointStatisticsResponse> {
|
||||
const params: Record<string, any> = {};
|
||||
const params: Record<string, string | number> = {};
|
||||
|
||||
if (limit !== undefined) {
|
||||
params.limit = limit;
|
||||
|
||||
@ -236,9 +236,7 @@ export const userManagementService = {
|
||||
const response = await apiClient.post<InviteLinkResponse>(
|
||||
'/api/v1/invite/generate',
|
||||
formData,
|
||||
{
|
||||
suppressErrorToast: true,
|
||||
} as any
|
||||
suppressErrorToastConfig()
|
||||
);
|
||||
|
||||
return response.data;
|
||||
@ -256,9 +254,7 @@ export const userManagementService = {
|
||||
* Revoke an invite link (admin only)
|
||||
*/
|
||||
async revokeInviteLink(inviteId: number): Promise<void> {
|
||||
await apiClient.delete(`/api/v1/invite/revoke/${inviteId}`, {
|
||||
suppressErrorToast: true,
|
||||
} as any);
|
||||
await apiClient.delete(`/api/v1/invite/revoke/${inviteId}`, suppressErrorToastConfig());
|
||||
},
|
||||
|
||||
/**
|
||||
@ -269,3 +265,5 @@ export const userManagementService = {
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
type SuppressibleRequestConfig = AxiosRequestConfig & { suppressErrorToast?: boolean };
|
||||
const suppressErrorToastConfig = (): SuppressibleRequestConfig => ({ suppressErrorToast: true });
|
||||
|
||||
@ -274,12 +274,9 @@ const extractErrorMessage = (error: unknown, fallback: string): string => {
|
||||
title: t('workspace.people.inviteLink.success', 'Invite link generated successfully!')
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
console.error('Failed to generate invite link:', error);
|
||||
const errorMessage = error.response?.data?.message ||
|
||||
error.response?.data?.error ||
|
||||
error.message ||
|
||||
t('workspace.people.inviteLink.error', 'Failed to generate invite link');
|
||||
const errorMessage = extractErrorMessage(error, t('workspace.people.inviteLink.error', 'Failed to generate invite link'));
|
||||
alert({ alertType: 'error', title: errorMessage });
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
|
||||
@ -8,6 +8,7 @@ import LoginHeader from '@app/routes/login/LoginHeader';
|
||||
import ErrorMessage from '@app/routes/login/ErrorMessage';
|
||||
import { BASE_PATH } from '@app/constants/app';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
|
||||
interface InviteData {
|
||||
email: string | null;
|
||||
@ -16,6 +17,28 @@ interface InviteData {
|
||||
emailRequired: boolean;
|
||||
}
|
||||
|
||||
type SuppressibleRequestConfig = AxiosRequestConfig & { suppressErrorToast?: boolean };
|
||||
const suppressErrorConfig: SuppressibleRequestConfig = { suppressErrorToast: true };
|
||||
|
||||
type ApiErrorResponse = {
|
||||
response?: { data?: { error?: string; message?: string } };
|
||||
message?: string;
|
||||
};
|
||||
|
||||
const extractInviteError = (error: unknown, fallback: string): string => {
|
||||
if (typeof error === 'object' && error !== null) {
|
||||
const apiError = error as ApiErrorResponse;
|
||||
return apiError.response?.data?.error
|
||||
?? apiError.response?.data?.message
|
||||
?? apiError.message
|
||||
?? fallback;
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
}
|
||||
return fallback;
|
||||
};
|
||||
|
||||
export default function InviteAccept() {
|
||||
const { token } = useParams<{ token: string }>();
|
||||
const navigate = useNavigate();
|
||||
@ -54,17 +77,11 @@ export default function InviteAccept() {
|
||||
const validateToken = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await apiClient.get<InviteData>(`/api/v1/invite/validate/${token}`, {
|
||||
suppressErrorToast: true,
|
||||
} as any);
|
||||
const response = await apiClient.get<InviteData>(`/api/v1/invite/validate/${token}`, suppressErrorConfig);
|
||||
setInviteData(response.data);
|
||||
setError(null);
|
||||
} catch (err: any) {
|
||||
const errorMessage =
|
||||
err.response?.data?.error ||
|
||||
err.message ||
|
||||
t('invite.validationError', 'Failed to validate invitation link');
|
||||
setError(errorMessage);
|
||||
} catch (err: unknown) {
|
||||
setError(extractInviteError(err, t('invite.validationError', 'Failed to validate invitation link')));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -106,18 +123,12 @@ export default function InviteAccept() {
|
||||
}
|
||||
formData.append('password', password);
|
||||
|
||||
await apiClient.post(`/api/v1/invite/accept/${token}`, formData, {
|
||||
suppressErrorToast: true,
|
||||
} as any);
|
||||
await apiClient.post(`/api/v1/invite/accept/${token}`, formData, suppressErrorConfig);
|
||||
|
||||
// Success - redirect to login
|
||||
navigate('/login?messageType=accountCreated');
|
||||
} catch (err: any) {
|
||||
const errorMessage =
|
||||
err.response?.data?.error ||
|
||||
err.message ||
|
||||
t('invite.acceptError', 'Failed to create account');
|
||||
setError(errorMessage);
|
||||
} catch (err: unknown) {
|
||||
setError(extractInviteError(err, t('invite.acceptError', 'Failed to create account')));
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user