Skip to content

Commit 4d0e73d

Browse files
author
colinmcneil
committed
Sync-aroo
1 parent 95c71fb commit 4d0e73d

File tree

4 files changed

+51
-75
lines changed

4 files changed

+51
-75
lines changed

src/extension/ui/src/App.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, Suspense } from 'react';
1+
import React, { useState, Suspense, useEffect } from 'react';
22
import { createDockerDesktopClient } from '@docker/extension-api-client';
33
import { Typography, Button, IconButton, Alert, DialogTitle, Dialog, DialogContent, CircularProgress, Paper, Box, SvgIcon, useTheme } from '@mui/material';
44
import { CatalogItemRichened } from './types/catalog';
@@ -51,6 +51,19 @@ export function App() {
5151
requiredImages.isLoading ||
5252
secrets.isLoading;
5353

54+
useEffect(() => {
55+
if (catalogAll.registryItems && config.config) {
56+
config.syncConfigWithRegistry(catalogAll.registryItems);
57+
}
58+
}, [catalogAll.registryItems]);
59+
60+
useEffect(() => {
61+
if (config.config) {
62+
console.log('registryItems', catalogAll.registryItems)
63+
catalogAll.syncRegistryWithConfig();
64+
}
65+
}, [config.config]);
66+
5467
return (
5568
<>
5669
{isLoading ? (

src/extension/ui/src/Registry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export const syncRegistryWithConfig = async (client: v1.DockerDesktopClient, reg
103103
return;
104104
}
105105
console.log('SYNC STARTED. CONFIG -> REGISTRY', config, registry)
106-
const oldRegString = JSON.stringify({ registry })
106+
const oldRegString = JSON.stringify(registry)
107107
for (const [itemName, itemConfig] of Object.entries(config)) {
108108
const registryItem = registry[itemName]
109109
if (registryItem) {

src/extension/ui/src/queries/useCatalog.ts

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { v1 } from "@docker/extension-api-client-types";
22
import { CatalogItem, CatalogItemRichened, CatalogItemWithName } from '../types/catalog';
3-
import { getRegistry } from '../Registry';
3+
import { getRegistry, syncRegistryWithConfig } from '../Registry';
44
import Secrets from '../Secrets';
55
import { parse } from 'yaml';
66
import { CATALOG_URL, POLL_INTERVAL, UNASSIGNED_SECRET_PLACEHOLDER } from '../Constants';
@@ -113,13 +113,14 @@ function useCatalog(client: v1.DockerDesktopClient) {
113113
catalogItems,
114114
catalogLoading,
115115
tryLoadCatalog,
116-
refetchCatalog
116+
refetchCatalog,
117117
};
118118
}
119119

120120
function useRegistry(client: v1.DockerDesktopClient) {
121121
const queryClient = useQueryClient();
122122
const [canRegister, setCanRegister] = useState<boolean>(false);
123+
const { config } = useConfig(client);
123124

124125
const {
125126
data: registryItems = undefined,
@@ -193,19 +194,26 @@ function useRegistry(client: v1.DockerDesktopClient) {
193194
}
194195
});
195196

197+
const syncRegistryWithConfigMutation = useMutation({
198+
mutationFn: async () => {
199+
if (!config || !registryItems) return { success: false };
200+
await syncRegistryWithConfig(client, registryItems, config);
201+
}
202+
});
203+
196204
return {
197205
registryItems,
198206
registryLoading,
199207
canRegister,
200208
tryLoadRegistry: refetchRegistry,
201-
mutateRegistry
209+
mutateRegistry,
210+
syncRegistryWithConfig: syncRegistryWithConfigMutation.mutateAsync
202211
};
203212
}
204213

205214
export function useCatalogOperations(client: v1.DockerDesktopClient) {
206215
const queryClient = useQueryClient();
207216
const { registryItems } = useRegistry(client);
208-
const { config } = useConfig(client);
209217

210218
// Register catalog item mutation
211219
const registerItemMutation = useMutation({
@@ -218,21 +226,6 @@ export function useCatalogOperations(client: v1.DockerDesktopClient) {
218226
[item.name]: { ref: item.ref }
219227
};
220228

221-
// Handle configuration
222-
if (item.config) {
223-
let itemConfig = config?.[item.name] || {};
224-
225-
// If there's a JSON schema configuration, validate and generate default values
226-
if (Array.isArray(item.config) && item.config.length > 0) {
227-
// Use JSON schema template for any remaining defaults
228-
const template = getTemplateForItem(item, itemConfig);
229-
itemConfig = { ...template, ...itemConfig };
230-
}
231-
232-
// Assign the configuration
233-
newRegistry[item.name].config = itemConfig;
234-
}
235-
236229
const payload = escapeJSONForPlatformShell(
237230
{ registry: newRegistry },
238231
client.host.platform
@@ -258,14 +251,6 @@ export function useCatalogOperations(client: v1.DockerDesktopClient) {
258251
[item.name]: { ref: item.ref }
259252
};
260253

261-
// If there's config, add it
262-
if (item.config && config && config[item.name]) {
263-
newRegistry[item.name] = {
264-
...newRegistry[item.name],
265-
config: config[item.name]
266-
};
267-
}
268-
269254
queryClient.setQueryData(['registry'], newRegistry);
270255
},
271256
onSuccess: async (data) => {
@@ -328,7 +313,7 @@ export function useCatalogOperations(client: v1.DockerDesktopClient) {
328313

329314
export function useCatalogAll(client: v1.DockerDesktopClient) {
330315
const { catalogItems, catalogLoading, tryLoadCatalog } = useCatalog(client);
331-
const { registryItems, registryLoading, canRegister, tryLoadRegistry } = useRegistry(client);
316+
const { registryItems, registryLoading, canRegister, tryLoadRegistry, syncRegistryWithConfig } = useRegistry(client);
332317
const {
333318
registerCatalogItem,
334319
unregisterCatalogItem,
@@ -347,5 +332,6 @@ export function useCatalogAll(client: v1.DockerDesktopClient) {
347332
tryLoadRegistry,
348333
registerCatalogItem,
349334
unregisterCatalogItem,
335+
syncRegistryWithConfig
350336
};
351337
}
Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { v1 } from "@docker/extension-api-client-types";
2-
import { getStoredConfig, syncRegistryWithConfig } from '../Registry';
2+
import { getStoredConfig, syncConfigWithRegistry } from '../Registry';
33
import { POLL_INTERVAL } from '../Constants';
44
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
55
import { CatalogItemRichened, CatalogItemWithName } from '../types/catalog';
@@ -20,7 +20,25 @@ export function useConfig(client: v1.DockerDesktopClient) {
2020
const queryClient = useQueryClient();
2121
const configRef = useRef<any>(null);
2222

23-
// Load config with React Query
23+
24+
// Sync config with registry - use the exact types from Registry.ts
25+
const syncConfigWithRegistryMutation = useMutation({
26+
mutationFn: async (registryItems: { [key: string]: { ref: string; config: any } }) => {
27+
try {
28+
if (!config) return { success: false };
29+
await syncConfigWithRegistry(client, registryItems, config);
30+
return { success: true };
31+
} catch (error) {
32+
console.error('Failed to sync config with registry:', error);
33+
throw error;
34+
}
35+
},
36+
onSuccess: async () => {
37+
// Refetch config to ensure UI is in sync after registry sync
38+
await refetchConfig();
39+
}
40+
});
41+
2442
const {
2543
data: config = undefined,
2644
refetch: refetchConfig,
@@ -40,11 +58,10 @@ export function useConfig(client: v1.DockerDesktopClient) {
4058
}
4159
},
4260
refetchInterval: POLL_INTERVAL,
43-
staleTime: 30000, // Data remains fresh for 30 seconds
61+
staleTime: 30000,
4462
gcTime: 300000,
4563
});
4664

47-
// Save config mutation
4865
const saveConfigMutation = useMutation({
4966
mutationFn: async ({ itemName, newConfig }: { itemName: string, newConfig: { [key: string]: any } }) => {
5067
try {
@@ -60,22 +77,17 @@ export function useConfig(client: v1.DockerDesktopClient) {
6077
}, client.host.platform);
6178

6279
await tryRunImageSync(client, ['--rm', '-v', 'docker-prompts:/docker-prompts', '--workdir', '/docker-prompts', 'vonwig/function_write_files:latest', payload]);
63-
64-
// Update our ref with the new state after successful save
6580
const updatedConfigRef = JSON.parse(JSON.stringify(updatedConfig));
6681
configRef.current = updatedConfigRef;
6782
return { itemName, updatedConfig: updatedConfigRef };
6883
} catch (error) {
6984
client.desktopUI.toast.error('Failed to update config: ' + error);
70-
// Treat YAML file write failures as fatal, no rollback
7185
throw error;
7286
}
7387
},
7488
onMutate: async ({ itemName, newConfig }) => {
75-
// Cancel any outgoing refetches
7689
await queryClient.cancelQueries({ queryKey: ['config'] });
7790

78-
// Optimistically update to the new value
7991
const updatedConfig = {
8092
...(queryClient.getQueryData(['config']) as Record<string, any> || {}),
8193
[itemName]: newConfig
@@ -85,29 +97,10 @@ export function useConfig(client: v1.DockerDesktopClient) {
8597
},
8698
onSuccess: (data) => {
8799
client.desktopUI.toast.success('Config saved successfully.');
88-
// Update the cached data with the new config
89100
queryClient.setQueryData(['config'], data.updatedConfig);
90101
}
91102
});
92103

93-
// Sync config with registry - use the exact types from Registry.ts
94-
const syncRegistryMutation = useMutation({
95-
mutationFn: async (registryItems: { [key: string]: { ref: string; config: any } }) => {
96-
try {
97-
if (!config) return { success: false };
98-
await syncRegistryWithConfig(client, registryItems, config);
99-
return { success: true };
100-
} catch (error) {
101-
console.error('Failed to sync config with registry:', error);
102-
throw error;
103-
}
104-
},
105-
onSuccess: async () => {
106-
// Refetch config to ensure UI is in sync after registry sync
107-
await refetchConfig();
108-
}
109-
});
110-
111104
const tryLoadConfig = async () => {
112105
await refetchConfig();
113106
};
@@ -123,27 +116,11 @@ export function useConfig(client: v1.DockerDesktopClient) {
123116
}
124117
};
125118

126-
// Make this function handle both with and without config, by ensuring config is present
127-
const syncConfigWithRegistry = async (registryItems: { [key: string]: { ref: string; config?: any } }) => {
128-
// Convert to the format expected by syncRegistryWithConfig
129-
const formattedRegistry: { [key: string]: { ref: string; config: any } } = {};
130-
131-
// Ensure all registry items have a config property, even if empty
132-
for (const [key, item] of Object.entries(registryItems)) {
133-
formattedRegistry[key] = {
134-
ref: item.ref,
135-
config: item.config || {}
136-
};
137-
}
138-
139-
await syncRegistryMutation.mutateAsync(formattedRegistry);
140-
};
141-
142119
return {
143120
config,
144121
configLoading,
145122
tryLoadConfig,
146123
saveConfig,
147-
syncConfigWithRegistry
124+
syncConfigWithRegistry: syncConfigWithRegistryMutation.mutateAsync
148125
};
149126
}

0 commit comments

Comments
 (0)