fully functional but missing permissions

This commit is contained in:
Tim Fry 2024-12-03 18:25:25 -04:00
parent b1330ec105
commit fa0216f1a6
2 changed files with 252 additions and 143 deletions

View File

@ -65,40 +65,68 @@ function build_data_array_from_post(settings $settings) {
// Create two arrays - one for rows to delete and one for new/updated rows
//
for ($i = 0; $i < count($_POST['phrase_detail_function']); $i++) {
//check for the empty rows to delete
if (empty($_POST['phrase_detail_data'][$i]) && !empty($_POST['phrase_detail_uuid'][$i])) {
//check for function to perform
$phrase_detail_function = $_POST['phrase_detail_function'][$i];
$phrase_detail_data = null;
$recording_uuid_or_file = '';
$phrase_detail_uuid = '';
//check for the empty rows to delete -- 0,false,null is valid
if (strlen($_POST['phrase_detail_data'][$i]) === 0
&& !empty($_POST['phrase_detail_uuid'][$i])
&& empty($_POST['slider'][$i])
&& empty($_POST['phrase_detail_text'][$i])) {
$drop_rows['phrase_details'][$drop_row_count++]['phrase_detail_uuid'] = $_POST['phrase_detail_uuid'][$i];
continue;
}
//only save rows with data
if (!empty($_POST['phrase_detail_data'][$i])) {
$recording_uuid_or_file = $_POST['phrase_detail_data'][$i];
//check for valid recordings and files
if (is_uuid($recording_uuid_or_file)) {
//recording UUID
$phrase_detail_data = $recording_files[$recording_uuid_or_file];
} else {
//not a recording so must be valid path inside the switch recording files
if (in_array($recording_uuid_or_file, $sound_files)) {
//valid switch audio file
$phrase_detail_data = $recording_uuid_or_file;
} else {
//ignore an invalid audio file
continue;
switch ($phrase_detail_function) {
case 'play-file':
//only save rows with data
if (!empty($_POST['phrase_detail_data'][$i])) {
$recording_uuid_or_file = $_POST['phrase_detail_data'][$i];
//check for valid recordings and files
if (is_uuid($recording_uuid_or_file)) {
//recording UUID
$phrase_detail_data = $recording_files[$recording_uuid_or_file];
} else {
//not a recording so must be valid path inside the switch recording files
if (in_array($recording_uuid_or_file, $sound_files)) {
//valid switch audio file
$phrase_detail_data = $recording_uuid_or_file;
} else {
//ignore an invalid audio file
continue(2);
}
}
//build data array
if ($_POST['phrase_detail_function'][$i] == 'execute' && substr($_POST['phrase_detail_data'][$i], 0,5) != "sleep" && !permission_exists("phrase_execute")) {
header("Location: phrase_edit.php?id=".$phrase_uuid);
exit;
}
}
}
//build data array
if ($_POST['phrase_detail_function'][$i] == 'execute' && substr($_POST['phrase_detail_data'][$i], 0,5) != "sleep" && !permission_exists("phrase_execute")) {
header("Location: phrase_edit.php?id=".$phrase_uuid);
exit;
}
$_POST['phrase_detail_tag'] = 'action'; // default, for now
$_POST['phrase_detail_group'] = "0"; // one group, for now
break;
case 'pause':
//check for value
$phrase_detail_data = $_POST['slider'][$i];
break;
case 'execute':
//check for the empty rows to delete
if (empty($_POST['phrase_detail_text'][$i]) && !empty($_POST['phrase_detail_uuid'][$i])) {
$drop_rows['phrase_details'][$drop_row_count++]['phrase_detail_uuid'] = $_POST['phrase_detail_uuid'][$i];
continue(2);
}
$phrase_detail_data = $_POST['phrase_detail_text'][$i];
break;
}
//update existing records in the database
$_POST['phrase_detail_tag'] = 'action'; // default, for now
$_POST['phrase_detail_group'] = "0"; // one group, for now
if ($phrase_detail_data !== null) {
if (!empty($_POST['phrase_detail_uuid'][$i])) {
//update existing records in the database
$phrase_detail_uuid = $_POST['phrase_detail_uuid'][$i];
} else {
//new record
$phrase_detail_uuid = uuid();
}
$array['phrase_details'][$i]['phrase_detail_uuid'] = $phrase_detail_uuid;
@ -107,7 +135,7 @@ function build_data_array_from_post(settings $settings) {
$array['phrase_details'][$i]['phrase_detail_order'] = $i;
$array['phrase_details'][$i]['phrase_detail_tag'] = $_POST['phrase_detail_tag'];
$array['phrase_details'][$i]['phrase_detail_pattern'] = $_POST['phrase_detail_pattern'] ?? null;
$array['phrase_details'][$i]['phrase_detail_function'] = $_POST['phrase_detail_function'][$i];
$array['phrase_details'][$i]['phrase_detail_function'] = $phrase_detail_function;
$array['phrase_details'][$i]['phrase_detail_data'] = $phrase_detail_data; //path and filename of recording
$array['phrase_details'][$i]['phrase_detail_method'] = $_POST['phrase_detail_method'] ?? null;
$array['phrase_details'][$i]['phrase_detail_type'] = $_POST['phrase_detail_type'] ?? null;
@ -481,12 +509,12 @@ if (count($_POST) > 0) {
echo "</tbody>";
//cloning row and buttons created outside of 'structure' table body
echo "<tbody>";
echo "<tr class='draggable-row' id='empty_row' draggable=true style='display: none;'>\n";
echo "<tr id='empty_row' style='display: none;'>\n";
echo " <td style='border-bottom: none;' nowrap='nowrap'><center><span class='fa-solid fa-arrows-up-down'></span></center></td>";
echo " <td class='vtable' style='border-bottom: none;' align='left' nowrap='nowrap'>\n";
echo " <select class='formfld' name='phrase_detail_function_empty' id='phrase_detail_function_empty' tag=''>\n";
echo " <option value='play-file'>".$text['label-play']."</option>\n";
echo " <option value='execute'>".$text['label-pause']."</option>\n";
echo " <option value='pause'>".$text['label-pause']."</option>\n";
if (if_group("superadmin")) {
echo " <option value='execute'>".$text['label-execute']."</option>\n";
}
@ -497,9 +525,14 @@ if (count($_POST) > 0) {
// if (if_group("superadmin")) {
// echo " <input id='phrase_detail_data_switch_empty' type='button' class='btn' style='margin-left: 4px; display: none;' value='&#9665;' onclick=\"action_to_select(); load_action_options(document.getElementById('phrase_detail_function_empty').selectedIndex);\">\n";
// }
echo " <input type=hidden name='hidden_empty' id='hidden_empty' value='uuid' tag='row'>";
echo " <input type=hidden name='empty_uuid' value=''>";
echo " <input class='formfld' type=text name='empty_phrase_detail_text' value='' style='width: 300px; min-width: 300px; max-width: 300px; display: none'>";
echo " <span style='white-space: nowrap; display: flex; align-items: center; gap: 10px;'>";
echo " <input class='form-control-range' type=range name='range' minrange='1' style='width: 250px; min-width: 250px; max-width: 250px; display: none'>";
echo " <input type='text' class='formfld' name='sleep' style='width: 40px; min-width: 40px; max-width: 40px; display: none'>";
echo " </span>";
echo " </td>\n";
echo " </tr>\n";
echo "</tr>\n";
echo "<tr>";
echo "<td>&nbsp;</td>";
echo "<td class='vtable' style='align=center;' colspan='2'><center>";

View File

@ -31,75 +31,37 @@ document.addEventListener("DOMContentLoaded", function () {
add_draggable_rows();
});
//
// Switch to a text input box when 'Execute' is selected instead of dropdown
//
function add_switch_to_text_input(select_action) {
if (window.permission_execute) {
const row = select_action.parentNode.parentNode;
const row_index = document.getElementById('structure').rows.length;
//get the select boxes
const select_list = row.querySelectorAll('td select'); //action and recording select dropdown boxes
const select_data = select_list[1];
// Create a new text input to replace the select when execute is chosen
const textInput = document.createElement('input');
textInput.type = 'text';
textInput.className = 'formfld';
textInput.id = 'phrase_detail_data_input[' + row_index + ']';
textInput.name = 'phrase_detail_data_input[' + row_index + ']';
//match style
textInput.style.width = select_data.style.width;
textInput.style.height = select_data.style.height;
//set to hide
textInput.style.display = 'none';
select_data.parentNode.appendChild(textInput);
select_action.addEventListener('change', function () {
if (select_action.value === 'execute') {
//show text box
select_data.style.display = 'none';
textInput.style.display = 'block';
} else {
//hide text box
select_data.style.display = 'block';
textInput.style.display = 'none';
}
});
}
}
//
// Inserts all existing records before the empty one
//
function add_existing() {
const tbody = document.getElementById('structure');
for (let i=0; i < window.phrase_details.length; i++) {
const newRow = document.getElementById('empty_row').cloneNode(true);
//un-hide the row
newRow.style.display = '';
//get the select boxes
const select_list = newRow.querySelectorAll('td select'); //action and recording select dropdown boxes
//play, pause, execute select box
const select_action = select_list[0];
add_switch_to_text_input(select_action);
select_by_value(select_action, 'play-file');
//recording select box
const select_recording = select_list[1];
select_by_text(select_recording, window.phrase_details[i]['display_name']);
const input_fields = newRow.querySelectorAll('td input');
const uuid_field = input_fields[0];
uuid_field.setAttribute('id' , 'phrase_detail_uuid[' + i +']');
uuid_field.setAttribute('name', 'phrase_detail_uuid[' + i +']');
uuid_field.value = window.phrase_details[i]['phrase_detail_uuid'];
//add the row to the table body
tbody.appendChild(newRow);
for (let index=0; index < window.phrase_details.length; index++) {
add_row();
const select_action = document.getElementById('phrase_detail_function[' + index + ']');
select_by_value(select_action, window.phrase_details[index].phrase_detail_function);
const select_data = document.getElementById('phrase_detail_data[' + index + ']');
select_by_text(select_data, window.phrase_details[index]['display_name']);
const uuid_field = document.getElementById('phrase_detail_uuid[' +index+']');
uuid_field.value = window.phrase_details[index]['phrase_detail_uuid'];
const slider = document.getElementById('slider['+index+']');
const sleep = document.getElementById('sleep['+index+']');
const phrase_detail_text = document.getElementById('phrase_detail_text['+index+']');
//update the sleep data
if (window.phrase_details[index].phrase_detail_function === 'pause') {
sleep.value = window.phrase_details[index].phrase_detail_data;
slider.value = window.phrase_details[index].phrase_detail_data;
}
//update the execute text
if (window.phrase_details[index].phrase_detail_function === 'execute') {
phrase_detail_text.value = window.phrase_details[index].phrase_detail_data;
}
// Manually trigger the change event to select the proper display
if (window.phrase_details[index].phrase_detail_function !== 'play-file') {
const changeEvent = new Event('change', { bubbles: true });
select_action.dispatchEvent(changeEvent);
}
}
}
@ -107,27 +69,27 @@ function add_existing() {
// Set the selected index on a dropdown box based on the value (key)
//
function select_by_value(selectElement, valueToFind) {
// Loop through the options of the select element
for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].value === valueToFind) {
selectElement.selectedIndex = i; // Set the selected index
return; // Exit the loop once found
}
}
console.warn('Value not found in select options');
// Loop through the options of the select element
for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].value === valueToFind) {
selectElement.selectedIndex = i; // Set the selected index
return; // Exit the loop once found
}
}
console.warn('Value not found in select options');
}
//
// Set the selected index on a dropdown box based on the text
//
function select_by_text(selectElement, textToFind) {
for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].text === textToFind) {
selectElement.selectedIndex = i;
return;
}
}
console.warn('Text not found in select options');
for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].text === textToFind) {
selectElement.selectedIndex = i;
return;
}
}
console.warn('Text not found in select options');
}
//
@ -137,29 +99,47 @@ function add_draggable_rows() {
const tableBody = document.getElementById('structure');
let draggedRow = null;
// Add drag-and-drop functionality
tableBody.addEventListener('dragstart', (e) => {
draggedRow = e.target;
e.target.classList.add('dragging');
});
// Add drag listeners only to the leftmost cell on the row
tableBody.querySelectorAll('tr').forEach(row => {
const dragHandleCell = row.cells[0]; // Assuming the first cell is the one left to the dropdown
tableBody.addEventListener('dragover', (e) => {
e.preventDefault();
const targetRow = e.target.closest('tr');
if (targetRow && targetRow !== draggedRow) {
const bounding = targetRow.getBoundingClientRect();
const offset = e.clientY - bounding.top;
if (offset > bounding.height / 2) {
targetRow.parentNode.insertBefore(draggedRow, targetRow.nextSibling);
} else {
targetRow.parentNode.insertBefore(draggedRow, targetRow);
if (!dragHandleCell) return;
// Enable dragging from this cell
dragHandleCell.setAttribute('draggable', 'true');
dragHandleCell.addEventListener('dragstart', (e) => {
draggedRow = row;
row.classList.add('dragging');
});
dragHandleCell.addEventListener('dragend', () => {
if (draggedRow) {
draggedRow.classList.remove('dragging');
draggedRow = null;
}
}
});
});
tableBody.addEventListener('dragend', () => {
draggedRow.classList.remove('dragging');
draggedRow = null;
dragHandleCell.addEventListener('dragover', (e) => {
e.preventDefault();
const targetRow = e.target.closest('tr');
if (targetRow && targetRow !== draggedRow) {
const bounding = targetRow.getBoundingClientRect();
const offset = e.clientY - bounding.top;
if (offset > bounding.height / 2) {
targetRow.parentNode.insertBefore(draggedRow, targetRow.nextSibling);
} else {
targetRow.parentNode.insertBefore(draggedRow, targetRow);
}
}
});
dragHandleCell.addEventListener('dragend', () => {
if (draggedRow) {
draggedRow.classList.remove('dragging');
draggedRow = null;
update_order();
}
});
});
}
@ -180,18 +160,47 @@ function update_order() {
//get the select boxes
const select_list = row.querySelectorAll('td select'); //action and recording select dropdown boxes
//get the input boxes
const input_boxes = row.querySelectorAll('td input');
console.log(input_boxes);
//uuid
const phrase_detail_uuid = input_boxes[0];
phrase_detail_uuid.removeAttribute('id');
phrase_detail_uuid.id = 'phrase_detail_uuid[' + index + ']';
phrase_detail_uuid.name = phrase_detail_uuid.id;
//execute action
const phrase_detail_text = input_boxes[1];
temp_value = phrase_detail_text.value;
console.log('phrase_detail_text', temp_value);
phrase_detail_text.removeAttribute('id');
phrase_detail_text.id = 'phrase_detail_text[' + index + ']';
phrase_detail_text.name = phrase_detail_text.id;
phrase_detail_text.value = temp_value;
//slider
const slider = input_boxes[2];
slider.removeAttribute('id');
slider.id = 'slider[' + index + ']';
slider.name = slider.id;
//sleep value
const sleep = input_boxes[3];
temp_value = sleep.value;
sleep.removeAttribute('id');
sleep.id = 'sleep[' + index + ']';
sleep.name = sleep.id;
sleep.value = temp_value;
//play, pause, execute select box
const select_action = select_list[0];
const select_function = select_list[0];
select_function.removeAttribute('id');
select_function.id = 'phrase_detail_function[' + index + ']'
select_function.name = select_function.id;
//recording select box
const select_recording = select_list[1];
const select_data = select_list[1];
select_data.removeAttribute('id');
select_data.id = 'phrase_detail_data[' + index + ']'
select_data.name = select_data.id;
//set the new id and name for action
select_action.id = 'phrase_detail_function[' + index + ']'
select_action.setAttribute('name', 'phrase_detail_function[' + index + ']');
//set the new id and name for recording
select_recording.id = 'phrase_detail_data[' + index + ']'
select_recording.setAttribute('name', 'phrase_detail_data[' + index + ']');
});
}
@ -210,16 +219,18 @@ function submit_phrase() {
//
function add_row() {
const tbody = document.getElementById('structure');
const newRow = document.getElementById('empty_row').cloneNode(true);
// current index is the count subtract the hidden row
const index = tbody.childElementCount - 1;
const index = tbody.childElementCount;
const newRow = document.getElementById('empty_row').cloneNode(true);
//reset id
newRow.removeAttribute('id');
newRow.id = 'row_' + index;
//un-hide row
newRow.style.display = '';
//reset id
newRow.id = 'row_' + index;
//reset 'name' attribute
newRow.setAttribute('name', 'recording_' + index);
@ -227,17 +238,82 @@ function add_row() {
const select_list = newRow.querySelectorAll('td select'); //action and recording select dropdown boxes
//play, pause, execute select box
const select_action = select_list[0];
select_action.removeAttribute('id');
select_action.id = 'phrase_detail_function[' + index + ']';
select_action.name = 'phrase_detail_function[' + index + ']';
//recording select box
const select_recording = select_list[1];
const select_data = select_list[1];
select_data.removeAttribute('id');
select_data.id = 'phrase_detail_data[' + index + ']';
select_data.name = 'phrase_detail_data[' + index + ']';
//uuid field
const uuid_field = newRow.querySelector('input[name="empty_uuid"]');
uuid_field.removeAttribute('id');
uuid_field.id = 'phrase_detail_uuid[' + index +']';
uuid_field.name = 'phrase_detail_uuid[' + index +']';
const phrase_detail_text = newRow.querySelector('input[name="empty_phrase_detail_text"]');
phrase_detail_text.removeAttribute('id');
phrase_detail_text.id = 'phrase_detail_text[' + index + ']';
phrase_detail_text.name = 'phrase_detail_text[' + index + ']';
//slider
const slider = newRow.querySelector('input[name="range"]');
slider.removeAttribute('id');
slider.id = 'slider[' + index + ']';
slider.name = 'slider[' + index + ']';
//sleep
const sleep = newRow.querySelector('input[name="sleep"]');
sleep.removeAttribute('id');
sleep.id = 'sleep[' + index + ']';
sleep.name = 'sleep[' + index + ']';
sleep.value = slider.value;
let changing = false;
slider.addEventListener('mousemove', function () {
changing = true;
sleep.value = slider.value;
changing = false;
});
sleep.addEventListener('keyup', function() {
if (!changing) {
if (sleep.value.length > 0)
slider.value = sleep.value;
else {
slider.value = 0;
}
}
})
//add switchable select box to text input box
add_switch_to_text_input(select_action);
select_action.addEventListener('change', function () {
if (select_action.value === 'execute') {
//show text box
select_data.style.display = 'none';
slider.style.display = 'none';
sleep.style.display = 'none';
phrase_detail_text.style.display = 'block';
} else if (select_action.value === 'pause') {
//show the range bar
select_data.style.display = 'none';
phrase_detail_text.style.display = 'none';
slider.style.display = 'block';
sleep.style.display = 'block';
} else {
//show drop down
phrase_detail_text.style.display = 'none';
slider.style.display = 'none';
sleep.style.display = 'none';
select_data.style.display = 'block';
}
});
//add the row to the table body
tbody.appendChild(newRow);
//reinitialize draggable functionality on the row
add_draggable_rows();
return index;
}
//