Fix TypeScript compilation errors in frontend components
- Remove unused variables in ApplicationInfo, ArchitectureDebugPage - Fix type errors in Dashboard, GovernanceAnalysis, GovernanceModelHelper (PageHeader description prop) - Add null checks and explicit types in DataValidationDashboard - Fix ObjectDetailModal type errors for _jiraCreatedAt and Date constructor - Remove unused imports and variables in SchemaConfigurationSettings - Update PageHeader to accept string | ReactNode for description prop
This commit is contained in:
165
docs/AZURE-PIPELINE-MSI-ERROR-FIX.md
Normal file
165
docs/AZURE-PIPELINE-MSI-ERROR-FIX.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Fix: MSI Authentication Error in Azure Pipeline
|
||||
|
||||
## 🔴 Error Message
|
||||
|
||||
```
|
||||
Could not fetch access token for Managed Service Principal.
|
||||
Please configure Managed Service Identity (MSI) for virtual machine
|
||||
```
|
||||
|
||||
## 🎯 Quick Fix
|
||||
|
||||
De service connection gebruikt Managed Service Identity (MSI), wat niet werkt met Azure DevOps Services (cloud).
|
||||
|
||||
**Oplossing: Herconfigureer de service connection met Service Principal authenticatie.**
|
||||
|
||||
---
|
||||
|
||||
## ✅ Stap-voor-Stap Oplossing
|
||||
|
||||
### Stap 1: Verwijder Bestaande Service Connection
|
||||
|
||||
1. Ga naar **Azure DevOps**
|
||||
2. **Project Settings** (onderaan links) → **Service connections**
|
||||
3. Zoek: `zuyderland-cmdb-acr-connection`
|
||||
4. Klik op **...** (three dots menu) → **Delete**
|
||||
5. Bevestig verwijdering
|
||||
|
||||
### Stap 2: Maak Nieuwe Service Connection
|
||||
|
||||
1. **Project Settings** → **Service connections** → **New service connection**
|
||||
2. Kies **"Docker Registry"**
|
||||
3. Kies **"Azure Container Registry"**
|
||||
4. **⚠️ BELANGRIJK**: Zorg dat **"Service Principal"** is geselecteerd als Authentication type
|
||||
- **NIET** "Managed Identity" of "Workload Identity federation"
|
||||
- **WEL** "Service Principal" (standaard optie)
|
||||
5. Vul in:
|
||||
- **Azure subscription**: Selecteer je subscription
|
||||
- **Azure container registry**: Selecteer `zdlasacr` uit de dropdown
|
||||
- **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
- **Description**: Optioneel
|
||||
6. Klik **"Save"** (of **"Verify and save"**)
|
||||
|
||||
### Stap 3: Test Pipeline
|
||||
|
||||
1. Ga naar **Pipelines** → Je pipeline
|
||||
2. Klik **"Run pipeline"**
|
||||
3. De pipeline zou nu moeten werken!
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Alternatief: Gebruik "Others" Optie
|
||||
|
||||
Als de Azure Container Registry optie nog steeds problemen geeft:
|
||||
|
||||
### Stap 1: Verwijder Bestaande Service Connection
|
||||
|
||||
(Zelfde als hierboven)
|
||||
|
||||
### Stap 2: Maak Service Connection met "Others"
|
||||
|
||||
1. **Project Settings** → **Service connections** → **New service connection**
|
||||
2. Kies **"Docker Registry"**
|
||||
3. Kies **"Others"** (in plaats van "Azure Container Registry")
|
||||
4. Vul handmatig in:
|
||||
- **Docker Registry**: `zdlasacr.azurecr.io`
|
||||
- **Docker ID**: (ACR admin username)
|
||||
- **Docker Password**: (ACR admin password)
|
||||
- **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
|
||||
### Stap 3: Haal ACR Admin Credentials Op
|
||||
|
||||
```bash
|
||||
# Login bij Azure
|
||||
az login
|
||||
|
||||
# Haal admin credentials op
|
||||
az acr credential show --name zdlasacr
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```json
|
||||
{
|
||||
"username": "zdlasacr",
|
||||
"passwords": [
|
||||
{
|
||||
"name": "password",
|
||||
"value": "xxxxxxxxxxxxx" ← Gebruik deze
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Gebruik:**
|
||||
- **Docker ID**: `zdlasacr` (of de username uit output)
|
||||
- **Docker Password**: `passwords[0].value` uit output
|
||||
|
||||
### Stap 4: Save en Test
|
||||
|
||||
1. Klik **"Save"**
|
||||
2. Test de pipeline opnieuw
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Waarom Gebeurt Dit?
|
||||
|
||||
**Managed Service Identity (MSI)** werkt alleen met:
|
||||
- ✅ Azure DevOps Server (on-premises) met Managed Identity
|
||||
- ❌ **NIET** met Azure DevOps Services (cloud) - Dit is jouw situatie!
|
||||
|
||||
**Service Principal** werkt met:
|
||||
- ✅ Azure DevOps Services (cloud) - **Dit is wat je nodig hebt!**
|
||||
- ✅ Azure DevOps Server (on-premises)
|
||||
- ✅ Alle Azure services
|
||||
|
||||
---
|
||||
|
||||
## ✅ Verificatie
|
||||
|
||||
Na het herconfigureren, controleer:
|
||||
|
||||
1. **Service Connection Details:**
|
||||
- Ga naar **Service connections** → `zuyderland-cmdb-acr-connection`
|
||||
- Check dat **Authentication type** = **"Service Principal"** (niet MSI)
|
||||
|
||||
2. **Test Pipeline:**
|
||||
- Run de pipeline opnieuw
|
||||
- De Docker build stap zou nu moeten werken
|
||||
|
||||
---
|
||||
|
||||
## 📚 Gerelateerde Documentatie
|
||||
|
||||
- **`AZURE-SERVICE-CONNECTION-TROUBLESHOOTING.md`** - Algemene troubleshooting
|
||||
- **`AZURE-SERVICE-CONNECTION-AUTH.md`** - Authentication types uitleg
|
||||
- **`AZURE-DEVOPS-SETUP.md`** - Service connection setup guide
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Nog Steeds Problemen?
|
||||
|
||||
Als het nog steeds niet werkt:
|
||||
|
||||
1. **Check ACR bestaat:**
|
||||
```bash
|
||||
az acr show --name zdlasacr
|
||||
```
|
||||
|
||||
2. **Check ACR admin is enabled:**
|
||||
```bash
|
||||
az acr show --name zdlasacr --query adminEnabled
|
||||
```
|
||||
Moet `true` zijn. Als `false`, enable het:
|
||||
```bash
|
||||
az acr update --name zdlasacr --admin-enabled true
|
||||
```
|
||||
|
||||
3. **Check subscription toegang:**
|
||||
- Ga naar Azure Portal → Subscription → Access control (IAM)
|
||||
- Check of je account toegang heeft
|
||||
|
||||
4. **Gebruik "Others" optie** als laatste redmiddel (werkt altijd)
|
||||
|
||||
---
|
||||
|
||||
**💡 Tip**: Service Principal is de aanbevolen methode voor Azure DevOps Services. Het is veilig, betrouwbaar en wordt automatisch beheerd door Azure DevOps.
|
||||
234
docs/AZURE-SERVICE-CONNECTION-PERMISSIONS.md
Normal file
234
docs/AZURE-SERVICE-CONNECTION-PERMISSIONS.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# Azure DevOps Service Connection - Permissions Error Fix
|
||||
|
||||
## 🔴 Error Message
|
||||
|
||||
```
|
||||
Failed to create an app in Microsoft Entra.
|
||||
Error: Insufficient privileges to complete the operation in Microsoft Graph
|
||||
Ensure that the user has permissions to create a Microsoft Entra Application.
|
||||
```
|
||||
|
||||
## 🎯 Probleem
|
||||
|
||||
Je account heeft onvoldoende rechten in Microsoft Entra (Azure AD) om automatisch een Service Principal aan te maken. Azure DevOps probeert dit automatisch te doen wanneer je een service connection aanmaakt.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Oplossing 1: Vraag Permissions Aan (Aanbevolen)
|
||||
|
||||
### Stap 1: Check Huidige Permissions
|
||||
|
||||
1. Ga naar **Azure Portal** → **Microsoft Entra ID** (of **Azure Active Directory**)
|
||||
2. Ga naar **Roles and administrators**
|
||||
3. Zoek je account en check welke rol je hebt
|
||||
|
||||
**Benodigde rollen:**
|
||||
- **Application Administrator** (aanbevolen)
|
||||
- **Cloud Application Administrator**
|
||||
- **Global Administrator** (heeft alle rechten)
|
||||
|
||||
### Stap 2: Vraag Permissions Aan
|
||||
|
||||
**Optie A: Vraag aan Azure Administrator**
|
||||
- Contacteer je Azure/IT administrator
|
||||
- Vraag om **Application Administrator** of **Cloud Application Administrator** rol
|
||||
- Of vraag om een Service Principal aan te maken voor jou
|
||||
|
||||
**Optie B: Vraag om Service Principal Aan te Maken**
|
||||
- Vraag je administrator om een Service Principal aan te maken
|
||||
- Gebruik deze in de "Others" optie (zie Oplossing 2)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Oplossing 2: Gebruik "Others" Optie met Bestaande Credentials
|
||||
|
||||
Als je geen permissions kunt krijgen, gebruik dan de "Others" optie met ACR admin credentials:
|
||||
|
||||
### Stap 1: Haal ACR Admin Credentials Op
|
||||
|
||||
```bash
|
||||
# Login bij Azure
|
||||
az login
|
||||
|
||||
# Check of admin is enabled
|
||||
az acr show --name zdlasacr --query adminEnabled
|
||||
|
||||
# Als false, enable admin (vereist Contributor of Owner rol op ACR)
|
||||
az acr update --name zdlasacr --admin-enabled true
|
||||
|
||||
# Haal admin credentials op
|
||||
az acr credential show --name zdlasacr
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```json
|
||||
{
|
||||
"username": "zdlasacr",
|
||||
"passwords": [
|
||||
{
|
||||
"name": "password",
|
||||
"value": "xxxxxxxxxxxxx" ← Gebruik deze
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Stap 2: Maak Service Connection met "Others"
|
||||
|
||||
1. **Azure DevOps** → **Project Settings** → **Service connections** → **New service connection**
|
||||
2. Kies **"Docker Registry"**
|
||||
3. Kies **"Others"** (niet "Azure Container Registry")
|
||||
4. Vul in:
|
||||
- **Docker Registry**: `zdlasacr.azurecr.io`
|
||||
- **Docker ID**: `zdlasacr` (of username uit output)
|
||||
- **Docker Password**: `passwords[0].value` uit output
|
||||
- **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
5. Klik **"Save"**
|
||||
|
||||
**✅ Dit werkt zonder extra Azure AD permissions!**
|
||||
|
||||
---
|
||||
|
||||
## ✅ Oplossing 3: Vraag Administrator om Service Principal
|
||||
|
||||
Als je administrator een Service Principal voor je kan aanmaken:
|
||||
|
||||
### Stap 1: Administrator Maakt Service Principal
|
||||
|
||||
```bash
|
||||
# Administrator voert uit:
|
||||
az login
|
||||
|
||||
# Maak Service Principal met ACR push permissions
|
||||
az ad sp create-for-rbac \
|
||||
--name "zuyderland-cmdb-acr-sp" \
|
||||
--role acrpush \
|
||||
--scopes /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ContainerRegistry/registries/zdlasacr
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```json
|
||||
{
|
||||
"appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"password": "xxxxxxxxxxxxx", ← Gebruik deze
|
||||
"tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
}
|
||||
```
|
||||
|
||||
### Stap 2: Gebruik in Azure DevOps
|
||||
|
||||
1. **Azure DevOps** → **Project Settings** → **Service connections** → **New service connection**
|
||||
2. Kies **"Docker Registry"** → **"Others"**
|
||||
3. Vul in:
|
||||
- **Docker Registry**: `zdlasacr.azurecr.io`
|
||||
- **Docker ID**: `appId` uit output (de GUID)
|
||||
- **Docker Password**: `password` uit output
|
||||
- **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
4. Klik **"Save"**
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Check Welke Permissions Je Hebt
|
||||
|
||||
### Via Azure Portal
|
||||
|
||||
1. Ga naar **Azure Portal** → **Microsoft Entra ID**
|
||||
2. **Roles and administrators**
|
||||
3. Zoek je account
|
||||
4. Check welke rollen je hebt
|
||||
|
||||
### Via Azure CLI
|
||||
|
||||
```bash
|
||||
# Login
|
||||
az login
|
||||
|
||||
# Check je rollen
|
||||
az role assignment list --assignee $(az account show --query user.name -o tsv) --all
|
||||
|
||||
# Check specifiek voor Microsoft Entra ID
|
||||
az ad signed-in-user show --query "displayName"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Benodigde Permissions Overzicht
|
||||
|
||||
| Rol | Kan Service Principal Aanmaken? | Kan ACR Toegang Geven? |
|
||||
|-----|--------------------------------|------------------------|
|
||||
| **Global Administrator** | ✅ Ja | ✅ Ja |
|
||||
| **Application Administrator** | ✅ Ja | ✅ Ja |
|
||||
| **Cloud Application Administrator** | ✅ Ja | ✅ Ja |
|
||||
| **User** | ❌ Nee | ❌ Nee |
|
||||
| **Contributor** (op Resource Group) | ❌ Nee | ✅ Ja (op resources) |
|
||||
|
||||
**Voor Azure DevOps Service Connection:**
|
||||
- Je hebt **Application Administrator** of hoger nodig om automatisch Service Principal aan te maken
|
||||
- Of gebruik **"Others"** optie met bestaande credentials (geen extra permissions nodig)
|
||||
|
||||
---
|
||||
|
||||
## 💡 Aanbeveling
|
||||
|
||||
**Voor jouw situatie:**
|
||||
|
||||
1. **Probeer eerst**: Vraag **Application Administrator** rol aan je Azure administrator
|
||||
- Dit is de schoonste oplossing
|
||||
- Werkt automatisch met Azure Container Registry optie
|
||||
|
||||
2. **Als dat niet kan**: Gebruik **"Others"** optie met ACR admin credentials
|
||||
- Werkt altijd
|
||||
- Geen extra permissions nodig
|
||||
- Iets minder geautomatiseerd, maar volledig functioneel
|
||||
|
||||
3. **Alternatief**: Vraag administrator om Service Principal aan te maken
|
||||
- Gebruik deze in "Others" optie
|
||||
- Veiliger dan admin credentials
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### "Admin is not enabled" Error
|
||||
|
||||
Als ACR admin niet is enabled:
|
||||
|
||||
```bash
|
||||
# Enable admin (vereist Contributor of Owner op ACR)
|
||||
az acr update --name zdlasacr --admin-enabled true
|
||||
```
|
||||
|
||||
**Als je geen permissions hebt:**
|
||||
- Vraag je administrator om admin te enableen
|
||||
- Of gebruik Service Principal (zie Oplossing 3)
|
||||
|
||||
### "Cannot connect to ACR" Error
|
||||
|
||||
Check:
|
||||
1. ACR naam is correct: `zdlasacr`
|
||||
2. Credentials zijn correct
|
||||
3. ACR is toegankelijk vanuit je netwerk
|
||||
4. Firewall rules staan toe
|
||||
|
||||
---
|
||||
|
||||
## 📚 Gerelateerde Documentatie
|
||||
|
||||
- **`AZURE-PIPELINE-MSI-ERROR-FIX.md`** - MSI error fix
|
||||
- **`AZURE-SERVICE-CONNECTION-TROUBLESHOOTING.md`** - Algemene troubleshooting
|
||||
- **`AZURE-ACR-PERMISSIONS.md`** - ACR permissions uitleg
|
||||
|
||||
---
|
||||
|
||||
## ✅ Quick Fix Checklist
|
||||
|
||||
- [ ] Check huidige Azure AD rol
|
||||
- [ ] Vraag Application Administrator rol aan (optie 1)
|
||||
- [ ] OF gebruik "Others" optie met ACR admin credentials (optie 2)
|
||||
- [ ] OF vraag administrator om Service Principal aan te maken (optie 3)
|
||||
- [ ] Test service connection
|
||||
- [ ] Test pipeline
|
||||
|
||||
---
|
||||
|
||||
**💡 Tip**: De "Others" optie is een volledig werkende oplossing en vereist geen extra Azure AD permissions. Het is iets minder geautomatiseerd, maar werkt perfect voor CI/CD pipelines.
|
||||
@@ -1,5 +1,60 @@
|
||||
# Azure DevOps Service Connection - Troubleshooting
|
||||
|
||||
## 🔴 Probleem: "Could not fetch access token for Managed Service Principal" (MSI Error)
|
||||
|
||||
**Error Message:**
|
||||
```
|
||||
Could not fetch access token for Managed Service Principal.
|
||||
Please configure Managed Service Identity (MSI) for virtual machine
|
||||
```
|
||||
|
||||
**Oorzaak:**
|
||||
De service connection is geconfigureerd om Managed Service Identity (MSI) te gebruiken, maar dit werkt **niet** met Azure DevOps Services (cloud). MSI werkt alleen met Azure DevOps Server (on-premises) met Managed Identity geconfigureerd.
|
||||
|
||||
**✅ Oplossing: Herconfigureer Service Connection met Service Principal**
|
||||
|
||||
### Stap 1: Verwijder Bestaande Service Connection
|
||||
|
||||
1. Ga naar **Azure DevOps** → **Project Settings** → **Service connections**
|
||||
2. Zoek de service connection: `zuyderland-cmdb-acr-connection`
|
||||
3. Klik op **...** (three dots) → **Delete**
|
||||
4. Bevestig verwijdering
|
||||
|
||||
### Stap 2: Maak Nieuwe Service Connection met Service Principal
|
||||
|
||||
1. **Project Settings** → **Service connections** → **New service connection**
|
||||
2. Kies **"Docker Registry"**
|
||||
3. Kies **"Azure Container Registry"**
|
||||
4. **Belangrijk**: Selecteer **"Service Principal"** als Authentication type (NIET Managed Identity!)
|
||||
5. Vul in:
|
||||
- **Azure subscription**: Selecteer je subscription
|
||||
- **Azure container registry**: Selecteer je ACR (`zdlasacr`)
|
||||
- **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
6. Klik **"Save"** (of **"Verify and save"**)
|
||||
|
||||
**✅ Dit zou nu moeten werken!**
|
||||
|
||||
### Alternatief: Gebruik "Others" Optie met Admin Credentials
|
||||
|
||||
Als de Azure Container Registry optie nog steeds problemen geeft:
|
||||
|
||||
1. **Kies "Docker Registry" → "Others"**
|
||||
2. **Vul handmatig in:**
|
||||
- **Docker Registry**: `zdlasacr.azurecr.io`
|
||||
- **Docker ID**: (ACR admin username)
|
||||
- **Docker Password**: (ACR admin password)
|
||||
|
||||
3. **Haal ACR admin credentials op:**
|
||||
```bash
|
||||
az acr credential show --name zdlasacr
|
||||
```
|
||||
Gebruik `username` en `passwords[0].value` uit de output.
|
||||
|
||||
4. **Service connection name**: `zuyderland-cmdb-acr-connection`
|
||||
5. **Save**
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Probleem: "Loading Registries..." blijft hangen
|
||||
|
||||
Als de Azure Container Registry dropdown blijft laden zonder resultaten, probeer deze oplossingen:
|
||||
|
||||
@@ -254,7 +254,7 @@ export default function ApplicationInfo() {
|
||||
setRefreshMessage(null);
|
||||
|
||||
try {
|
||||
const result = await refreshApplication(id);
|
||||
await refreshApplication(id);
|
||||
setRefreshMessage('Applicatie succesvol gesynchroniseerd vanuit Jira');
|
||||
|
||||
// Reload the application data after a short delay to show the success message
|
||||
|
||||
@@ -168,7 +168,7 @@ export default function ArchitectureDebugPage() {
|
||||
const referencedObjectKey = inputs.referencedObjectKey || (() => {
|
||||
// Try to find a reference in the object
|
||||
const references: string[] = [];
|
||||
for (const [key, value] of Object.entries(sampleObject)) {
|
||||
for (const [, value] of Object.entries(sampleObject)) {
|
||||
if (value && typeof value === 'object' && ('objectKey' in value || 'key' in value)) {
|
||||
const objKey = (value as any).objectKey || (value as any).key;
|
||||
if (objKey) references.push(objKey);
|
||||
@@ -288,7 +288,7 @@ export default function ArchitectureDebugPage() {
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!syncResponse.ok) throw new Error('Sync failed');
|
||||
const syncResult = await syncResponse.json();
|
||||
await syncResponse.json();
|
||||
|
||||
// Step 3: Check final count (should not have increased much)
|
||||
updateTestResult(testId, { message: 'Checking final object count...' });
|
||||
@@ -506,7 +506,7 @@ export default function ArchitectureDebugPage() {
|
||||
const error = await updateResponse.json();
|
||||
throw new Error(error.error || 'Update failed');
|
||||
}
|
||||
const updateResult = await updateResponse.json();
|
||||
await updateResponse.json();
|
||||
|
||||
// Step 3: Immediately check DB (without refresh)
|
||||
updateTestResult(testId, { message: 'Checking DB state immediately...' });
|
||||
|
||||
@@ -151,7 +151,7 @@ export default function DataValidationDashboard() {
|
||||
const grouped = new Map<string, typeof stats.comparison.typeComparisons>();
|
||||
const noSchemaGroup: typeof stats.comparison.typeComparisons = [];
|
||||
|
||||
for (const comp of stats.comparison.typeComparisons) {
|
||||
for (const comp of stats!.comparison.typeComparisons) {
|
||||
const schemaKey = comp.schemaId && comp.schemaName
|
||||
? `${comp.schemaId}|${comp.schemaName}`
|
||||
: '__NO_SCHEMA__';
|
||||
@@ -391,9 +391,9 @@ export default function DataValidationDashboard() {
|
||||
{Array.from(groupedBySchema.entries()).map(([schemaKey, typeComps]) => {
|
||||
const [schemaId, schemaName] = schemaKey.split('|');
|
||||
const isExpanded = expandedSchemas.has(schemaKey);
|
||||
const syncedCount = typeComps.filter(t => t.syncStatus === 'synced').length;
|
||||
const outdatedCount = typeComps.filter(t => t.syncStatus === 'outdated').length;
|
||||
const missingCount = typeComps.filter(t => t.syncStatus === 'missing').length;
|
||||
const syncedCount = typeComps.filter((t: { syncStatus: string }) => t.syncStatus === 'synced').length;
|
||||
const outdatedCount = typeComps.filter((t: { syncStatus: string }) => t.syncStatus === 'outdated').length;
|
||||
const missingCount = typeComps.filter((t: { syncStatus: string }) => t.syncStatus === 'missing').length;
|
||||
|
||||
return (
|
||||
<div key={schemaKey} className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden hover:shadow-md transition-shadow">
|
||||
@@ -472,7 +472,7 @@ export default function DataValidationDashboard() {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-gray-100">
|
||||
{typeComps.map((comp) => (
|
||||
{typeComps.map((comp: { typeName: string; cacheCount: number; jiraCount: number; difference: number; syncStatus: string; typeDisplayName: string }) => (
|
||||
<tr
|
||||
key={comp.typeName}
|
||||
className="hover:bg-blue-50/50 cursor-pointer transition-colors group"
|
||||
|
||||
@@ -79,7 +79,7 @@ export default function ObjectDetailModal({ objectId, onClose, onObjectClick, on
|
||||
}
|
||||
};
|
||||
|
||||
const renderAttributeValue = (key: string, value: any) => {
|
||||
const renderAttributeValue = (key: string, value: any): React.ReactNode | null => {
|
||||
// Skip internal/system fields
|
||||
if (key.startsWith('_')) return null;
|
||||
|
||||
@@ -296,24 +296,36 @@ export default function ObjectDetailModal({ objectId, onClose, onObjectClick, on
|
||||
Metadata
|
||||
</h3>
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-6 shadow-sm">
|
||||
{objectData.object._jiraUpdatedAt && (
|
||||
{(() => {
|
||||
const obj = objectData.object as Record<string, unknown>;
|
||||
const updatedAt = obj._jiraUpdatedAt;
|
||||
const createdAt = obj._jiraCreatedAt;
|
||||
const hasUpdatedAt = updatedAt && (typeof updatedAt === 'string' || typeof updatedAt === 'number' || updatedAt instanceof Date);
|
||||
const hasCreatedAt = createdAt && (typeof createdAt === 'string' || typeof createdAt === 'number' || createdAt instanceof Date);
|
||||
|
||||
if (!hasUpdatedAt && !hasCreatedAt) return null;
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-6">
|
||||
{hasUpdatedAt && (
|
||||
<div>
|
||||
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Laatst bijgewerkt (Jira)</div>
|
||||
<div className="text-sm font-medium text-gray-900 bg-gray-50 px-3 py-2 rounded-lg border border-gray-200">
|
||||
{new Date(objectData.object._jiraUpdatedAt).toLocaleString('nl-NL')}
|
||||
{new Date(updatedAt as string | number | Date).toLocaleString('nl-NL')}
|
||||
</div>
|
||||
</div>
|
||||
{objectData.object._jiraCreatedAt && (
|
||||
)}
|
||||
{hasCreatedAt && (
|
||||
<div>
|
||||
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Aangemaakt (Jira)</div>
|
||||
<div className="text-sm font-medium text-gray-900 bg-gray-50 px-3 py-2 rounded-lg border border-gray-200">
|
||||
{new Date(objectData.object._jiraCreatedAt).toLocaleString('nl-NL')}
|
||||
{new Date(createdAt as string | number | Date).toLocaleString('nl-NL')}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
interface PageHeaderProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
description?: string | React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
actions?: React.ReactNode;
|
||||
badge?: React.ReactNode;
|
||||
|
||||
@@ -5,17 +5,14 @@ import {
|
||||
getConfiguredObjectTypes,
|
||||
setConfiguredObjectTypeEnabled,
|
||||
bulkSetObjectTypesEnabled,
|
||||
checkConfiguration,
|
||||
getSchema,
|
||||
triggerTypeSync,
|
||||
getSchemas,
|
||||
setSchemaSearchEnabled,
|
||||
type SchemaWithObjectTypes,
|
||||
type ConfiguredObjectType,
|
||||
type SchemaConfigurationStats,
|
||||
type SchemaResponse,
|
||||
type SchemaObjectTypeDefinition,
|
||||
type SchemaAttributeDefinition,
|
||||
type SchemaSearchConfig,
|
||||
} from '../services/api';
|
||||
import CacheStatusIndicator from './CacheStatusIndicator';
|
||||
@@ -252,8 +249,6 @@ export default function SchemaConfigurationSettings() {
|
||||
if (stats) {
|
||||
setStats(prevStats => {
|
||||
if (!prevStats) return prevStats;
|
||||
const enabledCount = updates.filter(u => u.enabled).length;
|
||||
const disabledCount = updates.filter(u => !u.enabled).length;
|
||||
const currentEnabled = prevStats.enabledObjectTypes;
|
||||
const currentDisabled = prevStats.disabledObjectTypes;
|
||||
|
||||
@@ -355,9 +350,6 @@ export default function SchemaConfigurationSettings() {
|
||||
),
|
||||
})).filter(schema => schema.objectTypes.length > 0 || searchTerm === '');
|
||||
|
||||
const allEnabledCount = schemas.reduce((sum, s) => sum + s.objectTypes.filter(ot => ot.enabled).length, 0);
|
||||
const allDisabledCount = schemas.reduce((sum, s) => sum + s.objectTypes.filter(ot => !ot.enabled).length, 0);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Header Section */}
|
||||
@@ -698,7 +690,6 @@ export default function SchemaConfigurationSettings() {
|
||||
const enabledCount = schema.objectTypes.filter(ot => ot.enabled).length;
|
||||
const isExpanded = expandedSchemas.has(schema.schemaId);
|
||||
const allEnabled = schema.objectTypes.length > 0 && schema.objectTypes.every(ot => ot.enabled);
|
||||
const someEnabled = schema.objectTypes.some(ot => ot.enabled);
|
||||
|
||||
return (
|
||||
<div key={schema.schemaId} className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden hover:shadow-md transition-shadow">
|
||||
|
||||
Reference in New Issue
Block a user