Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

fix: improve handling of merging defaults for popup tiles #519

Merged
merged 5 commits into from
Nov 21, 2020

Conversation

akloeckner
Copy link
Contributor

This will let the user overwrite default popup layouts. And it makes the code more readable.

},
}, getItemFieldValue('history', item, entity))],
const layout = cacheInItem(item, '_popupHistory', () => angular.merge(DEFAULT_POPUP_HISTORY(item, entity), {
classes: getItemFieldValue('history.classes', item, entity) || [],
Copy link
Collaborator

Choose a reason for hiding this comment

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

It doesn't look like angular.merge will merge those array values:

> angular.merge({ a: [1] }, { a: [2] }).a
> [2]

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think https://www.npmjs.com/package/lodash.merge should work. angular.merge is deprecated anyway and they recommend lodash.merge.

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 question for this line might be: What is actually expected? angular.merge will merge by key, which is 1,2,3,... in the case of arrays. So, values in the same place will be overwritten, values in other places will be added. Since both use cases should be possible, I'd say this behavior is reasonable to expect.

Here's a more complete test case:

grafik

If we wanted only add user-defined classes, we could do so like this:

classes: [ , ...(getItemFieldValue('history.classes', item, entity) || [])],

Copy link
Collaborator

Choose a reason for hiding this comment

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

In the case of classes, I think the default behavior should be to append user classes to the ones that are there already because then the user doesn't need the knowledge of internal classes to add something. The [ , ...] also requires knowledge of how many internal classes are already applied and is error-prone in case something changes internally in the future.

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 meant, we could use the [, ...] in main.js. The users should definitely not need to to this themselves.

If we were to use another library, I'll need help to include it in the bundle. Just a hint: The merge of arrays will need to use the current (angular) behavior in a few prominent places, e.g., the main tile in popups (i.e. camera, iframe, history)...

In summary, I suggest to change the classes line(s) in main.js in the [, ...] way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

An additional thought on that is: we have two kinds of places where we would want to merge tile configurations
a) before "evaluation" of functions and templates, prominent example is during config loading.
b) after "evaluation" of functions and templates, prominent example might be the popups.

The a) case could be solved by nesting functions:

classes = newFunction(item) { objA.concat( oldFunction(item) ) }

Question is: Which item is meant in each of the functions? During config loading it will easy, because it can only be the same item. In the case of popups, it's not that easy. The function in the default will probably want to use the item in the popup. The function in the calling item will probably want to use that calling item.

So, I'm under the impression, it might boild down to the point: when do we actually want to evaluate functions and templates?

(Sorry for turning into a philosopher. :-) Maybe I should wait for you to be less ocupied...)

Copy link
Contributor Author

@akloeckner akloeckner Nov 16, 2020

Choose a reason for hiding this comment

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

I updated akloeckner/TileBoard@feature/defaults...akloeckner:test/merge-tiles in a way that I believe should handle all cases well. (It's untested, so treat it as a sketch.)

  • classes will always be concatenated.
  • to that end, everything that is not an array is embedded in an array
  • in order to allow for functions and templates, I wrap everything in another anonymous function and call this.parseFieleValue on both properties to be merged
  • functions and templates are thus evaluated against the same item always
  • unless we explicitly pass differently evaluated properties to the merger, such as in the line of this discussion. So, we are in total control of what is evaluated when and against which item.

Possible downsides:

  • everything is parseFieldValueed. But that should be ok, because non-parseable properties are simply piped through.
  • properties might become parsed multiple times. But that should be ok for the same reason.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Didn't mean to leave you here talking to yourself but I don't have much capacity for it currently.

I guess go ahead with your plan and I'll likely approve after a brief look :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem. I prefer to put down my notes, so you could pick up the line of thought. I'll give it another round of thinking and then go ahead.

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 added this approach to the PR. Would you mind a quick look? ;-)

scripts/globals/constants.js Outdated Show resolved Hide resolved
…ions

Squashed commit of the following:

commit 094ca09
Author: ak-test <akloeckner@users.noreply.github.com>
Date:   Mon Nov 16 19:07:19 2020 +0000

    make sure, no `undefined` ends up in `classes`

commit 2d33f07
Author: ak-test <akloeckner@users.noreply.github.com>
Date:   Mon Nov 16 18:33:10 2020 +0000

    use this.parseFieldValue

commit d74e070
Author: ak-test <akloeckner@users.noreply.github.com>
Date:   Mon Nov 9 23:01:36 2020 +0000

    draft a customized version of angular.merge for tile configurations
@rchl rchl changed the title Feature: defaults for popup fix: improve handling of merging defaults for popup tiles Nov 21, 2020
@rchl rchl merged commit 250ac64 into resoai:master Nov 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants