diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php --- a/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventEditController.php @@ -17,11 +17,13 @@ $viewer = $request->getViewer(); $user_phid = $viewer->getPHID(); $error_name = true; + $error_recurrence_end_date = true; $error_start_date = true; $error_end_date = true; $validation_exception = null; $is_recurring_id = celerity_generate_unique_node_id(); + $recurrence_end_date_id = celerity_generate_unique_node_id(); $frequency_id = celerity_generate_unique_node_id(); $all_day_id = celerity_generate_unique_node_id(); $start_date_id = celerity_generate_unique_node_id(); @@ -65,6 +67,7 @@ list($start_value, $end_value) = $this->getDefaultTimeValues($viewer); } + $recurrence_end_date_value = clone $start_value; $submit_label = pht('Create'); $page_title = pht('Create Event'); @@ -138,6 +141,7 @@ $start_value = AphrontFormDateControlValue::newFromEpoch( $viewer, $event->getDateFrom()); + $recurrence_end_date_value = clone $start_value; $submit_label = pht('Update'); $page_title = pht('Update Event'); @@ -179,6 +183,10 @@ $end_value = AphrontFormDateControlValue::newFromRequest( $request, 'end'); + $recurrence_end_date_value = AphrontFormDateControlValue::newFromRequest( + $request, + 'recurrenceEndDate'); + $description = $request->getStr('description'); $subscribers = $request->getArr('subscribers'); $edit_policy = $request->getStr('editPolicy'); @@ -213,6 +221,11 @@ ->setTransactionType( PhabricatorCalendarEventTransaction::TYPE_FREQUENCY) ->setNewValue(array('rule' => $frequency)); + + $xactions[] = id(new PhabricatorCalendarEventTransaction()) + ->setTransactionType( + PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE) + ->setNewValue($recurrence_end_date_value); } $xactions[] = id(new PhabricatorCalendarEventTransaction()) @@ -290,6 +303,8 @@ PhabricatorCalendarEventTransaction::TYPE_START_DATE); $error_end_date = $ex->getShortMessage( PhabricatorCalendarEventTransaction::TYPE_END_DATE); + $error_recurrence_end_date = $ex->getShortMessage( + PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE); $event->setViewPolicy($view_policy); $event->setEditPolicy($edit_policy); @@ -309,6 +324,7 @@ Javelin::initBehavior('recurring-edit', array( 'isRecurring' => $is_recurring_id, 'frequency' => $frequency_id, + 'recurrenceEndDate' => $recurrence_end_date_id, )); $is_recurring_checkbox = id(new AphrontFormCheckboxControl()) @@ -319,6 +335,17 @@ $is_recurring, $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()) ->setName('frequency') ->setOptions(array( @@ -421,6 +448,9 @@ if ($is_recurring_checkbox) { $form->appendChild($is_recurring_checkbox); } + if ($recurrence_end_date_control) { + $form->appendChild($recurrence_end_date_control); + } if ($recurrence_frequency_select) { $form->appendControl($recurrence_frequency_select); } diff --git a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php --- a/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEventViewController.php @@ -135,6 +135,9 @@ $event, PhabricatorPolicyCapability::CAN_EDIT); + var_dump($event->getIsRecurring()); + var_dump($event->getIsGhostEvent()); + if ($event->getIsRecurring() && $event->getIsGhostEvent()) { $index = $event->getSequenceIndex(); diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php --- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php +++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php @@ -118,8 +118,6 @@ return $object->setIsRecurring($xaction->getNewValue()); case PhabricatorCalendarEventTransaction::TYPE_FREQUENCY: return $object->setRecurrenceFrequency($xaction->getNewValue()); - case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE: - return $object->setRecurrenceEndDate($xaction->getNewValue()); case PhabricatorCalendarEventTransaction::TYPE_INSTANCE_OF_EVENT: return $object->setInstanceOfEventPHID($xaction->getNewValue()); case PhabricatorCalendarEventTransaction::TYPE_SEQUENCE_INDEX: @@ -133,6 +131,9 @@ case PhabricatorCalendarEventTransaction::TYPE_END_DATE: $object->setDateTo($xaction->getNewValue()); return; + case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE: + $object->setRecurrenceEndDate($xaction->getNewValue()); + return; case PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION: $object->setDescription($xaction->getNewValue()); return; @@ -264,10 +265,13 @@ protected function validateAllTransactions( PhabricatorLiskDAO $object, array $xactions) { + $recurrence_end_date_xaction = + PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE; $start_date_xaction = PhabricatorCalendarEventTransaction::TYPE_START_DATE; $end_date_xaction = PhabricatorCalendarEventTransaction::TYPE_END_DATE; $start_date = $object->getDateFrom(); $end_date = $object->getDateTo(); + $recurrence_end_date = $object->getRecurrenceEndDate(); $errors = array(); foreach ($xactions as $xaction) { @@ -275,6 +279,8 @@ $start_date = $xaction->getNewValue()->getEpoch(); } else if ($xaction->getTransactionType() == $end_date_xaction) { $end_date = $xaction->getNewValue()->getEpoch(); + } else if ($xaction->getNewValue() == $recurrence_end_date_xaction) { + $recurrence_end_date = $xaction->getNewValue()->getEpoch(); } } if ($start_date > $end_date) { @@ -285,6 +291,14 @@ pht('End date must be after start date.'), null); } + if ($recurrence_end_date && $recurrence_end_date < $end_date) { + $type = PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE; + $errors[] = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Invalid'), + pht('Recurring event must end after event end date.'), + null); + } return $errors; } @@ -313,6 +327,7 @@ $errors[] = $error; } break; + case PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE: case PhabricatorCalendarEventTransaction::TYPE_START_DATE: case PhabricatorCalendarEventTransaction::TYPE_END_DATE: foreach ($xactions as $xaction) { diff --git a/src/view/form/control/AphrontFormDateControl.php b/src/view/form/control/AphrontFormDateControl.php --- a/src/view/form/control/AphrontFormDateControl.php +++ b/src/view/form/control/AphrontFormDateControl.php @@ -23,6 +23,11 @@ return $this; } + public function setIsDisabled($is_datepicker_disabled) { + $this->isDisabled = $is_datepicker_disabled; + return $this; + } + public function setEndDateID($value) { $this->endDateID = $value; return $this; diff --git a/webroot/rsrc/js/application/calendar/behavior-recurring-edit.js b/webroot/rsrc/js/application/calendar/behavior-recurring-edit.js --- a/webroot/rsrc/js/application/calendar/behavior-recurring-edit.js +++ b/webroot/rsrc/js/application/calendar/behavior-recurring-edit.js @@ -5,10 +5,17 @@ JX.behavior('recurring-edit', function(config) { var checkbox = JX.$(config.isRecurring); + JX.DOM.listen(checkbox, 'change', null, function() { var frequency = JX.$(config.frequency); + var end_date = JX.$(config.recurrenceEndDate); 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); + } }); });