diff --git a/appointment/__init__.py b/appointment/__init__.py
index c216dbe..8d6ad8a 100644
--- a/appointment/__init__.py
+++ b/appointment/__init__.py
@@ -5,5 +5,5 @@
__package_name__ = "django-appointment"
__url__ = "https://github.com/adamspd/django-appointment"
__package_website__ = "https://django-appt.adamspierredavid.com/"
-__version__ = "3.4.0"
+__version__ = "3.4.1"
__test_version__ = False
diff --git a/appointment/static/js/app_admin/staff_index.js b/appointment/static/js/app_admin/staff_index.js
index d83d3f8..794e94d 100644
--- a/appointment/static/js/app_admin/staff_index.js
+++ b/appointment/static/js/app_admin/staff_index.js
@@ -40,6 +40,46 @@ document.addEventListener("DOMContentLoaded", function () {
});
});
+const AppStateProxy = new Proxy(AppState, {
+ set(target, property, value) {
+ console.log(`Setting ${property} to ${value}`)
+ // Check if the property being changed is 'isCreating'
+ if (value === true) {
+ attachEventListeners(); // Attach event listeners if isCreating becomes true
+ // (didn't check if property is isCreating, since AppStateProxy is only set with it)
+ }
+ target[property] = value; // Set the property value
+ return true; // Indicate successful setting
+ }
+});
+
+function attachEventListeners() {
+ // Checks if the DOM is already loaded
+ if (document.readyState === "complete" || document.readyState === "interactive") {
+ // DOM is already ready, attach event listeners directly
+ attachEventListenersToDropdown();
+ } else {
+ // If the DOM is not yet ready, then wait for the DOMContentLoaded event
+ document.addEventListener('DOMContentLoaded', function () {
+ attachEventListenersToDropdown();
+ });
+ }
+}
+
+function attachEventListenersToDropdown() {
+ const staffDropdown = document.getElementById('staffSelect');
+ if (staffDropdown && !staffDropdown.getAttribute('listener-attached')) {
+ staffDropdown.setAttribute('listener-attached', 'true');
+ staffDropdown.addEventListener('change', async function () {
+ const selectedStaffId = this.value;
+ const servicesDropdown = document.getElementById('serviceSelect');
+ const services = await fetchServicesForStaffMember(selectedStaffId);
+ updateServicesDropdown(servicesDropdown, services);
+ });
+ }
+}
+
+
function initializeCalendar() {
const formattedAppointments = formatAppointmentsForCalendar(appointments);
const calendarEl = document.getElementById('calendar');
@@ -285,7 +325,7 @@ function closeModal() {
cancelButton.style.display = "none";
// Reset the editing flag
- AppState.isEditingAppointment = false;
+ AppStateProxy.isEditingAppointment = false;
// Close the modal
$('#eventDetailsModal').modal('hide');
@@ -419,6 +459,32 @@ async function populateStaffMembers(selectedStaffId, isEditMode = false) {
return selectElement;
}
+// Function to fetch services for a specific staff member
+async function fetchServicesForStaffMember(staffId) {
+ const url = `${fetchServiceListForStaffURL}?staff_id=${staffId}`;
+ try {
+ const response = await fetch(url);
+ if (!response.ok) throw new Error('Network response was not ok');
+ const data = await response.json();
+ return data.services_offered || [];
+ } catch (error) {
+ console.error("Error fetching services: ", error);
+ return []; // Return an empty array in case of error
+ }
+}
+
+// Function to update services dropdown options
+function updateServicesDropdown(dropdown, services) {
+ // Clear existing options
+ dropdown.innerHTML = '';
+
+ // Populate with new options
+ services.forEach(service => {
+ const option = new Option(service.name, service.id); // Assuming service object has id and name properties
+ dropdown.add(option);
+ });
+}
+
function getCSRFToken() {
const metaTag = document.querySelector('meta[name="csrf-token"]');
if (metaTag) {
@@ -510,14 +576,17 @@ function createNewAppointment(dateInput) {
async function showCreateAppointmentModal(defaultStartTime, formattedDate) {
const servicesDropdown = await populateServices(null, false);
- const staffDropdown = await populateStaffMembers(null, false);
+ let staffDropdown = null;
+ if (isUserSuperUser) {
+ staffDropdown = await populateStaffMembers(null, false);
+ }
servicesDropdown.id = "serviceSelect";
servicesDropdown.disabled = false; // Enable dropdown
document.getElementById('eventModalBody').innerHTML = prepareCreateAppointmentModalContent(servicesDropdown, staffDropdown, defaultStartTime, formattedDate);
adjustCreateAppointmentModalButtons();
- AppState.isCreating = true;
+ AppStateProxy.isCreating = true;
$('#eventDetailsModal').modal('show');
}
@@ -581,7 +650,10 @@ async function showEventModal(eventId = null, isEditMode, isCreatingMode = false
if (!appointment) return;
const servicesDropdown = await getServiceDropdown(appointment.service_id, isEditMode);
- const staffDropdown = await getStaffDropdown(appointment.staff_id, isEditMode);
+ let staffDropdown = null;
+ if (isUserSuperUser) {
+ staffDropdown = await getStaffDropdown(appointment.staff_id, isEditMode);
+ }
document.getElementById('eventModalBody').innerHTML = generateModalContent(appointment, servicesDropdown, isEditMode, staffDropdown);
adjustModalButtonsVisibility(isEditMode, isCreatingMode);
@@ -608,11 +680,11 @@ function adjustModalButtonsVisibility(isEditMode, isCreatingMode) {
function toggleEditMode() {
const modal = document.getElementById("eventDetailsModal");
const appointment = appointments.find(app => Number(app.id) === Number(AppState.eventIdSelected));
- AppState.isCreating = false; // Turn off creating mode
+ AppStateProxy.isCreating = false; // Turn off creating mode
// Proceed only if an appointment is found
if (appointment) {
- AppState.isEditingAppointment = !AppState.isEditingAppointment; // Toggle the editing state
+ AppStateProxy.isEditingAppointment = !AppState.isEditingAppointment; // Toggle the editing state
updateModalUIForEditMode(modal, AppState.isEditingAppointment);
} else {
console.error("Appointment not found!");
diff --git a/appointment/templates/administration/staff_index.html b/appointment/templates/administration/staff_index.html
index e706582..2061809 100644
--- a/appointment/templates/administration/staff_index.html
+++ b/appointment/templates/administration/staff_index.html
@@ -316,7 +316,7 @@
const updateApptDateURL = "{% url 'appointment:update_appt_date_time' %}";
const validateApptDateURL = "{% url 'appointment:validate_appointment_date' %}";
const isUserStaffAdminURL = "{% url 'appointment:is_user_staff_admin' %}";
- const isUserSuperUser = "{{ is_superuser }}";
+ const isUserSuperUser = "{{ is_superuser }}" === "True";