fix: sync now resets installed_version when extension removed from server
- Backend: sync_customer_extensions now sets installed_version=NULL when extension is missing_on_server (previously only detected drift without updating DB) - Frontend: refresh button now calls /sync endpoint before reloading, ensuring the dashboard reflects actual server state Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+18
-4
@@ -204,6 +204,20 @@ function CustomerDetail({ customerId }) {
|
|||||||
const [selected, setSelected] = useState(new Set())
|
const [selected, setSelected] = useState(new Set())
|
||||||
const [batchDeploying, setBatchDeploying] = useState(false)
|
const [batchDeploying, setBatchDeploying] = useState(false)
|
||||||
const [batchProgress, setBatchProgress] = useState({ current: 0, total: 0, module: '' })
|
const [batchProgress, setBatchProgress] = useState({ current: 0, total: 0, module: '' })
|
||||||
|
const [syncing, setSyncing] = useState(false)
|
||||||
|
|
||||||
|
const syncAndReload = async () => {
|
||||||
|
setSyncing(true)
|
||||||
|
setDeployResult(null)
|
||||||
|
try {
|
||||||
|
await fetch('/sync', {
|
||||||
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ customer_id: customerId })
|
||||||
|
})
|
||||||
|
} catch (_) {}
|
||||||
|
reload()
|
||||||
|
setSyncing(false)
|
||||||
|
}
|
||||||
|
|
||||||
if (!customer) return <Loader />
|
if (!customer) return <Loader />
|
||||||
|
|
||||||
@@ -311,10 +325,10 @@ function CustomerDetail({ customerId }) {
|
|||||||
<h3 className="text-xl font-black text-slate-900">{customer.name}</h3>
|
<h3 className="text-xl font-black text-slate-900">{customer.name}</h3>
|
||||||
<p className="text-sm text-slate-500" dir="ltr">{customer.espocrm_url}</p>
|
<p className="text-sm text-slate-500" dir="ltr">{customer.espocrm_url}</p>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={() => reload()}
|
<button onClick={syncAndReload} disabled={syncing}
|
||||||
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
|
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all disabled:opacity-50"
|
||||||
title="רענון הרחבות">
|
title="סנכרון מול השרת">
|
||||||
<Icon name="refresh" className="text-lg" />
|
<Icon name="sync" className={`text-lg ${syncing ? 'animate-spin' : ''}`} />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => setEditing(true)}
|
<button onClick={() => setEditing(true)}
|
||||||
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
|
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
|
||||||
|
|||||||
@@ -394,6 +394,12 @@ def sync_customer_extensions(customer):
|
|||||||
if server_ver is None:
|
if server_ver is None:
|
||||||
drifts.append({'extension': ext_name, 'type': 'missing_on_server',
|
drifts.append({'extension': ext_name, 'type': 'missing_on_server',
|
||||||
'platform': platform_ver, 'server': None})
|
'platform': platform_ver, 'server': None})
|
||||||
|
if platform_ver is not None:
|
||||||
|
query("""UPDATE customer_extensions SET installed_version = NULL, installed_at = NULL, updated_at = NOW()
|
||||||
|
FROM extensions e WHERE customer_extensions.extension_id = e.id
|
||||||
|
AND customer_extensions.customer_id = %s AND e.name = %s""",
|
||||||
|
(cid, ext_name), fetch=None)
|
||||||
|
updated += 1
|
||||||
elif server_ver != platform_ver:
|
elif server_ver != platform_ver:
|
||||||
drifts.append({'extension': ext_name, 'type': 'version_mismatch',
|
drifts.append({'extension': ext_name, 'type': 'version_mismatch',
|
||||||
'platform': platform_ver, 'server': server_ver})
|
'platform': platform_ver, 'server': server_ver})
|
||||||
|
|||||||
Reference in New Issue
Block a user