Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(surveys): adds targeting changes to the survey revision history #23834

Merged
merged 28 commits into from
Jul 19, 2024

Conversation

dmarticus
Copy link
Contributor

@dmarticus dmarticus commented Jul 18, 2024

Closes #23725

A few interesting things that I did (things worth looking at in greater depth IMO)

  • Modified surveys.py to handle manually inserting changelog entries whenever we make changes to the survey targeting (this has to be done manually because the existing changes_between abstraction only supports calculating changes within an existing model, and doesn't support foreign key relationships. I wrote a test for this new behavior.
  • Put way too much work into surveyActivityDescriber to handle displaying changes to survey components in a easy-to-digest way. Outside of just writing a lot of code, these changes included:
    • introduced ts-pattern to do structured pattern matching of tuples so that I didn't have to write infinite chains of conditionals when pattern matching changes to question types. This dependency is quite small, and I think the developer ergonomics of introducing structural pattern matching to our codebase outweigh the slightly bigger bundle.
    • a bunch of unit tests for the various different display functions in this method, so it's easier to change it as we continue to go along.
  • Added support for parsing FeatureFlag models in activity_log
  • Added error handling to the changes_between method to prevent it from failing when it tried to look up objects that didn't exist. That's by design!

Changes

Feel free to pull this to your local branch and add some targeting behavior yourself, here's what my survey history looks like after a bunch of manual testing

2024-07-18 12 49 47

Does this work well for both Cloud and self-hosted?

Yes

How did you test this code?

  • manual tests for UI
  • unit tests for the server-side stuff
  • unit tests for the various information-distilling sub-methods in surveyActivityDescriber

@@ -260,6 +260,22 @@ export function flagActivityDescriber(logItem: ActivityLogItem, asNotification?:
return { description: null }
}

if (logItem.activity === 'created') {
Copy link
Contributor Author

@dmarticus dmarticus Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive by fix – I noticed that we never actually visualize (but we do log) creation events in the feature flag history! Here's what it look like now

image

Comment on lines +126 to +133
updated <strong>{questionChanges.length}</strong> question{questionChanges.length !== 1 ? 's' : ''}:
<ul className="bullet-list">
{questionChanges.map(({ index, changes }) => (
<li key={index}>
Question {index}:
<ul className="bullet-list">
{changes.map((changeItem, changeIndex) => (
<li key={changeIndex}>{changeItem}</li>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this gives us a UI like this, which I'm pretty happy with (although the "Question 1" bit seems bit clunky, I just wanted to let them know which question was actually changed!)

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it :)


// Use JSON.stringify for deep comparison of objects
if (JSON.stringify(beforeConditions?.events) !== JSON.stringify(afterConditions?.events)) {
changes.push(<>modified event conditions</>)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elected to not go into details about the event condition changes, just letting users know that they were changed at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reasonable for now 👍

]
: []

const specificChanges = match([before, after] as const)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some cool shit in here with ts-pattern that lets me match a tuple of types with a very nice combinator-style developer experience.

return [...commonChanges, ...typeChangeDescription, ...specificChanges, ...describeBranchingChanges(before, after)]
}

export function describeCommonChanges(before: SurveyQuestion, after: SurveyQuestion): JSX.Element[] {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have functions that are comparing outcomes conditionally, but now that they can be flattened by the .with() combinator, this whole chunk of code gets easier to read.

@dmarticus dmarticus requested a review from a team July 18, 2024 21:53
@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

1 snapshot changes in total. 0 added, 1 modified, 0 deleted:

  • chromium: 0 added, 1 modified, 0 deleted (diff for shard 1)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

Copy link
Contributor

github-actions bot commented Jul 18, 2024

Size Change: 0 B

Total Size: 1.07 MB

ℹ️ View Unchanged
Filename Size
frontend/dist/toolbar.js 1.07 MB

compressed-size-action

expect(getTextContent(changes[0])).toBe(
'changed question text from "What is your favorite color?" to "What is your favorite animal?"'
)
expect(getTextContent(changes[1])).toBe('updated description')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not also include the before/after description, like with the question change above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overlooked it; great feedback. Will add.

expect(changes).toHaveLength(3)
expect(getTextContent(changes[0])).toBe('changed rating display from emoji to number')
expect(getTextContent(changes[1])).toBe('changed rating scale from 5 to 10')
expect(getTextContent(changes[2])).toBe('updated rating labels from Poor-Excellent to Bad-Good')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multi-word labels will be rendered like this ...from Very bad-Very good to Quite bad-Quite good

I'd suggest double quotes here: ...from "Very bad"-"Very good" to "Quite bad"-"Quite good"

Comment on lines 60 to 63
if (value.length <= 50) {
return <strong>"{value}"</strong>
}
return <strong>"{value.slice(0, 50)}..."</strong>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you can use this handy utility function

export function truncate(str: string, maxLength: number): string {

Copy link
Contributor

@jurajmajerik jurajmajerik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fantastic work 🙌 a few minor comments

@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

2 snapshot changes in total. 0 added, 2 modified, 0 deleted:

  • chromium: 0 added, 2 modified, 0 deleted (diff for shard 1)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

1 snapshot changes in total. 0 added, 1 modified, 0 deleted:

  • chromium: 0 added, 1 modified, 0 deleted (diff for shard 1)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

@dmarticus dmarticus enabled auto-merge (squash) July 19, 2024 19:41
@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

1 snapshot changes in total. 0 added, 1 modified, 0 deleted:

  • chromium: 0 added, 1 modified, 0 deleted (diff for shard 1)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

2 snapshot changes in total. 0 added, 2 modified, 0 deleted:

Triggered by this commit.

👉 Review this PR's diff of snapshots.

@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

2 snapshot changes in total. 0 added, 2 modified, 0 deleted:

Triggered by this commit.

👉 Review this PR's diff of snapshots.

@dmarticus dmarticus merged commit f2575a0 into master Jul 19, 2024
89 of 90 checks passed
@dmarticus dmarticus deleted the feat/add-targeting-to-survey-history branch July 19, 2024 22:39
@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

1 snapshot changes in total. 0 added, 1 modified, 0 deleted:

  • chromium: 0 added, 1 modified, 0 deleted (wasn't pushed!)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

skoob13 pushed a commit that referenced this pull request Jul 22, 2024
…23834)

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
silentninja pushed a commit to silentninja/posthog that referenced this pull request Aug 8, 2024
…ostHog#23834)

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support survey targeting revision history
3 participants