blob: c93696a6a1be612e802213ce456005e1c57e5d57 [file] [log] [blame]
<!doctype html>
<html>
<head>
<script type="text/javascript">
// TODO(olakar): Replace the the DOM messing JS with lit-elements.
const timeZones = [
{name: "America/Los_Angeles", description: "Mountain View"},
{name: "America/New_York", description: "New York"},
{name: "Asia/Tokyo", description: "Tokyo"},
{name: "Australia/Sydney", description: "Sydney"},
];
const shifts = [
{{range $s := .Rota.Config.Shifts.Shifts}}
{name: {{$s.Name}}},
{{end}}
];
(function() {
function addShift(baseId, container, entries) {
container.appendChild(document.createTextNode("Name:"));
let input = document.createElement("input");
input.type = "text";
input.name = "addShiftName";
input.id = "addShiftName" + baseId;
input.required = true;
input.value = entries[0];
container.appendChild(input);
container.appendChild(document.createTextNode("Duration:"));
input = document.createElement("input")
input.type = "number";
input.name = "addShiftDuration";
input.id = "addShiftDuration" + baseId;
input.required = true;
input.value = entries[1];
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
function addMember(baseId , container, entries) {
container.appendChild(document.createTextNode("Name:"));
let input = document.createElement("input");
input.type = "text";
input.name = "addName";
input.id = "addName" + baseId;
input.required = true;
input.value = entries[0];
container.appendChild(input);
container.appendChild(document.createTextNode("Email:"));
input = document.createElement("input");
input.type = "email";
input.name = "addEmail";
input.id = "addEmail" + baseId;
input.required = true;
input.value = entries[1];
container.appendChild(input);
{{with .Rota}}
container.appendChild(document.createTextNode("Shift:"));
input = document.createElement("select");
input.name = "addMemberShiftName";
input.id = "addMemberShiftName" + baseId;
console.log(entries[2]);
input.value = entries[2];
shifts.forEach(shift => {
const option = document.createElement("option");
option.value = shift.name;
if (option.value == entries[2]) {
option.selected = true;
}
option.text = shift.name;
input.appendChild(option);
})
input.required = true;
{{else}}
input = document.createElement("input");
input.type = "hidden";
input.name = "addMemberShiftName";
input.id = "addMemberShiftName" + baseId;
input.value = "";
{{end}}
container.appendChild(input);
container.appendChild(document.createTextNode("TZ:"));
input = document.createElement("select");
input.name = "addTZ";
input.id = "addTZ" + baseId;
timeZones.forEach(zone => {
const option = document.createElement("option");
option.value = zone.name;
option.text = zone.description;
input.appendChild(option);
})
input.selectedIndex = 0;
input.value = entries[3];
container.appendChild(input);
container.appendChild(document.createElement("br"));
}
function addMemberFields() {
const container = document.getElementById("memberContainer");
const members = []; while (container.hasChildNodes()) {
if (container.lastChild.nodeType != Node.ELEMENT_NODE || container.lastChild.tagName === "BR" ) {
container.removeChild(container.lastChild);
continue;
}
members.push(container.lastChild.value);
container.removeChild(container.lastChild);
}
members.reverse();
const recordLength = 4;
// The member records contain the 4 fields `name` , `email`, `shift` and `timezone`.
// This for loop slices the list of entries up into records for the `addMember`
// function.
let i = 0;
for (; i < members.length; i += recordLength) {
addMember(i, container, members.slice(i, i+recordLength));
}
addMember(i, container, ["", "", "", ""]);
}
function deleteMember(idx) {
const member = document.getElementById("member" + idx);
member.parentNode.removeChild(member);
}
function deleteShift(idx) {
const shift = document.getElementById("shift" + idx);
shift.parentNode.removeChild(shift);
}
function addShiftFields() {
var container = document.getElementById("shiftContainer");
const shifts = [];
while (container.hasChildNodes()) {
if (container.lastChild.nodeType != Node.ELEMENT_NODE || container.lastChild.tagName === "BR") {
container.removeChild(container.lastChild);
continue;
}
shifts.push(container.lastChild.value);
container.removeChild(container.lastChild);
}
shifts.reverse();
var i = 0;
for (; i < shifts.length; i += 2) {
addShift(i, container, shifts.slice(i, i+2));
}
addShift(i, container, ["", ""]);
}
window.addShiftFields = addShiftFields;
window.addMemberFields = addMemberFields;
window.deleteMember = deleteMember;
window.deleteShift = deleteShift;
})();
</script>
<title>Create rotation</title>
</head>
<body>
<form action="{{with .Rota}}modifyrota{{else}}createrota{{end}}" method="POST" id="rotaForm">
<fieldset>
<legend>Modify rotation</legend>
<fieldset>
<legend>Rotation configuration</legend>
<table class="table">
<tbody>
<tr>
<td>
Rotation Name:
</td>
<td>
<input type="text" id="Name" name="Name" value="{{with .Rota}}{{.Config.Name}}" required readonly><small><i> can't be modified</i></small>{{else}}" required>{{end}}
</td>
</tr>
<tr>
<td>
Description:
</td>
<td>
<input type="text" id="Description" name="Description" value="{{with .Rota}}{{.Config.Description}}{{end}}" required>
</td>
</tr>
<tr>
<td>
Calendar:
</td>
<td>
<input type="text" id="Calendar" name="Calendar" value="{{with .Rota}}{{.Config.Calendar}}{{end}}">
</td>
</tr>
<tr>
<td>
Owners:</td><td><input type="text" id="Owners" name="Owners" value="{{with .Rota}}{{$.Owners}}{{else}}{{.User.Email}}{{end}}" required><small><i> comma separated</i></small>
</td>
</tr>
<tr>
<td>
Expiration:</td><td><input type="number" id="Expiration" name="Expiration" value="{{with .Rota}}{{.Config.Expiration}}{{else}}4{{end}}" required><small><i> Number of shifts remaining before generating new shifts</i></small>
</td>
</tr>
<tr>
<td>
Shifts To Schedule:
</td>
<td>
<input type="number" id="ShiftsToSchedule" name="ShiftsToSchedule" value="{{with .Rota}}{{.Config.ShiftsToSchedule}}{{else}}8{{end}}" required>
</td>
</tr>
<tr>
<td>
Email Subject Template:
</td><
<td>
<textarea id="EmailSubjectTemplate" class="text" cols="40" rows ="2" name="EmailSubjectTemplate" required>{{with .Rota}}{{.Config.Email.Subject}}{{end}}</textarea>
</td>
</tr>
<tr>
<td>
Email Body Template:
</td>
<td>
<textarea id="EmailBodyTemplate" class="text" cols="40" rows ="10" name="EmailBodyTemplate" required>{{with .Rota}}{{.Config.Email.Body}}{{end}}</textarea>
</td>
</tr>
<tr>
<td>
Email Days Before Notify:
</td>
<td>
<input id="EmailNotify" type="number" name="EmailNotify" required value="{{with .Rota}}{{.Config.Email.DaysBeforeNotify}}{{else}}7{{end}}">
</td>
</tr>
</tbody>
</table>
</fieldset>
<fieldset>
<legend>Rotation members</legend>
<table class="table">
<tbody>
<tr>
<td>Members:</td>
<td>
{{with .Rota}}
{{range $i, $m := .Members}}
<div id="member{{$i}}">
Email: <input type="text" name="memberName" value="{{$m.Email}}" id="memberName{{$i}}">
ShiftName: <select name="memberShiftName" id="memberShiftName{{$i}}">
{{range $s := $.Rota.Config.Shifts.Shifts}}
<option value="{{$s.Name}}" {{if eq $m.ShiftName $s.Name}}selected{{end}}>{{$s.Name}}</option>
{{end}}
</select>
<button type="button" onclick="deleteMember({{$i}})">Delete</button>
<br>
</div>
{{end}}
{{else}}
<select multiple name="members" size=20>
{{range $m := .Members}}
<option value="{{$m.Email}}" title={{$m.Email}}>{{$m.Name}} ({{$m.Email}})</option>
{{end}}
</select>
{{end}}
</td>
</tr>
</tbody>
</table>
<h4>Add member:</h4>
<div id="memberContainer"></div>
<br>
<button type="button" onclick="addMemberFields()">Add member</button>
</fieldset>
<fieldset>
<legend>Shift configuration</legend>
<table class="table">
<tbody>
<tr>
<td>
StartTime:
</td>
<td>
<input type="time" name="shiftStart" value='{{with .Rota}}{{.Config.Shifts.StartTime.Format "03:04"}}{{else}}00:00{{end}}' required><small><i> MTV time</i></small>
</td>
</tr>
<tr>
<td>
Length:
</td>
<td>
<input type="number" name="shiftLength" value="{{with .Rota}}{{.Config.Shifts.Length}}{{else}}5{{end}}" required><small><i> Shift lenght in days</i></small>
</td>
</tr>
<tr>
<td>
Skip:
</td>
<td>
<input type="number" name="shiftSkip" value="{{with .Rota}}{{.Config.Shifts.Skip}}{{else}}2{{end}}" required><small><i> Days to skip between shifts</i></small>
</td>
</tr>
<tr>
<td>
ShiftMembers:
</td>
<td>
<input type="number" name="shiftMembers" value="{{with .Rota}}{{.Config.Shifts.ShiftMembers}}{{else}}2{{end}}" required><small><i> nr of members to schedule</i></small>
</td>
<tr><td>Generator:</td>
<td>
<select name="generator">
<option value="Legacy" title="Legacy" {{with .Rota}}{{if eq .Config.Shifts.Generator "Legacy"}}selected{{end}}{{end}}>Legacy</option>
<option value="Fair" title="Fair" {{with .Rota}}{{if eq .Config.Shifts.Generator "Fair"}}selected{{end}}{{end}}>Fair</option>
<option value="Random" title="Random" {{with .Rota}}{{if eq .Config.Shifts.Generator "Random"}}selected{{end}}{{end}}>Random</option>
</select>
</td>
</tr>
</tbody>
</table>
{{with .Rota}}
<h4>Shifts</h4>
{{range $i, $s := .Config.Shifts.Shifts}}
<div id="shift{{$i}}">
Name: <input type="text" name="shiftName" value="{{$s.Name}}">
Duration: <input type="number" name="shiftDuration" value="{{$s.Duration.Hours}}">
<button type=button onclick="deleteShift({{$i}})">Delete</button>
<br>
</div>
{{end}}
{{end}}
<h4>Add shift:</h4>
<div id="shiftContainer"></div>
<br>
<button type="button" onclick="addShiftFields()">Add Shift</button>
</fieldset>
<br>
<button type="submit" form="rotaForm" value="Submit">{{with .Rota}}Modify{{else}}Create{{end}} Rota Config</button>
</fieldset>
</form>
</body>
</html>