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

Pass table data to template #137

Merged
merged 2 commits into from
Jul 26, 2023
Merged

Pass table data to template #137

merged 2 commits into from
Jul 26, 2023

Conversation

masnax
Copy link
Contributor

@masnax masnax commented Jul 12, 2023

Fixes an issue where artifacts would be shown in the table, and in rare occasions the whole table would be drawn incorrectly.

The issue was that the go-survey package we use for the selectable table does not re-compile the table template, instead pulling them from a map keyed by the string value of the template.

As @markylaing found, there is an interface{} type on MultiSelect that we can abuse to pass in our own data into the template. What this means is we no longer need a method to keep track of the data being passed into the template and template functions, so we can assign the template as soon as possible.

In order to still preserve the ability to pass in pre-checked values into the table, I've added a field on to the new templateData struct, which alongside the apply_defaults template function, allows setting pre-checked rows like before.

@tomponline
Copy link
Member

I've used the request review feature so its pinned to my todo list and doesnt get lost.

Copy link
Contributor

@markylaing markylaing left a comment

Choose a reason for hiding this comment

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

I've noticed that the current multiSelectQuestionTemplate contains %s formatting directives. Then when we update the table, the survey.MultiSelectQuestionTemplate is set via fmt.Sprintf(multiSelectQuestionTemplate). This means that the multiSelectQuestionTemplate isn't actually a valid template.

Is it possible to pass extra data where the template is rendered? Then rather than using %s you can use .border and .header and we won't need to keep resetting the template.

@masnax
Copy link
Contributor Author

masnax commented Jul 13, 2023

I've noticed that the current multiSelectQuestionTemplate contains %s formatting directives. Then when we update the table, the survey.MultiSelectQuestionTemplate is set via fmt.Sprintf(multiSelectQuestionTemplate). This means that the multiSelectQuestionTemplate isn't actually a valid template.

Yes, I suppose this would technically make more sense as a function than a global variable.

Is it possible to pass extra data where the template is rendered? Then rather than using %s you can use .border and .header and we won't need to keep resetting the template.

Unfortunately the template data is set internally, here and its return value is used internally where the table is rendered.

@markylaing
Copy link
Contributor

I've noticed that the current multiSelectQuestionTemplate contains %s formatting directives. Then when we update the table, the survey.MultiSelectQuestionTemplate is set via fmt.Sprintf(multiSelectQuestionTemplate). This means that the multiSelectQuestionTemplate isn't actually a valid template.

Yes, I suppose this would technically make more sense as a function than a global variable.

Is it possible to pass extra data where the template is rendered? Then rather than using %s you can use .border and .header and we won't need to keep resetting the template.

Unfortunately the template data is set internally, here and its return value is used internally where the table is rendered.

I find it a little bizarre that it is allowed to set the template but there is no easy/obvious way to set additional template data. I have managed to pass some extra data in via the default selection field though main...markylaing:microcloud:table-template

@markylaing
Copy link
Contributor

I find it a little bizarre that it is allowed to set the template but there is no easy/obvious way to set additional template data. I have managed to pass some extra data in via the default selection field though main...markylaing:microcloud:table-template

Of course this won't work if we actually want to set any defaults. Maybe we can submit an issue upstream for this.

Rather than relying on a method on the table to pass the list of all
entries to the template funcs, just pass it in from the template.

Signed-off-by: Max Asnaashari <max.asnaashari@canonical.com>
@masnax
Copy link
Contributor Author

masnax commented Jul 13, 2023

I find it a little bizarre that it is allowed to set the template but there is no easy/obvious way to set additional template data. I have managed to pass some extra data in via the default selection field though main...markylaing:microcloud:table-template

Of course this won't work if we actually want to set any defaults. Maybe we can submit an issue upstream for this.

Actually, by making the map a map[string]any, we can maintain the current functionality of the Default field by just adding a new template function.

I ended up using this approach, but with a struct to clearly represent the 3 fields that are passed into the template. So this fully eliminates any need to reassign the template, and we don't need a global table anymore! Yay!

I'll open an issue asking for a cleaner way to pass in data to the template though.

@masnax masnax changed the title Keep selectable table as global variable Pass table data to template Jul 13, 2023
@masnax masnax requested a review from markylaing July 13, 2023 20:28
@markylaing
Copy link
Contributor

I think perhaps the second and third commits could be combined into one? Only because the border and header values are passed into the template one way, then it is immediately changed in the following commit.

Apart from that, I think it's good to go.

Default is an interface{} so we can abuse this to pass the border and
header strings into the template without having to regenerate it.

Since we are co-opting the `Default` field to pass in template data,
this commit adds a new template function which effectively runs the
the functionality defined here:

https://github.com/go-survey/survey/blob/fa37277e6394c29db7bcc94062cb30cd7785a126/multiselect.go#L235-L257

but on the `DefaultRows` field of the templateData.

Signed-off-by: Max Asnaashari <max.asnaashari@canonical.com>
@masnax
Copy link
Contributor Author

masnax commented Jul 21, 2023

@markylaing As you said you were happy with this, I'll dismiss your earlier review and merge.

@masnax masnax dismissed markylaing’s stale review July 21, 2023 00:04

Concerns were addressed, an issue will be created in the upstream project

@masnax
Copy link
Contributor Author

masnax commented Jul 21, 2023

Ah, still can't merge without a review :)

Copy link
Contributor

@markylaing markylaing left a comment

Choose a reason for hiding this comment

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

Looks good. Can you post a link to the issue so we can follow it? Thanks.

@masnax
Copy link
Contributor Author

masnax commented Jul 26, 2023

AlecAivazis/survey#491

@masnax masnax merged commit e0cd4c7 into canonical:main Jul 26, 2023
8 checks passed
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.

None yet

3 participants