OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)
This commit is contained in:
76
app/Domain/Calendar/Templates/addEvent.blade.php
Normal file
76
app/Domain/Calendar/Templates/addEvent.blade.php
Normal file
@@ -0,0 +1,76 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
$values = $values ?? [];
|
||||
@endphp
|
||||
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light">{!! __('subtitles.event') !!}</h4>
|
||||
|
||||
<form action="{{ BASE_URL }}/calendar/addEvent/" method="post" class='formModal'>
|
||||
@csrf
|
||||
|
||||
@dispatchEvent('afterFormOpen')
|
||||
|
||||
<label for="description">{!! __('label.title') !!}</label>
|
||||
<x-global::forms.text-input id="description" name="description" value="{{ $tpl->escape($values['description']) }}" /><br />
|
||||
|
||||
<div class="par">
|
||||
<label for="dateFrom">{!! __('label.start_date') !!}</label>
|
||||
<input type="text" id="event_date_from" name="dateFrom" value="" autocomplete="off" /><br/>
|
||||
</div>
|
||||
<div class="par">
|
||||
<label for="">{!! __('label.start_time') !!}</label>
|
||||
<div class="input-append bootstrap-timepicker">
|
||||
<input type="time" id="event_time_from" name="timeFrom" value="" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="par">
|
||||
<label for="dateTo">{!! __('label.end_date') !!}</label>
|
||||
<input type="text" id="event_date_to" name="dateTo" value="" autocomplete="off" /><br/>
|
||||
</div>
|
||||
<div class="par">
|
||||
<label for="">{!! __('label.end_time') !!} </label>
|
||||
<div class="input-append bootstrap-timepicker">
|
||||
<input type="time" id="event_time_to" name="timeTo" value="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="allDay">{!! __('label.all_day') !!}</label>
|
||||
<input type="checkbox" id="allDay" name="allDay"
|
||||
@if (isset($values['allDay']) && $values['allDay'] === true)
|
||||
checked="checked"
|
||||
@endif
|
||||
/><br /><br />
|
||||
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
|
||||
<p class="stdformbutton">
|
||||
<input type="hidden" value="1" name="save" />
|
||||
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="saveEvent" id="saveEvent" />
|
||||
</p>
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
|
||||
@dispatchEvent('scripts.afterOpen')
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
leantime.calendarController.initEventDatepickers();
|
||||
});
|
||||
|
||||
@dispatchEvent('scripts.beforeClose')
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
|
||||
@endsection
|
||||
92
app/Domain/Calendar/Templates/calendarSettings.blade.php
Normal file
92
app/Domain/Calendar/Templates/calendarSettings.blade.php
Normal file
@@ -0,0 +1,92 @@
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light"><i class="fa fa-cog"></i> {{ __('label.calendar_settings') }}</h4>
|
||||
|
||||
<br />
|
||||
|
||||
{{-- Connected Calendars Section --}}
|
||||
<h5 class="subtitle">{{ __('label.connected_calendars') }}</h5>
|
||||
|
||||
@if(count($externalCalendars) > 0)
|
||||
<ul class="simpleList" style="margin-bottom: 20px;">
|
||||
@foreach($externalCalendars as $calendar)
|
||||
<li style="padding: 10px; background: var(--secondary-background); border-radius: var(--box-radius-small); margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>
|
||||
<span class="indicatorCircle" style="background-color: {{ e($calendar['colorClass']) }};"></span>
|
||||
<strong>{{ $calendar['name'] }}</strong>
|
||||
@if(!empty($calendar['subtitle']))
|
||||
<br><small class="text-muted">{!! $calendar['subtitle'] !!}</small>
|
||||
@endif
|
||||
</span>
|
||||
<span style="white-space: nowrap;">
|
||||
@if(!empty($calendar['actions']))
|
||||
{{-- Plugin-provided per-calendar actions --}}
|
||||
@foreach($calendar['actions'] as $action)
|
||||
<a href="{{ $action['url'] }}"
|
||||
class="{{ ($action['type'] ?? 'link') === 'modal' ? 'formModal' : '' }}"
|
||||
data-tippy-content="{{ $action['tooltip'] ?? '' }}">
|
||||
<i class="{{ e($action['icon']) }}"></i>
|
||||
</a>
|
||||
|
||||
@endforeach
|
||||
@elseif(empty($calendar['managedByPlugin']))
|
||||
{{-- Default iCal calendar actions --}}
|
||||
<a href="#/calendar/editExternal/{{ $calendar['id'] }}" class="formModal" data-tippy-content="{{ __('label.edit') }}">
|
||||
<i class="fa fa-pen"></i>
|
||||
</a>
|
||||
|
||||
<a href="#/calendar/delExternalCalendar/{{ $calendar['id'] }}" class="delete" data-tippy-content="{{ __('label.delete') }}">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
@endif
|
||||
</span>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@else
|
||||
<p class="text-muted small" style="font-style: italic;">
|
||||
{{ __('label.no_connected_calendars') }}
|
||||
</p>
|
||||
<br />
|
||||
@endif
|
||||
|
||||
{{-- Plugin-injected sections (Google Calendar, etc.) --}}
|
||||
{{-- Note: Plugin content via {!! !!} is trusted. Plugins are responsible for sanitizing their output. --}}
|
||||
@foreach($pluginSections as $section)
|
||||
<hr style="margin: 20px 0;" />
|
||||
|
||||
<h5 class="subtitle">
|
||||
@if(isset($section['icon']))
|
||||
@if(($section['iconType'] ?? 'fontawesome') === 'svg')
|
||||
<span style="display: inline-block; width: 20px; height: 20px; vertical-align: middle; margin-right: 8px;">{!! $section['icon'] !!}</span>
|
||||
@else
|
||||
<i class="{{ e($section['icon']) }}" style="margin-right: 8px;"></i>
|
||||
@endif
|
||||
@endif
|
||||
{{ $section['title'] }}
|
||||
</h5>
|
||||
|
||||
@if(isset($section['description']))
|
||||
<p class="text-muted small">{{ $section['description'] }}</p>
|
||||
@endif
|
||||
|
||||
@if(isset($section['content']))
|
||||
{!! $section['content'] !!}
|
||||
@endif
|
||||
|
||||
@if(isset($section['actions']))
|
||||
<div style="margin-top: 10px;">
|
||||
@foreach($section['actions'] as $action)
|
||||
<a href="{{ $action['url'] }}"
|
||||
class="btn {{ $action['class'] ?? 'btn-default' }} {{ ($action['type'] ?? 'link') === 'modal' ? 'formModal' : '' }}">
|
||||
@if(isset($action['icon']))
|
||||
<i class="{{ e($action['icon']) }}"></i>
|
||||
@endif
|
||||
{{ $action['label'] }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@dispatchEvent('afterCalendarSettings')
|
||||
68
app/Domain/Calendar/Templates/connectCalendar.blade.php
Normal file
68
app/Domain/Calendar/Templates/connectCalendar.blade.php
Normal file
@@ -0,0 +1,68 @@
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light"><i class="fa-regular fa-calendar-plus"></i> {{ __('label.connect_calendar_title') }}</h4>
|
||||
<p class="subtitle">{{ __('label.connect_calendar_description') }}</p>
|
||||
|
||||
<br />
|
||||
|
||||
{{-- iCal URL Import --}}
|
||||
<x-global::accordion id="connectCalendar-ical" class="noBackground">
|
||||
<x-slot name="title">
|
||||
<i class="fa fa-calendar-alt" style="margin-right: 5px;"></i> {{ __('label.ical_url_title') }}
|
||||
</x-slot>
|
||||
<x-slot name="content" style="padding-top: 10px;">
|
||||
<p class="text-muted small">{{ __('label.ical_url_description') }}</p>
|
||||
|
||||
<form action="{{ BASE_URL }}/calendar/connectCalendar" method="post" class="formModal">
|
||||
@csrf
|
||||
<label for="ical_name">{{ __('label.calendar_name') }}:</label>
|
||||
<x-global::forms.text-input id="ical_name" name="name" autocomplete="off" placeholder="{{ __('label.calendar_name') }}" /><br />
|
||||
|
||||
<label for="ical_url">{{ __('label.ical_url') }}:</label>
|
||||
<x-global::forms.text-input id="ical_url" name="url" autocomplete="off" style="width:100%;" placeholder="https://example.com/calendar.ics" /><br />
|
||||
|
||||
<label for="ical_color">{{ __('label.color') }}:</label>
|
||||
<input type="text" id="ical_color" name="colorClass" autocomplete="off" value="#082236" class="simpleColorPicker"/>
|
||||
|
||||
<br /><br />
|
||||
<x-global::forms.button tag="input" inputType="submit" name="save" contentRole="primary" :labelText="__('label.import_ical_button')" />
|
||||
</form>
|
||||
</x-slot>
|
||||
</x-global::accordion>
|
||||
|
||||
{{-- Plugin-injected providers (CalDAV, Google Calendar, etc.) --}}
|
||||
{{-- Note: SVG icons via {!! !!} are trusted plugin content. Plugins are responsible for sanitizing their output. --}}
|
||||
@foreach($providers as $provider)
|
||||
@if($provider['id'] !== 'ical')
|
||||
<x-global::accordion id="connectCalendar-{{ e($provider['id']) }}" class="noBackground">
|
||||
<x-slot name="title">
|
||||
@if(($provider['iconType'] ?? 'fontawesome') === 'svg')
|
||||
<span style="display: inline-block; width: 18px; height: 18px; vertical-align: middle; margin-right: 5px;">{!! $provider['icon'] !!}</span>
|
||||
@else
|
||||
<i class="{{ e($provider['icon']) }}" style="margin-right: 5px;"></i>
|
||||
@endif
|
||||
{{ $provider['title'] }}
|
||||
</x-slot>
|
||||
<x-slot name="content" style="padding-top: 10px;">
|
||||
<p class="text-muted small">{{ $provider['description'] }}</p>
|
||||
<x-global::forms.button tag="a" link="{{ $provider['actionUrl'] }}"
|
||||
contentRole="primary" class="{{ ($provider['actionType'] ?? 'link') === 'modal' ? 'formModal' : '' }}">
|
||||
{{ $provider['actionLabel'] }}
|
||||
</x-global::forms.button>
|
||||
</x-slot>
|
||||
</x-global::accordion>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@dispatchEvent('afterProviders')
|
||||
|
||||
<br />
|
||||
<p class="text-muted small">
|
||||
{{ __('label.more_integrations_hint') }}
|
||||
</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function() {
|
||||
leantime.ticketsController.initSimpleColorPicker();
|
||||
});
|
||||
</script>
|
||||
20
app/Domain/Calendar/Templates/delEvent.blade.php
Normal file
20
app/Domain/Calendar/Templates/delEvent.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
$id = (int) $_GET['id'];
|
||||
@endphp
|
||||
|
||||
<h4 class="widgettitle title-light">{!! __('subtitles.delete') !!}</h4>
|
||||
|
||||
<form method="post" class="formModal" action="{{ BASE_URL }}/calendar/delEvent/{{ $id }}">
|
||||
@dispatchEvent('afterFormOpen')
|
||||
<p>{!! __('text.confirm_event_deletion') !!}</p><br />
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
<x-global::forms.button inputType="submit" contentRole="primary" id="saveAndClose" value="closeModal">{!! __('buttons.yes_delete') !!}</x-global::forms.button>
|
||||
<x-global::forms.button tag="a" contentRole="tertiary" link="{{ BASE_URL }}/calendar/showMyCalendar">{!! __('buttons.back') !!}</x-global::forms.button>
|
||||
@dispatchEvent('beforeFormClose')
|
||||
</form>
|
||||
|
||||
@endsection
|
||||
20
app/Domain/Calendar/Templates/delExternalCal.blade.php
Normal file
20
app/Domain/Calendar/Templates/delExternalCal.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
$id = (int) $_GET['id'];
|
||||
@endphp
|
||||
|
||||
<h4 class="widgettitle title-light">{!! __('subtitles.delete') !!}</h4>
|
||||
|
||||
<form method="post" class="formModal" action="{{ BASE_URL }}/calendar/delExternalCalendar/{{ $id }}">
|
||||
@dispatchEvent('afterFormOpen')
|
||||
<p>{!! __('text.confirm_calendar_deletion') !!}</p><br />
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
<x-global::forms.button inputType="submit" contentRole="primary" id="saveAndClose" value="closeModal">{!! __('buttons.yes_delete') !!}</x-global::forms.button>
|
||||
<x-global::forms.button tag="a" contentRole="tertiary" link="{{ BASE_URL }}/calendar/showMyCalendar">{!! __('buttons.back') !!}</x-global::forms.button>
|
||||
@dispatchEvent('beforeFormClose')
|
||||
</form>
|
||||
|
||||
@endsection
|
||||
71
app/Domain/Calendar/Templates/editEvent.blade.php
Normal file
71
app/Domain/Calendar/Templates/editEvent.blade.php
Normal file
@@ -0,0 +1,71 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
$values = $values ?? [];
|
||||
@endphp
|
||||
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light">{!! __('subtitles.event') !!}</h4>
|
||||
|
||||
<form action="{{ BASE_URL }}/calendar/editEvent/{{ $values['id'] }}" method="post" class="formModal">
|
||||
|
||||
@dispatchEvent('afterFormOpen')
|
||||
|
||||
<label for="description">{!! __('label.title') !!}</label>
|
||||
<x-global::forms.text-input id="description" name="description" value="{{ $tpl->escape($values['description']) }}" /><br />
|
||||
|
||||
<label for="dateFrom">{!! __('label.start_date') !!}</label>
|
||||
<input type="text" id="event_date_from" autocomplete="off" name="dateFrom" value="{{ format($values['dateFrom'])->date() }}" />
|
||||
|
||||
<div class="par">
|
||||
<label> {!! __('label.start_time') !!}</label>
|
||||
<div class="input-append bootstrap-timepicker">
|
||||
<input type="time" id="event_time_from" name="timeFrom" value="{{ format($values['dateFrom'])->time24() }}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="dateTo">{!! __('label.end_date') !!}</label>
|
||||
<input type="text" id="event_date_to" autocomplete="off" name="dateTo" value="{{ format($values['dateTo'])->date() }}" />
|
||||
|
||||
<div class="par">
|
||||
<label for="">{!! __('label.end_time') !!} </label>
|
||||
<div class="input-append bootstrap-timepicker">
|
||||
<input type="time" id="event_time_to" name="timeTo" value="{{ format($values['dateTo'])->time24() }}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="allDay">{!! __('label.all_day') !!}</label>
|
||||
<input type="checkbox" id="allDay" name="allDay"
|
||||
@if ($values['allDay'] === 'true')
|
||||
checked="checked"
|
||||
@endif
|
||||
/>
|
||||
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
|
||||
<div class="clear"></div>
|
||||
<br />
|
||||
<x-global::forms.button tag="a" link="{{ BASE_URL }}/calendar/delEvent/{{ (int) $_GET['id'] }}" class="formModal delete right" state="danger" variant="outline"><i class="fa fa-trash"></i> {!! __('links.delete') !!}</x-global::forms.button>
|
||||
<input type="hidden" value="1" name="save" />
|
||||
<x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.save')" name="saveEvent" id="save" />
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function() {
|
||||
leantime.calendarController.initEventDatepickers();
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
|
||||
@endsection
|
||||
32
app/Domain/Calendar/Templates/editExternalCalendar.blade.php
Normal file
32
app/Domain/Calendar/Templates/editExternalCalendar.blade.php
Normal file
@@ -0,0 +1,32 @@
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light"><i class="fa-regular fa-calendar-plus"></i> {{ __('label.edit_ical') }}</h4>
|
||||
{!! __('label.import_ical_content') !!}
|
||||
|
||||
|
||||
<form action="{{ BASE_URL }}/calendar/editExternal/{{ $values['id'] }}" method="post" class="formModal">
|
||||
|
||||
<input type="hidden" name="save" value="1" />
|
||||
<label for="name">{{ $tpl->__('label.calendar_name') }}:</label>
|
||||
<x-global::forms.text-input id="name" name="name" autocomplete="off" value="{{ $values['name'] }}" /><br />
|
||||
|
||||
<label for="url">{{ $tpl->__('label.ical_url') }}:</label>
|
||||
<x-global::forms.text-input id="url" name="url" autocomplete="off" style="width:300px;" value="{{ $values['url'] }}" /><br />
|
||||
|
||||
<label for="color">{{ $tpl->__('label.color') }}:</label>
|
||||
<input type="text" name="colorClass" autocomplete="off" value="{{ $values['colorClass'] }}" class="simpleColorPicker"/>
|
||||
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
<br /><br />
|
||||
<x-global::forms.button tag="input" inputType="submit" name="save" id="save" :labelText="__('buttons.save')" />
|
||||
|
||||
|
||||
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
leantime.ticketsController.initSimpleColorPicker();
|
||||
</script>
|
||||
47
app/Domain/Calendar/Templates/export.blade.php
Normal file
47
app/Domain/Calendar/Templates/export.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
$url = $url ?? null;
|
||||
@endphp
|
||||
|
||||
<h4 class="widgettitle title-light"><i class="fa fa-file-export"></i> {!! __('label.ical_export') !!}</h4>
|
||||
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<form class="formModal" method="post" action="{{ BASE_URL }}/calendar/export">
|
||||
|
||||
@dispatchEvent('afterFormOpen')
|
||||
|
||||
{!! __('text.ical_export_description') !!}
|
||||
<br />
|
||||
|
||||
@if ($url)
|
||||
{!! __('text.you_ical_url') !!}
|
||||
<br /><x-global::forms.text-input value='{{ $url }}' style='width:100%;' />
|
||||
@else
|
||||
{!! __('text.no_url') !!}
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<input type="hidden" value="1" name="generateUrl" />
|
||||
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
|
||||
<br /><x-global::forms.button tag="input" inputType="submit" contentRole="primary" :labelText="__('buttons.generate_ical_url')" />
|
||||
|
||||
</div>
|
||||
<div class="col-md-6 align-right">
|
||||
@if ($url)
|
||||
<x-global::forms.button tag="a" link="{{ BASE_URL }}/calendar/export?remove=1" class="delete formModal" state="danger" variant="outline"><i class="fa fa-trash"></i> {!! __('links.remove_access') !!}</x-global::forms.button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
@endsection
|
||||
31
app/Domain/Calendar/Templates/importGCal.blade.php
Normal file
31
app/Domain/Calendar/Templates/importGCal.blade.php
Normal file
@@ -0,0 +1,31 @@
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<h4 class="widgettitle title-light"><i class="fa-regular fa-calendar-plus"></i> {{ __('label.import_ical') }}</h4>
|
||||
{!! __('label.import_ical_content') !!}
|
||||
|
||||
|
||||
<form action="{{ BASE_URL }}/calendar/importGCal" method="post" class="formModal">
|
||||
|
||||
<label for="name">{{ $tpl->__('label.calendar_name') }}:</label>
|
||||
<x-global::forms.text-input id="name" name="name" autocomplete="off" value="{{ $values['name'] }}" /><br />
|
||||
|
||||
<label for="url">{{ $tpl->__('label.ical_url') }}:</label>
|
||||
<x-global::forms.text-input id="url" name="url" autocomplete="off" style="width:300px;" value="{{ $values['url'] }}" /><br />
|
||||
|
||||
<label for="color">{{ $tpl->__('label.color') }}:</label>
|
||||
<input type="text" name="colorClass" autocomplete="off" value="{{ $values['colorClass'] }}" class="simpleColorPicker"/>
|
||||
|
||||
@dispatchEvent('beforeSubmitButton')
|
||||
<br /><br />
|
||||
<x-global::forms.button tag="input" inputType="submit" name="save" id="save" :labelText="__('buttons.save')" />
|
||||
|
||||
|
||||
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
leantime.ticketsController.initSimpleColorPicker();
|
||||
</script>
|
||||
93
app/Domain/Calendar/Templates/showAllGCals.blade.php
Normal file
93
app/Domain/Calendar/Templates/showAllGCals.blade.php
Normal file
@@ -0,0 +1,93 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@dispatchEvent('beforePageHeaderOpen')
|
||||
<div class="pageheader">
|
||||
@dispatchEvent('afterPageHeaderOpen')
|
||||
<form action="{{ BASE_URL }}/index.php?act=tickets.showAll" method="post" class="searchbar">
|
||||
<x-global::forms.text-input name="term" placeholder="To search type and hit enter..." />
|
||||
</form>
|
||||
|
||||
<div class="pageicon"><span class="fa {{ $tpl->getModulePicture() }}"></span></div>
|
||||
<div class="pagetitle">
|
||||
<h5>{!! __('OVERVIEW') !!}</h5>
|
||||
<h1>{!! __('ALL_GCCALS') !!}</h1>
|
||||
</div>
|
||||
@dispatchEvent('beforePageHeaderClose')
|
||||
</div><!--pageheader-->
|
||||
@dispatchEvent('afterPageHeaderClose')
|
||||
|
||||
<div class="maincontent">
|
||||
<div class="maincontentinner">
|
||||
<form action="">
|
||||
|
||||
@dispatchEvent('afterFormOpen')
|
||||
|
||||
<table cellpadding="0" cellspacing="0" border="0" class="allTickets table table-bordered"
|
||||
id="allTickets">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>{!! __('NAME') !!}</th>
|
||||
<th>{!! __('URL') !!}</th>
|
||||
<th>{!! __('COLOR') !!}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@foreach ($allCalendars as $row)
|
||||
<tr>
|
||||
<td>{!! $tpl->displayLink('calendar.editGCal', $row['id'], ['id' => $row['id']]) !!}</td>
|
||||
<td>{!! $tpl->displayLink('calendar.editGCal', $row['name'], ['id' => $row['id']]) !!}</td>
|
||||
<td>{{ $row['url'] }}</td>
|
||||
<td><span style="color: {{ $row['colorClass'] }}; padding:2px;">{{ $row['colorClass'] }}</span></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@dispatchEvent('beforeFormClose')
|
||||
|
||||
</form>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
|
||||
@dispatchEvent('scripts.afterOpen')
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
$("#allTickets").tablesorter({
|
||||
sortList:[[0,0]],
|
||||
widgets: ['zebra']
|
||||
}).tablesorterPager({container: $("#pager")});
|
||||
|
||||
//assign the sortStart event
|
||||
$("#allTickets").bind("sortStart",function() {
|
||||
|
||||
$('#loader').show();
|
||||
|
||||
|
||||
}).bind("sortEnd",function() {
|
||||
|
||||
$('#loader').hide();
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@dispatchEvent('scripts.beforeClose')
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
|
||||
<link rel='stylesheet' type='text/css' href='includes/libs/fullCalendar/fullcalendar.css' />
|
||||
|
||||
@endsection
|
||||
355
app/Domain/Calendar/Templates/showMyCalendar.blade.php
Normal file
355
app/Domain/Calendar/Templates/showMyCalendar.blade.php
Normal file
@@ -0,0 +1,355 @@
|
||||
@extends($layout)
|
||||
|
||||
@section('content')
|
||||
|
||||
@php
|
||||
if (! session()->exists('usersettings.submenuToggle.myCalendarView')) {
|
||||
session(['usersettings.submenuToggle.myCalendarView' => 'dayGridMonth']);
|
||||
}
|
||||
@endphp
|
||||
|
||||
@dispatchEvent('beforePageHeaderOpen')
|
||||
<div class="pageheader">
|
||||
@dispatchEvent('afterPageHeaderOpen')
|
||||
<div class="pageicon"><span class="fa {{ $tpl->getModulePicture() }}"></span></div>
|
||||
<div class="pagetitle">
|
||||
<h5>{!! __('headline.calendar') !!}</h5>
|
||||
<h1>{!! __('headline.my_calendar') !!}</h1>
|
||||
</div>
|
||||
@dispatchEvent('beforePageHeaderClose')
|
||||
</div><!--pageheader-->
|
||||
@dispatchEvent('afterPageHeaderClose')
|
||||
|
||||
{!! $tpl->displayNotification() !!}
|
||||
|
||||
<div class="maincontent">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<div class="maincontentinner">
|
||||
<h5 class="subtitle tw-pb-m">Calendars</h5>
|
||||
|
||||
<ul class="simpleList">
|
||||
<li><span class="indicatorCircle" style="background:var(--accent1)"></span>Events</li>
|
||||
<li><span class="indicatorCircle" style="background:var(--accent2)"></span>Projects & Tasks</li>
|
||||
|
||||
@foreach ($externalCalendars as $calendars)
|
||||
<li>
|
||||
@if (empty($calendars['managedByPlugin']))
|
||||
<div class="inlineDropDownContainer" style="float:right;">
|
||||
<a href="javascript:void(0);" class="dropdown-toggle ticketDropDown editHeadline" data-toggle="dropdown">
|
||||
<i class="fa fa-ellipsis-h" aria-hidden="true"></i>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="#/calendar/editExternal/{{ $calendars['id'] }}"><i class="fa-solid fa-pen-to-square"></i> {!! __('links.edit_calendar') !!}</a>
|
||||
</li>
|
||||
<li><a href="#/calendar/delExternalCalendar/{{ $calendars['id'] }}" class="delete"><i class="fa fa-trash"></i> {!! __('links.delete_external_calendar') !!}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<span class="indicatorCircle" style="background:{{ $calendars['colorClass'] }}"></span>{{ $calendars['name'] }}
|
||||
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
</ul>
|
||||
<hr />
|
||||
<a href="#/calendar/connectCalendar" class="formModal" style="display:block; margin-bottom:8px; margin-left:-5px;"><i class="fa-regular fa-calendar-plus" style="width:16px;"></i> {!! __('label.connect_calendar') !!}</a>
|
||||
<a href="#/calendar/calendarSettings" class="formModal" style="margin-left:-5px;"><i class="fa fa-cog" style="width:16px;"></i> {!! __('label.calendar_settings') !!}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<div class="maincontentinner">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<x-global::forms.button tag="a" link="#/calendar/addEvent" contentRole="primary" class="formModal"><i class='fa fa-plus'></i> {!! __('buttons.add_event') !!}</x-global::forms.button>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="fc-center center" id="calendarTitle" style="padding-top:5px;">
|
||||
<h2>..</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<x-global::forms.button tag="a" link="#/calendar/export" contentRole="default" class="right">Export</x-global::forms.button>
|
||||
<button class="fc-next-button btn btn-default right" type="button" style="margin-right:5px;">
|
||||
<span class="fc-icon fc-icon-chevron-right"></span>
|
||||
</button>
|
||||
<button class="fc-prev-button btn btn-default right" type="button" style="margin-right:5px;">
|
||||
<span class="fc-icon fc-icon-chevron-left"></span>
|
||||
</button>
|
||||
|
||||
<button class="fc-today-button btn btn-default right" style="margin-right:5px;">today</button>
|
||||
|
||||
|
||||
<select id="my-select" style="margin-right:5px;" class="right">
|
||||
<option class="fc-timeGridDay-button fc-button fc-state-default fc-corner-right" value="timeGridDay" {{ session('usersettings.submenuToggle.myCalendarView') == 'timeGridDay' ? 'selected' : '' }}>Day</option>
|
||||
<option class="fc-timeGridWeek-button fc-button fc-state-default fc-corner-right" value="timeGridWeek" {{ session('usersettings.submenuToggle.myCalendarView') == 'timeGridWeek' ? 'selected' : '' }}>Week</option>
|
||||
<option class="fc-dayGridMonth-button fc-button fc-state-default fc-corner-right" value="dayGridMonth" {{ session('usersettings.submenuToggle.myCalendarView') == 'dayGridMonth' ? 'selected' : '' }}>Month</option>
|
||||
<option class="fc-multiMonthYear-button fc-button fc-state-default fc-corner-right" value="multiMonthYear" {{ session('usersettings.submenuToggle.myCalendarView') == 'multiMonthYear' ? 'selected' : '' }}>Year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="calendar"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script type='text/javascript'>
|
||||
|
||||
@dispatchEvent('scripts.afterOpen')
|
||||
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
|
||||
//leantime.calendarController.initCalendar(events);
|
||||
leantime.calendarController.initExportModal();
|
||||
|
||||
});
|
||||
var eventSources = [];
|
||||
|
||||
var events = {events: [
|
||||
@foreach ($calendar as $calendarEvent)
|
||||
{
|
||||
title: {!! json_encode($calendarEvent['title']) !!},
|
||||
|
||||
start: new Date({{ format($calendarEvent['dateFrom'])->jsTimestamp() }}),
|
||||
@if (isset($calendarEvent['dateTo']))
|
||||
end: new Date({{ format($calendarEvent['dateTo'])->jsTimestamp() }}),
|
||||
@endif
|
||||
@if (isset($calendarEvent['allDay']) && $calendarEvent['allDay'] === true)
|
||||
allDay: true,
|
||||
@else
|
||||
allDay: false,
|
||||
@endif
|
||||
enitityId: {{ $calendarEvent['id'] }},
|
||||
@if (isset($calendarEvent['eventType']) && $calendarEvent['eventType'] == 'calendar')
|
||||
url: '{{ CURRENT_URL }}#/calendar/editEvent/{{ $calendarEvent['id'] }}',
|
||||
backgroundColor: '{{ $calendarEvent['backgroundColor'] ?? 'var(--accent2)' }}',
|
||||
borderColor: '{{ $calendarEvent['borderColor'] ?? 'var(--accent2)' }}',
|
||||
enitityType: "event",
|
||||
dateContext: '{{ $calendarEvent['dateContext'] ?? 'plan' }}',
|
||||
@else
|
||||
url: '{{ CURRENT_URL }}#/tickets/showTicket/{{ $calendarEvent['id'] }}?projectId={{ $calendarEvent['projectId'] }}',
|
||||
backgroundColor: '{{ $calendarEvent['backgroundColor'] ?? 'var(--accent2)' }}',
|
||||
borderColor: '{{ $calendarEvent['borderColor'] ?? 'var(--accent2)' }}',
|
||||
enitityType: "ticket",
|
||||
dateContext: '{{ $calendarEvent['dateContext'] ?? 'edit' }}',
|
||||
@endif
|
||||
},
|
||||
@endforeach
|
||||
]};
|
||||
|
||||
eventSources.push(events);
|
||||
|
||||
@foreach ($externalCalendars as $externalCalendar)
|
||||
@if (empty($externalCalendar['managedByPlugin']))
|
||||
eventSources.push(
|
||||
{
|
||||
url: '{{ BASE_URL }}/calendar/externalCal/{{ $externalCalendar['id'] }}',
|
||||
format: 'ics',
|
||||
color: '{{ $externalCalendar['colorClass'] }}',
|
||||
editable: false,
|
||||
}
|
||||
);
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const heightWindow = jQuery("body").height() - 210;
|
||||
|
||||
const calendarEl = document.getElementById('calendar');
|
||||
|
||||
const calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
timeZone: leantime.i18n.__("usersettings.timezone"),
|
||||
height: 'calc(100% - 40px)',
|
||||
stickyHeaderDates: true,
|
||||
initialView: '{{ session('usersettings.submenuToggle.myCalendarView') }}',
|
||||
eventSources:eventSources,
|
||||
editable: true,
|
||||
headerToolbar: false,
|
||||
dayHeaderFormat: leantime.dateHelper.getFormatFromSettings("dateformat", "luxon"),
|
||||
eventTimeFormat: leantime.dateHelper.getFormatFromSettings("timeformat", "luxon"),
|
||||
slotLabelFormat: leantime.dateHelper.getFormatFromSettings("timeformat", "luxon"),
|
||||
firstDay: leantime.i18n.__("language.firstDayOfWeek"),
|
||||
views: {
|
||||
timeGridDay: {
|
||||
|
||||
},
|
||||
timeGridWeek: {
|
||||
|
||||
},
|
||||
dayGridMonth: {
|
||||
dayHeaderFormat: { weekday: 'short' },
|
||||
},
|
||||
multiMonthYear: {
|
||||
showNonCurrentDates: true,
|
||||
multiMonthTitleFormat: { month: 'long', year: 'numeric' },
|
||||
dayHeaderFormat: { weekday: 'short' },
|
||||
},
|
||||
multiMonthOneMonth: {
|
||||
type: 'multiMonth',
|
||||
duration: {months: 1},
|
||||
multiMonthTitleFormat: {month: 'long', year: 'numeric'},
|
||||
dayHeaderFormat: {weekday: 'short'},
|
||||
},
|
||||
listWeek: {
|
||||
listDayFormat: {weekday: 'long'},
|
||||
listDaySideFormat: leantime.dateHelper.getFormatFromSettings("dateformat", "luxon"),
|
||||
}
|
||||
},
|
||||
nowIndicator: true,
|
||||
bootstrapFontAwesome: {
|
||||
close: 'fa-times',
|
||||
prev: 'fa-chevron-left',
|
||||
next: 'fa-chevron-right',
|
||||
prevYear: 'fa-angle-double-left',
|
||||
nextYear: 'fa-angle-double-right'
|
||||
},
|
||||
eventDrop: function (event) {
|
||||
|
||||
if(event.event.extendedProps.enitityType == "ticket") {
|
||||
|
||||
let dataVal = {};
|
||||
|
||||
if(event.event.extendedProps.dateContext == "due") {
|
||||
|
||||
dataVal = {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
dateToFinish: event.event.startStr
|
||||
}
|
||||
|
||||
}else{
|
||||
dataVal = {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
editFrom: event.event.startStr,
|
||||
editTo: event.event.endStr
|
||||
}
|
||||
}
|
||||
|
||||
leantime.rpc('Tickets.Tickets.patchTicket', { id: dataVal.id, values: dataVal })
|
||||
.catch(function (error) {
|
||||
jQuery.growl({ message: (error && error.message) ? error.message : leantime.i18n.__("short_notifications.not_saved"), style: "error" });
|
||||
event.revert();
|
||||
console.error('Could not update ticket dates', error);
|
||||
});
|
||||
|
||||
}else if(event.event.extendedProps.enitityType == "event") {
|
||||
|
||||
leantime.rpc('Calendar.Calendar.patch', {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
params: {
|
||||
dateFrom: event.event.startStr,
|
||||
dateTo: event.event.endStr
|
||||
}
|
||||
}).then(function (success) {
|
||||
// Denied/failed update resolves to false — undo the visual move.
|
||||
if (! success) { event.revert(); }
|
||||
}).catch(function (error) {
|
||||
console.error('Could not update event dates', error);
|
||||
event.revert();
|
||||
})
|
||||
}
|
||||
},
|
||||
eventResize: function (event) {
|
||||
|
||||
if(event.event.extendedProps.enitityType == "ticket") {
|
||||
|
||||
let dataVal = {};
|
||||
|
||||
if(event.event.extendedProps.dateContext == "due") {
|
||||
|
||||
dataVal = {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
dateToFinish: event.event.startStr
|
||||
}
|
||||
|
||||
}else{
|
||||
dataVal = {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
editFrom: event.event.startStr,
|
||||
editTo: event.event.endStr
|
||||
}
|
||||
}
|
||||
|
||||
leantime.rpc('Tickets.Tickets.patchTicket', { id: dataVal.id, values: dataVal })
|
||||
.catch(function (error) {
|
||||
jQuery.growl({ message: (error && error.message) ? error.message : leantime.i18n.__("short_notifications.not_saved"), style: "error" });
|
||||
event.revert();
|
||||
console.error('Could not update ticket dates', error);
|
||||
});
|
||||
|
||||
|
||||
}else if(event.event.extendedProps.enitityType == "event") {
|
||||
|
||||
leantime.rpc('Calendar.Calendar.patch', {
|
||||
id: event.event.extendedProps.enitityId,
|
||||
params: {
|
||||
dateFrom: event.event.startStr,
|
||||
dateTo: event.event.endStr
|
||||
}
|
||||
}).then(function (success) {
|
||||
// Denied/failed update resolves to false — undo the visual move.
|
||||
if (! success) { event.revert(); }
|
||||
}).catch(function (error) {
|
||||
console.error('Could not update event dates', error);
|
||||
event.revert();
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
eventMouseEnter: function() {
|
||||
},
|
||||
|
||||
}
|
||||
);
|
||||
calendar.setOption('locale', leantime.i18n.__("language.code"));
|
||||
calendar.render();
|
||||
calendar.scrollToTime( Date.now() );
|
||||
jQuery("#calendarTitle h2").text(calendar.getCurrentData().viewTitle);
|
||||
|
||||
jQuery('.fc-prev-button').click(function() {
|
||||
calendar.prev();
|
||||
calendar.getCurrentData()
|
||||
jQuery("#calendarTitle h2").text(calendar.getCurrentData().viewTitle);
|
||||
});
|
||||
jQuery('.fc-next-button').click(function() {
|
||||
calendar.next();
|
||||
jQuery("#calendarTitle h2").text(calendar.getCurrentData().viewTitle);
|
||||
});
|
||||
jQuery('.fc-today-button').click(function() {
|
||||
calendar.today();
|
||||
jQuery("#calendarTitle h2").text(calendar.getCurrentData().viewTitle);
|
||||
});
|
||||
jQuery("#my-select").on("change", function(e){
|
||||
|
||||
calendar.changeView(jQuery("#my-select option:selected").val());
|
||||
|
||||
leantime.rpc('Api.Api.setSubmenuState', {
|
||||
submenu: "myCalendarView",
|
||||
state: jQuery("#my-select option:selected").val()
|
||||
}).catch(function (e) { console.error('Could not update submenu state', e); });
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@dispatchEvent('scripts.beforeClose')
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
|
||||
<style type="text/css">
|
||||
.maincontent .maincontentinner {
|
||||
height:calc(100vh - 165px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@endsection
|
||||
Reference in New Issue
Block a user