-
Notifications
You must be signed in to change notification settings - Fork 1
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
22 #30
base: master
Are you sure you want to change the base?
22 #30
Conversation
9408176
to
4034463
Compare
4034463
to
e54cc54
Compare
src/components/entity-label.ts
Outdated
// handled by the parent | ||
if (this._fontWeight) { | ||
super.setFontWeight('bold'); | ||
} |
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.
feels like there may be a better way of changing label's font style and having the label background update.
most of the questions for any label type components are essentially based on how to inherit or derive from the base LabelComponent.
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 could probably add an on('frame')
event handler for the label component that checks if clipping/resizing is needed on every frame.. then text properties could be updated naturally without having to worry about ensuring that the clipping and sizing are updated explicitly. (Or every N frames if the logic is too expensive, but it looks cheap to me at the moment).
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.
setting all text properties in a LabelTextComponent first. the label background draws afterwards without having to update
} | ||
|
||
// TODO: maxWidth and clip is reused from the generic label component. is there a better way to share these? | ||
/** |
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.
would it be better to extend this component from the LabelComponent? the label style is fairly different and it doesn't need the label background at all
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 would be nice to share this logic in one way or another. if this component doesn't need most of what the label component offers, it might be good to break out an even more abstract component for just the text clipping piece, that can be extended by boht.
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.
new LabelTextComponent handles text styling and clipping
src/components/label.ts
Outdated
this._label.fontWeight = weight; | ||
this.clip(); | ||
this._background.bounds.width = this._label.bounds.width + (LABEL_HORIZONTAL_PADDING * 2); | ||
} |
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.
would it be better to make this more generic and pass in a configuration object? ex. setFontStyle({ weight: 'bold' })
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.
if we keep it like this, then yeah probably so. I'm thinking the frame event handler is probably the way to go here, though
// vms and vnics list | ||
this.vms = new VmAndVnicListComponent( | ||
this._vapp.vms, | ||
this.vappNetworks && this.vappNetworks.networkPositionsByName, |
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.
passing 'networkPositionsByName' derived from vappNetworks component here. is there a better way or naming convention to use? more documentation? // networkPositionsByName have x position data for matching vnics
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 was clear to me but might be helpful to be more explicit about the fact that it's the X position. maybe networkXPositionsByName
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.
since it's clear, i'll leave it as is. there's a possibility that positions might need to be converted (local, global, parent, child) later on, so i'll keep full position data
|
||
// finish VappNetworks - draw the top external segment and internal segment based on matching vnic positions | ||
if (vappNetworkCount) { | ||
this.vappNetworks.setTopAndBottomSegments(this.vms.lowestVnicPointByNetworkName); |
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.
passing 'lowestVnicPointByNetworkName' derived from vmsAndVnicList component here. is there a better way or naming convention to use? more documentation? // lowestVnicPointByNetworkName contains the lowest point data for matching vapp networks
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.
made sense to me, so I think it's OK
* Virtual Application Visual Component. | ||
*/ | ||
export class VappComponent extends paper.Group { | ||
|
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 major parent component that encapsulates everything else and handles most of the interdependent and shared data
src/components/vm-and-vnic-list.ts
Outdated
// reusable calculations | ||
const vappNetworkCount = Object.keys(this.vappNetworkPositionsByName).length; | ||
this.lastNetworkPositionX = vappNetworkCount && (vappNetworkCount - 1) * VAPP_NETWORK_RIGHT_MARGIN | ||
+ CONNECTOR_RADIUS - DEFAULT_STROKE_WIDTH; |
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.
could also loop through vappNetworkPositionsByName from line 36 to find max position instead of calculating it like this. does it matter?
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.
actually, there's an even simpler way of getting it from the bounds of the VappNetworkListComponent from the main VappComponent.
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, probably better to get it that way vs. having this calculation that is dependent on other, previous calulations
this._vapp.vapp_networks, | ||
new paper.Point(VAPP_PADDING + CONNECTOR_RADIUS, 0)); | ||
this.addChild(this.vappNetworks); | ||
} |
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.
max (furthest right) vapp network position can be derived from this component's bounds to pass to the vmAndVnicListComponent
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.
nevermind, edge labels can throw the width off
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.
simplifying even more by using the value straight from the vappNetworkList.lastNetworkPosition
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 finished an initial review but I need to come back and look at a few things more closely when I have time. Nice job, looking good so far!
); | ||
if (scrollbar.isEnabled) { | ||
canvas.onmouseenter = scrollbar.containerMouseEnter; |
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 don't like this pattern where you're requiring the parent component to bind the event handlers. That should be internal to the scrollbar at the time it is created. I suggest creating a wrapper for the canvas that you're rendering to which exposes Observables that are bound to those event handlers so that any component can easily subscribe to them.
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.
event handlers are internal to the scrollbar now
|
||
const content = new paper.Group({ applyMatrix: false }); | ||
// create origin paper Item for vapps to base position from | ||
const origin = new paper.Path.Circle({ |
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.
what is this about?
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.
VApps base their x position on the last child of the content
group (line 44 - content.lastChild.bounds.right). Most vApps will have the previous vApp to refer to, but the very first one won't. The origin
was created to be the first vApp's reference point. One way it could also be avoided is by doing a check in the loop at line 43:
vapps.forEach((vappData, index) => {
const position = new paper.Point(index === 0 ? 'explicit number' : content.lastChild.bounds.right), VERTICAL_POSITION);
...
}
src/components/scrollbar.ts
Outdated
/** | ||
* Gets isEnabled state. The scrollbar is enabled when content does not fit the container. | ||
*/ | ||
get isEnabled(): boolean { |
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.
typically a boolean field on a class (or a property accessor, like you have here) would just be named enabled
. Names like isEnabled
are usually used for getter methods
@@ -1,4 +1,7 @@ | |||
/* You can add global styles to this file, and also import other style files */ | |||
|
|||
@import (css) url('https://fonts.googleapis.com/css?family=Roboto:400,500,700&display=swap'); |
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.
where are we at with this? did you end up handling the issues that we talked about, where the font loads too slow and calculation of component positioning is based upon the wrong font sizes? Perfectly fine if that's still a TODO, I'm just curious
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.
yes. still a TODO right now. The delayed font loading seems to affect the label background sizes for the most part and could be solved with the onFrame solution suggested earlier. Another option I was thinking of looking into was using the Angular lifecycle methods to wait for the font to load completely before rendering the canvas. Or have an observable/promise that waits for the font to load, and then redraw. There are a few other font loading techniques too that I haven't dug into yet.
src/components/connector.test.ts
Outdated
import { VAPP_BACKGROUND_COLOR, CANVAS_BACKGROUND_COLOR } from '../constants/colors'; | ||
import * as paper from 'paper'; | ||
|
||
describe('connector component', () => { |
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!
src/components/vapp-network-list.ts
Outdated
* Clones the bottom segment of vapp networks to separate for scrolling and removes the original segment. | ||
* @param splitPositionY vertical point where the network path should be split for cloning and separation | ||
*/ | ||
cloneVmListSegments(splitPositionY: number) { |
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.
missing return type
// vms and vnics list | ||
this.vms = new VmAndVnicListComponent( | ||
this._vapp.vms, | ||
this.vappNetworks && this.vappNetworks.networkPositionsByName, |
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 was clear to me but might be helpful to be more explicit about the fact that it's the X position. maybe networkXPositionsByName
|
||
// finish VappNetworks - draw the top external segment and internal segment based on matching vnic positions | ||
if (vappNetworkCount) { | ||
this.vappNetworks.setTopAndBottomSegments(this.vms.lowestVnicPointByNetworkName); |
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.
made sense to me, so I think it's OK
src/components/vapp.ts
Outdated
*/ | ||
// TODO: add scroll listener with a better method. it's in parent demo component for now. could create a native canvas | ||
// event observable service similar to the paper.event service? | ||
setScrollListening(event: WheelEvent) { |
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 we definitely need to do something different for these event bindings, this is going to get out of hand like this
src/components/vm-and-vnic-list.ts
Outdated
// reusable calculations | ||
const vappNetworkCount = Object.keys(this.vappNetworkPositionsByName).length; | ||
this.lastNetworkPositionX = vappNetworkCount && (vappNetworkCount - 1) * VAPP_NETWORK_RIGHT_MARGIN | ||
+ CONNECTOR_RADIUS - DEFAULT_STROKE_WIDTH; |
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, probably better to get it that way vs. having this calculation that is dependent on other, previous calulations
* Clips and adds scrolling to the VmAndVnicList component when it's too large for the view. | ||
*/ | ||
private clipAndScrollVmList() { | ||
// create drop shadow at the top of the vm list that fades in or out onScroll |
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.
add return type
return expectedVnicPoints; | ||
} | ||
|
||
test.only('basic properties and vnics on different networks', () => { |
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.
remove only
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.
from all the tests
@mathieupkf - Could you also review the visuals? Netlify Demo The request to display scrollbars only on scroll area hover has also been implemented. There's a lot going on for visibility and opacity with the scrollbar system. Trying to add the 1s delay/fade in with all of that made the visuals very buggy unfortunately. The extra edge cases that aren't explicitly in the InVision designs are for a visual check on some of the layout logic. Let me know if the different vApp cases could be arranged better too. Thanks! |
@SuperConfuserUser - thanks Chely. |
@mathieupkf - a few updated scrollbar demos ready. 2 or 3 would be my personal pick. The more subtle drop shadow would be a nice touch to show the fold. Can do more variations as well if you have more ideas. |
Thanks @SuperConfuserUser ! |
@mathieupkf - Thanks for the review! The scrollbar dragging bug is fixed in this demo. We can definitely explore more scrollbar improvements when the project picks back up. |
network_name: '', | ||
is_connected: false | ||
network_name: 'A', | ||
is_connected: true | ||
}, |
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.
testing a case for when connected and disconnected vnics are out of order
|
||
// draw vms and their vnics | ||
this._vms.forEach((vmData, index) => { | ||
const pointY = (LABEL_HEIGHT + VM_MARGIN_VERTICAL) * index; | ||
const sharedPointY = (LABEL_HEIGHT + VM_MARGIN_VERTICAL) * index; | ||
let xPositionMultiplier = hasVappNetworks ? 1 : 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.
this would also work as let xPositionMultiplier = hasVappNetworks
since it's a boolean, but i wanted to be super explicit about where values come from
Added static designs for the vApp visual component.
Netlify Demo