@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve usability of Phrequent "Stop Time" dialog

Summary:
Fixes T5848.

- Disallow tracking negative time.
- Preserve note if there's an error with the time selection.
- Show start time and duration.
- Slightly better error messages.

Test Plan: Started and stopped time. Tried to select future/negative ranges.

Reviewers: hach-que, btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T5848

Differential Revision: https://secure.phabricator.com/D10218

+85 -34
+85 -32
src/applications/phrequent/controller/PhrequentTrackController.php
··· 13 13 14 14 public function processRequest() { 15 15 $request = $this->getRequest(); 16 - $user = $request->getUser(); 17 - $editor = new PhrequentTrackingEditor(); 16 + $viewer = $request->getUser(); 18 17 19 18 $phid = $this->phid; 20 19 $handle = id(new PhabricatorHandleQuery()) 21 - ->setViewer($user) 20 + ->setViewer($viewer) 22 21 ->withPHIDs(array($phid)) 23 22 ->executeOne(); 24 - 25 - if (!$this->isStartingTracking() && 26 - !$this->isStoppingTracking()) { 27 - throw new Exception('Unrecognized verb: '.$this->verb); 28 - } 23 + $done_uri = $handle->getURI(); 29 24 25 + $current_timer = null; 30 26 switch ($this->verb) { 31 27 case 'start': 32 28 $button_text = pht('Start Tracking'); ··· 41 37 $inner_text = pht('What time did you stop working?'); 42 38 $action_text = pht('Stop Timer'); 43 39 $label_text = pht('Stop Time'); 40 + 41 + 42 + $current_timer = id(new PhrequentUserTimeQuery()) 43 + ->setViewer($viewer) 44 + ->withUserPHIDs(array($viewer->getPHID())) 45 + ->withObjectPHIDs(array($phid)) 46 + ->withEnded(PhrequentUserTimeQuery::ENDED_NO) 47 + ->executeOne(); 48 + if (!$current_timer) { 49 + return $this->newDialog() 50 + ->setTitle(pht('Not Tracking Time')) 51 + ->appendParagraph( 52 + pht( 53 + 'You are not currently tracking time on this object.')) 54 + ->addCancelButton($done_uri); 55 + } 44 56 break; 57 + default: 58 + return new Aphront404Response(); 45 59 } 46 60 61 + $errors = array(); 62 + $v_note = null; 63 + $e_date = null; 64 + 47 65 $epoch_control = id(new AphrontFormDateControl()) 48 - ->setUser($user) 66 + ->setUser($viewer) 49 67 ->setName('epoch') 50 68 ->setLabel($action_text) 51 69 ->setValue(time()); 52 - 53 - $err = array(); 54 70 55 71 if ($request->isDialogFormPost()) { 72 + $v_note = $request->getStr('note'); 56 73 $timestamp = $epoch_control->readValueFromRequest($request); 57 - $note = $request->getStr('note'); 74 + 75 + if (!$epoch_control->isValid()) { 76 + $errors[] = pht('Please choose an valid date.'); 77 + $e_date = pht('Invalid'); 78 + } else { 79 + $max_time = PhabricatorTime::getNow(); 80 + if ($timestamp > $max_time) { 81 + if ($this->isStoppingTracking()) { 82 + $errors[] = pht( 83 + 'You can not stop tracking time at a future time. Enter the '. 84 + 'current time, or a time in the past.'); 85 + } else { 86 + $errors[] = pht( 87 + 'You can not start tracking time at a future time. Enter the '. 88 + 'current time, or a time in the past.'); 89 + } 90 + $e_date = pht('Invalid'); 91 + } 58 92 59 - if (!$epoch_control->isValid() || $timestamp > time()) { 60 - $err[] = pht('Invalid date, please enter a valid non-future date'); 93 + if ($this->isStoppingTracking()) { 94 + $min_time = $current_timer->getDateStarted(); 95 + if ($min_time > $timestamp) { 96 + $errors[] = pht( 97 + 'Stop time must be after start time.'); 98 + $e_date = pht('Invalid'); 99 + } 100 + } 61 101 } 62 102 63 - if (!$err) { 103 + if (!$errors) { 104 + $editor = new PhrequentTrackingEditor(); 64 105 if ($this->isStartingTracking()) { 65 - $editor->startTracking($user, $this->phid, $timestamp); 106 + $editor->startTracking($viewer, $this->phid, $timestamp); 66 107 } else if ($this->isStoppingTracking()) { 67 - $editor->stopTracking($user, $this->phid, $timestamp, $note); 108 + $editor->stopTracking($viewer, $this->phid, $timestamp, $v_note); 68 109 } 69 - return id(new AphrontRedirectResponse()); 110 + 111 + return id(new AphrontRedirectResponse())->setURI($done_uri); 70 112 } 71 113 72 114 } 73 115 116 + $epoch_control->setError($e_date); 117 + 74 118 $dialog = $this->newDialog() 75 119 ->setTitle($title_text) 76 - ->setWidth(AphrontDialogView::WIDTH_FORM); 77 - 78 - if ($err) { 79 - $dialog->setErrors($err); 80 - } 120 + ->setWidth(AphrontDialogView::WIDTH_FORM) 121 + ->setErrors($errors) 122 + ->appendParagraph($inner_text); 81 123 82 124 $form = new PHUIFormLayoutView(); 83 - $form 84 - ->appendChild(hsprintf( 85 - '<p>%s</p><br />', $inner_text)); 125 + 126 + if ($this->isStoppingTracking()) { 127 + $start_time = $current_timer->getDateStarted(); 128 + $start_string = pht( 129 + '%s (%s ago)', 130 + phabricator_datetime($start_time, $viewer), 131 + phutil_format_relative_time(PhabricatorTime::getNow() - $start_time)); 132 + 133 + $form->appendChild( 134 + id(new AphrontFormStaticControl()) 135 + ->setLabel(pht('Started At')) 136 + ->setValue($start_string)); 137 + } 86 138 87 139 $form->appendChild($epoch_control); 88 140 89 141 if ($this->isStoppingTracking()) { 90 - $form 91 - ->appendChild( 92 - id(new AphrontFormTextControl()) 93 - ->setLabel(pht('Note')) 94 - ->setName('note')); 142 + $form->appendChild( 143 + id(new AphrontFormTextControl()) 144 + ->setLabel(pht('Note')) 145 + ->setName('note') 146 + ->setValue($v_note)); 95 147 } 96 148 97 149 $dialog->appendChild($form); 98 150 99 - $dialog->addCancelButton($handle->getURI()); 151 + $dialog->addCancelButton($done_uri); 152 + 100 153 $dialog->addSubmitButton($action_text); 101 154 102 155 return $dialog;
-2
src/applications/phrequent/event/PhrequentUIEventListener.php
··· 45 45 ->setName(pht('Start Tracking Time')) 46 46 ->setIcon('fa-clock-o') 47 47 ->setWorkflow(true) 48 - ->setRenderAsForm(true) 49 48 ->setHref('/phrequent/track/start/'.$object->getPHID().'/'); 50 49 } else { 51 50 $track_action = id(new PhabricatorActionView()) 52 51 ->setName(pht('Stop Tracking Time')) 53 52 ->setIcon('fa-clock-o red') 54 53 ->setWorkflow(true) 55 - ->setRenderAsForm(true) 56 54 ->setHref('/phrequent/track/stop/'.$object->getPHID().'/'); 57 55 } 58 56