Kalender Update

* Feature Implementation Excel Export
This commit is contained in:
Daniel Spitzer
2025-03-03 09:21:24 +01:00
parent 007a04f332
commit cb67e821ec
5 changed files with 391 additions and 171 deletions

View File

@@ -104,6 +104,7 @@ endforeach;
class="btn btn-light btn-light-search top-search-filter"><i
class="fa-duotone fa-solid fa-phone-volume fa-calendar-call fa-calendar-call-search"></i>
</button>
</div>
</div>
<?php if (!$rights) : ?>
@@ -111,7 +112,14 @@ endforeach;
<span class="font-18 font-weight-500">Du wurdest nicht für den Kalender frei geschalten.</span>
</div>
<?php die(); endif; ?>
<div class="d-inline-block mr-1">
<button title="Excel Export"
class="btn btn-light btn-xls-calendar">
<i class="fa-duotone fa-solid fa-file-xls fa-xls-calendar"></i>
</div>
</button>
<div class="d-inline-block w-50 search-div" style="margin-top: -7px;">
<select id="jumpevent" class="jumpevent"></select>
</div>
@@ -351,142 +359,146 @@ endforeach;
</div>
</div>
<div class="modal fade" id="EventModal" aria-labelledby="EventModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title font-18 ml-2" id="EventModalLabel"><i
class="fa-duotone fa-solid fa-calendar-symbol"></i> <span>neuer Termin</span></h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row justify-content-center">
<div class="col-1">
<label for="name" class="col-form-label fw-medium ">Betreff</label>
</div>
<div class="col-6">
<div class="mb-2">
<input type="text" class="form-control is-require eventmodal-input" id="name">
</div>
</div>
<div class="col-3">
<div class="input-group mb-2">
<span title="Erinnerung" class="input-group-text spanwidht">Typ</span>
<select class="form-control form-select select-2" aria-label="Default select" id="type">
<option value="1">Termin</option>
<option value="2">IBN Xinon</option>
<option value="3">IBN ESTMK</option>
<option value="4">IBN SNOPP</option>
<option value="5">Störung</option>
<option value="6">Support Gespräch</option>
</select>
</div>
</div>
<div class="col-1 text-center">
<i title="Normal" class="fa-duotone privacy-click fa-regular fa-unlock mt-1"></i>
</div>
<div class="modal fade" id="EventModal" aria-labelledby="EventModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title font-18 ml-2" id="EventModalLabel"><i
class="fa-duotone fa-solid fa-calendar-symbol"></i> <span>neuer Termin</span></h1>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="row justify-content-center">
<div class="col-1">
<label for="location" class="col-form-label fw-medium ">Ort</label>
</div>
<div class="col-6">
<div class="mb-2">
<input type="text" class="form-control eventmodal-input" id="location">
<div class="modal-body">
<div class="row justify-content-center">
<div class="col-1">
<label for="name" class="col-form-label fw-medium ">Betreff</label>
</div>
<div class="col-6">
<div class="mb-2">
<input type="text" class="form-control is-require eventmodal-input" id="name">
</div>
</div>
<div class="col-3">
<div class="input-group mb-2">
<span title="Erinnerung" class="input-group-text spanwidht">Typ</span>
<select class="form-control form-select select-2" aria-label="Default select" id="type">
<option value="1">Termin</option>
<option value="2">IBN Xinon</option>
<option value="3">IBN ESTMK</option>
<option value="4">IBN SNOPP</option>
<option value="5">Störung</option>
<option value="6">Support Gespräch</option>
</select>
</div>
</div>
<div class="col-1 text-center">
<i title="Normal" class="fa-duotone privacy-click fa-regular fa-unlock mt-1"></i>
</div>
</div>
<div class="col-4">
<div class="input-group mb-2">
<div class="row justify-content-center">
<div class="col-1">
<label for="location" class="col-form-label fw-medium ">Ort</label>
</div>
<div class="col-6">
<div class="mb-2">
<input type="text" class="form-control eventmodal-input" id="location">
</div>
</div>
<div class="col-4">
<div class="input-group mb-2">
<span title="Erinnerung" class="input-group-text spanwidht"><i
class="fa-regular fa-eye"></i></span>
<select class="form-control form-select" aria-label="Default select" id="busy">
<option value="1">gebucht</option>
<option value="0">frei</option>
<option value="2">mit Vorbehalt</option>
</select>
<select class="form-control form-select" aria-label="Default select" id="busy">
<option value="1">gebucht</option>
<option value="0">frei</option>
<option value="2">mit Vorbehalt</option>
</select>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="row justify-content-center">
<div class="col-4">
<div class="input-group mb-2">
<span class="input-group-text spanwidht">Start</span>
<input id="start-date" type="date" class="form-control is-require eventmodal-input"
placeholder="Datum"
aria-label="Datum"
aria-describedby="Datum">
<div class="col-4">
<div class="input-group mb-2">
<span class="input-group-text spanwidht">Start</span>
<input id="start-date" type="date" class="form-control is-require eventmodal-input"
placeholder="Datum"
aria-label="Datum"
aria-describedby="Datum">
</div>
</div>
<div class="col-2">
<input id="start-time" type="time" class="form-control is-require eventmodal-input"
placeholder="Uhrzeit"
aria-label="Uhrzeit"
aria-describedby="Uhrzeit">
</div>
<div class="col-2 text-center">
<div class="form-check" style="margin-top: 7px;">
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
id="allday"> <label class="form-check-label fw-medium checkbox-label"
for="allday">
Ganztägig
</label>
</div>
</div>
<div class="col-2 text-right">
<div class="form-check" style="margin-top: 7px;">
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
id="recurringCheck">
<label class="form-check-label fw-medium checkbox-label" for="recurringCheck">
Serientermin
</label>
</div>
</div>
</div>
<div class="col-2">
<input id="start-time" type="time" class="form-control is-require eventmodal-input"
placeholder="Uhrzeit"
aria-label="Uhrzeit"
aria-describedby="Uhrzeit">
</div>
<div class="col-2 text-center">
<div class="form-check" style="margin-top: 7px;">
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
id="allday"> <label class="form-check-label fw-medium checkbox-label" for="allday">
Ganztägig
</label>
<div class="row justify-content-center">
<div class="col-4">
<div class="input-group mb-2">
<span class="input-group-text spanwidht">Ende</span>
<input id="end-date" type="date" class="form-control is-require eventmodal-input"
placeholder="Datum"
aria-label="Datum"
aria-describedby="Datum">
</div>
</div>
</div>
<div class="col-2 text-right">
<div class="form-check" style="margin-top: 7px;">
<input class="form-check-input eventmodal-checkbox" type="checkbox" value="" id="recurringCheck">
<label class="form-check-label fw-medium checkbox-label" for="recurringCheck">
Serientermin
</label>
<div class="col-2">
<input id="end-time" type="time" class="form-control is-require eventmodal-input"
placeholder="Uhrzeit"
aria-label="Uhrzeit"
aria-describedby="Uhrzeit">
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-4">
<div class="input-group mb-2">
<span class="input-group-text spanwidht">Ende</span>
<input id="end-date" type="date" class="form-control is-require eventmodal-input"
placeholder="Datum"
aria-label="Datum"
aria-describedby="Datum">
</div>
</div>
<div class="col-2">
<input id="end-time" type="time" class="form-control is-require eventmodal-input"
placeholder="Uhrzeit"
aria-label="Uhrzeit"
aria-describedby="Uhrzeit">
</div>
<div class="col-4">
<div class="input-group mb-2">
<div class="col-4">
<div class="input-group mb-2">
<span title="Erinnerung" class="input-group-text spanwidht"><i
class="fa-regular fa-bell"></i></span>
<select class="form-control form-select select2" aria-label="Default select" id="reminder">
<option value="NULL">Keine</option>
<option value="0">Zum Termin</option>
<option value="300">5 Minuten</option>
<option value="600">10 Minuten</option>
<option value="900">15 Minuten</option>
<option value="1800">30 Minuten</option>
<option value="3600">1 Stunde</option>
<option value="86400">1 Tag</option>
<option value="604800">1 Woche</option>
</select>
<select class="form-control form-select select2" aria-label="Default select"
id="reminder">
<option value="NULL">Keine</option>
<option value="0">Zum Termin</option>
<option value="300">5 Minuten</option>
<option value="600">10 Minuten</option>
<option value="900">15 Minuten</option>
<option value="1800">30 Minuten</option>
<option value="3600">1 Stunde</option>
<option value="86400">1 Tag</option>
<option value="604800">1 Woche</option>
</select>
</div>
</div>
</div>
</div>
<!-- Serientermin-Checkbox und zugehörige RRule-Optionen -->
<div class="row" id="recurring-settings" style="display:none;">
<div class="col-1"></div>
<div class="col-3"">
<!-- Serientermin-Checkbox und zugehörige RRule-Optionen -->
<div class="row" id="recurring-settings" style="display:none;">
<div class="col-1"></div>
<div class="col-3"
">
<!-- Frequenz: Täglich / Wöchentlich / Monatlich / Jährlich -->
<div class="mb-2">
<label for="rrule-frequency" class="col-form-label fw-medium">Wiederholungstyp</label>
@@ -509,7 +521,7 @@ endforeach;
<input type="date" class="form-control" id="rrule-until">
</div>
</div>
<!-- Wöchentliche Optionen (z.B. jeden Dienstag, jeden Freitag + Montag) -->
<!-- Wöchentliche Optionen (z.B. jeden Dienstag, jeden Freitag + Montag) -->
<div class="col-7">
<div class="mb-2" id="weekly-options" style="display:none;">
<label for="rrule-byweekday" class="col-form-label fw-medium">Wochentag(e)</label>
@@ -534,7 +546,7 @@ endforeach;
<label class="mr-2 col-form-label fw-medium col-2">Tag:</label>
<select class="form-control w-auto col-3" id="rrule-bymonthday">
<!-- Auswahl 131 -->
<?php for($i=1; $i<=31; $i++): ?>
<?php for ($i = 1; $i <= 31; $i++): ?>
<option value="<?= $i ?>"><?= $i ?></option>
<?php endfor; ?>
</select>
@@ -658,6 +670,7 @@ endforeach;
</div>
<div class="d-inline-block" id="customer-info-check-info"></div>
</div>
<div id="relContainer2" style="position:relative">
<select id="customer" class="jumpevent"></select>
</div>
@@ -739,13 +752,16 @@ endforeach;
</div>
<div id="output"></div>
<script type="text/javascript" src="<?= self::getResourcePath() ?>plugins/select2/js/i18n/de.js?<?= $git_merge_ts ?>"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>plugins/tinymce/tinymce.min.js?<?= $git_merge_ts ?>"></script>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>plugins/select2/js/i18n/de.js?<?= $git_merge_ts ?>"></script>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>plugins/tinymce/tinymce.min.js?<?= $git_merge_ts ?>"></script>
<script>
let requestUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEvents']) ?>";
let requestEventUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEvent']) ?>";
let requestEventSearchURL = "<?= self::getUrl("Calendar", "api", ['do' => 'searchCalendarEvents']) ?>";
let requestgenerateEventsxlsx = "<?= self::getUrl("Calendar", "api", ['do' => 'generateCalendarEventsXlsx']) ?>";
let requestEventAttachmentUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEventAttachment']) ?>";
let requestEventAttachmentTmpUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEventAttachmentTmp']) ?>";
let requestEventAttachmentTmpDeleteUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'deleteCalendarEventAttachmentTmp']) ?>";

View File

@@ -1,5 +1,12 @@
<?php
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Helper\Html;
class CalendarController extends mfBaseController
{
@@ -45,6 +52,11 @@ class CalendarController extends mfBaseController
$calendarEvents = CalendarModel::searchCalendarEvents($r);
return $calendarEvents;
die();
case "generateCalendarEventsXlsx" :
$r = $this->request;
$this->generateXlsx($r);
return $calendarEvents;
die();
case "getCalendarEventAttachment" :
$r = $this->request;
$id = ($r->id);
@@ -110,9 +122,9 @@ class CalendarController extends mfBaseController
case "insertCalendarEvent":
$r = $this->request;
if ($r->rruleData) {
$rrules=json_encode($this->generateGraphRecurrence($r->rruleData, $r->start));
$rrules = json_encode($this->generateGraphRecurrence($r->rruleData, $r->start));
}
$calendarEvents = CalendarModel::insertCalendarEvent($r, $this->me,$rrules);
$calendarEvents = CalendarModel::insertCalendarEvent($r, $this->me, $rrules);
if ($r->customer_info_check) {
if ($r->customer_info_type == 1) {
$body = $r->customer_info_text;
@@ -392,10 +404,11 @@ class CalendarController extends mfBaseController
die();
}
private function generateGraphRecurrence($data, $startDate) {
private function generateGraphRecurrence($data, $startDate)
{
$graph = [
'pattern' => [],
'range' => []
'range' => []
];
$freq = strtoupper($data['rrule_frequency']);
switch ($freq) {
@@ -414,10 +427,10 @@ class CalendarController extends mfBaseController
// Mapping: 1 => first, 2 => second, 3 => third, 4 => fourth, -1 => last
$setpos = intval($data['rrule_setpos']);
$indexMapping = [
1 => 'first',
2 => 'second',
3 => 'third',
4 => 'fourth',
1 => 'first',
2 => 'second',
3 => 'third',
4 => 'fourth',
-1 => 'last'
];
$graph['pattern']['index'] = isset($indexMapping[$setpos]) ? $indexMapping[$setpos] : 'first';
@@ -438,7 +451,7 @@ class CalendarController extends mfBaseController
if ($freq === 'WEEKLY' && !empty($data['rrule-byweekday'])) {
$days = is_array($data['rrule-byweekday']) ? $data['rrule-byweekday'] : [$data['rrule-byweekday']];
$graphDays = [];
foreach($days as $day) {
foreach ($days as $day) {
$graphDays[] = $this->convertDayToGraph(strtoupper($day));
}
$graph['pattern']['daysOfWeek'] = $graphDays;
@@ -459,7 +472,8 @@ class CalendarController extends mfBaseController
}
private function convertDayToGraph($dayAbbrev) {
private function convertDayToGraph($dayAbbrev)
{
$mapping = [
'MO' => 'monday',
'TU' => 'tuesday',
@@ -472,6 +486,104 @@ class CalendarController extends mfBaseController
return isset($mapping[$dayAbbrev]) ? $mapping[$dayAbbrev] : $dayAbbrev;
}
private function generateXlsx($r)
{
$calendarEvents = json_decode(CalendarModel::getCalendarEvents($this->me->id, 0, $r, true), true);
$eventTypes = CalendarModel::$eventTypes;
$xls = new Spreadsheet();
$sheet = $xls->getActiveSheet();
$writer = new Xlsx($xls);
$sheet->getStyle('A1:AN1')->getFont()->setBold(true);
$sheet->getStyle('A:E')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->getStyle('I:L')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->getColumnDimension('A')->setWidth(25);
$sheet->getColumnDimension('B')->setWidth(15);
$sheet->getColumnDimension('C')->setWidth(10);
$sheet->getColumnDimension('D')->setWidth(15);
$sheet->getColumnDimension('E')->setWidth(10);
$sheet->getColumnDimension('F')->setWidth(40);
$sheet->getColumnDimension('G')->setWidth(40);
$sheet->getColumnDimension('H')->setWidth(20);
$sheet->getColumnDimension('I')->setWidth(10);
$sheet->getColumnDimension('J')->setWidth(10);
$sheet->getColumnDimension('K')->setWidth(15);
$sheet->getColumnDimension('L')->setWidth(15);
$sheet->setCellValue([1, 1], 'Kalender')
->setCellValue([2, 1], 'Startdatum')
->setCellValue([3, 1], 'Startzeit')
->setCellValue([4, 1], 'Enddatum')
->setCellValue([5, 1], 'Endzeit')
->setCellValue([6, 1], 'Betreff')
->setCellValue([7, 1], 'Ort')
->setCellValue([8, 1], 'Beschreibung')
->setCellValue([9, 1], 'Termintyp')
->setCellValue([10, 1], 'Privat')
->setCellValue([11, 1], 'Sichtbarkeit')
->setCellValue([12, 1], 'Organisator')
;
$counter = 2;
foreach ($calendarEvents['data'] as $event) {
if ($event['privateflag']['privateflag']) {
$event['privateflag']['privateflag'] = "Ja";
} else {
$event['privateflag']['privateflag'] = "Nein";
}
if ($event['isorganizer']['isorganizer']) {
$event['isorganizer']['isorganizer'] = "Ja";
} else {
$event['isorganizer']['isorganizer'] = "Nein";
}
if ($event['busy']['busy'] == 1) {
$event['busy']['busy'] = "gebucht";
} else if ($event['busy']['busy'] == 2) {
$event['busy']['busy'] = "mit Vorbehalt";
} else {
$event['busy']['busy'] = "frei";
}
if ($event['allDay']['allDay'] == 0) {
$starttime = date("H:i", strtotime($event['cstart']['cstart']));
$endtime = date("H:i", strtotime($event['cend']['cend']));
$startdate = date("d.m.Y", strtotime($event['cstart']['cstart']));
$enddate = date("d.m.Y", strtotime($event['cend']['cend']));
} else {
$starttime = "";
$startdate = date("d.m.Y", strtotime($event['cstart']['cstart']));
$endtime = "";
$enddate = date("d.m.Y", strtotime($event['cend']['cend']) - 7500);
}
if ($event['event_type']['event_type'] != "") {
$helper = new Html();
$richText = $helper->toRichTextObject($event['description']['description']);
$calendarType = $eventTypes[$event['event_type']['event_type']];
$sheet->setCellValue([1, $counter], $event['calendar_name']['calendar_name'])
->setCellValue([2, $counter], $startdate)
->setCellValue([3, $counter], $starttime)
->setCellValue([4, $counter], $enddate)
->setCellValue([5, $counter], $endtime)
->setCellValue([6, $counter], $event['ccategory']['ccategory'])
->setCellValue([7, $counter], $event['location']['location'])
->setCellValue([8, $counter], $richText)
->setCellValue([9, $counter], $calendarType)
->setCellValue([10, $counter], $event['privateflag']['privateflag'])
->setCellValue([11, $counter], $event['busy']['busy'])
->setCellValue([12, $counter], $event['isorganizer']['isorganizer'])
;
$counter++;
}
}
header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-disposition: attachment; filename="Kalender-' . date('Y-m-d_H-i-s') . '-' . uniqid() . '.xlsx"');
$writer->save('php://output');
exit;
}
protected function indexAction()
{
$this->layout()->setTemplate("Calendar/Index");

View File

@@ -32,6 +32,15 @@ class CalendarModel
'690', // Spusu
'699' // 3 (Drei)
);
public static $eventTypes = array(
1 => 'Termin',
2 => 'IBN Xinon',
3 => 'IBN ESTMK',
4 => 'IBN Snopp',
5 => 'Störung',
6 => 'Support Gespräch'
);
public static $standardCalendarColors = [
'#b3d5f3', '#d0e2c0', '#bac2d4', '#c6d4c0', '#e3e3e3',
'#acdce5', '#cdb6c0', '#aae0e1', '#d9d9d9', '#d9e5d5',
@@ -149,7 +158,7 @@ class CalendarModel
die();
}
public static function getCalendarEvents($me, $id = 0, $r = 0)
public static function getCalendarEvents($me, $id = 0, $r = 0, $returnvalues = false)
{
$rrulefreq = array('daily' => 'DAILY', 'weekly' => 'WEEKLY', 'relativeMonthly' => 'MONTHLY', 'yearly' => 'YEARLY', 'absoluteMonthly' => 'absoluteMonthly');
$calendar = self::search(array("user_id" => $me));
@@ -196,7 +205,7 @@ class CalendarModel
}
$sql = "SELECT `cal_events`.id,`cal_events`.categories, uuid, calendar_id, `cal_events`.user_id, start_time, end_time, timezone, all_day_event, `cal_events`.name,`cal_calendars`.name calendar_name, description, location, repeat_end_time, reminder, ctime,cname, mtime,mname, muser_id, busy, status, resource_event_id, private, rrule, `cal_events`.background, `cal_events`.files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, is_organizer,event_type,busy,recurrence,rrule_events FROM cal_events INNER JOIN `cal_calendars` ON (`cal_calendars`.`id`=`cal_events`.`calendar_id`) WHERE 1=1 $where ";
$sql = "SELECT `cal_events`.id,`cal_events`.categories, uuid, calendar_id, `cal_events`.user_id, start_time, end_time, timezone, all_day_event, `cal_events`.name,`cal_calendars`.name calendar_name, description, location, repeat_end_time, reminder, ctime,cname, mtime,mname, muser_id, busy, status, resource_event_id, private, rrule, `cal_events`.background, `cal_events`.files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, is_organizer,event_type,busy,recurrence,rrule_events FROM cal_events INNER JOIN `cal_calendars` ON (`cal_calendars`.`id`=`cal_events`.`calendar_id`) WHERE 1=1 $where ORDER BY start_time DESC";
$res = $dbcal->query($sql);
if ($dbcal->num_rows($res)) {
@@ -384,7 +393,7 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
$json = json_encode($json);
if ($id == 0) {
if ($id == 0 && $returnvalues == false) {
echo trim($json);
die();
} else {

View File

@@ -673,11 +673,12 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
margin-left: -28px;
margin-top: 4px;
}
.cursor-alias{
.cursor-alias {
cursor: alias;
}
.fa-calendar-alert
{
.fa-calendar-alert {
font-size: 15px;
vertical-align: top;
margin-top: -1px;
@@ -688,57 +689,65 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
color: #ff0000;
opacity: 0.7;
}
.fa-calendar-alert:before {
color: #fff;
}
.fa-calendar-alert-search
{
.fa-calendar-alert-search {
font-size: 22px;
}
.logo-top-search
{
.logo-top-search {
height: 20px;
vertical-align: top;
cursor: pointer;
}
.btn-light-search
{
.btn-light-search {
border-color: #e5e5e5;
padding: 3px 6px;
}
.top-search-filter
{
filter:grayscale(100%);
.top-search-filter {
filter: grayscale(100%);
}
.fc-event-time {
z-index: 100;
}
.note-editor .dropdown-item {
padding: .15rem 1.2rem;
}
.note-editable p {
line-height: 1.2;
margin-bottom: 0;
}
.tooltip-description p {
margin-bottom: 0;
line-height: 1.2;
}
.note-dropdown-menu {
max-height: 250px !important;
overflow-y: auto !important;
z-index: 99999 !important;
}
.tox-dialog {
z-index: 1060 !important; /* oder ein höherer Wert, je nach Bedarf */
}
.tox .tox-tbtn--select {
max-width: 95px;
}
.fa-calendar-call
{
.fa-calendar-call {
font-size: 13px;
vertical-align: top;
margin-top: 0px;
@@ -748,12 +757,30 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
color: #ff0000;
opacity: 1;
}
.fa-calendar-call:before {
content: "\f2a0";
color: #000000;
opacity: 1;
}
.fa-calendar-call-search {
font-size: 21px;
margin-top: 0px;
}
}
.fa-xls-calendar {
font-size: 24px;
padding-top: 2px;
padding-bottom: 2px;
}
.btn-xls-calendar {
padding: 3px 6px;
background-color: #ffffff;
}
.btn-xls-calendar:hover, .btn-xls-calendar:focus, .btn-xls-calendar:active {
background-color: #ffffff !important;
border-color: #ffffff !important;
}

View File

@@ -556,8 +556,7 @@ document.addEventListener('DOMContentLoaded', function () {
$('.show-attendee').hide();
$('#recurringCheck').prop('checked', true);
$('#recurringCheck').change();
if (data.data.recurrence)
{
if (data.data.recurrence) {
$('#rrule-frequency').val(data.data.recurrence.recurrence.rrule_frequency);
$('#rrule-frequency').trigger('change');
$('#rrule-interval').val(data.data.recurrence.recurrence.rrule_interval);
@@ -1321,26 +1320,26 @@ $(document).ready(function () {
users.push($(this).val());
});
if ($('#recurringCheck').is(':checked') && $('#rrule-frequency').val() !== '') {
var rruleData = {};
rruleData.rrule_frequency = $('#rrule-frequency').val();
if ($('#recurringCheck').is(':checked') && $('#rrule-frequency').val() !== '') {
var rruleData = {};
rruleData.rrule_frequency = $('#rrule-frequency').val();
if (rruleData.rrule_frequency === 'WEEKLY') {
// Mehrere Wochentage als Array
rruleData['rrule-byweekday'] = $('#rrule-byweekday').val();
} else if (rruleData.rrule_frequency === 'MONTHLY') {
rruleData.monthly_type = $('#monthly-type').val();
if (rruleData.monthly_type === 'BYMONTHDAY') {
rruleData.rrule_bymonthday = $('#rrule-bymonthday').val();
} else if (rruleData.monthly_type === 'BYSETPOS') {
rruleData.rrule_setpos = $('#rrule-setpos').val();
rruleData.rrule_bynweekday = $('#rrule-bynweekday').val();
}
if (rruleData.rrule_frequency === 'WEEKLY') {
// Mehrere Wochentage als Array
rruleData['rrule-byweekday'] = $('#rrule-byweekday').val();
} else if (rruleData.rrule_frequency === 'MONTHLY') {
rruleData.monthly_type = $('#monthly-type').val();
if (rruleData.monthly_type === 'BYMONTHDAY') {
rruleData.rrule_bymonthday = $('#rrule-bymonthday').val();
} else if (rruleData.monthly_type === 'BYSETPOS') {
rruleData.rrule_setpos = $('#rrule-setpos').val();
rruleData.rrule_bynweekday = $('#rrule-bynweekday').val();
}
// Optionale Felder
rruleData.rrule_count = $('#rrule-count').val();
rruleData.rrule_until = $('#rrule-until').val();
}
// Optionale Felder
rruleData.rrule_count = $('#rrule-count').val();
rruleData.rrule_until = $('#rrule-until').val();
}
$.post(requestInsertUrl, {
@@ -2094,6 +2093,63 @@ $(document).ready(function () {
}
});
$("body").on("click", ".fa-xls-calendar", function (e) {
let checkbox = $(".calendar-check");
let calendarFilter = $('.btn-light-search');
let visibleCalendars = [];
let visibleCalendarTypes = [];
let mycalendar_id = $('#calendar-id').data('calendarid');
visibleCalendars.push(0);
checkbox.each(function () {
if ($(this).prop('checked')) {
visibleCalendars.push($(this).data('calendar_id'));
}
});
calendarFilter.each(function () {
if (!$(this).hasClass('top-search-filter')) {
visibleCalendarTypes.push($(this).data('ctype'));
}
});
$.ajax({
url: requestgenerateEventsxlsx,
method: 'POST',
data: {
visibleCalendars: visibleCalendars,
visibleCalendarTypes: visibleCalendarTypes
},
xhrFields: {
responseType: 'blob' // Erwartet binäre Daten als Blob
},
success: function (data, status, xhr) {
// Header auslesen, um den Dateinamen zu erhalten
var disposition = xhr.getResponseHeader('Content-Disposition');
var filename = "download.xlsx";
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
}
// Blob in eine URL umwandeln und Download auslösen
var url = window.URL.createObjectURL(data);
var a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
},
error: function (jqXHR, status, error) {
console.error("Download error:", error);
}
});
});
$("body").on("blur", ".cal-group-name-input", function (e) {
let groupname = $.trim($(this).val());
if (groupname.length > 3) {
@@ -2461,7 +2517,7 @@ $(document).ready(function () {
;
});
}
$(document).on('focusin', function (e) {
if ($(e.target).closest(".tox-tinymce, .tox-tinymce-aux, .moxman-window, .tam-assetmanager-root").length) {
e.stopImmediatePropagation();
@@ -2472,7 +2528,7 @@ $(document).ready(function () {
$('#recurringCheck').on('change', function () {
if ($(this).is(':checked')) {
$('#recurring-settings').show();
$('#rrule-until').attr('min' , $('#start-date').val());
$('#rrule-until').attr('min', $('#start-date').val());
} else {
$('#recurring-settings').hide();
$('#weekly-options').hide();