Removed all references to the water_usage_morning field to simplify data structures and form inputs. Introduced flexible autoload behavior in pagination and improved list filtering by excluding weekends and limiting displayed data to the most recent five days.
410 lines
15 KiB
Vue
410 lines
15 KiB
Vue
<script>
|
|
import {authenticatedRequest} from "@/components/session/authenticatedRequest.vue";
|
|
import {ref} from "vue";
|
|
import {parseError} from "@/components/request/HandleGlobalError.vue";
|
|
import {SuperUserObject} from "@/components/session/token/superUserObject.vue";
|
|
import {AdminUserObject} from "@/components/session/token/AdminUserObject.vue";
|
|
import {EditFieldForm} from "@/components/session/token/SessionUser/EditFieldForm.vue";
|
|
import {reCAPTCHA} from "@/components/session/token/SessionUser/reCAPTCHA/reCAPTCHA.vue";
|
|
import {Categories} from "@/components/session/token/SessionUser/Objects/Categories.vue";
|
|
import {Products} from "@/components/session/token/SessionUser/Objects/Products.vue";
|
|
import {ProductOptions} from "@/components/session/token/SessionUser/Objects/ProductOptions.vue";
|
|
import {Departments} from "@/components/session/token/SessionUser/Objects/Departments.vue";
|
|
import {DepartmentCategories} from "@/components/session/token/SessionUser/Objects/DepartmentCategories.vue";
|
|
import {EconomicDepartments} from "@/components/session/token/SessionUser/Objects/economicDepartments.vue";
|
|
import {EconomicProducts} from "@/components/session/token/SessionUser/Objects/economicProducts.vue";
|
|
import {Roles} from "@/components/session/token/SessionUser/Objects/Roles.vue";
|
|
import {Permissions} from "@/components/session/token/SessionUser/Objects/Permissions.vue";
|
|
import {CollectedOrderInvoices} from "@/components/session/token/SessionUser/Objects/CollectedOrderInvoices.vue";
|
|
import {DepartmentDailyReports} from "@/components/session/token/SessionUser/Objects/DepartmentDailyReports.vue";
|
|
import {Notifications} from "@/components/session/token/SessionUser/Objects/Notifications.vue";
|
|
import {Bookings} from "@/components/session/token/SessionUser/Objects/Bookings.vue";
|
|
import {Orders} from "@/components/session/token/SessionUser/Objects/Orders.vue";
|
|
import {Forms} from "@/components/session/token/SessionUser/Objects/Forms.vue";
|
|
import {Branding} from "@/components/session/token/SessionUser/Objects/Brandings.vue";
|
|
import {Vehicles} from "@/components/session/token/SessionUser/Objects/Vehicles.vue";
|
|
import {DepartmentNotificationSms} from "@/components/session/token/SessionUser/Objects/DepartmentNotificationSms.vue";
|
|
import {ObjectsGlobal} from "@/components/session/token/SessionUser/Objects/ObjectsGlobal.vue";
|
|
import {useRouter} from "vue-router";
|
|
import Swal from "sweetalert2";
|
|
|
|
/**
|
|
* Initiate the user session on app start
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export const initiateOnAppStart = async () => {
|
|
// Check if the user has a token stored in local storage
|
|
if (localStorage.getItem("token") !== null) {
|
|
// Set the token and authenticated status
|
|
SessionUser.token.value = localStorage.getItem("token");
|
|
SessionUser.authenticated.value = true;
|
|
// Fetch the user's session data
|
|
await getSessionData();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Authenticate the user
|
|
* @param {string} customer_number
|
|
* @param {string} password
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export const authenticateUser = async (customer_number, password) => {
|
|
return await authenticatedRequest("/auth/login", "POST", {
|
|
customer_number,
|
|
password,
|
|
})
|
|
.then((response) => {
|
|
SessionUser.token.value = response.data.token;
|
|
SessionUser.authenticated.value = true;
|
|
localStorage.setItem("token", response.data.token);
|
|
// Reload the window to make sure the user's session is initiated
|
|
window.location.reload();
|
|
})
|
|
.catch((error) => {
|
|
parseError(error, 'auth');
|
|
console.error(error);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Get the user's session data
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export const getSessionData = async () => {
|
|
return await authenticatedRequest("/auth/session", "GET")
|
|
.then((response) => {
|
|
SessionUser.user.id.value = response.data.data.id;
|
|
SessionUser.user.customer_number.value = response.data.data.customer_number;
|
|
SessionUser.user.group_id.value = response.data.data.group_id;
|
|
SessionUser.user.created_at.value = response.data.data.created_at;
|
|
SessionUser.user.updated_at.value = response.data.data.updated_at;
|
|
SessionUser.user.display_name.value = response.data.data.display_name;
|
|
// Set the last cached time to now, this is used to determine if the user's data is outdated
|
|
SessionUser.user.cached_at.value = new Date();
|
|
SessionUser.permissions.value = response.data.data.permissions;
|
|
// E-conomic data is only fetched if the array isn't empty
|
|
if (response.data.data.economic_customer.length > 0) {
|
|
SessionUser.economicData.customerNumber.value = response.data.data.economic_customer.customerNumber;
|
|
SessionUser.economicData.name.value = response.data.data.economic_customer.name;
|
|
// Set the display name to the e-conomic name if it's empty
|
|
if (SessionUser.user.display_name.value === null) {
|
|
SessionUser.user.display_name.value = response.data.data.economic_customer.name;
|
|
}
|
|
SessionUser.economicData.address.value = response.data.data.economic_customer.address;
|
|
SessionUser.economicData.zip.value = response.data.data.economic_customer.zip;
|
|
SessionUser.economicData.city.value = response.data.data.economic_customer.city;
|
|
SessionUser.economicData.mobilePhone.value = response.data.data.economic_customer.mobilePhone;
|
|
SessionUser.economicData.email.value = response.data.data.economic_customer.email;
|
|
SessionUser.economicData.cvr.value = response.data.data.economic_customer.corporateIdentificationNumber;
|
|
SessionUser.economicData.currency.value = response.data.data.economic_customer.currency;
|
|
SessionUser.economicData.country.value = response.data.data.economic_customer.country;
|
|
SessionUser.economicData.cached_at.value = new Date();
|
|
}
|
|
SessionUser.initiated.value = true;
|
|
})
|
|
.catch((error) => {
|
|
parseError(error, 'auth');
|
|
console.error(error);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Destroy the user's session
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export const destroySession = async () => {
|
|
return await authenticatedRequest("/auth/logout", "GET")
|
|
.then(() => {
|
|
SessionUser.forceRefresh();
|
|
localStorage.removeItem("token");
|
|
})
|
|
.catch((error) => {
|
|
parseError(error, 'auth');
|
|
console.error(error);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Force sign out the user
|
|
*/
|
|
export const forceClearSession = () => {
|
|
localStorage.removeItem("token");
|
|
SessionUser.forceRefresh();
|
|
};
|
|
|
|
/**
|
|
* Define the user session variables
|
|
*/
|
|
export const SessionUser = {
|
|
user: {
|
|
id: ref(null),
|
|
customer_number: ref(null),
|
|
display_name: ref(null),
|
|
group_id: ref(null),
|
|
created_at: ref(null),
|
|
updated_at: ref(null),
|
|
cached_at: ref(null),
|
|
},
|
|
/** The user's permissions */
|
|
permissions: ref([]),
|
|
hasPermission: (permission) => {
|
|
let hasPermission = (SessionUser.permissions.value.includes(permission) || SessionUser.permissions.value.includes('superuser'));
|
|
console.log('Checking permission: ' + permission + ' - ' + hasPermission);
|
|
return hasPermission;
|
|
},
|
|
/** Can access shortcuts */
|
|
canAccessAdmin: () => {
|
|
return SessionUser.hasPermission('admin') || SessionUser.hasPermission('superuser');
|
|
},
|
|
canAccessSuperUser: () => {
|
|
return SessionUser.hasPermission('superuser');
|
|
},
|
|
canAccessUser: () => {
|
|
return SessionUser.hasPermission('user');
|
|
},
|
|
canAccessDepartment: (id = 0) => {
|
|
return (SessionUser.hasPermission('department_access_' + parseInt(id)) || SessionUser.canAccessSuperUser());
|
|
},
|
|
canAccessDeveloper: () => {
|
|
// If the url is localhost, we can assume that the user is a developer
|
|
return window.location.hostname === "localhost";
|
|
},
|
|
/** Shortcuts for the user's group */
|
|
superUser: SuperUserObject,
|
|
adminUser: AdminUserObject,
|
|
|
|
/** Objects */
|
|
objects: {
|
|
categories: Categories,
|
|
products: Products,
|
|
product_options: ProductOptions,
|
|
departments: Departments,
|
|
department_categories: DepartmentCategories,
|
|
economic_departments: EconomicDepartments,
|
|
economic_products: EconomicProducts,
|
|
roles: Roles,
|
|
permissions: Permissions,
|
|
collectedOrderInvoices: CollectedOrderInvoices,
|
|
department_daily_reports: DepartmentDailyReports,
|
|
notifications: Notifications,
|
|
orders: Orders,
|
|
forms: Forms,
|
|
bookings: Bookings,
|
|
Branding: Branding,
|
|
vehicles: Vehicles,
|
|
department_notification_sms: DepartmentNotificationSms,
|
|
global: ObjectsGlobal,
|
|
},
|
|
/** The user's token & authentication status */
|
|
token: ref(null),
|
|
authenticated: ref(false),
|
|
/** The user's e-conomic data */
|
|
economicData: {
|
|
customerNumber: ref(null),
|
|
name: ref(null),
|
|
address: ref(null),
|
|
zip: ref(null),
|
|
city: ref(null),
|
|
mobilePhone: ref(null),
|
|
email: ref(null),
|
|
cvr: ref(null),
|
|
currency: ref(null),
|
|
country: ref(null),
|
|
cached_at: ref(null),
|
|
},
|
|
/** Check if the user's data is outdated (Older than 24 hours) */
|
|
isDataOutdated: () => {
|
|
return new Date() - SessionUser.user.cached_at.value > 1000 * 60 * 60 * 24;
|
|
},
|
|
/** Check if the user's e-conomic data is outdated (Older than 24 hours) */
|
|
isEconomicDataOutdated: () => {
|
|
return new Date() - SessionUser.economicData.cached_at.value > 1000 * 60 * 60 * 24;
|
|
},
|
|
/** Check if the user has e-conomic data */
|
|
hasEconomicData: () => {
|
|
return SessionUser.economicData.customerNumber.value !== null;
|
|
},
|
|
/** Is the object fully initiated */
|
|
initiated: ref(false),
|
|
isInitiated: () => {
|
|
return SessionUser.initiated.value;
|
|
},
|
|
/**
|
|
* Check if the user has a superuser token stored (This is used when the superuser is impersonating a user)
|
|
* @returns {boolean}
|
|
*/
|
|
hasSuperUserToken: () => {
|
|
return localStorage.getItem("superuser_token") !== null;
|
|
},
|
|
/**
|
|
* Set the user's token
|
|
* @param {string} token
|
|
*/
|
|
setToken: (token) => {
|
|
SessionUser.token.value = token;
|
|
localStorage.setItem("token", token);
|
|
// Reload the window to make sure the user's session is initiated
|
|
window.location.reload();
|
|
},
|
|
/** Reset the user's session data (Cache) */
|
|
forceRefresh: () => {
|
|
SessionUser.user.id.value = null;
|
|
SessionUser.user.customer_number.value = null;
|
|
SessionUser.user.display_name.value = null;
|
|
SessionUser.user.group_id.value = null;
|
|
SessionUser.user.created_at.value = null;
|
|
SessionUser.user.updated_at.value = null;
|
|
SessionUser.user.cached_at.value = null;
|
|
SessionUser.permissions.value = [];
|
|
SessionUser.authenticated.value = false;
|
|
SessionUser.economicData.customerNumber.value = null;
|
|
SessionUser.economicData.name.value = null;
|
|
SessionUser.economicData.address.value = null;
|
|
SessionUser.economicData.zip.value = null;
|
|
SessionUser.economicData.city.value = null;
|
|
SessionUser.economicData.mobilePhone.value = null;
|
|
SessionUser.economicData.email.value = null;
|
|
SessionUser.economicData.cvr.value = null;
|
|
SessionUser.economicData.currency.value = null;
|
|
SessionUser.economicData.country.value = null;
|
|
SessionUser.economicData.cached_at.value = null;
|
|
getSessionData();
|
|
},
|
|
auth: {
|
|
/** Authenticate the user */
|
|
authenticate: authenticateUser,
|
|
/** Logout the user */
|
|
logout: destroySession,
|
|
/** Force clear the user's session WARNING: This will not destroy the user's token */
|
|
forceClearSession: forceClearSession,
|
|
/** reCAPTCHA */
|
|
reCAPTCHA: reCAPTCHA,
|
|
},
|
|
functions: {
|
|
/** Check if the user has a token */
|
|
hasToken: () => {
|
|
return SessionUser.token.value !== null;
|
|
},
|
|
/** Show confirm logout dialog */
|
|
showConfirmLogoutDialog: () => {
|
|
Swal.fire(
|
|
{
|
|
title: 'Er du sikker?',
|
|
text: "Du vil blive logget ud af systemet",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Ja, log mig ud',
|
|
cancelButtonText: 'Annuller'
|
|
}
|
|
).then((result) => {
|
|
if (result.isConfirmed) {
|
|
SessionUser.auth.logout().then(() => {
|
|
SessionUser.auth.forceClearSession();
|
|
SessionUser.functions.redirectTo.pages.login();
|
|
});
|
|
}
|
|
});
|
|
},
|
|
/** Get the department id from the url */
|
|
getDepartmentIdFromUrl: () => {
|
|
// Check if the department id is in the route
|
|
const router = useRouter();
|
|
return parseInt(router.currentRoute.value.params.departmentId) > 0 ? parseInt(router.currentRoute.value.params.departmentId) : undefined;
|
|
},
|
|
/** Get the department ids the user has access to */
|
|
getAccessibleDepartments: () => {
|
|
return SessionUser.permissions.value.filter(permission => permission.includes('department_access_')).map(permission => parseInt(permission.split('_').pop()));
|
|
},
|
|
currency: {
|
|
toLocal: (value) => {
|
|
return new Intl.NumberFormat('da-DK', {style: 'currency', currency: 'DKK'}).format(value);
|
|
},
|
|
},
|
|
date: {
|
|
toWords: (date) => {
|
|
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
|
|
return new Date(date).toLocaleDateString('da-DK', options);
|
|
},
|
|
toLocal: (date) => {
|
|
return new Date(date).toLocaleString('da-DK');
|
|
},
|
|
isToday(date) {
|
|
const created_at_val = new Date(date);
|
|
const today = new Date();
|
|
return created_at_val.toDateString() === today.toDateString();
|
|
},
|
|
toLocalTimeHours: (date) => {
|
|
return new Date(date).toLocaleTimeString('da-DK', {hour: '2-digit', minute: '2-digit'});
|
|
},
|
|
getDateWeekdayNumber: (date) => {
|
|
const created_at_val = new Date(date);
|
|
const weekday = created_at_val.getDay();
|
|
return weekday === 0 ? 7 : weekday;
|
|
},
|
|
weekdayNumbers: {
|
|
monday: 1,
|
|
tuesday: 2,
|
|
wednesday: 3,
|
|
thursday: 4,
|
|
friday: 5,
|
|
saturday: 6,
|
|
sunday: 7,
|
|
}
|
|
},
|
|
/** Redirect to */
|
|
redirectTo: {
|
|
/**
|
|
* Pages to redirect to
|
|
*/
|
|
pages: {
|
|
login: () => {
|
|
window.location.href = '/login';
|
|
},
|
|
},
|
|
/**
|
|
* Redirect to a department
|
|
* @note This will redirect the user to '/admin/:department(/:path)'
|
|
* @param department The department id
|
|
* @param path The path to redirect to (Optional)
|
|
*/
|
|
department: (department, path = null) => {
|
|
window.location.href = '/admin/' + department + (path !== null ? '/' + path : '');
|
|
},
|
|
/**
|
|
* Redirect to a superuser page
|
|
* @note This will redirect the user to '/superuser(/:path)'
|
|
* @param path The path to redirect to (Optional)
|
|
*/
|
|
superUser: (path = null) => {
|
|
window.location.href = '/superuser' + (path !== null ? path : '');
|
|
},
|
|
/**
|
|
* Redirect to a user page
|
|
* @note This will redirect the user to '/user(/:path)'
|
|
* @param path The path to redirect to (Optional)
|
|
*/
|
|
user: (path = null) => {
|
|
window.location.href = '/user' + (path !== null ? path : '');
|
|
},
|
|
/**
|
|
* External redirect
|
|
* @param url The url to redirect to
|
|
* @param newTab Open the url in a new tab
|
|
*/
|
|
external: (url, newTab = false) => {
|
|
if (newTab) {
|
|
window.open(url, '_blank');
|
|
} else {
|
|
window.location.href = url;
|
|
}
|
|
},
|
|
}
|
|
},
|
|
request: authenticatedRequest,
|
|
editField: EditFieldForm,
|
|
getSessionData: getSessionData,
|
|
initiateOnAppStart: initiateOnAppStart
|
|
};
|
|
|
|
</script> |