made updates to manager info view
This commit is contained in:
+239
-31
@@ -202,7 +202,7 @@
|
||||
<div class="flex-1 relative bg-white flex flex-col overflow-hidden">
|
||||
<div id="fileListContainer" class="hidden flex-1 flex flex-col p-0 bg-white overflow-hidden"></div>
|
||||
<div id="pdfViewer" class="hidden flex-1 flex flex-col bg-gray-50">
|
||||
<div class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 bg-white shadow-sm flex-shrink-0">
|
||||
<div id="pdfControls" class="flex items-center gap-2 px-3 py-2 border-b border-gray-200 bg-white shadow-sm flex-shrink-0">
|
||||
<div class="flex items-center gap-1">
|
||||
<button id="pdfZoomOut" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">−</button>
|
||||
<button id="pdfZoomReset" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">45%</button>
|
||||
@@ -1032,7 +1032,7 @@
|
||||
|
||||
const col1 = document.createElement('div'); col1.className='flex-1';
|
||||
const label1 = document.createElement('div'); label1.className='text-xs font-bold text-gray-700 uppercase tracking-wide mb-1'; label1.textContent='Manager';
|
||||
const val1 = document.createElement('div'); val1.className='text-sm text-gray-900'; val1.textContent = job['Manager'] || '—';
|
||||
const val1 = document.createElement('div'); val1.className='text-sm text-gray-900'; val1.textContent = job['Project_Manager'] || '—';
|
||||
col1.appendChild(label1); col1.appendChild(val1);
|
||||
|
||||
const col2 = document.createElement('div'); col2.className='flex-1';
|
||||
@@ -1145,7 +1145,7 @@
|
||||
jobFullNameDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1" style="font-size: 8px;">Job Full Name</div><div class="text-gray-900 truncate" style="font-size: 10px;" title="${job.Job_Full_Name || '—'}">${job.Job_Full_Name || '—'}</div>`;
|
||||
|
||||
const managerDiv = document.createElement('div');
|
||||
managerDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1" style="font-size: 8px;">Manager</div><div class="text-gray-900" style="font-size: 10px;">${job.Manager || '—'}</div>`;
|
||||
managerDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1" style="font-size: 8px;">Manager</div><div class="text-gray-900" style="font-size: 10px;">${job.Project_Manager || '—'}</div>`;
|
||||
|
||||
const jobStatusDiv = document.createElement('div');
|
||||
jobStatusDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1" style="font-size: 8px;">Job Status</div><div class="text-gray-900" style="font-size: 10px;">${job.Job_Status || '—'}</div>`;
|
||||
@@ -1169,7 +1169,7 @@
|
||||
jobType.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">Job Type</div><div class="text-gray-900 text-center" style="font-size: 10px;">${job.Job_Type || '—'}</div>`;
|
||||
|
||||
const scopeDiv = document.createElement('div');
|
||||
scopeDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">Scope</div><div class="text-gray-900 text-center" style="font-size: 10px;">—</div>`;
|
||||
scopeDiv.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">Scope</div><div class="text-gray-900 text-center" style="font-size: 10px;">${job.Scope || '—'}</div>`;
|
||||
|
||||
row2.appendChild(jobNum);
|
||||
row2.appendChild(jobDivision);
|
||||
@@ -1206,7 +1206,7 @@
|
||||
contactNumber.appendChild(phoneDiv);
|
||||
|
||||
const extn = document.createElement('div');
|
||||
extn.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EXT.</div><div class="text-gray-900 text-center" style="font-size: 10px;">—</div>`;
|
||||
extn.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EXT.</div><div class="text-gray-900 text-center" style="font-size: 10px;">${job.EXT || '—'}</div>`;
|
||||
|
||||
row3.appendChild(companyClient);
|
||||
row3.appendChild(contactPerson);
|
||||
@@ -1253,7 +1253,14 @@
|
||||
|
||||
// EST Cost in 4th column (centered)
|
||||
const estimatedCostContainer = document.createElement('div');
|
||||
estimatedCostContainer.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EST Cost</div><div class="text-gray-900 text-center" style="font-size: 10px;">—</div>`;
|
||||
let costFormatted = '—';
|
||||
if(job.Estimated_Cost !== null && job.Estimated_Cost !== undefined && job.Estimated_Cost !== '') {
|
||||
const costNum = parseFloat(job.Estimated_Cost);
|
||||
if(!isNaN(costNum)) {
|
||||
costFormatted = '$' + costNum.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
}
|
||||
}
|
||||
estimatedCostContainer.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EST Cost</div><div class="text-gray-900 text-center" style="font-size: 10px;">${costFormatted}</div>`;
|
||||
|
||||
row4.appendChild(addressContainer);
|
||||
row4.appendChild(mapIconsContainer);
|
||||
@@ -1278,11 +1285,29 @@
|
||||
const estimatedStartDate = document.createElement('div');
|
||||
estimatedStartDate.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EST Start Date</div><div class="text-gray-900 text-center" style="font-size: 10px;">${startDateFormatted}</div>`;
|
||||
|
||||
let actualStartDateFormatted = '—';
|
||||
if(job.Start_Date_Actual){
|
||||
try {
|
||||
const date = new Date(job.Start_Date_Actual);
|
||||
actualStartDateFormatted = date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
|
||||
} catch(e) {
|
||||
actualStartDateFormatted = job.Start_Date_Actual;
|
||||
}
|
||||
}
|
||||
const actualStartDate = document.createElement('div');
|
||||
actualStartDate.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">Actual Start Date</div><div class="text-gray-900 text-center" style="font-size: 10px;">${startDateFormatted}</div>`;
|
||||
actualStartDate.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">Actual Start Date</div><div class="text-gray-900 text-center" style="font-size: 10px;">${actualStartDateFormatted}</div>`;
|
||||
|
||||
let estimatedEndDateFormatted = '—';
|
||||
if(job.Estimated_End_Date){
|
||||
try {
|
||||
const date = new Date(job.Estimated_End_Date);
|
||||
estimatedEndDateFormatted = date.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' });
|
||||
} catch(e) {
|
||||
estimatedEndDateFormatted = job.Estimated_End_Date;
|
||||
}
|
||||
}
|
||||
const estimatedEndDate = document.createElement('div');
|
||||
estimatedEndDate.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EST End Date</div><div class="text-gray-900 text-center" style="font-size: 10px;">—</div>`;
|
||||
estimatedEndDate.innerHTML = `<div class="font-bold text-gray-700 uppercase tracking-wide mb-1 text-center" style="font-size: 8px;">EST End Date</div><div class="text-gray-900 text-center" style="font-size: 10px;">${estimatedEndDateFormatted}</div>`;
|
||||
|
||||
row5.appendChild(estimatedStartDate);
|
||||
row5.appendChild(actualStartDate);
|
||||
@@ -1441,6 +1466,12 @@
|
||||
<button data-cmd="foreColor" data-val="#0000ff" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 text-gray-900 cursor-pointer flex items-center justify-center text-blue-600" style="font-size: 8px;">A</button>
|
||||
<button data-cmd="foreColor" data-val="#000000" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 text-gray-900 cursor-pointer flex items-center justify-center text-black" style="font-size: 8px;">A</button>
|
||||
<button data-cmd="removeFormat" class="h-6 px-2 rounded border border-gray-400 bg-gray-400 text-white cursor-pointer flex items-center justify-center" style="font-size: 8px;">Reset</button>
|
||||
<button id="jobNoteMic" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 cursor-pointer flex items-center justify-center" title="Voice to text">
|
||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="#4B5563">
|
||||
<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z"/>
|
||||
<path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="jobNewNote" contenteditable="true" class="min-h-14 max-h-[120px] overflow-auto p-2 border border-gray-600 rounded text-sm bg-white mb-2"></div>
|
||||
<div class="flex gap-2">
|
||||
@@ -1505,6 +1536,12 @@
|
||||
<button data-cmd="foreColor" data-val="#0000ff" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 text-gray-900 cursor-pointer flex items-center justify-center text-blue-600" style="font-size: 8px;">A</button>
|
||||
<button data-cmd="foreColor" data-val="#000000" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 text-gray-900 cursor-pointer flex items-center justify-center text-black" style="font-size: 8px;">A</button>
|
||||
<button data-cmd="removeFormat" class="h-6 px-2 rounded border border-gray-400 bg-gray-400 text-white cursor-pointer flex items-center justify-center" style="font-size: 8px;">Reset</button>
|
||||
<button id="managerNoteMic" class="h-6 w-8 rounded border border-gray-400 bg-gray-400 cursor-pointer flex items-center justify-center" title="Voice to text">
|
||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="#4B5563">
|
||||
<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z"/>
|
||||
<path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="managerNewNote" contenteditable="true" class="min-h-14 max-h-[120px] overflow-auto p-2 border border-gray-600 rounded text-sm bg-white mb-2"></div>
|
||||
<div class="flex gap-2">
|
||||
@@ -1597,12 +1634,21 @@
|
||||
populateNotesFileColumns([], 'managerNotesFileColumns');
|
||||
}
|
||||
|
||||
// Load and display notes filtered by type
|
||||
loadAndDisplayNotes(job);
|
||||
|
||||
// Setup toolbar functionality for job notes editor
|
||||
setupNoteEditorToolbar('jobNewNote', 'jobNoteEditor');
|
||||
|
||||
// Setup toolbar functionality for manager notes editor
|
||||
setupNoteEditorToolbar('managerNewNote', 'managerNoteEditor');
|
||||
|
||||
// Setup voice-to-text for job notes
|
||||
setupVoiceToText('jobNoteMic', 'jobNewNote');
|
||||
|
||||
// Setup voice-to-text for manager notes
|
||||
setupVoiceToText('managerNoteMic', 'managerNewNote');
|
||||
|
||||
// Setup close functionality
|
||||
document.getElementById('jobNoteCollapse').addEventListener('click', (e) => {
|
||||
console.log('Close job note editor');
|
||||
@@ -1668,6 +1714,102 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Setup voice-to-text functionality
|
||||
function setupVoiceToText(micButtonId, editorId) {
|
||||
const micBtn = document.getElementById(micButtonId);
|
||||
const editor = document.getElementById(editorId);
|
||||
|
||||
if(!micBtn || !editor) {
|
||||
console.log('Mic button or editor not found:', micButtonId, editorId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for browser support
|
||||
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
||||
if(!SpeechRecognition) {
|
||||
micBtn.disabled = true;
|
||||
micBtn.title = 'Speech recognition not supported';
|
||||
micBtn.style.opacity = '0.5';
|
||||
return;
|
||||
}
|
||||
|
||||
const recognition = new SpeechRecognition();
|
||||
recognition.continuous = true;
|
||||
recognition.interimResults = true;
|
||||
recognition.lang = 'en-US';
|
||||
|
||||
let isListening = false;
|
||||
const micIcon = micBtn.querySelector('svg');
|
||||
|
||||
micBtn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if(isListening) {
|
||||
recognition.stop();
|
||||
isListening = false;
|
||||
micIcon.setAttribute('fill', '#4B5563'); // Gray (inactive)
|
||||
micBtn.style.backgroundColor = '';
|
||||
} else {
|
||||
try {
|
||||
recognition.start();
|
||||
isListening = true;
|
||||
micIcon.setAttribute('fill', '#EF4444'); // Red (recording)
|
||||
micBtn.style.backgroundColor = '#FEE2E2'; // Light red background
|
||||
} catch(err) {
|
||||
console.error('Recognition start error:', err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
recognition.onresult = (event) => {
|
||||
let interimTranscript = '';
|
||||
let finalTranscript = '';
|
||||
|
||||
for(let i = event.resultIndex; i < event.results.length; i++) {
|
||||
const transcript = event.results[i][0].transcript;
|
||||
if(event.results[i].isFinal) {
|
||||
finalTranscript += transcript + ' ';
|
||||
} else {
|
||||
interimTranscript += transcript;
|
||||
}
|
||||
}
|
||||
|
||||
if(finalTranscript) {
|
||||
// Insert final transcript at cursor position
|
||||
editor.focus();
|
||||
const selection = window.getSelection();
|
||||
if(selection.rangeCount > 0) {
|
||||
const range = selection.getRangeAt(0);
|
||||
range.deleteContents();
|
||||
range.insertNode(document.createTextNode(finalTranscript));
|
||||
range.collapse(false);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
} else {
|
||||
// Fallback: append to end
|
||||
editor.innerHTML += finalTranscript;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onerror = (event) => {
|
||||
console.error('Speech recognition error:', event.error);
|
||||
isListening = false;
|
||||
micIcon.setAttribute('fill', '#4B5563');
|
||||
micBtn.style.backgroundColor = '';
|
||||
|
||||
if(event.error === 'not-allowed') {
|
||||
alert('Microphone access denied. Please allow microphone access in your browser settings.');
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onend = () => {
|
||||
isListening = false;
|
||||
micIcon.setAttribute('fill', '#4B5563');
|
||||
micBtn.style.backgroundColor = '';
|
||||
};
|
||||
}
|
||||
|
||||
// Setup toolbar for note editors
|
||||
function setupNoteEditorToolbar(editorId, containerId) {
|
||||
const editor = document.getElementById(editorId);
|
||||
@@ -1756,30 +1898,40 @@
|
||||
hour12: true
|
||||
});
|
||||
const currentUserName = getDisplayName();
|
||||
const noteType = isManagerNote ? '[MANAGER NOTE]' : '';
|
||||
const formatted = `${noteType}[${currentUserName} - ${timestamp}] [Job #${job?.Job_Number||'N/A'}] ${html}\n\n`;
|
||||
const updatedNotes = formatted + (job.Notes || '');
|
||||
const noteType = isManagerNote ? 'manager' : 'job';
|
||||
const typeLabel = isManagerNote ? '[MANAGER NOTE]' : '';
|
||||
const formatted = `${typeLabel}[${currentUserName} - ${timestamp}] [Job #${job?.Job_Number||'N/A'}] ${html}`;
|
||||
|
||||
try {
|
||||
const payloadNote = {
|
||||
Note: formatted.trim(),
|
||||
Job_Number: job?.Job_Number || '',
|
||||
Job_Number_Id: job?.id ? [job.id] : []
|
||||
Job_Number_Id: job?.id ? [job.id] : [],
|
||||
type: noteType
|
||||
};
|
||||
|
||||
// Update job record
|
||||
const resJob = await fetch(`${PB_COLLECTION_URL}/${job.id}`, {
|
||||
method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json', ...authHeaders()},
|
||||
body: JSON.stringify({Notes: updatedNotes})
|
||||
});
|
||||
// If it's a job note, also update Job_Info_Prod.Notes field
|
||||
if(!isManagerNote) {
|
||||
const updatedNotes = formatted + '\n\n' + (job.Notes || '');
|
||||
const resJob = await fetch(`${PB_COLLECTION_URL}/${job.id}`, {
|
||||
method: 'PATCH',
|
||||
headers: {'Content-Type': 'application/json', ...authHeaders()},
|
||||
body: JSON.stringify({Notes: updatedNotes})
|
||||
});
|
||||
|
||||
if(!resJob.ok) {
|
||||
console.error('Job_Info update failed:', resJob.status);
|
||||
throw new Error('Failed to update Job_Info: ' + resJob.status);
|
||||
}
|
||||
|
||||
const updated = await resJob.json();
|
||||
payloadNote.Job_Number_Id = [updated.id || job.id];
|
||||
|
||||
// Update current job object
|
||||
currentJob.Notes = updatedNotes;
|
||||
}
|
||||
|
||||
if(!resJob.ok) throw new Error('Job_Info update failed: ' + resJob.status);
|
||||
const updated = await resJob.json();
|
||||
const jobIdToLink = updated.id || job.id;
|
||||
|
||||
// Create note in notes collection
|
||||
payloadNote.Job_Number_Id = [jobIdToLink];
|
||||
// Create note in notes collection with type
|
||||
const resNote = await fetch(`${NOTES_COLLECTION_URL}`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json', ...authHeaders()},
|
||||
@@ -1787,17 +1939,23 @@
|
||||
});
|
||||
|
||||
if(!resNote.ok) {
|
||||
console.warn('Note creation failed with status', resNote.status);
|
||||
const errText = await resNote.text().catch(() => '');
|
||||
console.error('Note creation failed:', resNote.status, errText);
|
||||
// Don't throw if Notes collection fails but Job_Info succeeded
|
||||
if(!isManagerNote) {
|
||||
console.warn('Note saved to Job_Info but failed to save to Notes collection');
|
||||
} else {
|
||||
throw new Error('Failed to save note: ' + resNote.status);
|
||||
}
|
||||
}
|
||||
|
||||
// Update UI
|
||||
currentJob.Notes = updatedNotes;
|
||||
// Clear editor
|
||||
editor.innerHTML = '';
|
||||
alert('Note saved successfully!');
|
||||
|
||||
// Refresh the display
|
||||
if(currentJob) {
|
||||
populateManagerInfo(currentJob);
|
||||
await loadAndDisplayNotes(currentJob);
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Error saving note:', err);
|
||||
@@ -1805,6 +1963,55 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Load and display notes filtered by type
|
||||
async function loadAndDisplayNotes(job) {
|
||||
if(!job?.id) return;
|
||||
|
||||
try {
|
||||
// Fetch all notes for this job
|
||||
const filter = `Job_Number_Id?~"${job.id}"`;
|
||||
const resp = await fetch(`${NOTES_COLLECTION_URL}?filter=${encodeURIComponent(filter)}&sort=-created`, {
|
||||
headers: authHeaders()
|
||||
});
|
||||
|
||||
if(!resp.ok) {
|
||||
console.error('Failed to fetch notes:', resp.status);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await resp.json();
|
||||
const allNotes = data.items || [];
|
||||
|
||||
// Filter notes by type
|
||||
const jobNotes = allNotes.filter(n => !n.type || n.type === 'job');
|
||||
const managerNotes = allNotes.filter(n => n.type === 'manager');
|
||||
|
||||
// Update job notes display
|
||||
const jobNotesDisplay = document.querySelector('#jobNotesContent > div:first-child');
|
||||
if(jobNotesDisplay) {
|
||||
if(jobNotes.length > 0) {
|
||||
jobNotesDisplay.innerHTML = jobNotes.map(n => n.Note).join('\n\n');
|
||||
} else {
|
||||
jobNotesDisplay.innerHTML = '<span class="text-gray-400 italic">No notes available</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// Update manager notes display
|
||||
const managerNotesDisplay = document.querySelector('#managerNotesContent > div:first-child');
|
||||
if(managerNotesDisplay) {
|
||||
if(managerNotes.length > 0) {
|
||||
managerNotesDisplay.innerHTML = managerNotes.map(n => n.Note).join('\n\n');
|
||||
} else {
|
||||
managerNotesDisplay.innerHTML = '<span class="text-gray-400 italic">No manager notes available</span>';
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Loaded notes - Job:', jobNotes.length, 'Manager:', managerNotes.length);
|
||||
} catch(err) {
|
||||
console.error('Error loading notes:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to populate file columns in notes section
|
||||
function populateNotesFileColumns(files, containerId) {
|
||||
const container = document.getElementById(containerId);
|
||||
@@ -1855,7 +2062,7 @@
|
||||
fileName.className = 'truncate';
|
||||
fileItem.appendChild(fileName);
|
||||
|
||||
fileItem.onclick = () => openFilePreview(file);
|
||||
fileItem.onclick = () => openFilePreview(file.driveId || '', file.id || '', file.name, file.contentType || '', file.url);
|
||||
plansList.appendChild(fileItem);
|
||||
});
|
||||
} else {
|
||||
@@ -1884,7 +2091,7 @@
|
||||
fileName.className = 'truncate';
|
||||
fileItem.appendChild(fileName);
|
||||
|
||||
fileItem.onclick = () => openFilePreview(file);
|
||||
fileItem.onclick = () => openFilePreview(file.driveId || '', file.id || '', file.name, file.contentType || '', file.url);
|
||||
estimatesList.appendChild(fileItem);
|
||||
});
|
||||
} else {
|
||||
@@ -1922,7 +2129,7 @@
|
||||
fileName.className = 'truncate';
|
||||
fileItem.appendChild(fileName);
|
||||
|
||||
fileItem.onclick = () => openFilePreview(file);
|
||||
fileItem.onclick = () => openFilePreview(file.driveId || '', file.id || '', file.name, file.contentType || '', file.url);
|
||||
otherList.appendChild(fileItem);
|
||||
});
|
||||
} else {
|
||||
@@ -2105,6 +2312,7 @@
|
||||
let pdfPan = { x: 0, y: 0, dragging: false, startX: 0, startY: 0, baseX: 0, baseY: 0 };
|
||||
const pdfViewer = document.getElementById('pdfViewer');
|
||||
const pdfCanvas = document.getElementById('pdfCanvas');
|
||||
const pdfControls = document.getElementById('pdfControls');
|
||||
const pdfPageNum = document.getElementById('pdfPageNum');
|
||||
const pdfPageCount = document.getElementById('pdfPageCount');
|
||||
const pdfPrev = document.getElementById('pdfPrev');
|
||||
|
||||
Reference in New Issue
Block a user