Fancified the template selector
This commit is contained in:
@ -738,25 +738,65 @@ input:checked + .toggle-slider:before {
|
||||
}
|
||||
|
||||
.protocol-template-selector {
|
||||
padding: 2rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.protocol-template-selector label {
|
||||
display: block;
|
||||
margin-bottom: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-size: 1.1rem;
|
||||
.protocol-template-selector .stage-header {
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.protocol-template-select {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
.template-body {
|
||||
padding: 0 2rem 2rem;
|
||||
}
|
||||
|
||||
.template-options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.template-option {
|
||||
border: 1px solid var(--border-color);
|
||||
font-family: inherit;
|
||||
background-color: var(--light-color);
|
||||
margin-bottom: 1rem;
|
||||
padding: 1.5rem;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
transition: border-color 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.template-option:hover {
|
||||
border-color: #aaa;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.template-option.selected {
|
||||
border-color: var(--dark-color);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.template-select-btn {
|
||||
display: block;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--dark-color);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
/* Remove the underline effect */
|
||||
|
||||
.template-description {
|
||||
font-size: 0.95rem;
|
||||
color: var(--secondary-color);
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.protocol-metadata {
|
||||
@ -773,11 +813,11 @@ input:checked + .toggle-slider:before {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.metadata-field label {
|
||||
display: block;
|
||||
margin-bottom: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-size: 1.1rem;
|
||||
.metadata-field h2 {
|
||||
font-size: 1.4rem;
|
||||
margin: 0 0 0.75rem 0;
|
||||
color: var(--dark-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.metadata-field input[type="text"] {
|
||||
@ -786,6 +826,8 @@ input:checked + .toggle-slider:before {
|
||||
border: 1px solid var(--border-color);
|
||||
font-family: inherit;
|
||||
background-color: var(--light-color);
|
||||
font-size: 1.25rem; /* Larger font size for community name */
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.metadata-field textarea {
|
||||
|
@ -82,6 +82,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
/* Hide template selector */
|
||||
.protocol-template-selector { display: none !important; }
|
||||
.template-body { display: none !important; }
|
||||
|
||||
/* Expand all sections */
|
||||
.stage-body { display: block !important; }
|
||||
@ -235,13 +236,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Populate the template selector
|
||||
populateTemplateSelector(templates);
|
||||
|
||||
// Add template selection event handler
|
||||
if (protocolTemplateSelect) {
|
||||
protocolTemplateSelect.addEventListener('change', handleTemplateSelection);
|
||||
console.log('Template selector event handler attached');
|
||||
} else {
|
||||
console.error('Template select element not found');
|
||||
}
|
||||
// Template selection is now handled by buttons in the template options
|
||||
console.log('Template selection will be handled by buttons in the template options');
|
||||
} else {
|
||||
console.error('Templates not available after loading script');
|
||||
}
|
||||
@ -261,13 +257,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Populate the template selector
|
||||
populateTemplateSelector(templates);
|
||||
|
||||
// Add template selection event handler
|
||||
if (protocolTemplateSelect) {
|
||||
protocolTemplateSelect.addEventListener('change', handleTemplateSelection);
|
||||
console.log('Template selector event handler attached');
|
||||
} else {
|
||||
console.error('Template select element not found');
|
||||
}
|
||||
// Template selection is now handled by buttons in the template options
|
||||
console.log('Template selection will be handled by buttons in the template options');
|
||||
})
|
||||
.catch(importError => {
|
||||
console.error('ES module import also failed:', importError);
|
||||
@ -279,25 +270,47 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
}
|
||||
|
||||
// Function to populate the template selector dropdown
|
||||
// Function to populate the template selector with cards
|
||||
function populateTemplateSelector(templatesList) {
|
||||
if (!protocolTemplateSelect || !templatesList || templatesList.length === 0) {
|
||||
console.error('Cannot populate template selector - missing element or templates');
|
||||
if (!templatesList || templatesList.length === 0) {
|
||||
console.error('Cannot populate template selector - missing templates');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Populating template selector with', templatesList.length, 'templates');
|
||||
|
||||
// Clear all existing options
|
||||
while (protocolTemplateSelect.options.length > 0) {
|
||||
protocolTemplateSelect.remove(0);
|
||||
// Find the template options container
|
||||
const templateOptionsContainer = document.querySelector('.template-options');
|
||||
if (!templateOptionsContainer) {
|
||||
console.error('Template options container not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the default "Create Your Own" option
|
||||
const defaultOption = document.createElement('option');
|
||||
defaultOption.value = "";
|
||||
defaultOption.textContent = "-- Create Your Own Protocol --";
|
||||
protocolTemplateSelect.appendChild(defaultOption);
|
||||
// Clear existing template options
|
||||
templateOptionsContainer.innerHTML = '';
|
||||
|
||||
// Create the "Create Your Own" option first
|
||||
const createYourOwnOption = document.createElement('div');
|
||||
createYourOwnOption.className = 'template-option';
|
||||
createYourOwnOption.setAttribute('data-template-id', '');
|
||||
|
||||
const createYourOwnBtn = document.createElement('button');
|
||||
createYourOwnBtn.className = 'template-select-btn';
|
||||
createYourOwnBtn.textContent = 'Create Your Own Protocol';
|
||||
createYourOwnBtn.setAttribute('type', 'button');
|
||||
|
||||
const createYourOwnDesc = document.createElement('p');
|
||||
createYourOwnDesc.className = 'template-description';
|
||||
createYourOwnDesc.textContent = 'Start with a blank protocol and build it from scratch.';
|
||||
|
||||
createYourOwnOption.appendChild(createYourOwnBtn);
|
||||
createYourOwnOption.appendChild(createYourOwnDesc);
|
||||
createYourOwnOption.addEventListener('click', function() {
|
||||
console.log('Create your own option clicked');
|
||||
clearAllFields();
|
||||
});
|
||||
|
||||
templateOptionsContainer.appendChild(createYourOwnOption);
|
||||
|
||||
// Verify templates have required properties
|
||||
let validTemplateCount = 0;
|
||||
@ -310,67 +323,143 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
console.log(`Found ${validTemplateCount} valid templates out of ${templatesList.length} total`);
|
||||
|
||||
// Add template options
|
||||
// Add template options as cards
|
||||
templatesList.forEach(template => {
|
||||
const option = document.createElement('option');
|
||||
option.value = template.id;
|
||||
option.textContent = template.title;
|
||||
protocolTemplateSelect.appendChild(option);
|
||||
console.log('Added template option:', template.title, 'with ID:', template.id);
|
||||
if (!template.id || !template.title || !template.description) {
|
||||
return; // Skip invalid templates
|
||||
}
|
||||
|
||||
// Debugging template structure
|
||||
const templateOption = document.createElement('div');
|
||||
templateOption.className = 'template-option';
|
||||
templateOption.setAttribute('data-template-id', template.id);
|
||||
|
||||
// Make the entire card clickable
|
||||
templateOption.addEventListener('click', function() {
|
||||
// For debugging
|
||||
console.log('Template option clicked for:', template.id);
|
||||
|
||||
// Find and apply the template
|
||||
const selectedTemplate = templates.find(t => t.id === template.id);
|
||||
if (selectedTemplate) {
|
||||
applyTemplate(selectedTemplate);
|
||||
|
||||
// Close the template section after selection
|
||||
const templateSection = document.querySelector('.protocol-template-selector');
|
||||
if (templateSection) {
|
||||
const templateBody = templateSection.querySelector('.template-body');
|
||||
const toggleBtn = templateSection.querySelector('.toggle-btn');
|
||||
if (templateBody && toggleBtn) {
|
||||
templateBody.style.display = 'none';
|
||||
toggleBtn.textContent = '+';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('Template not found:', template.id);
|
||||
}
|
||||
});
|
||||
|
||||
const selectButton = document.createElement('button');
|
||||
selectButton.className = 'template-select-btn';
|
||||
selectButton.textContent = template.title;
|
||||
selectButton.setAttribute('type', 'button');
|
||||
|
||||
const description = document.createElement('p');
|
||||
description.className = 'template-description';
|
||||
description.textContent = template.description;
|
||||
|
||||
templateOption.appendChild(selectButton);
|
||||
templateOption.appendChild(description);
|
||||
templateOptionsContainer.appendChild(templateOption);
|
||||
|
||||
console.log('Added template option:', template.title, 'with ID:', template.id);
|
||||
console.log(' > Description:', template.description ? template.description.substring(0, 50) + '...' : 'MISSING');
|
||||
console.log(' > Has data:', template.data ? 'Yes' : 'No');
|
||||
console.log(' > Has stages:', template.data?.stages ? 'Yes - ' + Object.keys(template.data.stages).length + ' stages' : 'No');
|
||||
});
|
||||
|
||||
// We've already set up the click handler for "Create Your Own" when creating it
|
||||
}
|
||||
|
||||
// Handle template selection
|
||||
function handleTemplateSelection() {
|
||||
const selectedTemplateId = this.value;
|
||||
console.log('Template selection changed to:', selectedTemplateId);
|
||||
// Function to apply a template by ID
|
||||
function applyTemplateById(templateId) {
|
||||
console.log('Applying template by ID:', templateId);
|
||||
|
||||
if (selectedTemplateId) {
|
||||
if (templateId) {
|
||||
// Find the selected template from our loaded templates
|
||||
const selectedTemplate = templates.find(t => t.id === selectedTemplateId);
|
||||
const selectedTemplate = templates.find(t => t.id === templateId);
|
||||
|
||||
if (selectedTemplate) {
|
||||
console.log('Found template:', selectedTemplate.title);
|
||||
applyTemplate(selectedTemplate);
|
||||
} else {
|
||||
console.error('Template not found:', selectedTemplateId);
|
||||
}
|
||||
} else {
|
||||
// Clear all fields if "Create Your Own" is selected
|
||||
document.querySelectorAll('textarea').forEach(textarea => {
|
||||
textarea.value = '';
|
||||
});
|
||||
|
||||
// Reset protocol data
|
||||
protocol = {
|
||||
metadata: {
|
||||
communityName: "",
|
||||
summary: ""
|
||||
},
|
||||
stages: {}
|
||||
};
|
||||
|
||||
// Collapse all sections
|
||||
stageContents.forEach(content => {
|
||||
content.style.display = 'none';
|
||||
const toggleBtn = content.parentElement.querySelector('.toggle-btn');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.textContent = '+';
|
||||
|
||||
// Close the template section after selection
|
||||
const templateSection = document.querySelector('.protocol-template-selector');
|
||||
if (templateSection) {
|
||||
const templateBody = templateSection.querySelector('.template-body');
|
||||
const toggleBtn = templateSection.querySelector('.toggle-btn');
|
||||
if (templateBody && toggleBtn) {
|
||||
templateBody.style.display = 'none';
|
||||
toggleBtn.textContent = '+';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update preview mode if active
|
||||
if (previewModeActive) {
|
||||
markComponentsWithContent();
|
||||
} else {
|
||||
console.error('Template not found:', templateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to clear all fields
|
||||
function clearAllFields() {
|
||||
// Clear all textareas
|
||||
document.querySelectorAll('textarea').forEach(textarea => {
|
||||
textarea.value = '';
|
||||
});
|
||||
|
||||
// Clear community name input
|
||||
if (communityNameInput) {
|
||||
communityNameInput.value = '';
|
||||
}
|
||||
|
||||
// Clear protocol summary
|
||||
if (protocolSummaryTextarea) {
|
||||
protocolSummaryTextarea.value = '';
|
||||
}
|
||||
|
||||
// Reset protocol data
|
||||
protocol = {
|
||||
metadata: {
|
||||
communityName: "",
|
||||
summary: ""
|
||||
},
|
||||
stages: {}
|
||||
};
|
||||
|
||||
// Collapse all sections
|
||||
stageContents.forEach(content => {
|
||||
content.style.display = 'none';
|
||||
const toggleBtn = content.parentElement.querySelector('.toggle-btn');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.textContent = '+';
|
||||
}
|
||||
});
|
||||
|
||||
// Close the template section after clearing
|
||||
const templateSection = document.querySelector('.protocol-template-selector');
|
||||
if (templateSection) {
|
||||
const templateBody = templateSection.querySelector('.template-body');
|
||||
const toggleBtn = templateSection.querySelector('.toggle-btn');
|
||||
if (templateBody && toggleBtn) {
|
||||
templateBody.style.display = 'none';
|
||||
toggleBtn.textContent = '+';
|
||||
}
|
||||
}
|
||||
|
||||
// Update preview mode if active
|
||||
if (previewModeActive) {
|
||||
markComponentsWithContent();
|
||||
}
|
||||
|
||||
console.log('All fields cleared');
|
||||
}
|
||||
|
||||
// Function to apply a template to the form
|
||||
function applyTemplate(selectedTemplate) {
|
||||
if (!selectedTemplate) {
|
||||
@ -498,7 +587,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const moduleSelects = document.querySelectorAll('.module-select');
|
||||
console.log('Found module selects:', moduleSelects.length);
|
||||
|
||||
const protocolTemplateSelect = document.getElementById('protocol-template');
|
||||
const communityNameInput = document.getElementById('community-name');
|
||||
const protocolSummaryTextarea = document.getElementById('protocol-summary');
|
||||
|
||||
@ -509,27 +597,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const importJsonInput = document.getElementById('import-json');
|
||||
const importBtn = document.getElementById('import-btn');
|
||||
|
||||
// Function to initialize the template selector
|
||||
// This function is no longer needed with the new template UI
|
||||
// Keeping an empty function to avoid errors if it's called elsewhere
|
||||
function initializeTemplateSelector(templatesList) {
|
||||
if (!protocolTemplateSelect || !templatesList || templatesList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear existing options
|
||||
while (protocolTemplateSelect.options.length > 1) {
|
||||
protocolTemplateSelect.remove(1);
|
||||
}
|
||||
|
||||
// Add template options
|
||||
templatesList.forEach(template => {
|
||||
const option = document.createElement('option');
|
||||
option.value = template.id;
|
||||
option.textContent = template.title;
|
||||
protocolTemplateSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// Add template selection event handler
|
||||
protocolTemplateSelect.addEventListener('change', handleTemplateSelection);
|
||||
console.log('initializeTemplateSelector is deprecated, using new UI instead');
|
||||
}
|
||||
|
||||
// Hide module selectors since we're using templates directly
|
||||
@ -931,15 +1002,18 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
}
|
||||
|
||||
// If the imported protocol has template information, select that template
|
||||
if (protocol.templateId && protocolTemplateSelect) {
|
||||
protocolTemplateSelect.value = protocol.templateId;
|
||||
|
||||
// Update template description
|
||||
if (protocol.templateDescription && templateDescription) {
|
||||
templateDescription.textContent = protocol.templateDescription;
|
||||
templateDescription.style.display = 'block';
|
||||
}
|
||||
// If the imported protocol has template information, highlight the template
|
||||
if (protocol.templateId) {
|
||||
// Highlight the selected template option
|
||||
const templateOptions = document.querySelectorAll('.template-option');
|
||||
templateOptions.forEach(option => {
|
||||
const templateId = option.getAttribute('data-template-id');
|
||||
if (templateId === protocol.templateId) {
|
||||
option.classList.add('selected');
|
||||
} else {
|
||||
option.classList.remove('selected');
|
||||
}
|
||||
});
|
||||
|
||||
// Expand all sections
|
||||
stageContents.forEach(content => {
|
||||
@ -950,14 +1024,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If no template, reset the template selector
|
||||
if (protocolTemplateSelect) {
|
||||
protocolTemplateSelect.value = '';
|
||||
}
|
||||
if (templateDescription) {
|
||||
templateDescription.textContent = '';
|
||||
templateDescription.style.display = 'none';
|
||||
}
|
||||
// If no template, remove any highlights
|
||||
document.querySelectorAll('.template-option').forEach(option => {
|
||||
option.classList.remove('selected');
|
||||
});
|
||||
}
|
||||
|
||||
// Update preview mode if active
|
||||
|
@ -7,22 +7,32 @@
|
||||
<div class="builder-main">
|
||||
<div class="protocol-metadata">
|
||||
<div class="metadata-field">
|
||||
<label for="community-name">Community Name:</label>
|
||||
<h2>Community Name</h2>
|
||||
<input type="text" id="community-name" name="community-name" placeholder="Enter your community name...">
|
||||
</div>
|
||||
|
||||
<div class="metadata-field">
|
||||
<label for="protocol-summary">Summary:</label>
|
||||
<h2>Summary</h2>
|
||||
<textarea id="protocol-summary" name="protocol-summary" placeholder="Briefly describe this dispute resolution protocol and its purpose..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="protocol-template-selector">
|
||||
<label for="protocol-template">Select a Protocol Template:</label>
|
||||
<select id="protocol-template" class="protocol-template-select">
|
||||
<option value="">-- Create Your Own Protocol --</option>
|
||||
<!-- Template options will be populated by JavaScript -->
|
||||
</select>
|
||||
<div class="stage-header" id="template-header">
|
||||
<div class="stage-header-content">
|
||||
<h2>Select a Template</h2>
|
||||
</div>
|
||||
<button type="button" class="toggle-btn" aria-label="Toggle section" onclick="toggleTemplateSection(this)">+</button>
|
||||
</div>
|
||||
<div class="template-body" style="display: none;">
|
||||
<div class="template-options">
|
||||
<div class="template-option" data-template-id="">
|
||||
<button class="template-select-btn">Create Your Own Protocol</button>
|
||||
<p class="template-description">Start with a blank protocol and build it from scratch.</p>
|
||||
</div>
|
||||
<!-- Template options will be populated by JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="builder-content">
|
||||
@ -154,6 +164,22 @@ function toggleStage(button) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
function toggleTemplateSection(button) {
|
||||
const section = button.closest('.protocol-template-selector');
|
||||
const body = section.querySelector('.template-body');
|
||||
|
||||
if (body.style.display === 'block') {
|
||||
body.style.display = 'none';
|
||||
button.textContent = '+';
|
||||
} else {
|
||||
body.style.display = 'block';
|
||||
button.textContent = '-';
|
||||
}
|
||||
|
||||
// Prevent event from propagating
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
// Make headers also toggle sections
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const headers = document.querySelectorAll('.stage-header-content');
|
||||
@ -164,6 +190,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleButton.click();
|
||||
});
|
||||
});
|
||||
|
||||
// Make template header also toggle section
|
||||
const templateHeader = document.querySelector('#template-header .stage-header-content');
|
||||
if (templateHeader) {
|
||||
templateHeader.addEventListener('click', function() {
|
||||
const header = this.closest('#template-header');
|
||||
const toggleButton = header.querySelector('.toggle-btn');
|
||||
toggleButton.click();
|
||||
});
|
||||
}
|
||||
|
||||
// Textarea auto-resizing is now handled by the script in head.html
|
||||
|
||||
|
Reference in New Issue
Block a user