-
Notifications
You must be signed in to change notification settings - Fork 585
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
Update Import Flow to Match Designs #9891
Conversation
…ks/teachertool/rework_import
…omatically to rubric
…ks/teachertool/rework_import
…the faded background of the modal.
import { CautionLevel } from "../types"; | ||
import css from "./styling/ConfirmationModal.module.scss"; | ||
|
||
export type ConfirmationModalProps = { |
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.
Should this type be somewhere in the types
folder?
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.
It could be. I thought, since it was so closely tied to the component, it made sense to keep here, but I can move it to types.
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 think it should be moved to stay consistent.
|
||
return teacherTool.modal === "confirmation" && teacherTool.confirmationProps ? ( | ||
<Modal | ||
title={teacherTool.confirmationProps.title ?? ""} |
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.
There shouldn't be a case where the title is falsey, right? The title is required in confirmationProps
, so it this check shouldn't result in an empty string since we already check that confirmationProps
is populated above?
|
||
setFileIsOverSurface(false); | ||
|
||
const file = event.dataTransfer.files[0]; |
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 this can be done in a follow-up PR, but I think we need some handling for uploading multiple files. When I dragged in 3 JSON files, it's unclear to me which JSON file is going to get used or even if my other rubric files will get stored or something. If we don't want to support the multiple file scenario, I think just have an error or warning saying that we can only accept one rubric file at a time will helpful.
This will need to be done for the browse scenario as well.
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'm not sure what uploading multiple files would mean in terms of import, so my inclination would be to disallow it and provide an error message, but we can discuss as a team and follow up in a separate change.
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 importing the first file is fine. I'd prefer not to treat this as an error or warning. The fewer alarm states we create, the better. If we can make it "just work", that's good. The user will learn how it behaves through observation.
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 this might just be something we want to cover/ask in user testing. My thoughts are that because we have the modal where we tell the user that importing will override their current rubric, especially with the red coloring, we are putting the user in an alarm state, so I think we should give them the most piece of mind that we possibly can. Personally, when I saw the modal, I didn't even read the rubric title in the top bar because most of my focus was on the button and the details outlining what importing is going to do, so, when I dragged multiple rubrics in, I got nervous not knowing which rubric was going to override my current rubric. In my mind, a "just work" scenario if I drag multiple files in would be that all of my rubrics are now on the site and accessible. I know this isn't what we're going for right now, but I still think it's a valid scenario to consider. For now, I think we can take the first file, but I think we should make an issue for supporting uploading multiple rubrics at once.
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.
On that note, I don't think we should use a red/alarm color for the Continue button. The primary button color should be sufficient.
} | ||
export const DragAndDropFileSurface: React.FC<DragAndDropFileSurfaceProps> = ({ onFileDroppedAsync, errorMessage }) => { | ||
const [fileIsOverSurface, setFileIsOverSurface] = useState(false); | ||
const [errorKey, setErrorKey] = useState(0); // Used to reset animations on the error label. |
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.
Even with the comment here, I'm not sure I understand what errorKey does.
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.
By changing the key of the component, we force react to unmount the component and mount a new one, which resets the animation state. If we don't do this, then the animation only runs on the first error and no subsequent ones, since from the component's perspective, the animation has already run.
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.
Ohh, gotcha. Makes sense, so errorKey could technically be any type, as long as we can make a quick change to it to cause an unmount and mount, and that's why using numbers is convenient?
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.
As long as it's a valid key, then yes (though I think that's really only strings and numbers).
@@ -25,6 +25,7 @@ | |||
--pxt-content-background-glass: #C7D2FE40; | |||
--pxt-content-foreground: #1E293B; | |||
--pxt-content-accent: #EEF2FF; | |||
--pxt-content-secondary-foreground: #666666; |
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.
@eanders-ms I feel like I'm adding colors here kind of ad-hoc and I'm probably already making a mess of things. Did you have any conventions or systems in mind for how these should be organized and named? If not, maybe we could chat and come up with something (reasonably) consistent.
I considered glass/smoke/accent/etc but none of those quite seemed to fit for this one, IMO.
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 needs more design thinking, which will have to happen before we implement this for Arcade. A little bit of mess is fine for now, but I hope we can avoid adding too many ad-hoc values. Use an existing color variable if possible.
teachertool/src/types/index.ts
Outdated
@@ -44,3 +46,11 @@ export type CarouselCardSet = { | |||
}; | |||
|
|||
export type RequestStatus = "init" | "loading" | "error" | "success"; | |||
|
|||
export type ConfirmationModalProps = { |
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.
The inclusion of Props
in the name tells me this configures a React component. Props is uncommon for non-React configuration. I suggest using something else here. Suggestions:
ConfirmationModalOptions
ConfirmationModalParams
|
||
setFileIsOverSurface(false); | ||
|
||
const file = event.dataTransfer.files[0]; |
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 importing the first file is fine. I'd prefer not to treat this as an error or warning. The fewer alarm states we create, the better. If we can make it "just work", that's good. The user will learn how it behaves through observation.
@@ -0,0 +1,5 @@ | |||
.confirmation-modal { | |||
button.caution { | |||
background-color: rgb(255, 71, 71); |
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.
Can this color be derived from the toast error color? I think it will be the same color for all themes, so not a big issue to appear as a literal here. Though high-contrast might be a special case.
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.
} | ||
} | ||
|
||
@media screen and (max-height: 720px) { |
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.
We should be using breakpoints from react-common, not creating our own.
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.
Probably better to just remove this for now. We have an issue on the board tracking the need to implement responsive layout app-wide. Something we can address post v1.
|
||
setRubric(json); | ||
setActiveTab("rubric"); | ||
replaceActiveRubricAsync(json); |
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.
replaceActiveRubricAsync(json); | |
await replaceActiveRubricAsync(json); |
…s can be undefined if json parsing doesn't have the field)
teachertool/src/state/actions.ts
Outdated
@@ -55,6 +55,11 @@ type SetRubric = ActionBase & { | |||
rubric: Rubric; | |||
}; | |||
|
|||
type SetConfirmationProps = ActionBase & { |
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.
Can we change this name (and various related identifiers) to match?
type SetConfirmationProps = ActionBase & { | |
type SetConfirmationOptions = ActionBase & { |
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.
Looks great!
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.
Nice!
This updates our import flow (and confirmation dialog) to match our v1 designs.
I tried reusing https://github.com/microsoft/pxt/blob/master/webapp/src/draganddrop.ts, by moving it into browserutils and adding extra events for when drag enters and exits/leaves, but it didn't quite work out. The enter and exit events caused a lot of flickering when hovering over child elements, which I believe would require a workaround somewhat like the one I've described in the DragAndDropFileSurface in this PR. I wasn't comfortable adding that workaround at such a global scale (and it isn't necessary when you don't care about enter/exit), so I decided not to reuse.
Upload target:
https://makecode.microbit.org/app/5fc5d7fc1489c936a8bdc40422b6a5b3a5926855-6b68fdda25--evalhttps://makecode.microbit.org/app/3743a0ed15ed73ae921ee8bf75533603348b2665-b7ed2b5339--evalScreenshots
Import:
File hover:
Confirm:
Invalid file:
Small screen: