-
Notifications
You must be signed in to change notification settings - Fork 71
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
Dashboard fixes and refactors #3614
Conversation
- takes up space in the DOM, easier to style - horizontally centered - uses single config object for spin.js params - default aria attributes
- fetchDataOrError accepts data option that can be either formData or json data - fetchDataOrError returns response data, if any, on error, and provides access to response object
body { height: 100% } causes event.pageX and event.pageY not to work, because body scrolls rather than window scrolling
- show spinner instead of unstyled text while loading - show "No folder selected" instead of empty div when no folder selected
- captureGUID and captureErrorMessage as props instead of global state - CreateLink uses fetch wrapper
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## develop #3614 +/- ##
===========================================
+ Coverage 69.19% 69.25% +0.05%
===========================================
Files 53 54 +1
Lines 7193 7207 +14
===========================================
+ Hits 4977 4991 +14
Misses 2216 2216 ☔ View full report in Codecov by Sentry. |
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.
Whew! This is a lot. I gave it all a read-through, but did not pull down to test. I had one question about something possibly missed during refactoring, and then just made a couple remarks. Since this is behind the feature flag, let's QA in stage 🙂
Thanks for taking on this project!
for (const [key, { value }] of Object.entries(formData.value)) { | ||
formDataObj.append(key, value); | ||
formDataObj.append('file', file.value); | ||
if (!props.captureGUID) { |
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.
Just noting that the non-Vue version of this form actually doesn't do the patch
version of this: it always makes a new Perma Link.
So, we'll have to see if no title/description/url, ends up being what users want here. Could end up that they prefer the current behavior.
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.
Yeah huh, I didn't actually trigger that version in my testing, just did captures of invalid domains. How does one show 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.
I think the quickest way is, you could throw a 1/0
or raise HaltCaptureException
someplace in https://github.com/harvard-lil/perma/blob/develop/perma_web/perma/celery_tasks.py#L312, to make a failed capture.
if (error) { | ||
console.log(error, response) | ||
if (data) { | ||
errors.value = 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.
Does this want to be globalErrors.value
, like below, too?
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.
Theoretically no -- the idea here is the API would return 400
with data {title: "Terrible title"}
and it would render the same way as the validation
section previously in the function. Again I'm not sure what states would trigger that to test, though.
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 appears to give us a sticky footer without breaking anything. | ||
// But I'm not sure about 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.
LOL I love this comment.
onMounted(() => { | ||
globalStore.components.createLink = getCurrentInstance().exposed |
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 haven't seen this pattern before. Is it a way to let components communicate with each other?
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.
Yeah I made this one up, but the thought process was ...
- Vue components have this nice way to encapsulate inputs and outs --
defineProps
shows you what settings the parent component can set and two-way data bindings, anddefineExpose
shows you what methods the parent can poke. (globalState pokes holes in that whole encapsulation, so we always use that by way of a necessary or convenient evil.) - So for the direct parent, communication is easy -- you embed
<Child ref=child props...>
, and usechild.method()
to poke child. - Oh but then it turns out some extended relative needs to poke child sometimes too. So parent will store it as
globalState.childRef
and the relative can doglobalState.childRef.method()
. Alternatively we can have relative update a globalState variable and child watch it, which gets encapsulated in "event bus" libraries -- but if we're only going to have one instance of Child, that feels like unnecessarily poking holes in Child's defineProps/defineExpose interface. - Then after repeating this a few times, we have globalState.childRef and globalState.kidInstance and globalState.widget and it starts to feel messy, so what if we tidy them all up under a globalState.components dictionary and have the children register themselves instead of making their parents do it?
I think all of this makes sense and ends up flowing pretty naturally, except that it's not really proper for the children to register themselves, because the parents are the ones in a position to know how many instances there are. So it'd probably be better to do const childRef = ref(); globalState.components.child = childRef
in the parent. I can switch to that if you think it's worth updating.
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 would also have the virtue that globalState.components.child = childRef
is easier to read than globalStore.components.me = getCurrentInstance().exposed
)
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.
Interesting! Thanks for taking the time to walk me through it. It does seem like a tidy alternative to "we can have relative update a globalState variable and child watch it", if maybe a bit idiosyncratic? But no objections here! No opinion on switching things so the parent registers the child/children or not; I think I understand your argument that having the parent do it is more correct; I could believe this way is easier read, if it's not spread across files, maybe?
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.
globalState.components.child = childRef
does look MUCH less fancy than globalStore.components.me = getCurrentInstance().exposed
🙂
Changes made while responding to Becky's QA with developer-playground = true:
New upload modal implemented.
Fixed up status messages for folders:
If using keyboard, focus stays on caret button when opening/closing. If using mouse to click the rest of the row, focus goes to first input box on open, and does nothing on close.
Fixed.
Other changes in this PR:
I did my best to break these all out into separate commits, but probably mis-organized a line or two.