[#73238226]: enable milestone calls with level_id and no script_level_id

For pivotal item #73238226, I want to enable re-sharing of levels that were shared with you. In order to do that, the blockly apps need to be able to submit a new "program" via a milestone call to the dashboard while viewing the share page. The share page is not script based (it is level based, since the sharing is based on a LevelSource object). So I needed to enable a variant of the milestone() call that will record the "program" submitted as a new LevelSource (if necessary) and return it to the client.

This new URL is '/milestone/:user_id/level/:level_id'. It is routed to the same milestone method that services the existing milestone URL, but that method now sees script_level_id as an optional parameter and if doesn't find it, it looks for a level_id parameter instead. The activities controller now uses @level throughout the other methods.

The milestone response when a scrip_level_id is not supplied is much simpler, but it does have enough data in it to allow the share to occur.

I also cleaned up some of sendReport.js.erb to avoid some JS exceptions in rare cases where the response or report was incomplete.

To complete this pivotal item, a PR on the blockly side is forthcoming...
I think it is better to call it. Otherwise the state machine in the blockly app is sort of "stuck" indefinitely. I think it is better to make the onComplete() handler robust (which it appears to be based on my testing) then to let it just wait forever.