Compare commits
2 Commits
ff4bd2a868
...
e76ef0b241
Author | SHA1 | Date |
---|---|---|
Tykayn | e76ef0b241 | |
Tykayn | 3d22b1f50f |
|
@ -19,7 +19,8 @@
|
||||||
<strong>{{ i + 1 }}) {{ s.title }}</strong>
|
<strong>{{ i + 1 }}) {{ s.title }}</strong>
|
||||||
|
|
||||||
<p class="is-small">
|
<p class="is-small">
|
||||||
{{ s.duration }} min, par {{ s.author }}. Reste: {{ resteTopicMinutes(s) }}. Passé: {{ round(s.spentSeconds) }}.
|
{{ s.duration }} min, par {{ s.author }}. Reste: {{ resteTopicMinutes(s) }}.
|
||||||
|
Passé: {{ round(s.spentSeconds) }}.
|
||||||
</p>
|
</p>
|
||||||
<p *ngIf="s.finished">🎉</p>
|
<p *ngIf="s.finished">🎉</p>
|
||||||
</li>
|
</li>
|
||||||
|
@ -34,17 +35,22 @@
|
||||||
<h2>
|
<h2>
|
||||||
Texte du pad
|
Texte du pad
|
||||||
</h2>
|
</h2>
|
||||||
<textarea class="textarea mx-2 is-full" [(ngModel)]="pasteLand" id="pasteland"
|
<textarea name="note" id="pasteland" cols="30" rows="10" class="textarea mx-2 is-full" [(ngModel)]="pasteLand"
|
||||||
|
id="pasteland"
|
||||||
(ngModelChange)="parseTheListOfTopicsInPasteLand()"></textarea>
|
(ngModelChange)="parseTheListOfTopicsInPasteLand()"></textarea>
|
||||||
<h2>
|
<h2>
|
||||||
Compte rendu
|
Compte rendu du {{ (today) | date:'yyyy-MM-dd'}}
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<pre>
|
||||||
{{buildCompteRendu()}}
|
{{buildCompteRendu()}}
|
||||||
</p>
|
</pre>
|
||||||
<button class="btn is-primary" (click)="copyCompteRenduToClipboard()">
|
<button class="btn is-primary" (click)="copyCompteRenduToClipboard()">
|
||||||
copier
|
copier
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn is-primary" (click)="downloadCompteRendu()">
|
||||||
|
télécharger le compte rendu
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="liens">
|
<div class="liens">
|
||||||
|
@ -66,11 +72,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="explications">
|
<div class="explications">
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
{{statsExplication}}
|
{{statsExplication}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="debug" *ngIf="showDebug">
|
<div class="debug" *ngIf="showDebug">
|
||||||
debug:
|
debug:
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -89,15 +95,18 @@
|
||||||
'topic-is-finished': subjects[currentSubjectId].finished || ! isTopicRunning(subjects[currentSubjectId])
|
'topic-is-finished': subjects[currentSubjectId].finished || ! isTopicRunning(subjects[currentSubjectId])
|
||||||
}">
|
}">
|
||||||
|
|
||||||
|
<div class="content-current-subject">
|
||||||
|
|
||||||
<h1 class="subject active">
|
<h1 class="subject active">
|
||||||
{{ subjects[currentSubjectId].title }}
|
{{ subjects[currentSubjectId].title }}
|
||||||
</h1>
|
</h1>
|
||||||
<p>{{ subjects[currentSubjectId].duration }} min, par {{ subjects[currentSubjectId].author }}</p>
|
<p>{{ subjects[currentSubjectId].duration }} min, par {{ subjects[currentSubjectId].author }}</p>
|
||||||
<p>Reste: {{ countRemainingMinutes(subjects[currentSubjectId]) }} min</p>
|
<p>Reste: {{ countRemainingMinutes(subjects[currentSubjectId]) }} min</p>
|
||||||
<p>avancement: {{ getPercentProgressTimeForTopic(subjects[currentSubjectId]) }} %</p>
|
<div class="actions">
|
||||||
|
|
||||||
<p>Début: {{ startTime }}</p>
|
|
||||||
<p>Fin: {{ endTime }}</p>
|
<p>Début: {{ startTime }}, Fin: {{ endTime }}.
|
||||||
|
Durée: {{round(getMinutesBetweenTwoDates(startDate, endDate))}}</p>
|
||||||
|
|
||||||
<button class="btn btn-primary" (click)="previousSubject()">
|
<button class="btn btn-primary" (click)="previousSubject()">
|
||||||
précédent
|
précédent
|
||||||
|
@ -113,6 +122,31 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>avancement: {{ getPercentProgressTimeForTopic(subjects[currentSubjectId]) }} %</p>
|
||||||
|
</div>
|
||||||
|
<div class="stats">
|
||||||
|
<h2>
|
||||||
|
statistiques:
|
||||||
|
</h2>
|
||||||
|
{{statsExplication}}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="compte-rendu-infos">
|
||||||
|
<label for="scribe">scribe</label>
|
||||||
|
<input type="text" id="scribe" [(ngModel)]="scribe">
|
||||||
|
<br>
|
||||||
|
<label for="presents">{{countLinesInPresent()}}présents</label>
|
||||||
|
<textarea name="presents" id="note" cols="30" rows="10" id="presents" [(ngModel)]="presents"></textarea>
|
||||||
|
<br>
|
||||||
|
<label for="début">Début</label>
|
||||||
|
<input name="presents" id="début" [(ngModel)]="startTime"/>
|
||||||
|
<br>
|
||||||
|
<label for="fin">Fin</label>
|
||||||
|
<input name="presents" id="fin" [(ngModel)]="endTime"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -124,9 +124,11 @@ main {
|
||||||
.pill-group .pill:nth-child(6n + 1) {
|
.pill-group .pill:nth-child(6n + 1) {
|
||||||
--pill-accent: var(--bright-blue);
|
--pill-accent: var(--bright-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pill-group .pill:nth-child(6n + 2) {
|
.pill-group .pill:nth-child(6n + 2) {
|
||||||
--pill-accent: var(--french-violet);
|
--pill-accent: var(--french-violet);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pill-group .pill:nth-child(6n + 3),
|
.pill-group .pill:nth-child(6n + 3),
|
||||||
.pill-group .pill:nth-child(6n + 4),
|
.pill-group .pill:nth-child(6n + 4),
|
||||||
.pill-group .pill:nth-child(6n + 5) {
|
.pill-group .pill:nth-child(6n + 5) {
|
||||||
|
@ -152,29 +154,62 @@ main {
|
||||||
.social-links a:hover svg path {
|
.social-links a:hover svg path {
|
||||||
fill: var(--gray-900);
|
fill: var(--gray-900);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//.left-side{
|
//.left-side{
|
||||||
// width: 50%;
|
// width: 50%;
|
||||||
//}
|
//}
|
||||||
.subject{
|
.subject {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-left: 10px solid white;
|
border-left: 10px solid white;
|
||||||
&.active{
|
|
||||||
|
&.active {
|
||||||
border-left-color: #00b89c;
|
border-left-color: #00b89c;
|
||||||
|
width: 20em;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn{
|
.is-primary {
|
||||||
|
background: rgb(47, 86, 27)
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-right: 2ch;
|
||||||
|
margin-top: 1rem;
|
||||||
|
min-width: 10rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0.75rem 1.5rem;
|
padding: 0.75rem 1.5rem;
|
||||||
border: solid 1px slategray;
|
border: solid 1px slategray;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
float: left;
|
||||||
|
margin-right: 2ch;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
pre{
|
|
||||||
|
pre {
|
||||||
|
width: 20rem;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
background: lightslategrey;
|
background: lightslategrey;
|
||||||
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.is-clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&.subject {
|
||||||
|
background: rgba(170, 210, 199, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 650px) {
|
@media screen and (max-width: 650px) {
|
||||||
.content {
|
.content {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -30,6 +30,13 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
startTime: string = "20:30";
|
startTime: string = "20:30";
|
||||||
// startTime: string = "17:00";
|
// startTime: string = "17:00";
|
||||||
endTime: string = "22:00";
|
endTime: string = "22:00";
|
||||||
|
today: any = new Date();
|
||||||
|
// champs habituels pour le compte rendu:
|
||||||
|
scribe: string = 'tykayn';
|
||||||
|
private timekeeper: string = 'Chuck Norris';
|
||||||
|
private animator: string = 'Covid Copperfield';
|
||||||
|
presents: string = '- tykayn';
|
||||||
|
|
||||||
pasteLand: string = "* Présentation du suivi sur Nextcloud - 5min (tykayn)\n" +
|
pasteLand: string = "* Présentation du suivi sur Nextcloud - 5min (tykayn)\n" +
|
||||||
"* Réduction de bus factor - 5min (tykayn)\n" +
|
"* Réduction de bus factor - 5min (tykayn)\n" +
|
||||||
"* Réunion avec Wikimedia France - 5min (tykayn)\n" +
|
"* Réunion avec Wikimedia France - 5min (tykayn)\n" +
|
||||||
|
@ -40,11 +47,12 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
hints: string = "";
|
hints: string = "";
|
||||||
|
|
||||||
showDebug: boolean = true;
|
showDebug: boolean = true;
|
||||||
private startDate: Date = new Date();
|
startDate: Date = new Date();
|
||||||
private endDate: Date = new Date();
|
endDate: Date = new Date();
|
||||||
private topicChangeDate: Date = new Date();
|
private topicChangeDate: Date = new Date();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateTopicChangeDate(): void {
|
updateTopicChangeDate(): void {
|
||||||
const currentTime = new Date();
|
const currentTime = new Date();
|
||||||
const timeDifferenceInMilliseconds = this.topicChangeDate.getTime() - currentTime.getTime();
|
const timeDifferenceInMilliseconds = this.topicChangeDate.getTime() - currentTime.getTime();
|
||||||
|
@ -53,10 +61,12 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
console.log(`Spent ${timeDifferenceInSeconds} seconds`);
|
console.log(`Spent ${timeDifferenceInSeconds} seconds`);
|
||||||
this.subjects[this.currentSubjectId].spentSeconds += timeDifferenceInSeconds;
|
this.subjects[this.currentSubjectId].spentSeconds += timeDifferenceInSeconds;
|
||||||
this.topicChangeDate = currentTime;
|
this.topicChangeDate = currentTime;
|
||||||
|
this.makeStatisticsOnTopicsSpentSeconds()
|
||||||
}
|
}
|
||||||
round(val:number){
|
|
||||||
|
round(val: number) {
|
||||||
if (val < 60) {
|
if (val < 60) {
|
||||||
return Math.round(val) +' s'
|
return Math.round(val) + ' s'
|
||||||
}
|
}
|
||||||
return (Math.round(val / 60) * 60) + ' min'
|
return (Math.round(val / 60) * 60) + ' min'
|
||||||
}
|
}
|
||||||
|
@ -73,12 +83,13 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
if (boom[0]) {
|
if (boom[0]) {
|
||||||
accumulatedDuration += this.findMinutesDurationInDescription(topic) | 0
|
accumulatedDuration += this.findMinutesDurationInDescription(topic) | 0
|
||||||
|
|
||||||
|
|
||||||
newTopics.push({
|
newTopics.push({
|
||||||
id: ii,
|
id: ii,
|
||||||
title: boom[0],
|
title: boom[0],
|
||||||
duration: 15,
|
duration: 15,
|
||||||
spentSeconds: 0,
|
spentSeconds: 0,
|
||||||
author: '',
|
author: this.findAuthorInDescription(topic),
|
||||||
notes: '',
|
notes: '',
|
||||||
finished: false,
|
finished: false,
|
||||||
startDate: this.getStartDateAfterDuration(accumulatedDuration + ''),
|
startDate: this.getStartDateAfterDuration(accumulatedDuration + ''),
|
||||||
|
@ -129,9 +140,6 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
this.startDate = this.makeDateFromHourToday(this.startTime + '');
|
this.startDate = this.makeDateFromHourToday(this.startTime + '');
|
||||||
this.endDate = this.makeDateFromHourToday(this.endTime + '');
|
this.endDate = this.makeDateFromHourToday(this.endTime + '');
|
||||||
|
|
||||||
// this.interval = setInterval(() => {
|
|
||||||
this.updateProgressEveryPeriod();
|
|
||||||
// }, 1 * 1000);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,8 +149,10 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
nextSubject() {
|
nextSubject() {
|
||||||
this.updateTopicChangeDate()
|
this.updateTopicChangeDate()
|
||||||
|
if(this.currentSubjectId < this.subjects.length-1) {
|
||||||
this.currentSubjectId++
|
this.currentSubjectId++
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
findMinutesDurationInDescription(topic: string): number {
|
findMinutesDurationInDescription(topic: string): number {
|
||||||
let durationRegex = /-\s(\d+)min/g;
|
let durationRegex = /-\s(\d+)min/g;
|
||||||
|
@ -240,7 +250,10 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.statsExplication = `Total spent seconds: ${totalSeconds}\nAverage spent seconds: ${averageSeconds}\nLongest topic: ${longestTopic.title} (${longestSeconds} seconds)\nShortest topic: ${shortestTopic.title} (${shortestSeconds} seconds)`;
|
this.statsExplication = `Temps passé: ${this.round(totalSeconds)}
|
||||||
|
Moyenne par sujet: ${this.round(averageSeconds)}
|
||||||
|
Sujet le plus long: ${longestTopic.title.replace('*','')} (${this.round(longestSeconds)} )
|
||||||
|
Sujet le plus court : ${shortestTopic.title.replace('*','')} (${this.round(shortestSeconds)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,21 +262,92 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
this.updateTopicChangeDate()
|
this.updateTopicChangeDate()
|
||||||
}
|
}
|
||||||
|
|
||||||
compteRendu:string = ''
|
compteRendu: string = ''
|
||||||
|
|
||||||
|
formatDateYMD(date: Date) {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = date.getMonth() + 1;
|
||||||
|
const day = date.getDate();
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
buildCompteRendu(){
|
buildCompteRendu() {
|
||||||
let compteRendu = 'Compte rendu :\n\n';
|
let compteRendu = ` Compte rendu du ${this.formatDateYMD(this.today)}\n\n`;
|
||||||
|
compteRendu += `début: ${this.startTime}, fin:${this.endTime}.\n`;
|
||||||
|
compteRendu += `Présents:\n${this.formatPresentLines()}.\n`;
|
||||||
|
if (this.scribe) {
|
||||||
|
compteRendu += `Scribe: ${this.scribe}.\n`;
|
||||||
|
}
|
||||||
|
if (this.timekeeper) {
|
||||||
|
compteRendu += `Gardien du temps: ${this.timekeeper}.\n`;
|
||||||
|
}
|
||||||
|
if (this.animator) {
|
||||||
|
compteRendu += `Animation: ${this.animator}.\n`;
|
||||||
|
}
|
||||||
|
compteRendu += `Statistiques:\n
|
||||||
|
${this.statsExplication}.`;
|
||||||
for (const topic of this.subjects) {
|
for (const topic of this.subjects) {
|
||||||
compteRendu += `Sujet ${topic.id + 1} : ${topic.title}\n`;
|
compteRendu += `* ${topic.title}-`;
|
||||||
compteRendu += `Durée : ${topic.duration} minutes\n`;
|
compteRendu += ` ${topic.duration} min`;
|
||||||
compteRendu += `Temps écoulé : ${this.resteTopicMinutes(topic)}\n\n`;
|
compteRendu += ` (${topic.author})\n`;
|
||||||
|
compteRendu += ` ${topic.notes}\n`;
|
||||||
|
if(topic.spentSeconds){
|
||||||
|
|
||||||
|
compteRendu += `Temps écoulé : ${this.round(topic.spentSeconds)}\n\n`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.compteRendu = compteRendu
|
this.compteRendu = compteRendu
|
||||||
return compteRendu
|
return compteRendu
|
||||||
}
|
}
|
||||||
copyCompteRenduToClipboard() {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns each present person for each line with a dash at the beggining if missing
|
||||||
|
*/
|
||||||
|
formatPresentLines(){
|
||||||
|
let lines = ''
|
||||||
|
if (this.presents) {
|
||||||
|
lines += this.presents.split('\n').map(line => {
|
||||||
|
if(!line.length){
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (!line.startsWith('- ')) {
|
||||||
|
return `- ${line}`;
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}).join('\n') + '\n'
|
||||||
|
}
|
||||||
|
return lines.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
copyCompteRenduToClipboard() {
|
||||||
navigator.clipboard.writeText(this.compteRendu);
|
navigator.clipboard.writeText(this.compteRendu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private findAuthorInDescription(topic: string): string {
|
||||||
|
let authorRegex = /\(([^)]+)\)/g;
|
||||||
|
let matches = authorRegex.exec(topic);
|
||||||
|
if (matches) {
|
||||||
|
return matches[1];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
countLinesInPresent() {
|
||||||
|
return this.presents.split('\n').length;
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadCompteRendu() {
|
||||||
|
let fichier = new Blob([this.buildCompteRendu()], {type: 'text/plain'});
|
||||||
|
let lien = document.createElement('a');
|
||||||
|
lien.setAttribute('href', window.URL.createObjectURL(fichier));
|
||||||
|
lien.setAttribute('download', 'compte-rendu.txt');
|
||||||
|
lien.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
getMinutesBetweenTwoDates(date1: Date, date2: Date) {
|
||||||
|
return Math.floor((date2.getTime() - date1.getTime()) / 60000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue