-
Notifications
You must be signed in to change notification settings - Fork 49
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(interview): Copy dataset [3] #1128
Conversation
cdb35a2
to
1082398
Compare
5c65410
to
498ae19
Compare
1082398
to
40a8e80
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think it looks good, thanks! 🙏
498ae19
to
5ec0b86
Compare
01d9ef8
to
b453485
Compare
Rebased and good to go. |
|
||
if (value.set_prefix == set.set_prefix) { | ||
value.set_index = set.set_index | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MyPyDavid This is complicated, can you check if this is understandable to you. I just fixed a bug here. This front-end part is for copying blocks/questionset (and tabs/pages without attribute).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, yes, I can not make any cheese out of this but the comments help ;).
I've asked a LLM to explain it to me..
You don't want to split it a bit more into functions with meaningful names?
function adjustSetPrefix(value, set, newSetPrefixDepth) {
value.set_prefix = value.set_prefix.split('|').map((segment, idx) => {
return idx === newSetPrefixDepth ? set.set_index : segment;
}).join('|');
return value;
}
export function copySet(currentSet, currentSetValue, attrs) {
const pendingId = `copySet/${currentSet.set_prefix}/${currentSet.set_index}`;
return (dispatch, getState) => {
dispatch(addToPending(pendingId));
dispatch(copySetInit());
const set = createNewSet(attrs); // Encapsulates set creation logic
const value = prepareSetValue(attrs); // Encapsulates value preparation logic
if (isNil(value)) {
handleSetWithoutAttribute(dispatch, getState, pendingId, currentSet, set, finalizeCopySet(dispatch, getState));
} else {
handleSetWithAttribute(dispatch, pendingId, currentSetValue, value, finalizeCopySet(dispatch, getState));
}
};
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I will keep it like it is. Moving dispatch
into functions somehow feels wrong. To me it is actually harder to read with the functions.
set_value_serializer.is_valid(raise_exception=True) | ||
set_value = set_value_serializer.save() | ||
set_value_data = set_value_serializer.data | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the corresponding part in the backend for tabs/pages with an attribute. The problem before was that set_value.set_prefix.split('|')
for ''
and '0'
is both 1
. I hope I fixed it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, wanna handle each value maybe in a separate function inside of the copy_set
method?
def adjust_set_prefix(value, set_value, set_prefix_length):
if value.set_prefix == set_value.set_prefix:
value.set_index = set_value.set_index
else:
value.set_prefix = '|'.join([
str(set_value.set_index) if (index == set_prefix_length) else part
for index, part in enumerate(value.set_prefix.split('|'))
])
return value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, after some thought, I added a compute_set_prefix_from_set_value
function for the else
part. Mainly because I want some parametrized tests for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I think that the current implementation behaves as expected.
I have made only few optional code refactoring remarks.
Somethings about the UX of the tabs of the datasets, they should behave similar to tabs in a browser right?
- on deleting a dataset, it should activate the one to the right first when it's possible
- for UI design, should the delete icon not be inside of the activated tab? (or on all tabs??)
- in the delete modal, it should mention the name/label of the tab that will be deleted
During the interview, when applying to all or making the copy, there are multiple requests to /navigation
and /progress
. Could this maybe be optimized? I think it calls get requests for each dataset that is updated. Don't know if this could be handled somehow in a single request to each endpoint.
|
||
if (value.set_prefix == set.set_prefix) { | ||
value.set_index = set.set_index | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, yes, I can not make any cheese out of this but the comments help ;).
I've asked a LLM to explain it to me..
You don't want to split it a bit more into functions with meaningful names?
function adjustSetPrefix(value, set, newSetPrefixDepth) {
value.set_prefix = value.set_prefix.split('|').map((segment, idx) => {
return idx === newSetPrefixDepth ? set.set_index : segment;
}).join('|');
return value;
}
export function copySet(currentSet, currentSetValue, attrs) {
const pendingId = `copySet/${currentSet.set_prefix}/${currentSet.set_index}`;
return (dispatch, getState) => {
dispatch(addToPending(pendingId));
dispatch(copySetInit());
const set = createNewSet(attrs); // Encapsulates set creation logic
const value = prepareSetValue(attrs); // Encapsulates value preparation logic
if (isNil(value)) {
handleSetWithoutAttribute(dispatch, getState, pendingId, currentSet, set, finalizeCopySet(dispatch, getState));
} else {
handleSetWithAttribute(dispatch, pendingId, currentSetValue, value, finalizeCopySet(dispatch, getState));
}
};
}
rdmo/projects/managers.py
Outdated
|
||
# collect the attributes of all questions of all pages or questionsets | ||
# of this catalog, which have the attribute of this value | ||
attributes = set() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion for this:
attributes = {descendant.attribute for element in (catalog.pages + catalog.questions)
if element.attribute == set_value.attribute
for descendant in element.descendants}
Would be the same right? as a set comprehension
set_value_serializer.is_valid(raise_exception=True) | ||
set_value = set_value_serializer.save() | ||
set_value_data = set_value_serializer.data | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, wanna handle each value maybe in a separate function inside of the copy_set
method?
def adjust_set_prefix(value, set_value, set_prefix_length):
if value.set_prefix == set_value.set_prefix:
value.set_index = set_value.set_index
else:
value.set_prefix = '|'.join([
str(set_value.set_index) if (index == set_prefix_length) else part
for index, part in enumerate(value.set_prefix.split('|'))
])
return value
I would like to keep the icons where they are, I think it would be to crowded to add all the options to all tabs. (Makes more sense for a browser where you open and close tabs all the time.) |
this is also fine with me! 👍 |
The remark with the |
I also added 2 small fixes for the bugs we found in yesterdays meeting. Can you check again and approve? |
ok great, thanks so much! I'll check it today! |
thanks, this looks smooth now! |
Can the range slider also do apply to all? I can't see the icon for it.. And for file uploads, I would guess not right? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
datasets can be copied smoothly now!
🙏 (the slider works, but it needs a value first) |
I broke something else, good that we have tests 😏 |
yes, only for all this new interview stuff the front-end (playwright) tests are still missing! 🚨 😉 |
This PR adds the possibility to copy tabs (i.e. datasets) or better to create a new tab with all values from the current tab. It works a bit like deleting a set. If a
set_value
is present (e.g.project/dataset/id
), the catalog is used to get all values for the current set and copy them, along with a newset_value
. For#
style sets without attributes this is done in the front end. There is some black magic involved when theset_prefix
of values is updated with theset_index
of the new set.