1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-27 07:50:57 +01:00

DRAFT, recurring events need optional end dates

Summary: Ref T8357, DRAFT, recurring events need optional end dates

Test Plan: Edit recurring event, set end date, save, recurring ghosts should not generate after end date

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T8357

Differential Revision: https://secure.phabricator.com/D13088
This commit is contained in:
lkassianik 2015-06-01 18:56:11 -07:00
parent c83ddc3a0e
commit 95551a1a5a
7 changed files with 73 additions and 16 deletions

View file

@ -17,11 +17,13 @@ final class PhabricatorCalendarEventEditController
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$user_phid = $viewer->getPHID(); $user_phid = $viewer->getPHID();
$error_name = true; $error_name = true;
$error_recurrence_end_date = true;
$error_start_date = true; $error_start_date = true;
$error_end_date = true; $error_end_date = true;
$validation_exception = null; $validation_exception = null;
$is_recurring_id = celerity_generate_unique_node_id(); $is_recurring_id = celerity_generate_unique_node_id();
$recurrence_end_date_id = celerity_generate_unique_node_id();
$frequency_id = celerity_generate_unique_node_id(); $frequency_id = celerity_generate_unique_node_id();
$all_day_id = celerity_generate_unique_node_id(); $all_day_id = celerity_generate_unique_node_id();
$start_date_id = celerity_generate_unique_node_id(); $start_date_id = celerity_generate_unique_node_id();
@ -65,6 +67,8 @@ final class PhabricatorCalendarEventEditController
list($start_value, $end_value) = $this->getDefaultTimeValues($viewer); list($start_value, $end_value) = $this->getDefaultTimeValues($viewer);
} }
$recurrence_end_date_value = clone $end_value;
$recurrence_end_date_value->setOptional(true);
$submit_label = pht('Create'); $submit_label = pht('Create');
$page_title = pht('Create Event'); $page_title = pht('Create Event');
@ -138,6 +142,8 @@ final class PhabricatorCalendarEventEditController
$start_value = AphrontFormDateControlValue::newFromEpoch( $start_value = AphrontFormDateControlValue::newFromEpoch(
$viewer, $viewer,
$event->getDateFrom()); $event->getDateFrom());
$recurrence_end_date_value = id(clone $end_value)
->setOptional(true);
$submit_label = pht('Update'); $submit_label = pht('Update');
$page_title = pht('Update Event'); $page_title = pht('Update Event');
@ -179,6 +185,10 @@ final class PhabricatorCalendarEventEditController
$end_value = AphrontFormDateControlValue::newFromRequest( $end_value = AphrontFormDateControlValue::newFromRequest(
$request, $request,
'end'); 'end');
$recurrence_end_date_value = AphrontFormDateControlValue::newFromRequest(
$request,
'recurrenceEndDate');
$recurrence_end_date_value->setOptional(true);
$description = $request->getStr('description'); $description = $request->getStr('description');
$subscribers = $request->getArr('subscribers'); $subscribers = $request->getArr('subscribers');
$edit_policy = $request->getStr('editPolicy'); $edit_policy = $request->getStr('editPolicy');
@ -213,6 +223,11 @@ final class PhabricatorCalendarEventEditController
->setTransactionType( ->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_FREQUENCY) PhabricatorCalendarEventTransaction::TYPE_FREQUENCY)
->setNewValue(array('rule' => $frequency)); ->setNewValue(array('rule' => $frequency));
$xactions[] = id(new PhabricatorCalendarEventTransaction())
->setTransactionType(
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE)
->setNewValue($recurrence_end_date_value);
} }
$xactions[] = id(new PhabricatorCalendarEventTransaction()) $xactions[] = id(new PhabricatorCalendarEventTransaction())
@ -290,6 +305,8 @@ final class PhabricatorCalendarEventEditController
PhabricatorCalendarEventTransaction::TYPE_START_DATE); PhabricatorCalendarEventTransaction::TYPE_START_DATE);
$error_end_date = $ex->getShortMessage( $error_end_date = $ex->getShortMessage(
PhabricatorCalendarEventTransaction::TYPE_END_DATE); PhabricatorCalendarEventTransaction::TYPE_END_DATE);
$error_recurrence_end_date = $ex->getShortMessage(
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE);
$event->setViewPolicy($view_policy); $event->setViewPolicy($view_policy);
$event->setEditPolicy($edit_policy); $event->setEditPolicy($edit_policy);
@ -297,6 +314,7 @@ final class PhabricatorCalendarEventEditController
} }
$is_recurring_checkbox = null; $is_recurring_checkbox = null;
$recurrence_end_date_control = null;
$recurrence_frequency_select = null; $recurrence_frequency_select = null;
$name = id(new AphrontFormTextControl()) $name = id(new AphrontFormTextControl())
@ -309,6 +327,7 @@ final class PhabricatorCalendarEventEditController
Javelin::initBehavior('recurring-edit', array( Javelin::initBehavior('recurring-edit', array(
'isRecurring' => $is_recurring_id, 'isRecurring' => $is_recurring_id,
'frequency' => $frequency_id, 'frequency' => $frequency_id,
'recurrenceEndDate' => $recurrence_end_date_id,
)); ));
$is_recurring_checkbox = id(new AphrontFormCheckboxControl()) $is_recurring_checkbox = id(new AphrontFormCheckboxControl())
@ -319,6 +338,17 @@ final class PhabricatorCalendarEventEditController
$is_recurring, $is_recurring,
$is_recurring_id); $is_recurring_id);
$recurrence_end_date_control = id(new AphrontFormDateControl())
->setUser($viewer)
->setName('recurrenceEndDate')
->setLabel(pht('Recurrence End Date'))
->setError($error_recurrence_end_date)
->setValue($recurrence_end_date_value)
->setID($recurrence_end_date_id)
->setIsTimeDisabled(true)
->setAllowNull(true)
->setIsDisabled(!$is_recurring);
$recurrence_frequency_select = id(new AphrontFormSelectControl()) $recurrence_frequency_select = id(new AphrontFormSelectControl())
->setName('frequency') ->setName('frequency')
->setOptions(array( ->setOptions(array(
@ -421,6 +451,9 @@ final class PhabricatorCalendarEventEditController
if ($is_recurring_checkbox) { if ($is_recurring_checkbox) {
$form->appendChild($is_recurring_checkbox); $form->appendChild($is_recurring_checkbox);
} }
if ($recurrence_end_date_control) {
$form->appendChild($recurrence_end_date_control);
}
if ($recurrence_frequency_select) { if ($recurrence_frequency_select) {
$form->appendControl($recurrence_frequency_select); $form->appendControl($recurrence_frequency_select);
} }

View file

@ -135,7 +135,7 @@ final class PhabricatorCalendarEventViewController
$event, $event,
PhabricatorPolicyCapability::CAN_EDIT); PhabricatorPolicyCapability::CAN_EDIT);
if ($event->getIsRecurring() && $event->getIsGhostEvent()) { if ($event->getIsRecurring() && $event->getInstanceOfEventPHID()) {
$index = $event->getSequenceIndex(); $index = $event->getSequenceIndex();
$actions->addAction( $actions->addAction(
@ -231,6 +231,13 @@ final class PhabricatorCalendarEventViewController
$properties->addProperty( $properties->addProperty(
pht('Recurs'), pht('Recurs'),
ucwords(idx($event->getRecurrenceFrequency(), 'rule'))); ucwords(idx($event->getRecurrenceFrequency(), 'rule')));
if ($event->getRecurrenceEndDate()) {
$properties->addProperty(
pht('Recurrence Ends'),
phabricator_datetime($event->getRecurrenceEndDate(), $viewer));
}
if ($event->getInstanceOfEventPHID()) { if ($event->getInstanceOfEventPHID()) {
$properties->addProperty( $properties->addProperty(
pht('Recurrence of Event'), pht('Recurrence of Event'),

View file

@ -90,7 +90,6 @@ final class PhabricatorCalendarEventEditor
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case PhabricatorCalendarEventTransaction::TYPE_RECURRING: case PhabricatorCalendarEventTransaction::TYPE_RECURRING:
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY: case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT: case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX: case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
case PhabricatorCalendarEventTransaction::TYPE_NAME: case PhabricatorCalendarEventTransaction::TYPE_NAME:
@ -101,6 +100,7 @@ final class PhabricatorCalendarEventEditor
return $xaction->getNewValue(); return $xaction->getNewValue();
case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY: case PhabricatorCalendarEventTransaction::TYPE_ALL_DAY:
return (int)$xaction->getNewValue(); return (int)$xaction->getNewValue();
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE: case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
return $xaction->getNewValue()->getEpoch(); return $xaction->getNewValue()->getEpoch();
@ -118,8 +118,6 @@ final class PhabricatorCalendarEventEditor
return $object->setIsRecurring($xaction->getNewValue()); return $object->setIsRecurring($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY: case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY:
return $object->setRecurrenceFrequency($xaction->getNewValue()); return $object->setRecurrenceFrequency($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
return $object->setRecurrenceEndDate($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT: case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT:
return $object->setInstanceOfEventPHID($xaction->getNewValue()); return $object->setInstanceOfEventPHID($xaction->getNewValue());
case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX: case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX:
@ -133,6 +131,9 @@ final class PhabricatorCalendarEventEditor
case PhabricatorCalendarEventTransaction::TYPE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
$object->setDateTo($xaction->getNewValue()); $object->setDateTo($xaction->getNewValue());
return; return;
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
$object->setRecurrenceEndDate($xaction->getNewValue());
return;
case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION: case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION:
$object->setDescription($xaction->getNewValue()); $object->setDescription($xaction->getNewValue());
return; return;
@ -313,6 +314,7 @@ final class PhabricatorCalendarEventEditor
$errors[] = $error; $errors[] = $error;
} }
break; break;
case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE:
case PhabricatorCalendarEventTransaction::TYPE_START_DATE: case PhabricatorCalendarEventTransaction::TYPE_START_DATE:
case PhabricatorCalendarEventTransaction::TYPE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE:
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {

View file

@ -110,8 +110,9 @@ final class PhabricatorCalendarEventQuery
foreach ($events as $event) { foreach ($events as $event) {
$sequence_start = 0; $sequence_start = 0;
$instance_count = null; $sequence_end = null;
$duration = $event->getDateTo() - $event->getDateFrom(); $duration = $event->getDateTo() - $event->getDateFrom();
$end = null;
if ($event->getIsRecurring() && !$event->getInstanceOfEventPHID()) { if ($event->getIsRecurring() && !$event->getInstanceOfEventPHID()) {
$frequency = $event->getFrequencyUnit(); $frequency = $event->getFrequencyUnit();
@ -135,28 +136,31 @@ final class PhabricatorCalendarEventQuery
} }
$date = $start; $date = $start;
$start_datetime = PhabricatorTime::getDateTimeFromEpoch( $datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer);
$start,
$viewer);
if ($this->rangeEnd) { if (($this->rangeEnd && $event->getRecurrenceEndDate()) &&
$this->rangeEnd < $event->getRecurrenceEndDate()) {
$end = $this->rangeEnd; $end = $this->rangeEnd;
$instance_count = $sequence_start; } else if ($event->getRecurrenceEndDate()) {
$end = $event->getRecurrenceEndDate();
} else if ($this->rangeEnd) {
$end = $this->rangeEnd;
}
if ($end) {
$sequence_end = $sequence_start;
while ($date < $end) { while ($date < $end) {
$instance_count++; $sequence_end++;
$datetime = PhabricatorTime::getDateTimeFromEpoch($date, $viewer);
$datetime->modify($modify_key); $datetime->modify($modify_key);
$date = $datetime->format('U'); $date = $datetime->format('U');
} }
} else { } else {
$instance_count = $this->getRawResultLimit(); $sequence_end = $this->getRawResultLimit() + $sequence_start;
} }
$sequence_start = max(1, $sequence_start); $sequence_start = max(1, $sequence_start);
$max_sequence = $sequence_start + $instance_count; for ($index = $sequence_start; $index < $sequence_end; $index++) {
for ($index = $sequence_start; $index < $max_sequence; $index++) {
$instance_sequence_pairs[] = array($event->getPHID(), $index); $instance_sequence_pairs[] = array($event->getPHID(), $index);
$events[] = $event->generateNthGhost($index, $viewer); $events[] = $event->generateNthGhost($index, $viewer);

View file

@ -373,7 +373,6 @@ final class PhabricatorCalendarEventSearchEngine
$event->setDescription(pht('%s (%s)', $name_text, $status_text)); $event->setDescription(pht('%s (%s)', $name_text, $status_text));
$event->setName($status_text); $event->setName($status_text);
$event->setURI($status->getURI()); $event->setURI($status->getURI());
// $event->setEventID($status->getID());
$event->setViewerIsInvited($viewer_is_invited); $event->setViewerIsInvited($viewer_is_invited);
$month_view->addEvent($event); $month_view->addEvent($event);
} }

View file

@ -23,6 +23,11 @@ final class AphrontFormDateControl extends AphrontFormControl {
return $this; return $this;
} }
public function setIsDisabled($is_datepicker_disabled) {
$this->isDisabled = $is_datepicker_disabled;
return $this;
}
public function setEndDateID($value) { public function setEndDateID($value) {
$this->endDateID = $value; $this->endDateID = $value;
return $this; return $this;

View file

@ -5,10 +5,17 @@
JX.behavior('recurring-edit', function(config) { JX.behavior('recurring-edit', function(config) {
var checkbox = JX.$(config.isRecurring); var checkbox = JX.$(config.isRecurring);
JX.DOM.listen(checkbox, 'change', null, function() { JX.DOM.listen(checkbox, 'change', null, function() {
var frequency = JX.$(config.frequency); var frequency = JX.$(config.frequency);
var end_date = JX.$(config.recurrenceEndDate);
frequency.disabled = checkbox.checked ? false : true; frequency.disabled = checkbox.checked ? false : true;
end_date.disabled = checkbox.checked ? false : true;
if (end_date.disabled) {
JX.DOM.alterClass(end_date, 'datepicker-disabled', !checkbox.checked);
}
}); });
}); });