Browse Source

fix: use store_sync_config for data access display and disable product settings #98

- IntegrationsContent now uses store_sync_config policies instead of deprecated data_access_permissions
- DataAccessSettings now receives currentPolicies from store_sync_config
- Product Data settings are now disabled (store owners cannot change this)
- Fixed WebUI showing incorrect "Sync & cache" for all data types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude 5 months ago
parent
commit
b01da8aa07

+ 17 - 13
shopcall.ai-main/src/components/DataAccessSettings.tsx

@@ -148,16 +148,17 @@ export function DataAccessSettings({
   const security = getSecurityLevel();
   const SecurityIcon = security.icon;
 
-  const renderPolicyOptions = (dataType: 'products' | 'customers' | 'orders', policyKey: keyof AccessPolicySettings, isPII: boolean = false) => {
+  const renderPolicyOptions = (dataType: 'products' | 'customers' | 'orders', policyKey: keyof AccessPolicySettings, isPII: boolean = false, isDisabled: boolean = false) => {
     return (
       <RadioGroup
         value={policies[policyKey]}
         onValueChange={(value) => handlePolicyChange(dataType, value as DataAccessPolicy)}
         className="space-y-3 mt-3"
+        disabled={isDisabled}
       >
-        <div className="flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 hover:bg-slate-600/50 transition-colors">
-          <RadioGroupItem value="sync" id={`${dataType}-sync`} className="mt-1" disabled={saving} />
-          <Label htmlFor={`${dataType}-sync`} className="cursor-pointer flex-1">
+        <div className={`flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 ${isDisabled ? 'opacity-60 cursor-not-allowed' : 'hover:bg-slate-600/50'} transition-colors`}>
+          <RadioGroupItem value="sync" id={`${dataType}-sync`} className="mt-1" disabled={saving || isDisabled} />
+          <Label htmlFor={`${dataType}-sync`} className={`flex-1 ${isDisabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}>
             <div className="flex items-center gap-2 mb-1">
               <Database className="w-4 h-4 text-cyan-400" />
               <span className="text-white font-medium">Sync & Cache</span>
@@ -169,9 +170,9 @@ export function DataAccessSettings({
           </Label>
         </div>
 
-        <div className="flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 hover:bg-slate-600/50 transition-colors">
-          <RadioGroupItem value="api_only" id={`${dataType}-api`} className="mt-1" disabled={saving} />
-          <Label htmlFor={`${dataType}-api`} className="cursor-pointer flex-1">
+        <div className={`flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 ${isDisabled ? 'opacity-60 cursor-not-allowed' : 'hover:bg-slate-600/50'} transition-colors`}>
+          <RadioGroupItem value="api_only" id={`${dataType}-api`} className="mt-1" disabled={saving || isDisabled} />
+          <Label htmlFor={`${dataType}-api`} className={`flex-1 ${isDisabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}>
             <div className="flex items-center gap-2 mb-1">
               <Cloud className="w-4 h-4 text-blue-400" />
               <span className="text-white font-medium">API Access Only</span>
@@ -183,9 +184,9 @@ export function DataAccessSettings({
           </Label>
         </div>
 
-        <div className="flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 hover:bg-slate-600/50 transition-colors">
-          <RadioGroupItem value="not_allowed" id={`${dataType}-none`} className="mt-1" disabled={saving} />
-          <Label htmlFor={`${dataType}-none`} className="cursor-pointer flex-1">
+        <div className={`flex items-start space-x-3 p-3 rounded-md bg-slate-600/30 ${isDisabled ? 'opacity-60 cursor-not-allowed' : 'hover:bg-slate-600/50'} transition-colors`}>
+          <RadioGroupItem value="not_allowed" id={`${dataType}-none`} className="mt-1" disabled={saving || isDisabled} />
+          <Label htmlFor={`${dataType}-none`} className={`flex-1 ${isDisabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}>
             <div className="flex items-center gap-2 mb-1">
               <Ban className="w-4 h-4 text-red-400" />
               <span className="text-white font-medium">No Access</span>
@@ -246,18 +247,21 @@ export function DataAccessSettings({
 
         {/* Policy Settings */}
         <div className="space-y-6">
-          {/* Products Access */}
+          {/* Products Access - Always enabled, store owners cannot change this */}
           <div className="p-4 bg-slate-700/50 rounded-lg border border-slate-600">
             <div className="flex items-center gap-2 mb-2">
               <h4 className="text-white font-medium">Product Data</h4>
               <Badge variant="outline" className="text-xs border-blue-500 text-blue-400">
                 Public Data
               </Badge>
+              <Badge variant="outline" className="text-xs border-slate-500 text-slate-400">
+                Required
+              </Badge>
             </div>
             <p className="text-sm text-slate-400 mb-3">
-              Product information (names, prices, descriptions, stock levels)
+              Product information (names, prices, descriptions, stock levels). This setting is managed by the system and cannot be changed.
             </p>
-            {renderPolicyOptions('products', 'products_access_policy', false)}
+            {renderPolicyOptions('products', 'products_access_policy', false, true)}
           </div>
 
           {/* Customers Access - Hidden when VITE_HIDE_CUSTOMERS_ACCESS_SETTINGS is true */}

+ 30 - 9
shopcall.ai-main/src/components/IntegrationsContent.tsx

@@ -471,30 +471,30 @@ export function IntegrationsContent() {
   };
 
   const getDataAccessBadges = (shop: ConnectedStore) => {
-    const permissions = shop.data_access_permissions || {
-      allow_customer_access: true,
-      allow_order_access: true,
-      allow_product_access: true
-    };
+    // Use the store_sync_config policies instead of the old data_access_permissions
+    const syncConfig = shop.store_sync_config?.[0];
+    const productsPolicy = syncConfig?.products_access_policy || 'sync';
+    const customersPolicy = syncConfig?.customers_access_policy || 'api_only';
+    const ordersPolicy = syncConfig?.orders_access_policy || 'api_only';
 
     return (
       <div className="flex flex-wrap gap-1">
-        {permissions.allow_product_access && (
+        {productsPolicy !== 'not_allowed' && (
           <Badge variant="outline" className="text-xs border-blue-500 text-blue-400">
             {t('integrations.products')}
           </Badge>
         )}
-        {permissions.allow_customer_access && (
+        {customersPolicy !== 'not_allowed' && (
           <Badge variant="outline" className="text-xs border-green-500 text-green-400">
             {t('integrations.customers')}
           </Badge>
         )}
-        {permissions.allow_order_access && (
+        {ordersPolicy !== 'not_allowed' && (
           <Badge variant="outline" className="text-xs border-purple-500 text-purple-400">
             {t('integrations.orders')}
           </Badge>
         )}
-        {!permissions.allow_customer_access && !permissions.allow_order_access && (
+        {customersPolicy === 'not_allowed' && ordersPolicy === 'not_allowed' && (
           <Badge variant="outline" className="text-xs border-orange-500 text-orange-400">
             {t('integrations.limitedAccess')}
           </Badge>
@@ -920,7 +920,28 @@ export function IntegrationsContent() {
                 allow_order_access: true,
                 allow_product_access: true
               }}
+              currentPolicies={selectedStore.store_sync_config?.[0] ? {
+                products_access_policy: selectedStore.store_sync_config[0].products_access_policy || 'sync',
+                customers_access_policy: selectedStore.store_sync_config[0].customers_access_policy || 'api_only',
+                orders_access_policy: selectedStore.store_sync_config[0].orders_access_policy || 'api_only'
+              } : undefined}
               onPermissionsUpdated={handlePermissionsUpdated}
+              onPoliciesUpdated={(newPolicies) => {
+                // Update the store in the list with the new policies
+                setConnectedShops(prev => prev.map(shop =>
+                  shop.id === selectedStore?.id
+                    ? {
+                        ...shop,
+                        store_sync_config: [{
+                          ...(shop.store_sync_config?.[0] || { enabled: true, sync_frequency: 'hourly' }),
+                          products_access_policy: newPolicies.products_access_policy,
+                          customers_access_policy: newPolicies.customers_access_policy,
+                          orders_access_policy: newPolicies.orders_access_policy
+                        }]
+                      }
+                    : shop
+                ));
+              }}
             />
           )}
           <div className="flex justify-end pt-4 border-t border-slate-700">