Added functionality to add and remove connections to other signals.
This commit is contained in:
parent
25e59cd92c
commit
fd2cf357dd
|
@ -65,7 +65,7 @@ public class SignalService {
|
|||
branch = this.branchRepository.findByNameAndRailSystem(branchData.name(), rs)
|
||||
.orElse(new Branch(rs, branchData.name(), BranchStatus.FREE));
|
||||
}
|
||||
Direction dir = Direction.valueOf(branchData.direction().trim().toUpperCase());
|
||||
Direction dir = Direction.parse(branchData.direction());
|
||||
branchConnections.add(new SignalBranchConnection(signal, branch, dir));
|
||||
}
|
||||
signal = signalRepository.save(signal);
|
||||
|
|
|
@ -132,10 +132,34 @@ function railSystemChanged() {
|
|||
canvasTranslation.y = -1 * (bb.y + (bb.height / 2));
|
||||
canvasScaleIndex = SCALE_INDEX_NORMAL;
|
||||
drawRailSystem();
|
||||
window.setInterval(railSystemUpdated, 1000);
|
||||
});
|
||||
$.get("/api/railSystems/" + railSystem.id + "/branches")
|
||||
.done(branches => {
|
||||
railSystem.branches = branches;
|
||||
const branchSelects = $('.js_branch_list');
|
||||
branchSelects.empty();
|
||||
railSystem.branches.forEach(branch => {
|
||||
branchSelects.append($('<option value="' + branch.name + '"></option>'))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function railSystemUpdated() {
|
||||
console.log("Refreshing...");
|
||||
$.get("/api/railSystems/" + railSystem.id + "/signals")
|
||||
.done(signals => {
|
||||
railSystem.signals = signals;
|
||||
drawRailSystem();
|
||||
});
|
||||
$.get("/api/railSystems/" + railSystem.id + "/branches")
|
||||
.done(branches => {
|
||||
railSystem.branches = branches;
|
||||
const branchSelects = $('.js_branch_list');
|
||||
branchSelects.empty();
|
||||
railSystem.branches.forEach(branch => {
|
||||
branchSelects.append($('<option value="' + branch.name + '"></option>'))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -152,6 +176,29 @@ function onSignalSelected(signal) {
|
|||
if (signal !== null) {
|
||||
const tpl = Handlebars.compile($('#signalTemplate').html());
|
||||
detailPanel.html(tpl(signal));
|
||||
signal.branchConnections.forEach(con => {
|
||||
const select = $('#signalPotentialConnectionsSelect-' + con.id);
|
||||
$.get("/api/railSystems/" + railSystem.id + "/branches/" + con.branch.id + "/signals")
|
||||
.done(signals => {
|
||||
signals = signals.filter(s => s.id !== signal.id);
|
||||
let connections = [];
|
||||
signals.forEach(s => {
|
||||
s.branchConnections
|
||||
.filter(c => c.branch.id === con.branch.id && !con.reachableSignalConnections.some(rc => rc.connectionId === c.id))
|
||||
.forEach(potentialConnection => {
|
||||
potentialConnection.signalName = s.name;
|
||||
potentialConnection.signalId = s.id;
|
||||
connections.push(potentialConnection);
|
||||
});
|
||||
});
|
||||
select.empty();
|
||||
const row = $('#signalPotentialConnectionsRow-' + con.id);
|
||||
row.toggle(connections.length > 0);
|
||||
connections.forEach(c => {
|
||||
select.append($(`<option value="${c.id}">${c.signalName} via ${c.direction} connection ${c.id}</option>`))
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,12 +219,15 @@ function addRailSystem() {
|
|||
|
||||
function deleteRailSystem() {
|
||||
if (railSystem !== null && railSystem.id) {
|
||||
$.ajax({
|
||||
url: "/api/railSystems/" + railSystem.id,
|
||||
type: "DELETE"
|
||||
})
|
||||
.always(() => {
|
||||
refreshRailSystems(true);
|
||||
confirm("Are you sure you want to permanently remove rail system " + railSystem.id + "?")
|
||||
.then(() => {
|
||||
$.ajax({
|
||||
url: "/api/railSystems/" + railSystem.id,
|
||||
type: "DELETE"
|
||||
})
|
||||
.always(() => {
|
||||
refreshRailSystems(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -196,3 +246,134 @@ function refreshRailSystems(selectFirst) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addNewSignal() {
|
||||
const modalElement = $('#addSignalModal');
|
||||
const form = $('#addSignalForm');
|
||||
form.validate();
|
||||
if (!form.valid()) return;
|
||||
const data = {
|
||||
name: $('#addSignalName').val().trim(),
|
||||
position: {
|
||||
x: $('#addSignalPositionX').val(),
|
||||
y: $('#addSignalPositionY').val(),
|
||||
z: $('#addSignalPositionZ').val()
|
||||
},
|
||||
branchConnections: [
|
||||
{
|
||||
direction: $('#addSignalFirstConnectionDirection').val(),
|
||||
name: $('#addSignalFirstConnectionBranch').val()
|
||||
},
|
||||
{
|
||||
direction: $('#addSignalSecondConnectionDirection').val(),
|
||||
name: $('#addSignalSecondConnectionBranch').val()
|
||||
}
|
||||
]
|
||||
};
|
||||
const modal = bootstrap.Modal.getInstance(modalElement[0]);
|
||||
modal.hide();
|
||||
modalElement.on("hidden.bs.modal", () => {
|
||||
confirm("Are you sure you want to add this new signal to the system?")
|
||||
.then(() => {
|
||||
$.post({
|
||||
url: "/api/railSystems/" + railSystem.id + "/signals",
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json"
|
||||
})
|
||||
.done((response) => {
|
||||
form.trigger("reset");
|
||||
railSystemChanged();
|
||||
})
|
||||
.fail((response) => {
|
||||
$('#addSignalAlertsContainer').append($('<div class="alert alert-danger">An error occurred.</div>'));
|
||||
modal.show();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
form.trigger("reset");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeReachableConnection(signalId, fromId, toId) {
|
||||
confirm(`Are you sure you want to remove the connection from ${fromId} to ${toId} from signal ${signalId}?`)
|
||||
.then(() => {
|
||||
$.get(`/api/railSystems/${railSystem.id}/signals/${signalId}`)
|
||||
.done(signal => {
|
||||
let connections = [];
|
||||
signal.branchConnections.forEach(con => {
|
||||
con.reachableSignalConnections.forEach(reachableCon => {
|
||||
connections.push({from: con.id, to: reachableCon.connectionId});
|
||||
});
|
||||
});
|
||||
connections = connections.filter(c => !(c.from === fromId && c.to === toId));
|
||||
$.post({
|
||||
url: `/api/railSystems/${railSystem.id}/signals/${signal.id}/signalConnections`,
|
||||
data: JSON.stringify({connections: connections}),
|
||||
contentType: "application/json"
|
||||
})
|
||||
.done((response) => {
|
||||
railSystemChanged();
|
||||
})
|
||||
.fail((response) => {
|
||||
console.error(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addReachableConnectionBtn(signalId, fromId) {
|
||||
const select = $('#signalPotentialConnectionsSelect-' + fromId);
|
||||
const toId = select.val();
|
||||
if (toId) {
|
||||
addReachableConnection(signalId, fromId, toId);
|
||||
}
|
||||
}
|
||||
|
||||
function addReachableConnection(signalId, fromId, toId) {
|
||||
confirm(`Are you sure you want to add a connection from ${fromId} to ${toId} from signal ${signalId}?`)
|
||||
.then(() => {
|
||||
$.get(`/api/railSystems/${railSystem.id}/signals/${signalId}`)
|
||||
.done(signal => {
|
||||
let connections = [];
|
||||
signal.branchConnections.forEach(con => {
|
||||
con.reachableSignalConnections.forEach(reachableCon => {
|
||||
connections.push({from: con.id, to: reachableCon.connectionId});
|
||||
});
|
||||
});
|
||||
if (!connections.find(c => c.from === fromId && c.to === toId)) {
|
||||
connections.push({from: fromId, to: toId});
|
||||
$.post({
|
||||
url: `/api/railSystems/${railSystem.id}/signals/${signal.id}/signalConnections`,
|
||||
data: JSON.stringify({connections: connections}),
|
||||
contentType: "application/json"
|
||||
})
|
||||
.done((response) => {
|
||||
railSystemChanged();
|
||||
})
|
||||
.fail((response) => {
|
||||
console.error(response);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function confirm(message) {
|
||||
const modalElement = $('#confirmModal');
|
||||
if (message) {
|
||||
$('#confirmModalBody').html(message);
|
||||
} else {
|
||||
$('#confirmModalBody').html("Are you sure you want to continue?");
|
||||
}
|
||||
const modal = new bootstrap.Modal(modalElement[0], {keyboard: false});
|
||||
modal.show();
|
||||
return new Promise((resolve, reject) => {
|
||||
$('#confirmModalOkButton').click(() => {
|
||||
modalElement.on("hidden.bs.modal", () => resolve());
|
||||
});
|
||||
$('#confirmModalCancelButton').click(() => {
|
||||
modalElement.on("hidden.bs.modal", () => reject());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -43,9 +43,17 @@
|
|||
<div id="railMapDetailPanel" class="col p-2 border">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addSignalModal">Add Signal</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: none;">
|
||||
<div>
|
||||
<script id="signalTemplate" type="text/x-handlebars-template">
|
||||
<h3>{{name}}</h3>
|
||||
<hr>
|
||||
|
@ -65,20 +73,132 @@
|
|||
<dl class="row">
|
||||
<dt class="col-sm-3">Branch</dt>
|
||||
<dd class="col-sm-9">{{this.branch.name}} <small class="text-muted">{{this.branch.id}}</small></dd>
|
||||
{{#if this.reachableSignalConnections.length}}
|
||||
<dt class="col-sm-3">Reachable Signals</dt>
|
||||
<dd class="col-sm-9">
|
||||
{{#each this.reachableSignalConnections}}
|
||||
<p><a onclick="selectSignalById({{this.signalId}})" href="#">{{this.signalName}}</a> <small class="text-muted">{{this.signalId}}</small> via {{this.direction}} connection {{this.connectionId}}</p>
|
||||
{{/each}}
|
||||
</dd>
|
||||
{{/if}}
|
||||
<dt class="col-sm-3">Reachable Signals</dt>
|
||||
<dd class="col-sm-9">
|
||||
{{#each this.reachableSignalConnections}}
|
||||
<p>
|
||||
<a onclick="selectSignalById({{this.signalId}})" href="#">{{this.signalName}}</a>
|
||||
<small class="text-muted">{{this.signalId}}</small> via
|
||||
{{this.direction}} connection {{this.connectionId}}
|
||||
<span
|
||||
class="btn btn-sm btn-danger js_removeSignalConnection"
|
||||
onclick="removeReachableConnection({{../../id}}, {{../id}}, {{this.connectionId}})"
|
||||
>Remove</span>
|
||||
</p>
|
||||
{{/each}}
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="row" id="signalPotentialConnectionsRow-{{this.id}}">
|
||||
<div class="col-auto">
|
||||
<select id="signalPotentialConnectionsSelect-{{this.id}}" class="form-select form-select-sm">
|
||||
{{#each this.potentialSignalConnections}}
|
||||
<option value="{{this.connectionId}}">{{this.signalName}} via {{this.branchName}} on {{this.direction}} connection</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-primary btn-sm" onclick="addReachableConnectionBtn({{../id}}, {{this.id}})">Add Connection</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
<div class="modal fade" tabindex="-1" id="confirmModal" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 id="confirmModalHeader">Confirm</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="confirmModalBody">Are you sure you want to continue?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="confirmModalCancelButton">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="confirmModalOkButton">Ok</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" tabindex="-1" id="addSignalModal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add Signal</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Fill in the following data to add a new signal to the system.</p>
|
||||
<form id="addSignalForm">
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<input id="addSignalName" type="text" class="form-control" placeholder="Name" aria-label="Name" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<h6>Position</h6>
|
||||
<div class="col">
|
||||
<input id="addSignalPositionX" class="form-control" placeholder="X" aria-label="X" type="number" step="0.1" required>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input id="addSignalPositionY" class="form-control" placeholder="Y" aria-label="Y" type="number" step="0.1" required>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input id="addSignalPositionZ" class="form-control" placeholder="Z" aria-label="Z" type="number" step="0.1" required>
|
||||
</div>
|
||||
</div>
|
||||
<h6>Connections</h6>
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<select id="addSignalFirstConnectionDirection" class="form-select" required>
|
||||
<option value="N">North</option>
|
||||
<option value="S">South</option>
|
||||
<option value="E">East</option>
|
||||
<option value="W">West</option>
|
||||
<option value="NW">NorthWest</option>
|
||||
<option value="NE">NorthEast</option>
|
||||
<option value="SW">SouthWest</option>
|
||||
<option value="SE">SouthEast</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input id="addSignalFirstConnectionBranch" type="text" class="form-control" placeholder="Branch Name" list="addSignalFirstConnectionBranchList" required>
|
||||
<datalist id="addSignalFirstConnectionBranchList" class="js_branch_list">
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<select id="addSignalSecondConnectionDirection" class="form-select" required>
|
||||
<option value="N">North</option>
|
||||
<option value="S">South</option>
|
||||
<option value="E">East</option>
|
||||
<option value="W">West</option>
|
||||
<option value="NW">NorthWest</option>
|
||||
<option value="NE">NorthEast</option>
|
||||
<option value="SW">SouthWest</option>
|
||||
<option value="SE">SouthEast</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input id="addSignalSecondConnectionBranch" type="text" class="form-control" placeholder="Branch Name" list="addSignalSecondConnectionBranchList" required>
|
||||
<datalist id="addSignalSecondConnectionBranchList" class="js_branch_list">
|
||||
</datalist>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div id="addSignalAlertsContainer"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" onclick="addNewSignal()">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.3/dist/jquery.validate.min.js" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js" integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue