@qwickapps/server 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +4 -4
- package/dist/src/core/control-panel.d.ts.map +1 -1
- package/dist/src/core/control-panel.js +10 -7
- package/dist/src/core/control-panel.js.map +1 -1
- package/dist/src/core/gateway.d.ts.map +1 -1
- package/dist/src/core/gateway.js +46 -47
- package/dist/src/core/gateway.js.map +1 -1
- package/dist/src/plugins/api-keys/ApiKeysManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/ApiKeysManagementPage.js +1 -1
- package/dist/src/plugins/api-keys/ApiKeysManagementPage.js.map +1 -1
- package/dist/src/plugins/api-keys/ApiKeysStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/ApiKeysStatusWidget.js +1 -1
- package/dist/src/plugins/api-keys/ApiKeysStatusWidget.js.map +1 -1
- package/dist/src/plugins/auth/AuthManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/auth/AuthManagementPage.js +1 -1
- package/dist/src/plugins/auth/AuthManagementPage.js.map +1 -1
- package/dist/src/plugins/auth/AuthStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/auth/AuthStatusWidget.js +1 -1
- package/dist/src/plugins/auth/AuthStatusWidget.js.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.js +9 -0
- package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
- package/dist/src/plugins/bans/BansManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/bans/BansManagementPage.js +1 -1
- package/dist/src/plugins/bans/BansManagementPage.js.map +1 -1
- package/dist/src/plugins/bans/BansStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/bans/BansStatusWidget.js +1 -1
- package/dist/src/plugins/bans/BansStatusWidget.js.map +1 -1
- package/dist/src/plugins/cache/CacheManagementPage.js +1 -1
- package/dist/src/plugins/cache/CacheManagementPage.js.map +1 -1
- package/dist/src/plugins/cache/CacheStatusWidget.js +1 -1
- package/dist/src/plugins/cache/CacheStatusWidget.js.map +1 -1
- package/dist/src/plugins/devices/DevicesManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/devices/DevicesManagementPage.js +1 -1
- package/dist/src/plugins/devices/DevicesManagementPage.js.map +1 -1
- package/dist/src/plugins/devices/DevicesStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/devices/DevicesStatusWidget.js +1 -1
- package/dist/src/plugins/devices/DevicesStatusWidget.js.map +1 -1
- package/dist/src/plugins/diagnostics/DiagnosticsManagementPage.js +1 -1
- package/dist/src/plugins/diagnostics/DiagnosticsManagementPage.js.map +1 -1
- package/dist/src/plugins/diagnostics/DiagnosticsStatusWidget.js +1 -1
- package/dist/src/plugins/diagnostics/DiagnosticsStatusWidget.js.map +1 -1
- package/dist/src/plugins/entitlements/EntitlementsManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/EntitlementsManagementPage.js +1 -1
- package/dist/src/plugins/entitlements/EntitlementsManagementPage.js.map +1 -1
- package/dist/src/plugins/entitlements/EntitlementsStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/EntitlementsStatusWidget.js +1 -1
- package/dist/src/plugins/entitlements/EntitlementsStatusWidget.js.map +1 -1
- package/dist/src/plugins/health/HealthManagementPage.js +1 -1
- package/dist/src/plugins/health/HealthManagementPage.js.map +1 -1
- package/dist/src/plugins/health/HealthStatusWidget.js +1 -1
- package/dist/src/plugins/health/HealthStatusWidget.js.map +1 -1
- package/dist/src/plugins/logs/LogsManagementPage.js +1 -1
- package/dist/src/plugins/logs/LogsManagementPage.js.map +1 -1
- package/dist/src/plugins/logs/LogsStatusWidget.js +1 -1
- package/dist/src/plugins/logs/LogsStatusWidget.js.map +1 -1
- package/dist/src/plugins/maintenance/MaintenanceManagementPage.js +1 -1
- package/dist/src/plugins/maintenance/MaintenanceManagementPage.js.map +1 -1
- package/dist/src/plugins/maintenance/MaintenanceStatusWidget.js +1 -1
- package/dist/src/plugins/maintenance/MaintenanceStatusWidget.js.map +1 -1
- package/dist/src/plugins/maintenance/SeedManagementPage.js +1 -1
- package/dist/src/plugins/maintenance/SeedManagementPage.js.map +1 -1
- package/dist/src/plugins/maintenance/seed-executor.js +2 -2
- package/dist/src/plugins/maintenance/seed-executor.js.map +1 -1
- package/dist/src/plugins/maintenance-plugin.d.ts +2 -0
- package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
- package/dist/src/plugins/maintenance-plugin.js +402 -2
- package/dist/src/plugins/maintenance-plugin.js.map +1 -1
- package/dist/src/plugins/notifications/NotificationsManagementPage.js +1 -1
- package/dist/src/plugins/notifications/NotificationsManagementPage.js.map +1 -1
- package/dist/src/plugins/notifications/NotificationsStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/notifications/NotificationsStatusWidget.js +1 -1
- package/dist/src/plugins/notifications/NotificationsStatusWidget.js.map +1 -1
- package/dist/src/plugins/parental/ParentalManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/parental/ParentalManagementPage.js +1 -1
- package/dist/src/plugins/parental/ParentalManagementPage.js.map +1 -1
- package/dist/src/plugins/parental/ParentalStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/parental/ParentalStatusWidget.js +1 -1
- package/dist/src/plugins/parental/ParentalStatusWidget.js.map +1 -1
- package/dist/src/plugins/postgres/PostgresManagementPage.js +1 -1
- package/dist/src/plugins/postgres/PostgresManagementPage.js.map +1 -1
- package/dist/src/plugins/postgres/PostgresStatusWidget.js +1 -1
- package/dist/src/plugins/postgres/PostgresStatusWidget.js.map +1 -1
- package/dist/src/plugins/preferences/PreferencesManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/preferences/PreferencesManagementPage.js +1 -1
- package/dist/src/plugins/preferences/PreferencesManagementPage.js.map +1 -1
- package/dist/src/plugins/preferences/PreferencesStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/preferences/PreferencesStatusWidget.js +1 -1
- package/dist/src/plugins/preferences/PreferencesStatusWidget.js.map +1 -1
- package/dist/src/plugins/profiles/ProfilesManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/profiles/ProfilesManagementPage.js +1 -1
- package/dist/src/plugins/profiles/ProfilesManagementPage.js.map +1 -1
- package/dist/src/plugins/profiles/ProfilesStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/profiles/ProfilesStatusWidget.js +1 -1
- package/dist/src/plugins/profiles/ProfilesStatusWidget.js.map +1 -1
- package/dist/src/plugins/qwickbrain/QwickbrainManagementPage.js +1 -1
- package/dist/src/plugins/qwickbrain/QwickbrainManagementPage.js.map +1 -1
- package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.js +1 -1
- package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.js.map +1 -1
- package/dist/src/plugins/rate-limit/RateLimitManagementPage.js +1 -1
- package/dist/src/plugins/rate-limit/RateLimitManagementPage.js.map +1 -1
- package/dist/src/plugins/rate-limit/RateLimitStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/rate-limit/RateLimitStatusWidget.js +1 -1
- package/dist/src/plugins/rate-limit/RateLimitStatusWidget.js.map +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.js +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.js.map +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.js +1 -1
- package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.js.map +1 -1
- package/dist/src/plugins/usage/UsageManagementPage.d.ts.map +1 -1
- package/dist/src/plugins/usage/UsageManagementPage.js +1 -1
- package/dist/src/plugins/usage/UsageManagementPage.js.map +1 -1
- package/dist/src/plugins/usage/UsageStatusWidget.d.ts.map +1 -1
- package/dist/src/plugins/usage/UsageStatusWidget.js +1 -1
- package/dist/src/plugins/usage/UsageStatusWidget.js.map +1 -1
- package/dist/src/plugins/users/UsersManagementPage.js +1 -1
- package/dist/src/plugins/users/UsersManagementPage.js.map +1 -1
- package/dist/src/plugins/users/UsersStatusWidget.js +1 -1
- package/dist/src/plugins/users/UsersStatusWidget.js.map +1 -1
- package/dist/ui/src/api/clientBuilder.d.ts +3 -3
- package/dist/ui/src/api/clientBuilder.js +5 -5
- package/dist/ui/src/api/clientBuilder.js.map +1 -1
- package/dist/ui/src/api/controlPanelApi.js +19 -19
- package/dist/ui/src/api/controlPanelApi.js.map +1 -1
- package/dist/ui/src/components/ControlPanelApp.d.ts.map +1 -1
- package/dist/ui/src/components/ControlPanelApp.js +5 -4
- package/dist/ui/src/components/ControlPanelApp.js.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.js +3 -1
- package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/CMSMaintenanceWidget.js +8 -8
- package/dist/ui/src/dashboard/widgets/CMSMaintenanceWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/CMSStatusWidget.js +2 -2
- package/dist/ui/src/dashboard/widgets/CMSStatusWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +4 -4
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.d.ts.map +1 -1
- package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js +2 -1
- package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +6 -6
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.d.ts +8 -0
- package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.js +132 -0
- package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +6 -6
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/index.d.ts +1 -0
- package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
- package/dist/ui/src/dashboard/widgets/index.js +1 -0
- package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
- package/dist-ui/assets/{index-DRG9n0cx.css → index-De-dCl_t.css} +1 -1
- package/dist-ui/assets/{index-D-4HKPkw.js → index-DnEQCOGR.js} +112 -109
- package/dist-ui/assets/{index-D-4HKPkw.js.map → index-DnEQCOGR.js.map} +1 -1
- package/dist-ui/index.html +2 -2
- package/dist-ui-lib/index.js +2623 -2441
- package/dist-ui-lib/index.js.map +1 -1
- package/dist-ui-lib/src/api/clientBuilder.d.ts +3 -3
- package/dist-ui-lib/src/dashboard/widgets/MigrationManagementWidget.d.ts +7 -0
- package/dist-ui-lib/src/dashboard/widgets/index.d.ts +1 -0
- package/package.json +5 -2
- package/src/core/control-panel.ts +10 -7
- package/src/core/gateway.ts +48 -51
- package/src/plugins/api-keys/ApiKeysManagementPage.tsx +1 -1
- package/src/plugins/api-keys/ApiKeysStatusWidget.tsx +1 -1
- package/src/plugins/auth/AuthManagementPage.tsx +1 -1
- package/src/plugins/auth/AuthStatusWidget.tsx +1 -1
- package/src/plugins/auth/adapters/supertokens-adapter.ts +9 -13
- package/src/plugins/auth/auth-plugin.ts +10 -0
- package/src/plugins/auth/env-config.ts +1 -0
- package/src/plugins/auth/types.ts +2 -0
- package/src/plugins/bans/BansManagementPage.tsx +1 -1
- package/src/plugins/bans/BansStatusWidget.tsx +1 -1
- package/src/plugins/cache/CacheManagementPage.tsx +1 -1
- package/src/plugins/cache/CacheStatusWidget.tsx +1 -1
- package/src/plugins/devices/DevicesManagementPage.tsx +1 -1
- package/src/plugins/devices/DevicesStatusWidget.tsx +1 -1
- package/src/plugins/diagnostics/DiagnosticsManagementPage.tsx +1 -1
- package/src/plugins/diagnostics/DiagnosticsStatusWidget.tsx +1 -1
- package/src/plugins/entitlements/EntitlementsManagementPage.tsx +1 -1
- package/src/plugins/entitlements/EntitlementsStatusWidget.tsx +1 -1
- package/src/plugins/health/HealthManagementPage.tsx +1 -1
- package/src/plugins/health/HealthStatusWidget.tsx +1 -1
- package/src/plugins/logs/LogsManagementPage.tsx +1 -1
- package/src/plugins/logs/LogsStatusWidget.tsx +1 -1
- package/src/plugins/maintenance/MaintenanceManagementPage.tsx +1 -1
- package/src/plugins/maintenance/MaintenanceStatusWidget.tsx +1 -1
- package/src/plugins/maintenance/SeedManagementPage.tsx +1 -1
- package/src/plugins/maintenance/seed-executor.ts +7 -6
- package/src/plugins/maintenance-plugin.ts +501 -5
- package/src/plugins/notifications/NotificationsManagementPage.tsx +1 -1
- package/src/plugins/notifications/NotificationsStatusWidget.tsx +1 -1
- package/src/plugins/parental/ParentalManagementPage.tsx +1 -1
- package/src/plugins/parental/ParentalStatusWidget.tsx +1 -1
- package/src/plugins/postgres/PostgresManagementPage.tsx +1 -1
- package/src/plugins/postgres/PostgresStatusWidget.tsx +1 -1
- package/src/plugins/preferences/PreferencesManagementPage.tsx +1 -1
- package/src/plugins/preferences/PreferencesStatusWidget.tsx +1 -1
- package/src/plugins/profiles/ProfilesManagementPage.tsx +1 -1
- package/src/plugins/profiles/ProfilesStatusWidget.tsx +1 -1
- package/src/plugins/qwickbrain/QwickbrainManagementPage.tsx +1 -1
- package/src/plugins/qwickbrain/QwickbrainStatusWidget.tsx +1 -1
- package/src/plugins/rate-limit/RateLimitManagementPage.tsx +1 -1
- package/src/plugins/rate-limit/RateLimitStatusWidget.tsx +1 -1
- package/src/plugins/subscriptions/SubscriptionsManagementPage.tsx +1 -1
- package/src/plugins/subscriptions/SubscriptionsStatusWidget.tsx +1 -1
- package/src/plugins/usage/UsageManagementPage.tsx +1 -1
- package/src/plugins/usage/UsageStatusWidget.tsx +1 -1
- package/src/plugins/users/UsersManagementPage.tsx +1 -1
- package/src/plugins/users/UsersStatusWidget.tsx +1 -1
- package/ui/src/App.tsx +4 -3
- package/ui/src/api/clientBuilder.ts +5 -5
- package/ui/src/api/controlPanelApi.ts +19 -19
- package/ui/src/components/ControlPanelApp.tsx +5 -4
- package/ui/src/dashboard/builtInWidgets.tsx +3 -0
- package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +3 -8
- package/ui/src/dashboard/widgets/CMSMaintenanceWidget.tsx +8 -8
- package/ui/src/dashboard/widgets/CMSStatusWidget.tsx +2 -2
- package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +4 -4
- package/ui/src/dashboard/widgets/DatabaseOperationsWidget.tsx +2 -1
- package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +6 -6
- package/ui/src/dashboard/widgets/MigrationManagementWidget.tsx +319 -0
- package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +6 -6
- package/ui/src/dashboard/widgets/index.ts +1 -0
- package/ui/src/hooks/useJobStream.ts +2 -2
- package/ui/src/pages/ContentOpsJobsPage.tsx +3 -3
- package/ui/src/pages/PluginPage.tsx +1 -1
- package/ui/src/pages/TenantsManagementPage.tsx +1 -1
|
@@ -10,7 +10,7 @@ export interface QwickbrainStatusWidgetProps {
|
|
|
10
10
|
apiPrefix?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function QwickbrainStatusWidget({ apiPrefix = '/
|
|
13
|
+
export function QwickbrainStatusWidget({ apiPrefix = '/qapi/qwickbrain' }: QwickbrainStatusWidgetProps) {
|
|
14
14
|
const [stats, setStats] = useState<{
|
|
15
15
|
totalDocuments: number;
|
|
16
16
|
indexedRepositories: number;
|
|
@@ -31,7 +31,7 @@ interface RateLimitStats {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export const RateLimitManagementPage: React.FC<RateLimitManagementPageProps> = ({
|
|
34
|
-
apiPrefix = '/
|
|
34
|
+
apiPrefix = '/qapi/rate-limit',
|
|
35
35
|
}) => {
|
|
36
36
|
const [rules, setRules] = useState<RateLimitRule[]>([]);
|
|
37
37
|
const [stats, setStats] = useState<RateLimitStats | null>(null);
|
|
@@ -10,7 +10,7 @@ export interface RateLimitStatusWidgetProps {
|
|
|
10
10
|
apiPrefix?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function RateLimitStatusWidget({ apiPrefix = '/
|
|
13
|
+
export function RateLimitStatusWidget({ apiPrefix = '/qapi/rate-limit' }: RateLimitStatusWidgetProps) {
|
|
14
14
|
const [stats, setStats] = useState<{
|
|
15
15
|
totalRequests: number;
|
|
16
16
|
blockedRequests: number;
|
|
@@ -23,7 +23,7 @@ interface Subscription {
|
|
|
23
23
|
amount?: number;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export function SubscriptionsManagementPage({ apiPrefix = '/
|
|
26
|
+
export function SubscriptionsManagementPage({ apiPrefix = '/qapi/subscriptions' }: SubscriptionsManagementPageProps) {
|
|
27
27
|
const [activeTab, setActiveTab] = useState<'all' | 'active' | 'expiring' | 'config'>('all');
|
|
28
28
|
const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
|
|
29
29
|
const [loading, setLoading] = useState(true);
|
|
@@ -10,7 +10,7 @@ export interface SubscriptionsStatusWidgetProps {
|
|
|
10
10
|
apiPrefix?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function SubscriptionsStatusWidget({ apiPrefix = '/
|
|
13
|
+
export function SubscriptionsStatusWidget({ apiPrefix = '/qapi/subscriptions' }: SubscriptionsStatusWidgetProps) {
|
|
14
14
|
const [stats, setStats] = useState<{
|
|
15
15
|
totalSubscriptions: number;
|
|
16
16
|
activeSubscriptions: number;
|
|
@@ -21,7 +21,7 @@ interface UsageEvent {
|
|
|
21
21
|
metadata?: Record<string, unknown>;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function UsageManagementPage({ apiPrefix = '/
|
|
24
|
+
export function UsageManagementPage({ apiPrefix = '/qapi/usage' }: UsageManagementPageProps) {
|
|
25
25
|
const [activeTab, setActiveTab] = useState<'recent' | 'features' | 'users' | 'config'>('recent');
|
|
26
26
|
const [events, setEvents] = useState<UsageEvent[]>([]);
|
|
27
27
|
const [loading, setLoading] = useState(true);
|
|
@@ -10,7 +10,7 @@ export interface UsageStatusWidgetProps {
|
|
|
10
10
|
apiPrefix?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function UsageStatusWidget({ apiPrefix = '/
|
|
13
|
+
export function UsageStatusWidget({ apiPrefix = '/qapi/usage' }: UsageStatusWidgetProps) {
|
|
14
14
|
const [stats, setStats] = useState<{
|
|
15
15
|
totalEvents: number;
|
|
16
16
|
activeUsers: number;
|
|
@@ -33,7 +33,7 @@ interface UsersStats {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const UsersManagementPage: React.FC<UsersManagementPageProps> = ({
|
|
36
|
-
apiPrefix = '/
|
|
36
|
+
apiPrefix = '/qapi/users',
|
|
37
37
|
}) => {
|
|
38
38
|
const [users, setUsers] = useState<User[]>([]);
|
|
39
39
|
const [stats, setStats] = useState<UsersStats | null>(null);
|
|
@@ -25,7 +25,7 @@ interface UsersStats {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const UsersStatusWidget: React.FC<UsersStatusWidgetProps> = ({
|
|
28
|
-
apiPrefix = '/
|
|
28
|
+
apiPrefix = '/qapi/users',
|
|
29
29
|
}) => {
|
|
30
30
|
const [stats, setStats] = useState<UsersStats | null>(null);
|
|
31
31
|
const [loading, setLoading] = useState(true);
|
package/ui/src/App.tsx
CHANGED
|
@@ -71,9 +71,10 @@ declare global {
|
|
|
71
71
|
*/
|
|
72
72
|
const basePath = window.__APP_BASE_PATH__ ?? '';
|
|
73
73
|
|
|
74
|
-
// Set API base URL
|
|
75
|
-
// When
|
|
76
|
-
|
|
74
|
+
// Set API base URL - use window.__API_BASE_PATH__ (always '/qapi' for QwickApps Server APIs)
|
|
75
|
+
// When UI is mounted at /cpanel, QwickApps Server APIs are at /qapi (not /cpanel/qapi)
|
|
76
|
+
const apiBasePath = (window as any).__API_BASE_PATH__ ?? '';
|
|
77
|
+
api.setBaseUrl(apiBasePath);
|
|
77
78
|
|
|
78
79
|
// Footer content with QwickApps Server branding
|
|
79
80
|
const footerContent = (
|
|
@@ -21,23 +21,23 @@ export interface RouteManifestEntry {
|
|
|
21
21
|
/**
|
|
22
22
|
* Build typed API client from server manifest
|
|
23
23
|
*
|
|
24
|
-
* Fetches the manifest from /
|
|
24
|
+
* Fetches the manifest from /client-manifest (baseUrl already includes /qapi) and generates a nested
|
|
25
25
|
* client object with methods for each route.
|
|
26
26
|
*
|
|
27
|
-
* @param baseUrl - Base URL
|
|
27
|
+
* @param baseUrl - Base URL for QwickApps Server APIs (e.g., '/qapi' or 'http://localhost:3000/qapi')
|
|
28
28
|
* @returns Promise resolving to the generated client
|
|
29
29
|
*
|
|
30
30
|
* @example
|
|
31
31
|
* ```typescript
|
|
32
|
-
* const client = await buildClientFromManifest<APIClient>('
|
|
32
|
+
* const client = await buildClientFromManifest<APIClient>('/qapi');
|
|
33
33
|
* const logs = await client.logs.query({ limit: 10 });
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
36
|
export async function buildClientFromManifest<T = any>(
|
|
37
37
|
baseUrl: string
|
|
38
38
|
): Promise<T> {
|
|
39
|
-
// Fetch manifest from server
|
|
40
|
-
const manifestUrl = `${baseUrl}/
|
|
39
|
+
// Fetch manifest from server (baseUrl already includes /qapi prefix)
|
|
40
|
+
const manifestUrl = `${baseUrl}/client-manifest`;
|
|
41
41
|
const response = await fetch(manifestUrl);
|
|
42
42
|
|
|
43
43
|
if (!response.ok) {
|
|
@@ -701,7 +701,7 @@ class ControlPanelApi {
|
|
|
701
701
|
}
|
|
702
702
|
|
|
703
703
|
async acceptInvitation(token: string): Promise<AcceptInvitationResponse> {
|
|
704
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
704
|
+
const response = await this._fetch(`${this.baseUrl}/users/accept-invitation/${encodeURIComponent(token)}`);
|
|
705
705
|
if (!response.ok) {
|
|
706
706
|
const error = await response.json().catch(() => ({}));
|
|
707
707
|
throw new Error(error.error || `Accept invitation failed: ${response.statusText}`);
|
|
@@ -714,7 +714,7 @@ class ControlPanelApi {
|
|
|
714
714
|
params.set('status', 'invited');
|
|
715
715
|
params.set('limit', '100');
|
|
716
716
|
|
|
717
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
717
|
+
const response = await this._fetch(`${this.baseUrl}/users?${params}`);
|
|
718
718
|
if (!response.ok) {
|
|
719
719
|
throw new Error(`Invitations request failed: ${response.statusText}`);
|
|
720
720
|
}
|
|
@@ -739,7 +739,7 @@ class ControlPanelApi {
|
|
|
739
739
|
duration = Math.max(0, Math.floor((expiresDate.getTime() - now.getTime()) / 1000));
|
|
740
740
|
}
|
|
741
741
|
|
|
742
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
742
|
+
const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`, {
|
|
743
743
|
method: 'POST',
|
|
744
744
|
headers: { 'Content-Type': 'application/json' },
|
|
745
745
|
body: JSON.stringify({ reason, duration }),
|
|
@@ -751,7 +751,7 @@ class ControlPanelApi {
|
|
|
751
751
|
}
|
|
752
752
|
|
|
753
753
|
async unbanUser(email: string): Promise<void> {
|
|
754
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
754
|
+
const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`, {
|
|
755
755
|
method: 'DELETE',
|
|
756
756
|
});
|
|
757
757
|
if (!response.ok) {
|
|
@@ -760,7 +760,7 @@ class ControlPanelApi {
|
|
|
760
760
|
}
|
|
761
761
|
|
|
762
762
|
async checkBan(email: string): Promise<{ banned: boolean; ban?: Ban }> {
|
|
763
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
763
|
+
const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`);
|
|
764
764
|
if (!response.ok) {
|
|
765
765
|
throw new Error(`Ban check failed: ${response.statusText}`);
|
|
766
766
|
}
|
|
@@ -774,7 +774,7 @@ class ControlPanelApi {
|
|
|
774
774
|
// ==================
|
|
775
775
|
|
|
776
776
|
async getEntitlements(email: string): Promise<EntitlementResult> {
|
|
777
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
777
|
+
const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}`);
|
|
778
778
|
if (!response.ok) {
|
|
779
779
|
throw new Error(`Entitlements request failed: ${response.statusText}`);
|
|
780
780
|
}
|
|
@@ -782,7 +782,7 @@ class ControlPanelApi {
|
|
|
782
782
|
}
|
|
783
783
|
|
|
784
784
|
async refreshEntitlements(email: string): Promise<EntitlementResult> {
|
|
785
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
785
|
+
const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}/refresh`, {
|
|
786
786
|
method: 'POST',
|
|
787
787
|
});
|
|
788
788
|
if (!response.ok) {
|
|
@@ -793,7 +793,7 @@ class ControlPanelApi {
|
|
|
793
793
|
|
|
794
794
|
async checkEntitlement(email: string, entitlement: string): Promise<{ has: boolean }> {
|
|
795
795
|
const response = await this._fetch(
|
|
796
|
-
`${this.baseUrl}/
|
|
796
|
+
`${this.baseUrl}/entitlements/${encodeURIComponent(email)}/check/${encodeURIComponent(entitlement)}`
|
|
797
797
|
);
|
|
798
798
|
if (!response.ok) {
|
|
799
799
|
throw new Error(`Entitlement check failed: ${response.statusText}`);
|
|
@@ -802,7 +802,7 @@ class ControlPanelApi {
|
|
|
802
802
|
}
|
|
803
803
|
|
|
804
804
|
async getAvailableEntitlements(): Promise<EntitlementDefinition[]> {
|
|
805
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
805
|
+
const response = await this._fetch(`${this.baseUrl}/entitlements/available`);
|
|
806
806
|
if (!response.ok) {
|
|
807
807
|
throw new Error(`Available entitlements request failed: ${response.statusText}`);
|
|
808
808
|
}
|
|
@@ -811,7 +811,7 @@ class ControlPanelApi {
|
|
|
811
811
|
}
|
|
812
812
|
|
|
813
813
|
async grantEntitlement(email: string, entitlement: string): Promise<void> {
|
|
814
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
814
|
+
const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}`, {
|
|
815
815
|
method: 'POST',
|
|
816
816
|
headers: { 'Content-Type': 'application/json' },
|
|
817
817
|
body: JSON.stringify({ entitlement }),
|
|
@@ -824,7 +824,7 @@ class ControlPanelApi {
|
|
|
824
824
|
|
|
825
825
|
async revokeEntitlement(email: string, entitlement: string): Promise<void> {
|
|
826
826
|
const response = await this._fetch(
|
|
827
|
-
`${this.baseUrl}/
|
|
827
|
+
`${this.baseUrl}/entitlements/${encodeURIComponent(email)}/${encodeURIComponent(entitlement)}`,
|
|
828
828
|
{ method: 'DELETE' }
|
|
829
829
|
);
|
|
830
830
|
if (!response.ok) {
|
|
@@ -833,7 +833,7 @@ class ControlPanelApi {
|
|
|
833
833
|
}
|
|
834
834
|
|
|
835
835
|
async invalidateEntitlementCache(email: string): Promise<void> {
|
|
836
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
836
|
+
const response = await this._fetch(`${this.baseUrl}/entitlements/cache/${encodeURIComponent(email)}`, {
|
|
837
837
|
method: 'DELETE',
|
|
838
838
|
});
|
|
839
839
|
if (!response.ok) {
|
|
@@ -896,7 +896,7 @@ class ControlPanelApi {
|
|
|
896
896
|
}
|
|
897
897
|
|
|
898
898
|
async getPluginDetail(id: string): Promise<PluginDetailResponse> {
|
|
899
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
899
|
+
const response = await this._fetch(`${this.baseUrl}/plugins/${encodeURIComponent(id)}`);
|
|
900
900
|
if (!response.ok) {
|
|
901
901
|
if (response.status === 404) {
|
|
902
902
|
throw new Error(`Plugin not found: ${id}`);
|
|
@@ -957,7 +957,7 @@ class ControlPanelApi {
|
|
|
957
957
|
* Delete auth configuration (revert to environment variables)
|
|
958
958
|
*/
|
|
959
959
|
async deleteAuthConfig(): Promise<{ success: boolean; message: string }> {
|
|
960
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
960
|
+
const response = await this._fetch(`${this.baseUrl}/auth/config`, {
|
|
961
961
|
method: 'DELETE',
|
|
962
962
|
});
|
|
963
963
|
if (!response.ok) {
|
|
@@ -979,7 +979,7 @@ class ControlPanelApi {
|
|
|
979
979
|
* Test current auth provider connection (uses existing env/runtime config)
|
|
980
980
|
*/
|
|
981
981
|
async testCurrentAuthProvider(): Promise<TestProviderResponse> {
|
|
982
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
982
|
+
const response = await this._fetch(`${this.baseUrl}/auth/test-current`, {
|
|
983
983
|
method: 'POST',
|
|
984
984
|
headers: { 'Content-Type': 'application/json' },
|
|
985
985
|
});
|
|
@@ -1019,7 +1019,7 @@ class ControlPanelApi {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
|
|
1021
1021
|
async disconnectNotificationsClient(clientId: string): Promise<{ success: boolean }> {
|
|
1022
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
1022
|
+
const response = await this._fetch(`${this.baseUrl}/notifications/clients/${encodeURIComponent(clientId)}`, {
|
|
1023
1023
|
method: 'DELETE',
|
|
1024
1024
|
});
|
|
1025
1025
|
if (!response.ok) {
|
|
@@ -1030,7 +1030,7 @@ class ControlPanelApi {
|
|
|
1030
1030
|
}
|
|
1031
1031
|
|
|
1032
1032
|
async forceNotificationsReconnect(): Promise<{ success: boolean; message: string }> {
|
|
1033
|
-
const response = await this._fetch(`${this.baseUrl}/
|
|
1033
|
+
const response = await this._fetch(`${this.baseUrl}/notifications/reconnect`, {
|
|
1034
1034
|
method: 'POST',
|
|
1035
1035
|
});
|
|
1036
1036
|
if (!response.ok) {
|
|
@@ -1104,7 +1104,7 @@ class ControlPanelApi {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
|
|
1106
1106
|
async updatePreferences(preferences: Record<string, unknown>): Promise<PreferencesResponse> {
|
|
1107
|
-
const url = `${this.baseUrl}/
|
|
1107
|
+
const url = `${this.baseUrl}/preferences`;
|
|
1108
1108
|
const response = await this._fetch(url, {
|
|
1109
1109
|
method: 'PUT',
|
|
1110
1110
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -1118,7 +1118,7 @@ class ControlPanelApi {
|
|
|
1118
1118
|
}
|
|
1119
1119
|
|
|
1120
1120
|
async deletePreferences(): Promise<void> {
|
|
1121
|
-
const url = `${this.baseUrl}/
|
|
1121
|
+
const url = `${this.baseUrl}/preferences`;
|
|
1122
1122
|
const response = await this._fetch(url, {
|
|
1123
1123
|
method: 'DELETE',
|
|
1124
1124
|
});
|
|
@@ -147,10 +147,11 @@ export function ControlPanelApp({
|
|
|
147
147
|
// Combine built-in widget components with custom ones
|
|
148
148
|
const allWidgetComponents = [...getBuiltInWidgetComponents(), ...widgetComponents];
|
|
149
149
|
|
|
150
|
-
// Configure API base URL - read from injected
|
|
151
|
-
// Server injects window.__APP_BASE_PATH__
|
|
152
|
-
//
|
|
153
|
-
|
|
150
|
+
// Configure API base URL - read from injected __API_BASE_PATH__ if available
|
|
151
|
+
// Server injects window.__APP_BASE_PATH__ for UI routing (e.g., '/cpanel')
|
|
152
|
+
// and window.__API_BASE_PATH__ for QwickApps Server API calls (always '/qapi')
|
|
153
|
+
// Example: UI mounted at /cpanel, but QwickApps Server APIs go to /qapi (not /cpanel/qapi)
|
|
154
|
+
const apiBasePath = (window as any).__API_BASE_PATH__ || '';
|
|
154
155
|
api.setBaseUrl(apiBasePath);
|
|
155
156
|
|
|
156
157
|
// Fetch version from API
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
CMSStatusWidget,
|
|
19
19
|
CMSMaintenanceWidget,
|
|
20
20
|
SeedManagementWidget,
|
|
21
|
+
MigrationManagementWidget,
|
|
21
22
|
ServiceControlWidget,
|
|
22
23
|
EnvironmentConfigWidget,
|
|
23
24
|
DatabaseOpsWidget,
|
|
@@ -40,6 +41,7 @@ export const builtInWidgetComponents: Record<string, React.ComponentType> = {
|
|
|
40
41
|
CMSStatusWidget: CMSStatusWidget,
|
|
41
42
|
CMSMaintenanceWidget: CMSMaintenanceWidget,
|
|
42
43
|
SeedManagementWidget: SeedManagementWidget,
|
|
44
|
+
MigrationManagementWidget: MigrationManagementWidget,
|
|
43
45
|
ServiceControlWidget: ServiceControlWidget,
|
|
44
46
|
EnvironmentConfigWidget: EnvironmentConfigWidget,
|
|
45
47
|
DatabaseOpsWidget: DatabaseOpsWidget,
|
|
@@ -65,6 +67,7 @@ export function getBuiltInWidgetComponents(): WidgetComponent[] {
|
|
|
65
67
|
{ name: 'CMSStatusWidget', component: CMSStatusWidget },
|
|
66
68
|
{ name: 'CMSMaintenanceWidget', component: CMSMaintenanceWidget },
|
|
67
69
|
{ name: 'SeedManagementWidget', component: SeedManagementWidget },
|
|
70
|
+
{ name: 'MigrationManagementWidget', component: MigrationManagementWidget },
|
|
68
71
|
{ name: 'ServiceControlWidget', component: ServiceControlWidget },
|
|
69
72
|
{ name: 'EnvironmentConfigWidget', component: EnvironmentConfigWidget },
|
|
70
73
|
{ name: 'DatabaseOpsWidget', component: DatabaseOpsWidget },
|
|
@@ -12,14 +12,9 @@ import { Box, Typography, Chip, CircularProgress, Alert } from '@mui/material';
|
|
|
12
12
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
|
13
13
|
import ErrorIcon from '@mui/icons-material/Error';
|
|
14
14
|
import BlockIcon from '@mui/icons-material/Block';
|
|
15
|
-
import { api } from '../../api/controlPanelApi';
|
|
15
|
+
import { api, type AuthConfigStatus } from '../../api/controlPanelApi';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
state: 'enabled' | 'disabled' | 'error';
|
|
19
|
-
adapter: string | null;
|
|
20
|
-
error?: string;
|
|
21
|
-
missingVars?: string[];
|
|
22
|
-
}
|
|
17
|
+
type AuthStatus = AuthConfigStatus;
|
|
23
18
|
|
|
24
19
|
const adapterLabels: Record<string, string> = {
|
|
25
20
|
supertokens: 'SuperTokens',
|
|
@@ -36,7 +31,7 @@ export function AuthStatusWidget() {
|
|
|
36
31
|
useEffect(() => {
|
|
37
32
|
const fetchStatus = async () => {
|
|
38
33
|
try {
|
|
39
|
-
const data = await api.
|
|
34
|
+
const data = await api.getAuthConfigStatus();
|
|
40
35
|
setStatus(data);
|
|
41
36
|
} catch (err) {
|
|
42
37
|
setError(err instanceof Error ? err.message : 'Failed to fetch auth status');
|
|
@@ -49,8 +49,8 @@ export function CMSMaintenanceWidget() {
|
|
|
49
49
|
|
|
50
50
|
const fetchStatus = async () => {
|
|
51
51
|
try {
|
|
52
|
-
const basePath = (window as any).
|
|
53
|
-
const response = await fetch(`${basePath}/
|
|
52
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
53
|
+
const response = await fetch(`${basePath}/cms/status`);
|
|
54
54
|
if (!response.ok) {
|
|
55
55
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
56
56
|
}
|
|
@@ -63,8 +63,8 @@ export function CMSMaintenanceWidget() {
|
|
|
63
63
|
|
|
64
64
|
const fetchSeeds = async () => {
|
|
65
65
|
try {
|
|
66
|
-
const basePath = (window as any).
|
|
67
|
-
const response = await fetch(`${basePath}/
|
|
66
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
67
|
+
const response = await fetch(`${basePath}/cms/seeds`);
|
|
68
68
|
if (!response.ok) {
|
|
69
69
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
70
70
|
}
|
|
@@ -88,8 +88,8 @@ export function CMSMaintenanceWidget() {
|
|
|
88
88
|
setError(null);
|
|
89
89
|
setSuccess(null);
|
|
90
90
|
try {
|
|
91
|
-
const basePath = (window as any).
|
|
92
|
-
const response = await fetch(`${basePath}/
|
|
91
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
92
|
+
const response = await fetch(`${basePath}/cms/restart`, { method: 'POST' });
|
|
93
93
|
const data = await response.json();
|
|
94
94
|
|
|
95
95
|
if (response.ok) {
|
|
@@ -109,8 +109,8 @@ export function CMSMaintenanceWidget() {
|
|
|
109
109
|
setSuccess(null);
|
|
110
110
|
|
|
111
111
|
try {
|
|
112
|
-
const basePath = (window as any).
|
|
113
|
-
const response = await fetch(`${basePath}/
|
|
112
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
113
|
+
const response = await fetch(`${basePath}/cms/seeds/${seedName}/execute`, {
|
|
114
114
|
method: 'POST',
|
|
115
115
|
});
|
|
116
116
|
if (!response.ok) {
|
|
@@ -35,8 +35,8 @@ export function CMSStatusWidget() {
|
|
|
35
35
|
|
|
36
36
|
const fetchStatus = async () => {
|
|
37
37
|
try {
|
|
38
|
-
const basePath = (window as any).
|
|
39
|
-
const response = await fetch(`${basePath}/
|
|
38
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
39
|
+
const response = await fetch(`${basePath}/cms/status`);
|
|
40
40
|
if (!response.ok) {
|
|
41
41
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
42
42
|
}
|
|
@@ -47,8 +47,8 @@ export function CacheMaintenanceWidget() {
|
|
|
47
47
|
setLoading(true);
|
|
48
48
|
setError(null);
|
|
49
49
|
try {
|
|
50
|
-
const basePath = (window as any).
|
|
51
|
-
const response = await fetch(`${basePath}/
|
|
50
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
51
|
+
const response = await fetch(`${basePath}/cache:default/stats`);
|
|
52
52
|
if (!response.ok) {
|
|
53
53
|
if (response.status === 404) {
|
|
54
54
|
throw new Error('Cache plugin not configured');
|
|
@@ -76,8 +76,8 @@ export function CacheMaintenanceWidget() {
|
|
|
76
76
|
setSuccess(null);
|
|
77
77
|
|
|
78
78
|
try {
|
|
79
|
-
const basePath = (window as any).
|
|
80
|
-
const response = await fetch(`${basePath}/
|
|
79
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
80
|
+
const response = await fetch(`${basePath}/cache:default/flush`, {
|
|
81
81
|
method: 'POST',
|
|
82
82
|
headers: { 'Content-Type': 'application/json' },
|
|
83
83
|
});
|
|
@@ -159,7 +159,8 @@ const AdminCredentialsDialog: React.FC<AdminCredentialsDialogProps> = ({
|
|
|
159
159
|
|
|
160
160
|
export const DatabaseOperationsWidget: React.FC<DatabaseOperationsWidgetProps> = () => {
|
|
161
161
|
// Use default values since props cannot be passed through WidgetContribution
|
|
162
|
-
|
|
162
|
+
// QwickApps Server plugin routes are at /qapi/* when integrated with Next.js apps
|
|
163
|
+
const apiPrefix = '/qapi/postgres:default';
|
|
163
164
|
const instanceName = 'default';
|
|
164
165
|
const [status, setStatus] = useState<DatabaseStatus | null>(null);
|
|
165
166
|
const [loading, setLoading] = useState(true);
|
|
@@ -61,8 +61,8 @@ export function LogsMaintenanceWidget() {
|
|
|
61
61
|
|
|
62
62
|
const fetchSources = async () => {
|
|
63
63
|
try {
|
|
64
|
-
const basePath = (window as any).
|
|
65
|
-
const response = await fetch(`${basePath}/
|
|
64
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
65
|
+
const response = await fetch(`${basePath}/logs/sources`);
|
|
66
66
|
if (!response.ok) throw new Error('Failed to fetch log sources');
|
|
67
67
|
const data = await response.json();
|
|
68
68
|
setSources(data.sources || []);
|
|
@@ -80,8 +80,8 @@ export function LogsMaintenanceWidget() {
|
|
|
80
80
|
setLoading(true);
|
|
81
81
|
setError(null);
|
|
82
82
|
try {
|
|
83
|
-
const basePath = (window as any).
|
|
84
|
-
const response = await fetch(`${basePath}/
|
|
83
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
84
|
+
const response = await fetch(`${basePath}/logs/stats?source=${selectedSource}`);
|
|
85
85
|
if (!response.ok) throw new Error('Failed to fetch log stats');
|
|
86
86
|
const data = await response.json();
|
|
87
87
|
setStats(data);
|
|
@@ -110,8 +110,8 @@ export function LogsMaintenanceWidget() {
|
|
|
110
110
|
setSuccess(null);
|
|
111
111
|
|
|
112
112
|
try {
|
|
113
|
-
const basePath = (window as any).
|
|
114
|
-
const response = await fetch(`${basePath}/
|
|
113
|
+
const basePath = (window as any).__API_BASE_PATH__ || '';
|
|
114
|
+
const response = await fetch(`${basePath}/logs/clear`, {
|
|
115
115
|
method: 'POST',
|
|
116
116
|
headers: { 'Content-Type': 'application/json' },
|
|
117
117
|
body: JSON.stringify({ source: selectedSource }),
|