politics-rewired / Spoke

Politics Rewired's fork of Spoke
GNU General Public License v3.0
35 stars 16 forks source link

Support script import from word processor file #1113

Open ajohn25 opened 2 years ago

ajohn25 commented 2 years ago

Is your feature request related to a problem? Please describe. The Script Preview feature facilitates sharing a campaign script with collaborators who are not Spoke organization members. One common method of making edits as a team is to paste the script preview into a Google Doc and then indicate edits to be made. However, edits cannot be imported into Spoke, so it becomes the responsibility of a Spoke Admin to manually make any requested changes.

Describe the solution you'd like The interactions section on the AdminCampaignEdit page should include an "Import Script" button to allow a Spoke Admin to import the script tree from a Google Doc. The template document would presumably use a similar format as Script Preview to distinguish the different parts of the script.

Describe alternatives you've considered Similar functionality but allowing import from a .docx file instead of a Google Doc.

bengilvar commented 1 year ago

A large client also requested this and said that people love this feature on other spoke forks.

hiemanshu commented 1 year ago

Using mammoth can convert a docx file to html, that is decently formatted! We can make our changes to the template to change the final html output if it makes things easier to read. Here's the html file from https://docs.google.com/document/d/1gFji2Vh_0svb4j7VUtmJZkqNhRWt3htp_bdGoWh6S6w/edit#

<h2>
  <a id="_fo6nvxcomzft"></a>Notes
</h2>
<p>You can put any notes about the script/campaign here. This section will not affect the import.</p>
<h2>
  <a id="_rq2aln93r4lg"></a>
  <strong>Interactions</strong>
</h2>
<h3>
  <a id="_c0kp9j93yptd"></a>Initial
</h3>
<p>Hey! This is {texterAliasOrFirstName}. I’m a union member and wanted to tell you that tomorrow’s election is really important for [STATE] families. Will you vote tomorrow?</p>
<h3>
  <a id="_edhteqpzb9e7"></a>Disposition
</h3>
<h4>
  <a id="_m4wosljnxa17"></a>Already Voted
</h4>
<ul>
  <li>That’s great to hear! Make sure your friends and family vote, too.</li>
  <li>
    <em>Will Vote</em>
  </li>
</ul>
<h4>
  <a id="_wcdg7tecn0rl"></a>Voting later
</h4>
<ul>
  <li>That’s great to hear! Do you know where and when to vote tomorrow?</li>
  <li>
    <em>Will Vote </em>
  </li>
</ul>
<h5>
  <a id="_1ly04omicia"></a>When/Where
</h5>
<h6>
  <a id="_bvbbmjs3gcp2"></a>Yes
</h6>
<ul>
  <li>
    <ul>
      <li>Sounds great! Make sure your friends and family vote, too. </li>
    </ul>
  </li>
</ul>
<h6>
  <a id="_33y9nsy9grhv"></a>No
</h6>
<ul>
  <li>
    <ul>
      <li>Voting hours are [HOURS], and you can find your polling place here: [WEBSITE]</li>
    </ul>
  </li>
</ul>
<h4>
  <a id="_udpoy0fvtcl4"></a>Not voting
</h4>
<ul>
  <li>This election is so crucial for working people, and union members could be the difference in who gets elected. Will you reconsider voting tomorrow?</li>
  <li>
    <em>Not Voting</em>
  </li>
</ul>
<h5>
  <a id="_cy3jx0a55xgz"></a>Reconsider
</h5>
<h6>
  <a id="_9pra7thuxzur"></a>No
</h6>
<ul>
  <li>
    <ul>
      <li>Well, if you change your mind, voting hours are [HOURS], and you can find your polling place here [WEBSITE]</li>
    </ul>
  </li>
</ul>
<h6>
  <a id="_w27n09pq2epu"></a>Yes
</h6>
<ul>
  <li>
    <ul>
      <li>That’s great to hear! Do you know where and when to vote tomorrow?</li>
      <li>
        <em>Will Vote </em>
      </li>
    </ul>
  </li>
</ul>
<h5>
  <a id="_g2zrav9ss3ao"></a>When/Where
</h5>
<h6>
  <a id="_e9cfc4bdrrwf"></a>Yes
</h6>
<ul>
  <li>
    <ul>
      <li>
        <ul>
          <li>Sounds great! Make sure your friends and family vote, too. </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
<h6>
  <a id="_qxnp4848h05e"></a>No
</h6>
<ul>
  <li>
    <ul>
      <li>
        <ul>
          <li>Voting hours are [HOURS], and you can find your polling place here: [WEBSITE]</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
<h4>
  <a id="_o7qezyxt8ab8"></a>Moved/Ineligible
</h4>
<ul>
  <li>No problem. If you have friends or family in [STATE], please make sure they vote!</li>
  <li>
    <em>Moved</em>
  </li>
</ul>
<h2>
  <a id="_ahw39pox7il"></a>Canned Responses
</h2>
<h3>
  <a id="_6g7hkr7v9nkd"></a>How did you get my number?
</h3>
<p>Union members like me are working with your union and others reaching out to members to encourage them to vote. </p>
<h3>
  <a id="_ab1iiopeqox4"></a>Wrong Number
</h3>
<p>"Wrong Number": Thank you for letting me know! I’ll make sure this is reflected in our list. Have a great day.😀</p>
<p>
  <em>4 — Wrong Number</em>
</p>
<p>
  <em>2: Another tag</em>
</p>
<h3>
  <a id="_goagta7555g9"></a>Individual union concerns/complaints
</h3>
<p>I hear you, but unfortunately can’t help with that. You’ll have to reach out to your local union or shop steward.</p>
<h3>
  <a id="_9r8tjzxb0gd4"></a>Questions about the candidates
</h3>
<p>For more information about the candidates on the ballot, I suggest visiting the [STATE] AFL-CIO website for a list of endorsed candidates: [WEBSITE]</p>
<h2>
  <a id="_58vk5po22syk"></a>Action Handlers
</h2>
<p>
  <em>Will Vote</em>
</p>
<p>ngpvan-action</p>
<p>{"value":"{\"canvassContext\":{\"contactTypeId\":78,\"inputTypeId\":4},\"responses\":[{\"type\":\"SurveyResponse\",\"surveyQuestionId\":400595,\"surveyResponseId\":1638961}]}","label":"20: Vote - 1-Will Vote"}</p>
<p>
  <em>Maybe Voting</em>
</p>
<p>ngpvan-action</p>
<p>{"value":"{\"canvassContext\":{\"contactTypeId\":78,\"inputTypeId\":4},\"responses\":[{\"type\":\"SurveyResponse\",\"surveyQuestionId\":400595,\"surveyResponseId\":1638962}]}","label":"20: Vote - 2-Maybe Voting"}</p>
<p>
  <em>Not Voting</em>
</p>
<p>ngpvan-action</p>
<p>{"value":"{\"canvassContext\":{\"contactTypeId\":78,\"inputTypeId\":4},\"responses\":[{\"type\":\"SurveyResponse\",\"surveyQuestionId\":400595,\"surveyResponseId\":1638963}]}","label":"20: Vote - 3-Not Voting"}</p>
<p>
  <em>Moved</em>
</p>
<p>ngpvan-action</p>
<p>{"value":"{\"canvassContext\":{\"contactTypeId\":78,\"inputTypeId\":4},\"resultCodeId\":5}","label" : "Moved"}</p>
<h2>
  <a id="_8a18sidxbmg5"></a>Template Instructions
</h2>
<p>(Sections start with Heading 2)</p>
<p>For Interactions (the elements that make up a script):</p>
<h3>
  <a id="_eq3yosn9o576"></a>Question labels use Heading 3
</h3>
<h4>
  <a id="_4h9snxb2ljqr"></a>Answer labels indented with Heading 4
</h4>
<ul>
  <li>
    <ul>
      <li>Script below in normal text</li>
      <li>
        <em>Action Handlers are italicized</em>
      </li>
    </ul>
  </li>
</ul>
<h5>
  <a id="_nrdwyh4d56un"></a>Follow-up questions with Heading 5
</h5>
<h6>
  <a id="_p2cghsrwm3rn"></a>Follow up answer labels Heading 6
</h6>
<ul>
  <li>
    <ul>
      <li>
        <ul>
          <li>Script text normal again</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
<p>For Canned Responses:</p>
<h3>
  <a id="_ux9sj668bsza"></a>Use Heading 3 for the canned response label
</h3>
<p>Followed by the canned response script text</p>
<p>
  <em>4 — Tag to associate (starting with tag id) </em>
</p>
<h3>
  <a id="_gs2wx87jb17t"></a>Another canned response label
</h3>
<p>Another script response</p>
hiemanshu commented 1 year ago

@politics-rewired/organizing do you want support for both google docs and uploading a .docx files, or just the .docx upload is enough? Since you can download a docx from google docs anyways.

hiemanshu commented 1 year ago

Organizing wants to use Google Sheets for this!

https://rewiredcoop.slack.com/archives/C02LYSTHP0Q/p1669140236706069

hiemanshu commented 1 year ago

Created by: @hiemanshu Signed off by:

User Story

As an Admin/Supervolunteer/Owner I should be able to import the script using Google Sheets

UI Design Considerations

A new section called "Import from Sheets" with instructions, a link to the helpdesk document, and a field to paste the sheets link, and Import button.

The new section can be used in the future to import campaign variables, canned responses from the same sheet doc.

Technical Details

The most complex part of this would be figuring out how to import the formatting from sheets. Other parts of this are connecting to google sheets and pulling in the sheet data.

Acceptance Criteria

Scenario: User import sheet into fresh campaign “Given that I'm an Admin When I open the "Import from Sheets" Section Then I paste the link of the sheets And I click the import button Then Spoke imports the script into interactions steps section"

Scenario: User import sheet into campaign with steps “Given that I'm an Admin When I open the "Import from Sheets" Section Then I paste the link of the sheets And click the import button Then Spoke displays a warning about current scripts being deleted And I click on the accept button Then Spoke deletes all my current interactions And Spoke imports the script into interactions section"

QA Considerations

Organizing should test this with multiple scenarios of loads of possible paths

hiemanshu commented 1 year ago

@politics-rewired/organizing @bchrobot thoughts?

bchrobot commented 1 year ago
hiemanshu commented 1 year ago

I think it would be good to document why Sheets over Docs. I don't disagree, but would like to see it recorded. Has anyone from https://github.com/orgs/politics-rewired/teams/organizing personally used the Docs import feature from MoveOn.org's (or other's) fork?

Yeah, this happened over slack I think, we should definitely add more info here. The short version is Docs relies on tab based formatting to add new levels. In sheets you just use the next column. Much easier to debug / work with.

Add acceptance criteria for attempting to import a sheet with an invalid format Will do!

Is it too much to add a stretch goal of a separate Google Sheets plugin that adds a "Validate for Spoke import" button to Google Sheets itself?

We could add it a new card for it! It's a doable stretch goal, and for the sake of UAC and Story Points, would be worth just splitting into it's own task.

hiemanshu commented 1 year ago

@politics-rewired/organizing did you have a final doc style for this ready?

ajohn25 commented 1 year ago

Typed this up a while ago and forgot to hit send 🤦🏾‍♂️

I think it would be good to document why Sheets over Docs. I don't disagree, but would like to see it recorded. Has anyone from https://github.com/orgs/politics-rewired/teams/organizing personally used the Docs import feature from MoveOn.org's (or other's) fork?

I've used docs import on another fork and agree with this list of things we came up with for why Sheets is better:

@kennyycheng here's the 2 versions of script import sheets we're deciding between if you have any feedback! https://docs.google.com/spreadsheets/d/1J8NPOfGvbyR77u9FRSTH566YiWq8gkTU9jwqR66TgQc/edit#gid=0

@hiemanshu so far we're also in agreement on the 1st example sheet in the linked spreadsheet

kennyycheng commented 1 year ago

This all makes sense to me, and I agree that Example 1 feels clearer and easier to follow (especially given the templates + strong error messaging)!

lediur commented 1 year ago

Maybe a question for choosing Sheets over something else: how would the Sheets plan handle the collaboration story as originally described in the OP? Google Sheets collaboration is cell-based (so only one person can edit one cell at a time) and doesn't do suggestions beyond cell-level comments, so that specific user behavior feels less optimal.

Also, the sheets based flow in Example 1 seems like it would have a substantial amount of duplicate work throughout the script because there is no deduplication of nodes. From that perspective, Example 2 seems somewhat more usable to me even if the initial impression is somewhat more confusing.

I wonder if it makes sense to instead use Google Docs, Notion, etc to export to Markdown. There are tools to export Markdown from Google Docs and a wide variety of formats, and it's human editable enough for more tech-savvy users to edit directly. Google Docs, Notion, etc can address the collaboration issues more specifically, and a simpler markup language like Markdown might help describe this workflow a bit better. It could also lend itself a bit more cleanly to some kind of future node-based editor[1] that's more intuitive for users to interact with.

I do not think that users should interact with the Markdown document directly, unless they specifically need or want to. We should be able to handle this entirely using export and import tools from the editing software into Spoke.

A description of this intermediate Markdown document format might look like:

Happy to produce a formal parsing grammar later if that's helpful for unambiguous implementation.

An example Markdown document (after export) might look like (based on the script sheets example):

# Initial

Hey {campaignVariable}! Will you support Rewired in the upcoming election?

## Will they support Rewired?

- [yes_support_rewired]
- [no_support_rewired]
- [maybe_support_rewired]

# [yes_support_rewired] YES they will support Rewired

Great! Will you volunteer with us?

## Will they volunteer?

- [yes_volunteer]
- [no_volunteer]

# [no_support_rewired] NO they will not support Rewired

Got it, thanks for letting me know! Have a great day!

# [maybe_support_rewired] MAYBE they will support Rewired

Got it! You can read more about us here: {linkVariable}.

Will you volunteer with us?

## Will they volunteer?

- [yes_volunteer]
- [no_volunteer]

# [yes_volunteer] YES they will volunteer

Thank you so much for your support! Have a great day!

# [no_volunteer] NO they will not volunteer

I understand! Have a great day!

This should be equivalent to the example sheet provided above. This is somewhat similar to Example 2, but the links are forward references rather than backreferences as described in Example 2.

Worked examples as they appear in popular editors (Rewired internal)

Google Docs

Notion

Other notes


1 for reference, a node based editor looks something like this

image

ajohn25 commented 1 year ago

@politics-rewired/spoke-client let's review ^ next week! thx for the suggestion @lediur