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

Add settings panel #62

Merged
merged 19 commits into from
Apr 16, 2020
Merged

Add settings panel #62

merged 19 commits into from
Apr 16, 2020

Conversation

larkox
Copy link
Contributor

@larkox larkox commented Mar 18, 2020

Summary

Created an implementation for the settings panel which use post messages with slack attachments. This setting panel should be reusable for other projects.

Ticket Link

Fixes #61

@larkox larkox added the 1: PM Review Requires review by a product manager label Mar 18, 2020
@larkox
Copy link
Contributor Author

larkox commented Mar 18, 2020

Current implementation look like this:
image

Also allow disabling some settings based on the status of others:
image

@aaronrothschild
Copy link
Contributor

Hmmm. Is there a way to indicate via the interactive buttons what is currently set? (ie: an active border around "Yes")

@asaadmahmood any ideas on how to best articulate to the user what is currently set already?

Current implementation look like this:
image

I'm thinking of changing the verbiage on current status to:

  • "Currently, I will send you an update before updating your status" or
  • "Currently, I will not send you an update before updating your status"

@asaadmahmood Should we use "I" to refer to the CalendarBot itself?

Also allow disabling some settings based on the status of others:
image

@larkox
Copy link
Contributor Author

larkox commented Mar 18, 2020

If we were to wait for this PR we would be able to apply some color to the one selected. Not sure if it is the best way to show it.

@asaadmahmood
Copy link

I didn't get this, what is "I"?
"Should we use "I" to refer to the CalendarBot itself?"

For the second one, I'd suggest:
Do you want to update your status to DND in Mattermost when you are in a meeting?
Yes No

I'm guessing the user only sees this one, not again and again, because if he has selected either yes or no, that's his setting, and he can change it when he wants, rather than seeing that message popup time and time again.

So it makes sense not to focus on what the setting is right now i.e. Currently, and just ask him what he wants to do.

@larkox
Copy link
Contributor Author

larkox commented Mar 19, 2020

@asaadmahmood with "I" Aaron refers to "I" as in "I, me, myself" or "I, you, he".

The idea of this is to work as a "panel". It will be always present there until it is somehow closed (in the current implementation, it is only when we disconnect, or write /settings again). It would be a similar idea to go to the system settings, and change settings there.

@asaadmahmood
Copy link

Got it. Yeah I think we can use "I" to get a more personal feel.
This post wouldn't be used much. Once I press yes or no, after a while, it may even scroll above, and I may need to access my settings from elsewhere to reconfigure the status settings.

@larkox
Copy link
Contributor Author

larkox commented Mar 19, 2020

You are right. The post will be seldom reused, and we will have to write /mscalendar settings every time we want to change a setting, since the post will scroll above, but I kind of like the idea of persistent panel. That way, you also are able to better see dependency between settings.
Finally, knowing the current state is important, since you are not changing here one single setting. You are taking a look at all the settings, and changing the one you want.

Copy link
Contributor

@aaronrothschild aaronrothschild left a comment

Choose a reason for hiding this comment

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

LGTM

@aaronrothschild aaronrothschild removed the 1: PM Review Requires review by a product manager label Mar 20, 2020
@larkox larkox added the 2: Dev Review Requires review by a core committer label Mar 20, 2020
@larkox larkox requested a review from levb March 20, 2020 17:42
levb
levb previously approved these changes Mar 24, 2020
"github.com/mattermost/mattermost-server/v5/model"
)

type sh struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

1/5 s/sh/handler/

DeletePost(postID string) error

// DMUpdatePost substitute one post with another
DMUpdatePost(post *model.Post) error
Copy link
Contributor

Choose a reason for hiding this comment

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

s/DMUpdatePost/UpdatePost/ ??

@levb
Copy link
Contributor

levb commented Mar 24, 2020

Nice stuff! I think it'll need to mature and get simplified a bit, but I want to use it, now!

@larkox larkox dismissed stale reviews from levb and aaronrothschild via c394d60 March 24, 2020 16:08
mickmister
mickmister previously approved these changes Mar 24, 2020
Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Great separation of concerns. I really like the generic implementation in the utils/settingspanel package. LGTM 👍

GetConfirmationSettingID = "get_confirmation"
)

func (s *pluginStore) SetSetting(userID, settingID string, value interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

value interface{} Great, I see this can support strings as well 👍

@larkox larkox added 3: QA Review Requires review by a QA tester and removed 2: Dev Review Requires review by a core committer labels Mar 24, 2020
@codecov-io
Copy link

codecov-io commented Mar 26, 2020

Codecov Report

Merging #62 into master will decrease coverage by 2.35%.
The diff coverage is 0.98%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #62      +/-   ##
==========================================
- Coverage   26.20%   23.85%   -2.36%     
==========================================
  Files          57       60       +3     
  Lines        2015     2218     +203     
==========================================
+ Hits          528      529       +1     
- Misses       1432     1634     +202     
  Partials       55       55              
Impacted Files Coverage Δ
server/command/command.go 33.33% <0.00%> (-0.96%) ⬇️
server/command/settings.go 0.00% <0.00%> (ø)
server/mscalendar/mscalendar.go 100.00% <ø> (ø)
server/mscalendar/settings.go 0.00% <0.00%> (ø)
server/mscalendar/settings_daily_summary.go 0.00% <0.00%> (ø)
server/command/disconnect.go 100.00% <100.00%> (ø)
server/mscalendar/notification.go 47.26% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 20e7195...207f876. Read the comment docs.

mickmister
mickmister previously approved these changes Mar 27, 2020
@larkox larkox requested a review from mickmister April 2, 2020 12:12
@mickmister mickmister added the 2: Dev Review Requires review by a core committer label Apr 2, 2020
levb
levb previously approved these changes Apr 8, 2020
Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Great job @larkox! I have a few questions and requests since last review

server/utils/settingspanel/empty_setting.go Outdated Show resolved Hide resolved
server/store/setting_store.go Outdated Show resolved Hide resolved
server/utils/settingspanel/handler.go Outdated Show resolved Hide resolved
server/utils/settingspanel/read_only_setting.go Outdated Show resolved Hide resolved
server/mscalendar/settings_daily_summary.go Outdated Show resolved Hide resolved
server/plugin/plugin.go Outdated Show resolved Hide resolved

actions = []*model.PostAction{&actionOptionsH, &actionOptionsM, &actionOptionsAPM}

if currentTextValue != "Not set" {
Copy link
Contributor

Choose a reason for hiding this comment

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

currentTextValue is initialized as Not set. but is being compared to Not set here.

server/store/setting_store.go Outdated Show resolved Hide resolved
Comment on lines 88 to 108
stringValue := value.(string)
splittedValue := strings.Split(stringValue, " ")
timezone := strings.Join(splittedValue[1:], " ")

found := false
for _, dsum := range dsumIndex {
if dsum.MattermostUserID == userID {
stringValue := value.(string)
if stringValue == "true" {
found = true

if splittedValue[0] == "true" {
dsum.Enable = true
break
}

if stringValue == "false" {
if splittedValue[0] == "false" {
dsum.Enable = false
break
}

dsum.PostTime = value.(string)
dsum.PostTime = splittedValue[0]
dsum.Timezone = timezone
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems pretty hacky to me. What is the reason for needing to accept interface{} here?

Maybe make a struct to pass in here instead of doing string parsing. We can still accept interface{}, but assert it to be what we expect it to be. This way, the caller can be more specific with what it's passing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are many considerations here to do it this way.

First of all, this function is called (with a few steps) by the handler, which is agnostic.
The handler passes the context in case of buttons, the option in case of selects. Since this is a select in general, we should receive a string, which is the only value an option can have, and then parse it.

Regarding receiving interface instead of string, is just to make the type conversions where it makes sense, which is here. Otherwise, we would have to make the conversions in the case block on the switch on SetSetting.

We could put all the parsing in one function that returns this struct you are talking about, but I am not sure whether it would improve the readibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

What happens when this value gets more complicated, or we have a more complicated value we have to handle similarly? Is there anyway the origin of the data can tell this function "this is the post time", or "this is the enable flag"? For example, if this store value had more than one boolean, this would not work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could codify the option content as a JSON string. What do you think?

}
}

return "Daily summary not set", nil
err = s.SaveDailySummaryIndex(dsumIndex)
Copy link
Contributor

Choose a reason for hiding this comment

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

StoreDailySummaryUserSettings is available so you don't need to access the index directly

Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Thanks for addressing the feedback @larkox! LGTM after a few more questions/comments are resolved

currentValueMessage := "Disabled"

actions := []*model.PostAction{}
if !disabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

This !disabled block is pretty long, leading up to just about the end of the function. Do you think we can instead have a short if disabled block that returns early on?

if dsum != nil {
timezone = dsum.Timezone
} else {
timezone = "UTC"
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what benefit the user gets in setting their settings with the wrong timezone. 1/5 Instead of falling back on UTC, return an error here saying that we couldn't get their timezone from Microsoft.


actions = []*model.PostAction{&actionOptionsH, &actionOptionsM, &actionOptionsAPM}

buttonText := "Enable"
Copy link
Contributor

Choose a reason for hiding this comment

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

What purpose did the if currentTextValue == "Not set." block serve that is no longer necessary? Just want to understand the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea was not to show the Enable button before a Daily Summary was set, but I thought that it would make sense to allow the enable with the default value.

@larkox larkox requested a review from mickmister April 13, 2020 13:45
Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Awesome! LGTM 👍

@levb levb added 1: PM Review Requires review by a product manager and removed 2: Dev Review Requires review by a core committer labels Apr 13, 2020
@levb levb added this to the 0.1.0 milestone Apr 13, 2020
@aaronrothschild aaronrothschild removed the 1: PM Review Requires review by a product manager label Apr 13, 2020
@aaronrothschild
Copy link
Contributor

LGTM

@mickmister
Copy link
Contributor

/update-branch

Copy link

@DHaussermann DHaussermann left a comment

Choose a reason for hiding this comment

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

Spoke with @mickmister We want to merge this now to be verified in master. This will aid in making other PRs more testable.

@DHaussermann DHaussermann removed the 3: QA Review Requires review by a QA tester label Apr 16, 2020
@mickmister mickmister merged commit 396a032 into mattermost:master Apr 16, 2020
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.

Settings panel
9 participants