From e908bf62508eee974f8c5f67c2ccdcf419520ff2 Mon Sep 17 00:00:00 2001 From: Emily Wangler Date: Sat, 30 Sep 2023 18:46:20 +0200 Subject: [PATCH 1/2] add ability to set a prefix for calendar entry titles --- src/components/CalendarForm.tsx | 34 ++++++++++++++++++++++------- src/components/CalendarTable.tsx | 3 ++- src/components/IcsDownload.tsx | 25 ++++++++++++++------- src/i18n/de.json | 12 +++++++---- src/i18n/fr.json | 12 +++++++---- src/i18n/it.json | 12 +++++++---- src/styles/calendar.less | 37 ++++++++++++++++++++++++-------- 7 files changed, 97 insertions(+), 38 deletions(-) diff --git a/src/components/CalendarForm.tsx b/src/components/CalendarForm.tsx index d35f654..449f76a 100644 --- a/src/components/CalendarForm.tsx +++ b/src/components/CalendarForm.tsx @@ -30,6 +30,7 @@ type MyState = { startDate: string responsible: string puffer: number + calendarTitlePrefix: string taskList: Array, tasks: Array } @@ -41,6 +42,7 @@ class CalendarForm extends React.Component { startDate: new Date().toISOString().slice(0, 10), responsible: 'all', puffer: 0, + calendarTitlePrefix: '', taskList: [], tasks: [] }; @@ -80,6 +82,10 @@ class CalendarForm extends React.Component { this.setState({ puffer: parseInt(e.currentTarget.value) }); }; + onChangeTitlePrefix= (e: React.FormEvent): void => { + this.setState({ calendarTitlePrefix: e.currentTarget.value }); + }; + taskSort = (a: TaskT, b: TaskT) => { let aDate = a.deadline let bDate = b.deadline @@ -133,12 +139,6 @@ class CalendarForm extends React.Component { -
  • - - -
  • +
    +
  • + + +
  • +
  • + +
    + +
    + {t('calendarPage.prefixPreview', { calendarTitlePrefix: this.state.calendarTitlePrefix })} +
    +
    +
  • - +
  • - + ); } diff --git a/src/components/CalendarTable.tsx b/src/components/CalendarTable.tsx index ab79da8..0c6863c 100644 --- a/src/components/CalendarTable.tsx +++ b/src/components/CalendarTable.tsx @@ -6,6 +6,7 @@ import Task, { TaskT } from './Task'; type Props = { t: any tasks: Array + prefix: string } function CalendarTable(props: Props) { @@ -16,7 +17,7 @@ function CalendarTable(props: Props) { }) return (
    - + diff --git a/src/components/IcsDownload.tsx b/src/components/IcsDownload.tsx index 8023302..0424ce8 100644 --- a/src/components/IcsDownload.tsx +++ b/src/components/IcsDownload.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { withTranslation } from 'react-i18next' import { TaskT } from './Task' import { ChapterT } from './Chapter'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; const A = styled.a` border: none; @@ -10,7 +11,7 @@ const A = styled.a` background: var(--color-primary-light); padding: 0.3em; border-radius: 4px; - + &:hover { color: white; opacity: 0.5; @@ -20,6 +21,7 @@ const A = styled.a` type Props = { t: any tasks: Array + calendarTitlePrefix: string } function buildDescription(task: TaskT): string { @@ -33,7 +35,7 @@ function buildLinks(task: TaskT): string { }).join(',') } -function generateIcs(tasks: Array) { +function generateIcs(tasks: Array, calendarTitlePrefix: string) { const ics = require('ics') const events = tasks.map(function (task) { @@ -48,7 +50,7 @@ function generateIcs(tasks: Array) { return { start: [deadline.getFullYear(), deadline.getMonth() + 1, deadline.getDate()], end: [deadline.getFullYear(), deadline.getMonth() + 1, deadline.getDate()], - title: task.title, + title: `${calendarTitlePrefix} ${task.title}`, description: buildLinks(task), url: buildLinks(task), status: 'CONFIRMED', @@ -66,17 +68,24 @@ function generateIcs(tasks: Array) { }) } +function downloadIcs(mouseClickEvent: React.MouseEvent, tasks: TaskT[], calendarTitlePrefix: string) { + const value = generateIcs(tasks, calendarTitlePrefix) + const data = new Blob([value], { type: 'text/calendar' }); + const link = window.URL.createObjectURL(data); + + mouseClickEvent.currentTarget.href = link; +} + function IcsDownload(props: Props) { const { t } = props; if (props.tasks[0]) { - const value = generateIcs(props.tasks) - // console.log(value) - const data = new Blob([value], { type: 'text/calendar' }); - const link = window.URL.createObjectURL(data); return ( ); } diff --git a/src/i18n/de.json b/src/i18n/de.json index 3740ba5..4c4231f 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -14,16 +14,20 @@ "title": "Kalender", "startDate": "Startdatum Lager", "responsible": "Verantwortlich", - "puffer": "Puffer", + "puffer": "Puffer (Tage)", "responsibleOptions": { "all": "Alle", "ll": "Lagerleitung", "al": "Abteilungsleitung", "c": "Coach" }, - "generate": "Generieren", - "download": "Download als .ics", - "filename": "Daten.ics", + "prefixPlaceholder": "Prefix für Kalendereinträge", + "prefixPreview": "Vorschau: {{calendarTitlePrefix}} Lagerdaten an Coach", + "ics": { + "generate": "Generieren", + "download": "Download als .ics", + "filename": "Daten.ics" + }, "table": { "what": "Was", "who": "Wer", diff --git a/src/i18n/fr.json b/src/i18n/fr.json index a3cceab..3578f54 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -14,16 +14,20 @@ "title": "Calendrier", "startDate": "Premier jour du camp", "responsible": "Responsable", - "puffer": "Marge", + "puffer": "Marge (jours)", "responsibleOptions": { "all": "Tous", "ll": "Responsable de camp", "al": "Responsable de groupe", "c": "Coach" }, - "generate": "Générer", - "download": "Télécharger .ics", - "filename": "Dates.ics", + "prefixPlaceholder": "Préfixe pour les entrées de calendrier", + "prefixPreview": "Aperçu: {{calendarTitlePrefix}} Données relatives", + "ics": { + "generate": "Générer", + "download": "Télécharger .ics", + "filename": "Dates.ics" + }, "table": { "what": "Quoi", "who": "Qui", diff --git a/src/i18n/it.json b/src/i18n/it.json index b40c1b1..1205ba3 100644 --- a/src/i18n/it.json +++ b/src/i18n/it.json @@ -14,16 +14,20 @@ "title": "Calendario", "startDate": "Primo giorno del campo", "responsible": "Responsabile", - "puffer": "Puffer", + "puffer": "Tampone (giorni)", "responsibleOptions": { "all": "Tutti", "ll": "Capo campo", "al": "Capo Sezione", "c": "Coach" }, - "generate": "Generieren", - "download": "Download als .ics", - "filename": "Dati.ics", + "prefixPlaceholder": "Prefisso per le voci del calendario", + "prefixPreview": "Anteprima: {{calendarTitlePrefix}} Dati del campo", + "ics": { + "generate": "Generare", + "download": "Scarica come .ics", + "filename": "Dati.ics" + }, "table": { "what": "Cosa", "who": "Chi", diff --git a/src/styles/calendar.less b/src/styles/calendar.less index 7d7b0e7..eca0a3a 100644 --- a/src/styles/calendar.less +++ b/src/styles/calendar.less @@ -1,5 +1,13 @@ .calendar { overflow-x: scroll; + + input, select { + border: 1px solid black; + height: 30px; + width: 200px; + margin: 0; + } + .calendar-table { ul { @@ -37,12 +45,30 @@ } } } + .calendar-ics { margin-bottom: 20px; + display: flex; + align-items: flex-start; + justify-content: end; + gap: 8px; + + .ics_download { + padding: 0.5em; + line-height: normal; + } } .calendar-form-container { + hr { + border: 0.5px solid #8c3c4f + } .calendar-form { + .calendar-title-prefix-hint { + font-weight: 200; + font-size: 15px; + } + list-style-type: none; padding: 0; max-width: 50%; @@ -65,19 +91,12 @@ justify-content: space-between; margin-top: 8px; - input, select { - border: 1px solid black; - height: 30px; - width: 200px; - margin: 0; - } - #puffer { - width: 197px; + width: 200px; } #responsible { - width: 201px; + width: 206px; } } } From dc781ed9d0ccb1e507e7237c0b7c7edd8d4c1fd7 Mon Sep 17 00:00:00 2001 From: Emily Wangler Date: Sat, 30 Sep 2023 18:55:42 +0200 Subject: [PATCH 2/2] fix overflow --- src/styles/calendar.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/calendar.less b/src/styles/calendar.less index eca0a3a..53954af 100644 --- a/src/styles/calendar.less +++ b/src/styles/calendar.less @@ -67,6 +67,7 @@ .calendar-title-prefix-hint { font-weight: 200; font-size: 15px; + width: 206px; } list-style-type: none;