35632-vm/workflow_actions.php
2025-11-20 03:49:15 +00:00

344 lines
13 KiB
PHP

<?php
// Mock data for demonstration, this would come from the database
$workflow_id = $_GET['id'] ?? 1;
$workflow_name = "Smart Candidate Intake"; // Fetched from DB based on $workflow_id
// Mock actions for this workflow
$actions = [
['type' => 'Create Task', 'params' => ['name' => 'Review new candidate', 'assign_to' => 'hiring_manager']],
['type' => 'Send Email', 'params' => ['subject' => 'Welcome!', 'to' => '{candidate_email}']],
['type' => 'AI Analysis', 'params' => ['prompt' => 'Summarize candidate resume']],
];
$available_actions = [
['name' => 'Send Email', 'icon' => '📧'],
['name' => 'Create Task', 'icon' => '✅'],
['name' => 'Send Slack Notification', 'icon' => '💬'],
['name' => 'Update Candidate Status', 'icon' => '👤'],
['name' => 'AI Analysis', 'icon' => '🤖'],
['name' => 'Add to Report', 'icon' => '📊'],
['name' => 'Schedule Event', 'icon' => '📅'],
];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Workflow Builder - <?= htmlspecialchars($workflow_name) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<style>
body {
background-color: #f8f9fa;
}
.workflow-builder-container {
display: flex;
gap: 20px;
margin-top: 20px;
}
.action-library {
width: 250px;
flex-shrink: 0;
}
.action-library .card-body {
padding: 1rem;
}
.action-item {
display: flex;
align-items: center;
padding: 10px;
border: 1px solid #dee2e6;
border-radius: 5px;
margin-bottom: 10px;
cursor: pointer;
background-color: #fff;
transition: all 0.2s ease;
}
.action-item:hover {
background-color: #f1f3f5;
border-color: #adb5bd;
}
.action-item-icon {
font-size: 20px;
margin-right: 15px;
}
.canvas {
flex-grow: 1;
}
.workflow-step {
background-color: #fff;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
position: relative;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.workflow-step .step-header {
display: flex;
align-items: center;
font-weight: bold;
}
.workflow-step .step-icon {
font-size: 20px;
margin-right: 10px;
color: #0d6efd;
}
.workflow-step .step-description {
color: #6c757d;
margin-top: 5px;
font-size: 0.9rem;
}
.step-connector {
position: absolute;
left: 35px;
top: 100%;
width: 2px;
height: 15px;
background-color: #dee2e6;
}
.start-node {
border-color: #198754;
}
.start-node .step-icon {
color: #198754;
}
.add-action-btn-container {
text-align: center;
position: relative;
}
.add-action-btn-container .line {
position: absolute;
left: 50%;
top: -15px;
width: 2px;
height: 15px;
background-color: #dee2e6;
transform: translateX(-50%);
}
.config-panel {
display: none;
position: fixed;
top: 0;
right: 0;
width: 400px;
height: 100%;
background-color: #fff;
box-shadow: -5px 0 15px rgba(0,0,0,0.1);
z-index: 1050;
padding: 20px;
overflow-y: auto;
}
.config-panel-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #dee2e6;
padding-bottom: 10px;
margin-bottom: 20px;
}
.config-panel-header h4 {
margin: 0;
}
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
z-index: 1040;
}
</style>
</head>
<body>
<div class="container-fluid p-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">Actions for: <span class="fw-bold text-primary"><?= htmlspecialchars($workflow_name) ?></span></h1>
<div>
<button class="btn btn-success"><i class="fas fa-play me-2"></i>Test Workflow</button>
<a href="workflows.php" class="btn btn-secondary"><i class="fas fa-arrow-left me-2"></i>Back to Workflows</a>
</div>
</div>
<div class="workflow-builder-container">
<!-- Action Library -->
<div class="action-library">
<div class="card">
<div class="card-header fw-bold">
Action Library
</div>
<div class="card-body">
<?php foreach ($available_actions as $action): ?>
<div class="action-item" onclick="openConfigPanel('<?= htmlspecialchars($action['name']) ?>')">
<span class="action-item-icon"><?= $action['icon'] ?></span>
<span><?= htmlspecialchars($action['name']) ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- Canvas -->
<div class="canvas">
<!-- Start Node -->
<div class="workflow-step start-node">
<div class="step-header">
<span class="step-icon"><i class="fas fa-flag-checkered"></i></span>
<span>Start Trigger</span>
</div>
<div class="step-description">When a candidate is created</div>
<div class="step-connector"></div>
</div>
<!-- Action Nodes -->
<?php foreach ($actions as $index => $action): ?>
<div class="workflow-step" onclick="openConfigPanel('<?= htmlspecialchars($action['type']) ?>', <?= htmlspecialchars(json_encode($action['params'])) ?>)">
<div class="step-header">
<span class="step-icon">
<?php
$icon = 'fas fa-question-circle';
foreach ($available_actions as $avail_action) {
if ($avail_action['name'] === $action['type']) {
$icon = $avail_action['icon'];
break;
}
}
echo $icon;
?>
</span>
<span><?= htmlspecialchars($action['type']) ?></span>
</div>
<div class="step-description">
<?php
$desc = 'Configure this action';
if ($action['type'] === 'Create Task') {
$desc = 'Create task: "' . htmlspecialchars($action['params']['name'] ?? '') . '" for ' . htmlspecialchars($action['params']['assign_to'] ?? '');
} elseif ($action['type'] === 'Send Email') {
$desc = 'Send email with subject: "' . htmlspecialchars($action['params']['subject'] ?? '') . '"';
} elseif ($action['type'] === 'AI Analysis') {
$desc = 'Run AI analysis';
}
echo $desc;
?>
</div>
<?php if ($index < count($actions)): ?>
<div class="step-connector"></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<div class="add-action-btn-container">
<div class="line"></div>
<button class="btn btn-primary rounded-pill" onclick="showActionLibraryFocus()"><i class="fas fa-plus"></i> Add Action</button>
</div>
</div>
</div>
</div>
<!-- Configuration Panel -->
<div class="overlay" onclick="closeConfigPanel()"></div>
<div class="config-panel" id="config-panel">
<!-- Content will be injected by JavaScript -->
</div>
<script>
const configPanel = document.getElementById('config-panel');
const overlay = document.querySelector('.overlay');
const availableActions = <?= json_encode($available_actions) ?>;
function showActionLibraryFocus() {
document.querySelector('.action-library .card').scrollIntoView({ behavior: 'smooth', block: 'center' });
document.querySelector('.action-library .card').classList.add('shadow-lg');
setTimeout(() => {
document.querySelector('.action-library .card').classList.remove('shadow-lg');
}, 1500);
}
function openConfigPanel(actionType, params = {}) {
let formHtml = '';
const action = availableActions.find(a => a.name === actionType);
formHtml += `
<div class="config-panel-header">
<h4>${action.icon} ${action.name}</h4>
<button type="button" class="btn-close" onclick="closeConfigPanel()"></button>
</div>
`;
if (actionType === 'Create Task') {
formHtml += `
<form>
<div class="mb-3">
<label class="form-label">Task Name</label>
<input type="text" class="form-control" value="${params.name || ''}">
</div>
<div class="mb-3">
<label class="form-label">Assign To</label>
<select class="form-select">
<option ${params.assign_to === 'hiring_manager' ? 'selected' : ''}>Hiring Manager</option>
<option ${params.assign_to === 'recruiter' ? 'selected' : ''}>Recruiter</option>
<option>Specific User...</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Due Date</label>
<input type="date" class="form-control" value="${params.due_date || ''}">
</div>
<div class="mb-3">
<label class="form-label">Priority</label>
<select class="form-select">
<option>High</option>
<option selected>Medium</option>
<option>Low</option>
</select>
</div>
</form>
`;
} else if (actionType === 'Send Email') {
formHtml += `
<form>
<div class="mb-3">
<label class="form-label">To</label>
<input type="text" class="form-control" value="${params.to || '{candidate_email}'}">
</div>
<div class="mb-3">
<label class="form-label">Subject</label>
<input type="text" class="form-control" value="${params.subject || ''}">
</div>
<div class="mb-3">
<label class="form-label">Body</label>
<textarea class="form-control" rows="8"></textarea>
<small class="form-text text-muted">Use variables like {candidate_name}, {role}, etc.</small>
</div>
</form>
`;
} else {
formHtml += '<p>Configuration for this action is not yet implemented.</p>';
}
formHtml += `
<div class="mt-4">
<button class="btn btn-primary">Save Action</button> fostering a more intuitive and user-friendly experience.
<button type="button" class="btn btn-danger ms-2">Delete</button>
</div>
`;
configPanel.innerHTML = formHtml;
configPanel.style.display = 'block';
overlay.style.display = 'block';
}
function closeConfigPanel() {
configPanel.style.display = 'none';
overlay.style.display = 'none';
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>