Skip to content
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

Features/cgu/24.2/isd #984

Draft
wants to merge 31 commits into
base: releases/24.2
Choose a base branch
from
Draft

Conversation

cguglielmo
Copy link
Member

No description provided.

@cguglielmo cguglielmo marked this pull request as draft April 25, 2024 10:38
@cguglielmo cguglielmo force-pushed the features/cgu/24.2/isd branch 2 times, most recently from aeb7ec7 to e0acb81 Compare May 14, 2024 12:54
cguglielmo and others added 13 commits May 20, 2024 22:46
Also, don't fail if there is no parent, because tiles may be created
without one (e.g. by hybrid manager for a scout js tile grid)
Focus manager calls preventDefault() if user presses mouse down on a
non-focusable element to ensure the currently active element does not
lose focus. Unfortunately, this also prevents the dragstart event which
 is needed if a widget requires drag & drop support.
The method already works correctly.
The new early === check may be a tiny bit faster.
The other changes are just code style related.
FormFieldMenu uses the ColumnLayout which makes the widgets as width
as they prefer to be. This means the size may change if an error status
appears or the label changes so the parent needs to be invalidated.
This does currently not happen because HtmlComponent.isValidatorRoot()
returns true if layoutData.useUiWidth is set to false. This is the case
here because a LogicalGridData is used instead of a ColumnLayoutData.
This enables automatic serialization / deserialization if the enum
is used in a data object.
The returned jquery collection contained jquery objects
instead of html elements which is different to jquery
collection by jquery and prevents using methods like .on()
Makes it possible to add custom save needed behavior.

Also removed saveNeeded from model because it is a computed property
If the resizable element is inside a scroll container, the scroll
position needs to be considered when drawing the overlay
This ensures the resizable is always visible
even on inverted tiles.
If there are many tests, the sandbox will be moved out of view which may
break tests that need to interact with the sandbox elements,
e.g. by clicking on them

This fix reduces the height of the jasmine reporter section so the
sandbox is always on top. Because of the overflowing, the content of
the reporter section is still visible even though its height is 0.
Remove obsolete namespace in spec name.
Remove obsolete jshint annotation.
Remove DEFAULT_TIMEOUT_INTERVAL because it will affect every spec not
only FocusManagerSpec and it does not seem to be needed.
This is useful if the splitter itself should be visualized in another
way, e.g. by using one of the fields border.
Not every icon always has the same width.
If icons are used in table cells along with text,
the alignment of the texts in a column may be off.
This typically affects list boxes or smart fields if the lookup rows
have icons.
The tree doesn't have that problem because it uses a min-width for the
icons. The same logic is now applied to table cells as well.
HybridActionEvent uses actionType instead of eventType.

Also move HybridEvent type to Adapter because it is only relevant for
the communication with Java and not part of the hybrid manager api.
Sometimes the result object is already available. In that
case it would be cumbersome to map the values into the given result
object. With the new method the result object can be returned directly.
When importing the main index file from files in the testing folder,
the import must not necessarily end with 'index'.
For example if the index is in a folder called src/main/js, the
import could be ../main/js. In fact, this how IntelliJ adds the import
by default.
Codes delivered by the CodeResource are DOs and can therefor contain a
_type property
If some of the tiles have h or w > 1 and others don't, the navigation
 between the tiles did not work properly.
@cguglielmo
Copy link
Member Author

jenkins run tests

@fschinkel fschinkel requested review from mvilliger, fschinkel and bschwarzent and removed request for mvilliger May 22, 2024 07:26
@@ -390,4 +390,5 @@
/* -------------------------------- */
@iphone5-height: 568px;
@iphone5-width: 320px;
@iphone6-width: 375px;
@iphone6-width: 375px; // includes iphone 6, 6s, 6s plus, 7, 8
Copy link
Member

Choose a reason for hiding this comment

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

Looks good but the comment of this commit has a typo: sizes.lesS

@@ -56,4 +56,25 @@ public static UserAgent getCurrentUserAgent() {
}
}

/**
Copy link
Member

Choose a reason for hiding this comment

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

Is this method really necessary? It would also be possible to use the ClientRunContext instead?

this.spy?.dispose();
this.spy = null;
} else {
this.spy = new LogicalGridLayoutSpy();
Copy link
Member

Choose a reason for hiding this comment

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

trigger layout in order to draw the spies cell bounds?

Copy link
Member Author

Choose a reason for hiding this comment

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

this is not possible here since we don't have the $container. The idea is to use scout.setLogicalGridSpyEnabled

@@ -228,77 +230,67 @@ export class LogicalGridLayoutInfo implements LogicalGridLayoutInfoModel {
prefw = this.logicalWidthInPixel(cons);
}
prefw = Math.floor(prefw);
for (j = cons.gridx; j < cons.gridx + cons.gridw && j < this.cols; j++) {
for (let j = cons.gridx; j < cons.gridx + cons.gridw && j < this.cols; j++) {
Copy link
Member

Choose a reason for hiding this comment

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

Please simplify this loop. As cons.gridw is 1 this loop is pointless and can be replaced by a simple if-statement.

Suggested change
for (let j = cons.gridx; j < cons.gridx + cons.gridw && j < this.cols; j++) {
if (cons.gridx < this.cols) {

if (cons.widthHint > 0) {
distWidth = cons.widthHint - spanWidth - (hSpan - 1) * this.hgap;
distWidth[lc.PREF] = cons.widthHint - spanWidth[lc.PREF] - hGaps;
Copy link
Member

Choose a reason for hiding this comment

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

Please simplify:
distWidth[lc.PREF] will always be value - spanWidth[lc.PREF] - hGaps and distWidth[lc.MAX] is cons.maxWidth - spanWidth[lc.MAX] - hGaps.
Then distWidth[lc.PREF] and spanWidth[lc.PREF] (or distWidth[lc.MAX] and spanWidth[lc.MAX]) are passed to _distributeWidth where the values are summed up again.
So it will be the same to just calculate distWidth = value - hGaps and pass only this value to the _distributeWidth method.

*/
protected _distributeWidth<T>(cons: LogicalGridData, distWidth: number, spanWidth: number, widths: number[], fixedWidths: boolean[], calc: (equalWidth: number, width: number) => number) {
let hSpan = cons.gridw;
let equalWidth = Math.floor((distWidth + spanWidth) / hSpan);
Copy link
Member

Choose a reason for hiding this comment

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

This is not a proper way to distribute equally.
Consider the 99 distributed to 10 columns.
This will lead to 9 columns being 9 wide and the last one being 18 wide.

See pie charts or #222794 for a proper algorithm (ticket has a proof attached).

expect(rows[0][1]).toEqual(new Rectangle(75, 0, parentSize.width - 75, 30));
});

describe('maxWidth', () => {
Copy link
Member

Choose a reason for hiding this comment

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

add test cases for the problems pointed out in LogicalGridLayoutInfo

DO_ENTITY result = exportResult(form);
if (result == null) {
result = createEmptyResult();
}
fireHybridWidgetEvent("save", result);
}
else if (FormEvent.TYPE_RESET_COMPLETE == e.getType()) {
Copy link
Member

Choose a reason for hiding this comment

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

Result needs to be exported and sent to the UI in the reset case as well.
See HybridManager._onHybridFormEvent. The sent data will be set onto the Form and then a reset-Event is triggered. Therefore, the current data (after reset) needs to be sent otherwise it will be empty in the UI after a reset.

Copy link
Member Author

Choose a reason for hiding this comment

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

How did it work before my change? Nothing was done with the result. Does it need to be passed to fireHybridWidgetEvent?

@@ -1266,7 +1266,7 @@ export class TileGrid<TTile extends Tile = Tile> extends Widget implements TileG
findTileIndexAt(x: number, y: number, startIndex?: number, reverse?: boolean): number {
Copy link
Member

Choose a reason for hiding this comment

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

Test?

* If there are tiles selected but there is no focused tile, an object is returned containing the tile to be focused.
* This is the last tile if diff is > 0 and the first tile otherwise.
*/
protected _computeFocusedTileOrSelection(diff: number): TileGridSelectionInstruction {
Copy link
Member

Choose a reason for hiding this comment

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

I find it a bit confusing that the first part of this method looks exactly like the implementation of computeFocusedTile(). Maybe this could be combined by passing the array of tiles as an argument to computeFocusedTile()?

Why does the method use the word "or", but the implementation returns both the focused tile "and" the selection?

If all other computeXYZ() methods are public, shouldn't this method be public as well?

let focusedTile = null;
let focusedTileIndex = -1;
let result = this._computeFocusedTile(xDiff);
let result = this._computeFocusedTileOrSelection(xDiff);
if (result.selectedTiles !== null) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (result.selectedTiles !== null) {
if (result.selectedTiles) {

Or should we even need to check the length of the array? Maybe a JsDoc on the interface would help clarify the API.

Same with computeSelectionY.

@Override
public void cancelLoading() {
if (m_loadJob != null) {
m_loadJob.cancel(true);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe set the member to null? Or add .whenDone() when scheduling the job and set it to null, so it will also be reset upon normal completion.

@@ -61,6 +62,8 @@ export class TileGrid<TTile extends Tile = Tile> extends Widget implements TileG
updateTextFilterText: string;
defaultMenuTypes: string[];
wrappable: boolean;
movableProducer: (tile: Tile) => TileMoveHandler;
resizableProducer: (tile: Tile) => Resizable;
Copy link
Member

Choose a reason for hiding this comment

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

Same issue as with movableProducer.

minBounds: Rectangle;
maxBounds: Rectangle;
distance: number[];
edge: string;
Copy link
Member

Choose a reason for hiding this comment

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

Consider using a string union type: edge: 'e' | 'n' | ...;

if (this._context.currentBounds.equals(this._context.initialBounds)) {
return;
}
this.$container.trigger('resizeend', {
Copy link
Member

Choose a reason for hiding this comment

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

Is the spelling here intentional? It does not seem to be a native event, and I could not find any other reference to "resizeend" in the code.

distance = this._calcDistance(ctx.mousedownEvent, event);
let newBounds = this._computeBounds(event);
if (newBounds) {
$.throttle(this._resizeHandler, Resizable.FPS)(newBounds);
Copy link
Member

Choose a reason for hiding this comment

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

Does that work? I think $.throttle returns a new function that wraps the original function. If $.throttle is called during each mouse movement, new wrappers are created, but the subsequent calls are not throttled.

@@ -294,6 +324,16 @@ export class TileGrid<TTile extends Tile = Tile> extends Widget implements TileG
this.setTiles([]);
}

moveTileBefore(tileToMove: ObjectOrModel<TTile>, sibling: TTile) {
let tiles = arrays.moveBefore(this._tiles, tileToMove as Tile, sibling);
Copy link
Member

Choose a reason for hiding this comment

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

Why does the type of the first argument allow models? this._tiles does not contain any models (according to its type), therefore a model could never be moved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants