mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-21 23:43:17 +01:00
* Calendar: ask user to apply changes in series master to already created exceptions
This commit is contained in:
parent
cbd2e4c695
commit
7ccd1e4cf2
@ -864,11 +864,12 @@ class calendar_uiforms extends calendar_ui
|
||||
unset($event['edit_single']); // if we further edit it, it's just a single event
|
||||
unset($preserv['edit_single']);
|
||||
}
|
||||
else // conflict or error, we need to reset everything to the state befor we tried to save it
|
||||
else // conflict or error, we need to reset everything to the state before we tried to save it
|
||||
{
|
||||
$event['id'] = $event['reference'];
|
||||
$event['reference'] = $event['recurrence'] = 0;
|
||||
$event['uid'] = $content['uid'];
|
||||
$preserv['apply_to_future_exceptions'] = $content['apply_to_future_exceptions'] ?? null;
|
||||
}
|
||||
$update_type = 'edit';
|
||||
}
|
||||
@ -933,8 +934,15 @@ class calendar_uiforms extends calendar_ui
|
||||
if (is_array($conflicts))
|
||||
{
|
||||
$event['button_was'] = $button; // remember for ignore
|
||||
$preserv['apply_changes_to_exceptions'] = $content['apply_changes_to_exceptions'] ?? null;
|
||||
$preserv['no_notifications'] = $content['no_notifications'] ?? null;
|
||||
return $this->conflicts($event,$conflicts,$preserv);
|
||||
}
|
||||
// check if we should apply the changes to the exceptions
|
||||
if (!empty($content['apply_changes_to_exceptions']))
|
||||
{
|
||||
$this->apply_changes_to_exceptions($event, $messages, !empty($content['no_notifications']));
|
||||
}
|
||||
|
||||
// Event spans multiple days, need an edit to make sure they all get updated
|
||||
// We could check old date, as removing from days could still be an update
|
||||
@ -1201,7 +1209,7 @@ class calendar_uiforms extends calendar_ui
|
||||
$event['recurrence'] = $preserv['recurrence'] = $preserv['actual_date'];
|
||||
$event['start'] = $preserv['edit_single'] = $preserv['actual_date'];
|
||||
$event['recur_type'] = MCAL_RECUR_NONE;
|
||||
foreach(array('recur_enddate','recur_interval','recur_exception','recur_data') as $name)
|
||||
foreach(array('recur_enddate','recur_interval','recur_exception','recur_data', 'recur_rdates') as $name)
|
||||
{
|
||||
unset($event[$name]);
|
||||
}
|
||||
@ -1947,6 +1955,9 @@ class calendar_uiforms extends calendar_ui
|
||||
//Disable videoconference if the module is not enabled
|
||||
$etpl->disableElement('videoconference', calendar_hooks::isVideoconferenceDisabled());
|
||||
|
||||
$content['future_exceptions'] = !empty($content['id']) && !empty($content['recur_type']) &&
|
||||
$this->bo->search(['start' => Api\DateTime::to('now', 'ts')], 'cal_reference='.(int)$content['id']);
|
||||
|
||||
// non_interactive==true from $_GET calls immediate save action without displaying the edit form
|
||||
if(isset($_GET['non_interactive']) && (bool)$_GET['non_interactive'] === true)
|
||||
{
|
||||
@ -1962,6 +1973,66 @@ class calendar_uiforms extends calendar_ui
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply given data of event-master to future exceptions
|
||||
*
|
||||
* @param array $master
|
||||
* @param ?array $messages on return error-messages
|
||||
* @param ?bool $skip_notifications
|
||||
* @return void
|
||||
*/
|
||||
protected function apply_changes_to_exceptions(array $master, ?array $messages=null, ?bool $skip_notifications=null)
|
||||
{
|
||||
foreach($this->bo->search([
|
||||
'start' => Api\DateTime::to('now', 'ts')
|
||||
], 'cal_reference='.(int)$master['id']) as $event)
|
||||
{
|
||||
$changes = 0;
|
||||
foreach($master as $name => $value)
|
||||
{
|
||||
switch($name)
|
||||
{
|
||||
case 'title';
|
||||
case 'description':
|
||||
case 'location':
|
||||
case 'cat_id':
|
||||
case 'priority':
|
||||
if ($event[$name] != $value)
|
||||
{
|
||||
$event[$name] = $value;
|
||||
$changes++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'participants':
|
||||
// only add new participants, leave status of current participants alone
|
||||
foreach($value as $uid => $status)
|
||||
{
|
||||
if (!isset($event['participants'][$uid]))
|
||||
{
|
||||
$event['participants'][$uid] = $status;
|
||||
$changes++;
|
||||
}
|
||||
}
|
||||
unset($event['participant_status']);
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($name[0] === '#' && $event[$name] != $value)
|
||||
{
|
||||
$event[$name] = $value;
|
||||
$changes++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($changes)
|
||||
{
|
||||
$this->bo->update($event, true, true, false, true, $messages, $skip_notifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the participants for display in edit dialog
|
||||
*
|
||||
|
@ -2261,14 +2261,14 @@ export class CalendarApp extends EgwApp
|
||||
*/
|
||||
move_edit_series(_DOM,_button)
|
||||
{
|
||||
var content : any = this.et2.getArrayMgr('content').data;
|
||||
var start_date = this.et2.getValueById('start');
|
||||
var end_date = this.et2.getValueById('end');
|
||||
var whole_day = <et2_checkbox> this.et2.getWidgetById('whole_day');
|
||||
var duration = ''+this.et2.getValueById('duration');
|
||||
var is_whole_day = whole_day && whole_day.get_value() == whole_day.options.selected_value;
|
||||
var button = _button;
|
||||
var that = this;
|
||||
const content : any = this.et2.getArrayMgr('content').data;
|
||||
const start_date = this.et2.getValueById('start');
|
||||
const end_date = this.et2.getValueById('end');
|
||||
const whole_day = <et2_checkbox> this.et2.getWidgetById('whole_day');
|
||||
const duration = ''+this.et2.getValueById('duration');
|
||||
const is_whole_day = whole_day && whole_day.get_value() == whole_day.options.selected_value;
|
||||
const button = _button;
|
||||
const that = this;
|
||||
|
||||
let instance_date_regex = window.location.search.match(/date=(\d{4}-\d{2}-\d{2}(?:.+Z)?)/);
|
||||
let instance_date;
|
||||
@ -2278,15 +2278,13 @@ export class CalendarApp extends EgwApp
|
||||
instance_date.setUTCMinutes(instance_date.getUTCMinutes() +instance_date.getTimezoneOffset());
|
||||
}
|
||||
if (typeof content != 'undefined' && content.id != null &&
|
||||
typeof content.recur_type != 'undefined' && content.recur_type != null && content.recur_type != 0
|
||||
)
|
||||
typeof content.recur_type != 'undefined' && content.recur_type != null && content.recur_type != 0)
|
||||
{
|
||||
if (content.start != start_date ||
|
||||
content.whole_day != is_whole_day ||
|
||||
(duration && ''+content.duration != duration ||
|
||||
// End date might ignore seconds, and be 59 seconds off for all day events
|
||||
!duration && Math.abs(new Date(end_date) - new Date(content.end)) > 60000)
|
||||
)
|
||||
!duration && Math.abs(new Date(end_date) - new Date(content.end)) > 60000))
|
||||
{
|
||||
et2_calendar_event.series_split_prompt(
|
||||
content, instance_date, function(_button_id)
|
||||
@ -2294,20 +2292,22 @@ export class CalendarApp extends EgwApp
|
||||
if(_button_id == Et2Dialog.OK_BUTTON)
|
||||
{
|
||||
that.et2.getInstanceManager().submit(button);
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
// check if we have future exceptions and changes with might be applied to them too
|
||||
if (content.future_exceptions)
|
||||
{
|
||||
return true;
|
||||
Et2Dialog.show_dialog((_button) => {
|
||||
this.et2.setValueById('apply_changes_to_exceptions', _button == Et2Dialog.YES_BUTTON);
|
||||
this.et2.getInstanceManager().submit(button);
|
||||
}, 'Otherwise, changes to the title, description, ... or new participants will not be transferred to exceptions that have already been created.', 'Apply changes to (future) exceptions too?', undefined, Et2Dialog.BUTTONS_YES_NO, Et2Dialog.QUESTION_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,6 +61,7 @@ allows to edit the event again calendar de Erlaubt den Termin erneut zu bearbeit
|
||||
always calendar de Immer
|
||||
always use full edit dialog calendar de Immer das komplette Bearbeiten-Fenster verwenden
|
||||
always use the full edit dialog, not this little dialog calendar de Verwende immer das komplette Bearbeiten-Fenster, anstatt dem verkürzten Dialog.
|
||||
apply changes to (future) exceptions too? calendar de Änderungen auch auf (zukünftige) Ausnahmen anwenden?
|
||||
apply the action on the whole query, not only the shown events calendar de Befehl auf die gesamte Abfrage anwenden, NICHT nur auf die angezeigten Termine.
|
||||
apply the changes calendar de Übernimmt die Änderungen
|
||||
appointment settings calendar de Einstellungen der Terminverwaltung
|
||||
@ -449,6 +450,7 @@ only used for first viewing of calendar, afterwards last selected view is used.
|
||||
open todo's: calendar de Unerledigte Aufgaben:
|
||||
optional calendar de Optional
|
||||
organizer calendar de Organisator
|
||||
otherwise, changes to the title, description, ... or new participants will not be transferred to exceptions that have already been created. calendar de Andernfalls werden Änderungen im Titel, in der Beschreibung, ... oder neue Teilnehmer nicht auf bereits erstellte Ausnahmen übertragen.
|
||||
output unit calendar de Ausgabeeinheit
|
||||
overlap holiday calendar de Überlappender Feiertag
|
||||
owner too calendar de Auch Besitzer
|
||||
|
@ -61,6 +61,7 @@ allows to edit the event again calendar en Allows to edit the event again
|
||||
always calendar en Always
|
||||
always use full edit dialog calendar en Always use full edit dialog
|
||||
always use the full edit dialog, not this little dialog calendar en Always use the full edit dialog, not this little dialog
|
||||
apply changes to (future) exceptions too? calendar en Apply changes to (future) exceptions too?
|
||||
apply the action on the whole query, not only the shown events calendar en Apply the action on the whole query, NOT only the shown events.
|
||||
apply the changes calendar en Apply the changes
|
||||
appointment settings calendar en Appointment settings
|
||||
@ -449,6 +450,7 @@ only used for first viewing of calendar, afterwards last selected view is used.
|
||||
open todo's: calendar en Open ToDo's:
|
||||
optional calendar en Optional
|
||||
organizer calendar en Organizer
|
||||
otherwise, changes to the title, description, ... or new participants will not be transferred to exceptions that have already been created. calendar en Otherwise, changes to the title, description, ... or new participants will not be transferred to exceptions that have already been created.
|
||||
output unit calendar en Output unit
|
||||
overlap holiday calendar en Overlap holiday
|
||||
owner too calendar en Owner too
|
||||
|
@ -268,6 +268,7 @@
|
||||
<et2-button statustext="Find free timeslots where the selected participants are available for the given timespan" label="Freetime search" id="freetime" onclick="app.calendar.freetime_search" image="timesheet" span="all" noSubmit="true"></et2-button>
|
||||
<et2-button align="right" statustext="Delete this event" label="Delete" id="button[delete]" onclick="app.calendar.delete_btn(widget,$cont[query_delete_exceptions]);" image="delete"></et2-button>
|
||||
<et2-textbox type="hidden" id="delete_exceptions"></et2-textbox>
|
||||
<et2-textbox type="hidden" id="apply_changes_to_exceptions"></et2-textbox>
|
||||
</et2-hbox>
|
||||
</template>
|
||||
</overlay>
|
Loading…
Reference in New Issue
Block a user