Hi, I've playing around with the patch8, and even if it looks great, it leaks of some flexibility in the end.

Here I detail a set of ideas for refactoring that part.

Currently, actions frame is only show in main list view, with all threads. But actions can also be performed while in single thread view. Maybe the set of actions could be different in some how, I don't know, but the most probably situation is to be able to make the same actions as standing in the list view, but with just a single thread selected: the current viewed thread.

For that (I've looking trough the code) the actions frame should be converted to a single call, so different views can make use of it, something like:

  if (!empty($form['#rows'])) {
    $form[] = _privatemsg_thread_actions_form($query_name, $account);
  }

passing query_name as argument may allow some kind of configuration for the module, according to current view, or in the end, current query.

Next, the way operations are being added now is very good, even the undo action is a great feature, but I can't figure out, if I have 35 tags, may operation in a usable way with this select, I mean: I will have to look through a long select list and find my option. (I know, you may answer: modify the form and attach more options, what can be good, but then I may answer, why on earth do you want the operations api?)

IMHO, currently hook_privatemsg_thread_operations is underexploited, and my proposal would suggest to improve it a little.. just a little.. enough for holding other module's options, but full defined options.. Just some ideas..

  foreach (module_invoke_all('privatemsg_thread_operations') as $operation => $array) {
    if(isset($array['options'])){
      $form['actions'][$operation] = array(
        '#type' => 'select',
        '#options' => array_merge(array(t($array['title'])), $array['options']),
        '#default_value' => 0,
        '#attributes' => array('onchange' => "$('#".$operation."-submit').click()"),
      );
      $form[$operation.'-submit'] = array(
        '#type' => 'submit', 
        '#value' => t($array['title']), 
        '#attributes' => array('style', 'display: none;'),
        '#submit' => $array['submit']
      );
    } else {
      $form['actions'][$operation] = array(
        '#type'  => 'submit',
        '#name' => $operation,
        '#value' => t($array['title']),
        '#submit' => array($array['submit']),
      );
    }
  }

This will build the actions form with several kind of actions: buttons for direct actions, and select lists for option-based actions (mark as read, or as unread). Now, this would be a possible implementation of this hook:

/**
 * Implementation of hook_privatemsg_thread_operations().
 */
function privatemsg_privatemsg_thread_operations() {
  $operations = array();

  $operations['delete'] = array(
    'title'  => t('Delete'),
    'description' => t('Remove the thread'),
    'submit' => 'privatemsg_list_submit_delete',
  );

  $operations['mark_as'] = array(
    'title'   => t('Mark as...'),
    'description' => t('Sets read/unread status'),
    'options' => array( PRIVATEMSG_UNREAD => t('Unread'), PRIVATEMSG_READ => t('Read')),
    'submit'  => 'privatemsg_thread_change_status'
  );

  return $operations;
}

On the other hand, other modules (in example, the tags module) would add the following actions:


/**
 * Implementation of hook_privatemsg_thread_operations().
 */
function privatemsg_tags_privatemsg_thread_operations() {
  $operations = array();

  $tags = _privatemsg_tags_get_user_tags();
  $operations['move_to'] = array(
    'title'   => t('Move to...'),
    'description' => t('Sets only this tag to the thread selection'),
    'options' => $options,
    'submit'  => 'privatemsg_tags_set_tag'
  );
  $operations['tag_as'] = array(
    'title'   => t('Tags..'),
    'description' => t('Set/Unset selected tag'),
    'options' => $options,
    'submit'  => 'privatemsg_tags_change_tag'
  );

  return $operations;
}

Note: consider again, it's pseudo-code. I'm not having in count nothing about undoing actions in my explanation, but that also could be integrated wihtout any trouble. The idea I'm talking about is in the included image.

But having this method, results could improve site usability much more. For now, the "actions code" can handle the view and user operation, BUT is insufficent when talking about message auto-filtering-tagging and so: what I called in other posts, the message routing part. When viewing a thread or a list of them, if I decide something to do I will do 1 action. But in auto-filtering-tagging stage, I may choose more than one action.. maybe I would like to handle the messages matching the from "ilo" as: mark as read, apply tag 'stone', remove from inbox, and delete. Each one is the actions I choosed for that filter could be each one of the elements in the array returned by _privatemsg_thread_actions_form (thinking about gmail filtering options).

I just want to say, we have the filters (saved searches in the filter module), we now have the actions, we can do a very flexible message routing code (applying searches filter to incoming messages and performing actions) if we mix both, but for that, "actions" should be refactored this way to be reusable.

what do you think?

CommentFileSizeAuthor
actions.png5.76 KBilo

Comments

naheemsays’s picture

This should probably go with #380534: per thread(s) Actions mechanism should be refactored.

I like how it looks, but the tagging/folders should be an either or IMO, not both. Have a setting in the admin pages over which metaphor to use.

ilo’s picture

bnz, folders do not exists, tust tags are allowded. But the tagging module could provide two diferent actions:

"Move to ..." (Interpreted as move to folder) means remove any tag, and apply just the selected tag
"Set tag ..." Keep other thread's tag, and apply the selected tag

Two very different actions for the end-user, even if it looks the same for any of us. Users with 'folder' based training will be more firiendly with "moving to", the rest will comply with "tag as".

In fact, it's an "OR" of: folders or tags, and the winner is tags.

berdir’s picture

Status: Active » Closed (duplicate)

I added an answer in #348907-34: Per thread/Multiple thread actions, as long as the patch is not commited, we should discuss it there. No need to open a new issue for that, imho.

naheemsays’s picture

bnz, folders do not exists, tust tags are allowded. But the tagging module could provide two diferent actions:

"Move to ..." (Interpreted as move to folder) means remove any tag, and apply just the selected tag
"Set tag ..." Keep other thread's tag, and apply the selected tag

I understand but what I was trying to say was that in the UI, there needs to be a choice of one metaphor or the other. Showing both next to each other is IMO more confusing than strictly only having one.

At most this should be a choice made by by the site admin - at the least something we enforce on the users. IMO That is what useability is all about. giving good defaults instead of exposing every nook and cranny to the end user.

Another "problem" with the folder metaphor is for it to work properly, moving it to another folder should also remove it from the inbox...

berdir’s picture

Another "problem" with the folder metaphor is for it to work properly, moving it to another folder should also remove it from the inbox...
Yes, that is imho the reason why inbox needs to be a tag, and not something hardcoded (aka if a thread is not only from you, it's in inbox.. ). If inbox is a tag, then this is really easy.

As for the configuration. If we allow it to be configurable, it's easy to allow both too.. make it an OR and not an XOR.