forked from Simnation/Main
1208 lines
39 KiB
JavaScript
1208 lines
39 KiB
JavaScript
![]() |
const resName = GetParentResourceName();
|
||
|
let hasDoorsCreator = null; // editing this is useless, don't do it
|
||
|
|
||
|
// Open/Close menu
|
||
|
function openMenu(version, fullConfig) {
|
||
|
$("#dealerships-creator-version").text(version);
|
||
|
|
||
|
loadDealerships();
|
||
|
loadVehicles();
|
||
|
loadClasses();
|
||
|
loadSettings(fullConfig);
|
||
|
|
||
|
$("#dealerships-creator").show()
|
||
|
}
|
||
|
|
||
|
function closeMenu() {
|
||
|
// Resets current active tab
|
||
|
$("#dealerships-creator").find(".nav-link, .tab-pane").each(function() {
|
||
|
if($(this).data("isDefault") == "1") {
|
||
|
$(this).addClass(["active", "show"])
|
||
|
} else {
|
||
|
$(this).removeClass(["active", "show"])
|
||
|
}
|
||
|
})
|
||
|
|
||
|
$("#dealerships-creator").hide();
|
||
|
|
||
|
$.post(`https://${resName}/close`)
|
||
|
}
|
||
|
$("#close-main-btn").click(closeMenu);
|
||
|
|
||
|
// Messages received by client
|
||
|
window.addEventListener('message', (event) => {
|
||
|
let data = event.data;
|
||
|
let action = data.action;
|
||
|
|
||
|
switch(action) {
|
||
|
case "openMenu": {
|
||
|
openMenu(data.version, data.fullConfig);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "hasDoorsCreator": {
|
||
|
hasDoorsCreator = data.hasDoorsCreator;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
/*
|
||
|
███████ ███████ ████████ ████████ ██ ███ ██ ██████ ███████
|
||
|
██ ██ ██ ██ ██ ████ ██ ██ ██
|
||
|
███████ █████ ██ ██ ██ ██ ██ ██ ██ ███ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||
|
███████ ███████ ██ ██ ██ ██ ████ ██████ ███████
|
||
|
*/
|
||
|
|
||
|
/* Discord logs */
|
||
|
function toggleDiscordLogsInSettings(enable) {
|
||
|
$("#settings-mainDiscordWebhook").prop("disabled", !enable);
|
||
|
$("#settings-mainDiscordWebhook").prop("required", enable);
|
||
|
|
||
|
$("#settings-specific-webooks-div").find(`.form-control`).prop("disabled", !enable);
|
||
|
}
|
||
|
|
||
|
$("#settings-areDiscordLogsActive").change(function() {
|
||
|
let enabled = $(this).prop("checked");
|
||
|
|
||
|
toggleDiscordLogsInSettings(enabled);
|
||
|
})
|
||
|
|
||
|
function getSeparatedDiscordWebhooks() {
|
||
|
let webhooks = {};
|
||
|
|
||
|
$("#settings-specific-webooks-div").find(".form-control").each(function(index, element) {
|
||
|
let webhook = $(element).val();
|
||
|
if(!webhook) return;
|
||
|
|
||
|
let logType = $(element).data("logType");
|
||
|
webhooks[logType] = webhook;
|
||
|
});
|
||
|
|
||
|
return webhooks;
|
||
|
}
|
||
|
/* Discord logs END */
|
||
|
|
||
|
function loadSettings(fullConfig) {
|
||
|
// Generic
|
||
|
$("#settings-locale").val(fullConfig.locale);
|
||
|
$("#settings-ace-permission").val(fullConfig.acePermission);
|
||
|
$("#settings-can-always-carry").prop("checked", fullConfig.canAlwaysCarryItem);
|
||
|
|
||
|
// Help notification
|
||
|
setTomSelectValue("#settings-help-notification-script", fullConfig.helpNotification)
|
||
|
|
||
|
// Discord logs
|
||
|
$("#settings-areDiscordLogsActive").prop("checked", fullConfig.areDiscordLogsActive);
|
||
|
$("#settings-mainDiscordWebhook").val(fullConfig.mainDiscordWebhook);
|
||
|
|
||
|
toggleDiscordLogsInSettings(fullConfig.areDiscordLogsActive);
|
||
|
|
||
|
for(const[logType, webhook] of Object.entries(fullConfig.specificWebhooks)) {
|
||
|
$("#settings-specific-webooks-div").find(`[data-log-type="${logType}"]`).val(webhook);
|
||
|
}
|
||
|
// Discord logs - END
|
||
|
|
||
|
// Player dealership
|
||
|
$("#settings-minutes-to-receive-vehicle-after-order").val(fullConfig.minutesToReceiveVehicleAfterOrder);
|
||
|
$("#settings-persistent-displayed-vehicles").prop("checked", fullConfig.persistentDisplayedVehicles);
|
||
|
}
|
||
|
|
||
|
$("#settings").submit(async function(event) {
|
||
|
if(isThereAnyErrorInForm(event)) return;
|
||
|
|
||
|
let clientSettings = {
|
||
|
helpNotification: $("#settings-help-notification-script").val(),
|
||
|
}
|
||
|
|
||
|
let sharedSettings = {
|
||
|
locale: $("#settings-locale").val(),
|
||
|
}
|
||
|
|
||
|
let serverSettings = {
|
||
|
// Generic
|
||
|
acePermission: $("#settings-ace-permission").val(),
|
||
|
canAlwaysCarryItem: $("#settings-can-always-carry").prop("checked"),
|
||
|
|
||
|
// Discord logs
|
||
|
areDiscordLogsActive: $("#settings-areDiscordLogsActive").prop("checked"),
|
||
|
mainDiscordWebhook: $("#settings-mainDiscordWebhook").val(),
|
||
|
specificWebhooks: getSeparatedDiscordWebhooks(),
|
||
|
|
||
|
// Player dealership
|
||
|
minutesToReceiveVehicleAfterOrder: parseInt( $("#settings-minutes-to-receive-vehicle-after-order").val() ),
|
||
|
persistentDisplayedVehicles: $("#settings-persistent-displayed-vehicles").prop("checked"),
|
||
|
}
|
||
|
|
||
|
const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({
|
||
|
clientSettings: clientSettings,
|
||
|
serverSettings: serverSettings,
|
||
|
sharedSettings: sharedSettings
|
||
|
}));
|
||
|
showServerResponse(response);
|
||
|
|
||
|
refreshTranslations(sharedSettings.locale);
|
||
|
});
|
||
|
|
||
|
/*
|
||
|
█████ ██████ ███ ███ ██ ███ ██ ██████ ███████ █████ ██ ███████ ██████ ███████ ██ ██ ██ ██████ ███████
|
||
|
██ ██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||
|
███████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ █████ ███████ ██ █████ ██████ ███████ ███████ ██ ██████ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||
|
██ ██ ██████ ██ ██ ██ ██ ████ ██████ ███████ ██ ██ ███████ ███████ ██ ██ ███████ ██ ██ ██ ██ ███████
|
||
|
*/
|
||
|
let dealershipsDatatable = $("#dealerships-container").DataTable( {
|
||
|
"lengthMenu": [10, 15, 20],
|
||
|
"createdRow": function ( row, data, index ) {
|
||
|
$(row).addClass("clickable");
|
||
|
|
||
|
$(row).click(function() {
|
||
|
let id = parseInt( data[0] );
|
||
|
editDealership(id);
|
||
|
})
|
||
|
},
|
||
|
});
|
||
|
|
||
|
let dealerships = {};
|
||
|
|
||
|
async function loadDealerships() {
|
||
|
const rawDealerships = await $.post(`https://${resName}/getAllDealerships`);
|
||
|
|
||
|
// Manually create the table to avoid incompatibilities due table indexing
|
||
|
dealerships = {};
|
||
|
|
||
|
for(const[k, dealershipData] of Object.entries(rawDealerships)) {
|
||
|
dealerships[dealershipData.id] = dealershipData;
|
||
|
}
|
||
|
|
||
|
dealershipsDatatable.clear();
|
||
|
|
||
|
for(const[id, dealershipData] of Object.entries(dealerships)) {
|
||
|
dealershipsDatatable.row.add([
|
||
|
id,
|
||
|
dealershipData.label
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
dealershipsDatatable.draw();
|
||
|
}
|
||
|
|
||
|
function setDefaultDataOfDealership() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
// Generic
|
||
|
$(`input[name=dealership-type][value="auto"]`).prop("checked", true).change();
|
||
|
|
||
|
$("#dealership-label").val("Default");
|
||
|
dealershipModal.data("markerData", getDefaultMarkerCustomization());
|
||
|
dealershipModal.data("blipData", getDefaultBlipCustomization());
|
||
|
dealershipModal.data("vehiclesData", null);
|
||
|
$("#dealership-account-name").val("");
|
||
|
$("#dealership-account-name").val("bank");
|
||
|
|
||
|
// Coordinates
|
||
|
$("#auto-dealership-coords-list").empty();
|
||
|
|
||
|
// Spawn points
|
||
|
$("#dealership-spawn-points-list").empty();
|
||
|
|
||
|
// Showroom
|
||
|
$("#dealership-showroom-coords-x").val("");
|
||
|
$("#dealership-showroom-coords-y").val("");
|
||
|
$("#dealership-showroom-coords-z").val("");
|
||
|
$("#dealership-showroom-heading").val("");
|
||
|
|
||
|
// Restrictions
|
||
|
dealershipModal.data("jobsData", null);
|
||
|
setRequiredLicenseForDealership(null);
|
||
|
|
||
|
// Options
|
||
|
$("#dealership-pay-with-society-money").prop("checked", false).change();
|
||
|
$("#dealership-always-open").prop("checked", true).change();
|
||
|
$("#dealership-minutes-before-prices-update").val(0);
|
||
|
$("#dealership-is-resell-active").prop("checked", false).change();
|
||
|
$("#dealership-resell-percentage").val("");
|
||
|
dealershipModal.data("resellPointMarkerData", getDefaultResellCustomization());
|
||
|
setSelectedSocietiesForDealership(false);
|
||
|
|
||
|
// Resell points
|
||
|
$("#dealership-resell-points-list").empty();
|
||
|
|
||
|
// Test drive data
|
||
|
$("#dealership-is-test-drive-active").prop("checked", false).change();
|
||
|
$("#dealership-test-drive-duration").val("");
|
||
|
$("#dealership-test-drive-change-routing-bucket").prop("checked", false);
|
||
|
$("#dealership-test-drive-coords-x").val("");
|
||
|
$("#dealership-test-drive-coords-y").val("");
|
||
|
$("#dealership-test-drive-coords-z").val("");
|
||
|
|
||
|
// Player dealership
|
||
|
$("#player-dealership-price").val("");
|
||
|
$("#player-dealership-resell-percentage").val("");
|
||
|
|
||
|
$("#player-dealership-coords-x").val("");
|
||
|
$("#player-dealership-coords-y").val("");
|
||
|
$("#player-dealership-coords-z").val("");
|
||
|
|
||
|
$("#dealership-enter-showroom-coords-x").val("");
|
||
|
$("#dealership-enter-showroom-coords-y").val("");
|
||
|
$("#dealership-enter-showroom-coords-z").val("");
|
||
|
|
||
|
// Display points
|
||
|
$("#player-dealership-display-points-list").empty();
|
||
|
}
|
||
|
|
||
|
$("#new-dealership-btn").click(function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
// Converts from edit modal to create modal
|
||
|
dealershipModal.data("action", "create");
|
||
|
|
||
|
$("#delete-dealership-btn").hide();
|
||
|
$("#save-dealership-btn").text( getLocalizedText("menu:create") );
|
||
|
|
||
|
setDefaultDataOfDealership();
|
||
|
|
||
|
dealershipModal.modal("show");
|
||
|
})
|
||
|
|
||
|
$("#dealership-customize-blip-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldBlipData = dealershipModal.data("blipData");
|
||
|
let blipData = await blipDialog(oldBlipData)
|
||
|
|
||
|
dealershipModal.data("blipData", blipData);
|
||
|
});
|
||
|
|
||
|
$("#dealership-customize-marker-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldMarkerData = dealershipModal.data("markerData");
|
||
|
let markerData = await markerDialog(oldMarkerData)
|
||
|
|
||
|
dealershipModal.data("markerData", markerData);
|
||
|
});
|
||
|
|
||
|
$("#dealership-choose-vehicles-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldVehicles = dealershipModal.data("vehiclesData");
|
||
|
let vehicles = await vehiclesDialog(oldVehicles, true);
|
||
|
|
||
|
dealershipModal.data("vehiclesData", vehicles);
|
||
|
});
|
||
|
|
||
|
$("#dealership-choose-account-btn").click(async function() {
|
||
|
const accountName = await accountsDialog();
|
||
|
|
||
|
$("#dealership-account-name").val(accountName);
|
||
|
});
|
||
|
|
||
|
$("#dealership-choose-jobs-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldJobs = dealershipModal.data("jobsData");
|
||
|
let jobs = await jobsDialog(oldJobs);
|
||
|
|
||
|
dealershipModal.data("jobsData", jobs);
|
||
|
})
|
||
|
|
||
|
function setRequiredLicenseForDealership(licenseType) {
|
||
|
const btn = $("#dealership-choose-required-license-btn");
|
||
|
if(licenseType) {
|
||
|
btn.text(getLocalizedText("menu:license_required") + licenseType);
|
||
|
} else {
|
||
|
btn.text(getLocalizedText("menu:no_license_required"));
|
||
|
}
|
||
|
|
||
|
btn.data("licenseType", licenseType ? licenseType : null);
|
||
|
}
|
||
|
|
||
|
$("#dealership-choose-required-license-btn").click(async function() {
|
||
|
const requiredLicenseType = await licensesDialog();
|
||
|
setRequiredLicenseForDealership(requiredLicenseType);
|
||
|
});
|
||
|
|
||
|
$("#dealership-societies-to-send-money-to-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldSocieties = dealershipModal.data("societiesData");
|
||
|
let societies = await societiesDialog(oldSocieties);
|
||
|
|
||
|
setSelectedSocietiesForDealership(societies);
|
||
|
})
|
||
|
|
||
|
async function setSelectedPayingSociety(jobName) {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
dealershipModal.data("payingSociety", jobName);
|
||
|
|
||
|
const label = jobName ? await getJobLabel(jobName) : getLocalizedText("menu:none");
|
||
|
$("#dealership-paying-society").val(label);
|
||
|
}
|
||
|
|
||
|
$("#dealership-pay-with-society-money").change(function() {
|
||
|
let enabled = $(this).prop("checked");
|
||
|
|
||
|
$("#dealership-choose-paying-society-btn").prop("disabled", !enabled);
|
||
|
$("#dealership-account-name-div").toggle(!enabled);
|
||
|
|
||
|
const loanInput = $("#dealership-loan-is-active");
|
||
|
|
||
|
loanInput.prop("disabled", enabled)
|
||
|
|
||
|
if(enabled) {
|
||
|
loanInput.prop("checked", false).change();
|
||
|
}
|
||
|
|
||
|
if(!enabled) {
|
||
|
setSelectedPayingSociety(null);
|
||
|
}
|
||
|
})
|
||
|
|
||
|
$("#dealership-choose-paying-society-btn").click(async function() {
|
||
|
let jobName = await singleJobDialog();
|
||
|
setSelectedPayingSociety(jobName);
|
||
|
})
|
||
|
|
||
|
async function setSelectedSocietiesForDealership(societies) {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
dealershipModal.data("societiesData", societies);
|
||
|
|
||
|
if(!societies) {
|
||
|
$("#dealership-societies-to-send-money-to").val( getLocalizedText("menu:none") );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let jobNames = "";
|
||
|
let isTheFirst = true;
|
||
|
|
||
|
for(const [societyName, percentage] of Object.entries(societies)) {
|
||
|
if(!isTheFirst) {
|
||
|
jobNames += ", ";
|
||
|
} else {
|
||
|
isTheFirst = false;
|
||
|
}
|
||
|
|
||
|
jobNames += await getJobLabel(societyName) + " (" + percentage + "%)";
|
||
|
}
|
||
|
|
||
|
$("#dealership-societies-to-send-money-to").val(jobNames);
|
||
|
}
|
||
|
|
||
|
$("#dealership-loan-is-active").change(function() {
|
||
|
const enabled = $(this).prop("checked");
|
||
|
|
||
|
$("#dealership-loan-percentage").prop("disabled", !enabled).prop("required", enabled);
|
||
|
$("#dealership-loan-interval").prop("disabled", !enabled).prop("required", enabled);
|
||
|
});
|
||
|
|
||
|
$("#dealership-is-resell-active").change(function() {
|
||
|
const enabled = $(this).prop("checked");
|
||
|
|
||
|
$("#dealership-resell-percentage").prop("disabled", !enabled).prop("required", enabled);
|
||
|
$("#dealership-resell-point-customize-marker-btn").prop("disabled", !enabled);
|
||
|
$("#dealership-resell-div").toggle(enabled);
|
||
|
});
|
||
|
|
||
|
$("#dealership-resell-point-customize-marker-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
let oldMarkerData = dealershipModal.data("resellPointMarkerData");
|
||
|
let markerData = await markerDialog(oldMarkerData)
|
||
|
|
||
|
dealershipModal.data("resellPointMarkerData", markerData);
|
||
|
});
|
||
|
|
||
|
$("#dealership-is-test-drive-active").change(function() {
|
||
|
const enabled = $(this).prop("checked");
|
||
|
|
||
|
$("#dealership-test-drive-duration").prop("disabled", !enabled).prop("required", enabled)
|
||
|
$("#dealership-test-drive-change-routing-bucket").prop("disabled", !enabled)
|
||
|
$("#dealership-test-drive-coords-x").prop("disabled", !enabled).prop("required", enabled)
|
||
|
$("#dealership-test-drive-coords-y").prop("disabled", !enabled).prop("required", enabled)
|
||
|
$("#dealership-test-drive-coords-z").prop("disabled", !enabled).prop("required", enabled)
|
||
|
$("#dealership-test-drive-heading").prop("disabled", !enabled).prop("required", enabled)
|
||
|
$("#dealership-test-drive-current-coords-btn").prop("disabled", !enabled)
|
||
|
})
|
||
|
|
||
|
$("#dealership-test-drive-current-coords-btn").click(async function() {
|
||
|
let data = await chooseCoords();
|
||
|
if(!data) return;
|
||
|
|
||
|
$("#dealership-test-drive-coords-x").val(data.coords.x);
|
||
|
$("#dealership-test-drive-coords-y").val(data.coords.y);
|
||
|
$("#dealership-test-drive-coords-z").val(data.coords.z);
|
||
|
$("#dealership-test-drive-heading").val(data.heading);
|
||
|
});
|
||
|
|
||
|
function addPointToPointsList(listDiv, wantsHeading, wantsRadius, pointData) {
|
||
|
let div = $(`
|
||
|
<div class="d-flex gap-1 align-items-center justify-content-center my-2 coords-div">
|
||
|
<button type="button" class="btn-close delete-coords-btn me-2"></button>
|
||
|
|
||
|
<div class="form-floating text-body col">
|
||
|
<input type="number" step="0.01" class="form-control form-control-sm coords-x" placeholder="X" required>
|
||
|
<label>${getLocalizedText("menu:x")}</label>
|
||
|
</div>
|
||
|
|
||
|
<div class="form-floating text-body col">
|
||
|
<input type="number" step="0.01" class="form-control form-control-sm coords-y" placeholder="Y" required>
|
||
|
<label>${getLocalizedText("menu:y")}</label>
|
||
|
</div>
|
||
|
|
||
|
<div class="form-floating text-body col">
|
||
|
<input type="number" step="0.01" class="form-control form-control-sm coords-z" placeholder="Z" required>
|
||
|
<label>${getLocalizedText("menu:z")}</label>
|
||
|
</div>
|
||
|
|
||
|
<div class="form-floating text-body col heading-div">
|
||
|
<input type="number" step="0.01" class="form-control form-control-sm heading" placeholder="Heading" required>
|
||
|
<label>${getLocalizedText("menu:heading")}</label>
|
||
|
</div>
|
||
|
|
||
|
<div class="form-floating text-body col radius-div">
|
||
|
<input type="number" class="form-control form-control-sm radius" value="5" placeholder="Radius" required>
|
||
|
<label>${getLocalizedText("menu:radius")}</label>
|
||
|
</div>
|
||
|
|
||
|
<button type="button" class="btn btn-secondary col-auto current-coords-btn" data-bs-toggle="tooltip" data-bs-placement="top" title="${getLocalizedText("menu:choose_coords")}"><i class="bi bi-arrow-down-square"></i></button>
|
||
|
</div>
|
||
|
`)
|
||
|
|
||
|
if(!wantsHeading) {
|
||
|
div.find(".heading-div").remove();
|
||
|
}
|
||
|
|
||
|
if(!wantsRadius) {
|
||
|
div.find(".radius-div").remove();
|
||
|
}
|
||
|
|
||
|
div.find(".current-coords-btn").click(async function() {
|
||
|
let data = await chooseCoords();
|
||
|
if(!data) return;
|
||
|
|
||
|
div.find(".coords-x").val(data.coords.x);
|
||
|
div.find(".coords-y").val(data.coords.y);
|
||
|
div.find(".coords-z").val(data.coords.z);
|
||
|
div.find(".heading").val(data.heading);
|
||
|
}).tooltip();
|
||
|
|
||
|
div.find(".delete-coords-btn").click(function() {
|
||
|
div.remove();
|
||
|
});
|
||
|
|
||
|
if(pointData) {
|
||
|
let coords = null;
|
||
|
|
||
|
if(wantsHeading || wantsRadius) {
|
||
|
coords = pointData.coords;
|
||
|
div.find(".heading").val(pointData.heading);
|
||
|
div.find(".radius").val(pointData.radius);
|
||
|
} else {
|
||
|
coords = pointData;
|
||
|
}
|
||
|
|
||
|
div.find(".coords-x").val(coords.x);
|
||
|
div.find(".coords-y").val(coords.y);
|
||
|
div.find(".coords-z").val(coords.z);
|
||
|
}
|
||
|
|
||
|
listDiv.append(div);
|
||
|
}
|
||
|
|
||
|
function setPointToPointsList(listDiv, wantsHeading, wantsRadius, pointsList) {
|
||
|
listDiv.empty();
|
||
|
|
||
|
if(!pointsList) return;
|
||
|
|
||
|
for(const pointData of pointsList) {
|
||
|
addPointToPointsList(listDiv, wantsHeading, wantsRadius, pointData);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getPointFromPointsList(listDiv) {
|
||
|
let pointsList = [];
|
||
|
|
||
|
listDiv.find(".coords-div").each(function() {
|
||
|
const coords = {
|
||
|
x: parseFloat( $(this).find(".coords-x").val() ),
|
||
|
y: parseFloat( $(this).find(".coords-y").val() ),
|
||
|
z: parseFloat( $(this).find(".coords-z").val() ),
|
||
|
}
|
||
|
|
||
|
const headingInput = $(this).find(".heading");
|
||
|
const radiusInput = $(this).find(".radius");
|
||
|
|
||
|
if(headingInput.prop("required")) {
|
||
|
const heading = parseFloat( headingInput.val() );
|
||
|
const radius = parseFloat( radiusInput.val() );
|
||
|
|
||
|
pointsList.push({
|
||
|
coords,
|
||
|
heading,
|
||
|
radius
|
||
|
});
|
||
|
} else {
|
||
|
pointsList.push(coords);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
return pointsList;
|
||
|
}
|
||
|
|
||
|
$("#dealership-add-coordinates-btn").click(function() {
|
||
|
const div = $("#auto-dealership-coords-list");
|
||
|
addPointToPointsList(div);
|
||
|
});
|
||
|
|
||
|
$("#player-dealership-current-coords-btn").click(async function() {
|
||
|
let data = await chooseCoords();
|
||
|
if(!data) return;
|
||
|
|
||
|
$("#player-dealership-coords-x").val(data.coords.x);
|
||
|
$("#player-dealership-coords-y").val(data.coords.y);
|
||
|
$("#player-dealership-coords-z").val(data.coords.z);
|
||
|
});
|
||
|
|
||
|
$("#dealership-add-spawnpoint-btn").click(async function() {
|
||
|
const div = $("#dealership-spawn-points-list");
|
||
|
addPointToPointsList(div, true, true);
|
||
|
});
|
||
|
|
||
|
$("#dealership-add-resell-point-btn").click(async function() {
|
||
|
const div = $("#dealership-resell-points-list");
|
||
|
addPointToPointsList(div, false, false);
|
||
|
});
|
||
|
|
||
|
$("#dealership-add-display-point-btn").click(async function() {
|
||
|
const div = $("#player-dealership-display-points-list");
|
||
|
addPointToPointsList(div, true, true);
|
||
|
});
|
||
|
|
||
|
$("#dealership-enter-showroom-current-coords-btn").click(async function() {
|
||
|
let data = await chooseCoords();
|
||
|
if(!data) return;
|
||
|
|
||
|
$("#dealership-enter-showroom-coords-x").val(data.coords.x);
|
||
|
$("#dealership-enter-showroom-coords-y").val(data.coords.y);
|
||
|
$("#dealership-enter-showroom-coords-z").val(data.coords.z);
|
||
|
});
|
||
|
|
||
|
$("#dealership-showroom-current-coords-btn").click(async function() {
|
||
|
let data = await chooseCoords();
|
||
|
if(!data) return;
|
||
|
|
||
|
$("#dealership-showroom-coords-x").val(data.coords.x);
|
||
|
$("#dealership-showroom-coords-y").val(data.coords.y);
|
||
|
$("#dealership-showroom-coords-z").val(data.coords.z);
|
||
|
$("#dealership-showroom-heading").val(data.heading);
|
||
|
});
|
||
|
|
||
|
function toggleAutoDealershipFields(hasToShow) {
|
||
|
$("#dealership-account-name-div").toggle(hasToShow);
|
||
|
$("#dealership-account-name").prop("required", hasToShow);
|
||
|
|
||
|
$("#auto-dealership-coords-div").toggle(hasToShow);
|
||
|
$("#auto-dealership-coords-list").find("input").prop("required", hasToShow);
|
||
|
|
||
|
$("#dealership-restrictions-div").toggle(hasToShow);
|
||
|
$("#dealership-paying-society-div").toggle(hasToShow);
|
||
|
|
||
|
$("#dealership-resell-points-div").toggle(hasToShow);
|
||
|
$("#dealership-is-resell-active").prop("checked");
|
||
|
|
||
|
// options to disable to avoid issues when switching to player dealership
|
||
|
if(!hasToShow) {
|
||
|
$("#dealership-pay-with-society-money").prop("checked", false).change();
|
||
|
$("#dealership-is-resell-active").prop("checked", false).change();
|
||
|
$("#dealership-resell-points-list").empty();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function togglePlayerOwnedDealershipField(hasToShow) {
|
||
|
$("#player-dealership-coords-div").toggle(hasToShow);
|
||
|
$("#player-dealership-coords-div").find("input").prop("required", hasToShow);
|
||
|
|
||
|
$("#player-dealership-purchase-div").toggle(hasToShow);
|
||
|
$("#player-dealership-purchase-div").find("input").prop("required", hasToShow);
|
||
|
|
||
|
$("#player-dealership-display-div").toggle(hasToShow);
|
||
|
$("#player-dealership-display-div").find("input").prop("required", hasToShow);
|
||
|
|
||
|
$("#player-dealership-enter-showroom-div").toggle(hasToShow);
|
||
|
$("#player-dealership-enter-showroom-div").find("input").prop("required", hasToShow);
|
||
|
}
|
||
|
|
||
|
$("input[name=dealership-type]").change(function() {
|
||
|
const type = $(this).val();
|
||
|
|
||
|
toggleAutoDealershipFields(type == "auto");
|
||
|
togglePlayerOwnedDealershipField(type == "player");
|
||
|
});
|
||
|
|
||
|
function setSharedDealershipData(data) {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
// Generic
|
||
|
dealershipModal.data("blipData", data.blipData);
|
||
|
dealershipModal.data("markerData", data.markerData);
|
||
|
dealershipModal.data("vehiclesData", data.vehiclesData);
|
||
|
$("#dealership-account-name").val(data.accountName);
|
||
|
|
||
|
// Spawn points
|
||
|
setPointToPointsList($("#dealership-spawn-points-list"), true, true, data.spawnPointsList);
|
||
|
|
||
|
// Showroom
|
||
|
$("#dealership-showroom-coords-x").val(data.showroomPoint.coords.x);
|
||
|
$("#dealership-showroom-coords-y").val(data.showroomPoint.coords.y);
|
||
|
$("#dealership-showroom-coords-z").val(data.showroomPoint.coords.z);
|
||
|
$("#dealership-showroom-heading").val(data.showroomPoint.heading);
|
||
|
|
||
|
// Options
|
||
|
dealershipModal.data("societiesData", data.societiesToSendMoneyTo);
|
||
|
$("#dealership-pay-with-society-money").prop("checked", data.payWithSocietyMoney).change();
|
||
|
|
||
|
// Loan data
|
||
|
$("#dealership-loan-is-active").prop("checked", data.loanData.isActive).change();
|
||
|
$("#dealership-loan-percentage").val(data.loanData.percentage).change();
|
||
|
$("#dealership-loan-interval").val(data.loanData.intervalDays);
|
||
|
|
||
|
// Test drive data
|
||
|
$("#dealership-is-test-drive-active").prop("checked", data.testDriveData.isActive).change();
|
||
|
$("#dealership-test-drive-duration").val(data.testDriveData.duration);
|
||
|
$("#dealership-test-drive-change-routing-bucket").prop("checked", data.testDriveData.changeRoutingBucket);
|
||
|
$("#dealership-test-drive-coords-x").val(data.testDriveData.pointData.coords.x);
|
||
|
$("#dealership-test-drive-coords-y").val(data.testDriveData.pointData.coords.y);
|
||
|
$("#dealership-test-drive-coords-z").val(data.testDriveData.pointData.coords.z);
|
||
|
$("#dealership-test-drive-heading").val(data.testDriveData.pointData.heading);
|
||
|
}
|
||
|
|
||
|
function setAutoDealershipData(data) {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
// Coordinates
|
||
|
setPointToPointsList($("#auto-dealership-coords-list"), false, false, data.coordinatesList);
|
||
|
|
||
|
// Restrictions
|
||
|
dealershipModal.data("jobsData", data.jobsData);
|
||
|
setRequiredLicenseForDealership(data.requiredLicense)
|
||
|
|
||
|
// Options
|
||
|
dealershipModal.data("payingSociety", data.payingSociety);
|
||
|
|
||
|
// Resell data
|
||
|
$("#dealership-is-resell-active").prop("checked", data.resellData.isActive).change();
|
||
|
$("#dealership-resell-percentage").val(data.resellData.percentage);
|
||
|
setPointToPointsList($("#dealership-resell-points-list"), false, false, data.resellData.points);
|
||
|
dealershipModal.data("resellPointMarkerData", data.resellData.markerData);
|
||
|
}
|
||
|
|
||
|
function setPlayerDealershipData(data) {
|
||
|
// Generic
|
||
|
$("#player-dealership-price").val(data.price);
|
||
|
$("#player-dealership-resell-percentage").val(data.resellPercentage);
|
||
|
|
||
|
// Coordinates
|
||
|
$("#player-dealership-coords-x").val(data.coordinates.x);
|
||
|
$("#player-dealership-coords-y").val(data.coordinates.y);
|
||
|
$("#player-dealership-coords-z").val(data.coordinates.z);
|
||
|
|
||
|
// Display points
|
||
|
setPointToPointsList($("#player-dealership-display-points-list"), true, true, data.displayPointsList);
|
||
|
|
||
|
// Enter showroom coords
|
||
|
$("#dealership-enter-showroom-coords-x").val(data.enterShowroomCoords.x);
|
||
|
$("#dealership-enter-showroom-coords-y").val(data.enterShowroomCoords.y);
|
||
|
$("#dealership-enter-showroom-coords-z").val(data.enterShowroomCoords.z);
|
||
|
}
|
||
|
|
||
|
function editDealership(id) {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
const dealershipInfo = dealerships[id];
|
||
|
|
||
|
dealershipModal.data("dealershipId", id);
|
||
|
dealershipModal.data("action", "edit");
|
||
|
|
||
|
$("#delete-dealership-btn").show();
|
||
|
$("#save-dealership-btn").text(getLocalizedText("menu:confirm"));
|
||
|
|
||
|
const data = dealershipInfo.data;
|
||
|
|
||
|
// Generic
|
||
|
$("#dealership-label").val(dealershipInfo.label);
|
||
|
|
||
|
setSharedDealershipData(data);
|
||
|
|
||
|
if(dealershipInfo.type == "auto") {
|
||
|
setAutoDealershipData(data);
|
||
|
} else {
|
||
|
setPlayerDealershipData(data);
|
||
|
}
|
||
|
|
||
|
// As last input, so all elements are already added to the DOM
|
||
|
$(`input[name=dealership-type][value=${dealershipInfo.type}]`).prop("checked", true).change();
|
||
|
|
||
|
dealershipModal.modal("show");
|
||
|
}
|
||
|
|
||
|
function getSharedDealershipData() {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
return {
|
||
|
// Generic
|
||
|
blipData: dealershipModal.data("blipData"),
|
||
|
markerData: dealershipModal.data("markerData"),
|
||
|
vehiclesData: dealershipModal.data("vehiclesData"),
|
||
|
accountName: $("#dealership-account-name").val(),
|
||
|
|
||
|
// Spawn points
|
||
|
spawnPointsList: getPointFromPointsList( $("#dealership-spawn-points-list") ),
|
||
|
|
||
|
// Showroom
|
||
|
showroomPoint: {
|
||
|
coords: {
|
||
|
x: parseFloat( $("#dealership-showroom-coords-x").val() ),
|
||
|
y: parseFloat( $("#dealership-showroom-coords-y").val() ),
|
||
|
z: parseFloat( $("#dealership-showroom-coords-z").val() ),
|
||
|
},
|
||
|
heading: parseFloat( $("#dealership-showroom-heading").val() ),
|
||
|
},
|
||
|
|
||
|
// Options
|
||
|
societiesToSendMoneyTo: dealershipModal.data("societiesData"),
|
||
|
payWithSocietyMoney: $("#dealership-pay-with-society-money").prop("checked"),
|
||
|
|
||
|
loanData: {
|
||
|
isActive: $("#dealership-loan-is-active").prop("checked"),
|
||
|
percentage: parseInt( $("#dealership-loan-percentage").val() ),
|
||
|
intervalDays: parseInt( $("#dealership-loan-interval").val() )
|
||
|
},
|
||
|
|
||
|
testDriveData: {
|
||
|
isActive: $("#dealership-is-test-drive-active").prop("checked"),
|
||
|
duration: parseInt( $("#dealership-test-drive-duration").val() ),
|
||
|
changeRoutingBucket: $("#dealership-test-drive-change-routing-bucket").prop("checked"),
|
||
|
pointData: {
|
||
|
coords: {
|
||
|
x: parseFloat( $("#dealership-test-drive-coords-x").val() ),
|
||
|
y: parseFloat( $("#dealership-test-drive-coords-y").val() ),
|
||
|
z: parseFloat( $("#dealership-test-drive-coords-z").val() ),
|
||
|
},
|
||
|
heading: parseFloat( $("#dealership-test-drive-heading").val() ),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getAutoDealershipData() {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
|
||
|
const sharedData = getSharedDealershipData();
|
||
|
const data = {
|
||
|
// Coordinates
|
||
|
coordinatesList: getPointFromPointsList( $("#auto-dealership-coords-list") ),
|
||
|
|
||
|
// Restrictions
|
||
|
jobsData: dealershipModal.data("jobsData"),
|
||
|
requiredLicense: $("#dealership-choose-required-license-btn").data("licenseType"),
|
||
|
|
||
|
// Options
|
||
|
payingSociety: dealershipModal.data("payingSociety"),
|
||
|
resellData: {
|
||
|
isActive: $("#dealership-is-resell-active").prop("checked"),
|
||
|
percentage: parseInt( $("#dealership-resell-percentage").val() ),
|
||
|
points: getPointFromPointsList( $("#dealership-resell-points-list") ),
|
||
|
markerData: dealershipModal.data("resellPointMarkerData")
|
||
|
},
|
||
|
}
|
||
|
|
||
|
return {...sharedData, ...data}
|
||
|
}
|
||
|
|
||
|
function getPlayerDealershipData() {
|
||
|
const sharedData = getSharedDealershipData();
|
||
|
const data = {
|
||
|
// Generic
|
||
|
price: parseInt( $("#player-dealership-price").val() ),
|
||
|
resellPercentage: parseInt( $("#player-dealership-resell-percentage").val() ),
|
||
|
|
||
|
// Coordinates
|
||
|
coordinates: {
|
||
|
x: parseFloat( $("#player-dealership-coords-x").val() ),
|
||
|
y: parseFloat( $("#player-dealership-coords-y").val() ),
|
||
|
z: parseFloat( $("#player-dealership-coords-z").val() ),
|
||
|
},
|
||
|
|
||
|
// Display points
|
||
|
displayPointsList: getPointFromPointsList( $("#player-dealership-display-points-list") ),
|
||
|
|
||
|
// Enter showroom coords
|
||
|
enterShowroomCoords: {
|
||
|
x: parseFloat( $("#dealership-enter-showroom-coords-x").val() ),
|
||
|
y: parseFloat( $("#dealership-enter-showroom-coords-y").val() ),
|
||
|
z: parseFloat( $("#dealership-enter-showroom-coords-z").val() ),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {...sharedData, ...data}
|
||
|
}
|
||
|
|
||
|
$("#dealership-form").submit(async function(event) {
|
||
|
if(isThereAnyErrorInForm(event)) return;
|
||
|
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
let action = dealershipModal.data("action");
|
||
|
|
||
|
const dealershipType = $("input[name=dealership-type]:checked").val();
|
||
|
|
||
|
let dealershipInfo = {
|
||
|
label: $("#dealership-label").val(),
|
||
|
type: dealershipType,
|
||
|
|
||
|
data: dealershipType == "auto" ? getAutoDealershipData() : getPlayerDealershipData()
|
||
|
}
|
||
|
|
||
|
let success = null;
|
||
|
|
||
|
switch(action) {
|
||
|
case "create": {
|
||
|
success = await $.post(`https://${resName}/createDealership`, JSON.stringify(dealershipInfo));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "edit": {
|
||
|
success = await $.post(`https://${resName}/updateDealership`, JSON.stringify({dealershipId: dealershipModal.data("dealershipId"), dealershipInfo: dealershipInfo}));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!success) return;
|
||
|
|
||
|
dealershipModal.modal("hide");
|
||
|
loadDealerships();
|
||
|
})
|
||
|
|
||
|
$("#delete-dealership-btn").click(async function() {
|
||
|
let dealershipModal = $("#dealership-modal");
|
||
|
let dealershipId = dealershipModal.data("dealershipId");
|
||
|
|
||
|
const success = await $.post(`https://${resName}/deleteDealership`, JSON.stringify({dealershipId: dealershipId}));
|
||
|
if(!success) return;
|
||
|
|
||
|
dealershipModal.modal("hide");
|
||
|
loadDealerships();
|
||
|
});
|
||
|
|
||
|
$("#import-dealership-btn").click(async function() {
|
||
|
const dealershipModal = $("#dealership-modal");
|
||
|
const dealershipId = dealershipModal.data("dealershipId");
|
||
|
|
||
|
const importedData = await dealershipsDialog();
|
||
|
|
||
|
const oldAction = dealershipModal.data("action"); // To remember if it's an edit or create
|
||
|
|
||
|
dealerships[dealershipId] = importedData;
|
||
|
editDealership(dealershipId);
|
||
|
dealershipModal.data("action", oldAction);
|
||
|
})
|
||
|
|
||
|
$(document).keyup(function(e) {
|
||
|
if (e.key === "Escape") {
|
||
|
exitShowroom();
|
||
|
closeMenu();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/*
|
||
|
██ ██ ███████ ██ ██ ██ ██████ ██ ███████ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||
|
██ ██ █████ ███████ ██ ██ ██ █████ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||
|
████ ███████ ██ ██ ██ ██████ ███████ ███████ ███████
|
||
|
*/
|
||
|
|
||
|
async function takeVehicleImage(spawnName) {
|
||
|
$('html').hide();
|
||
|
await $.post(`https://${resName}/takeVehicleImage`, JSON.stringify({spawnName}));
|
||
|
$('html').show();
|
||
|
}
|
||
|
|
||
|
async function deleteVehicle(spawnName) {
|
||
|
if(!await confirmDeletion()) return;
|
||
|
|
||
|
const response = await $.post(`https://${resName}/deleteVehicle`, JSON.stringify({spawnName}));
|
||
|
showServerResponse(response);
|
||
|
|
||
|
if(response === true) {
|
||
|
loadVehicles();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let vehiclesDatatable = $("#vehicles-container").DataTable( {
|
||
|
"lengthMenu": [15, 30, 50],
|
||
|
"order": [
|
||
|
[ $('th[data-translation-id="menu:valid"]').index(), 'desc' ],
|
||
|
[ $('th[data-translation-id="menu:spawn_name"]').index(), 'asc' ]
|
||
|
],
|
||
|
"columnDefs": [
|
||
|
{
|
||
|
"targets": -1, // Last column
|
||
|
"data": null,
|
||
|
"className": "col-1",
|
||
|
"defaultContent": `
|
||
|
<div class="d-inline-flex gap-3">
|
||
|
<button class='btn btn-danger py-0 px-2 delete-vehicle-btn' data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class=\"bi bi-trash\"></i></button>
|
||
|
<button class='btn btn-info py-0 px-2 take-image-btn' data-bs-toggle="tooltip" data-bs-placement="top" title="Take image"><i class=\"bi bi-image\"></i></button>
|
||
|
</div>
|
||
|
`
|
||
|
},
|
||
|
{
|
||
|
"targets": -3, // 'type' column
|
||
|
"className": "col-1",
|
||
|
}
|
||
|
],
|
||
|
"createdRow": function (row, data, index) {
|
||
|
$('td', row).css('white-space', 'nowrap').addClass("py-3");
|
||
|
|
||
|
let vehicleData = data[data.length - 1];
|
||
|
|
||
|
$(row).find(".delete-vehicle-btn").click(function() {
|
||
|
deleteVehicle(vehicleData.spawnName);
|
||
|
}).tooltip();
|
||
|
|
||
|
$(row).find(".take-image-btn").click(function() {
|
||
|
takeVehicleImage(vehicleData.spawnName);
|
||
|
}).tooltip();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
let vehicles = {};
|
||
|
|
||
|
async function loadVehicles() {
|
||
|
const rawVehicles = await $.post(`https://${resName}/getAllVehicles`);
|
||
|
|
||
|
// Manually create the table to avoid incompatibilities due table indexing
|
||
|
vehicles = {};
|
||
|
|
||
|
for(const[k, vehicleData] of Object.entries(rawVehicles)) {
|
||
|
vehicles[vehicleData.spawnName] = vehicleData;
|
||
|
}
|
||
|
|
||
|
vehiclesDatatable.clear();
|
||
|
|
||
|
for(const[id, vehicleData] of Object.entries(vehicles)) {
|
||
|
const spawnName = vehicleData.isValid
|
||
|
? vehicleData.spawnName
|
||
|
: `<span class="text-danger fw-bold">${vehicleData.spawnName}</span>`;
|
||
|
|
||
|
vehiclesDatatable.row.add([
|
||
|
spawnName ?? "???",
|
||
|
vehicleData.label ?? "???",
|
||
|
vehicleData.class ?? "???",
|
||
|
vehicleData.type ?? "???",
|
||
|
vehicleData.isValid ? "✅" : "❌",
|
||
|
vehicleData
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
vehiclesDatatable.draw();
|
||
|
}
|
||
|
|
||
|
async function setDefaultDataOfVehicle() {
|
||
|
$("#create-vehicle-spawn-name").val("");
|
||
|
$("#create-vehicle-label").val("");
|
||
|
$("#create-vehicle-class").val("sport");
|
||
|
$("input[name=create-vehicle-type][value=car]").prop("checked", true).change();
|
||
|
|
||
|
// Remove all things in select #create-vehicle-class
|
||
|
$("#create-vehicle-class").empty();
|
||
|
const classes = await $.post(`https://${resName}/getAllClasses`);
|
||
|
for(const [k, classData] of Object.entries(classes)) {
|
||
|
$("#create-vehicle-class").append(`<option value="${classData.id}">${classData.label}</option>`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$("#new-vehicle-btn").click(function() {
|
||
|
let vehicleModal = $("#vehicle-modal");
|
||
|
|
||
|
setDefaultDataOfVehicle();
|
||
|
|
||
|
vehicleModal.modal("show");
|
||
|
});
|
||
|
|
||
|
async function isVehicleValid(spawnName) {
|
||
|
return await $.post(`https://${resName}/isVehicleValid`, JSON.stringify({spawnName}));
|
||
|
}
|
||
|
|
||
|
$("#vehicle-form").submit(async function(event) {
|
||
|
if(isThereAnyErrorInForm(event)) return;
|
||
|
|
||
|
let vehicleModal = $("#vehicle-modal");
|
||
|
|
||
|
const vehicleInfo = {
|
||
|
spawnName: $("#create-vehicle-spawn-name").val(),
|
||
|
label: $("#create-vehicle-label").val(),
|
||
|
class: $("#create-vehicle-class").val(),
|
||
|
type: $("input[name=create-vehicle-type]:checked").val(),
|
||
|
}
|
||
|
|
||
|
if(!await isVehicleValid(vehicleInfo.spawnName)) {
|
||
|
swal("ERROR", `Spawn name not valid!`, "error");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let submitButton = event.originalEvent.submitter;
|
||
|
let submitButtonName = submitButton.name;
|
||
|
|
||
|
const response = await $.post(`https://${resName}/createVehicle`, JSON.stringify(vehicleInfo));
|
||
|
showServerResponse(response);
|
||
|
if(response !== true) return;
|
||
|
|
||
|
if (submitButtonName == "create-vehicle-with-image-btn") {
|
||
|
takeVehicleImage(vehicleInfo.spawnName);
|
||
|
}
|
||
|
|
||
|
vehicleModal.modal("hide");
|
||
|
loadVehicles();
|
||
|
})
|
||
|
|
||
|
$("#all-vehicles-picture-btn").click(async function() {
|
||
|
if(!await confirmDeletion()) return;
|
||
|
closeMenu();
|
||
|
$.post(`https://${resName}/takeAllVehiclesImages`);
|
||
|
})
|
||
|
|
||
|
/*
|
||
|
██████ ██ █████ ███████ ███████ ███████ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██
|
||
|
██ ██ ███████ ███████ ███████ █████ ███████
|
||
|
██ ██ ██ ██ ██ ██ ██ ██
|
||
|
██████ ███████ ██ ██ ███████ ███████ ███████ ███████
|
||
|
*/
|
||
|
let classesDatatable = $("#classes-container").DataTable( {
|
||
|
"lengthMenu": [15, 30, 50],
|
||
|
"createdRow": function (row, data, index) {
|
||
|
$('td', row).css('white-space', 'nowrap').addClass("py-3");
|
||
|
$(row).addClass("clickable");
|
||
|
|
||
|
let classData = data[data.length - 1];
|
||
|
|
||
|
$(row).click(function() {
|
||
|
editClass(classData.id);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
let classes = {};
|
||
|
|
||
|
async function loadClasses() {
|
||
|
const rawClasses = await $.post(`https://${resName}/getAllClasses`);
|
||
|
|
||
|
// Manually create the table to avoid incompatibilities due table indexing
|
||
|
classes = {};
|
||
|
|
||
|
for(const[k, classData] of Object.entries(rawClasses)) {
|
||
|
classes[classData.id] = classData;
|
||
|
}
|
||
|
|
||
|
classesDatatable.clear();
|
||
|
|
||
|
for(const[id, classData] of Object.entries(classes)) {
|
||
|
classesDatatable.row.add([
|
||
|
classData.id,
|
||
|
classData.label,
|
||
|
classData
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
classesDatatable.draw();
|
||
|
}
|
||
|
|
||
|
function setClassConfig(config={}){
|
||
|
$("#create-class-id").val(config.id);
|
||
|
$("#create-class-label").val(config.label);
|
||
|
|
||
|
$("#create-class-id").prop("disabled", config.id ? true : false);
|
||
|
}
|
||
|
|
||
|
$("#new-class-btn").click(function() {
|
||
|
let classModal = $("#class-modal");
|
||
|
|
||
|
// Converts from edit modal to create modal
|
||
|
classModal.data("action", "create");
|
||
|
|
||
|
$("#delete-class-btn").hide();
|
||
|
$("#save-class-btn").text( getLocalizedText("menu:create") );
|
||
|
|
||
|
setClassConfig();
|
||
|
|
||
|
classModal.modal("show");
|
||
|
});
|
||
|
|
||
|
$("#class-form").submit(async function(event) {
|
||
|
if(isThereAnyErrorInForm(event)) return;
|
||
|
|
||
|
let classModal = $("#class-modal");
|
||
|
|
||
|
const classInfo = {
|
||
|
id: $("#create-class-id").val(),
|
||
|
label: $("#create-class-label").val(),
|
||
|
}
|
||
|
|
||
|
let action = classModal.data("action");
|
||
|
|
||
|
let response = null;
|
||
|
|
||
|
switch(action) {
|
||
|
case "create": {
|
||
|
response = await $.post(`https://${resName}/createClass`, JSON.stringify(classInfo));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "edit": {
|
||
|
response = await $.post(`https://${resName}/updateClass`, JSON.stringify({classId: classInfo.id, classInfo}));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
showServerResponse(response);
|
||
|
if(response !== true) return;
|
||
|
|
||
|
classModal.modal("hide");
|
||
|
loadClasses();
|
||
|
})
|
||
|
|
||
|
function editClass(classId) {
|
||
|
const classModal = $("#class-modal");
|
||
|
const classInfo = classes[classId];
|
||
|
|
||
|
classModal.data("classId", classId);
|
||
|
classModal.data("action", "edit");
|
||
|
|
||
|
$("#delete-class-btn").show();
|
||
|
$("#save-class-btn").text(getLocalizedText("menu:confirm"));
|
||
|
|
||
|
setClassConfig(classInfo);
|
||
|
|
||
|
classModal.modal("show");
|
||
|
}
|
||
|
|
||
|
$("#delete-class-btn").click(async function() {
|
||
|
if(!await confirmDeletion()) return;
|
||
|
|
||
|
let classModal = $("#class-modal");
|
||
|
let classId = classModal.data("classId");
|
||
|
|
||
|
const response = await $.post(`https://${resName}/deleteClass`, JSON.stringify({classId}));
|
||
|
showServerResponse(response);
|
||
|
if(response !== true) return;
|
||
|
|
||
|
classModal.modal("hide");
|
||
|
loadClasses();
|
||
|
});
|