@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.

Added a popup to both start and end times with Phrequent allowing the user to edit their start/end times. Also added a field for notes on the stop time

Summary:
I have added a dialog box which pops up when a user starts or stops tracking time on an issue with Phrequent. These dialogs allow the user to modify the time if it so happens that they forgot to either clock in or out.
I have also added a Note field in the dialog when a user stops tracking time. This allows them to enter a note about the time, and is entered into the database, but is currently (as far as I know) not visible anywhere in Phabricator.
I have made these changes according to the suggestions found in T3568

Also, upon clocking in or out, if the time entered is a future time, an error is returned and the user is asked to enter a valid time.

Test Plan:
Start tracking time and edit the start date/time, then end the time and edit that timestamp as well.
Also, try entering future dates/times and ensure that the dialog reports an error and asks for the time again.
Ensure that these edited times are recorded properly.

Reviewers: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Maniphest Tasks: T3568

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

authored by

Brayden and committed by
epriestley
715bf1fd 3e9a988c

+84 -9
+84 -9
src/applications/phrequent/controller/PhrequentTrackController.php
··· 15 15 $request = $this->getRequest(); 16 16 $user = $request->getUser(); 17 17 18 + $phid = $this->phid; 19 + $handle = id(new PhabricatorHandleQuery()) 20 + ->setViewer($user) 21 + ->withPHIDs(array($phid)) 22 + ->executeOne(); 23 + 18 24 if (!$this->isStartingTracking() && 19 25 !$this->isStoppingTracking()) { 20 26 throw new Exception('Unrecognized verb: ' . $this->verb); 21 27 } 22 28 23 - if ($this->isStartingTracking()) { 24 - $this->startTracking($user, $this->phid); 25 - } else if ($this->isStoppingTracking()) { 26 - $this->stopTracking($user, $this->phid); 29 + switch ($this->verb) { 30 + case 'start': 31 + $button_text = pht('Start Tracking'); 32 + $title_text = pht('Start Tracking Time'); 33 + $inner_text = pht('What time did you start working?'); 34 + $action_text = pht('Start Timer'); 35 + $label_text = pht('Start Time'); 36 + break; 37 + case 'stop': 38 + $button_text = pht('Stop Tracking'); 39 + $title_text = pht('Stop Tracking Time'); 40 + $inner_text = pht('What time did you stop working?'); 41 + $action_text = pht('Stop Timer'); 42 + $label_text = pht('Stop Time'); 43 + break; 44 + } 45 + 46 + $epoch_control = id(new AphrontFormDateControl()) 47 + ->setUser($user) 48 + ->setName('epoch') 49 + ->setLabel($action_text) 50 + ->setValue(time()); 51 + 52 + $err = array(); 53 + 54 + if ($request->isDialogFormPost()) { 55 + $timestamp = $epoch_control->readValueFromRequest($request); 56 + $note = $request->getStr('note'); 57 + 58 + if (!$epoch_control->isValid() || $timestamp > time()) { 59 + $err[] = pht('Invalid date, please enter a valid non-future date'); 60 + } 61 + 62 + if (!$err) { 63 + if ($this->isStartingTracking()) { 64 + $this->startTracking($user, $this->phid, $timestamp); 65 + } else if ($this->isStoppingTracking()) { 66 + $this->stopTracking($user, $this->phid, $timestamp, $note); 67 + } 68 + return id(new AphrontRedirectResponse()); 69 + } 70 + 71 + } 72 + 73 + $dialog = $this->newDialog() 74 + ->setTitle($title_text) 75 + ->setWidth(AphrontDialogView::WIDTH_FORM); 76 + 77 + if ($err) { 78 + $dialog->setErrors($err); 27 79 } 28 80 29 - return id(new AphrontRedirectResponse()); 81 + $form = new PHUIFormLayoutView(); 82 + $form 83 + ->appendChild(hsprintf( 84 + "<p>%s</p><br />", $inner_text)); 85 + 86 + $form->appendChild($epoch_control); 87 + 88 + if ($this->isStoppingTracking()) { 89 + $form 90 + ->appendChild( 91 + id(new AphrontFormTextControl()) 92 + ->setLabel(pht('Note')) 93 + ->setName('note')); 94 + } 95 + 96 + $dialog->appendChild($form); 97 + 98 + $dialog->addCancelButton($handle->getURI()); 99 + $dialog->addSubmitButton($action_text); 100 + 101 + return $dialog; 30 102 } 31 103 32 104 private function isStartingTracking() { ··· 37 109 return $this->verb === 'stop'; 38 110 } 39 111 40 - private function startTracking($user, $phid) { 112 + private function startTracking($user, $phid, $timestamp) { 41 113 $usertime = new PhrequentUserTime(); 42 - $usertime->setDateStarted(time()); 114 + $usertime->setDateStarted($timestamp); 43 115 $usertime->setUserPHID($user->getPHID()); 44 116 $usertime->setObjectPHID($phid); 45 117 $usertime->save(); 46 118 } 47 119 48 - private function stopTracking($user, $phid) { 120 + private function stopTracking($user, $phid, $timestamp, $note) { 49 121 if (!PhrequentUserTimeQuery::isUserTrackingObject($user, $phid)) { 50 122 // Don't do anything, it's not being tracked. 51 123 return; ··· 57 129 queryfx( 58 130 $conn, 59 131 'UPDATE %T usertime '. 60 - 'SET usertime.dateEnded = UNIX_TIMESTAMP() '. 132 + 'SET usertime.dateEnded = %d, '. 133 + 'usertime.note = %s '. 61 134 'WHERE usertime.userPHID = %s '. 62 135 'AND usertime.objectPHID = %s '. 63 136 'AND usertime.dateEnded IS NULL '. 64 137 'ORDER BY usertime.dateStarted, usertime.id DESC '. 65 138 'LIMIT 1', 66 139 $usertime_dao->getTableName(), 140 + $timestamp, 141 + $note, 67 142 $user->getPHID(), 68 143 $phid); 69 144 }