version 1.2
Reviewed-on: jlusiardi/retrotool_dev#28 Co-authored-by: Joachim Lusiardi <joachim@lusiardi.de> Co-committed-by: Joachim Lusiardi <joachim@lusiardi.de>
This commit is contained in:
parent
95a97182e3
commit
24213c4022
23
app.py
23
app.py
@ -28,6 +28,7 @@ def prepareRetroData(retroData, participantId, ttl=0):
|
||||
"extId": retroData["extId"],
|
||||
"moods": retroData["moods"],
|
||||
"participants": len(retroData["participants"]),
|
||||
"participants_ready": len(retroData["participants_ready"]),
|
||||
"good": [foo(x) for x in retroData["good"]],
|
||||
"bad": [foo(x) for x in retroData["bad"]],
|
||||
"todo": [foo(x) for x in retroData["todo"]],
|
||||
@ -68,6 +69,7 @@ def createRetro():
|
||||
"good": [],
|
||||
"bad": [],
|
||||
"todo": [],
|
||||
"participants_ready": [],
|
||||
}
|
||||
redis_client.set(f"retro_{ext_id}", json.dumps(newRetro))
|
||||
redis_client.set(f"retrotimer_{ext_id}", "timer", ex=duration)
|
||||
@ -146,7 +148,7 @@ def handle_join(data):
|
||||
def handle_mood_update(retroId, participantId, mood):
|
||||
print(f"{participantId} changed mood to {mood}")
|
||||
retro = json.loads(redis_client.get(f"retro_{retroId}"))
|
||||
retro["moods"][participantId] = mood
|
||||
retro["moods"][participantId] = min(10, max(1,mood))
|
||||
redis_client.set(f"retro_{retroId}", json.dumps(retro))
|
||||
|
||||
join_room(retroId)
|
||||
@ -420,6 +422,25 @@ def handle_remark_edited(retroId, participantId, commentId, remarkId, text):
|
||||
)
|
||||
|
||||
|
||||
@socketio.on("participant_ready")
|
||||
def handle_remark_edited(retroId, participantId):
|
||||
print(f"{participantId} is ready")
|
||||
retro = json.loads(redis_client.get(f"retro_{retroId}"))
|
||||
|
||||
retro["participants_ready"].append(participantId)
|
||||
retro["participants_ready"] = list(set(retro["participants_ready"]))
|
||||
|
||||
redis_client.set(f"retro_{retroId}", json.dumps(retro))
|
||||
|
||||
join_room(retroId)
|
||||
ttl = redis_client.ttl(f"retrotimer_{retroId}")
|
||||
emit(
|
||||
"transmit_retro",
|
||||
json.dumps(prepareRetroData(retro, participantId, ttl)),
|
||||
to=retroId,
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
if __name__ == "__main__":
|
||||
socketio.run(app, debug=True)
|
||||
|
45
package-lock.json
generated
45
package-lock.json
generated
@ -1,15 +1,28 @@
|
||||
{
|
||||
"name": "retrotool",
|
||||
"name": "retrotool_dev",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@types/bootstrap": "^5.2.10",
|
||||
"@types/socket.io-client": "3.0.0",
|
||||
"bootstrap": "5.3.7",
|
||||
"socket.io-client": "4.8.1",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||
@ -17,6 +30,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/bootstrap": {
|
||||
"version": "5.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.2.10.tgz",
|
||||
"integrity": "sha512-F2X+cd6551tep0MvVZ6nM8v7XgGN/twpdNDjqS1TUM7YFNEtQYWk+dKAnH+T1gr6QgCoGMPl487xw/9hXooa2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/socket.io-client": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-3.0.0.tgz",
|
||||
@ -28,6 +51,26 @@
|
||||
"socket.io-client": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.7",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz",
|
||||
"integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/twbs"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/bootstrap"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
|
@ -2,6 +2,8 @@
|
||||
"devDependencies": {
|
||||
"@types/socket.io-client": "3.0.0",
|
||||
"socket.io-client": "4.8.1",
|
||||
"@types/bootstrap": "^5.2.10",
|
||||
"bootstrap": "5.3.7",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,15 @@
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"socket.io-client": "https://cdn.socket.io/4.8.1/socket.io.esm.min.js"
|
||||
"socket.io-client": "https://cdn.socket.io/4.8.1/socket.io.esm.min.js",
|
||||
"@popperjs/core": "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js",
|
||||
"bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.esm.min.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="module">
|
||||
import { init_starter } from "/static/retro.js";
|
||||
init_starter();
|
||||
init_starter("{{ url_for('createRetro') }}");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div class="container text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1>Retro "<span id="title"></span>" mit <span id="numberOfParticipants">?</span> Teilnehmenden</h1>
|
||||
<h1>Retro "<span id="title"></span>" mit <span id="numberOfParticipants">?</span> Teilnehmenden (<span id="numberOfReadyParticipants">?</span> sind fertig)</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -27,7 +27,7 @@
|
||||
<div class="card-body">
|
||||
Teile folgenden link: <input id="shareLink" type="text" class="form-control" id="exampleFormControlInput1"
|
||||
value="" />
|
||||
<button type="button" class="btn btn-primary"
|
||||
<button type="button" class="btn btn-outline-primary"
|
||||
onclick="var copyTextarea = document.getElementById('shareLink');copyTextarea.focus();copyTextarea.select();document.execCommand('copy')">
|
||||
<i class="bi bi-clipboard-plus"></i>
|
||||
</button>
|
||||
@ -48,14 +48,19 @@
|
||||
<div class="card" style="height: 100%;">
|
||||
<h5 class="card-header">Werkzeuge</h5>
|
||||
<div class="card-body" style="align-content: center;">
|
||||
<button type="button" class="btn btn-primary" id="exportButton" data-bs-toggle="modal"
|
||||
<button type="button" class="btn btn-outline-primary" id="exportButton" data-bs-toggle="modal"
|
||||
data-bs-target="#exportBackdrop">
|
||||
<i class="bi bi-download"></i>
|
||||
</button>
|
||||
<button id="ReadyButton" type="button" class="btn btn-outline-primary">🏁</button>
|
||||
<button id="help" type="button" class="btn btn-outline-primary" data-bs-toggle="modal"
|
||||
data-bs-target="#helpBackdrop">
|
||||
<i class="bi bi-patch-question"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade modal-xl" id="exportBackdrop" data-bs-backdrop="static" data-bs-keyboard="false"
|
||||
<div class="modal fade modal-xl" id="exportBackdrop" data-bs-backdrop="static" data-bs-keyboard="true"
|
||||
tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
@ -72,53 +77,133 @@
|
||||
})]);
|
||||
}
|
||||
</script>
|
||||
<button type="button" class="btn btn-primary" onclick="foo()">
|
||||
<button type="button" class="btn btn-outline-primary" onclick="foo()">
|
||||
<i class="bi bi-clipboard-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade modal-xl" id="helpBackdrop" data-bs-backdrop="static" data-bs-keyboard="true"
|
||||
tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Hilfe</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: left;">
|
||||
<h2>Tastaturkürzel</h2>
|
||||
überall ausser bei Textfeldern:
|
||||
<ul>
|
||||
<li><kbd>h</kbd>: Zeigt diese Hilfe an</li>
|
||||
<li><kbd>+</kbd>: Stimmungswert um 1 Punkt anheben</li>
|
||||
<li><kbd>-</kbd>: Stimmungswert um 1 Punkt absenken</li>
|
||||
<li><kbd>g</kbd>: Lege guten Punkt an</li>
|
||||
<li><kbd>s</kbd>: Lege schlechten Punkt an</li>
|
||||
<li><kbd>t</kbd>: Lege ToDo an</li>
|
||||
<li><kbd>r</kbd>: Markiere dich als "Fertig"</li>
|
||||
<li><kbd>e</kbd>: Exportiere die Retro</li>
|
||||
</ul>
|
||||
In Textfeldern:
|
||||
<ul>
|
||||
<li><kbd>alt</kbd>+<kbd>enter</kbd></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<div class="card">
|
||||
<h5 class="card-header">Gut gelaufen</h5>
|
||||
<div class="card-body">
|
||||
<textarea class="form-control" id="positivTextarea" rows="2"></textarea>
|
||||
<button type="submit" class="btn btn-primary mb-3" id="positivButton">
|
||||
<div class="card-header" style="font-size: 1.25rem;">
|
||||
Gut gelaufen
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#createGoodModal" style="margin-bottom: 0px !important;">
|
||||
<i class="bi bi-file-earmark-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal fade" id="createGoodModal" data-bs-keyboard="true" tabindex="-1" aria-labelledby="createGoodModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="createGoodModalLabel">Neuer positiver Punkt</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="positivTextarea" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="positivButton" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Anlegen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="goods" class="mb-3">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="card">
|
||||
<h5 class="card-header">Schlecht gelaufen</h5>
|
||||
<div class="card-body">
|
||||
<textarea class="form-control" id="negativTextarea" rows="2"></textarea>
|
||||
<button type="submit" class="btn btn-primary mb-3" id="negativButton"><i
|
||||
class="bi bi-file-earmark-plus"></i></button>
|
||||
<div class="card-header" style="font-size: 1.25rem;">
|
||||
Schlecht gelaufen
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#createBadModal" style="margin-bottom: 0px !important;">
|
||||
<i class="bi bi-file-earmark-plus"></i></button>
|
||||
</div>
|
||||
<div class="modal fade" id="createBadModal" data-bs-keyboard="true" tabindex="-1" aria-labelledby="createBadModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="createBadModalLabel">Neuer negativer Punkt</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="negativTextarea" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="negativButton" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Anlegen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bads" class="mb-3">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="card">
|
||||
<h5 class="card-header">ToDos</h5>
|
||||
<div class="card-body">
|
||||
<textarea class="form-control" id="todoTextarea" rows="2"></textarea>
|
||||
<button type="submit" class="btn btn-primary mb-3" id="todoButton"><i
|
||||
class="bi bi-file-earmark-plus"></i></button>
|
||||
<div class="card-header" style="font-size: 1.25rem;">
|
||||
ToDos
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#createTodoModal" style="margin-bottom: 0px !important;">
|
||||
<i class="bi bi-file-earmark-plus"></i></button>
|
||||
</div>
|
||||
<div class="modal fade" id="createTodoModal" data-bs-keyboard="true" tabindex="-1" aria-labelledby="createTodoModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="createTodoModalLabel">Neues ToDo anlegen</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="todoTextarea" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="todoButton" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Anlegen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="todos" class="mb-3">
|
||||
</div>
|
||||
@ -139,7 +224,9 @@
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"socket.io-client": "https://cdn.socket.io/4.8.1/socket.io.esm.min.js"
|
||||
"socket.io-client": "https://cdn.socket.io/4.8.1/socket.io.esm.min.js",
|
||||
"@popperjs/core": "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js",
|
||||
"bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.esm.min.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { io, Socket } from "socket.io-client";
|
||||
import { Modal } from "bootstrap";
|
||||
|
||||
interface ServerToClientEvents {
|
||||
transmit_retro: (participantId: string, mood: number) => void;
|
||||
@ -14,9 +15,10 @@ interface ClientToServerEvents {
|
||||
comment_edited: (retroId: string, participantId: string, commentId: string, text: string) => void;
|
||||
thumb_up: (retroId: string, participantId: string, commentId: string) => void;
|
||||
thumb_down: (retroId: string, participantId: string, commentId: string) => void;
|
||||
remark_added: (retroId: string, participantId: string, commentId: string, text: string) => void;
|
||||
remark_added: (retroId: string, participantId: string, commentId: string, text: string) => void;
|
||||
remark_removed: (retroId: string, participantId: string, commentId: string, remarkId: string) => void;
|
||||
remark_edited: (retroId: string, participantId: string, commentId: string, remarkId: string, text: string) => void;
|
||||
participant_ready: (retroId: string, participantId: string) => void;
|
||||
}
|
||||
|
||||
class Remark {
|
||||
@ -55,6 +57,7 @@ class Comment {
|
||||
class Retro {
|
||||
extId: string;
|
||||
participants: [];
|
||||
participants_ready: number;
|
||||
moods: Map<string, number>;
|
||||
good: Array<Comment>;
|
||||
bad: Array<Comment>;
|
||||
@ -66,6 +69,7 @@ class Retro {
|
||||
this.title = data["title"];
|
||||
this.remainingTime = data["remainingTime"];
|
||||
this.extId = data["extId"];
|
||||
this.participants_ready = data["participants_ready"];
|
||||
this.participants = data["participants"];
|
||||
this.moods = new Map();
|
||||
for (let k in (data["moods"] as object)) {
|
||||
@ -125,15 +129,16 @@ function displayRemarks(targetElement: HTMLElement, comment: Comment): string {
|
||||
targetElement.innerHTML = "";
|
||||
comment.remarks.forEach(function (remark: Remark) {
|
||||
var deleteButtonId = `${remark.extId}_deleteButton`;
|
||||
var editButtonId = `${remark.extId}_editButton`;
|
||||
var editButtonId = `${remark.extId}Button`;
|
||||
var textareaId = `${remark.extId}Textarea`;
|
||||
targetElement.innerHTML += `
|
||||
<div class="card">
|
||||
<h5 class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#editBd_${remark.extId}"><i class="bi bi-pencil-square"></i></button>
|
||||
<button id="${deleteButtonId}" type="button" class="btn btn-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#editBd_${remark.extId}"><i class="bi bi-pencil-square"></i></button>
|
||||
<button id="${deleteButtonId}" type="button" class="btn btn-outline-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
@ -144,7 +149,7 @@ function displayRemarks(targetElement: HTMLElement, comment: Comment): string {
|
||||
<p class="card-text">${remark.text}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="editBd_${remark.extId}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal fade" id="editBd_${remark.extId}" data-bs-backdrop="static" data-bs-keyboard="true" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -152,11 +157,11 @@ function displayRemarks(targetElement: HTMLElement, comment: Comment): string {
|
||||
<button id="${editButtonId}_cancel2" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="editTa_${remark.extId}" rows="2">${remark.text}</textarea>
|
||||
<textarea class="form-control" id="${textareaId}" rows="2">${remark.text}</textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="${editButtonId}_cancel" type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${editButtonId}" type="button" class="btn btn-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
<button id="${editButtonId}_cancel" type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${editButtonId}" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -165,19 +170,23 @@ function displayRemarks(targetElement: HTMLElement, comment: Comment): string {
|
||||
});
|
||||
comment.remarks.forEach(function (remark: Remark) {
|
||||
var deleteButtonId = `${remark.extId}_deleteButton`;
|
||||
var editButtonId = `${remark.extId}_editButton`;
|
||||
var editButtonId = `${remark.extId}Button`;
|
||||
var textareaId = `${remark.extId}Textarea`;
|
||||
document.getElementById(deleteButtonId).onclick = function () {
|
||||
socket.emit('remark_removed', retroId, participantId, comment.extId, remark.extId);
|
||||
};
|
||||
document.getElementById(editButtonId).addEventListener("click", function () {
|
||||
var newValue = (document.getElementById(`editTa_${remark.extId}`) as HTMLTextAreaElement).value;
|
||||
var newValue = (document.getElementById(textareaId) as HTMLTextAreaElement).value;
|
||||
socket.emit('remark_edited', retroId, participantId, comment.extId, remark.extId, newValue);
|
||||
});
|
||||
document.getElementById(editButtonId + "_cancel").addEventListener("click", function () {
|
||||
(document.getElementById(`editTa_${remark.extId}`) as HTMLTextAreaElement).value = remark.text;
|
||||
(document.getElementById(textareaId) as HTMLTextAreaElement).value = remark.text;
|
||||
});
|
||||
document.getElementById(editButtonId + "_cancel2").addEventListener("click", function () {
|
||||
(document.getElementById(`editTa_${remark.extId}`) as HTMLTextAreaElement).value = remark.text;
|
||||
(document.getElementById(textareaId) as HTMLTextAreaElement).value = remark.text;
|
||||
});
|
||||
document.getElementById(`editBd_${remark.extId}`).addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById(textareaId).focus()
|
||||
});
|
||||
});
|
||||
return tmp;
|
||||
@ -188,35 +197,36 @@ function create_or_update(comment: Comment, type: string) {
|
||||
var cardContentId = `${cardId}_content`;
|
||||
var cardCommentsId = `${cardId}_comments`;
|
||||
var deleteButtonId = `${cardId}_deleteButton`;
|
||||
var editButtonId = `${cardId}_editButton`;
|
||||
var editButtonId = `${cardId}Button`;
|
||||
var textareaId = `${cardId}Textarea`;
|
||||
var thumbUpButtonId = `${cardId}_thumbUpButton`;
|
||||
var thumbDownButtonId = `${cardId}_thumbDownButton`;
|
||||
var thumbUpCounterId = `${cardId}_thumbUpCounter`;
|
||||
var thumbDownCounterId = `${cardId}_thumbDownCounter`;
|
||||
var addRemarkButtonId = `${cardId}_remarkButton`;
|
||||
var addRemarkTextareaId = `${cardId}_remarkTextarea`;
|
||||
var addRemarkButtonId = `${cardId}_remarkButton`;
|
||||
var addRemarkTextareaId = `${cardId}_remarkTextarea`;
|
||||
var buttons = "";
|
||||
var modal = "";
|
||||
if (comment.canEdit()) {
|
||||
buttons = `
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#editBd_${comment.extId}"><i class="bi bi-pencil-square"></i></button>
|
||||
<button id="${deleteButtonId}" type="button" class="btn btn-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#editBd_${comment.extId}"><i class="bi bi-pencil-square"></i></button>
|
||||
<button id="${deleteButtonId}" type="button" class="btn btn-outline-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
`
|
||||
modal = `<div class="modal fade" id="editBd_${comment.extId}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
modal = `<div class="modal fade" id="editBd_${comment.extId}" data-bs-backdrop="static" data-bs-keyboard="true" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Eintrag bearbeiten</h1>
|
||||
<button id="${editButtonId}_cancel2" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<button id="${editButtonId}_cancel2" type="button" class="btn-outline-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="editTa_${comment.extId}" rows="2">${comment.text}</textarea>
|
||||
<textarea class="form-control" id="${textareaId}" rows="2">${comment.text}</textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="${editButtonId}_cancel" type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${editButtonId}" type="button" class="btn btn-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
<button id="${editButtonId}_cancel" type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${editButtonId}" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -227,21 +237,21 @@ function create_or_update(comment: Comment, type: string) {
|
||||
<div id="${cardId}" class="card">
|
||||
<h5 class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<div class="col-4">
|
||||
${buttons}
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addRemarkBd_${comment.extId}">
|
||||
<div class="col-2">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addRemarkBd_${comment.extId}">
|
||||
<i class="bi bi-chat-left-text"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<div class="col-6">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="${thumbUpButtonId}" type="button" class="btn btn-success btn-sm">
|
||||
<button id="${thumbUpButtonId}" type="button" class="btn btn-outline-success btn-sm">
|
||||
<span id="${thumbUpCounterId}">${comment.up}</span>
|
||||
<i class="bi bi-hand-thumbs-up"></i>
|
||||
</button>
|
||||
<button id="${thumbDownButtonId}" type="button" class="btn btn-success btn-sm">
|
||||
<button id="${thumbDownButtonId}" type="button" class="btn btn-outline-success btn-sm">
|
||||
<span id="${thumbDownCounterId}">${comment.down}</span>
|
||||
<i class="bi bi-hand-thumbs-down"></i>
|
||||
</button>
|
||||
@ -256,19 +266,19 @@ function create_or_update(comment: Comment, type: string) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="addRemarkBd_${comment.extId}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal fade" id="addRemarkBd_${comment.extId}" data-bs-backdrop="static" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Bemerkung hinzufügen</h1>
|
||||
<button id="${addRemarkButtonId}_cancel2" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<button id="${addRemarkButtonId}_cancel2" type="button" class="btn-outline-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" id="${addRemarkTextareaId}" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="${addRemarkButtonId}_cancel" type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${addRemarkButtonId}" type="button" class="btn btn-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
<button id="${addRemarkButtonId}_cancel" type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button id="${addRemarkButtonId}" type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -293,14 +303,17 @@ function create_or_update(comment: Comment, type: string) {
|
||||
socket.emit('comment_removed', retroId, participantId, comment.extId);
|
||||
});
|
||||
document.getElementById(editButtonId).addEventListener("click", function () {
|
||||
var newValue = (document.getElementById(`editTa_${comment.extId}`) as HTMLTextAreaElement).value;
|
||||
var newValue = (document.getElementById(textareaId) as HTMLTextAreaElement).value;
|
||||
socket.emit('comment_edited', retroId, participantId, comment.extId, newValue);
|
||||
});
|
||||
document.getElementById(editButtonId + "_cancel").addEventListener("click", function () {
|
||||
(document.getElementById(`editTa_${comment.extId}`) as HTMLTextAreaElement).value = comment.text;
|
||||
(document.getElementById(textareaId) as HTMLTextAreaElement).value = comment.text;
|
||||
});
|
||||
document.getElementById(editButtonId + "_cancel2").addEventListener("click", function () {
|
||||
(document.getElementById(`editTa_${comment.extId}`) as HTMLTextAreaElement).value = comment.text;
|
||||
(document.getElementById(textareaId) as HTMLTextAreaElement).value = comment.text;
|
||||
});
|
||||
document.getElementById(`editBd_${comment.extId}`).addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById(textareaId).focus()
|
||||
});
|
||||
}
|
||||
document.getElementById(thumbUpButtonId).addEventListener("click", function () {
|
||||
@ -315,9 +328,11 @@ function create_or_update(comment: Comment, type: string) {
|
||||
if (remarkTextarea.value.length > 0) {
|
||||
socket.emit('remark_added', retroId, participantId, comment.extId, remarkTextarea.value);
|
||||
remarkTextarea.value = "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById(`addRemarkBd_${comment.extId}`).addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById(addRemarkTextareaId).focus()
|
||||
});
|
||||
}
|
||||
document.getElementById(cardContentId).innerHTML = comment.text;
|
||||
document.getElementById(thumbUpCounterId).innerHTML = comment.up.toString();
|
||||
@ -338,9 +353,11 @@ function calc_time(seconds: number): string {
|
||||
}
|
||||
|
||||
function update_retro(retro: Retro, own_participant_id: string) {
|
||||
console.log(retro);
|
||||
// render number of participants
|
||||
(document.getElementById('title') as HTMLParagraphElement).textContent = retro.title;
|
||||
(document.getElementById('numberOfParticipants') as HTMLParagraphElement).textContent = retro.participants.toString();
|
||||
(document.getElementById('numberOfReadyParticipants') as HTMLParagraphElement).textContent = retro.participants_ready.toString();
|
||||
(document.getElementById('timer') as HTMLDivElement).textContent = calc_time(Math.max(retro.remainingTime, 0));
|
||||
(document.getElementById('timer') as HTMLDivElement).setAttribute("val", retro.remainingTime.toString());
|
||||
var shareLink = window.location.href;
|
||||
@ -413,6 +430,79 @@ export function init_retro(_retroId: string, _participantId: string) {
|
||||
"retroId": retroId
|
||||
}
|
||||
});
|
||||
document.onkeydown = function (ev: KeyboardEvent) {
|
||||
//@ts-ignore
|
||||
var nodeName: string = ev.target.nodeName;
|
||||
//@ts-ignore
|
||||
var targetId: string = ev.target.id;
|
||||
if(nodeName == "TEXTAREA" && ev.altKey) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
document.onkeyup = function (ev: KeyboardEvent) {
|
||||
// console.log(ev)
|
||||
//@ts-ignore
|
||||
var nodeName: string = ev.target.nodeName;
|
||||
//@ts-ignore
|
||||
var targetId: string = ev.target.id;
|
||||
switch (nodeName) {
|
||||
case "TEXTAREA":
|
||||
switch (ev.key) {
|
||||
case "Enter":
|
||||
if (ev.altKey) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
var buttonId = targetId.replace("Textarea", "Button");
|
||||
document.getElementById(buttonId).click();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (ev.key) {
|
||||
case "r":
|
||||
ev.preventDefault();
|
||||
document.getElementById("ReadyButton").click();
|
||||
break;
|
||||
case "+":
|
||||
ev.preventDefault();
|
||||
socket.emit('mood_change', retroId, participantId, Number.parseInt(rangeInput.value) + 1);
|
||||
break;
|
||||
case "-":
|
||||
ev.preventDefault();
|
||||
socket.emit('mood_change', retroId, participantId, Number.parseInt(rangeInput.value) - 1);
|
||||
break;
|
||||
case "e":
|
||||
ev.preventDefault();
|
||||
document.getElementById("exportButton").click();
|
||||
break;
|
||||
case "g":
|
||||
ev.preventDefault();
|
||||
(new Modal("#createGoodModal", {})).toggle();
|
||||
break;
|
||||
case "h":
|
||||
ev.preventDefault();
|
||||
(new Modal("#helpBackdrop", {})).toggle();
|
||||
break;
|
||||
case "s":
|
||||
ev.preventDefault();
|
||||
(new Modal("#createBadModal", {})).toggle();
|
||||
break;
|
||||
case "t":
|
||||
ev.preventDefault();
|
||||
(new Modal("#createTodoModal", {})).toggle();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const exportButton = document.getElementById('exportButton')! as HTMLButtonElement;
|
||||
exportButton.addEventListener('click', function (this: HTMLButtonElement) {
|
||||
@ -465,6 +555,57 @@ export function init_retro(_retroId: string, _participantId: string) {
|
||||
JSON.stringify(retro);
|
||||
})
|
||||
|
||||
// const exportButton = document.getElementById('exportButton')! as HTMLButtonElement;
|
||||
// exportButton.addEventListener('click', function (this: HTMLButtonElement) {
|
||||
// function showComments(comments: Comment[]): string {
|
||||
// var exportText = ``;
|
||||
// if (comments.length > 0) {
|
||||
// exportText = `<ul>`;
|
||||
// for (let index = 0; index < comments.length; index++) {
|
||||
// const comment = comments[index];
|
||||
// exportText += `<li>${comment.text} (${comment.up} 👍/ ${comment.down} 👎)`;
|
||||
// if (comment.remarks.length > 0) {
|
||||
// exportText += `<ul>`;
|
||||
// for (let remarkIndex = 0; remarkIndex < comment.remarks.length; remarkIndex++) {
|
||||
// const remark = comment.remarks[remarkIndex];
|
||||
// exportText += `<li>${remark.text}</li>`
|
||||
// }
|
||||
// exportText += `</ul>`;
|
||||
// }
|
||||
// exportText += `</li>`
|
||||
// }
|
||||
// exportText += `</ul>`;
|
||||
// } else {
|
||||
// exportText = "Es wurden keine Punkte eingebracht."
|
||||
// }
|
||||
// return exportText;
|
||||
// }
|
||||
// const exportDiv = document.getElementById("exportDivId")! as HTMLDivElement;
|
||||
// var exportText = `<h1>Zusammenfassung für '${retro.title}'</h1>`;
|
||||
// exportText += `<h2>Gut gelaufen</h2>`;
|
||||
// exportText += showComments(retro.good);
|
||||
// exportText += `<h2>Schlecht gelaufen</h2>`;
|
||||
// exportText += showComments(retro.bad);
|
||||
// exportText += `<h2>Todos</h2>`;
|
||||
// exportText += showComments(retro.todo);
|
||||
// exportText += `<h2>Teamstimmung</h2>`;
|
||||
// exportText += `<div>`;
|
||||
// if (retro.moods.size > 0) {
|
||||
// var sum = 0;
|
||||
// var values = "";
|
||||
// retro.moods.forEach(function name(value: number) {
|
||||
// sum += value;
|
||||
// })
|
||||
// var moods: number[] = Array.from(retro.moods.values());
|
||||
// exportText += `Durchschnittliche Stimmung: ${sum / retro.moods.size} (Einzelne Werte: ${moods.join(", ")})`;
|
||||
// } else {
|
||||
// exportText += `Durchschnittliche Stimmung kann aufgrund fehlender Werte nicht berechnet werden`;
|
||||
// }
|
||||
// exportText += `</div>`;
|
||||
// exportDiv.innerHTML = exportText;
|
||||
// JSON.stringify(retro);
|
||||
// })
|
||||
|
||||
// handle positiv button clicks to submit stuff positivButton
|
||||
const positivButton = document.getElementById('positivButton')! as HTMLButtonElement;
|
||||
positivButton.addEventListener('click', function (this: HTMLButtonElement) {
|
||||
@ -474,6 +615,15 @@ export function init_retro(_retroId: string, _participantId: string) {
|
||||
positivTextarea.value = "";
|
||||
}
|
||||
})
|
||||
document.getElementById("createGoodModal").addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById("positivTextarea").focus()
|
||||
});
|
||||
document.getElementById("createBadModal").addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById("negativTextarea").focus()
|
||||
});
|
||||
document.getElementById("createTodoModal").addEventListener('shown.bs.modal', function () {
|
||||
document.getElementById("todoTextarea").focus()
|
||||
});
|
||||
|
||||
const negativButton = document.getElementById('negativButton')! as HTMLButtonElement;
|
||||
negativButton.addEventListener('click', function (this: HTMLButtonElement) {
|
||||
@ -493,6 +643,11 @@ export function init_retro(_retroId: string, _participantId: string) {
|
||||
}
|
||||
})
|
||||
|
||||
const readyButton = document.getElementById('ReadyButton')! as HTMLButtonElement;
|
||||
readyButton.onclick=function (this: HTMLButtonElement) {
|
||||
socket.emit('participant_ready', retroId, participantId);
|
||||
};
|
||||
|
||||
// handle the mood slider
|
||||
const rangeInput = document.getElementById('moodRange')! as HTMLInputElement;
|
||||
const rangeOutput = document.getElementById('moodValue')!;
|
||||
@ -518,7 +673,7 @@ export function init_retro(_retroId: string, _participantId: string) {
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
export function init_starter() {
|
||||
export function init_starter(url: string) {
|
||||
const link = document.getElementById('starter')! as HTMLLinkElement;
|
||||
link.addEventListener("click", function () {
|
||||
const duration_input = document.getElementById('duration')! as HTMLInputElement;
|
||||
@ -526,7 +681,7 @@ export function init_starter() {
|
||||
const title_input = document.getElementById('title')! as HTMLInputElement;
|
||||
const title = title_input.value;
|
||||
const link = document.getElementById('starter')! as HTMLLinkElement;
|
||||
link.href = link.href + "?duration=" + (duration * 60) + "&title=" + title;
|
||||
link.href = url + "?duration=" + (duration * 60) + "&title=" + title;
|
||||
return false;
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user