To avoid losing any information (e.g., remote mappings with costs) or getting a mess in the data structure, we need to stop allowing to re-submit cancelled jobs.

Instead, add a button that creates a new job with new job items that point to the same source.

Comments

blueminds’s picture

Status: Active » Needs review
StatusFileSize
new9.46 KB

See the patch.

miro_dietiker’s picture

Status: Needs review » Needs work

Here, a quick first review.

  1. +++ b/entity/tmgmt.entity.job.inc
    @@ -102,6 +102,23 @@ class TMGMTJob extends Entity {
    +  public function cloneAsUnprocessed() {
    

    This is absolutely right. Pushing this into the __clone() method would be wrong IMHO.

  2. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -550,6 +550,20 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +    $form['actions']['resubmit'] = array(
    ...
    +    $form['actions']['cancel_translation'] = array(
    

    I would prefer these two swapped: First cancel, then resubmit.

    The naming is inconsistent: "cancel_TRANSLATION" - then "resubmit_translation". Otherwise cancel + resubmit.

  3. +++ b/ui/tmgmt_ui.test
    @@ -370,4 +370,62 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +    $job->addItem('test_source', 'test', 1);
    

    I would say we need multiple items.

  4. +++ b/ui/tmgmt_ui.test
    @@ -370,4 +370,62 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +      $_item = $resubmitted_job->getItems(array('data' => array('value' => serialize($item->data))));
    +      $_item = reset($_item);
    

    First it's a list of items, then a single item. Name it so.

  5. +++ b/ui/tmgmt_ui.test
    @@ -370,4 +370,62 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +    $this->assertRaw(t('Job has been resubmitted to the translator as a new job <a href="@url">#@id</a>.',
    

    Also, the new job should have a special log message referring to its origin.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new8.91 KB
new2.97 KB

cancel_translation and resubmit_translation are mutually exclusive so the order does not matter there.

Both jobs do have a message attached.

For the rest see the patch.

miro_dietiker’s picture

Status: Needs review » Needs work

:-) nice, almost there.

+++ b/entity/tmgmt.entity.job_item.inc
@@ -114,6 +114,16 @@ class TMGMTJobItem extends Entity {
+    $clone->tjid = $clone->tjiid = $clone->changed = NULL;
+    $clone->state = TMGMT_JOB_ITEM_STATE_ACTIVE;

Here you need to clear data of the items as well.

Bonus points for test coverage. (But it requires, data isn't empty first..)

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new9.17 KB
new1.4 KB

Oh yes...

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/entity/tmgmt.entity.job.inc
    @@ -102,6 +102,17 @@ class TMGMTJob extends Entity {
    +    $clone->tjid = $clone->uid = $clone->changed = $clone->reference = NULL;
    

    I think this would be less confusing if you write separate lines. Feels weird to set completely different things in a single multi-assignment line.

    Also, uid should probably be set to the current user?

  2. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -550,6 +550,20 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +      '#attributes' => array('onclick' => 'return confirm("' . t('This action will duplicate current job and submit to the translator. Do you which to continue?') . '")'),
    ...
    +      '#attributes' => array('onclick' => 'return confirm("' . t('This action will cancel the job at the translator. Do you which to continue?') . '")'),
    

    onclick confirmations seem like a completely new behavior, Drupal usually uses confirm forms?

  3. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -575,6 +589,45 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
     /**
    + * Submit handler of the job translation cancel action.
    + */
    +function tmgmt_ui_job_cancel_translation(array $form, array &$form_state) {
    +  /** @var TMGMTJob $job */
    +  $job = entity_ui_form_submit_build_entity($form, $form_state);
    +  if (!$job->cancelTranslation()) {
    +    // This is the case when a translator does not support the cancel operation.
    +    // It would make more sense to not display the button for the action,
    +    // however we do not know if the translator is able to cancel a job until
    +    // we trigger the action.
    +    drupal_set_message(t('The translation could not be cancelled, the selected translator does not support this action.'), 'warning');
    +  }
    +}
    

    We should use the get messages to display the message that the translator might have added, not just invent something that might not be correct.

  4. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -575,6 +589,45 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +/**
    + * Submit handler to duplicate a job and submit it to a translator.
    + */
    +function tmgmt_ui_job_resubmit(array $form, array &$form_state) {
    +  /** @var TMGMTJob $job */
    +  $job = entity_ui_form_submit_build_entity($form, $form_state);
    +  $job_to_resubmit = $job->cloneAsUnprocessed();
    +  $job_to_resubmit->save();
    +  /** @var TMGMTJobItem $item */
    +  foreach ($job->getItems() as $item) {
    +    $item_to_resubmit = $item->cloneAsActive();
    +    $job_to_resubmit->addExistingItem($item_to_resubmit);
    +  }
    +
    +  tmgmt_ui_job_request_translation($job_to_resubmit);
    +
    +  $job->addMessage('Job has been resubmitted to the translator as a new job <a href="@url">#@id</a>.',
    +    array('@url' => url('admin/tmgmt/jobs/' . $job_to_resubmit->tjid), '@id' => $job_to_resubmit->tjid));
    +  $job_to_resubmit->addMessage('This job is a resubmission of the previously cancelled job <a href="@url">#@id</a>',
    +    array('@url' => url('admin/tmgmt/jobs/' . $job->tjid), '@id' => $job->tjid));
    +
    +  $form_state['redirect'] = 'admin/tmgmt/jobs/' . $job_to_resubmit->tjid;
    +}
    

    Why is this a single action?

    I'd expect a Duplicate, that *just* duplicates and then lets me go through the checkout process again?

    Chances are that I *don't* want to use the same translator again, otherwise I probably wouldn't have cancelled?

  5. +++ b/ui/tmgmt_ui.test
    @@ -370,4 +370,67 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +      $this->assertEqual($_item->word_count, $item->word_count);
    

    word_count and the other statistics have to be re-calculated. They're not re-set, so we're not sure they are.

    I think there are two main reasons to cancel a job:

    a) not being happy with the translator. at all. That's where re-submit doesn't work.

    b) The source might have changed, e.g. the nodes were changed and need to be translated again. So we need to make sure that everything is properly re-calculated based on what exists right now. Here a retranslate could be useful, but there might be some options, the different text results in a different quote and so on, so it's ok to click twice.

miro_dietiker’s picture

Uh, oh, interesting...
So with cloning the job + items, we are recapturing the item source...
So a "cloned" job might be different in content.

Sure, a source update is expected sometimes and makes sense. But i'm not so sure it should be implicit...

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new10.99 KB
new8.72 KB

see the patch

miro_dietiker’s picture

Status: Needs review » Needs work

Some more detailled review. The clones seem much cleaner now. Still something more to test.

  1. +++ b/entity/tmgmt.entity.job_item.inc
    @@ -118,7 +118,15 @@ class TMGMTJobItem extends Entity {
    +    $clone->changed = NULL;
    +    $clone->word_count = NULL;
    +    $clone->count_accepted = NULL;
    +    $clone->count_pending = NULL;
    +    $clone->count_translated = NULL;
    +    $clone->count_reviewed = NULL;
    

    Please also check the other counter values in the test.

  2. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -552,17 +552,17 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +      '#submit' => array('tmgmt_ui_submit_redirect'),
    ...
    +      '#submit' => array('tmgmt_ui_submit_redirect'),
    
    @@ -589,27 +589,60 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +function tmgmt_ui_job_action_form(array $form, array &$form_state, TMGMTJob $job, $action) {
    ...
    +    case 'cancel_translation':
    +      $message = t('This action will cancel the job at the translator');
    ...
    +    case 'resubmit_translation':
    +      $message = t('This action will duplicate current job');
    
    +++ b/ui/tmgmt_ui.module
    @@ -49,6 +49,15 @@ function tmgmt_ui_menu() {
    +    'page callback' => 'drupal_get_form',
    +    'page arguments' => array('tmgmt_ui_job_action_form', 3, 4),
    

    Not sure this pattern is that common. Possibly use separate confirmation forms?
    https://api.drupal.org/api/drupal/modules%21system%21system.module/funct...
    Check core and other good examples.

  3. +++ b/ui/includes/tmgmt_ui.pages.inc
    @@ -552,17 +552,17 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +      '#redirect' => 'admin/tmgmt/jobs/' . $job->tjid . '/resubmit_translation',
    
    @@ -589,27 +589,60 @@ function tmgmt_job_form($form, &$form_state, TMGMTJob $job, $op = 'edit') {
    +    default:
    +      drupal_goto('admin/tmgmt/jobs/' . $job->tjid);
    
    +++ b/ui/tmgmt_ui.module
    @@ -49,6 +49,15 @@ function tmgmt_ui_menu() {
    +  $items['admin/tmgmt/jobs/%tmgmt_job/%'] = array(
    

    With this setup i can use any constructed URL admin/tmgmt/jobs/' . $job->tjid . '/xyz' that redirects. We should be more selective.
    With explicit forms at the confirmation URLs we would be much more straight forward readable and less risk for uncovered accidental special cases.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new11.42 KB
new3.29 KB

here we go

berdir’s picture

Shouldn't resubmit_translation now be renamed to clone or duplicate or something like that?

blueminds’s picture

Was thinking about it as well as that is what we do now, but if i want to cancel a job i expect the action to be named with "cancel" and not duplicate/ clone. Also the cloning is only part of the action we do, we first do cancel the old job and then move on to duplicate it.

berdir’s picture

Status: Needs review » Needs work
StatusFileSize
new19.83 KB

Ok, yes, resubmit is fine, but I don't get the _transaction suffix, that makes no sense to me. Neither in the machine name, nor the button label (maybe Cancel/Re-submit job instead?).

Even with that change, the buttons don't work anymore, we have too many of them:

too_many_confusing_buttons.png

We can't have two cancel buttons. Ideas? We could make cancel a link, similar to the confirm forms, but that only helps a bit...

The menu items and operation handling should be in TMGMTJobUIController.

berdir’s picture

Oh, also, the resubmit messages are no longer correct ("has been resubmitted", for example).

blueminds’s picture

The cancel button: what is its purpose? From reading the code it should relocate to the jobs list, but it will not do so as the #type is button and not submit. Also this button is displayed only in case the job is active, so if unprocessed or submitted it is not there, why? From reading the code it servers as a back action that optionally cancels everything that I have done in the translator settings. So why not call it "Back" and display it at any job state?

blueminds’s picture

Or what about keeping the cancel button with "cancel" text and use "terminate" for the action of not wanting the translation process to continue?

blueminds’s picture

We now do "Abort translation". This is an action that will abort the translation process and therefore cancel the job.

The cancel button remained cancel as such behaviour is in most of the times triggered by a cancel button.

blueminds’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, tmgmt-cancell_translation-2106637-6.patch, failed testing.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new12.41 KB

ojeje...

berdir’s picture

Still not convinced about the button labels (especially the translation part, we don't do that anywhere else). Will try to sit together with Miro and discuss it through.

berdir’s picture

Status: Needs review » Needs work

Recoverable fatal error: Argument 3 passed to tmgmt_ui_job_cancel() must be an instance of TMGMTJob, none given

No test for cancel?

I still *really* would like to see this as a link, we have too many buttons there. Have a look at how confirm_form() does this, it also supports a ?destination= override. I don't think we need to worry about the redirect queue, we don't have cancel yet on checkout anyway (although that's where we should have it and where it should probably be a button that deletes the job again and instead don't display a delete on that page, separate issue).

Also, we discussed this quite a bit here, and this is what we agreed on:
- Abort translation => Abort job.
- We discussed Abort vs. Cancel and agreed on Abort, that however means we need to do it consistently. The job state label needs to be renamed to Aborted, and we need a job item state for aborted as well. Aborted job items should not display their progress information in the view (it's still ok to view them and e.g. copy out translations in there, but it shouldn't be possible to accept or do anything with them, that right now possible, you can add translations, review it and save it as completely. Maybe only display cancel there for aborted job items and nothing else)
- We will not yet rename the constants and methods (but use abort for the new ones for job items), but open a follow-up issue for that part.
- Resubmit to translator => Resubmit. Instead, explain on the confirm form what this means more detailed, have a short but correct title/question (Resubmit as a new job?) and replace the stupid this can not be undone description (because it can) with something that explains what it does: This creates a new job with the same items which can then be submitted again.
- The abort confirm page also needs some work, it shouldn't use abort *and* cancel. Instead, "Abort this job?" and a description that explains a request to abort the job will be sent to the translator and it won't be possible to do anything with it if that succeeds
- The confirm forms are also not yet part of the operationForm() method, see delete for example. Also, looking at that, we do have a dead implementation for cancel there, which means we can replace that one.

miro_dietiker’s picture

Perfectly summarised.

Additionally, we need to define what happens if a translator callback is fired and wants to pass translations.
The job is aborted, agree. I tend to say it should be rejected with no update applied.
On the other hand i don't see any negative effect: We have paid it, data still might come in. It will not hurt.
The question even is, in case we don't get money back, should we tell the translator to stop? :-)

Any thoughts?

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new19.21 KB
new19.32 KB

hehe, one of those where interdiff is larger than patch itself ;)

miro_dietiker’s picture

Status: Needs review » Needs work
  1. +++ b/entity/tmgmt.entity.job.inc
    @@ -429,7 +443,7 @@ class TMGMTJob extends Entity {
    -  public function isCancelled() {
    +  public function isAborted() {
    

    That's a public API. You can't just rename that within a minor release.

  2. +++ b/ui/includes/tmgmt_ui.controller.job.inc
    @@ -57,6 +73,12 @@ class TMGMTJobUIController extends EntityDefaultUIController {
    +          t('This creates a new job with the same items which can then be submitted again.'));
    

    Also state: In case the sources meanwhile changed, the new job will reflect the update.

  3. +++ b/ui/tmgmt_ui.test
    @@ -38,7 +38,7 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +  function NOtestCheckoutForm() {
    
    @@ -227,7 +227,7 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +  function NOtestCheckoutFunction() {
    
    @@ -275,7 +275,7 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +  public function NOtestReview() {
    
    @@ -304,7 +304,7 @@ class TMGMTUITestCase extends TMGMTBaseTestCase {
    +  public function NOtestSuggestions() {
    

    Me unhappy about disabled tests. :-)

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new19.52 KB
new4.88 KB

And what about making the methods deprecated?

Status: Needs review » Needs work

The last submitted patch, tmgmt-cancell_translation-2106637-9.patch, failed testing.

blueminds’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, tmgmt-cancell_translation-2106637-9.patch, failed testing.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new18.92 KB
new3.83 KB

Here is with original method names.

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/entity/tmgmt.entity.job.inc
    @@ -424,10 +438,12 @@ class TMGMTJob extends Entity {
       /**
    -   * Returns whether the state of this job is 'cancelled'.
    +   * Returns whether the state of this job is 'aborted'.
        *
        * @return boolean
    -   *   TRUE if the state is 'cancelled', FALSE otherwise.
    +   *   TRUE if the state is 'aborted', FALSE otherwise.
    +   *
    +   * @todo - we need to refactor this method to use the "abort" term.
        */
       public function isCancelled() {
         return $this->isState(TMGMT_JOB_STATE_CANCELLED);
    @@ -479,13 +495,15 @@ class TMGMTJob extends Entity {
    
    @@ -479,13 +495,15 @@ class TMGMTJob extends Entity {
       }
    

    Not sure what to do with the comments :( The mix with abort/cancel is a bit weird. Maybe clarify the @todo, because it now partially already uses the term "abort" ;) Just not in the method name, so it should say, @todo Rename method to isAborted() in http://drupal.org/node/....

  2. +++ b/tmgmt.module
    @@ -51,6 +51,9 @@ define('TMGMT_JOB_STATE_ACCEPTED', 3);
      * to confirm it by returning TRUE in cancelTranslation().
    + *
    + * @todo - as of #2106637#comment-7993257 there will be a followup to rename
    + * the constant and methods that deal with cancel operation to "abort".
      */
    

    References don't work like this. We need to create a new issue and reference to that.

  3. +++ b/ui/includes/tmgmt_ui.controller.job.inc
    @@ -73,6 +95,44 @@ class TMGMTJobUIController extends EntityDefaultUIController {
           case 'cancel':
             $entity->cancelTranslation();
             return t('Cancelled the translation job %label.', array('%label' => $entity->label()));
    +      case 'abort':
    +        if (!$entity->cancelTranslation()) {
    +          // This is the case when a translator does not support the cancel operation.
    +          // It would make more sense to not display the button for the action,
    +          // however we do not know if the translator is able to cancel a job until
    +          // we trigger the action.
    +          foreach ($entity->getMessagesSince() as $message) {
    

    We still have cancel and abort here now. We should only have one, the old cancel must be some left-over that was changed a long time ago.

  4. +++ b/ui/includes/tmgmt_ui.controller.job.inc
    @@ -73,6 +95,44 @@ class TMGMTJobUIController extends EntityDefaultUIController {
    +
    +        // We want to redirect to the new job checkout page, could not find any
    +        // nicer way how to control a redirect from here.
    +        $this->path = $this->path . '/' . $job_to_resubmit->tjid;
    

    Yeah, that's a hack :( $this->path is the the overview path, this could theoretically lead to crazy side effects.

    We might have to override the submit callback that calls this function, where it uses $this->path for the redirect and do something differently if operation is resubmit.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new19.62 KB
new4.83 KB

Status: Needs review » Needs work

The last submitted patch, tmgmt-cancell_translation-2106637-11.patch, failed testing.

blueminds’s picture

Status: Needs work » Needs review
StatusFileSize
new19.6 KB

fixed submit handler

berdir’s picture

Status: Needs review » Fixed

Ok, testbot happy (had to kick it a bit, first testbot committed suicide while testing the patched) and I'm happy.

Removed cancel menu callback and confirm form in ui controller before commit.

Committed and pushed!

Status: Fixed » Closed (fixed)
Issue tags: +

Automatically closed - issue fixed for 2 weeks with no activity.