Skip to content
Merged
2 changes: 2 additions & 0 deletions src/components/BPMNPreview.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
.preview-container {
width: 100%;
height: 100%;
min-height: 160px;
background: var(--bpmn-preview-bg);
position: relative;
}

.bpmn-preview-svg {
Expand Down
154 changes: 145 additions & 9 deletions src/components/BPMNPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ const BPMNPreview = ({ file, repository, selectedBranch, profile }) => {

useEffect(() => {
const loadPreview = async () => {
if (!file || !repository || !containerRef.current) return;
if (!file || !repository || !containerRef.current) {
console.log('🚫 BPMNPreview: Missing required props:', {
hasFile: !!file,
hasRepository: !!repository,
hasContainer: !!containerRef.current,
fileName: file?.name
});
return;
}

try {
setLoading(true);
Expand All @@ -27,6 +35,16 @@ const BPMNPreview = ({ file, repository, selectedBranch, profile }) => {
const ref = selectedBranch || 'main';
const isDemo = file.path?.includes('demo/') || file.sha?.startsWith('demo-');

console.log('🎬 BPMNPreview: Starting preview load for file:', {
fileName: file.name,
filePath: file.path,
owner: owner,
repoName: repoName,
ref: ref,
isDemo: isDemo,
hasDownloadUrl: !!file.download_url
});

let bpmnXml;

if (isDemo) {
Expand Down Expand Up @@ -82,12 +100,41 @@ const BPMNPreview = ({ file, repository, selectedBranch, profile }) => {
</bpmn:definitions>`;
} else {
// For real files, try to load the actual BPMN content
console.log('📥 BPMNPreview: Attempting to load real BPMN file content...');
try {
console.log('🌐 BPMNPreview: Calling githubService.getFileContent with params:', {
owner, repoName, path: file.path, ref
});
bpmnXml = await githubService.getFileContent(owner, repoName, file.path, ref);
console.log('✅ BPMNPreview: Successfully loaded BPMN content, length:', bpmnXml?.length);
console.log('🔍 BPMNPreview: Content preview (first 100 chars):', bpmnXml?.substring(0, 100));

// Validate that we got actual BPMN content
if (!bpmnXml || typeof bpmnXml !== 'string') {
throw new Error('Invalid content received: not a string');
}

if (!bpmnXml.includes('bpmn:definitions') && !bpmnXml.includes('<definitions')) {
console.warn('⚠️ BPMNPreview: Content does not appear to be valid BPMN XML');
console.log('🔍 BPMNPreview: Full content received:', bpmnXml);
throw new Error('Content does not appear to be valid BPMN');
}

console.log('✅ BPMNPreview: BPMN content validation passed');
} catch (fileError) {
console.warn('Could not load BPMN file content:', fileError);
console.warn('❌ BPMNPreview: Could not load BPMN file content:', fileError.message, fileError.status);
console.error('🔍 BPMNPreview: File loading error details:', {
error: fileError,
stack: fileError.stack,
fileName: file.name,
filePath: file.path,
owner,
repoName,
ref
});
// Fallback to a generic BPMN diagram if file can't be loaded
const processName = file.name.replace('.bpmn', '').replace(/[-_]/g, ' ');
console.log('🔄 BPMNPreview: Using fallback BPMN diagram for:', processName);
bpmnXml = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
Expand Down Expand Up @@ -139,30 +186,112 @@ const BPMNPreview = ({ file, repository, selectedBranch, profile }) => {
}
}

console.log('🔧 BPMNPreview: Creating BPMN viewer...');
console.log('🔍 BPMNPreview: About to create viewer with BPMN content length:', bpmnXml?.length);

// Create and initialize viewer with clean separation
const viewer = new BpmnViewer();
viewerRef.current = viewer;

console.log('✅ BPMNPreview: BPMN viewer instance created successfully');

try {
// Attach viewer to container first
await viewer.attachTo(containerRef.current);
console.log('🔗 BPMNPreview: Attaching viewer to container...');
console.log('🔍 BPMNPreview: Container element details:', {
exists: !!containerRef.current,
className: containerRef.current?.className,
width: containerRef.current?.offsetWidth,
height: containerRef.current?.offsetHeight,
parentExists: !!containerRef.current?.parentElement
});

// Create timeout promise for viewer operations
const createTimeoutPromise = (operation, timeoutMs = 10000) => {
return new Promise((_, reject) => {
setTimeout(() => {
reject(new Error(`${operation} timeout after ${timeoutMs}ms`));
}, timeoutMs);
});
};

// Attach viewer to container first with timeout
const attachPromise = viewer.attachTo(containerRef.current);
await Promise.race([attachPromise, createTimeoutPromise('Viewer attach', 5000)]);
console.log('✅ BPMNPreview: Successfully attached viewer to container');

// Then import XML
await viewer.importXML(bpmnXml);
console.log('📊 BPMNPreview: Importing BPMN XML...');
console.log('🔍 BPMNPreview: XML content preview (first 200 chars):', bpmnXml?.substring(0, 200));

// Import XML with timeout handling
const importStartTime = Date.now();
const importPromise = viewer.importXML(bpmnXml);
const importResult = await Promise.race([importPromise, createTimeoutPromise('XML import', 15000)]);
const importTime = Date.now() - importStartTime;

console.log(`✅ BPMNPreview: Successfully imported BPMN XML in ${importTime}ms`);
console.log('📊 BPMNPreview: Import result details:', {
warnings: importResult?.warnings?.length || 0,
hasWarnings: !!(importResult?.warnings?.length),
warningDetails: importResult?.warnings
});

if (importResult?.warnings?.length > 0) {
console.warn('⚠️ BPMNPreview: Import warnings:', importResult.warnings);
}

console.log('🎯 BPMNPreview: Fitting to viewport...');
// Fit to viewport for preview
const canvas = viewer.get('canvas');
console.log('🔍 BPMNPreview: Canvas service retrieved:', !!canvas);

const zoomStartTime = Date.now();
canvas.zoom('fit-viewport');
const zoomTime = Date.now() - zoomStartTime;

console.log(`✅ BPMNPreview: Successfully fitted to viewport in ${zoomTime}ms`);

// Final validation - check if diagram was actually rendered
const viewbox = canvas.viewbox();
console.log('🔍 BPMNPreview: Final viewport details:', {
viewbox,
hasElements: viewbox.inner?.width > 0 && viewbox.inner?.height > 0,
containerHasContent: containerRef.current?.children?.length > 0
});

// Check if container actually has content
if (containerRef.current?.children?.length === 0) {
console.warn('⚠️ BPMNPreview: Container is empty after rendering - potential issue');
}

console.log(`🎉 BPMNPreview: Successfully rendered preview for: ${file.name}`);
setLoading(false);
} catch (importError) {
console.error('Failed to import BPMN XML:', importError);
setError('Failed to load preview');
console.error('❌ BPMNPreview: Failed to import BPMN XML:', importError);
console.error('🔍 BPMNPreview: Import error details:', {
message: importError.message,
stack: importError.stack,
fileName: file.name,
xmlLength: bpmnXml?.length,
xmlPreview: bpmnXml?.substring(0, 300),
containerState: {
exists: !!containerRef.current,
hasChildren: containerRef.current?.children?.length || 0,
clientHeight: containerRef.current?.clientHeight,
clientWidth: containerRef.current?.clientWidth
}
});
setError(`Failed to load preview: ${importError.message}`);
setLoading(false);
}

} catch (renderError) {
console.error('Failed to render BPMN preview:', renderError);
console.error('❌ BPMNPreview: Failed to render BPMN preview:', renderError.message || renderError);
console.log('🔍 BPMNPreview: Error details:', {
fileName: file.name,
filePath: file.path,
errorMessage: renderError.message,
errorStack: renderError.stack
});
setError('Failed to load preview');
setLoading(false);
}
Expand All @@ -182,8 +311,15 @@ const BPMNPreview = ({ file, repository, selectedBranch, profile }) => {

// Only run if we have all required props
if (file && repository && containerRef.current) {
console.log('🚀 BPMNPreview: Starting loadPreview for:', file.name);
loadPreview();
} else {
console.log('⏭️ BPMNPreview: Skipping loadPreview, missing props:', {
hasFile: !!file,
hasRepository: !!repository,
hasContainer: !!containerRef.current,
fileName: file?.name
});
setLoading(false);
}

Expand Down
10 changes: 8 additions & 2 deletions src/components/BPMNViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import { PageLayout, useDAKParams } from './framework';
import './BPMNViewer.css';

const BPMNViewerComponent = () => {
return (
<PageLayout pageName="bpmn-viewer">
<BPMNViewerContent />
</PageLayout>
);
};

const BPMNViewerContent = () => {
const location = useLocation();
const navigate = useNavigate();
const viewerRef = useRef(null);
Expand Down Expand Up @@ -475,7 +483,6 @@ const BPMNViewerComponent = () => {
}

return (
<PageLayout pageName="bpmn-viewer">
<div className={`bpmn-viewer ${enhancedFullwidth ? 'enhanced-fullwidth' : ''} ${autoHide ? 'auto-hide' : ''}`}>
<div className="viewer-content">

Expand Down Expand Up @@ -598,7 +605,6 @@ const BPMNViewerComponent = () => {
</div>
</div>
</div>
</PageLayout>
);
};

Expand Down
11 changes: 11 additions & 0 deletions src/components/BusinessProcessSelection.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ const BusinessProcessSelection = () => {

const bpmnFiles = await githubService.getBpmnFiles(owner, repoName, ref);

console.log('📊 BusinessProcessSelection: Received BPMN files:', {
count: bpmnFiles.length,
files: bpmnFiles.map(f => ({
name: f.name,
path: f.path,
size: f.size,
hasDownloadUrl: !!f.download_url,
sha: f.sha?.substring(0, 8)
}))
});

// If no files found and we're in demo mode, provide fallback files
if (bpmnFiles.length === 0 && profile?.isDemo) {
console.log('No BPMN files found in demo mode, providing fallback demo files');
Expand Down
4 changes: 2 additions & 2 deletions src/components/DAKDashboardWithFramework.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const DAKDashboardContent = () => {

try {
// Check repository permissions
const hasPermission = await githubService.checkRepositoryPermissions(repository.owner.login, repository.name);
const hasPermission = await githubService.checkRepositoryWritePermissions(repository.owner.login, repository.name);
setHasWriteAccess(hasPermission);
} catch (error) {
console.error('Error checking repository permissions:', error);
Expand All @@ -58,7 +58,7 @@ const DAKDashboardContent = () => {
}

try {
const issues = await githubService.getRepositoryIssues(repository.owner.login, repository.name);
const issues = await githubService.getIssues(repository.owner.login, repository.name);

// Count issues by label
const counts = {};
Expand Down
10 changes: 0 additions & 10 deletions src/components/framework/PageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const PageContext = createContext(null);
*/
export const usePage = () => {
const context = useContext(PageContext);
console.log('usePage: called, context is:', context ? 'available' : 'null');
if (!context) {
console.error('usePage: PageContext is null - component not wrapped in PageProvider');
throw new Error('usePage must be used within a PageProvider');
Expand All @@ -39,9 +38,6 @@ const determinePageType = (params) => {
const { user, repo } = params;
const asset = params['*']; // Wildcard parameter for asset path

console.log('PageProvider: determinePageType called with params:', params);
console.log('PageProvider: extracted values:', { user, repo, asset });

if (asset) return PAGE_TYPES.ASSET;
if (user && repo) return PAGE_TYPES.DAK;
if (user) return PAGE_TYPES.USER;
Expand All @@ -56,12 +52,6 @@ export const PageProvider = ({ children, pageName }) => {
const location = useLocation();
const navigate = useNavigate();

console.log('PageProvider: initialized with:', {
pageName,
params,
locationPathname: location.pathname
});

const [pageState, setPageState] = useState({
type: determinePageType(params),
pageName,
Expand Down
2 changes: 1 addition & 1 deletion src/services/actorDefinitionService.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ActorDefinitionService {
*/
async loadSchema() {
try {
const response = await fetch('/schemas/actor-definition.json');
const response = await fetch(`${process.env.PUBLIC_URL || ''}/schemas/actor-definition.json`);
this.actorSchema = await response.json();
} catch (error) {
console.warn('Could not load actor definition schema:', error);
Expand Down
Loading
Loading